Cannon.js — это мощная физическая библиотека для JavaScript, предназначенная для симуляции твёрдого тела и взаимодействий в 3D-пространстве. Одним из ключевых аспектов работы с физикой является отслеживание контактов между объектами и вычисление возникающих при этом сил. Это важно как для отладки физической симуляции, так и для создания эффектных взаимодействий, например, при столкновениях или нажатиях.
Cannon.js использует систему событий для уведомления о взаимодействиях тел. Основные события, связанные с контактами:
collide — срабатывает при столкновении двух тел.beginContact и endContact — используются
для начала и окончания контакта (доступно через расширения или
пользовательские обработчики).Пример регистрации события collide для конкретного
тела:
bodyA.addEventListener('collide', function(event) {
const bodyB = event.body; // Другое тело, с которым произошло столкновение
const contact = event.contact; // Объект контакта с параметрами
console.log('Столкновение с телом:', bodyB.id);
});
Объект contact содержит важную информацию о
столкновении:
contact.bi и contact.bj — тела,
участвующие в контакте.contact.ni — нормаль столкновения, направленная от
bi к bj.contact.ri и contact.rj — векторы от
центров масс тел до точки контакта.contact.getImpactVelocityAlongNormal() — скорость
сближения тел вдоль нормали.Эти данные позволяют логировать как факт контакта, так и его динамику.
Для глобального логирования всех контактов удобно использовать массив
world.contacts, который заполняется при каждом шаге
симуляции:
world.step(timeStep);
world.contacts.forEach(contact => {
const bodyA = contact.bi;
const bodyB = contact.bj;
const normal = contact.ni;
const impactVelocity = contact.getImpactVelocityAlongNormal();
console.log(`Контакт между ${bodyA.id} и ${bodyB.id}`);
console.log(`Нормаль: x=${normal.x}, y=${normal.y}, z=${normal.z}`);
console.log(`Скорость сближения: ${impactVelocity}`);
});
Важно учитывать, что world.contacts доступен только
после вызова world.step, так как контакты вычисляются в
процессе интеграции.
Для вычисления и отслеживания сил контакта можно использовать объект
ContactEquation, который создаётся Cannon.js автоматически
для каждого контакта. Основные свойства:
contactEquation.jacobianElementA и
contactEquation.jacobianElementB — матрицы Якоби для тел,
участвующих в контакте.contactEquation.multiplier — коэффициент силы,
действующей вдоль нормали.contactEquation.ni — нормаль контакта.Пример получения силы контакта для одного контакта:
bodyA.addEventListener('collide', function(event) {
const contact = event.contact;
const forceMagnitude = contact.getImpactVelocityAlongNormal() * contact.bi.mass;
console.log(`Сила контакта: ${forceMagnitude.toFixed(2)}`);
});
Этот подход позволяет не только визуализировать столкновения, но и использовать силы для геймплейных эффектов: отбрасывание объектов, повреждения или звуковые эффекты.
Для наглядного логирования контактов часто используют вспомогательные объекты, например, маленькие сферы в точках столкновения:
const sphereGeo = new THREE.SphereGeometry(0.05, 8, 8);
const sphereMat = new THREE.MeshBasicMaterial({ color: 0xff0000 });
bodyA.addEventListener('collide', function(event) {
const contactPoint = event.contact.rj.vadd(event.body.position);
const sphere = new THREE.Mesh(sphereGeo, sphereMat);
sphere.position.copy(contactPoint);
scene.add(sphere);
});
Визуализация помогает убедиться, что расчёт нормалей и сил совпадает с ожидаемым поведением в пространстве.
В сложных симуляциях часто необходимо контролировать количество контактов и максимальные силы, чтобы избежать нестабильности:
let maxForce = 0;
world.step(timeStep);
world.contacts.forEach(contact => {
const force = contact.getImpactVelocityAlongNormal() * contact.bi.mass;
if(force > maxForce) maxForce = force;
});
console.log(`Максимальная сила за шаг: ${maxForce.toFixed(2)}`);
Это позволяет отлаживать параметры friction,
restitution и mass тел для стабильной
симуляции.
getImpactVelocityAlongNormal() для расчёта
динамических эффектов, так как она учитывает относительное движение
тел.Эти подходы формируют основу систем мониторинга и отладки физики в Cannon.js, обеспечивая контроль над контактами и силами в реальном времени.