Пространственное разбиение — ключевой механизм оптимизации физического движка Oimo.js, позволяющий эффективно обрабатывать столкновения и уменьшать вычислительную нагрузку при большом количестве объектов. В основе лежит разделение сцены на логические блоки или ячейки, чтобы проверка пересечений выполнялась только между объектами, находящимися в одной ячейке или соседних ячейках.
Oimo.js использует Spatial Hashing, где 3D-пространство разбивается на кубические ячейки одинакового размера. Каждому объекту соответствует набор ячеек, которые он занимает. Основные параметры:
Пример инициализации мира с настройкой пространственного разбиения:
const world = new OIMO.World({
timestep: 1/60,
iterations: 8,
broadphase: 2, // 2 = Spatial Hash
worldscale: 1,
random: true
});
world.broadphase.cellSize = 2;
world.broadphase.hashMask = 1023;
Здесь broadphase: 2 указывает на использование
Spatial Hash. Свойство cellSize задаёт размер ячеек, а
hashMask — маску для быстрого вычисления индекса в
хэш-таблице.
Размер ячейки определяет, как движок будет фильтровать возможные столкновения:
Практическая рекомендация — выбирать размер ячейки примерно равный максимальному размеру объекта, либо чуть больше среднего размера всех динамических тел в сцене.
Oimo.js автоматически обновляет позиции объектов в пространственном разбиении каждый кадр. Однако для объектов с высокой скоростью движения важно корректно настраивать ширину ячеек и timestep, чтобы объекты не «проскальзывали» между ячейками без регистрации.
Дополнительный параметр worldscale влияет на числовую точность расчётов: уменьшение масштаба повышает стабильность маленьких объектов при больших сценах.
Oimo.js поддерживает несколько типов широкофазного алгоритма:
Spatial Hash является оптимальным вариантом для сцен с сотнями динамических тел, где столкновения распределены по всему пространству.
Каждая ячейка учитывает соседние 26 ячеек (включая диагональные), чтобы не пропустить столкновения между объектами, находящимися на границах ячеек. Параметры соседей задаются внутренне, но понимание их работы важно для анализа производительности. Увеличение размера ячеек снижает количество соседей, уменьшение — увеличивает.
cellSize.timestep или использовать суб-итерации.Пространственное разбиение в Oimo.js — фундаментальная оптимизация, позволяющая масштабировать физические симуляции. Точное понимание работы Spatial Hash, размеров ячеек и соседних проверок обеспечивает стабильность и высокую производительность сцены.