Ammo.js — это порт Bullet Physics на JavaScript с использованием
WebAssembly. Для работы с мягкими телами необходима правильная
инициализация физического мира. Сначала создаётся объект
Ammo.btSoftBodyWorldInfo, который хранит глобальные
параметры мягких тел:
const collisionConfiguration = new Ammo.btSoftBodyRigidBodyCollisionConfiguration();
const dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration);
const broadphase = new Ammo.btDbvtBroadphase();
const solver = new Ammo.btSequentialImpulseConstraintSolver();
const softBodySolver = new Ammo.btDefaultSoftBodySolver();
const physicsWorld = new Ammo.btSoftRigidDynamicsWorld(
dispatcher,
broadphase,
solver,
collisionConfiguration,
softBodySolver
);
physicsWorld.setGravity(new Ammo.btVector3(0, -9.81, 0));
const softBodyWorldInfo = new Ammo.btSoftBodyWorldInfo();
softBodyWorldInfo.set_m_gravity(new Ammo.btVector3(0, -9.81, 0));
softBodyWorldInfo.set_m_sparsesdf(new Ammo.btSparseSdf3());
Ключевым моментом является установка m_gravity и
m_sparsesdf, которые управляют поведением мягких тел.
Мягкое тело создаётся на основе сетки вершин (mesh) в Three.js.
Наиболее часто используется функция
btSoftBodyHelpers.CreateFromTriMesh, которая принимает
массив вершин и индексов треугольников:
const vertices = geometry.attributes.position.array;
const indices = geometry.index.array;
const softBody = Ammo.btSoftBodyHelpers.CreateFromTriMesh(
softBodyWorldInfo,
vertices,
indices,
indices.length / 3,
true
);
Основные параметры:
softBodyWorldInfo — информация о физическом мире для
мягких тел.vertices — массив координат вершин в формате
[x1, y1, z1, x2, y2, z2, ...].indices — массив индексов треугольников.true в конце — включает генерацию нормалей для
столкновений.После создания мягкое тело необходимо добавить в мир:
physicsWorld.addSoftBody(softBody);
softBody.setTotalMass(1, false);
softBody.setPose(true, false);
Для реалистичного поведения важно задать свойства материала:
const sbConfig = softBody.get_m_cfg();
sbConfig.set_viterations(40); // внутренние итерации
sbConfig.set_piterations(40); // позиционные итерации
sbConfig.set_kDF(0.5); // демпфирование
sbConfig.set_kDP(0.01); // динамическое демпфирование
sbConfig.set_kPR(250); // жёсткость растяжения
viterations и piterations определяют
стабильность симуляции.kDF и kDP отвечают за гашение
колебаний.kPR регулирует сопротивление растяжению.Эти параметры напрямую влияют на поведение вершин сетки.
Каждая вершина geometry в Three.js должна обновляться
согласно положению соответствующего узла мягкого тела в Ammo.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();
vertices[3*i] = pos.x();
vertices[3*i + 1] = pos.y();
vertices[3*i + 2] = pos.z();
}
geometry.attributes.position.needsUpdate = true;
geometry.computeVertexNormals();
Ключевые моменты:
position обязательно
устанавливать needsUpdate = true.Float32Array для вершин
— минимизирует лишние копирования данных.viterations, piterations) при малых или
медленных объектах.Мягкие тела в Ammo.js могут взаимодействовать с твёрдыми объектами.
Для этого твёрдое тело добавляется в тот же
physicsWorld:
const rigidBody = createRigidBody(mesh, mass);
physicsWorld.addRigidBody(rigidBody);
softBody.appendAnchor(nodeIndex, rigidBody, false, 1);
appendAnchor позволяет закрепить узел к твёрдому телу с
определённой силой.false отключает ограничение вращения.Такой подход позволяет создавать тканевые сцены с объектами, на которые они могут реагировать физически.
Для корректного движения мягкого тела шаг симуляции должен вызываться на каждом кадре:
const deltaTime = clock.getDelta();
physicsWorld.stepSimulation(deltaTime, 10);
updateSoftBodyMesh(softBody, geometry);
renderer.render(scene, camera);
stepSimulation принимает deltaTime и
максимальное число суб-итераций.updateSoftBodyMesh синхронизирует вершины
Three.js с узлами мягкого тела.Эти методы позволяют полностью интегрировать мягкие тела Ammo.js с визуальной сеткой Three.js, создавая реалистичное поведение объектов, подверженных деформациям и взаимодействию с окружающей средой.