Oimo.js — это легковесная библиотека для физического моделирования в браузере на языке JavaScript. Она позволяет создавать динамические симуляции твердых тел, коллизий и взаимодействий объектов в 3D-пространстве. Основным строительным блоком является мир (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
});
Здесь ключевое значение имеет параметр timestep,
определяющий шаг симуляции, и iterations, влияющий на
точность расчета контактов и силы столкновений.
В Oimo.js объекты представляются rigid bodies — твердыми телами, которые могут быть динамическими, статическими или кинематическими. Каждое тело имеет набор свойств:
position — текущие координаты тела.rotation — ориентация в пространстве (Quaternion или
Euler).linearVelocity — линейная скорость.angularVelocity — угловая скорость.sleeping — состояние покоя (true, если тело находится в
состоянии сна).awake() / sleep() — методы управления
состоянием активности.Статус тела напрямую влияет на его поведение в симуляции. Динамическое тело участвует во всех вычислениях столкновений и движений, статическое тело служит опорой и не перемещается, кинематическое управляется напрямую, не реагируя на силы.
Для визуализации физической симуляции часто используется цветовое кодирование, позволяющее сразу определить состояние тела:
Пример применения цветового кодирования:
function getColorByBody(body) {
if (!body.isDynamic) return 0x0000ff; // синий
if (body.sleeping) return 0xff0000; // красный
return 0x00ff00; // зеленый
}
Каждый кадр симуляции можно обновлять, проверяя состояние тела:
world.bodies.forEach(body => {
const color = getColorByBody(body);
meshMap[body.id].material.color.setHex(color);
});
Состояния тела могут изменяться динамически:
body.awake();
body.sleep();
body.setKinematicPosition({x: 5, y: 10, z: 0});
При переходе между состояниями цветовое кодирование должно синхронизироваться с новым статусом тела.
Oimo.js часто используется совместно с Three.js для рендеринга объектов. Связь между физическим телом и графическим объектом осуществляется через массив сопоставления:
const meshMap = {};
world.bodies.forEach(body => {
const geometry = new THREE.BoxGeometry(...);
const material = new THREE.MeshStandardMaterial({color: 0x00ff00});
const mesh = new THREE.Mesh(geometry, material);
meshMap[body.id] = mesh;
scene.add(mesh);
});
При каждом обновлении физики:
world.step();
world.bodies.forEach(body => {
const mesh = meshMap[body.id];
mesh.position.copy(body.getPosition());
mesh.quaternion.copy(body.getQuaternion());
mesh.material.color.setHex(getColorByBody(body));
});
Такой подход позволяет сразу визуально оценить состояние объектов в симуляции, облегчая отладку сложных взаимодействий и проверку корректности поведения твердых тел.
Для крупных сцен с десятками или сотнями тел важно минимизировать количество операций обновления цвета:
InstancedMesh в Three.js для массового
рендеринга объектов одного типа.mesh.material.color.setHex.if (body.prevState !== body.sleeping) {
mesh.material.color.setHex(getColorByBody(body));
body.prevState = body.sleeping;
}
Такой подход уменьшает нагрузку на GPU и обеспечивает плавное отображение физики даже при высокой плотности объектов.
Помимо цвета, можно использовать прозрачность, масштаб или подсветку для визуализации состояния тела:
Эти визуальные индикаторы помогают создавать интерактивные симуляции, где физическое поведение тел сразу понятно по графическому представлению.