Система координат и единицы измерения

Oimo.js использует правостороннюю декартову систему координат, где ось X направлена вправо, ось Y — вверх, а ось Z — на пользователя (в сторону экрана). Важно понимать, что физический мир в Oimo.js моделируется в метрах, а не в пикселях или других единицах. Это обеспечивает стабильность симуляции и корректное поведение физических объектов при взаимодействиях.

Основные понятия

  • Положение (position): вектор, определяющий координаты объекта в пространстве. Представляется через объект OIMO.Vec3 с тремя компонентами: x, y и z.

    let position = new OIMO.Vec3(0, 5, 0);
  • Размеры (size): объекты задаются в метрах. Например, куб размером 1x1x1 будет восприниматься как куб со стороной в один метр.

  • Единицы силы и массы: масса измеряется в килограммах, силы — в ньютонах, ускорение — в м/с². Это согласуется с реальными физическими законами.

Работа с координатами

Oimo.js оперирует положением объектов через rigidBody.setPosition() и rigidBody.getPosition(). Внутри симуляции координаты объектов изменяются автоматически на каждом шаге интеграции.

let body = world.add({
  type: 'box',
  size: [1, 1, 1],
  pos: [0, 10, 0],
  move: true,
  density: 1
});

body.getPosition(); // вернёт объект OIMO.Vec3 с текущей позицией
  • Перемещение объекта должно учитывать, что изменения позиции напрямую через setPosition() могут конфликтовать с физическим интегратором. Для естественного движения предпочтительнее использовать силы (applyForce) или скорость (setLinearVelocity).

Векторные операции

Oimo.js предоставляет набор встроенных операций с векторами:

  • Vec3.add(v1, v2): сложение векторов.
  • Vec3.sub(v1, v2): вычитание.
  • Vec3.scale(v, scalar): умножение на скаляр.
  • Vec3.dot(v1, v2): скалярное произведение.
  • Vec3.cross(v1, v2): векторное произведение.

Пример расчёта смещения:

let pos = body.getPosition();
let offset = new OIMO.Vec3(2, 0, 0);
let newPos = OIMO.Vec3.add(pos, offset);

Привязка к графике

Для интеграции с Three.js или Babylon.js, где единицы часто задаются в условных координатах, необходимо согласовывать масштаб:

  • Если сцена визуализируется в сантиметрах, каждый метр Oimo.js соответствует 100 единицам графической сцены.
  • При расчётах коллизий важно передавать размеры объектов и их положение с учётом масштабного коэффициента.
const SCALE = 100; // 1 метр = 100 единиц
mesh.position.set(
  body.getPosition().x * SCALE,
  body.getPosition().y * SCALE,
  body.getPosition().z * SCALE
);

Ротация и локальная система координат

Oimo.js использует кватернионы для задания ориентации (Quaternion) и позволяет работать с локальными осями объекта. Ключевые моменты:

  • Quaternion хранит вращение относительно мировой системы координат.
  • Векторная математика учитывает локальные оси объекта при применении силы или импульса.
  • Для преобразования между локальной и глобальной системой координат используется умножение векторов на матрицы вращения, создаваемые кватернионами.
let q = body.getQuaternion();
let forward = new OIMO.Vec3(0, 0, 1); // локальная ось Z
let globalForward = q.toMatrix().multiplyVec3(forward);

Координация физических и визуальных объектов

  • Любое прямое изменение позиции или вращения в графическом движке должно сопровождаться обновлением состояния физического тела.
  • Константный шаг интеграции (world.step(timeStep)) обеспечивает синхронность между физикой и рендером.
  • Смешение единиц (например, метр в физике и пиксель в графике) без корректного масштаба может привести к нестабильности симуляции.

Практические рекомендации

  1. Всегда использовать метры в физических расчётах.
  2. Преобразование координат между физикой и визуализацией следует делать централизованно через масштабный коэффициент.
  3. Изменение позиции через силы предпочтительнее прямого присваивания.
  4. При работе с вращениями учитывать локальные оси и использовать кватернионы, чтобы избежать эффекта гимбал-лок.

Соблюдение этих правил позволяет создавать стабильные и предсказуемые симуляции с точной привязкой к графическим объектам.