Библиотека Oimo.js предоставляет эффективный движок физического моделирования твёрдых тел в среде JavaScript, основой которого является итерационный импульсный решатель (Iterative Impulse Solver). Этот компонент отвечает за корректное вычисление столкновений, ограничения движения и реакций между объектами в реальном времени.
Итерационный импульсный решатель оперирует не с аналитическим решением системы уравнений, а с приближенными решениями, которые постепенно уточняются через несколько итераций. Каждое столкновение и ограничение модели представлено в виде импульса, который применяется к телам для изменения их скорости и угловой скорости.
Для двух тел с массами ( m_1 ) и ( m_2 ), сталкивающихся с относительной скоростью ( v_{rel} ), изменение скорости определяется формулой:
[ J = - (1 + e) ]
где:
Импульс добавляется к линейной и угловой скорости объектов:
[ v_1’ = v_1 + n, v_2’ = v_2 - n]
Решатель выполняет несколько проходов по всем столкновениям и ограничениям. В каждом проходе импульсы корректируют текущие скорости объектов. Такой подход позволяет устранить накопленные ошибки, вызванные множественными пересекающимися контактами.
Ключевые шаги итерационного цикла:
Количество итераций влияет на точность: 4–10 итераций достаточно для большинства игр, 20 и более требуется для сцен с плотным взаимодействием объектов.
Oimo.js использует решатель также для поддержки жёстких соединений (joints), таких как шарнирные, пружинные или фиксированные соединения. Каждое соединение создаёт собственное линейное и угловое ограничение, которое в виде импульса корректирует движение объектов.
Пример применения импульса для шарнирного соединения:
[ v_a’ = v_a + n, v_b’ = v_b - n]
где ( n ) направлен вдоль оси ограничения. Для более сложных соединений импульсы могут включать в себя торсионные составляющие, учитывая момент инерции.
Фрикция рассчитывается после нормального импульса и зависит от коэффициента трения ( ). Решатель ограничивает касательные импульсы по формуле:
[ |J_t| |J_n|]
где ( J_n ) — нормальный импульс. Это обеспечивает реалистичное скольжение и предотвращает «залипание» объектов при контакте.
Oimo.js использует фиксированный временной шаг ( t ) для расчёта новых скоростей:
[ v_{t+t} = v_t + a t]
Импульсы корректируют уже интегрированные скорости, что позволяет решателю учитывать как внешние силы (гравитацию, силу пользователя), так и внутренние ограничения.
Итерационный импульсный решатель является ядром физического движка Oimo.js, обеспечивая реалистичное взаимодействие объектов, балансируя между точностью и производительностью, и поддерживая сложные механические соединения и контактные сцены.