Three.js: 第一人称相机碰撞检测

Three.js: First person camera collision detection

我在 Three.js 中有一个非常简单的场景,用户可以在其中移动相机以获得第一人称视角。

相机不得在物体内部移动,例如一个立方体。我试图用 Raycaster.intersectObjects 来防止这种情况发生。但是,当我走进立方体时,只能识别立方体的一个面。似乎立方体的其他面不是 "visible" 射线,但当然它们是完美渲染的。

相关代码如下所示:

cubeGeometry = new THREE.CubeGeometry(size, size, size, 20, 20, 20);
cubeMesh = new THREE.Mesh(cubeGeometry, new THREE.MeshBasicMaterial({color: 0x00FF00, wireframe: true, side: THREE.DoubleSide}));
geometries.push(cubeMesh); 

...

var oldCamera;
function moveAround(){
    oldCamera = camera.clone();
    if(movement=="forward") camera.translateZ(-30);
    if(movement=="left") camera.translateX(-30);
    if(movement=="backward") camera.translateZ(30);
    if(movement=="right") camera.translateX(30);
    ray = new THREE.Raycaster(camera.position, oldCamera.position.normalize());
    ray.far = 100;
    if(ray.intersectObjects(geometries).length>0){
        // only the case with one of the faces of a cube
        ...

[编辑 2020.05.09]

我在 GitHub 上上传了一个工作示例:

https://github.com/TovAqulic/threejs_collision_issue/blob/master/index.html

您可以使用箭头键移动(相机,即您自己),也可以使用鼠标转动。

所有几何对象,即周围的墙和中间的方块,都是 geometries 数组的一部分,用 raycaster.intersectObjects(geometries) 检查。

在几乎所有情况下,如预期的那样,通过正面、向后或侧向运动移动到墙上时运动会受阻。

但是,有些位置你可以穿过墙壁,尤其是右边的墙壁。例如,加载页面后直接移动到右墙。

我不明白我做错了什么。

ray = new THREE.Raycaster(camera.position, oldCamera.position.normalize());

这段代码并不理想。创建 THREE.Raycaster 的实例一次,然后重新使用它。也将其命名为 raycaster(因为它不是 THREE.Ray 的实例)。此外,在调用 intersectObjects() 之前,请使用此代码准备 raycaster:

raycaster.ray.origin.copy( camera.position );
camera.getWorldDirection( raycaster.ray.direction );