Данные результата: тело, точка, нормаль

Библиотека Oimo.js представляет собой легковесный физический движок для JavaScript, ориентированный на симуляцию твёрдых тел. Для реализации точной физики в 3D важно понимать, как движок работает с телами (bodies), точками контакта (contact points) и нормалями (normals). Эти элементы формируют основу взаимодействия объектов в пространстве.


Тело (Body)

Тело в Oimo.js представляет собой отдельный физический объект с массой, формой, положением и скоростью. Каждый объект создаётся через конструктор OIMO.Body или через удобные фабричные функции. Основные свойства тела:

  • position — вектор {x, y, z} позиции центра массы в мировых координатах.
  • rotation — ориентация тела, обычно представляется кватернионом {x, y, z, w}.
  • velocity — линейная скорость в пространстве.
  • angularVelocity — угловая скорость вращения.
  • mass — масса объекта, влияющая на инерцию и динамику столкновений.
  • shape — геометрическая форма тела: коробка, сфера, цилиндр или коническая форма.

Пример создания тела:

let box = new OIMO.Body({
    type: 'box',
    size: [2, 2, 2],
    pos: [0, 5, 0],
    move: true
});
world.addBody(box);

Ключевой момент: телу присваивается тип — динамическое (dynamic), статическое (static) или кинематическое (kinematic). Только динамические тела участвуют в полной физической симуляции с силами и столкновениями.


Точка контакта (Contact Point)

Точка контакта — это конкретная позиция в пространстве, где два тела соприкасаются. В Oimo.js при обнаружении столкновения формируется массив точек контакта, каждая из которых содержит:

  • position — координаты точки в мировых координатах.
  • penetrationDepth — глубина проникновения одного тела в другое.
  • body1, body2 — ссылки на участвующие тела.
  • normal — нормаль поверхности в точке контакта (указывающая от первого тела ко второму).

Пример обработки точек контакта:

world.step();
world.contacts.forEach(contact => {
    console.log('Position:', contact.position);
    console.log('Penetration:', contact.penetrationDepth);
    console.log('Bodies:', contact.body1.id, contact.body2.id);
});

Особенность: каждая точка контакта формирует основу для расчёта сил реакции, трения и отражения. Именно через точки контакта движок реализует физически корректные столкновения.


Нормаль (Normal)

Нормаль — это вектор, перпендикулярный поверхности в точке контакта, определяющий направление силы реакции. В Oimo.js нормаль используется для:

  • Расчёта силы столкновения по закону сохранения импульса.
  • Определения направления, в котором объекты отталкиваются друг от друга.
  • Вычисления компонента силы трения вдоль поверхности.

Пример извлечения нормали:

world.contacts.forEach(contact => {
    let n = contact.normal; // {x, y, z}
    console.log('Normal vector:', n);
});

Нормаль всегда направлена от первого тела к второму. Векторы нормалей нормализованы, что упрощает применение физических формул.


Связь тела, точки и нормали

  • Тело задаёт объект с массой и формой.
  • Точка контакта фиксирует конкретное место взаимодействия тел.
  • Нормаль указывает направление силы, действующей на тела в этой точке.

Эта триада используется для расчёта импульсов, сил трения и корректной симуляции столкновений. Например, чтобы вычислить силу отталкивания, нормаль умножается на величину импульса, учитывающего массу и скорость тел.


Применение в симуляции

Для точной симуляции нужно учитывать:

  1. Множество точек контакта: при сложных столкновениях тела могут иметь несколько точек контакта, каждая из которых влияет на результирующую силу.
  2. Реакция на нормаль: сила реакции всегда направлена вдоль нормали и корректируется с учётом массы и коэффициентов трения.
  3. Динамика тела: изменения позиции и скорости тела зависят от всех точек контакта и нормалей, что позволяет моделировать устойчивую физику.
world.step();
world.contacts.forEach(contact => {
    let impulseMagnitude = computeImpulse(contact.body1, contact.body2, contact.normal);
    applyImpulse(contact.body1, contact.body2, contact.normal, impulseMagnitude);
});

Важные детали реализации

  • Точки контакта обновляются каждый кадр симуляции.
  • Нормали могут быть не идеально перпендикулярны при сложных столкновениях; движок использует усреднение нескольких точек.
  • Тела с высокой массой или высокой скоростью требуют меньшего времени шага (timeStep) для корректного вычисления точек контакта и нормалей.

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