Three.js精确地形碰撞

3
我一直在使用WebGL库Three.js开发游戏引擎。我已经实现了基本的地形碰撞,可以找到用户所站立的面。使用面顶点的平均或最大Y位置是不够的。
有什么公式可以用来找到物体相对于所“站立”的地形面的确切Y位置?假设我知道面的四个顶点位置和物体的向量位置。
平面是一个THREE.PlaneGeometry(2000,2000,128,128),由高度图增强。上面的图片是其中一个面。

有一个 geometry.computeCentroids() 函数可以使用,然后使用面的质心。 - gaitat
我已经执行了geo.computeCentroids(),但问题是字符并不总是站在面的中心。 - Hobbes
既然你正在进行碰撞检测,我想你已经在发送射线了。当你成功找到一个面时,为什么不做射线与平面的交点计算来找到精确的位置呢?不知道three.js是否内置了这个功能。 - gaitat
我正在使用另一种方法来寻找脸部。射线投影的性能不如我所希望的那样好。无论如何,我只能找到一个脸。我需要知道我站在脸部哪个部位的精确y位置。由于这个面内没有顶点(只有在角落里),只能使用某种数学来推断这些数据,而我不知道是什么数学。 - Hobbes
2个回答

5

由于评论区无法放置代码,因此我将代码放在这里。 你不需要自己计算,让three.js来为你解决。你可以像下面这样做:

var plane = new THREE.Plane();
plane.setFromCoplanarPoints (v1, v2, v3);

// x, y, z: position of your object
var ray = new THREE.Ray (new THREE.Vector3(x, y, z), new THREE.Vector3(0, 1, 0));
var where = ray.intersectPlane (plane);

并且从Vector3的“where”中使用y分量来改变您对象的位置。


v1、v2、v3 对应于您的图像中的顶点。代码中的“plane”与 planeGeometry 无关。而 ray.intersectPlane 不接受网格。请查看手册。 - gaitat
我不确定在不知道使用THREE.Plane对象创建的平面是否可以像THREE.PlaneGeometry一样被细分和位移,以及使用planeIntercept()返回精确交点的向量而不仅仅是它所击中的平面的几何数据的情况下,是否应该重新设计代码。我知道interceptObjects()返回网格、几何数据、距离和其他一些信息,但不返回精确的交点,这在这里行不通,因为用户可能(并经常)处于顶点之间。 - Hobbes
1
你只需要创建交点的平面,不要多做其他事情。当你有了v1、v2、v3向量后,创建它,进行交点运算,然后丢弃它。 - gaitat
好的,与其在每一帧创建飞机,我现在为每次检测重复使用同一个飞机,并重新定位它。移动现在需要1毫秒而不是0毫秒,这对我来说可以接受。这种方法并不完美,但比以前好多了。我的角色不再漂浮在面的最大顶点位置上 =] 偶尔当我在陡峭的上坡/下坡时移动我的脚会沉入表面以下,但还是谢谢。投票支持。 - Hobbes
很好,这个效果相当不错。测试两个向量组都返回一个值,所以我只需要取最大值即可。在陡峭的斜坡上,我的脚还是有点埋在地下,但要解决这个问题,我需要调整模型的x/z旋转,而我不确定是否想这样做,因为攀登山峰的人并不垂直于表面(在卡通中有时候会)。我想知道我是否正确分配了向量。我正在做v1 = face.a,v2 = face.b,v3 = face.c,v4 = face.d。 - Hobbes
显示剩余7条评论

1

你可以轻松找到你的物体所站在的表面高度。

const down = new THREE.Vector3(0, -1, 0);
const raycaster = new THREE.Raycaster();

raycaster.set(obj.position, down);
const collisionResults = raycaster.intersectObject(terrain);

if (collisionResults.length > 0 && collisionResults[0].distance > 0)
   const pointHeight = collisionResults[0].point.y;

此时,只需从对象的y坐标中减去pointHeight,即可得到相对高度。

const relativeHeight = obj.position.y - pointHeight;

虽然这绝对是最容易实现的方法,但有一个警告。例如,我的地形大约有30K个多边形,使用这种方法比Gaitat的答案慢得多。 - Hobbes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接