Интеграция DebugDraw с Three.js

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.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

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

DebugDraw поддерживает визуализацию:

  1. Силовых векторов и контактных точек — помогает анализировать взаимодействие между объектами.
  2. Различных типов коллайдеров — сферы, капсулы, цилиндры, полигоны.
  3. Фильтрации по типу тел — можно выделять только динамические или только статические объекты.
  4. Настройки прозрачности и цвета — позволяют совмещать несколько физических систем на одной сцене для сложных симуляций.

Пример фильтрации динамических тел:

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) для ускорения столкновений.
  • Ограничивать количество объектов, визуализируемых DebugDraw, через фильтры.
  • Настраивать timestep и iterations для баланса точности и скорости.

Эта интеграция обеспечивает мощный инструмент для разработки и отладки физических симуляций в браузере, сочетая точность Oimo.js и наглядность Three.js.