我正在使用版本为68的Three.js。我的碰撞检测方法与这位作者在此处使用的相同,大多数情况下非常好用(向作者致以最大的感谢!):http://stemkoski.github.io/Three.js/Collision-Detection.html
如果您想从github下载源代码,请点击以下链接,查找Collision-Detection.html:https://github.com/stemkoski/stemkoski.github.com
以下是与碰撞检测相关的代码:
这通常很有效,但有时我会将立方体部分地移入墙壁中,却不会注册碰撞。例如,看看这张图片:
在左上角应该显示“命中”,但没有。
注意:我也尝试了他的建议并进行了以下操作,但似乎帮助不大。
var MovingCube;
var collidableMeshList = [];
var wall = new THREE.Mesh(wallGeometry, wallMaterial);
wall.position.set(100, 50, -100);
scene.add(wall);
collidableMeshList.push(wall);
var wall = new THREE.Mesh(wallGeometry, wireMaterial);
wall.position.set(100, 50, -100);
scene.add(wall);
var wall2 = new THREE.Mesh(wallGeometry, wallMaterial);
wall2.position.set(-150, 50, 0);
wall2.rotation.y = 3.14159 / 2;
scene.add(wall2);
collidableMeshList.push(wall2);
var wall2 = new THREE.Mesh(wallGeometry, wireMaterial);
wall2.position.set(-150, 50, 0);
wall2.rotation.y = 3.14159 / 2;
scene.add(wall2);
var cubeGeometry = new THREE.CubeGeometry(50,50,50,1,1,1);
var wireMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe:true } );
MovingCube = new THREE.Mesh( cubeGeometry, wireMaterial );
MovingCube.position.set(0, 25.1, 0);
// collision detection:
// determines if any of the rays from the cube's origin to each vertex
// intersects any face of a mesh in the array of target meshes
// for increased collision accuracy, add more vertices to the cube;
// for example, new THREE.CubeGeometry( 64, 64, 64, 8, 8, 8, wireMaterial )
// HOWEVER: when the origin of the ray is within the target mesh, collisions do not occur
var originPoint = MovingCube.position.clone();
for (var vertexIndex = 0; vertexIndex < MovingCube.geometry.vertices.length; vertexIndex++)
{
var localVertex = MovingCube.geometry.vertices[vertexIndex].clone();
var globalVertex = localVertex.applyMatrix4( MovingCube.matrix );
var directionVector = globalVertex.sub( MovingCube.position );
var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize() );
var collisionResults = ray.intersectObjects( collidableMeshList );
if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() )
appendText(" Hit ");
}
这通常很有效,但有时我会将立方体部分地移入墙壁中,却不会注册碰撞。例如,看看这张图片:
![Collision Detection](https://istack.dev59.com/ztGpo.webp)
THREE.BoxGeometry( 64, 64, 64, 8, 8, 8, wireMaterial ) // BoxGeometry is used in version 68 instead of CubeGeometry
有人知道如何使这个方法更精确吗?另一个问题:有人知道以下if语句是用于什么的,即为什么对象的距离必须小于方向向量的长度吗?
if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() )
object.geometry.computeBoundingBox(); //object is THREE.Mesh
var objectBoundingBox = object.geometry.boundingBox.clone();
然后,您可以在另一个网格上执行相同的操作,并执行以下操作以查看它们是否相交:if (object.isIntersectionBox(otherObjectBoundingBox))
但是,对于我来说,这总是正确的!Box3是边界框,源代码在此处:链接您有什么想法我可能做错了什么? - Programmer_Dif (objectBoundingBox.isIntersectionBox(otherObjectBoundingBox))
。 - Programmer_D