场景的查询框架 :SceneQuery

构建一个场景一般都是比较复杂的,像这样一个复杂的场景我们是不会直接拿去渲染的,这就涉及到我们为了达到各种目的对现有的场景各种目的进行切割,最终我们会使用我们切割的这部分内容。

 

 

SceneQuery:

这个类里面需要关注的是它定义的一个WorldFragment的结构体,这个结果体描述的是世界整体的一个部分。

  enum WorldFragmentType {   // WorldFragment的类型
            WFT_NONE,
            WFT_PLANE_BOUNDED_REGION,  // 对应查询类型中的区域查询
            WFT_SINGLE_INTERSECTION,       // 对应求交查询
            WFT_CUSTOM_GEOMETRY,            // 用户自定义的类型
            WFT_RENDER_OPERATION
        };

   struct WorldFragment {  
            WorldFragmentType fragmentType;  // 与上面对应
            Vector3 singleIntersection;  // WFT_SINGLE_INTERSECTION
            list<Plane>::type* planes;  // WFT_PLANE_BOUNDED_REGION
            void* geometry;                   // WFT_CUSTOM_GEOMETRY
            RenderOperation* renderOp; 
        };

虽然现在还不清楚这每种类型具体针对什么结构,但是为啥WorldFragment不是联合体而是结构体呢?

        SceneManager* mParentSceneMgr;
        uint32 mQueryMask;        //过滤查询结果,对应单一场景元素
	uint32 mQueryTypeMask; //过滤查询结果,对应一类场景元素
        set<WorldFragmentType>::type mSupportedWorldFragments;
        WorldFragmentType mWorldFragmentType;

这里的过滤掩码在SceneManager中被定义。

 

IntersectionSceneQuery:(相交查询,变量所有对象,找出其中两两相交的对值

    typedef std::pair<MovableObject*, MovableObject*> SceneQueryMovableObjectPair;
    typedef std::pair<MovableObject*, SceneQuery::WorldFragment*> SceneQueryMovableObjectWorldFragmentPair;
    typedef list<SceneQueryMovableObjectPair>::type SceneQueryMovableIntersectionList;
    typedef list<SceneQueryMovableObjectWorldFragmentPair>::type SceneQueryMovableWorldFragmentIntersectionList;
    /** Holds the results of an intersection scene query (pair values). */
	struct _OgreExport IntersectionSceneQueryResult : public SceneMgtAlloc
    {
        /// List of movable / movable intersections (entities, particle systems etc)
        SceneQueryMovableIntersectionList movables2movables;
        /// List of movable / world intersections
        SceneQueryMovableWorldFragmentIntersectionList movables2world;
    };

 

execute :

    IntersectionSceneQuery::execute(void)
    {
        clearResults();
        mLastResult = OGRE_NEW IntersectionSceneQueryResult();
        // Call callback version with self as listener
        execute(this);
        return *mLastResult;
    }

 这个方法会查询所有满足相交的结果,但是呢这里没有实现,也就是说它的具体的子类会实现具体的碰撞规则。

这个,父类就是比较抽象,没有什么真本事。

 

RaySceneQuery :(沿射线方向的碰撞检测,获取相应的查询结果)

    struct _OgreExport RaySceneQueryResultEntry   // 存储查询结果的结构体
    {
        Real distance;                      // 射线的起点到物体的距离
        MovableObject* movable;    // 
        SceneQuery::WorldFragment* worldFragment;  // 
        bool operator < (const RaySceneQueryResultEntry& rhs) const
        {
            return this->distance < rhs.distance;
        }

    };
    typedef vector<RaySceneQueryResultEntry>::type RaySceneQueryResult;
Ray mRay;   // 射线

 RaySceneQueryResultEntry存储射线碰结果的结构体,每个结果体里面保存模型和之间的距离。

 

RegionSceneQuery :(区域检测,只要是锁定区域的全部查询出来)

typedef list<MovableObject*>::type SceneQueryResultMovableList;
    typedef list<SceneQuery::WorldFragment*>::type SceneQueryResultWorldFragmentList;
    /** Holds the results of a scene query. */
	struct _OgreExport SceneQueryResult : public SceneMgtAlloc
    {
        /// List of movable objects in the query (entities, particle systems etc)
        SceneQueryResultMovableList movables;
        /// List of world fragments
		SceneQueryResultWorldFragmentList worldFragments;
    }

SceneQueryResult* mLastResult;

 这是个抽象类,它只是描述了记录结果的方式。

RegionSceneQuery的子类:AxisAlignedBoxSceneQuery(边界盒查询,不规则矩形内所有对象),SphereSceneQuery(查询球状区域内的所有对象),PlaneBoundedVolumeListSceneQuery(查询一个平面上所有对象)

// 1.边界盒:利用mAABB判断边界
AxisAlignedBox mAABB;
// 2.球 :利用球体判断边界
Sphere mSphere;
// 3.平面上 :这是一个list是多个平面
PlaneBoundedVolumeList mVolumes;

 我看到所有官方提供的SceneQuery类里面的void execute(SceneQueryListener* listener);都没有实现,是否以为着这个判定的规则由我们自己来实现?这样的花我们在使用的时候需要扩展自己的SceneQuery。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值