Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/455.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Three.js-用于碰撞检测的精确光线投射_Javascript_Three.js_Collision Detection - Fatal编程技术网

Javascript Three.js-用于碰撞检测的精确光线投射

Javascript Three.js-用于碰撞检测的精确光线投射,javascript,three.js,collision-detection,Javascript,Three.js,Collision Detection,我正在使用Three.js,版本68。我使用的碰撞检测方法与这家伙在这里使用的方法相同,这在大多数情况下都很好(向作者说声“谢谢”): 如果您想从github下载源代码,这里有一个链接。只需查找冲突检测.html: 以下是对碰撞检测非常重要的代码: var MovingCube; var collidableMeshList = []; var wall = new THREE.Mesh(wallGeometry, wallMaterial); wall.position.set(100, 5

我正在使用Three.js,版本68。我使用的碰撞检测方法与这家伙在这里使用的方法相同,这在大多数情况下都很好(向作者说声“谢谢”):

如果您想从github下载源代码,这里有一个链接。只需查找冲突检测.html:

以下是对碰撞检测非常重要的代码:

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 ");
}
有人知道这种方法如何更准确吗另一个问题:是否有人知道以下if语句的目的,即为什么对象的距离必须小于方向向量的长度

if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() )
if(collisionResults.length>0&&collisionResults[0]。距离
首先回答最后一个问题:该行检测碰撞是否发生在MovingCube内部。光线投射代码从MovingCube的位置向其每个顶点投射光线。将返回光线与之相交的任何对象,以及与找到相交对象的MovingCube位置之间的距离(
collisionResults[0]。距离
)。该距离与移动立方体位置到相关顶点的距离进行比较。如果到碰撞的距离小于到顶点的距离,则碰撞发生在立方体内部

光线投射是一种较差的碰撞检测方法,因为它只检测光线投射的确切方向上的碰撞。它还有一些附加的边缘情况。例如,如果光线是从另一个对象内部投射的,则另一个对象可能不会被视为发生碰撞。另一个例子是,Three.js中的光线投射使用边界球体(或者,如果不可用,则使用边界框)来计算光线相交,因此光线可以与对象“相交”,即使它们在视觉上不会击中对象

如果只处理球体或直立长方体,那么检查碰撞是一个简单的数学问题。(这就是为什么Three.js使用边界球体和边界框的原因,而大多数需要进行碰撞检查的应用程序只使用次碰撞几何体,这些几何体没有渲染几何体复杂。)如果球体中心之间的距离小于其半径之和,则球体发生碰撞。如果边缘重叠,则框发生碰撞(例如,框1的左边缘在框2的右边缘的左侧,且框在垂直距离(其半高之和)和水平距离(其半长之和)内)

对于某些应用程序,您还可以使用体素,例如,将世界划分为立方体单位,进行长方体数学运算,并说如果两个对象与同一立方体单位重叠,则两个对象发生碰撞

对于更复杂的应用程序,您可能需要使用Ammo.js、Cannon.js或Physi.js之类的库

光线投射之所以吸引人,是因为它可以在不使用库的情况下处理更复杂的几何体。然而,正如您所发现的,它并不完美。:-)


我写了一本名为GameDevelopmentwithThree.js的书,深入探讨了这个主题。(我不会在这里链接到它,因为我不是来推广它的,但是如果你感兴趣的话,你可以用谷歌搜索。)这本书附带了一些示例代码,展示了如何进行基本的碰撞检测,包括3D捕获旗帜游戏的完整代码。

谢谢你的回答!我正在尝试使用three.js使边界框正常工作。基本上可以执行以下操作:
object.geometry.computeBoundingBox()//对象是三个。Mesh
var objectBoundingBox=object.geometry.boundingBox.clone()
然后您可以在另一个网格上执行相同的操作,并执行以下操作以查看它们是否相交:
如果(object.isIntersectionBox(otherObjectBoundingBox))
但是,这对我来说总是正确的!框3是边界框,来源在这里:知道我可能做错了什么吗?在我之前的评论if语句中犯了一个错误。应该是这样的:
if(objectBoundingBox.isIntersectionBox(otherObjectBoundingBox))
我只需控制台.log()您正在比较的框,并手动尝试isIntersectionBox源中的条件,看看您得到了什么结果,然后从中得到什么结果。下面是该边界框示例的一个JS摘要:。正如您所看到的,这些立方体彼此并不接近,但isIntersectionBox返回true。似乎边界框的计算是正确的。我不知道我能做些什么来让它永远是假的。好吧,看起来这篇文章很有效!:。感谢您使用边界框=)
if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() )