一般游戏中都要涉及物体运动之间的交互。相比之下2D画面中的碰撞检测要容易的多,无论是采用像素判断还是使用物体面积与距离判断都是可行的。
但是问题到3D游戏中就有很大的麻烦。对于PC机的运算能力,几乎不可能使用检测每个物体的多边形和顶点的穿透,那样的运算量对PC来讲几乎是不可完成的。所以PC游戏上使用的碰撞检测不可能使用太精确的检测。而且对于3D碰撞检测问题,还没有几乎完美的解决方案。目前只能采取根据需要来取舍运算速度和精确性。
目前成功商业3D游戏普遍采用的碰撞检测是采用BSP树及包装盒方式。简单讲就是采用一个描述用的正方体或者球型体包裹住3D物体对象整体(或者是主要部分),之后根据“描述用”包装盒的距离、位置等信息来计算是否发生碰撞。当然除了球体和正方体以外,其他形状也可以作包装盒,但是相比计算量和方便性来讲 还是前边两中形状更方便些,所以其他形状的包装只用在一些特殊部分使用。BSP树是用来控制检测顺序和方向的数据描述。因为在一个游戏场景中可能存在很多物体,他们之间大多属于较远位置或者相对无关的状态,一个物体的碰撞运算没必要遍历这些物体,同时节省重要的时间。
我们今天主要讨论的不是这种3D碰撞检测方式。因为我们是对初学3D编程的人员写的这篇文章。目的在于使大家简单建立自己的3D场景,而不用在开始就把大量精力消耗在碰撞检测问题上,从而把注意力放在基础的图形编程之上。
如果需要认真研究成熟的3D碰撞问题上,请参考其他文章,这类文章网上有很多。在本文最后我也会附上一些相关文章的连接。
=====fengye=====
===『原创』RE:『原创』适合初学的简单3D碰撞检测初探(对于3D编程初学人员)===2005040408460704===
以下内容涉及的数学基础运算请参考解析几何、三角函数、线性代数。对于物理运动的描述及控制也请参考其他资料。这里仅讲述3D碰撞问题。
对于可控制的3D动态场景,不仅需要能准确及时的绘制图形,而且需要在内存中建立一个控制描述世界。在这个世界中不必考虑具体的图形绘制,但要把每个即将在屏幕上绘制的物体都考虑在内。为每个物体建立一个包围盒(或者说是定位坐标组)。每个运动的物体都要有状态属性,比如运动方向,速度,当前位置信息。这些信息用来检测和处理碰撞问题。
我们首先假设我们要作的是一个简单的赛车程序。4辆车,几个可移动障碍物,和完整的塞道护拦。
首先对于比较开阔的场景,应该划分区域,比如把塞道划分为4X4个区域(A00-A44)。整个塞道护拦由多个长方体拼界而成。在16个区域的接合位置,拼合塞道的长方型要有交叉,目的为了防止检测漏洞。为了简单,不考虑多线处理问题,我们采用处理一侦渲染一侦的方式。每次处理的时候要保留上次绘制前的处理数据(及上一侦的赛车状态)。现在假设赛车在A23区域,即将处理计算下一侦的数据。那么根据运动速度和方向,计算出下一侦的赛车位置(其实计算的只是包围盒的8个顶点位置)。根据赛车的包围盒信息检测赛车目前仍然处在A23区域中。现在开始分别计算包围盒的8个顶点是否和A23区域内的所有赛道护拦有穿透。当发现一个穿透的时候,马上计算该穿透点穿透的护拦的面,以及穿透点的法线。根据碰撞处理的需要,马上把上一侦的赛车状态调整(根据需要考虑是否复制出来数据,再修改,防止这次依然有其他问题需要恢复?)。比如我们这里可以把赛车的方向根据碰撞面和法线作一个反射与原方向的偏离角度,来偏转车辆方向。速度根据穿透线和法线角度来适当减少。车辆转动,根据车辆的穿透顶点和速度,角度等信息来计算。再次做预计位置计算,如果没有穿透了,那么就保存当前状态然后渲染,继续。可是很可能仍然就穿透,这时候就根据具体游戏的可能性来看,是回到前侦状态再休整呢?还是继续刚才复制出来的数据继续修正?这就看具体需要的可能性了。可以根据自己的研究来决定。
注意以上所作的前提条件是成功渲染的前一侦是已经处理过,不包含物体穿透的。(当然,烟雾、灯光等不考虑碰撞穿透的物体不在计算内。)
以上检测还是有漏洞,有可能出现死循环,(这就看你的赛道设计和运动描述是否合理了)为避免死循环,还是建议设计一个计数器,比如在一侦内反复检测了8次,仍然有穿透,那么停止检测,调用紧急处理函数来解决这一问题。(例如,将车辆重置于赛道中心或其他地方等方法。)
=====fengye=====
===『原创』RE:『原创』适合初学的简单3D碰撞检测初探(对于3D编程初学人员)===2005040409180904===
以上方法基本可以构建简单的3D场景世界了,尽管还有很多不足。
计算一侦,绘制一侦的方法是不太理想的,最好分成多个线程。
其实不难看出,此方法也是根据包围盒简化出来的,根据具体需要,可能还需要有些变化,请大家自己想些处理方式。
具体使用中还有一些问题要注意,一时想不起来了,回头再补充吧。
也欢迎读者提出意见交流。
=====fengye=====
===『原创』RE:『原创』适合初学的简单3D碰撞检测初探(对于3D编程初学人员)===2005040512022504===
www.GAMERES.com 上有很多关于物理及碰撞的文章