Используйте "vector.applyQuaternion" или аналогичный в ammo.js - PullRequest
0 голосов
/ 21 октября 2019

Я хочу сделать браузерную VR-игру с использованием Three.js и Ammo.js для физики и твердых тел. Голова vr и контроллеры настроены, модели загружены, но пули не будут стрелять из пистолета, как я хочу. Когда я попытался сделать то же самое, используя только Three.js без жестких тел в сцене, я использовал «vector.applyQuaternion» из документации Three.js, и это сработало, пули были выпущены сверху пистолета. Проблема в том, что я не нашел ничего похожего для использования кода ammo.js

без использования кода ammo.js

       ...  function handleController( controller ) {

               if ( controller1.userData.isSelecting ) {



                bullet1.position.set( controller1.position.x , controller1.position.y + 0.018 , controller1.position.z -0.01);
                bullet1.userData.velocity.x = 0;
                bullet1.userData.velocity.y = 10;
                bullet1.userData.velocity.z = 10;
                bullet1.userData.velocity.applyQuaternion( controller1.quaternion );
                scene.add(bullet1);



               }

                if ( controller2.userData.isSelecting ) {

                bullet2.position.set( controller2.position.x  , controller2.position.y + 0.018 , controller2.position.z -0.01 );
                bullet2.userData.velocity.x = 0;
                bullet2.userData.velocity.y = 10;
                bullet2.userData.velocity.z = 10;
                bullet2.userData.velocity.applyQuaternion( controller2.quaternion );
                scene.add(bullet2);


               }

          } ...

        function render() {
            handleController( controller1 );
            handleController( controller2 );

            var delta = clock.getDelta()
            bullet1.position.x -= bullet1.userData.velocity.x *  delta;
            bullet1.position.y -= bullet1.userData.velocity.y *  delta;
            bullet1.position.z -= bullet1.userData.velocity.z *  delta;



            bullet2.position.x -= bullet2.userData.velocity.x *  delta;
            bullet2.position.y -= bullet2.userData.velocity.y *  delta;
            bullet2.position.z -= bullet2.userData.velocity.z *  delta;

            renderer.render( scene, camera ); 
        } 

с ammo.js

            function createBullet1RigidBody( threeObject, physicsShape, mass ) {
                //threeObject.position.copy( pos );
                //threeObject.quaternion.copy( quat1 );
                quat1.set( controller1.position.x, controller1.position.y , controller1.position.z , Math.PI/2 );
                pos1 = new THREE.Vector3 ( controller1.position.x, controller1.position.y , controller1.position.z  );
                var transform = new Ammo.btTransform();
                transform.setIdentity();
                transform.setOrigin( new Ammo.btVector3( controller1.position.x, controller1.position.y, controller1.position.z -0.5) );
                transform.setRotation( new Ammo.btQuaternion( quat1.x, quat1.y, quat1.z, quat1.w ) );
                var motionState = new Ammo.btDefaultMotionState( transform );
                var localInertia = new Ammo.btVector3( 0, 0, 0 );
                physicsShape.calculateLocalInertia( mass, localInertia );
                var rbInfo = new Ammo.btRigidBodyConstructionInfo( mass, motionState, physicsShape, localInertia );
                var body1 = new Ammo.btRigidBody( rbInfo );
                threeObject.userData.physicsBody = body1;
                scene.add( threeObject );
                if ( mass > 0 ) {
                    bullet1Bodies.push( threeObject );
                    // Disable deactivation
                    body1.setActivationState( 4 );
                }
                physicsWorld.addRigidBody( body1 );
                return body1;
            }


        function createBullet2RigidBody( threeObject, physicsShape, mass ) {
                //threeObject.position.copy( pos );
                //threeObject.quaternion.copy( quat2 );
                var transform = new Ammo.btTransform();
                transform.setIdentity();
                transform.setOrigin( new Ammo.btVector3( controller2.position.x, controller2.position.y, controller2.position.z -0.5 ) );
                transform.setRotation( new Ammo.btQuaternion( quat.x, quat.y, quat.z, quat.w ) );
                var motionState = new Ammo.btDefaultMotionState( transform );
                var localInertia = new Ammo.btVector3( 0, 0, 0 );
                physicsShape.calculateLocalInertia( mass, localInertia );
                var rbInfo = new Ammo.btRigidBodyConstructionInfo( mass, motionState, physicsShape, localInertia );
                var body2 = new Ammo.btRigidBody( rbInfo );
                threeObject.userData.physicsBody = body2;
                scene.add( threeObject );
                if ( mass > 0 ) {
                    bullet2Bodies.push( threeObject );
                    // Disable deactivation
                    body2.setActivationState( 4 );
                }
                physicsWorld.addRigidBody( body2 );
                return body2;
            }

 ...

    function handleController( controller ) {

            if ( controller1.userData.isSelecting ) {

            var bullet1Mass = 0.1;
            var bullet1Radius = 0.6;
            var bullet1 = new THREE.Mesh( geometry_bullet, new THREE.MeshLambertMaterial( { color: 0x2661b9 } ) );
            var bullet1Shape = new Ammo.btSphereShape ( bullet1Radius );

            bullet1Shape.setMargin ( margin );


            var bullet1_body = createBullet1RigidBody( bullet1, bullet1Shape, bullet1Mass, bullet1Radius );
            //bullet1.position.set( pos1.x, pos1.y, pos1.z );
            bullet1.userData.physicsBody.setFriction( 0 );
            bullet1_body.setLinearVelocity( new Ammo.btVector3( 100, 100, 100 , controller1.quaternion) );
            }

            if ( controller2.userData.isSelecting ) {


            var bullet2Mass = 0.1;
            var bullet2Radius = 0.6;
            var bullet2 = new THREE.Mesh( geometry_bullet, new THREE.MeshLambertMaterial( { color: 0xee2f2f } ) );
            var bullet2Shape = new Ammo.btSphereShape ( bullet2Radius );
            var pos2 = new THREE.Vector3 ( controller2.position.x, controller2.position.y + 10, controller2.position.z +10 );
            bullet2Shape.setMargin ( margin );

            //quat2.set( 0,0,0,1 );
            var bullet2_body = createBullet2RigidBody( bullet2, bullet2Shape, bullet2Mass, bullet2Radius, pos2, quat2 );
            //var pos2 = bullet2.position.set( controller2.position.x, controller2.position.y, controller2.position.z -0.1 );
            bullet2.userData.physicsBody.setFriction( 0 );
            bullet2_body.setLinearVelocity( new Ammo.btVector3( 0, 0, controller2.position.z *100 ) );
            //bullet2.userData.physicsBody.applyQuaternion(controller2.quaternion);
            }

        } 

В результате пули созданы, но они движутся только по оси Z. Скорость пули2 изменяется, если я перемещаю контроллер по оси x, а пули движутся только по оси z. Пули bullet1 следуют за движением по оси x, y, z, но не за вращением контроллера. "Bullet2.userData.physicsBody.applyQuaternion (controller2.quaternion);"строка является комментарием, если я удаляю бары, я получаю эту ошибку «Ошибка типа: bullet2.userData.physicsBody.applyQuaternion не является функцией». Я ожидал сделать то же самое, что и в предыдущем примере, без боеприпасов (userData.velocity.applyQuaternion), но в ammo.js нет LinearVelocity, я могу использовать только getLinearVelocity и setLinearVelocity.

...