Настройка contactCallback на уровне Shape

В Oimo.js взаимодействие физических объектов между собой определяется коллизиями, которые регистрируются на уровне тел (RigidBody) и форм (Shape). Для более детального контроля коллизий используется механизм contact callbacks. Хотя коллбэки можно назначать на уровне тела, настройка их на уровне отдельной формы (Shape) предоставляет возможность реагировать только на конкретные компоненты тела, что особенно важно для сложных составных объектов.

Основы contactCallback

Каждая форма (Shape) в Oimo.js может иметь собственный contact callback. Это функция, вызываемая при столкновении данной формы с другой формой. Сигнатура функции имеет следующий вид:

function callback(contactPoint, otherShape, thisShape) {
    // contactPoint — объект с информацией о точке контакта
    // otherShape — форма, с которой произошло столкновение
    // thisShape — текущая форма, на которой установлен callback
}
  • contactPoint содержит координаты столкновения, нормаль, силу реакции и другие данные.
  • otherShape позволяет определить, с каким объектом произошло взаимодействие.
  • thisShape используется для идентификации формы, вызвавшей коллбэк.

Привязка callback к Shape

Для назначения коллбэка используется свойство contactCallback формы:

let shape = body.addShape(new OIMO.Shape({
    type: 'box',
    size: [1, 1, 1],
    pos: [0, 0, 0],
    density: 1
}));

shape.contactCallback = function(contactPoint, otherShape, thisShape) {
    console.log('Столкновение формы', thisShape, 'с формой', otherShape);
};

Здесь коллбэк будет срабатывать только при контакте этой конкретной формы, независимо от остальных форм тела.

Фильтрация столкновений

Для оптимизации и предотвращения лишних вызовов коллбэка используется фильтрация по маске групп и категорий:

shape.filterGroup = 1;    // группа формы
shape.filterMask  = 2;    // с какими группами разрешено взаимодействие
  • filterGroup определяет принадлежность формы к конкретной группе.
  • filterMask определяет, с какими группами эта форма может вступать в контакт.

Коллбэк будет вызван только если другой объект принадлежит разрешённой группе.

Использование нескольких callback для составных объектов

Составные тела (Compound Bodies) содержат несколько форм. Каждая форма может иметь свой contactCallback. Это позволяет:

  • Определять, какая часть объекта получила удар.
  • Реализовывать индивидуальные реакции для разных компонентов.
  • Управлять событиями столкновений на уровне деталей, не создавая отдельные тела.

Пример:

let compoundBody = world.add({
    type: 'rigidBody',
    shapes: [
        { type: 'box', size: [2, 1, 1], pos: [0, 0, 0] },
        { type: 'sphere', size: [0.5], pos: [0, 1, 0] }
    ]
});

compoundBody.shapes[0].contactCallback = (cp, other, self) => {
    console.log('Контакт с нижней коробкой');
};

compoundBody.shapes[1].contactCallback = (cp, other, self) => {
    console.log('Контакт с верхним шаром');
};

Доступ к дополнительной информации контакта

Объект contactPoint предоставляет следующие ключевые свойства:

  • position — координаты точки контакта в мировых координатах.
  • normal — вектор нормали от текущей формы к другой.
  • penetrationDepth — глубина проникновения объектов.
  • impulse — сила, приложенная к телу в момент контакта.

Эта информация позволяет рассчитывать реакцию, например, изменение цвета объекта, проигрывание анимации или вычисление повреждений в игровом движке.

Особенности производительности

Назначение contactCallback на уровне форм незначительно увеличивает нагрузку при большом количестве объектов. Чтобы снизить влияние на производительность:

  1. Использовать фильтры filterGroup и filterMask.
  2. Ограничивать количество форм с активными коллбэками.
  3. Внутри callback минимизировать сложные вычисления; лучше помечать события и обрабатывать их вне цикла физики.

Примеры практического применения

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

Итоговые рекомендации по настройке

  • Всегда назначать callback на форме, а не на теле, если нужна точная реакция.
  • Использовать фильтры для ограничения вызовов и повышения производительности.
  • Доступ к полям contactPoint позволяет реализовать сложную логику взаимодействия.
  • Для составных объектов каждая форма может иметь свой callback, что открывает возможности для детализированной физики и игрового взаимодействия.

Настройка contactCallback на уровне формы в Oimo.js обеспечивает гибкий и точный контроль за столкновениями, позволяя создавать сложные физические реакции без необходимости дробить объекты на отдельные тела.