Oimo.js — это физический движок твёрдых тел, реализованный на JavaScript и ориентированный на работу в браузере. Библиотека предназначена для расчёта динамики объектов в реальном времени и чаще всего используется совместно с WebGL-фреймворками, такими как Three.js, для построения интерактивных 3D-сцен.
В основе Oimo.js лежит классическая архитектура физического движка:
Движок ориентирован на производительность и простоту интеграции, но не претендует на физическую точность промышленного уровня.
Основной сущностью в Oimo.js является RigidBody — объект с массой, положением, ориентацией, скоростью и набором коллайдеров.
Поддерживаются два типа тел:
Каждое тело может иметь:
Oimo.js поддерживает базовый набор коллизионных примитивов:
Отсутствует встроенная поддержка сложных произвольных мешей (TriangleMesh) и выпуклых многоугольников с автоматической генерацией оболочки, что ограничивает использование в сложных сценах.
Для первичной фильтрации пар тел используется алгоритм AABB (Axis-Aligned Bounding Box). Его задача — быстро определить потенциально пересекающиеся объекты.
Преимущества:
Ограничение заключается в том, что AABB не подходит для очень сложных или вытянутых форм без увеличения ложных срабатываний.
После отбора потенциальных пар выполняется точный расчёт столкновения:
Используются методы SAT (Separating Axis Theorem) для примитивных форм и аналитические решения для сфер и капсул.
Oimo.js применяет итерационный импульсный солвер. Его задачи:
Параметры солвера:
При увеличении количества итераций повышается стабильность, но снижается производительность.
Движение тел рассчитывается через интеграцию уравнений Ньютона:
Поддерживаются:
Интегратор — полуявный (semi-implicit Euler), обеспечивающий приемлемую стабильность при невысоких вычислительных затратах.
Oimo.js поддерживает базовые типы соединений:
С их помощью реализуются:
Ограничения работают через тот же итерационный солвер, что и контакты. При сложных цепочках соединений возможна потеря стабильности.
Oimo.js оптимизирован для браузерной среды:
Характерные особенности производительности:
Для тяжёлых сцен иногда используется перенос вычислений в Web Worker.
Oimo.js не содержит встроенного рендера. Обычно используется связка:
Синхронизация выполняется вручную:
Отсутствует автоматическая система биндинга, что увеличивает объём инфраструктурного кода.
Oimo.js не является научным симулятором. Ограничения включают:
Для борьбы с туннелированием используется увеличение количества шагов симуляции или уменьшение размера timestep.
Симуляция строится на фиксированном шаге времени:
Oimo.js не реализует встроенную систему адаптивного шага.
Числовая стабильность зависит от масштаба:
Отсутствует автоматическая нормализация единиц измерения.
Поддерживаются:
Однако система фильтрации не так гибка, как в более сложных движках.
Для повышения производительности реализован механизм “засыпания”:
В сложных механических системах преждевременный сон может нарушать симуляцию.
По сравнению с крупными физическими движками, такими как Bullet, Oimo.js не поддерживает:
Также отсутствуют:
Oimo.js развивается медленнее, чем крупные проекты физики. Сообщество относительно небольшое. Обновления выходят нерегулярно.
Документация ограничена:
Отсутствует формальная спецификация или строгая система версионирования API.
Oimo.js подходит для:
Менее подходит для:
Oimo.js занимает нишу лёгкого физического движка для веб-приложений. Он предоставляет базовый, но достаточный набор инструментов для динамики твёрдых тел, при этом жертвуя расширенной функциональностью ради простоты и скорости работы в браузере. Его архитектура прозрачна и удобна для изучения принципов работы физических движков, однако при росте сложности сцены быстро проявляются ограничения точности и производительности.