ThreeJS с физическим движком PhysiJS не вызывает событие столкновения

Скриншот падающего ящика

Ожидаемый результат: коробка упадет на землю и появится окно с предупреждением "Коробка только что упала на землю"

Что происходит: окно оповещения не создается. Соответствующие журналы консоли javascript также не создаются при столкновении.


Я делюсь небольшой базой кода в моем репозитории github. Вы можете клонировать его и запустить самостоятельно в браузере Chrome. Вы можете проверить часть physijsBox.addEventListener() в файле ****scripts/app. js**** в исходном коде.

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:


person Rakib    schedule 10.11.2016    source источник
comment
Почему вы устанавливаете трение для обоих объектов на 0? Расчет impulse связан с коэффициентом трения. Величина импульса - это то, что физические движки используют для обнаружения столкновения, насколько я знаю. Соотношение трения при расчете импульса приведено здесь - euclideanspace.com/physics/dynamics/ столкновение/тройка   -  person Munim Dibosh    schedule 10.11.2016
comment
Можешь попробовать дать им немного трения?   -  person Munim Dibosh    schedule 10.11.2016
comment
Настройка трения не дает никаких улучшений. Если вы вытащите код и запустите его, вы увидите, что коллизия действительно имеет место. Падающая коробка меняет курс и ударяется о землю. Но по какой-то причине он не запускает столкновение EVENT, так что событие столкновения может быть получено physijsBox.addEventListener('collision', function(){})   -  person Rakib    schedule 10.11.2016
comment
Ага. Только что попробовал написать другую версию кода, следуя одному из их примеров — gist.github.com/dibosh /b7055c6a41a127814e86ad30f53f3384 Пытался даже добавить два объекта и заставить их столкнуться. Не работает! Похоже, что событие collision вообще не запускается.   -  person Munim Dibosh    schedule 10.11.2016


Ответы (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));
person XavCo7    schedule 15.11.2016
comment
привет @XavCo7. Я попробовал ваши предложения. К сожалению, они не оказали никакого влияния на приложение. Удалось ли вам заставить это работать таким образом, запустив код github, которым я поделился? - person Rakib; 16.11.2016
comment
@syedrakib на самом деле, я не пытался запускать репозиторий кода. Я чувствовал, что могу просто решить эту проблему, посмотрев, что вы сделали неправильно в своей настройке. Я только что нашел что-то новое, пожалуйста, проверьте мой ответ еще раз. - person XavCo7; 17.11.2016