………………………………………………………………………………………………… 重要的图片编写一个最好的碰撞检测例程。我们开始设计并且编写它的基本程序框架,与此同时我们也正在开发着一款游戏的图形管线。要想在工程结束的时候才加入碰撞检测是比较不好的。因为,快速的编写一个碰撞检测会使得游戏开发周期延迟甚至会导致游戏难产。在一个完美的游戏引擎中,碰撞检测应该是精确、有效、而且速度要快。这些意味着碰撞检测必须通过场景几何学的管理途径。蛮力方法是不会工作的 — 因为今天,3D游戏每幀运行时处理的数据量是令人难以置信的。你能想象一个多边形物体的检测时间。在一个完美的比赛发动机,碰撞察觉应该是精确,有效,并且很快的。这些要求意味着那碰撞察觉必须仔细到景色被系住几何学管理管道。禽兽力量方法嬴得’t 工作—今天’s 3D 比赛每框架处理的数据的数量能是介意犹豫。去是你能核对对在景色的每另外的多角形的一个物体的每多角形的时间。 The Big Picture To create an optimal collision detection routine, we have to start planning and creating its basic framework at the same time that we’re developing a game’s graphics pipeline. Adding collision detection near the end of a project is very difficult. Building a quick collision detection hack near the end of a development cycle will probably ruin the whole game because it’ll be impossible to make it efficient. In a perfect game engine, collision detection should be precise, efficient, and very fast. These requirements mean that collision detection has to be tied closely to the scene geometry management pipeline. Brute force methods won’t work — the amount of data that today’s 3D games handle per frame can be mind-boggling. Gone are the times when you could check each polygon of an object against every other polygon in the scene. / 4 ………………………………………………………………………………………………… 让我们来看看一个游戏的基本循环引擎。(Listing 1) http://www.gamasutra.com/features/20000330/bobic_l1.htm 这段代码简要的阐明了我们碰撞检测的想法。我们假设碰撞没发生并且更新物体的位置,如果我们发现碰撞发生了,我们移动物体回来并且不允许它通过边界(或删除它或采取一些另外预防措施)。然而,因为我们不知道物体的先前的位置是否仍然是可得到的,这个假设是太过分简单化的。你必须为这种情况设计一个解决方案(否则,你将可能经历碰撞而你将被粘住)。如果你是一个细心的玩家,你可能在游戏中会注意到,当你走近一面墙并且试图通过它时,你会看见墙开始动摇。你正在经历的,是感动运动返回来的效果。动摇是一个粗糙的时间坡度的结果(时间片)。 Let’s begin by taking a look at a basic game engine loop (Listing 1). A quick scan of this code reveals our strategy for collision detection. We assume that collision has not occurred and update the object’s position. If we find that a collision has occurred, we move the object back and do not allow it to pass the boundary (or destroy it or take some other preventative measure). However, this assumption is too simplistic because we don’t know if the object’s previous position is still available. You’ll have to devise a scheme for what to do in this case (otherwise, you’ll probably experience a crash or you’ll be stuck). If you’re an avid game player, you’ve probably noticed that in some games, the view starts to shake when you approach a wall and try to go through it. What you’re experiencing is the effect of moving the player back. Shaking is the result of a coarse time gradient (time slice). / 5 ………………………………………………………………………………………………… 但是我们的方法是有缺陷的。我们忘记在我们的方程中加入时间。图1显示了时间的重要性,因而它不能省去。就算一个物体不在时间 t1 或 t2 抵触,它可以在时间t1 < t < t2穿过t边界哪儿。这是非常正确的,我们已经有大而连续的框架可操作。我们会发现必须还要一个好方法来处理差异。 But our method is flawed. We forgot to include the time in our equation. Figure 1 shows that time is just too important to leave out. Even if an object doesn’t collide at time t1 or t2, it may cross the boundary at time t where t1 < t < t2. This is especially true when we have large jumps between successive frames (such as when the user hit an afterburner or something like that). We'll have to find a good way to deal with discrepancy as well. / 6 ………………………………………………………………………………………………… 我们应该将时间作为第4维也加入到所有的计算中去。这些使得计算变得很复杂,然而,我们只能舍弃它们。我们也可从原来的物体在时间 t1 和 t2 之间的占据,然后靠着墙测试结果(图 2 )。 We could treat time as a fourth dimension and do all of our calculations in 4D. These calculations can get very complex, however, so we’ll stay away from them. We could also create a solid out of the space that the original object occupies between time t1 and t2 and then test the resulting solid against the wall (Figure 2). / 7 ………………………………………………………………………………………………… 一条简单的途径就是在 2 不同的时间在一个物体的地点附近创造凸壳。这条途径的效率很低并且毫无疑问它会降低你游戏的执行速度。如果不建立凸壳,我们可以在物体附近建立一个范围框。在我们熟悉几种技术后,我们要再次回到这个问题上。 An easy approach is to create a convex hull around an object’s location at two different times. This approach is very inefficient and will definitely slow down your game. Instead of constructing a convex hull, we could construct a bounding box around the solid. We’ll come back to this problem once we get accustomed to several other techniques. / 8 ………………………………………………………………………………………………… 另外的途径,它是更容易的实现但是少些精确,是在正中央为交叉的一半和测试细分给的时间间隔。另外的途径,其是更容易的实现但是少些精确,是细分在为在midpoint 的交叉的一半和测试的给的时间间隔。这计算能递归地为每个结果的一半返回。这途径将比先前的方法更快,但是它不能保证精确检测所有碰撞的。 Another approach, which is easier to implement but less accurate, is to subdivide the given time interval in half and test for intersection at the midpoint. This calculation can be done recursively for each resulting half, too. This approach will be faster than the previous methods, but it’s not guaranteed to catch all of the collisions. / 9 ………………………………………………………………………………………………… 另外的隐藏的问题是 collide_with_other_objects ()例程,它检查一个对象是否在场景内与任何另外的对象交叉。如果我们的场景有很多物体时,这例程会变得更重要。如果我们需要在场景对所有的别的对象检查,我们将粗略地做