Oimo.js — это JavaScript-порт физического движка OimoPhysics, предназначенный для расчёта твёрдотельной динамики в браузере. Библиотека ориентирована на моделирование жёстких тел, столкновений и ограничений (constraints) и широко применяется совместно с WebGL-рендерами, в частности с Three.js.
Переход от ветки 1.x к 2.x стал не косметическим обновлением, а фактически переработкой архитектуры, API и внутреннего ядра. Версия 2.x упростила структуру кода, улучшила производительность и изменила принципы конфигурации мира и тел.
В версии 1.x библиотека имела более сложную и громоздкую архитектуру, во многом унаследованную от оригинального C++-движка. Код содержал большое количество низкоуровневых классов и вспомогательных структур, что затрудняло понимание и сопровождение.
Версия 2.x была переработана с акцентом на:
В результате ядро стало компактнее и легче для интеграции в современные сборочные системы.
В 1.x мир создавался через конструктор с передачей конфигурационного объекта:
var world = new OIMO.World({
timestep: 1/60,
iterations: 8,
broadphase: 2,
worldscale: 1,
gravity: [0, -9.8, 0]
});
Конфигурация включала параметры broadphase, масштабирования и числа итераций солвера.
В 2.x API стало более лаконичным:
var world = new OIMO.World({
gravity: [0, -9.8, 0]
});
Некоторые параметры получили значения по умолчанию, а сложные настройки были скрыты от базового уровня использования.
Ключевое отличие: 2.x делает упор на минимальный конфигурационный вход, снижая порог вхождения.
В ветке 1.x тела создавались через универсальный
метод world.add(), в который передавался большой
конфигурационный объект:
world.add({
type: 'box',
size: [1, 1, 1],
pos: [0, 10, 0],
move: true,
density: 1
});
В 2.x структура параметров была упрощена и унифицирована. Некоторые свойства были переименованы, а логика движения стала более прозрачной:
world.add({
type: 'box',
size: [1, 1, 1],
pos: [0, 10, 0],
density: 1
});
Флаг move был заменён на более явную модель: статическое
тело определяется через density: 0.
Отличие 2.x: устранение дублирующих параметров и переход к физически корректной модели через плотность.
В версии 1.x можно было выбирать тип broadphase через числовой параметр:
В 2.x выбор broadphase чаще всего осуществляется автоматически. Разработчики библиотеки сделали акцент на оптимизированном варианте по умолчанию, устранив необходимость ручной настройки в большинстве случаев.
Это снизило гибкость, но повысило стабильность и предсказуемость поведения.
В 1.x система контактов была более детализированной, но сложной. Доступ к контактным данным требовал обхода внутренних структур:
var contact = world.contacts;
while(contact){
// обработка
contact = contact.next;
}
В 2.x интерфейс работы с контактами стал более упорядоченным, внутренние цепочки были оптимизированы, а структура данных стала легче для анализа.
Основные изменения:
Версия 1.x поддерживала базовые типы ограничений:
В 2.x механизм ограничений был переработан для повышения численной устойчивости. Основные изменения:
Внутренний солвер стал более эффективным, что особенно заметно при большом количестве соединённых тел.
В 1.x активно использовались объекты JavaScript, что приводило к частым выделениям памяти и нагрузке на сборщик мусора.
В 2.x была внедрена стратегия:
Это значительно уменьшило количество GC-паузы в сложных сценах.
В 1.x при большом количестве тел могли наблюдаться:
Версия 2.x улучшила:
Результат — более предсказуемое поведение в динамических сценах.
В 1.x присутствовал параметр
worldscale, позволяющий изменять масштаб симуляции. Это
часто использовалось для адаптации физических величин к визуальной
сцене.
В 2.x данный параметр был исключён или существенно упрощён. Разработчики сделали ставку на использование реальных единиц измерения и корректную настройку размеров объектов.
Изменение философии:
Версия 1.x чаще подключалась как глобальный скрипт:
<script src="oimo.min.js"></script>
В 2.x улучшена совместимость с:
Это упрощает интеграцию в сложные приложения.
В ветке 1.x многие классы имели длинные и не всегда интуитивные названия, отражающие внутреннюю структуру физического ядра.
В 2.x наблюдается:
Например, доступ к позиции и вращению стал проще и логичнее, что облегчает синхронизацию с графическими объектами.
Миграция с 1.x на 2.x не является полностью совместимой:
Старый код требует адаптации, особенно в частях, где использовались расширенные параметры broadphase или нестандартные ограничения.
В 1.x динамичность объекта определялась флагом
move.
В 2.x:
density > 0 — динамическое тело,density = 0 — статическое тело.Такой подход соответствует физической модели твёрдотельной динамики и делает API более логичным.
Версия 1.x иногда демонстрировала нестабильность при сложных вращениях и комбинациях сил.
В 2.x улучшены:
Это особенно важно для механических конструкций и сложных систем ограничений.
| Характеристика | 1.x | 2.x |
|---|---|---|
| Архитектура | Более громоздкая | Упрощённая |
| Настройка мира | Расширенная | Минималистичная |
| Broadphase | Выбирается вручную | Оптимальный по умолчанию |
| Статические тела | Флаг move |
density = 0 |
| Производительность | Ниже при больших сценах | Выше и стабильнее |
| Совместимость | Глобальный скрипт | Поддержка модулей |
| Численная устойчивость | Средняя | Повышенная |
Версия 1.x предоставляет больше низкоуровневого контроля, но требует глубокого понимания внутренней структуры движка. Она подходит для проектов, где важна гибкость и возможность тонкой настройки.
Версия 2.x ориентирована на:
Переход между версиями связан с адаптацией конфигурации тел и пересмотром подхода к масштабированию и статическим объектам, однако выигрыш в устойчивости и простоте сопровождения оправдывает миграцию в большинстве современных проектов.