Oimo.js — это легковесная библиотека для физического моделирования
твёрдых тел в JavaScript. Основной её задачей является реалистичное
моделирование столкновений, динамики тел и физических взаимодействий в
3D-пространстве. Центральной концепцией является создание миров
(World), в которых размещаются тела
(RigidBody) с различными формами
(Shape) и физическими свойствами.
Для работы с Oimo.js необходимо создать объект мира:
const world = new OIMO.World({
timestep: 1/60,
gravity: [0, -9.8, 0],
iterations: 8,
});
timestep — шаг симуляции, определяющий частоту
обновления физического мира.gravity — вектор силы тяжести.iterations — количество итераций для решения
столкновений, влияет на точность симуляции.Создание тел происходит через конструктор
OIMO.RigidBody, которому передаются параметры формы,
позиции, массы и динамического состояния:
const box = world.add({
type: "box",
size: [1, 1, 1],
pos: [0, 5, 0],
move: true, // true — динамическое тело
density: 1
});
Выпуклая оболочка (Convex Hull) позволяет моделировать
сложные объекты с минимальными вычислительными затратами. Она строится
на основе множества вершин, описывающих объект. В Oimo.js для этого
применяется тип формы "convex".
Вершины передаются массивом чисел или массивом объектов с
координатами x, y, z. Пример массива вершин куба:
const vertices = [
[-0.5, -0.5, -0.5],
[0.5, -0.5, -0.5],
[0.5, 0.5, -0.5],
[-0.5, 0.5, -0.5],
[-0.5, -0.5, 0.5],
[0.5, -0.5, 0.5],
[0.5, 0.5, 0.5],
[-0.5, 0.5, 0.5]
];
Для использования этих вершин необходимо создать объект формы:
const convexBody = world.add({
type: "convex",
vertices: vertices,
pos: [0, 2, 0],
move: true,
density: 1
});
Особенности работы с вершинными массивами:
Помимо вершин, можно задавать дополнительные параметры:
margin — расстояние вокруг оболочки, используемое для
расчёта столкновений. Значение по умолчанию 0.05.density — плотность материала, влияющая на массу
тела.friction и restitution — коэффициенты
трения и упругости соответственно.Пример с дополнительными параметрами:
const convexWithParams = world.add({
type: "convex",
vertices: vertices,
pos: [2, 2, 0],
move: true,
density: 2,
friction: 0.5,
restitution: 0.3,
margin: 0.02
});
После создания тел необходимо обновлять физический мир каждый кадр:
function upd ate() {
world.step(); // обновление физики
requestAnimationFrame(upd ate);
}
update();
Каждое тело содержит свойства position и
rotation, которые можно использовать для синхронизации с
визуализацией, например в Three.js:
mesh.position.se t(
convexBody.position.x,
convexBody.position.y,
convexBody.position.z
);
mesh.quaternion.se t(
convexBody.rotation.x,
convexBody.rotation.y,
convexBody.rotation.z,
convexBody.rotation.w
);
Для сложных моделей рекомендуется:
В совокупности использование массива вершин для выпуклой оболочки позволяет эффективно моделировать сложные объекты, сохраняя высокую производительность и точность столкновений в Oimo.js.