本以为Ogre没有实现collision,在看源代码的时候忽然发现了AABB的身影。。。哇塞,真有呀~~~
OgreAxisAlignedBox.h
这里面定义了AABB方块体。每一个SceneNode都可以调用Ogre::SceneNode::_getWorldAABB()获得这个Node的AABB,然后用这个AABB来判断是否和其他的AABB相交。(其实还可以是球体、平面、向量,不过这几种不出现在真实的世界,所以Ogre只提供每个SceneNode的__getWorldAABB()这一个方法)
并且SceneManager也提供了全局的相交查询函数。
但是。。。。。木有发现solver。。。。。嗨,还是只提供了碰撞检测,都不给个处理办法。。。所以你检测到相交的话,就自己解决吧。
不过只有AABB这一种模型有点苦逼啊。其实仔细想想,要是人体不需要精细检测的话,其他的需求也不是很大。像havok那样还提供多级的,好是好,但是消耗资源哇~~~嗯,心里安慰了。不过AABB让我怎么拿棍子打人啊?呀,对,用vector,取AABB的对角线啊~~~
没那么苦逼啦~~~今天又发现一个文件,里面都是碰撞检测的查询。这个很强悍了。
OgreSceneQuery.h
这里面定义了不少类,但是一个碰撞系统的机构的架构出来了。
基类(接口)是SceneQuery类,这个类只提供接口,所有不同的查询都得继承这个类来各自实现。而更有意思的是,每一种SceneManager都要继承SceneQuery的子类的子类,实现自己在自己的场景管理结构的不同种类的查询。
继承SceneQuery类的子类有:
RegionSceneQuery:区域查询,提供最基本的区域查询函数,返回指定区域内的所有物体。
AxisAlignedBoxSceneQuery:继承RegionSceneQuery,多加了设置和获取AABB大小的函数,查询一个正方体范围内相交物体
SphereSceneQuery:继承RegionSceneQuery,多加了设置和获取Sphere大小的函数,查询一个球体范围内相交物体
PlaneBoundedVolumeListSceneQuery:继承自RegionSceneQuery,多加了设置和获取平面提及的函数,查询一个平面体积内相交物体
RaySceneQuery:射线查询,查询并返回指定射线上的所有物体
以下不是继承SceneQuery的
IntersectionSceneQuery类,这个类(或子类)的对象是被一个特定的SceneManager创建(上面的都是),不同的是上面的是查询在一个特定的区域内有什么,这个是查询SceneManager里的所有可移动的Node,看有没有相交的。
里面是这样实现的。
1、由于可移动的物体是分类的,分成各种section,每个section里都有很多个这种物体的实体。
2、所以根据要查询的类型(就是mask),作为跳过某个section的根据,除了mask中指明的跳过的section,其他按照循环遍历进行挨个循环比较。。。。。。。。也就是把场景中不手动设置跳过跳过的所有活动物体两两比较一次。。。。这个碰撞检测够牛。。。。谁写的。。。。太胡闹了。。。按照这个算法检测碰撞的话,估计别的活不用干了。。。。。
还有雷的呢,知道上面介绍的SceneQuery的子类们都是如何进行查询的?比如AABB,直接把要查询的AABB立方体与世界所有其他能动的做相交测试。。。。。。
所以想检测碰撞(如果想能稍微高效些。。。。还是选个物理引擎吧。。。有兴趣的自己实现。。。。)
另外,还有一个类:SceneQueryListener,用来在查询的过程中,每得到一个结果就执行,也就是callback。每种SceneQuery的子类都可以传递一个SceneQueryListener来作为查询的callback
还有一个RaySceneQueryListener,由于Ray查询返回的值特殊,所以专门定义了一个回调函数接口。
还有一个IntersectionSceneQueryListener,由于相交查询返回的是一对物体,所以得专门定义回调函数。