Библиотека Oimo.js предоставляет мощный движок физики для симуляции твердых тел в 3D-пространстве на языке JavaScript. Одной из ключевых возможностей при работе с физикой является обработка столкновений и получение подробной информации о контактах между телами. Для этого используется объект ContactInfo, который содержит полный набор данных о столкновении.
Объект ContactInfo создаётся системой Oimo.js автоматически для каждого контакта между телами и включает следующие основные поля:
Oimo.Shape), участвующий в контакте.Oimo.Shape) в контакте.Oimo.RigidBody),
которому принадлежит shape1.Oimo.RigidBody),
которому принадлежит shape2.Oimo.Vec3) координат
точки контакта в мировых координатах.Oimo.Vec3),
указывающая от body1 к body2.Эти поля позволяют получить детальные сведения о взаимодействии тел, необходимые для расчёта физических реакций, визуализации столкновений и настройки поведения объектов.
Для анализа всех текущих контактов в мире используется объект
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);
}
});
Это позволяет реализовать игровую логику, коллизии для персонажей или интерактивных объектов.
Пример контроля импульса:
world.contacts.forEach(contact => {
if(contact.impulse > 10) {
console.log("Сильный удар между телами:", contact.body1.name, contact.body2.name);
}
});
Такой подход позволяет идентифицировать интенсивные столкновения и реализовать соответствующую реакцию в логике симуляции.
Для отладки и визуализации контактов можно создать вспомогательные объекты, которые отображают точку и нормаль контакта:
world.contacts.forEach(contact => {
drawSphere(contact.point, 0.05, 0xff0000);
drawArrow(contact.point, contact.normal, 0.2, 0x00ff00);
});
Это позволяет наглядно отслеживать динамику столкновений и корректность работы физического движка.
ContactInfo для детального анализа
столкновений.Эффективное использование ContactInfo делает симуляции в Oimo.js точными, детализированными и гибкими для любых игровых или инженерных приложений.