0
votes

I'm using Three.js and PointerLockControls.js. I'd like to attach a quasy bounding box to my camera. I want to develop a scene in which when I go near / or collide with a given object (when the camera collides with it) I want to be able to detect it, and handle the collision somehow. My first thought was to create a new Mesh, give it a transparent material and move it the same way as I do with the camera, but this does not really work because after a little while my Mesh will start moving in a different direction than my camera for some reason (in the code below this cameraBox is of red color). This is the way I create the camera and the Mesh:

    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    controls = new THREE.PointerLockControls(camera);

    scene.add(controls.getObject());

    controls.getObject().position.set(20, 30, 20);

    var cameraBox = new THREE.Mesh(
            new THREE.BoxGeometry(20, 30, 20),
            new THREE.MeshBasicMaterial({color: 0xff0000})
    );

    cameraBox.position.set(20, 30, 20);
    scene.add(cameraBox);

This is my render function:

        function render() {
            var delta = clock.getDelta();
            if (controlsEnabled) {
                velocity.x -= velocity.x * 10.0 * delta;
                velocity.z -= velocity.z * 10.0 * delta;
                velocity.y -= 9.8 * 100.0 * delta; // 100.0 = mass

                if (moveForward) velocity.z -= 200.0 * delta;
                if (moveBackward) velocity.z += 200.0 * delta;
                if (moveLeft) velocity.x -= 200.0 * delta;
                if (moveRight) velocity.x += 200.0 * delta;

                controls.getObject().translateX(velocity.x * delta);
                controls.getObject().translateY(velocity.y * delta);
                controls.getObject().translateZ(velocity.z * delta);

                cameraBox.translateX(velocity.x * delta);
                cameraBox.translateY(velocity.y * delta);
                cameraBox.translateZ(velocity.z * delta);

                if (controls.getObject().position.y < 30) {
                    velocity.y = 0;
                    controls.getObject().position.y = 30;
                    canJump = true;
                }

                if (cameraBox.position.y < 30) {
                    velocity.y = 0;
                    cameraBox.position.y = 30;
                    canJump = true;
                }
            }

            requestAnimationFrame(render);
            webGLRenderer.render(scene, camera);
        }

I wrote my own method to get an object's (rather Mesh's) bounding box, because I find the computeBoundingBox() method rather confusing. It seems it won't take the Mesh's current position into account. I pass the dimensions object with the help of a Mesh's geometry property.

function getBoundingBox(position, dimensions) {
    return {
        minX: position.x,
        maxX: position.x + dimensions.width,
        minY: position.y,
        maxY: position.y + dimensions.height,
        minZ: position.z,
        maxZ: position.z + dimensions.depth
    };
}

The other idea I had is to use the controls.getObject().position coordinates which would give me the camera's position (?) but those coordinates are, again, weird and do not seem to be the same as if I get a Mesh's position. Thanks in advance!

1

1 Answers

0
votes

You can create a bounding box from an object and detect a collision with the camera like this:

var boundingBox = new THREE.Box3().fromObject( object );
var collision = boundingBox.containsPoint( camera.position );

collision is true if the camera intersects with the bounding box.