我正在制作3D游戏,并被告知here和here我应该始终在服务器端执行碰撞检测。现在,问题是我不知道怎么做!玩家在平面上的碰撞很容易,因为玩家是用圆柱体表示的,但是,本地图本身是带有丘陵的模型时,如何进行碰撞检测呢?是否可以通过某种方式在Node.js服务器上导入3D模型?然后,说我确实导入了模型,是否有一些碰撞检测库,还是我必须自己进行数学计算? (我的最后一招就是将模型转换为JSON(模型已经转换为JSON),然后读取所有顶点,但这很痛苦。)
这些模型是在Blender中制作的,可以转换为.obj,.dae或 .js(JSON)(这是我当前使用的格式)。
如果没有这样的模块,可以导入模型并对照它们检查碰撞,我想我可以自己做。在这种情况下,请提供一些提示,或者进一步阅读如何测试点是否与某些顶点定义的对象发生碰撞。
编辑:“ map ”上将带有对象,例如树木和房屋。我在想,也许是山洞。它也将有山丘之类的东西,但是我猜不可能有一个高度图。
最佳答案
如果您要自己动手解决方案,建议您采取以下措施。
地形
优选地,地形为栅格,仅每个顶点的高度变化。结果是一堆四边形,每个四边形在(x,y)平面上具有相同的尺寸。顶点具有变化的(z)值以构成斜率。网格排列使您可以轻松确定在执行碰撞检查时必须测试哪些三角形以进行相交。
如果这不是一个选择(在建模程序包中预先构建的地形),则您可能仍要使用内存网格,并存储(部分地)在每个单元格内的三角形列表。
检查碰撞
最简单的方法是考虑您的 Actor 在太空中的位置。然后,您可以按照以下步骤确定该点的地形高度:
对于“纯网格”地形,步骤3仅涉及一次点/平面检查,以确定我们需要的2个三角形中的哪个。否则,您必须对每个三角形进行三角检查(您可能可以重复使用点/平面检查或使用BSP进行进一步优化)。
步骤4伪代码:
point = [ x, y, z ] // actor position
relativePt = point - triangle.vertices[0]
normal = triangle.plane.normal
distance = relativePt DOT normal // (this is a dot-product)
intersection = [
point.x,
point.y,
point.z + distance / normal.z ]
这将从角色位置开始向上/向下直接计算光线与三角形平面的交点。这就是(x,y)位置处的地形高度。然后,您可以简单地检查角色的位置是否低于该高度,如果是,则将其z坐标设置为地形高度。
物体(房屋,树木等)
为每个对象提供一个或多个大致与它的实际形状相对应的凸碰撞体积(请参见this page on UDN,以查看虚幻引擎如何与对象的碰撞 shell 一起使用)。
您将必须使用某种空间分割技术来快速确定在移动角色时要检查碰撞的所有世界对象中的哪一个。如果大多数运动是二维的(例如,仅地形和一些房屋),则可以使用简单的网格或quadtree(类似于带有更多分割的网格)。 3维选项将为octree。
空间分割的点与组织为网格的地形相同:将放置对象与空间中的单元/体积相关联,以便您可以确定要检查碰撞的对象集,而不是检查是否与所有对象发生碰撞。
检查碰撞
注意:在这种情况下,将角色的碰撞体积建模为盒子或3面圆柱体左右。
另外,您可能要考虑为每个对象构建BSP树,并为actor使用与轴对齐的边界框。但这已经超出了此答案的范围。如果您的对象将具有更复杂的碰撞体积,那将更快。
最后的想法
好吧,这已经是一个很长的答案,而这只是一些大招。碰撞是一个相当广泛的主题,因为您可以根据需要采用多种方法。
例如,我没有涉及“跟踪碰撞”,即当 Actor 移动时检测碰撞。相反,以上关于对象的建议将检查actor是否在对象内部。这可能会或可能不会满足您的需求。
我也刚刚意识到我还没有涉及actor vs vs actor碰撞。最好的做法是在(x,y)平面上碰撞2个圆,并另外检查其垂直空间是否相交。
无论如何,我真的要把它包起来。希望这至少可以为您指明正确的方向。
关于javascript - Node.js服务器上的3D模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10829429/