Oimo.js — это легковесная физическая библиотека на JavaScript, предназначенная для симуляции твердых тел в трехмерных сценах. Она обеспечивает реалистичное поведение объектов с упором на производительность, что особенно важно для веб-приложений и игр, где нагрузка на CPU должна оставаться минимальной. Основными объектами в Oimo.js являются тела (RigidBody), шарниры (Joints) и контейнеры мира (World).
Мир в Oimo.js создается через объект OIMO.World, который
управляет всеми физическими телами и их взаимодействиями:
const world = new OIMO.World({
timestep: 1/60,
gravity: [0, -9.8, 0]
});
timestep — шаг симуляции, обычно 1/60 для 60 FPS.gravity — вектор гравитации в формате
[x, y, z].Каждый объект в мире должен быть зарегистрирован через методы
addRigidBody и addJoint.
RigidBody является основным строительным блоком физики. Создание тела выглядит следующим образом:
const box = world.add({
type: "box",
size: [1, 1, 1],
pos: [0, 5, 0],
rot: [0, 0, 0],
move: true,
density: 1
});
type — форма тела: box,
sphere, cylinder, capsule.size — размеры тела; для сферы достаточно одного
значения радиуса.pos и rot — начальная позиция и
вращение.move — указывает, подвижное ли тело.density — плотность материала, влияет на массу.Оimo.js автоматически рассчитывает массу тела как произведение
плотности на объем. Для динамических объектов важно правильно подбирать
density и move.
Ключевыми параметрами поведения тела являются:
box.friction = 0.5;
box.restitution = 0.3;
box.linearDamping = 0.01;
box.angularDamping = 0.05;
Для создания соединений между объектами Oimo.js использует Joints. Типы соединений:
Пример шарнирного соединения:
const hinge = new OIMO.HingeJoint(box1, box2, {
pos1: [0, -1, 0],
pos2: [0, 1, 0],
axis1: [0, 0, 1],
axis2: [0, 0, 1],
collideConnected: false
});
world.addJoint(hinge);
pos1 и pos2 — точки крепления на
телах.axis1 и axis2 — оси вращения.collideConnected — предотвращает столкновение
соединённых тел.Симуляция обновляется вызовом метода step():
function animate() {
world.step();
requestAnimationFrame(animate);
}
animate();
Рекомендуется вызывать step() с тем же шагом, который
был задан при создании мира (timestep). После каждого шага
можно обновлять визуальные объекты, синхронизируя их с положением
физических тел.
Havok в Babylon.js ориентирован на реализм и сложные столкновения, поддерживает мягкие тела, тряпичные симуляции и разрушения, но имеет большую нагрузку на CPU/GPU. Oimo.js, в отличие от Havok, более лёгкий и быстрый, идеален для браузерных игр и простых физико-динамических эффектов.
Когда выбирать Oimo.js:
Когда выбирать Havok:
timestep снижает точность, уменьшение — увеличивает
нагрузку.Для визуализации тела из Oimo.js используют синхронизацию с
Mesh:
mesh.position.copyFrom(box.getPosition());
mesh.rotationQuaternion.copyFrom(box.getQuaternion());
Важно использовать кватернионы для вращения, так как Oimo.js хранит ориентацию в виде кватерниона.
Использование Oimo.js позволяет создавать сцены с падающими объектами, цепями, катящимися шарами и простыми физическими взаимодействиями без чрезмерной нагрузки, что делает его идеальным инструментом для браузерной 3D-физики.