Oimo.js — это легковесный физический движок на JavaScript, ориентированный на симуляцию твердых тел в 3D-пространстве. Основная архитектура движка основана на телах (rigid bodies), коллайдерах (shapes), джоинтах (joints) и глобальных свойствах мира (world). Каждое тело имеет свойства массы, инерции, позиции, ориентации и скорости.
В Oimo.js скорость тела разделена на линейную и угловую. Линейная скорость описывает движение тела в пространстве, а угловая — вращение вокруг собственного центра массы.
Мир создается через объект OIMO.World:
const world = new OIMO.World({
timestep: 1/60,
iterations: 8,
broadphase: 2, // 1 = brute-force, 2 = sweep & prune
worldscale: 1,
random: true,
info: false
});
Добавление тела происходит через создание OIMO.RigidBody
и добавление к нему формы (shape):
const box = world.add({
type: "box",
size: [1, 1, 1],
pos: [0, 5, 0],
rot: [0, 0, 0],
move: true,
density: 1
});
Тела могут быть статическими (move: false) или
динамическими (move: true).
Каждое тело имеет свойства:
linearVelocity — вектор [x, y, z],
измеряющий скорость перемещения.angularVelocity — вектор [x, y, z],
измеряющий скорость вращения вокруг осей.Пример получения и установки скорости:
console.log(box.linearVelocity); // [vx, vy, vz]
console.log(box.angularVelocity); // [ax, ay, az]
// Установка скорости
box.linearVelocity.set(5, 0, 0);
box.angularVelocity.set(0, 1, 0);
Эти векторы обновляются автоматически при каждом шаге симуляции через
метод world.step().
Состояние сна (sleep) используется для оптимизации симуляции: тела, находящиеся в покое, не вычисляются каждый кадр. Пороги сна в Oimo.js определяются максимальной линейной и угловой скоростью, ниже которых тело считается неподвижным.
Каждое тело имеет свойства:
sleepLinearVelocity: порог линейной скорости для
перехода в сон.sleepAngularVelocity: порог угловой скорости для
перехода в сон.Пример:
box.sleepLinearVelocity = 0.01; // м/с
box.sleepAngularVelocity = 0.01; // рад/с
Если обе скорости тела остаются ниже этих значений в течение нескольких шагов симуляции, тело автоматически переходит в состояние сна.
Тело может быть пробуждено вручную через метод
awake():
box.awake();
Кроме того, любое столкновение или внешнее воздействие автоматически выводит тело из сна, даже если скорости остаются малы.
Уменьшение порогов сна делает симуляцию более точной: тела будут реагировать на микродвижения. Однако это увеличивает вычислительную нагрузку, так как большее количество тел остается активным.
Увеличение порогов повышает производительность, но может привести к “залипанию” объектов в покое и потере физической точности. Оптимальные значения часто находятся экспериментально, в зависимости от размеров и массы объектов.
Для контроля состояния сна можно проверять свойство
isSleeping каждого тела:
if (box.isSleeping) {
console.log("Тело находится в состоянии сна");
} else {
console.log("Тело активно");
}
Логирование линейной и угловой скорости позволяет визуально оценивать влияние выбранных порогов на динамику сцены.
Проверка перехода тела в сон внутри Oimo.js выглядит как:
if ( |linearVelocity| < sleepLinearVelocity && |angularVelocity| < sleepAngularVelocity ) {
body.sleep();
}
Где |linearVelocity| и |angularVelocity| —
длины соответствующих векторов. Тело выходит из сна при превышении этих
порогов или при столкновении.
Эти механизмы позволяют точно настраивать поведение объектов в Oimo.js, снижать нагрузку на CPU и сохранять реалистичную физику движения, включая линейные и угловые аспекты динамики.