zoukankan      html  css  js  c++  java
  • PlaneBoundedVolumeList平面体积查询

    学习了下OGRE中文网上的那篇中级教程后,跟据自己的情况封了一个鼠标选择类。

    Selection.h

    //=============================================================================
    //class:  框选矩形类
    //Desc:   显示鼠标框选矩形
    //day:    2008/06/30
    //author: 苗琳
    //=============================================================================
    class SelectionRectangle : public ManualObject
    {
    public:
        SelectionRectangle(const String &name)
            : ManualObject(name)
        {
            setRenderQueueGroup(RENDER_QUEUE_OVERLAY);   //设置该渲染队列为所有层之上      
            setUseIdentityProjection(true);              //使用单位化投影矩阵
            setUseIdentityView(true);                    //使用单位化视图矩阵
            setQueryFlags(0);
        }
        //-----------------------------------------------------------------------------
        // name: 绘制矩形框
        // Desc:
        //-----------------------------------------------------------------------------
        void DrawRectangle(float left, float top, float right, float bottom)
        {
            //转换坐标为-1 到 +1之间
            left = left * 2 - 1;
            right = right * 2 - 1;
            top = 1 - top * 2;
            bottom = 1 - bottom * 2;
            //清除以前绘制的所有点
            clear();    
            //开始绘制线带
            begin("", RenderOperation::OT_LINE_STRIP);       
            position(left, top, -1);
            position(right, top, -1);
            position(right, bottom, -1);
            position(left, bottom, -1);
            position(left, top, -1);
            end();
        }

        void DrawRectangle(const Vector2 &topLeft, const Vector2 &bottomRight)
        {
            DrawRectangle(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
        }
    };

    //=============================================================================
    //class:  选择物体类
    //Desc:   对用户选择物体的处理 , 包括框选,点选等
    //day:    2008/06/30
    //author: 苗琳
    //=============================================================================
    class CSelection
    {
    public:
        CSelection(SceneManager* pSceneMgr , Camera* pCamera);
        ~CSelection(void);
        //不选择所有物体
        void deselectObjects();
        //选择一个物体
        void selectObject(MovableObject *obj);
        //执行查询
        void performSelection(const Vector2 &first, const Vector2 &second);

    public:
        Vector2 mStart, mStop;                               //框选开始点/结束点
        SceneManager *mSceneMgr;                             //场景管理者
        Camera*  m_pCamera;                                  //摄像机
        PlaneBoundedVolumeListSceneQuery *mVolQuery;         //平面体积查询器
        RaySceneQuery* m_pRaySceneQuery;                     //射线场景查询器
        std::list mSelected;                 //当前选择的物体列表              
        SelectionRectangle *mRect;                           //框选矩形显示类
        bool mSelecting;                                     //是否正在框选
    };

    Selection.cpp

    //=============================================================================
    //class:  选择物体类
    //Desc:   对用户选择物体的处理 , 包括框选,点选等
    //day:    2008/06/30
    //author: 苗琳
    //=============================================================================

    #include "Selection.h"

    //-----------------------------------------------------------------------------
    // name: 构造函数
    // Desc:
    //-----------------------------------------------------------------------------
    CSelection::CSelection(SceneManager* pSceneMgr , Camera* pCamera) : mRect(0) , mSceneMgr(pSceneMgr) , m_pCamera(pCamera)
    {

        //初始化框选矩形
        mRect = new SelectionRectangle("SelectionRectangle");
        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(mRect);

        //初始化框选/点选查询器
        mVolQuery = mSceneMgr->createPlaneBoundedVolumeQuery(PlaneBoundedVolumeList());     //初始化平面体积查询器
        m_pRaySceneQuery=mSceneMgr->createRayQuery(Ray());                                  //初始化射线场景查询器

        //初始化选择状态
        mSelecting = false;
        mRect->setVisible(false);
    }

    //-----------------------------------------------------------------------------
    // name: 析构函数
    // Desc:
    //-----------------------------------------------------------------------------
    CSelection::~CSelection(void)
    {
        //删除查询器
        mSceneMgr->destroyQuery(mVolQuery);
        mSceneMgr->destroyQuery(m_pRaySceneQuery);
        SafeDelete(mRect);
    }

    //-----------------------------------------------------------------------------
    // name: 不选择所有物体
    // Desc: 设置所有被选物体的包围盒清空被选物体数组
    //-----------------------------------------------------------------------------
    void CSelection::deselectObjects()
    {
        std::list::iterator itr;
        for (itr = mSelected.begin(); itr != mSelected.end(); ++itr)
            (*itr)->getParentSceneNode()->showBoundingBox(false);
        mSelected.clear();
    }

    //-----------------------------------------------------------------------------
    // name: 选择一个物体
    // Desc: 添加一个物体到被选数组里,并且显示这个物体的包围盒
    //-----------------------------------------------------------------------------
    void CSelection::selectObject(MovableObject *obj)
    {
        obj->getParentSceneNode()->showBoundingBox(true);
        mSelected.push_back(obj);
    }

    //-----------------------------------------------------------------------------
    // name: 进行框选查询
    // Desc: 在用户框选完成后调用
    //-----------------------------------------------------------------------------
    void CSelection::performSelection(const Vector2 &first, const Vector2 &second)
    {
        float left = first.x, right = second.x,
            top = first.y, bottom = second.y;

        //如果用户是反着框的话,转换一下坐标
        if (left > right)
            swap(left, right);
        if (top > bottom)
            swap(top, bottom);

        //跟据用户框选的范围大小,判断是框选还是点选
        if ((right - left) * (bottom - top) < 0.0001)
        {
            //right+=0.002;
            //bottom+=0.002;
            Ray selectRay = m_pCamera->getCameraToViewportRay(left, top);
            m_pRaySceneQuery->setRay(selectRay);
            m_pRaySceneQuery->setSortByDistance(true);

            RaySceneQueryResult result = m_pRaySceneQuery->execute();
            deselectObjects();
            RaySceneQueryResult::iterator itr;
            for ( itr = result.begin(); itr != result.end(); itr++ )
            {
                //筛选掉一些非选择性物体
                if (itr->movable->getParentSceneNode()->getName()=="" ||
                    itr->movable->getParentSceneNode()->getName()=="eye" ||
                    itr->movable->getName()=="entBrush" ||
                    itr->movable->getName()=="Axis" ||
                    itr->movable->getName()=="ETTerrain/Terrain/Tile[0][0]" ||
                    itr->movable->getName()=="ETTerrain/Terrain/Tile[1][0]" ||
                    itr->movable->getName()=="ETTerrain/Terrain/Tile[0][1]" ||
                    itr->movable->getName()=="ETTerrain/Terrain/Tile[1][1]")
                {
                    continue;
                }
                selectObject(itr->movable);
            }

        }
        else
        {
            //由选择框产生四条射线,分别从选择框四个角发射
            Ray topLeft = m_pCamera->getCameraToViewportRay(left, top);
            Ray topRight = m_pCamera->getCameraToViewportRay(right, top);
            Ray bottomLeft = m_pCamera->getCameraToViewportRay(left, bottom);
            Ray bottomRight = m_pCamera->getCameraToViewportRay(right, bottom);

            //以下平面定义了一个在摄像机前无限伸展的“开放锥体”
            PlaneBoundedVolume vol;
            vol.planes.push_back(Plane(topLeft.getPoint(3), topRight.getPoint(3), bottomRight.getPoint(3)));         // 前平面
            vol.planes.push_back(Plane(topLeft.getOrigin(), topLeft.getPoint(100), topRight.getPoint(100)));         // 顶平面
            vol.planes.push_back(Plane(topLeft.getOrigin(), bottomLeft.getPoint(100), topLeft.getPoint(100)));       // 左平面
            vol.planes.push_back(Plane(topLeft.getOrigin(), bottomRight.getPoint(100), bottomLeft.getPoint(100)));   // 底平面
            vol.planes.push_back(Plane(topLeft.getOrigin(), topRight.getPoint(100), bottomRight.getPoint(100)));     // 右平面

            //增加上面定义的盒子到平面体积查询中
            PlaneBoundedVolumeList volList;
            volList.push_back(vol);
            mVolQuery->setVolumes(volList);
            SceneQueryResult result = mVolQuery->execute();

            //显示查询结果
            deselectObjects();
            SceneQueryResultMovableList::iterator itr;
            for (itr = result.movables.begin(); itr != result.movables.end(); ++itr)
            {
                //筛选掉一些非选择性物体
                if ((*itr)->getParentSceneNode()->getName()=="" ||
                    (*itr)->getParentSceneNode()->getName()=="eye" ||
                    (*itr)->getName()=="entBrush" ||
                    (*itr)->getName()=="Axis" )
                {
                    continue;
                }
                selectObject(*itr);
            }
        }

    }


    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/miaolinvip/archive/2008/07/20/2680507.aspx

  • 相关阅读:
    PHP如何计算两个时间之间相差多少时分秒
    关于php如何连贯操作类方法(以数据库为例)
    php中递归创建目录
    John细说PHP的验证码
    PHP内部函数使用外部变量的方法
    php中call_user_func_array()的使用
    linux-Centos6.5中nginx1.63源码安装
    shopnc 商城源码阅读笔记-缓存技术
    PHP引用传值规范问题
    shopnc 商城源码阅读笔记--开篇概述
  • 原文地址:https://www.cnblogs.com/lizhengjin/p/1848171.html
Copyright © 2011-2022 走看看