Обзор архитектуры библиотеки

Cannon.js — это физический движок для Javascript, реализующий тела с твердой динамикой (rigid bodies), контакты и столкновения, а также систему интеграции движения во времени. Он ориентирован на реалистичное моделирование физики объектов в 3D-пространстве и предоставляет гибкие инструменты для настройки физических параметров.

В основе архитектуры лежат три ключевых компонента: мир (World), тела (Body) и формы (Shape). Эти элементы взаимодействуют через силы, импульсы и коллизии, обеспечивая корректное поведение объектов.


Мир (World)

World — центральный объект, управляющий симуляцией. Он хранит список всех тел, осуществляет пошаговое обновление состояния и обрабатывает столкновения. Основные свойства и методы:

  • gravity — вектор гравитации (CANNON.Vec3), задающий направление и величину силы тяжести для всех объектов.
  • broadphase — алгоритм предварительной фильтрации потенциальных столкновений (NaiveBroadphase, SAPBroadphase).
  • step(dt, timeSinceLastCall, maxSubSteps) — основной метод для обновления мира на шаг времени dt. Позволяет точно интегрировать движение при переменных частотах кадров.
  • addBody(body) и removeBody(body) — добавление и удаление тел из симуляции.

World отвечает за сбор всех столкновений, генерацию контактных точек и передачу их в систему constraint solver, что обеспечивает реалистичное взаимодействие объектов.


Тела (Body)

Body представляет собой физический объект, обладающий массой, инерцией и положением в пространстве. Основные параметры:

  • mass — масса тела; значение 0 делает объект статическим.
  • position — текущие координаты в мире (CANNON.Vec3).
  • velocity и angularVelocity — линейная и угловая скорости.
  • force и torque — суммарные силы и моменты, действующие на тело за текущий шаг.
  • linearDamping и angularDamping — коэффициенты затухания, моделирующие сопротивление среды.

Методы Body включают:

  • applyForce(force, relativePoint) — применение силы к телу.
  • applyImpulse(impulse, relativePoint) — мгновенное изменение скорости тела.
  • addShape(shape, offset, orientation) — добавление формы к телу с заданным смещением и ориентацией.

Тела могут быть статическими, динамическими или кинематическими, что задаёт правила их взаимодействия с другими объектами.


Формы (Shape)

Shape определяет геометрию тела для расчета столкновений. Cannon.js предоставляет несколько типов форм:

  • Box — параллелепипед, задается векторами половинных размеров.
  • Sphere — сфера, задается радиусом.
  • Cylinder — цилиндр, задается радиусами основания, высотой и количеством сегментов.
  • Plane — бесконечная плоскость, используется для пола или стен.
  • ConvexPolyhedron — произвольный выпуклый многогранник, поддерживает сложные формы.
  • Trimesh — сетка треугольников для точного столкновения, но более вычислительно затратная.

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


Столкновения и контактная система

Cannon.js использует двухступенчатый процесс столкновений:

  1. Broadphase — быстрый отбор пар тел, которые могут столкнуться. Алгоритмы NaiveBroadphase и SAPBroadphase оптимизируют поиск потенциальных контактов.
  2. Narrowphase — точный расчет точек контакта между выбранными телами с учетом их форм. Здесь создаются contact points с нормалями, глубиной проникновения и коэффициентами трения.

Контакты обрабатываются solver-ом, который вычисляет силы реакции для предотвращения проникновения тел друг в друга и моделирования трения.


Constraints (Ограничения)

Ограничения позволяют связывать тела и ограничивать их движение:

  • PointToPointConstraint — фиксирует точки двух тел друг относительно друга.
  • HingeConstraint — соединение, позволяющее вращение вокруг оси.
  • DistanceConstraint — поддерживает фиксированное расстояние между телами.
  • LockConstraint — полностью фиксирует относительное положение и ориентацию тел.

Constraints используют Lagrange multiplier solver, что обеспечивает точное соблюдение ограничений без нарушения физической реалистичности.


Система интеграции движения

Cannon.js применяет интегратор Velocity Verlet, обеспечивающий баланс между стабильностью и точностью. При каждом шаге:

  1. Обновляются скорости с учетом сил и моментов.
  2. Вычисляются новые позиции и ориентации тел.
  3. Применяются контактные силы и ограничения через solver.

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


Расширяемость и структура кода

Библиотека построена модульно:

  • cannon-es (современная версия) разделяет классы на отдельные модули: World, Body, Shape, Solver, ContactEquation.
  • Пользователь может создавать кастомные формы, собственные ограничения и модифицировать solver, сохраняя совместимость с базовой архитектурой.

Оптимизация и производительность

  • Использование SAPBroadphase вместо NaiveBroadphase значительно снижает количество проверок столкновений для больших сцен.
  • Статические объекты не участвуют в интеграции, что экономит вычислительные ресурсы.
  • Trimesh следует использовать только для сложных, редко двигающихся объектов из-за высокой нагрузки на Narrowphase.

Взаимодействие с визуализацией

Cannon.js не занимается рендерингом. Он предоставляет позиции и ориентации объектов, которые можно использовать совместно с библиотеками визуализации, такими как:

  • Three.js
  • Babylon.js

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


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