Внутренний граф зависимостей объектов

В библиотеке Oimo.js физические объекты сцены не существуют изолированно. Каждый объект может быть связан с другими через контакты, ограничения и взаимодействия, формируя внутренний граф зависимостей. Этот граф определяет порядок обновления физических состояний, расчёт сил и столкновений. Узлы графа соответствуют телам (RigidBody), а рёбра — связям через контакты или джойнты (Joint).

Ключевой принцип: при симуляции каждый узел должен быть обработан после всех узлов, от которых зависит его состояние. Нарушение порядка приводит к нестабильности, «пробиваниям» тел и неверным результатам столкновений. Oimo.js строит граф зависимостей автоматически, основываясь на текущих контактах и ограничениях.

Узлы графа и их свойства

RigidBody является основным узлом. Важные параметры:

  • position и rotation — определяют положение и ориентацию тела в пространстве.
  • velocity и angularVelocity — линейная и угловая скорость.
  • mass — масса тела, критичная для расчёта импульсов.
  • forces и torques — накопленные силы и моменты на шаг симуляции.

Каждое тело отслеживает входящие и исходящие связи, чтобы корректно распределять импульсы при контакте с другими телами.

Joint (например, DistanceJoint, HingeJoint) формирует рёбра графа. Joint хранит:

  • ссылки на два тела (bodyA и bodyB).
  • ограничения по перемещению и вращению.
  • параметры силы коррекции (stiffness, damping).

Joint гарантирует, что физические расчёты будут учитывать взаимное влияние тел, предотвращая проникновение друг в друга или нарушения заданного расстояния.

Построение и обновление графа

Граф зависимостей обновляется каждый кадр. Процесс включает:

  1. Сбор контактов: Oimo.js проверяет все коллайдеры на пересечение и создаёт объекты Contact.
  2. Формирование рёбер: Для каждого контакта создаются связи между телами. Если тела соединены джойнтом, добавляется дополнительное ребро.
  3. Определение порядка обновления: Алгоритм топологической сортировки используется для расчёта последовательности интеграции. Циклы разрушаются с помощью итеративного решения системы ограничений.
  4. Распределение сил и импульсов: На основе графа рассчитываются линейные и угловые скорости, учитывая массу и моменты инерции.

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

Влияние на производительность

Граф зависимостей напрямую влияет на эффективность симуляции. Основные аспекты:

  • Количество узлов: чем больше тел, тем сложнее построить граф и топологически отсортировать его.
  • Сложность рёбер: наличие джойнтов с высокой жёсткостью увеличивает количество итераций для стабилизации системы.
  • Циклические зависимости: требуют дополнительных шагов для устранения конфликтов, что может замедлять расчёт.

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

Работа с динамическими изменениями сцены

При добавлении или удалении тел и джойнтов граф перестраивается:

  • Добавление тела: создаётся новый узел с пустыми рёбрами, которые заполняются при первом контакте или присоединении джойнтов.
  • Удаление тела: удаляются все исходящие и входящие связи, предотвращая ошибки в расчётах соседних узлов.
  • Изменение свойств джойнта: корректирует ограничения на рёбрах графа, влияя на распределение сил.

Важно понимать, что Oimo.js использует ленивое обновление графа: изменения применяются при следующем шаге симуляции, что позволяет минимизировать излишние пересчёты.

Практическое использование

Для контроля над зависимостями полезно:

  • Разбивать сцену на логические группы, чтобы уменьшить плотность графа.
  • Избегать чрезмерного количества жёстких джойнтов в одной области.
  • Использовать isStatic для неподвижных тел, чтобы исключить их из динамического графа.
  • Следить за глубиной вложенности контактов, чтобы не создавать сложные циклы.

Эти методы помогают сохранить стабильность симуляции и позволяют Oimo.js эффективно обрабатывать даже большие системы с десятками и сотнями тел.

Итоговая структура графа

Внутренний граф зависимостей в Oimo.js — это динамическая направленная структура, где:

  • Узлы = RigidBody
  • Рёбра = Contact и Joint
  • Порядок обновления = топологическая сортировка с итеративной стабилизацией циклов
  • Цель = корректное распространение сил, импульсов и коррекция столкновений

Понимание этой структуры критично для точного моделирования физики и оптимизации производительности сложных 3D сцен.