В библиотеке Cannon.js для имитации физики 3D-объектов используется класс Body, который отвечает за физическое поведение объектов: массу, инерцию, силы и столкновения. Для визуализации этих объектов в сцене обычно применяется Three.js или аналогичная графическая библиотека. Связка Body–Mesh обеспечивает синхронизацию физики и визуальной модели, создавая удобный интерфейс для работы с динамическими объектами.
Body — это объект физического мира. У него есть свойства:
mass — масса тела.position — текущее положение в пространстве.quaternion — ориентация в виде кватерниона.velocity и angularVelocity — линейная и
угловая скорость.shape — геометрическая форма для столкновений (Box,
Sphere, Plane, ConvexPolyhedron и др.).Mesh — визуальное представление объекта. В
Three.js это THREE.Mesh с геометрией и материалом. Mesh
не участвует в расчетах физики, он лишь отображает
состояние Body.
Ключевой момент: Body является источником истины для позиции и ориентации объекта, Mesh просто повторяет эти параметры.
Класс-обёртка объединяет Body и Mesh, предоставляя единый интерфейс для управления объектом.
class PhysicsObject {
constructor(mesh, shape, mass = 1) {
this.mesh = mesh;
this.body = new CANNON.Body({
mass: mass,
shape: shape,
position: new CANNON.Vec3(mesh.position.x, mesh.position.y, mesh.position.z)
});
}
updateMesh() {
// Обновление позиции и ориентации Mesh на основе Body
this.mesh.position.copy(this.body.position);
this.mesh.quaternion.copy(this.body.quaternion);
}
applyForce(forceVector, relativePoint) {
this.body.applyForce(
new CANNON.Vec3(forceVector.x, forceVector.y, forceVector.z),
new CANNON.Vec3(relativePoint.x, relativePoint.y, relativePoint.z)
);
}
applyImpulse(impulseVector, relativePoint) {
this.body.applyImpulse(
new CANNON.Vec3(impulseVector.x, impulseVector.y, impulseVector.z),
new CANNON.Vec3(relativePoint.x, relativePoint.y, relativePoint.z)
);
}
}
Особенности класса:
updateMesh
должен вызываться на каждом кадре после шага симуляции Cannon.js.applyForce и
applyImpulse позволяют реализовать взаимодействие с телами
динамически.position и quaternion.const sphereGeometry = new THREE.SphereGeometry(1, 32, 32);
const sphereMaterial = new THREE.MeshStandardMaterial({ color: 0xff0000 });
const sphereMesh = new THREE.Mesh(sphereGeometry, sphereMaterial);
const sphereShape = new CANNON.Sphere(1);
const physicsSphere = new PhysicsObject(sphereMesh, sphereShape, 5);
world.addBody(physicsSphere.body);
scene.add(physicsSphere.mesh);
После этого объект начинает взаимодействовать с другими телами и гравитацией в Cannon.js, а визуальная часть отображает текущее состояние физики.
Для корректной работы необходимо синхронизировать Mesh с Body после шага физического мира:
function animate() {
requestAnimationFrame(animate);
// Шаг физического мира
world.step(1/60);
// Синхронизация Mesh с Body
physicsSphere.updateMesh();
renderer.render(scene, camera);
}
animate();
body.addEventListener('collide', callback) и обрабатывать
физические контакты.body.shape позволяет изменять физические свойства без
пересоздания объекта, важно лишь обновить инерцию через
body.updateMassProperties().mass = 0) Body становится статическим и не подвержен
силам.world.step(fixedTimeStep, deltaTime, maxSubSteps).class PhysicsGroup {
constructor() {
this.objects = [];
}
add(mesh, shape, mass) {
const obj = new PhysicsObject(mesh, shape, mass);
this.objects.push(obj);
world.addBody(obj.body);
scene.add(obj.mesh);
return obj;
}
update() {
this.objects.forEach(obj => obj.updateMesh());
}
}
Использование PhysicsGroup упрощает управление
множеством динамических объектов и их обновление на каждом кадре.
Связка Body–Mesh в Cannon.js является фундаментальной для интеграции физики с графикой, обеспечивая точное и удобное управление объектами, динамическое взаимодействие и возможность масштабирования симуляции от одного тела до сложных систем.