Библиотека Oimo.js представляет собой легковесный физический движок для JavaScript, ориентированный на симуляцию твёрдых тел. Для реализации точной физики в 3D важно понимать, как движок работает с телами (bodies), точками контакта (contact points) и нормалями (normals). Эти элементы формируют основу взаимодействия объектов в пространстве.
Тело в Oimo.js представляет собой отдельный
физический объект с массой, формой, положением и скоростью. Каждый
объект создаётся через конструктор OIMO.Body или через
удобные фабричные функции. Основные свойства тела:
{x, y, z} позиции
центра массы в мировых координатах.{x, y, z, w}.Пример создания тела:
let box = new OIMO.Body({
type: 'box',
size: [2, 2, 2],
pos: [0, 5, 0],
move: true
});
world.addBody(box);
Ключевой момент: телу присваивается тип —
динамическое (dynamic), статическое (static)
или кинематическое (kinematic). Только динамические тела
участвуют в полной физической симуляции с силами и столкновениями.
Точка контакта — это конкретная позиция в пространстве, где два тела соприкасаются. В Oimo.js при обнаружении столкновения формируется массив точек контакта, каждая из которых содержит:
Пример обработки точек контакта:
world.step();
world.contacts.forEach(contact => {
console.log('Position:', contact.position);
console.log('Penetration:', contact.penetrationDepth);
console.log('Bodies:', contact.body1.id, contact.body2.id);
});
Особенность: каждая точка контакта формирует основу для расчёта сил реакции, трения и отражения. Именно через точки контакта движок реализует физически корректные столкновения.
Нормаль — это вектор, перпендикулярный поверхности в точке контакта, определяющий направление силы реакции. В Oimo.js нормаль используется для:
Пример извлечения нормали:
world.contacts.forEach(contact => {
let n = contact.normal; // {x, y, z}
console.log('Normal vector:', n);
});
Нормаль всегда направлена от первого тела к второму. Векторы нормалей нормализованы, что упрощает применение физических формул.
Эта триада используется для расчёта импульсов, сил трения и корректной симуляции столкновений. Например, чтобы вычислить силу отталкивания, нормаль умножается на величину импульса, учитывающего массу и скорость тел.
Для точной симуляции нужно учитывать:
world.step();
world.contacts.forEach(contact => {
let impulseMagnitude = computeImpulse(contact.body1, contact.body2, contact.normal);
applyImpulse(contact.body1, contact.body2, contact.normal, impulseMagnitude);
});
timeStep) для корректного вычисления точек контакта и
нормалей.Эта структура данных — тело, точка, нормаль — обеспечивает основу физической модели в Oimo.js и позволяет создавать реалистичные симуляции столкновений, трения и динамического взаимодействия объектов в 3D-пространстве.