欢迎加入Cocos2d-x 交流群:193411763
转载时请注明原文出处 :http://blog.csdn.net/u012945598/article/details/39665911
----------------------------------------------------------------------------------------------------------------------------------------
在上一篇文章中讲解了AABB包围盒碰撞检测的原理,并在文章末尾提到了Cocos2d-x 3.3beta0版本中小乌龟碰撞检测的例子,这个例子使用的并非是AABB碰撞检测,而是比AABB包围盒更加精确的OBB包围盒的碰撞检测方法,本篇文章将对OBB包围盒及其碰撞检测方法进行介绍。
1. OBB包围盒
OBB(Oriented Bounding Box)包围盒也被称作有向包围盒或定向包围盒,它会随着物体的移动、缩放、旋转。简单来说,它就是一个能够旋转的AABB包围盒。在Cocos2d-x中使用过物理引擎的开发者一定见过当我们在物理世界中创建一个物体并开启调试模式时,这个物体会被红色的矩形包围,当物体做平移或旋转时,这个红色矩形也会做同样的操作,这个红色矩形正是该物体的OBB包围盒。如图1-1所示:
图1-1
相对于AABB包围盒来讲,OBB在碰撞精度上要高于AABB,但是精确度的提高同时带来的就是效率的降低,OBB的算法无疑是要比AABB复杂的,同样内存消耗也会更大,这个问题我们可以从OBB的表达式来得到结论。
OBB包围盒的表达式:
表达一个AABB包围盒或OBB包围盒都有若干种方式,但是无疑需要选中里面最优的一种。对于AABB来说,通常只要使用两个顶点的坐标信息标识一个AABB包围盒就可以了,其它的顶点信息都可以通过计算得出。但是对于OBB包围盒的表达方式只有两点信息显然是不够的。
想要唯一标识一个OBB包围盒我们大概会想到,使用8个顶点的集合、6个面的集合、1个顶点和3各彼此正交的边向量,又或者是1个中心点、1个旋转矩阵和3个1/2边长(注:一个旋转矩阵包含了三个旋转轴,若是二维的OBB包围盒则是一个中心点,两个旋转轴,两个1/2边长)。
上述最后一种方法就是最常用的方法,下面来看一段Cocos2d-x 3.3beta0中CCOBB.h中的代码:
Vec3 _center; // 中心点
/*
以下三个变量为正交单位向量,
定义了当前OBB包围盒的x,y,z轴
用于计算矢量投影
*/
Vec3 _xAxis; // 包围盒x轴方向单位矢量
Vec3 _yAxis; // 包围盒y轴方向单位矢量
Vec3 _zAxis; // 包围盒z轴方向单位矢量
Vec3 _extents; // 3个1/2边长,半长、半宽、半高
Cocos2d-x 3.0beta0在CCOBB.h中定义了五个成员变量,每一个数据类型都是一个三维向量,包含了3个浮点数。也就是说,表达一个OBB包围盒需要15个float类型的变量,占用60个字节,然而表示一个AABB包围盒仅需要两个顶点,24个字节,从这一点上来说,OBB的内存消耗算很高了。
一种减少开销的方案是:只存储旋转矩阵的两个轴,只是在测试时利用叉积计算第三个轴,这样可以减少CPU操作开销并节省3个浮点数分量,降低20%内存消耗。
OBB包围盒的创建:
如何用一个高效的算法构建一个紧密包围的OBB包围盒或是AABB包围盒是一个很复杂的问题,因为不同的形状物