Oimo.js — это легковесный физический движок для JavaScript, обеспечивающий высокую производительность для симуляций твердых тел. Для визуализации физического мира, созданного в Oimo.js, особенно на этапе отладки, используется DebugDraw. В сочетании с Three.js он позволяет наглядно отображать коллайдеры, ограничения и взаимодействия между объектами сцены.
Для начала необходимо подключить три ключевых компонента: сам Oimo.js, Three.js и модуль DebugDraw. В Three.js создается стандартная сцена, камера и рендерер:
import * as THREE from 'three';
import OIMO from 'oimo';
import { OimoDebugDrawer } from 'oimo/debug-drawer';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.set(0, 5, 10);
На этом этапе создается базовая сцена Three.js, которая будет синхронизирована с физическим миром 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,
gravity: [0, -9.8, 0]
});
Важно: параметр worldscale влияет на
стабильность симуляции и размеры объектов. Оптимальные значения зависят
от масштаба сцены в Three.js.
Oimo.js использует RigidBody для создания тел и
Shape для коллайдеров. Пример создания динамического куба и
статической плоскости:
const ground = world.add({
type: 'box',
size: [20, 1, 20],
pos: [0, -0.5, 0],
rot: [0, 0, 0],
move: false
});
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 — динамическим.density влияет на массу и инерцию объекта.pos и rot задают начальное положение и
ориентацию.DebugDraw создает объекты Three.js для визуализации
физических тел. Для интеграции используется
OimoDebugDrawer:
const debugDrawer = new OimoDebugDrawer(world, {
color: 0xff0000, // цвет линий
opacity: 0.5, // прозрачность
wireframe: true, // отображение в виде каркаса
scene: scene // сцена Three.js
});
Особенности:
scene обязателен для добавления визуализации в сцену
Three.js.wireframe: true позволяет видеть внутренние грани
коллайдеров, что облегчает отладку.opacity и color помогают различать разные
типы тел и границ.Основная задача — обновлять физику и синхронизировать визуализацию с каждой итерацией рендеринга. Используется анимационный цикл:
function animate() {
requestAnimationFrame(animate);
// Шаг симуляции Oimo.js
world.step();
// Обновление DebugDraw
debugDrawer.update();
// Рендер сцены Three.js
renderer.render(scene, camera);
}
animate();
Важные моменты:
world.step() выполняет интеграцию движения тел.debugDrawer.update() обновляет положение
визуализированных коллайдеров.DebugDraw поддерживает визуализацию:
Пример фильтрации динамических тел:
debugDrawer.filter = (body) => body.move;
Чтобы камера следовала за объектом или обеспечивала свободное
перемещение по сцене, можно использовать OrbitControls:
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 1, 0);
controls.update();
Это позволяет визуально исследовать физические взаимодействия под любым углом, сохраняя синхронизацию с DebugDraw.
Для больших сцен с множеством тел:
broadphase: 2 (sweep & prune) для
ускорения столкновений.timestep и iterations для
баланса точности и скорости.Эта интеграция обеспечивает мощный инструмент для разработки и отладки физических симуляций в браузере, сочетая точность Oimo.js и наглядность Three.js.