Oimo.js — это легковесная JavaScript-библиотека для симуляции трёхмерной физики. Она позволяет моделировать твёрдые тела, столкновения, силы и ограничения с высокой производительностью прямо в браузере. Основой движка является интеграция физических законов Ньютона в дискретное время, что позволяет получать реалистичное поведение объектов при взаимодействии друг с другом.
В Oimo.js все объекты делятся на тела (bodies) и формы (shapes). Тело представляет собой объект с массой, положением, ориентацией и скоростью. Форма определяет геометрические характеристики тела — куб, сферу, цилиндр или произвольный меш. Каждое тело может содержать одну или несколько форм, что позволяет строить сложные объекты.
Пример создания кубического тела:
const world = new OIMO.World({
timestep: 1/60,
iterations: 8,
broadphase: 2,
worldscale: 1,
random: true
});
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 и т.д.).size — размеры вдоль осей XYZ.pos — начальная позиция.rot — начальная ориентация в градусах.move — подвижность тела.density — плотность, влияющая на массу.Oimo.js поддерживает различные физические параметры, влияющие на поведение объектов при столкновениях:
Пример установки коэффициента восстановления:
box.restitution = 0.8; // тело отскакивает на 80% от скорости столкновения
Oimo.js использует метод интеграции Эйлера с исправлением ошибок позиции (ERP — Error Reduction Parameter) для обеспечения стабильности симуляции. ERP регулирует, как быстро движок исправляет ошибку позиции объектов при наложении или проникновении. Высокие значения ERP приводят к более жёсткому исправлению проникновений, низкие — к мягкому, что снижает риск вибраций, но может допускать небольшие перекрытия.
ERP применяется в ограничениях (constraints) и при контактах:
erp — значение от 0 до 1, где 0 полностью игнорирует
коррекцию позиции, а 1 полностью исправляет позицию за один шаг.Пример использования при создании соединения:
const joint = world.add({
type: "jointDistance",
body1: box,
body2: anotherBox,
min: 2,
max: 2,
collision: false,
erp: 0.25
});
Коллизии в Oimo.js рассчитываются с использованием broadphase и narrowphase алгоритмов.
При расчёте контакта используются параметры:
friction — трение между телами.restitution — упругость столкновения.erp — коррекция проникновения.Контакты генерируются каждый шаг симуляции, что позволяет динамически реагировать на столкновения и изменять физические свойства объектов.
Oimo.js поддерживает несколько типов соединений:
ERP влияет на все соединения: при больших скоростях или сильных силах низкий ERP может вызвать дрожание соединений, а высокий ERP делает соединение жёстким и точным.
Мир Oimo.js создаётся с параметрами:
timestep — шаг времени симуляции (обычно 1/60).iterations — число итераций для решения ограничений.
Чем больше, тем точнее, но медленнее.broadphase — алгоритм широкофазного поиска столкновений
(0–3).worldscale — масштаб мира, влияет на стабильность
вычислений.Пример обновления мира:
function update() {
world.step();
requestAnimationFrame(update);
}
update();
timestep — слишком большой шаг времени
снижает точность интеграции и может вызвать проникновения.Oimo.js позволяет моделировать сложные физические системы с высокой производительностью, если правильно настроить параметры тел, контактов и ограничений. ERP и коэффициент восстановления занимают центральное место в обеспечении реалистичного поведения объектов при столкновениях и соединениях.