使用 cannon.js 和 three.js 的物体从地平面落下

问题描述 投票:0回答:1

我最近开始使用物理引擎。我正在使用 cannon.es/js 和 three.js 盒子和加载的模型刚好穿过平面并从视野中掉落。我尝试使用

groundBody.quaternion.setFromEuler(-Math.PI/2,0,0)
但对象在屏幕上移动而不是向下移动。我认为我的定位和尺寸是这里的问题。你能帮帮我吗?非常感谢

这是我正在处理的代码

<html>
  <head>
    <title>My 3D Model</title>
    <script type="module">
        import * as THREE from "https://cdn.skypack.dev/[email protected]/build/three.module.js";
        import { GUI } from "https://cdn.skypack.dev/[email protected]/build/dat.gui.module.js";
        import { TrackballControls } from "https://cdn.skypack.dev/[email protected]/examples/jsm/controls/TrackballControls.js";
        import {OrbitControls} from "https://cdn.skypack.dev/[email protected]/examples/jsm/controls/OrbitControls.js";
        import { STLLoader } from "https://cdn.skypack.dev/[email protected]/examples/jsm/loaders/STLLoader.js";
        import { OBJLoader } from "https://cdn.skypack.dev/[email protected]/examples/jsm/loaders/OBJLoader.js";
        import * as CANNON from 'https://unpkg.com/[email protected]/dist/cannon-es.js'

        // webgl 
        const renderer = new THREE.WebGLRenderer();

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

        document.body.appendChild(renderer.domElement);
       // scene
        const scene = new THREE.Scene();

        const camera = new THREE.PerspectiveCamera(
            75,
            window.innerWidth/window.innerHeight,
            0.1,
            1000
        );

        const orbit = new OrbitControls(camera,renderer.domElement);
       

        camera.position.set(0,200,-100);
        orbit.update();
        const ambientLight = new THREE.AmbientLight();
       scene.add( ambientLight );

       const directionalLight = new THREE.DirectionalLight( 0xffffff, 5.0 );
       directionalLight.position.set( 10, 100, -100 );
       scene.add( directionalLight );
        
        
        const world = new CANNON.World({
          gravity : new CANNON.Vec3(0,-9.81,0)
        });

        const groundBody = new CANNON.Body({
            shape : new CANNON.Plane(),
            type : CANNON.Body.STATIC,
        })
        world.addBody(groundBody);
        groundBody.quaternion.setFromEuler(Math.PI/2,0,0);
        let mesh,body;
        const material = new THREE.MeshPhysicalMaterial({ color: 0xaaaaaa })
       const loader = new OBJLoader()
       loader.load('resources/Model_8_8.obj', (object) => {
        const geometry = object.children[0].geometry;
        mesh = new THREE.Mesh(geometry, material)
       scene.add(mesh)
       //mesh.rotateZ(Math.PI);
       const boundingBox = new THREE.Box3().setFromObject(object);
            const width = boundingBox.max.x - boundingBox.min.x;
            const height = boundingBox.max.y - boundingBox.min.y;
            const depth = boundingBox.max.z - boundingBox.min.z;
            const shape = new CANNON.Box(new CANNON.Vec3(width / 2, height / 2, depth / 2))
            body= new CANNON.Body({
              mass :10,
              shape :shape
            })
            //body3.position.set(0, 1800, -100);
            world.addBody(body);
            const boxGeometry = new THREE.BoxGeometry(30,30,30);
        const boxMat = new THREE.MeshBasicMaterial({
            color: 0x00ff00,
            wireframe : true
        });
            const boxMesh = new THREE.Mesh(boxGeometry,boxMat);
            scene.add(boxMesh);

        const groundGeo = new THREE.PlaneGeometry(300,300);
        const groundMat = new THREE.MeshBasicMaterial({
            color:0xffffff,
            side : THREE.DoubleSide,
            wireframe: true
        });
        const groundMesh = new THREE.Mesh(groundGeo,groundMat);
        scene.add(groundMesh);
       

        const boxBody = new CANNON.Body({
            mass : 10,
            shape : new CANNON.Box(new CANNON.Vec3(15,15,15))
        });
        world.addBody(boxBody);
    
        const timeStep = 1 / 60 ;

        function animate(){
            world.step(timeStep);
            groundMesh.position.copy(groundBody.position);
            groundMesh.quaternion.copy(groundBody.quaternion);
            boxMesh.position.copy(boxBody.position);
            boxMesh.quaternion.copy(boxBody.quaternion);
            mesh.position.copy(body.position);
            mesh.quaternion.copy(body.quaternion);

            renderer.render(scene,camera);
        }
        renderer.setAnimationLoop(animate);
        window.addEventListener('resize',function(){
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth,window.innerHeight);
        });
      })
</script>
</head>
<body>
</body>

</html>
javascript three.js webgl physics-engine cannon.js
1个回答
0
投票

我不熟悉 cannonJS,但似乎有 2 个选项可以使用。 就像在 https://github.com/schteppe/cannon.js?files=1 中,重力设置为 Z 坐标,将重力更改为 Z 坐标,不要随平面旋转。然后给 boxBody.position.z = 100 一个位置,它起作用了。

否则你必须改变你的平面几何尺寸,而不是新的 CANNON.Plane() 形状,一个新的 CANNON.Box(new CANNON.Vec3(15, 15, 1)) 形状,而 Z 坐标只是1,旋转后这是你的 Y 尺寸。在这种情况下,不在 z 中而是在 y 中设置位置 (boxBody.position.y = 100)。我认为,你的例子中的错误是两种物理学在它们中的每一个中都在一起,这是造成失败的原因。 (我真的不知道 new Cannon.Plane() 在做什么。)干杯

一些应该有效的代码片段:

  const groundBody = new CANNON.Body({
    shape: new CANNON.Box(new CANNON.Vec3(15, 15, 1)),
    type: CANNON.Body.STATIC,
  });

  world.addBody(boxBody);
  boxBody.position.y = 100;
© www.soinside.com 2019 - 2024. All rights reserved.