Боеприпасы. js Custom Me sh столкновение со сферой - PullRequest
1 голос
/ 09 января 2020

Я пытаюсь генерировать коллизии для каждого объекта / меня sh. Все они имеют статус c и должны сталкиваться с шаром / сферой, который является динамическим c.

Мой код выглядит следующим образом:

const transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(-1.1726552248001099, 2.6692488193511963, 0));
transform.setRotation(new Ammo.btQuaternion(0.5, -0.5, 0.5, 0.4999999701976776));
const motionState = new Ammo.btDefaultMotionState(transform);

// Vertices and indices are parsed by GLTF parser by loaders.gl
const vertices = Entity.vertices;
const indices = Entity.indices;
const scale = [0.15933185815811157, 1.1706310510635376, 0.15933185815811157];

// btConvexHullShape or btBvhTriangleMeshShape, see below.

const localInertia = new Ammo.btVector3(0, 0, 0);

const rbInfo = new Ammo.btRigidBodyConstructionInfo(0, motionState, shape, localInertia);
const object = new Ammo.btRigidBody(rbInfo);

this._physicsWorld.addRigidBody(object);

Я пробовал 2 метода: btConvexHullShape и btBvhTriangleMeshShape, и оба не работали.

  • btConvexHullShape
const shape = new Ammo.btConvexHullShape();
for (let i = 0; i < vertices.length / 3; i++) {
    shape.addPoint(new Ammo.btVector3(vertices[i * 3] * scale[0], vertices[i * 3 + 1] * scale[1], vertices[i * 3 + 2] * scale[2]));
}

Путь сферы с использованием btConvexHullShape является чем-то вроде этого (это не так) введите отверстие): Path of the sphere using btConvexHullShape

Я думаю, боеприпасы. js соединяет самые верхние точки? Как я могу контролировать, какие точки связаны на основе индексов? Также кажется, что этот подход очень медленный (вершины 30k занимают некоторое время), поэтому я попытался:

  • btBvhTriangleMeshShape
const mesh = new Ammo.btTriangleMesh(true, true);
for (let i = 0; i * 3 < indices.length; i++) {
    mesh.addTriangle(
        new Ammo.btVector3(vertices[indices[i * 3]] * scale[0], vertices[indices[i * 3] + 1] * scale[1], vertices[indices[i * 3] + 2] * scale[2]),
        new Ammo.btVector3(vertices[indices[i * 3 + 1]] * scale[0], vertices[indices[i * 3 + 1] + 1] * scale[1], vertices[indices[i * 3 + 1] + 2] * scale[2]),
        new Ammo.btVector3(vertices[indices[i * 3 + 2]] * scale[0], vertices[indices[i * 3 + 2] + 1] * scale[1], vertices[indices[i * 3 + 2] + 2] * scale[2]),
        false
    );
}
const shape = new Ammo.btBvhTriangleMeshShape(mesh, true, true);

This метод немного лучше, но сфера просто проходит через объект, когда она отскакивает один раз (отскакивает от круга и проходит через объект (красный круг)): Path of the sphere using btBvhTriangleMeshShape

1 Ответ

1 голос
/ 10 января 2020

Причина, по которой btConvexHullShape не работала (хотя столкновение вокруг него действительно работает), заключается в том, что это не для вогнутых фигур.

Что касается btBvhTriangleMeshShape , я неправильно ввел вершины. Мне пришлось умножить индексы на 3 (потому что каждая вершина имеет 3 компонента).

Вот полный рабочий код:

const transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(-1.1726552248001099, 2.6692488193511963, 0));
transform.setRotation(new Ammo.btQuaternion(0.5, -0.5, 0.5, 0.4999999701976776));
const motionState = new Ammo.btDefaultMotionState(transform);

// Vertices and indices are parsed by GLTF parser by loaders.gl
const vertices = Entity.vertices;
const indices = Entity.indices;
const scale = [0.15933185815811157, 1.1706310510635376, 0.15933185815811157];

const mesh = new Ammo.btTriangleMesh(true, true);
mesh.setScaling(new Ammo.btVector3(scale[0], scale[1], scale[2]));
for (let i = 0; i * 3 < indices.length; i++) {
    mesh.addTriangle(
        new Ammo.btVector3(vertices[indices[i * 3] * 3], vertices[indices[i * 3] * 3 + 1], vertices[indices[i * 3] * 3 + 2]),
        new Ammo.btVector3(vertices[indices[i * 3 + 1] * 3], vertices[indices[i * 3 + 1] * 3 + 1], vertices[indices[i * 3 + 1] * 3 + 2]),
        new Ammo.btVector3(vertices[indices[i * 3 + 2] * 3], vertices[indices[i * 3 + 2] * 3 + 1], vertices[indices[i * 3 + 2] * 3 + 2]),
        false
    );
}
const shape = new Ammo.btBvhTriangleMeshShape(mesh, true, true);

const localInertia = new Ammo.btVector3(0, 0, 0);

const rbInfo = new Ammo.btRigidBodyConstructionInfo(0, motionState, shape, localInertia);
const object = new Ammo.btRigidBody(rbInfo);

this._physicsWorld.addRigidBody(object);
...