Нельзя двигать твердое тело с помощью боеприпасов JS в ТРИ JS - PullRequest
0 голосов
/ 30 апреля 2020

Недавно начал работать над боеприпасами js, чтобы применить простую физику в игре, но я застрял в двух проблемах ...

  1. не могу двигать твердое тело
  2. тела не сталкиваются

, когда я перемещаю землю вместо коробки, она движется правильно, но не сталкивается с коробкой. также кто-то может объяснить мне, что такое границы столкновений, которые слишком важны для физики столкновений

код ...

        import * as THREE from "./Javascript/three.module.js"
        import Stats from './Javascript/three.js-master/examples/jsm/libs/stats.module.js';
        import { GUI } from './Javascript/three.js-master/examples/jsm/libs/dat.gui.module.js';
        import { OrbitControls } from './Javascript/three.js-master/examples/jsm/controls/OrbitControls.js';
        import { Water } from "./Javascript/three.js-master/examples/jsm/objects/Water.js";
        import { Sky } from './Javascript/three.js-master/examples/jsm/objects/Sky.js';

        var container, stats;
        var camera, scene, renderer, light;
        var controls, water, sphere;

        Ammo().then(start)

        let phy_world , tmpTrans , physicsWorld , clock , rigidBodies = [] , ball , blockPlane

        let moveDirection = { left: 0, right: 0, forward: 0, back: 0 }
        const STATE = { DISABLE_DEACTIVATION : 4 }
        const FLAGS = { CF_KINEMATIC_OBJECT: 2 }

        let kObject = null, 
        kMoveDirection = { left: 0, right: 0, forward: 0, back: 0 }, 
        tmpPos = new THREE.Vector3(), tmpQuat = new THREE.Quaternion();
        let ammoTmpPos = null, ammoTmpQuat = null;


        function start (){

            tmpTrans = new Ammo.btTransform();
            ammoTmpPos = new Ammo.btVector3();
            ammoTmpQuat = new Ammo.btQuaternion();


            init()
            animate()

            setupPhysicsWorld();

            setupGraphics();
            createBlock();
            createBall();

            renderFrame();

        }

        function setupPhysicsWorld(){

            let collisionConfiguration  = new Ammo.btDefaultCollisionConfiguration(),
                dispatcher              = new Ammo.btCollisionDispatcher(collisionConfiguration),
                overlappingPairCache    = new Ammo.btDbvtBroadphase(),
                solver                  = new Ammo.btSequentialImpulseConstraintSolver();

            physicsWorld           = new Ammo.btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
            physicsWorld.setGravity(new Ammo.btVector3(0, -10, 0));

        }


        function setupGraphics(){

            //create clock for timing
            clock = new THREE.Clock();
        }

        function init() {

            container = document.getElementById( 'container' );

            //

            renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            renderer.gammaInput = true;
            renderer.gammaOutput = true;

            renderer.shadowMap.enabled = true;
            container.appendChild( renderer.domElement );

            //

            scene = new THREE.Scene() // if i replace it to Physijs.Scene , Module shows error
            //

            camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 1, 20000 );
            camera.position.set( 30, 30, 100 );

            //

            light = new THREE.DirectionalLight( 0xffffff, 0.8 );
            scene.add( light );

            // Water

            var waterGeometry = new THREE.PlaneBufferGeometry( 10000, 10000 );

            water = new Water(
                waterGeometry,
                {
                    textureWidth: 512,
                    textureHeight: 512,
                    waterNormals: new THREE.TextureLoader().load( 'media/waternormals.jpg', function ( texture ) {

                        texture.wrapS = texture.wrapT = THREE.RepeatWrapping;

                    } ),
                    alpha: 1.0,
                    sunDirection: light.position.clone().normalize(),
                    sunColor: 0xffffff,
                    waterColor: 0x001e0f,
                    distortionScale: 3.7,
                    fog: scene.fog !== undefined
                }
            );

            water.rotation.x = - Math.PI / 2;
            water.scale.x = 1000000
            water.scale.y = 100000
            scene.add( water );

            // Skybox

            var sky = new Sky();

            var uniforms = sky.material.uniforms;

            uniforms[ 'turbidity' ].value = 10;
            uniforms[ 'rayleigh' ].value = 2;
            uniforms[ 'luminance' ].value = 1;
            uniforms[ 'mieCoefficient' ].value = 0.005;
            uniforms[ 'mieDirectionalG' ].value = 0.8;

            var parameters = {
                distance: 400,
                inclination: 0.2835,
                azimuth: 0.205
            };

            var cubeCamera = new THREE.CubeCamera( 0.1, 1, 512 );
            cubeCamera.renderTarget.texture.generateMipmaps = true;
            cubeCamera.renderTarget.texture.minFilter = THREE.LinearMipmapLinearFilter;

            scene.background = cubeCamera.renderTarget;

            function updateSun() {

                var theta = Math.PI * ( parameters.inclination - 0.5 );
                var phi = 2 * Math.PI * ( parameters.azimuth - 0.5 );

                light.position.x = parameters.distance * Math.cos( phi );
                light.position.y = parameters.distance * Math.sin( phi ) * Math.sin( theta );
                light.position.z = parameters.distance * Math.sin( phi ) * Math.cos( theta );

                sky.material.uniforms[ 'sunPosition' ].value = light.position.copy( light.position );
                water.material.uniforms[ 'sunDirection' ].value.copy( light.position ).normalize();

                cubeCamera.update( renderer, sky );

            }

            updateSun();

            //



            //

            controls = new OrbitControls( camera, renderer.domElement );
            controls.maxPolarAngle = Math.PI * 0.495;
            controls.target.set( 0, 0, 0 );
            controls.enablePan = false
            controls.enableZoom = false
            controls.minDistance = 40.0;
            controls.maxDistance = 200.0;
            controls.update();

            //

            stats = new Stats();
            container.appendChild( stats.dom );

            // GUI

            var gui = new GUI();

            var folder = gui.addFolder( 'Sky' );
            folder.add( parameters, 'inclination', 0, 0.5, 0.0001 ).onChange( updateSun );
            folder.add( parameters, 'azimuth', 0, 1, 0.0001 ).onChange( updateSun );
            folder.open();

            var uniforms = water.material.uniforms;

            var folder = gui.addFolder( 'Water' );
            folder.add( uniforms.distortionScale, 'value', 0, 8, 0.1 ).name( 'distortionScale' );
            folder.add( uniforms.size, 'value', 0.1, 10, 0.1 ).name( 'size' );
            folder.add( uniforms.alpha, 'value', 0.9, 1, .001 ).name( 'alpha' );
            folder.open();

            //

            window.addEventListener( 'resize', onWindowResize, false );

        }

        function onWindowResize() {

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

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

        }

        function animate() {

            requestAnimationFrame( animate );
            render();
            stats.update();

        }

        function render() {
            var time = performance.now() * 0.001;
            water.material.uniforms[ 'time' ].value += 1.0 / 60.0;
            renderer.render( scene, camera );
        }

        function createBlock(){

            let pos = {x: 0, y: 0, z: 0};
            let scale = {x: 50, y: 2, z: 50};
            let quat = {x: 0, y: 20, z: 0, w: 1};
            let mass = 0;

            //threeJS Section
            blockPlane = new THREE.Mesh(new THREE.BoxBufferGeometry(), new THREE.MeshPhongMaterial({color: 0xa0afa4}));

            blockPlane.position.set(pos.x, pos.y, pos.z);
            blockPlane.scale.set(scale.x, scale.y, scale.z);

            blockPlane.castShadow = true;
            blockPlane.receiveShadow = true;

            scene.add(blockPlane);


            //Ammojs Section
            let transform = new Ammo.btTransform();
            transform.setIdentity();
            transform.setOrigin( new Ammo.btVector3( pos.x, pos.y, pos.z ) );
            transform.setRotation( new Ammo.btQuaternion( quat.x, quat.y, quat.z, quat.w ) );
            let motionState = new Ammo.btDefaultMotionState( transform );

            let colShape = new Ammo.btBoxShape( new Ammo.btVector3( scale.x * 0.5, scale.y * 0.5, scale.z * 0.5 ) );
            colShape.setMargin( 0.05 );

            let localInertia = new Ammo.btVector3( 0, 0, 0 );
            colShape.calculateLocalInertia( mass, localInertia );

            let rbInfo = new Ammo.btRigidBodyConstructionInfo( mass, motionState, colShape, localInertia );
            let body = new Ammo.btRigidBody( rbInfo );


            physicsWorld.addRigidBody( body );
        }

        function renderFrame(){

            let deltaTime = clock.getDelta();

            updatePhysics( deltaTime );

            renderer.render( scene, camera );

            requestAnimationFrame( renderFrame );

        }

        function updatePhysics( deltaTime ){

            // Step world
            physicsWorld.stepSimulation( deltaTime, 10 );

            // Update rigid bodies
            for ( let i = 0; i < rigidBodies.length; i++ ) {
                let objThree = rigidBodies[ i ];
                let objAmmo = objThree.userData.physicsBody;
                let ms = objAmmo.getMotionState();
                if ( ms ) {

                    ms.getWorldTransform( tmpTrans );
                    let p = tmpTrans.getOrigin();
                    let q = tmpTrans.getRotation();
                    objThree.position.set( p.x(), p.y(), p.z() );
                    objThree.quaternion.set( q.x(), q.y(), q.z(), q.w() );

                }
            }

        }

        function createBall(){

            let pos = {x: 0, y: 20, z: 0};
            let radius = 2;
            let quat = {x: 0, y: 0, z: 0, w: 1};
            let mass = 0;

            //threeJS Section
            ball = new THREE.Mesh(new THREE.SphereBufferGeometry(radius), new THREE.MeshPhongMaterial({color: 0xff0505}));

            ball.position.set(pos.x, pos.y, pos.z);

            ball.castShadow = true;
            ball.receiveShadow = true;

            scene.add(ball);


            //Ammojs Section
            let transform = new Ammo.btTransform();
            transform.setIdentity();
            transform.setOrigin( new Ammo.btVector3( pos.x, pos.y, pos.z ) );
            transform.setRotation( new Ammo.btQuaternion( quat.x, quat.y, quat.z, quat.w ) );
            let motionState = new Ammo.btDefaultMotionState( transform );


            let colShape = new Ammo.btSphereShape( radius );
            colShape.setMargin( 0.05 );

            let localInertia = new Ammo.btVector3( 0, 0, 0 );
            colShape.calculateLocalInertia( mass, localInertia );

            let rbInfo = new Ammo.btRigidBodyConstructionInfo( mass, motionState, colShape, localInertia );
            let body = new Ammo.btRigidBody( rbInfo );

            //body.setFriction(4);
            //body.setRollingFriction(10);

            //body.setActivationState( STATE.DISABLE_DEACTIVATION );
            //body.setCollisionFlags( FLAGS.CF_KINEMATIC_OBJECT );


            physicsWorld.addRigidBody( body );

            ball.userData.physicsBody = body;
            rigidBodies.push(ball);





        }

        //var forward , backward , left , right , speed = 1

            document.onkeydown = (e) => {
                switch(e.which) {
                    case 38: //↑: FORWARD
                        kMoveDirection.forward = 1
                    break;

                    case 40: //↓: BACK
                        kMoveDirection.back = 1
                    break;

                    case 37: //←: LEFT
                        kMoveDirection.left = 1
                    break;

                    case 39: //→: RIGHT
                        kMoveDirection.right = 1
                    break;
                }
            }




            document.onkeydown = (e) => {
                switch(e.which) {
                    case 38: //↑: FORWARD
                        kMoveDirection.forward = 0
                    break;

                    case 40: //↓: BACK
                        kMoveDirection.back = 0
                    break;

                    case 37: //←: LEFT
                        kMoveDirection.left = 0
                    break;

                    case 39: //→: RIGHT
                        kMoveDirection.right = 0
                    break;
                }
            }


            setInterval(()=>{

                if ( kMoveDirection.forward )
                    ball.position.y -= speed
                if ( kMoveDirection.backward )
                    ball.position.y += speed
                if ( kMoveDirection.left )
                    ball.position.x -= speed

                if ( kMoveDirection.right )
                    ball.position.x += speed },1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...