cannonjs与Three.js将一个身体与网格相关联

时间:2014-12-11 13:40:41

标签: javascript physics-engine

我使用以下代码在cannonjs中生成两个球体,其中Three.js作为渲染模块。

var world, mass, body, shape, timeStep=1/60,
    camera, scene, renderer, geometry, material, mesh;
    initThree();
    initCannon();
    animate();

    function initCannon() {
        world = new CANNON.World();
        world.gravity.set(0,0,0);
        world.broadphase = new CANNON.NaiveBroadphase();
        world.solver.iterations = 10;

        geometry = new THREE.SphereGeometry( 3);
        material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } ); 
        mesh = new THREE.Mesh( geometry, material );
        body = new CANNON.Body({mass:0.2});
        body.angularVelocity.set(0,5,0);
        body.angularDamping = 0.9;
        world.add(body);
        scene.add(mesh);

        geometry = new THREE.SphereGeometry(2);
        material = new THREE.MeshBasicMaterial( { color: 0x00ff00, wireframe: true } );
        mesh = new THREE.Mesh(geometry,material);
        body = new CANNON.Body({mass: 1});
        body.angularVelocity.set(0,10,0);
        body.angularDamping = 0.5;
        world.add(body);
        scene.add(mesh);
    }

    function initThree() {
        scene = new THREE.Scene();
        camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 100 );
        camera.position.z = 5;
        scene.add( camera );

        renderer = new THREE.WebGLRenderer();
        renderer.setSize( window.innerWidth, window.innerHeight );
        document.body.appendChild( renderer.domElement );
    }

    function animate() {
        requestAnimationFrame( animate );
        updatePhysics();
        render();
    }

    function updatePhysics() {
        // Step the physics world
        world.step(timeStep);
        // Copy coordinates from Cannon.js to Three.js
        mesh.position.copy(body.position);
        mesh.quaternion.copy(body.quaternion);
    }

    function render() {
        renderer.render( scene, camera );
    }

结果,我确实显示了两个球体,但只有在initCannon()中声明的第二个体动画。 cannonjs体在某种程度上与Three.js网格无关。我试过“body.mesh = mesh”,但它没有帮助。

网格的声明最初是在initThree()中完成的,但我不知道这是否重要。

我做错了什么?请帮忙。如果需要,请询问更多细节。

1 个答案:

答案 0 :(得分:1)

您正在覆盖变量。在开始时,您声明一个变量body,然后您说body = new CANNON.Body...,之后您对第二个球体使用相同的句子,因此第一个被覆盖。你应该有一个变量body2,一个变量mesh2来避免这种情况。如果您只需要两个实体,这种方法可以正常工作,但如果您计划拥有更多实体,则需要采用不同的方法:数组。在数组中,您可以存储所有实体,然后循环遍历它并单独处理每个实体。例如:

这里我们创建10个实体:

var bodies= []; //create the array

for (var i = 0; i < 10; i++) {
    bodies.push({ //insert into the array an object that contains the information for each body/mesh
        body: new CANNON.Body({mass:0.2}),
        mesh = new THREE.Mesh(geometry,material)
    })
};

然后我们使用它们:

for (var i=0, l=bodies.length; i < l; i++) { //we loop through each body
    var body = bodies[i]; //this will be the current body
    //MOVE THE BODY AND UPDATE THE MESH HERE
}

这将是一种更好的方法。它更易于维护,您可以拥有浏览器可以处理的多个主体。如果你只需要两个,你最快的修复就是为第二个体添加第二个变量并单独处理它。

编辑: 请注意:https://www.youtube.com/watch?v=tW6pmzd34Hc他也将圆圈存储到数组中。我希望它能让它更清晰一点。