Получение информации о контакте через ContactInfo

Библиотека Oimo.js предоставляет мощный движок физики для симуляции твердых тел в 3D-пространстве на языке JavaScript. Одной из ключевых возможностей при работе с физикой является обработка столкновений и получение подробной информации о контактах между телами. Для этого используется объект ContactInfo, который содержит полный набор данных о столкновении.

Структура объекта ContactInfo

Объект ContactInfo создаётся системой Oimo.js автоматически для каждого контакта между телами и включает следующие основные поля:

  • shape1 – первый объект формы (Oimo.Shape), участвующий в контакте.
  • shape2 – второй объект формы (Oimo.Shape) в контакте.
  • body1 – тело (Oimo.RigidBody), которому принадлежит shape1.
  • body2 – тело (Oimo.RigidBody), которому принадлежит shape2.
  • point – вектор (Oimo.Vec3) координат точки контакта в мировых координатах.
  • normal – нормаль контакта (Oimo.Vec3), указывающая от body1 к body2.
  • depth – глубина проникновения (penetration depth), числовое значение, показывающее, насколько тела перекрываются.
  • impulse – величина силы импульса, применённого для корректировки столкновения.
  • friction – коэффициент трения в точке контакта.

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

Получение списка контактов

Для анализа всех текущих контактов в мире используется объект Oimo.World, который содержит методы и события для отслеживания столкновений. Основной подход:

world.contacts.forEach(contact => {
    console.log(contact.point);   // точка контакта
    console.log(contact.normal);  // нормаль столкновения
    console.log(contact.depth);   // глубина проникновения
});

world.contacts возвращает массив объектов ContactInfo, автоматически обновляемый на каждом шаге симуляции.

Использование глубины и нормали контакта

  • Глубина проникновения позволяет определить степень наложения тел. Она используется для расчёта корректирующих импульсов и предотвращения “проваливания” тел друг в друга.
  • Нормаль контакта критична для определения направления силы реакции. Направление нормали всегда от body1 к body2, что облегчает применение импульса для возвращения тел в допустимую позицию.

Пример применения:

world.contacts.forEach(contact => {
    const impulseVector = contact.normal.clone().scale(contact.depth * 0.5);
    contact.body1.applyImpulse(impulseVector);
    contact.body2.applyImpulse(impulseVector.clone().scale(-1));
});

В этом примере используется нормаль контакта для симметричного приложения импульса к телам.

Фильтрация контактов по телам или формам

Иногда требуется обработать контакты только для определённых объектов:

world.contacts.forEach(contact => {
    if(contact.body1.name === "player" || contact.body2.name === "player") {
        console.log("Контакт с игроком:", contact.point, contact.depth);
    }
});

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

Работа с трением и импульсом

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

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

world.contacts.forEach(contact => {
    if(contact.impulse > 10) {
        console.log("Сильный удар между телами:", contact.body1.name, contact.body2.name);
    }
});

Такой подход позволяет идентифицировать интенсивные столкновения и реализовать соответствующую реакцию в логике симуляции.

Объединение ContactInfo с визуализацией

Для отладки и визуализации контактов можно создать вспомогательные объекты, которые отображают точку и нормаль контакта:

world.contacts.forEach(contact => {
    drawSphere(contact.point, 0.05, 0xff0000);
    drawArrow(contact.point, contact.normal, 0.2, 0x00ff00);
});
  • Красная сфера – точка контакта.
  • Зелёная стрелка – нормаль контакта.

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

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

  • Использовать ContactInfo для детального анализа столкновений.
  • Применять нормаль и глубину контакта для расчёта реактивных импульсов.
  • Фильтровать контакты по телам и формам для управления игровой логикой.
  • Использовать визуализацию точек контакта для отладки симуляции.
  • Контроль трения и импульса помогает создавать реалистичное физическое поведение объектов.

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