Three.js碰撞检测

时间:2018-01-22 12:47:47

标签: javascript three.js collision-detection

我认为我遗漏了一些非常基本的东西,但我找不到答案,也找不到文档或其他工作代码。 我正在使用THREE.js库制作类似基本博物馆的东西。我已经设置了大部分内容,但我想让相机发生碰撞。我这样做了:

                var d = camera.position.distanceTo( plane_8.position );
            if ( d < 200 )
            {
                camera.position = previousPosition;
                camera.rotation = previousRotation;
            }

简单,但应该工作,至少在一面墙上。但事实并非如此。我忘记了什么? 完整代码:

    <html>
<head>
    <title>#10 - WebGL - Three.js</title>
    <style>canvas { width: 100%; height: 100% }</style>
</head>

<body>
    <script src="js/three.js"></script>
    <script src="js/THREEx.KeyboardState.js"></script>

    <script>  
        var keyboard = new THREEx.KeyboardState();
        var clock = new THREE.Clock();
        var scene = new THREE.Scene();
        var camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 4096 ); 
        var renderer = new THREE.WebGLRenderer({ antialias: true }); 

        renderer.setSize( window.innerWidth, window.innerHeight ); 

        document.body.appendChild( renderer.domElement ); 

        camera.position.set(0,0,1900); 
        scene.fog = new THREE.Fog( 0x555555, 2048, 4096 ); 

        //=================================================================

        var texture = THREE.ImageUtils.loadTexture('img/grass.jpg');
        texture.repeat.set( 7,7); 
        texture.wrapS = THREE.RepeatWrapping; 
        texture.wrapT = THREE.RepeatWrapping; 
        texture.anisotropy = 16; 

        var textureW = THREE.ImageUtils.loadTexture('img/Brickwall.jpg'); 
        textureW.repeat.set( 1,1); 
        textureW.wrapS = THREE.RepeatWrapping; 
        textureW.wrapT = THREE.RepeatWrapping; 
        textureW.anisotropy = 16;  
        var textureS = THREE.ImageUtils.loadTexture('img/styropian.jpeg'); 
        textureS.repeat.set( 1,1); 
        textureS.wrapS = THREE.RepeatWrapping;
        textureS.wrapT = THREE.RepeatWrapping; 
        textureS.anisotropy = 16; 

        //Mona Lisa
        var textureM = THREE.ImageUtils.loadTexture('img/MonaLisa.jpg'); 
        textureM.anisotropy = 16;  
        var planeMaterialM = new THREE.MeshPhongMaterial({map: textureM}); 
        var planeGeometryM = new THREE.PlaneGeometry(385, 577); 
        var planeM = new THREE.Mesh( planeGeometryM, planeMaterialM );
            planeM.position.x -= 500;
            planeM.position.z -= 1000;
        scene.add( planeM );
        var planeMaterial = new THREE.MeshPhongMaterial({map: texture}); 
        var planeGeometry = new THREE.PlaneGeometry(8192, 8192); 
        var plane = new THREE.Mesh( planeGeometry, planeMaterial );
            plane.rotation.x = - Math.PI / 2; 
            plane.position.y -= 512;
            plane.position.z -= 512;
        scene.add( plane ); 


        var planeMaterial_2 = new THREE.MeshPhongMaterial({color: 0x999999});  
        var planeGeometry_2= new THREE.CubeGeometry( 8192, 8, 4096 );
        var plane_2 = new THREE.Mesh( planeGeometry_2, planeMaterial_2 );
            plane_2.position.y += 512;
            plane_2.position.z += 1024;
            scene.add( plane_2 );   

        var planeMaterial_3 = new THREE.MeshPhongMaterial({map:textureW});  
        var planeGeometry_3= new THREE.CubeGeometry( 4096, 1024, 8 );
        var plane_3 = new THREE.Mesh( planeGeometry_3, planeMaterial_3 );
            plane_3.position.z -= 1024;
            scene.add( plane_3 );

        var planeMaterial_4 = new THREE.MeshPhongMaterial({map:textureW});  
        var planeGeometry_4= new THREE.CubeGeometry( 60,1024,2048 );
        var plane_4 = new THREE.Mesh( planeGeometry_4, planeMaterial_4 );
            plane_4.position.x -= 2048;
            scene.add( plane_4 );
        var plane_5 = new THREE.Mesh( planeGeometry_4, planeMaterial_4 );
            plane_5.position.x -= 1024;
            scene.add( plane_5);
        var plane_6 = new THREE.Mesh( planeGeometry_4, planeMaterial_4 );
            plane_6.position.x -= 0;
            scene.add( plane_6);
        var plane_7 = new THREE.Mesh( planeGeometry_4, planeMaterial_4 );
            plane_7.position.x += 1024;
            scene.add( plane_7);
        var plane_8 = new THREE.Mesh( planeGeometry_4, planeMaterial_4 );
            plane_8.position.x += 2048;
            scene.add( plane_8);    

        var planeMaterial_C = new THREE.MeshPhongMaterial({map:textureW});  
        var planeGeometry_C= new THREE.CubeGeometry( 5120, 1024, 60 );
        var plane_C = new THREE.Mesh( planeGeometry_C, planeMaterial_C );
            plane_C.position.z =+ 2048;
            plane_C.position.x =+ 512;
            scene.add( plane_C );

            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, -100, 1900);
scene.add( MovingCube );





        var light = new THREE.AmbientLight( 0x101020 );
            scene.add(light);

        var pointLight = new THREE.PointLight( 0xffffff, 1, 2048 );
            pointLight.position.set( -512, 0, -512 );
            scene.add( pointLight );            
        var pointLight2 = new THREE.PointLight( 0xffffff, 1, 3000 );
            pointLight2.position.set( 0, 0, 1536 );
            scene.add( pointLight2 );            
        var pointLight3 = new THREE.PointLight( 0xffffff, 1, 2048 );
            pointLight3.position.set( 512, 0, -512 ); 
            scene.add( pointLight3 );           
        var kat=0;
        var katL=0;

        function render() {     
            requestAnimationFrame(render);
            kat += 0.02; 
            katL += 0.07;

            var delta = clock.getDelta();
            var moveDistance = 700 * delta; 
            var rotateAngle = Math.PI / 3.5 * delta; 
            var previousPosition = camera.position.clone();
            var previousRotation = camera.rotation.clone();

                if ( keyboard.pressed("W") )
                    camera.translateZ( -moveDistance );
                if ( keyboard.pressed("S") )
                    camera.translateZ(  moveDistance );
                if ( keyboard.pressed("Q") )
                    camera.translateX( -moveDistance );
                if ( keyboard.pressed("E") )
                    camera.translateX(  moveDistance ); 
if ( keyboard.pressed("A") )
    camera.rotateOnAxis( new THREE.Vector3(0,1,0), rotateAngle);
if ( keyboard.pressed("D") )
    camera.rotateOnAxis( new THREE.Vector3(0,1,0), -rotateAngle);

        var d = camera.position.distanceTo( plane_8.position );
            if ( d < 200 )
            {
                camera.position = previousPosition;
                camera.rotation = previousRotation;
            }


            renderer.render(scene, camera);

        }



                render();       


    </script>
</body>

1 个答案:

答案 0 :(得分:0)

我目前正在为我的项目开发冲突。尝试使用光线投射。我的播放器(我可以通过WSAD和鼠标控制)发射光线投射并检查它们是否击中任何物体。

部分代码:

this.update = function (timestamp) {

    if (!this.enabled) return;


    if (this.hitTest) {
        this.doHitTest();
    }

    camera.quaternion.multiplyQuaternions(this.angleQuaternion, camera.quaternion);
    setFromQuaternionYComponent(this.object.quaternion, camera.quaternion);

    var delta = (timestamp - lastTimestamp) / 1000;
    lastTimestamp = timestamp;
    var actualMoveSpeed = delta * this.movementSpeed;

    if (this.moveForward && !lockMoveForward) this.object.translateZ(-actualMoveSpeed);
    if (this.moveBackward && !lockMoveBackward) this.object.translateZ(actualMoveSpeed);

    if (this.moveLeft && !lockMoveLeft) this.object.translateX(-actualMoveSpeed);
    if (this.moveRight && !lockMoveRight) this.object.translateX(actualMoveSpeed);

    if (this.verticalMovement && this.moveUp) this.object.translateY(actualMoveSpeed);
    if (this.verticalMovement && this.moveDown) this.object.translateY(-actualMoveSpeed);

    var hasPosition = this.sensor && this.sensor.getState().hasPosition;
    var vrCameraPosition;
    if (hasPosition) {
        vrCameraPosition = camera.position.clone();
        vrCameraPosition.applyQuaternion(this.angleQuaternion);
    }
    if (hasPosition) {
        camera.position.add(vrCameraPosition);
    } else {
        //camera.position.copy(this.object.position);
        camera.position.set(this.object.position.x, camera.position.y, this.object.position.z);
    }
};

this.doHitTest = function () {
    this.unlockAllDirections();
    var hitObjects = [];
    var cameraDirection = this.getDirection2(new THREE.Vector3(0, 0, 0)).clone();
    for (var i = 0; i < 4; i++) {
        // Applying rotation for each direction:
        var direction = cameraDirection.clone();
        direction.applyMatrix4(rotationMatrices[i]);

        var rayCaster = new THREE.Raycaster(camera.position, direction);
        var intersects = rayCaster.intersectObjects(this.hitMeshesArray, true);
        if ((intersects.length > 0 && intersects[0].distance < hitTestDistance)) {
            this.lockDirectionByIndex(i);
            hitObjects.push(intersects[0]);
            // console.log(intersects[0].object.name, i);
        }
    }

    return hitObjects;
};


this.getDirection2 = function (v) {

    var direction = new THREE.Vector3(0, 0, -1);
    var rotation = new THREE.Euler(0, 0, 0, "YXZ");

    var rx = camera.rotation.x;

    var ry = camera.rotation.y;

    // console.log("DIRECTION:", this);
    rotation.set(rx, ry, 0);
    v.copy(direction).applyEuler(rotation);
    // console.log(v);
    return v;
};

尝试将所有内容放在jsbin或simillar上,以便我们检查它。