Ammo.js представляет собой JavaScript-порт библиотеки Bullet Physics и предоставляет полноценный физический движок для работы с жёсткими и мягкими телами. Взаимодействие мягких тел (soft bodies) с твёрдыми объектами (rigid bodies) требует понимания нескольких ключевых принципов: структуры данных, интеграции симуляции и обработки коллизий.
Мягкое тело в Ammo.js создаётся как сетчатая структура узлов (nodes), соединённых между собой связями (links). Основные параметры, влияющие на физику мягкого тела:
Создание мягкого тела через Ammo.js выглядит так:
const softBodyHelpers = new Ammo.btSoftBodyHelpers();
const softBody = softBodyHelpers.CreateFromTriMesh(
physicsWorld.getWorldInfo(),
vertices, indices, indices.length / 3, true
);
softBody.get_m_cfg().set_viterations(40);
softBody.get_m_cfg().set_piterations(40);
softBody.setTotalMass(1, false);
physicsWorld.addSoftBody(softBody, 1, -1);
Ключевой момент: viterations и
piterations отвечают за точность расчёта вершин и связей
соответственно. Увеличение этих параметров повышает стабильность
симуляции, но снижает производительность.
Твёрдые тела в Ammo.js создаются через btRigidBody и
обладают свойствами:
btBoxShape, btSphereShape.const boxShape = new Ammo.btBoxShape(new Ammo.btVector3(1,1,1));
const transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(0,5,0));
const motionState = new Ammo.btDefaultMotionState(transform);
const localInertia = new Ammo.btVector3(0,0,0);
boxShape.calculateLocalInertia(1, localInertia);
const rigidBodyInfo = new Ammo.btRigidBodyConstructionInfo(1, motionState, boxShape, localInertia);
const rigidBody = new Ammo.btRigidBody(rigidBodyInfo);
physicsWorld.addRigidBody(rigidBody);
Для корректного взаимодействия важно учитывать несколько аспектов:
Мягкие тела имеют типы коллизий, которые определяются через
конфигурацию softBody.get_m_cfg(). Для взаимодействия с
твёрдыми телами нужно установить флаги:
softBody.get_m_cfg().set_collisions(
Ammo.btSoftBodyConfig.SDF_RS + Ammo.btSoftBodyConfig.CL_SS
);
SDF_RS — столкновение мягкого тела с твёрдым
телом.CL_SS — внутренние столкновения мягкого тела
(самосоприкосновение).Твёрдые тела могут деформировать мягкие при контакте, если соблюдаются следующие условия:
stiffness).Для того чтобы мягкое тело могло толкать твёрдое, необходимо:
Стабильность — основной вызов при взаимодействии мягких и твёрдых тел. Рекомендации:
viterations и
piterations для мягких тел.Пример пошаговой интеграции:
const deltaTime = 1/60;
physicsWorld.stepSimulation(deltaTime, 10);
softBody.setTotalMass(softBodyMass, false);
Для отображения симуляции важно синхронизировать позиции узлов мягкого тела с мешем в Three.js или другом рендерере. Пример обновления вершин:
const nodes = softBody.get_m_nodes();
for (let i = 0; i < nodes.size(); i++) {
const node = nodes.at(i);
const pos = node.get_m_x();
mesh.geometry.attributes.position.setXYZ(i, pos.x(), pos.y(), pos.z());
}
mesh.geometry.attributes.position.needsUpdate = true;
Своевременная синхронизация обеспечивает плавное отображение деформаций, отражающих физическое взаимодействие с твёрдыми объектами.
iterations, отключение внутренних столкновений
(CL_SS) при необходимости.Эти подходы обеспечивают глубокое понимание и контроль при моделировании взаимодействия мягких и твёрдых тел в Ammo.js, позволяя создавать реалистичные и стабильные симуляции в браузере.