在ammo.js中使用“ vector.applyQuaternion”或类似的名称

时间:2019-10-21 10:09:25

标签: javascript three.js webvr rigid-bodies ammo.js

我想制作一个浏览器VR射击游戏,使用Three.js和Ammo.js进行物理和刚体设计。设置了VR头和控制器,模型已加载,但子弹不会像我想要的那样从枪上射出。当我尝试仅使用Three.js在场景中没有僵尸来做同样的事情时,我使用Three.js文档中的“ vector.applyQuaternion”,并且奏效了,子弹是从枪顶发射的。问题是我找不到与使用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轴上移动。如果我在x轴上移动控制器,则bullet2的速度会发生变化,而子弹仅在z轴上移动。 bullet1的项目符号跟随x,y,z轴上的运动,但不跟随控制器的旋转。 “ bullet2.userData.physicsBody.applyQuaternion(controller2.quaternion);”这行是注释,如果我删除这些小节,则会收到此错误“ TypeError:bullet2.userData.physicsBody.applyQuaternion不是函数”。我原本希望在没有弹药(userData.velocity.applyQuaternion)的情况下能做与上一个示例相同的操作,但是ammo.js中没有LinearVelocity,我只能使用getLinearVelocity和setLinearVelocity。

1 个答案:

答案 0 :(得分:0)

基于我见过的弹药版本,您对setLinearVelocity()的调用不正确。 btVector3构造函数必须仅使用x,y,z。使用ThreeJS数学对其进行计算,类似于在其他地方进行的操作(选择幅度并通过控制器的四元数旋转vector3)。也许可以解决您的问题。

注意:我质疑为什么需要对子弹进行物理模拟。大多数射击游戏都不这样做。方便快捷地是在检查是否拦截玩家/墙壁时直观地更新进度。如果需要重力效果,请在每帧上应用小的垂直下落。如果您想弹跳,请使用截距曲面的法线更改速度。弹药引擎非常适合手榴弹弹跳(复杂,不可预测的相互作用)之类的东西。