我正在使用three.js。如何检测three.js中的碰撞?
我的场景中有两个网格几何图形。
如果这些几何图形相交(或者如果已转换则与相交),我想将其检测为碰撞。
如何执行three.js的碰撞检测?如果three.js没有碰撞检测设施,是否还有其他库可能会与three.js结合使用?
我正在使用three.js。如何检测three.js中的碰撞?
我的场景中有两个网格几何图形。
如果这些几何图形相交(或者如果已转换则与相交),我想将其检测为碰撞。
如何执行three.js的碰撞检测?如果three.js没有碰撞检测设施,是否还有其他库可能会与three.js结合使用?
在Three.js中,utili CollisionUtils.js和Collisions.js似乎不再受支持,而mrdoob(three.js的创建者)自己建议更新到three.js的最新版本,并将Ray类用于此目的。接下来是解决这个问题的方法之一。
想法是这样的:假设我们想要检查一个名为“Player”的给定网格是否与包含在名为“collidableMeshList”的数组中的任何网格相交。我们可以做的是创建一系列从玩家网格坐标开始的射线(Player.position),并向玩家网格几何中的每个顶点延伸。每个Ray都有一个名为“intersectObjects”的方法,该方法返回Ray相交的对象数组,以及与这些对象中每个对象的距离(从Ray的原点开始测量)。如果与交叉点的距离小于玩家位置与几何顶点之间的距离,则碰撞发生在玩家网格的内部 - 我们可能称之为“实际”碰撞。
我已经张贴在一个工作示例:
http://stemkoski.github.io/Three.js/Collision-Detection.html
您可以移动红色线框立方体用箭头键并用W/A/S/d旋转。当它与蓝色立方体中的一个相交时,如上所述,对于每个交叉点,屏幕顶部将出现一次“击中”一词。代码的重要部分如下。
for (var vertexIndex = 0; vertexIndex < Player.geometry.vertices.length; vertexIndex++)
{
var localVertex = Player.geometry.vertices[vertexIndex].clone();
var globalVertex = Player.matrix.multiplyVector3(localVertex);
var directionVector = globalVertex.subSelf(Player.position);
var ray = new THREE.Ray(Player.position, directionVector.clone().normalize());
var collisionResults = ray.intersectObjects(collidableMeshList);
if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length())
{
// a collision occurred... do something...
}
}
这种方法有两个潜在的问题。 (1)当射线的原点位于网格M内时,射线与M之间不会有碰撞结果返回。 (2)对于一个小的物体(与玩家网格有关)可能在各种射线之间“滑动”,因此不会记录碰撞。减少此问题发生的两种可能方法是编写代码,使小对象创建光线并从其角度进行碰撞检测,或者在网格中包含更多顶点(例如,使用CubeGeometry(100,100,100, 20,20,20)而不是CubeGeometry(100,100,100,1,1,1)。)后一种方法可能会导致性能下降,所以我建议少用一下。
我希望其他人会用这个问题的解决方案来解决这个问题。在开发这里描述的解决方案之前,我自己努力了很长一段时间。
谢谢您的详细解释!我还在努力寻找一个体面的解决方案,为我的游戏提供地形和3D对象,而你的回答给了我一些新的见解! – Nick 2012-08-25 13:13:31
虽然此方法似乎测试是否有任何顶点与俯仰的中心相交,但测试所有边(连接的顶点)时速度会慢两倍,但精度为100%(?)。因此,要详细说明,您需要遍历每个面,并使顶点[n]和顶点[(n + 1)%len]得到所有边。如果我拥抱某人,他们会交叉我的位置和我的手的中心,但它们不会与我的皮肤相交,因为边缘检查会进行测试。 – Funkodebat 2013-08-10 03:59:28
这是个好主意!对于100%(?)精度,我认为您需要测试两个网格中的每一个的边缘,并且您需要测试它们在两个方向上的走向,因为碰撞只能在一个方向上检测到,当射线从外部到网格的内部。确定它可能会慢一些,但是你可以通过初步的边界球半径检查来加速它。但最重要的是,我认为你的准确率可能达到100%...... – 2013-08-10 20:30:38
这实在是过于宽泛的一个话题在SO问题覆盖,但对于润滑网站的SEO一点的缘故,这里有几个简单的出发点:
如果你想真的简单的碰撞检测,而不是一个完整的物理引擎,然后检查了Three.js: Simple Collision Detection
如果,你想一些碰撞响应另一方面,不只是“做了A和B撞?”,看看Physijs,这是一个超级易于使用的Ammo.js包装Three.js周围
您链接的demo是ray collision – eqiproo 2012-07-13 18:40:18
关于如何做一些与碰撞检测一样广泛的单线问题不是真正的问题,而是一个学习主题。 Google是你的朋友。 – Nate 2012-07-13 15:44:46
我在谷歌搜索它,但我只发现了射线碰撞。 – eqiproo 2012-07-13 15:56:21
我认为射线碰撞是要走的路... Adnan(大概)引用的CollisionUtils.js和Collisions.js文件已过时,并且不属于最近的(本文撰写时为v49)三。 js版本。 – 2012-07-13 19:14:26