【问题标题】:ThreeJS with PhysiJS physics engine not triggering collision event带有 PhysiJS 物理引擎的 ThreeJS 不会触发碰撞事件
【发布时间】:2016-11-10 05:33:06
【问题描述】:

预期结果:一个盒子会掉在地上,它会产生一个警告框,上面写着“盒子刚刚落地”

发生了什么:未创建警报框。冲突时也不会产生相关的 javascript 控制台日志。


我在my github repo 上共享一个小代码库。您可以克隆它并在您的 chrome 浏览器中自己运行它。您可以检查源代码中****scripts/app.js**** 文件中的physijsBox.addEventListener() 部分。

var sceneObj = (function(){

    "use strict";

    Physijs.scripts.worker = "scripts/physijs_worker.js";
    Physijs.scripts.ammo = "ammo.js";

    var scene, camera, renderer
    var physijsBox, physijsGround

    function initScene(){
        scene = new Physijs.Scene();
        scene.setGravity = new THREE.Vector3(0, -50, 0);

        camera = new THREE.PerspectiveCamera(35, window.innerWidth/window.innerHeight , 1, 1000);
        camera.position.z = 100;

        renderer = window.WebGLRenderingContext ? new THREE.WebGLRenderer() : new THREE.CanvasRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.getElementById("webgl-container").appendChild(renderer.domElement);

        addPhysijsBox();
        addPhysijsGround();
        render();
    }

    function addPhysijsBox(){
        var myBoxMaterial = Physijs.createMaterial(
            new THREE.MeshBasicMaterial({
                color: 0xff00ff
            }),
            0,  // friction
            0.8 // restitution / bounciness
        );
        physijsBox = new Physijs.BoxMesh(new THREE.CubeGeometry(15,15,15), myBoxMaterial);
        physijsBox.position.set(0,30,10);
        physijsBox.rotation.set(0,50,90);
        scene.add(physijsBox);

        physijsBox.addEventListener('collision', function(
            theOtherObject, linearVelocity, angularVelocity, arg4
        ){
            console.log("box collided with something");
            if (theOtherObject.name == "ground"){
                alert("Box just hit the ground");
            }
        })
    }

    function addPhysijsGround(){
        var myGroundMaterial = Physijs.createMaterial(
            new THREE.MeshBasicMaterial({
                color: 0x008888
            }),
            0, // friction
            0.4 // restitution / bounciness
        );
        physijsGround = new Physijs.BoxMesh(new THREE.CubeGeometry(150, 3, 150), myGroundMaterial, 0);
        physijsGround.name = "ground";
        physijsGround.position.y = -15;
        scene.add(physijsGround);
    }

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

    window.onLoad = initScene();
    return scene;

})();

相关的 PhysiJS 文档:

【问题讨论】:

  • 为什么将两个对象的摩擦力都设置为 0? impulse 的计算与摩擦系数有关。脉冲幅度是物理引擎用来检测碰撞 AFAIK 的。这里给出了脉冲计算中的摩擦关系-euclideanspace.com/physics/dynamics/collision/threed
  • 你能试着给他们一些摩擦吗?
  • 设置摩擦没有任何改善。如果你拉代码并运行它,你会看到碰撞实际上正在发生。落下的盒子在撞到地面时会改变路线并颠簸。但由于某种原因,它没有触发碰撞 EVENT 以便physijsBox.addEventListener('collision', function(){}) 可以拾取碰撞事件
  • 是的。刚刚尝试按照他们的一个示例编写不同版本的代码 - gist.github.com/dibosh/b7055c6a41a127814e86ad30f53f3384 甚至尝试添加两个对象并使它们发生碰撞。没用!似乎collision 事件根本没有被触发。

标签: javascript three.js collision-detection physics-engine physijs


【解决方案1】:

我建议添加一个更新监听器:

function initScene(){

    // Create scene object here...

    scene.addEventListener("update", function(){
        scene.simulate(undefined, 2);
    });

    // Rest of start function here...

    scene.simulate();
}

相应地调整您的渲染功能:

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

哦,还有window.onLoad 的一个小错误:

window.onload = initScene;

另外,请确保为移动框指定质量,否则它将默认为零,使其无法移动。

重读代码...

我看到你有 .setGravity 作为属性。嗯,它实际上是一个函数:

scene.setGravity(new THREE.Vector3(0, -50, 0));

【讨论】:

  • 嗨@XavCo7。我已经尝试过你的建议。不幸的是,它们对应用程序没有任何影响。您是否能够通过运行我共享的 github 代码使其以这种方式工作?
  • @syedrakib 实际上,我没有尝试运行代码仓库。我觉得我可以通过查看您在设置中做错了什么来解决它。我刚刚发现了一些新东西,请再次检查我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-18
  • 1970-01-01
  • 2017-09-29
  • 1970-01-01
  • 1970-01-01
  • 2012-01-07
相关资源
最近更新 更多