使用Raycaster进行Three.js碰撞检测:IntersectObjects方法返回的交叉距离没有意义

时间:2014-11-23 21:50:16

标签: javascript three.js collision-detection collision raycasting

我正在制作一个简单的three.js游戏,其中用户控制一个名为playerModel的太空船(一个带有简单BoxGeometry的Mesh obj),并且必须避免在-Z方向远距离生成并进入的小行星(SphereGeometry)朝向船的+ Z方向。

这是我的detectCollisions函数:

// Returns true if playerModel is intersecting with 
// any of obstacles, false otherwise.
function detectCollisions(obstacles) {
    var origin = playerModel.position.clone();

    for (var v = 0; v < playerModel.geometry.vertices.length; v++) {       
        var localVertex = playerModel.geometry.vertices[v].clone();
        var globalVertex = localVertex.applyMatrix4(playerModel.matrix);
        var directionVector = globalVertex.sub(playerModel.position);

        var ray = new THREE.Raycaster(origin, directionVector.clone().normalize());
        var intersections = ray.intersectObjects(obstacles);
        if (intersections.length > 0 && 
            intersections[0].distance < directionVector.length()) {
            console.log("Fatal collision!");    // definitely a collision
            return true;
          }
    }
    return false;
}  

我在游戏循环中调用此方法如下,其中&#34; spheres&#34;是小行星的阵列:

function draw() {   
    // loop draw function call
    requestAnimationFrame(draw);
    // draw THREE.JS scene
    renderer.render(scene, camera);

    if (!isGameOver) {
        generateSpheres();
        handleKey();  // updates player direction
        movePlayer(); // moves player in direction
        moveSpheres();
        if (detectCollisions(spheres))
            gameOver();
    }
}

这是&#39;工作&#39;从某种意义上说,它检测到交叉点并在它执行时调用gameOver函数,但它检测到的视觉上甚至不接近碰撞的碰撞。 ray.intersectObjects方法似乎返回交叉点,其距离被计算得非常接近(类似于10),即使它与之相交的小行星对象的位置非常远(位置类似于:x:-872 y: -331 z:-5940)来自playerModel,位于(0,0,50)。

似乎导致致命碰撞的交叉小行星对象总是有faceIndex 37,不知道为什么。小行星是用环和段= = 7并且在20到150之间变化的半径创建的。玩家模型相当小(w:15,h:15,d:30)。非常感谢您的任何帮助!

1 个答案:

答案 0 :(得分:0)

也许它是BoundingSphere但是如果Object改变了大小(没有缩放),这只会是一个问题。

Object.Model.geometry.computeBoundingSphere();

BoundingSphere

但我不认为这是你问题的解决方案。你能上传一个jsfiddle吗?