首页 > 解决方案 > 将对象从 BoxBufferGeometry 更改为 BufferGeometry 时,弹药 js 中的 enableAngularMotor 似乎不起作用

问题描述

我正在使用 three.js 和 ammo.js 创建弹球游戏,并且在使用从加载的 GLTF 文件克隆的 bufferGeometry 时使用 enableAngularMotor 旋转鳍状肢时遇到问题,而使用 BoxBufferGeometry 的相同代码可以正常工作。

在最初的测试版本中,我有一个与铰链相连的 threejs BoxBufferGeometry 块,并且可以正常工作。我已经将代码转移到了 three.js 中 gltf 加载器上的加载回调,并且来自新的更好模型克隆的几何可以正常读取,但是相同的铰链接线代码似乎没有旋转鳍状肢。

                    var loader = new THREE.GLTFLoader();
                    let mass = ms;
                    loader.load(whichFile,function ( gltf ) {
                        gltf.animations; // Array<THREE.AnimationClip>
                        gltf.scene; // THREE.Scene
                        gltf.scenes; // Array<THREE.Scene>
                        gltf.cameras; // Array<THREE.Camera>
                        gltf.asset; // Object
                        gltf.scene.scale.set(Size[0],Size[1],Size[2]);
                        gltf.scene.position.set(Pos[0],Pos[1],Pos[2]);
                        gltf.asset.castShadow = true;
                        gltf.asset.receiveShadow = true;

                        gltf.scene.traverse(function (child) {
                            if (child.isMesh) {
                                child.castShadow = true;
                                child.receiveShadow = true;
                                let geometry = new THREE.Geometry().fromBufferGeometry( child.geometry );
                                let qCircX = new THREE.Mesh(geometry, child.material);
                                //scene.add(qCircX);
                                qCircX.scale.set(Size[0],Size[1],Size[2]);
                                qCircX.position.set(Pos[0],Pos[1],Pos[2]);
                                geometry.computeFaceNormals();
                                geometry.mergeVertices();
                                geometry.computeVertexNormals();
                                child.geometry = new THREE.BufferGeometry().fromGeometry( geometry );
                                let qCirc = new THREE.Mesh(child.geometry, child.material);
                                qCirc.scale.set(Size[0],Size[1],Size[2]);
                                qCirc.position.set(Pos[0],Pos[1],Pos[2]);
                                qCirc.castShadow = true;
                                qCirc.receiveShadow = true;
                                scene.add(qCirc);

                                let transform = new Ammo.btTransform();
                                transform.setIdentity();
                                transform.setOrigin( new Ammo.btVector3( Pos[0],Pos[1],Pos[2] ) );
                                let motionState = new Ammo.btDefaultMotionState( transform );
                                let vertices, face, triangles = [];

                                vertices = geometry.vertices;

                                vertices = generateVertexMesh(geometry, vertices, triangles);

                                let i, triangle, triangle_mesh = new Ammo.btTriangleMesh;
                                let _vec3_1 = new Ammo.btVector3(0,0,0);
                                let _vec3_2 = new Ammo.btVector3(0,0,0);
                                let _vec3_3 = new Ammo.btVector3(0,0,0);
                                for ( i = 0; i < triangles.length; i++ ) {
                                    triangle = triangles[i];
                                    _vec3_1.setX(triangle[0].x);
                                    _vec3_1.setY(triangle[0].y);
                                    _vec3_1.setZ(triangle[0].z);
                                    _vec3_2.setX(triangle[1].x);
                                    _vec3_2.setY(triangle[1].y);
                                    _vec3_2.setZ(triangle[1].z);
                                    _vec3_3.setX(triangle[2].x);
                                    _vec3_3.setY(triangle[2].y);
                                    _vec3_3.setZ(triangle[2].z);
                                    triangle_mesh.addTriangle(
                                        _vec3_1,
                                        _vec3_2,
                                        _vec3_3,
                                        true
                                    );
                                }
                                let colSurround = new Ammo.btBvhTriangleMeshShape( triangle_mesh, true, true );
                                let localInertia = new Ammo.btVector3( 0, 0, 0 );
                                colSurround.calculateLocalInertia( mass, localInertia );
                                let rbInfo = new Ammo.btRigidBodyConstructionInfo( mass, motionState, colSurround, localInertia );
                                let body = new Ammo.btRigidBody( rbInfo );
                                body.setRestitution(rest);
                                qCirc.userData.physicsBody = body;

                                qCirc.name = objName;

                                collidableMeshList.push(qCirc);

                                if(addToScoreColliders){
                                    scoreList.push(objName);
                                }

                                //console.log(ballArray);
                                if ( mass > 0 ) {
                                    rigidBodies.push( qCirc );
                                    //console.log(rigidBodies);
                                    body.setActivationState( 4 );
                                }
                                physicsWorld.addRigidBody( body );


                                if(objName == "flipperL"){
                                    let pos = {x:-16,y:0,z:27}, posBumper = {x:0,y:0,z:0}, scaleHinge = {x:1,y:1,z:1}, scaleBumper = {x:1,y:1,z:1}, quat = {x:0,y:0,z:0,w:1}, quatBumper = {x:0,y:0,z:0,w:1}, mass = 0, massBumper = 9;

                                    // create the hinge and bumper objects
                                    leftHinge = createPhysicsGeometry(0xff0000,pos,scaleHinge,quat,mass,"leftHinge",0,[0,0], true);

                                    // Hinge constraint to move the bumper
                                    let pivotA = new Ammo.btVector3( 0, 0.5, 0 ),pivotB = new Ammo.btVector3( -1.5, -3, 0 ),axis = new Ammo.btVector3( 0, 1, 0 );

                                    leftHingeConstraint = new Ammo.btHingeConstraint( leftHinge.userData.physicsBody, qCirc.userData.physicsBody, pivotA, pivotB, axis, axis, true );
                                    leftHingeConstraint.setLimit(0, Math.PI/2 * 0.5, 0.9, 0.3, 1);
                                    physicsWorld.addConstraint( leftHingeConstraint, true );
                                    leftHingeActive = true;
                                    bumperGeoms[0] = qCirc;
                                }

                                if(objName == "flipperR"){
                                    let pos = {x:16,y:0,z:27}, posBumper = {x:0,y:0,z:0}, scaleHinge = {x:1,y:1,z:1}, scaleBumper = {x:1,y:1,z:1}, quat = {x:0, y:0, z:0, w: 1},quatBumper = {x:0,y:0,z:0,w:1}, mass = 0, massBumper = 9;

                                    // create the hinge and bumper objects
                                    rightHinge = createPhysicsGeometry(0xff0000,pos,scaleHinge,quat,mass,"rightHinge",0,[0,0], true);

                                    // Hinge constraint to move the bumper
                                    let pivotA = new Ammo.btVector3( 0, 0.5, 0 ),pivotB = new Ammo.btVector3( 1.5, -3, 0 ),axis = new Ammo.btVector3( 0, 1, 0 );

                                    //console.log(bumperArray);

                                    rightHingeConstraint = new Ammo.btHingeConstraint( rightHinge.userData.physicsBody, qCirc.userData.physicsBody, pivotA, pivotB, axis, axis, true );
                                    rightHingeConstraint.setLimit(-Math.PI/2 * 0.5, 0, 0.9, 0.3, 1);
                                    physicsWorld.addConstraint( rightHingeConstraint, true );
                                    rightHingeActive = true;
                                    bumperGeoms[1] = qCirc;
                                }
                            }
                        });
                    },
                    // called while loading is progressing
                    function ( xhr ) {
                        console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
                    },
                    // called when loading has errors
                    function ( error ) {
                        console.log( 'An error happened : ' + error );
                    });
                }```

When an area of the screen is pressed, the angular motor is enabled with a multiplier to turn the flipper, whereas now the flipper doesn't rotate. I don't get any errors logging to the console, and logging geometry to check it's loaded ok is fine.

标签: javascriptgame-physicsammo.js

解决方案


好的,所以我采用了另一种方法,使 gltf 场景成为现有简单长方体鳍状肢的孩子。


推荐阅读