Three.js光线投射碰撞不起作用

时间:2019-07-08 20:25:12

标签: three.js collision-detection raycasting

我正在开发街机风格的Everest飞行模拟器。

在我构建此调试器的调试器中,我有一个terrain和直升飞机类,它们生成BufferGeometry地形网格物体,直升机停机坪几何形状的组以及直升飞机“相机和几何形状”的组。

我的问题是,目前我似乎无法检测到任何碰撞。我想它可能不支持BufferGeometries,所以这对我来说是个问题,因为我需要地形作为Buffer,因为它的范围太广了……作为标准几何,它会导致浏览器内存崩溃。

但是,仅测试直升机停机坪的几何形状仍然不会触发。它们在一个组中,因此我将这些组添加到全局窗口数组中,并将碰撞检查设置为递归但无济于事。

最终,我愿意接受其他形式的碰撞检测,并且可能需要两种类型,因为我拥有才能使用缓冲区几何。关于如何解决此问题或更好的解决方案的任何想法?

直升机对象本身

// Rect to Simulate Helicopter
const geometry = new THREE.BoxGeometry( 2, 1, 4 ),
      material = new THREE.MeshBasicMaterial(),
      rect = new THREE.Mesh( geometry, material );

rect.position.x = 0;
rect.position.y = terrain.returnCameraStartPosY();
rect.position.z = 0;
rect.rotation.order = "YXZ";
rect.name = "heli";

// Link Camera and Helicopter
const heliCam = new THREE.Group(),
      player = new Helicopter(heliCam, "OH-58 Kiowa", 14000);

heliCam.add(camera);
heliCam.add(rect);
heliCam.position.set( 0, 2040, -2000 );
heliCam.name = "heliCam";
scene.add(heliCam);

将对象添加到全局碰撞阵列

// Add Terrain
const terrain = new Terrain.ProceduralTerrain(),
      terrainObj = terrain.returnTerrainObj(),
      helipadEnd = new Terrain.Helipad( 0, 1200, -3600, "Finish", true ),
      helipadStart = new Terrain.Helipad( 0, 2000, -2000, "Start", false ),
      helipadObjStart = helipadStart.returnHelipadObj(),
      helipadObjEnd = helipadEnd.returnHelipadObj();

window.collidableMeshList.push(terrainObj);
window.collidableMeshList.push(helipadObjStart);
window.collidableMeshList.push(helipadObjEnd);

碰撞检测功能每帧运行一次

collisionDetection(){
    const playerOrigin = this.heli.children[1].clone(); // Get Box Mesh from Player Group

    for (let i = playerOrigin.geometry.vertices.length - 1; i >= 0; i--) {
        const localVertex      = playerOrigin.geometry.vertices[i].clone(),
              globalVertex     = localVertex.applyMatrix4( playerOrigin.matrix ),
              directionVector  = globalVertex.sub( playerOrigin.position ),
              ray              = new THREE.Raycaster( playerOrigin, directionVector.clone().normalize() ),
              collisionResults = ray.intersectObjects( window.collidableMeshList, true ); // Recursive Boolean for children

        if ( collisionResults.length > 0 ){
            this.landed = true;
            console.log("Collision");
        }

        // if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() ){
        //  this.landed = true;
        //  console.log("Collision with vectorLength")
        // }    
    }
}

1 个答案:

答案 0 :(得分:0)

很难说出自定义类中发生了什么,但是看起来您正在使用Object3D作为raycaster的第一个参数,而不是使用{{ 1}}。您为什么不尝试以下方法:

Vector3

此外,您确定要使用BufferGeometry吗?因为当您访问这样的顶点值:this.heli.children[1].clone()时,它应该给您一个错误。没有vertices attribute in a BufferGeometry,所以我不知道您如何确定方向向量。