Node.js服务器上的3D模型

我正在做一个3D游戏, 在这里和这里我被告知应该总是在服务器端执行碰撞检测。 现在,问题是,我不知道如何! 在平面上的玩家之间的碰撞很容易,因为玩家是用一个圆柱体表示的,但是当地图本身是一个带有小丘的模型等等时,我该如何进行碰撞检测呢? 有可能以某种方式导入Node.js服务器上的3D模型? 然后说,我有模型导入,是否有一些碰撞检测库,或者我必须自己做math? (我最后的手段是将模型转换为JSON (模型已经转换为JSON),然后读取所有的顶点,但这将是一个痛苦。)

模型是在Blender中制作的,可以转换为.obj,.dae或.js(JSON) (这是我目前使用的)。

如果没有这样的模块,那么模型就可以导入并且碰撞被检查,我想我可以自己做。 在这种情况下,请提供一些提示,或者进一步阅读如何testing某个点是否与某些顶点定义的对象发生碰撞。

编辑: “地图”将有树木和房屋的对象。 我在想,甚至可能是洞穴。 它也将有山和什么不,但一个高度图是不可能的,我想。

如果你想要一个自己动手的解决scheme,我会build议如下。

地形

最好是地形是一个网格,每个顶点只有高度不同。 结果是一堆四边形,每个在(x,y)平面上具有相同的尺寸。 顶点有不同的(z)值来组成斜率。 网格布置允许您轻松确定在执行碰撞检查时您将不得不testing哪些三angular形进行交叉testing。

如果这不是一个选项(在build模包中预先构build的地形),那么您可能会想要使用内存中的网格,并存储(部分)在每个单元格内的三angular形列表。

检查碰撞

最简单的方法是考虑你的演员在太空中的点。 那么你会确定在这一点的地形的高度如下:

  1. 确定点位于的网格单元格
  2. 获取与单元格相关的三angular形
  3. 获取包含点的三angular形(在(x,y)平面中)
  4. 获得三angular形/飞机的高度点

在“纯网格”地形的情况下,步骤3只涉及单点/平面检查以确定我们需要的两个三angular形中的哪一个。 否则,您必须为每个三angular形做一个三angular形点检查(您可以重新使用点/平面检查或使用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 ] 

这将计算从演员位置向上/向下直线与三angular形平面的交点。 这就是(x,y)位置的地形高度。 那么你可以简单地检查一下演员的位置是否在这个高度以下,如果是的话,把它的z坐标设置为地形的高度。

物体(房屋,树木…)

为每个对象提供一个或多个与其实际形状大体一致的凸面碰撞体(请参阅UDN上的此页面,了解虚幻引擎如何与碰撞体一起使用对象)。

移动演员时,您将不得不使用一些空间细分技术来快速确定要检查碰撞的所有世界物体中的哪一个。 如果大多数运动是二维的(例如,只是地形和一些房屋),你可以使用一个简单的网格或四叉树 (就像是一个有更多细分的网格)。 三维选项将是八叉树 。

空间细分的点与组织为网格的地形相同:要将空间中的地点对象与空间中的单元/体积相关联,以便可以确定要检查碰撞的对象集合,而不是检查与所有对象的碰撞。

检查碰撞

  1. 使用您使用的空间细分技术获取“潜在的碰撞对象”; fe得到演员当前网格单元中的对象。
  2. 对于每个对象的每个凸面碰撞体积:
  3. 使用分离轴定理 ,确定主angular是否与碰撞体积相交。 看到我的回答不同的职位的一些实施提示(这个问题是关于二维情况,但代码很大程度上适用,只读“边”为“平面”)。
  4. 如果发生碰撞,请使用其中一个“违规飞机”的法线将演员移动到该飞机旁边。

注意:在这种情况下,您的演员的碰撞体积为一个盒子或三面圆柱左右。

此外,您可能需要考虑为每个对象构build一个BSP树,并为您的演员使用轴alignment的边界框。 但是这超出了这个答案的范围。 如果你的物体会有更复杂的碰撞体积,那会更快。

最后的想法

那么这已经是一个很长的回答了,这只是一些宽泛的描述。 碰撞是一个相当广泛的话题,因为有很多不同的方法可以根据你的需要采取。

例如,我没有涉及演员动作时检测到碰撞的“追踪碰撞”。 相反,上面关于对象的build议检查一个actor是否在一个对象中。 这可能会或可能不适合您的需求。

我也刚刚意识到我没有涉及演员对演员的碰撞。 也许这最好的办法是在(x,y)平面上碰撞2个圆圈,并检查其垂直空间是否相交。

无论如何,我真的要把这个包起来。 希望这至less能指出你正确的方向。