Параметр numVelocityIterations

Библиотека Oimo.js реализует физический движок на основе метода rigid body dynamics, где расчёт движения объектов зависит от итеративных процедур решения уравнений движения и ограничений. Одним из ключевых параметров управления точностью симуляции является numVelocityIterations.

Определение и назначение

numVelocityIterations задаёт количество итераций, которые движок выполняет для корректировки скоростей тел в процессе разрешения ограничений, таких как столкновения и соединения. В физическом движке каждая итерация улучшает точность вычисления скоростей и, как следствие, уменьшает просачивание тел через друг друга и повышает стабильность симуляции.

  • Тип значения: целое число (integer)
  • Диапазон: обычно от 1 до 20, но может быть больше для сложных сцен.
  • По умолчанию: 8 в большинстве конфигураций Oimo.js

Механизм работы

При симуляции кадр делится на несколько этапов:

  1. Интеграция скоростей: вычисляются новые скорости тел с учётом сил (гравитации, внешних воздействий).
  2. Решение ограничений: движок многократно корректирует скорости, чтобы удовлетворить условия контактов и соединений.
  3. Интеграция позиций: пересчитываются новые позиции тел на основе скоростей.

Именно на втором этапе задействуется numVelocityIterations. Каждая итерация проходит по всем контактам и соединениям, корректируя скорости так, чтобы:

  • уменьшить скольжение и проникновение тел,
  • обеспечить соблюдение ограничений соединений (hinges, joints, springs),
  • стабилизировать энергетику системы при столкновениях.

Увеличение числа итераций повышает точность решения, но напрямую влияет на производительность.

Влияние на точность и стабильность

  • Малое значение (1–3):

    • Быстрая симуляция, низкая нагрузка на CPU.
    • Телам легче «проходить сквозь друг друга» при столкновениях.
    • Соединения могут выглядеть мягкими или расшатанными.
  • Среднее значение (4–8):

    • Баланс между точностью и производительностью.
    • Типичный выбор для динамичных сцен с множеством объектов.
  • Высокое значение (9–20+):

    • Минимизация ошибок проникновения и проскальзывания.
    • Может заметно замедлить симуляцию при большом числе тел.
    • Желательно для статических или медленно движущихся объектов, где важна точность.

Практические рекомендации

  1. Для простых сцен с небольшим числом объектов достаточно значений 4–6.
  2. Для сложных механизмов и многоступенчатых соединений целесообразно поднять до 10–12.
  3. При симуляции высокоскоростных столкновений необходимо увеличить до 15–20, чтобы предотвратить проникновение.
  4. В сочетании с numPositionIterations следует соблюдать баланс: слишком высокая точность скоростей без достаточных итераций для позиций может привести к нестабильности.

Пример настройки

const world = new OIMO.World({
    timestep: 1/60,
    iterations: 8, // общее число итераций
    broadphase: 2, // тип broadphase
    worldscale: 1,
    random: true,
});

// При создании тела можно явно указать numVelocityIterations
const box = world.add({
    type: "box",
    size: [1, 1, 1],
    pos: [0, 10, 0],
    move: true,
    density: 1,
    friction: 0.4,
    restitution: 0.1,
    numVelocityIterations: 12
});

В этом примере тело box будет обрабатываться с повышенной точностью расчёта скоростей, что важно для предотвращения ошибок при столкновениях с другими объектами.

Взаимодействие с другими параметрами

  • numPositionIterations – управляет точностью корректировки позиций.
  • timestep – размер шага симуляции: меньший шаг позволяет использовать меньше итераций без потери точности.
  • friction и restitution – параметры материала: при высоких значениях трения или упругости стоит увеличить numVelocityIterations, чтобы уменьшить проскакивание и проскальзывание.

Использование numVelocityIterations является критическим для создания реалистичной симуляции в Oimo.js. Правильная настройка позволяет достичь баланса между стабильностью, точностью и производительностью, особенно в сценах с большим числом динамических объектов или сложными механическими соединениями.