Oimo.js — это легковесный физический движок для браузеров на JavaScript, обеспечивающий реалистичную симуляцию твердых тел. Он позволяет моделировать столкновения, гравитацию и динамику объектов без использования сложных внешних библиотек.
Для начала необходимо создать мир (World), который будет управлять всеми телами и их взаимодействиями:
const world = new OIMO.World({
timestep: 1/60,
iterations: 8,
broadphase: 2, // 1 - brute force, 2 - sweep and prune
worldscale: 1, // масштаб мира
random: true,
info: false,
gravity: [0, -9.8, 0]
});
Ключевые параметры:
timestep — шаг симуляции, чаще всего 1/60 для 60
FPS.iterations — количество итераций решения системы
ограничений, влияет на стабильность симуляции.broadphase — алгоритм обнаружения потенциальных
столкновений.gravity — вектор силы гравитации.В Oimo.js объекты представлены RigidBody с определенной формой (Shape). Формы могут быть простыми: box, sphere, cylinder, capsule, cone, convex.
Пример создания куба:
const box = world.add({
type: "box",
size: [1, 1, 1],
pos: [0, 5, 0],
rot: [0, 0, 0],
move: true,
density: 1
});
Параметры:
type — форма тела.size — размеры для коробки
[ширина, высота, глубина].pos — начальная позиция [x, y, z].rot — начальный поворот в радианах
[x, y, z].move — динамическое (true) или статическое
(false) тело.density — плотность, влияет на массу тела.Для сферы или цилиндра структура параметров аналогична, с заменой
size на radius и height, если
требуется.
Физические параметры определяют поведение тел при столкновениях и под действием силы:
[vx, vy, vz].[ax, ay, az].Пример настройки:
box.friction = 0.5;
box.restitution = 0.3;
box.linearVelocity = [0, 0, 0];
box.angularVelocity = [0, 0, 0];
Для динамического взаимодействия можно применять силы и импульсы:
// Прямое добавление силы
box.applyForce([10, 0, 0], box.getPosition());
// Импульс (мгновенное воздействие)
box.applyImpulse([0, 5, 0], box.getPosition());
applyForce(forceVector, position) — постоянная
сила.applyImpulse(impulseVector, position) — мгновенное
изменение скорости.getPosition() возвращает текущие координаты центра
тела.Oimo.js позволяет определять, когда тела сталкиваются, через контакты:
world.step(); // обновление мира
world.contacts.forEach(contact => {
const bodyA = contact.shape1.body;
const bodyB = contact.shape2.body;
console.log("Столкновение между:", bodyA, bodyB);
});
world.step() — обновление симуляции на один шаг.world.contacts — массив текущих столкновений.shape1,
shape2) и соответствующие тела.Oimo.js поддерживает различные joints, которые ограничивают движение тел:
distance — сохраняет расстояние между двумя
точками.hinge — шарнир, позволяющий вращение вокруг одной
оси.slider — скользящее движение вдоль одной оси.spring — имитация пружины.Пример создания шарнира:
world.add({
type: "hinge",
body1: box,
body2: anotherBox,
pos1: [0, -0.5, 0],
pos2: [0, 0.5, 0],
axis: [0, 0, 1],
min: -Math.PI/4,
max: Math.PI/4
});
Oimo.js не занимается графикой, поэтому интеграция с WebGL или Three.js осуществляется через синхронизацию позиций и вращений:
function update() {
world.step(); // обновление физики
// синхронизация объектов Three.js
mesh.position.copy(box.getPosition());
mesh.quaternion.copy(box.getQuaternion());
requestAnimationFrame(update);
}
update();
getPosition() возвращает Vector3.getQuaternion() возвращает Quaternion для
поворота.convex) для
большого числа объектов.box.sleep(); // перевод тела в режим покоя
box.wakeUp(); // пробуждение тела
Использование Oimo.js напрямую позволяет гибко управлять физикой в браузере без привязки к внешним плагинам, обеспечивая точный контроль над всеми аспектами симуляции.