要让 Three.js 渲染的物体与 Cannon.js 物理引擎中的 Body
保持一致,你需要在 动画循环 (tick
) 里同步 position
和 quaternion
,让 Three.js
物体的位置和旋转跟随 Cannon.js
的物理模拟。
🔥 核心代码
const tick = () => {
world.step(1/60); // **更新物理世界**
// **遍历所有物体,让 Three.js 物体与 Cannon.js 物体同步**
for (const obj of objects) {
obj.mesh.position.copy(obj.body.position);
obj.mesh.quaternion.copy(obj.body.quaternion);
}
// 渲染 Three.js 场景
renderer.render(scene, camera);
requestAnimationFrame(tick);
};
🚀 详细步骤
1️⃣ 初始化物理世界(Cannon.js)
import * as THREE from 'three';
import * as CANNON from 'cannon-es';
// 创建 Cannon.js 物理世界
const world = new CANNON.World();
world.gravity.set(0, -9.82, 0); // 添加重力
2️⃣ 创建物理 Body(Cannon.js)
const body = new CANNON.Body({
mass: 1, // 质量(0 代表静止物体)
shape: new CANNON.Sphere(1), // 形状:球体
position: new CANNON.Vec3(0, 5, 0), // 初始位置
});
world.addBody(body);
3️⃣ 创建 Three.js 物体
const geometry = new THREE.SphereGeometry(1, 32, 32);
const material = new THREE.MeshStandardMaterial({ color: 0xff0000 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
4️⃣ 让 mesh
和 body
关联
const objects = [{ mesh, body }];
5️⃣ 动画循环:同步 Three.js
物体与 Cannon.js
const tick = () => {
world.step(1/60); // **更新 Cannon.js 物理世界**
// **同步 Three.js 物体**
for (const obj of objects) {
obj.mesh.position.copy(obj.body.position);
obj.mesh.quaternion.copy(obj.body.quaternion);
}
// 渲染
renderer.render(scene, camera);
requestAnimationFrame(tick);
};
tick(); // 开始动画循环
✅ 关键点
world.step(1/60)
👉 物理引擎每帧更新一次。mesh.position.copy(body.position)
👉 确保 Three.js 物体位置跟随物理世界的body
。mesh.quaternion.copy(body.quaternion)
👉 确保 Three.js 物体的旋转同步。- 循环
objects
数组 👉 适用于多个物体,不用手动同步每个物体。
🎯 总结
如果 Three.js 物体和 Cannon.js 物理模拟不同步:
- ✅ 检查
body
是否有mass
(mass=0
代表静止物体)。 - ✅ 确保
tick()
动画循环里更新position
和quaternion
。 - ✅ 使用
world.step(1/60)
来保持物理引擎的稳定模拟。
这样,Three.js 的渲染结果就会完全跟随 Cannon.js 物理模拟的运动! 🚀