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

原文地址:https://www.cnblogs.com/lizhengjin/p/1848171.html