Фильтрация столкновений является одной из ключевых возможностей физических движков, позволяющей контролировать, какие объекты могут взаимодействовать друг с другом. В библиотеке Oimo.js используется система collision groups, которая обеспечивает гибкое управление столкновениями между телами.
Каждое тело в Oimo.js может быть отнесено к одной или нескольким группам столкновений, представленных в виде битовых масок. Это позволяет задавать правила, по которым тело будет реагировать на другие объекты.
Основные элементы фильтрации:
Физический движок проверяет столкновения по следующему правилу:
(bodyA.group & bodyB.mask) !== 0 && (bodyB.group & bodyA.mask) !== 0
Если условие истинно, столкновение учитывается в симуляции; если ложно — объекты проходят сквозь друг друга без реакции.
Для задания collision group при создании тела используется свойство
group объекта конфигурации, а для mask — свойство
mask.
Пример создания двух тел с фильтрацией:
import * as OIMO from 'oimo';
const world = new OIMO.World();
// Тело принадлежит группе 1, сталкивается только с группой 2
const boxA = world.add({
type: 'box',
size: [1, 1, 1],
pos: [0, 5, 0],
move: true,
group: 1,
mask: 2
});
// Тело принадлежит группе 2, сталкивается с группой 1
const boxB = world.add({
type: 'box',
size: [1, 1, 1],
pos: [0, 0, 0],
move: false,
group: 2,
mask: 1
});
В данном примере boxA будет реагировать только на boxB, и наоборот. Любые другие тела, которые не входят в соответствующую группу, будут игнорироваться.
Одно тело может принадлежать сразу нескольким группам. Для этого
используется побитовое ИЛИ (|) при указании числа группы и
маски:
const boxC = world.add({
type: 'sphere',
size: [0.5],
pos: [2, 5, 0],
move: true,
group: 1 | 4, // тело принадлежит группе 1 и 4
mask: 2 | 8 // сталкивается с группами 2 и 8
});
Таким образом, boxC будет сталкиваться с объектами из групп 2 и 8, но не с объектами, которые принадлежат только к 1 или 4, если они не входят в маску.
Группы столкновений и маски можно изменять динамически после создания тела. Это позволяет включать и отключать столкновения по мере работы симуляции:
// Добавление тела в новую группу
boxA.group |= 4; // теперь тело принадлежит группам 1 и 4
// Изменение маски столкновений
boxA.mask = 2 | 8; // теперь тело сталкивается с группами 2 и 8
При изменении масок столкновений Oimo.js учитывает новые правила сразу, без необходимости пересоздавать тело.
Фильтрация через collision groups предоставляет мощный инструмент управления физическим взаимодействием объектов, позволяя создавать сложные и оптимизированные симуляции с минимальными избыточными проверками столкновений.