обнаружение столкновений в группе три js (THREE.Group) - PullRequest
0 голосов
/ 02 июля 2018

Я работаю над обнаружением столкновений 3D AABB для коробки и сферы.

Если блок добавляется непосредственно в сцену, то обнаруживается столкновение, но если его добавить в группу (THREE.Group) и повернуть, то столкновение не обнаруживается.

Это код для добавления поля

function addPlatforms() {

    var coreGroup = new THREE.Group(); // this is the group
    scene.add(coreGroup);

    var box = [];

    cube_box1 = new THREE.Box3(new THREE.Vector3(), new THREE.Vector3());
    box.push(new THREE.Mesh(new THREE.BoxGeometry(1, 1, 0.2), materials.solid));
    box[0].position.set(-1.83, -0.22, 1.11);
    box[0].rotation.x += Math.PI / 2;
    box[0].rotation.z -= 0.78;
    box[0].receiveShadow = true;


    cube_box2 = new THREE.Box3(new THREE.Vector3(), new THREE.Vector3());
    box.push(new THREE.Mesh(new THREE.BoxGeometry(1, 1, 0.2), materials.solid));
    box[1].position.set(-2.15, -0.22, 0.51);
    box[1].rotation.x += Math.PI / 2;
    box[1].receiveShadow = true;

    var platGroup = new THREE.Group();
    platGroup.add(box[0]);
    platGroup.add(box[1]);
    platGroup.rotation.y -= 2;
    platGroup.position.y  = 1;

    coreGroup.add(platGroup);


    cube_box1.setFromObject(box[0]);
    platformArr.push(cube_box1);

    cube_box2.setFromObject(box[1]);
    platformArr.push(cube_box2);
}

Код для получения Столкновения между коробкой и сферой.

Визит https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_collision_detection/Bounding_volume_collision_detection_with_THREE.js

THREE.Sphere.__closest = new THREE.Vector3();
THREE.Sphere.prototype.intersectsBox = function(box) {
    // get box closest point to sphere center by clamping
    THREE.Sphere.__closest.set(this.center.x, this.center.y, this.center.z);
    THREE.Sphere.__closest.clamp(box.min, box.max);

    var distance = this.center.distanceToSquared(THREE.Sphere.__closest);
    return distance < (this.radius * this.radius);
};

function isCollision() {
    for (var i = 0; i < platformArr.length; i++) {
        _cubeBox = platformArr[i];
        return sphereBox.intersectsBox(_cubeBox);
    }
}

Вот как добавляется сфера

function addBall(){

    sphere = new THREE.Mesh(
        new THREE.SphereGeometry(0.19, 20, 20), materials.solid);
    sphere.position.set(0, 1, -2);
    sphere.geometry.computeBoundingSphere();
    scene.add(sphere);

    sphereBox = new THREE.Sphere(sphere.position, sphere.geometry.boundingSphere.radius);
    sphereBox.radius = sphere.geometry.boundingSphere.radius;

    cy = sphere.position.y;
}  

Логика визуализации

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

    if (collision) { // ball is on surface
        vy = -vy;
        collision = false;
    }

    cy -= vy * dt;

    sphere.position.y = cy;

    if (vy <= mvy)
        vy += gravity;

    collision = isCollision();
}

Если в сцену добавлен прямоугольник и обнаружена коллизия со сферой, то работает. Ex - Создайте простое поле и измените некоторые свойства, такие как вращение и положение

var _box = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 0.2), materials.solid);
_box.position.set(-1.83, -0.22, 1.11);
_box.rotation.x += Math.PI / 2;
_box.rotation.z -= 0.78;
_box.receiveShadow = true;

Тогда найди столкновение в живом обновлении

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

    if (collision) { // ball is on surface
        vy = -vy;
        collision = false;
    }

    cy -= vy * dt;

    sphere.position.y = cy;

    if (vy <= mvy)
        vy += gravity;

    collision = sphereBox.intersectsBox(_box);
}

1 Ответ

0 голосов
/ 04 июля 2018

По умолчанию матрица мира объекта будет обновляться каждый кадр. Вы создаете эти ящики, трансформируете и добавляете их в группу. Затем вы мгновенно звоните cube_box1.setFromObject(box[0]);, который использует matrixWorld внутри страны. Но мировые матрицы коробок еще не установлены. Вы можете подождать фрейм, чтобы матрицы могли быть автоматически рассчитаны, или вам нужно запускать обновления матриц вручную:

//... your code ...
coreGroup.add(platGroup);

coreGroup.updateMatrixWorld( true );

cube_box1.setFromObject(box[0]);
platformArr.push(cube_box1);
//... your code ...

Преобразования матрицы документов Three.js

При изменении преобразования родительского или дочернего объекта вы можете запросить обновление matrixWorld дочернего объекта, вызвав updateMatrixWorld().

Three.js Документы Object3D

.matrixAutoUpdate : Boolean

Когда это установлено, он вычисляет матрицу положения (вращение или кватернион) и масштабирует каждый кадр, а также пересчитывает свойство matrixWorld. По умолчанию Object3D.DefaultMatrixAutoUpdate (true).

...