【发布时间】:2010-12-29 22:54:24
【问题描述】:
我一直想知道这一点。在像GTA 这样有成千上万个对象的游戏中,游戏如何知道您是否在使用健康包?
不可能每个对象都有一个事件监听器?迭代也不好?我只是想知道它实际上是如何完成的。
【问题讨论】:
-
好问题!我对游戏编程的各个低级结构和方法了解很多,但经常想知道它们是如何组合在一起的。
标签: algorithm data-structures 3d collision-detection
我一直想知道这一点。在像GTA 这样有成千上万个对象的游戏中,游戏如何知道您是否在使用健康包?
不可能每个对象都有一个事件监听器?迭代也不好?我只是想知道它实际上是如何完成的。
【问题讨论】:
标签: algorithm data-structures 3d collision-detection
对此没有一个答案,但大世界通常通过使用类似于 quadtree 或 kd-tree 的方式进行空间划分,这使得寻找最近邻居的搜索时间低于线性时间(分数幂,或者最坏的情况O( N^(2/3) ) 用于 3D 游戏)。这些方法通常被称为 BSP 用于二进制空间分区。
关于碰撞检测,每个对象通常也有一个与之关联的包围体网格(一组多边形形成一个凸包)。这些高度简化的网格(有时只是一个立方体)不会被绘制,而是用于检测碰撞。最基本的方法是创建一个平面,该平面垂直于连接每个对象的中点的线与与该线的中点相交的平面。如果一个物体的包围体在这个平面的两边都有点,那就是碰撞(你只需要在平面上测试两个包围体中的一个)。另一种方法是增强的GJK 距离算法。如果您想深入了解教程,请查看NeHe Productions' OpenGL lesson #30。
顺便说一句,包围体也可以用于其他优化,例如所谓的遮挡查询。这是一个确定哪些对象在其他对象(遮挡物)之后的过程,因此不需要处理/渲染。边界体也可用于平截头体剔除,这是确定哪些对象在透视观察体之外(太近、太远或超出视野角度)的过程,因此不需要渲染。
正如 Kylotan 所指出的,使用包围体在检测遮挡时会产生误报,并且对于某些类型的对象(例如环形)根本不起作用(例如,通过甜甜圈中的孔看)。 portal-culling 上的另一个线程是让这些对象正确遮挡。
【讨论】:
Quadtrees and Octrees、another quadtree 是使用空间分区的常用方法来完成此任务。后面的示例显示,与逐对蛮力搜索碰撞相比,处理量减少了 97%。
【讨论】:
游戏物理引擎中的一种常见技术是扫描和修剪方法。 David Baraff's SIGGRAPH notes 对此进行了解释(请参阅带约束的运动章节)。 Havok 肯定会使用这个,我认为这是 Bullet 中的一个选项,但我不确定 PhysX。
这个想法是,您可以查看每个轴上的 AABB(轴对齐边界框)的重叠;如果两个对象的 AABB 的投影在所有三个轴上都重叠,则 AABB 必须重叠。您可以通过对AABB的起点和终点进行排序来相对快速地检查每个轴;帧之间有很多时间相干性,因为通常大多数对象的移动速度都不是很快,所以排序变化不大。
一旦 sweep-and-prune 检测到 AABB 之间的重叠,您就可以对对象进行更详细的检查,例如球体与盒子。如果详细检查显示发生碰撞,您可以通过施加力来解决碰撞,和/或触发游戏事件或播放音效。
【讨论】:
正确。通常没有每个对象的事件侦听器。内存中通常有一个模仿游戏地图的非二叉树结构。想象一下地铁/地下地图。 这种记忆结构是游戏中事物的集合。您是玩家、怪物和可以拾取的物品,或者可能会爆炸并伤害您的物品。因此,当玩家在游戏中移动时,玩家对象指针会在游戏/地图内存结构中移动。
见How should I have my game entities knowledgeable of the things around them?
【讨论】:
我想推荐 Christer Ericson 关于实时碰撞检测的可靠书籍。它介绍了碰撞检测的基础知识,同时提供了当代研究工作的参考。
Real-Time Collision Detection (The Morgan Kaufmann Series in Interactive 3-D Technology)
【讨论】:
有很多优化可以使用。
首先 - 任何对象(例如索引 i)都以立方体为界,中心坐标为CXi,CYi,大小为Si
其次 - 碰撞检测与估计一起工作:
a) 查找所有符合条件的立方体 i,j 对:Abs(CXi-CXj)<(Si+Sj) AND Abs(CYi-CYj)<(Si+Sj)
b) 现在我们只使用 a) 中的对。我们更准确地计算它们之间的距离,例如 Sqrt(Sqr(CXi-CXj)+Sqr(CYi-CYj)),对象现在表示为几个简单图形的集合 - 立方体、球体、圆锥 - 我们使用几何公式来检查这些图形的交叉点。
c) b) 中检测到交叉点的对象被处理为与物理计算等的碰撞。
【讨论】: