You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Cannon.js与Three.js的ConvexPolyhedron精确对齐尺寸与方位

问题:Three.js四面体与Cannon.js物理刚体精确对齐

我用Three.js创建了四面体,却只能手动估算顶点和面的参数来构建Cannon.js的ConvexPolyhedron刚体,导致两者无法对齐,代码如下:

const tetrahedronGeometry = new THREE.TetrahedronGeometry(1); // Size of the tetrahedron

const tetraMaterial = new THREE.MeshBasicMaterial({
  color: 0x00ff00,
  wireframe: true,
}); // Green material

const tetrahedron = new THREE.Mesh(tetrahedronGeometry, tetraMaterial);

scene.add(tetrahedron);


const vertices = [
  new CANNON.Vec3(1, 0, 0), // Vertex 0
  new CANNON.Vec3(-0.5, Math.sqrt(3) / 2, 0), // Vertex 1
  new CANNON.Vec3(-0.5, -Math.sqrt(3) / 2, 0), // Vertex 2
  new CANNON.Vec3(0, 0, 1), // Vertex 3
];

const faces = [
  [0, 1, 2], // Face 0 (triangle)
  [0, 3, 1], // Face 1 (triangle)
  [0, 2, 3], // Face 2 (triangle)
  [1, 2, 3], // Face 3 (triangle)
];
const normalsTetra = computeFaceNormals(vertices, faces);

const tetrahedronShape = new CANNON.ConvexPolyhedron({
  vertices,
  faces,
  normalsTetra,
});

const tetrahedronBody = new CANNON.Body({
  mass: 2, // Set mass
  shape: tetrahedronShape,
  position: new CANNON.Vec3(0, 10, 0),
});

效果显示两者错位,请问有没有程序化方法让它们尺寸、方位精确对齐?


解决方案:从Three.js几何体直接提取数据构建Cannon刚体

不需要手动估算顶点和面,直接从Three.js的TetrahedronGeometry中提取现成的顶点和面数据,就能保证完全对齐:

1. 提取顶点数据

Three.js的几何体顶点存储在geometry.attributes.position.array中,每三个连续数值对应一个顶点的x、y、z坐标,直接遍历转换为Cannon的Vec3即可。

2. 提取面索引数据

Three.js的几何体面索引存储在geometry.index.array中,每三个连续数值对应一个三角形面的顶点索引,按组提取后就是Cannon需要的面数组。

3. 自动计算法向量(可选)

Cannon.js的ConvexPolyhedron可以自动计算面法向量,不需要手动调用computeFaceNormals,只需传入vertices和faces即可。

完整修正代码

const tetrahedronGeometry = new THREE.TetrahedronGeometry(1);
const tetraMaterial = new THREE.MeshBasicMaterial({
  color: 0x00ff00,
  wireframe: true,
});
const tetrahedron = new THREE.Mesh(tetrahedronGeometry, tetraMaterial);
scene.add(tetrahedron);

// 从Three.js几何体提取顶点转换为Cannon Vec3
const vertices = [];
const positionArray = tetrahedronGeometry.attributes.position.array;
for (let i = 0; i < positionArray.length; i += 3) {
  vertices.push(new CANNON.Vec3(
    positionArray[i],
    positionArray[i + 1],
    positionArray[i + 2]
  ));
}

// 从Three.js几何体提取面索引
const faces = [];
const indexArray = tetrahedronGeometry.index.array;
for (let i = 0; i < indexArray.length; i += 3) {
  faces.push([
    indexArray[i],
    indexArray[i + 1],
    indexArray[i + 2]
  ]);
}

// 创建Cannon凸多面体形状(自动计算法向量)
const tetrahedronShape = new CANNON.ConvexPolyhedron({ vertices, faces });

const tetrahedronBody = new CANNON.Body({
  mass: 2,
  shape: tetrahedronShape,
  position: new CANNON.Vec3(0, 10, 0),
});
world.addBody(tetrahedronBody); // 记得添加到物理世界

// 同步Three.js模型与Cannon刚体的位置旋转
function animate() {
  requestAnimationFrame(animate);
  world.step(1/60);
  
  // 同步位置和旋转
  tetrahedron.position.copy(tetrahedronBody.position);
  tetrahedron.quaternion.copy(tetrahedronBody.quaternion);
  
  renderer.render(scene, camera);
}
animate();

关键说明

  • 之前错位的原因是手动定义的顶点尺寸、坐标与Three.jsTetrahedronGeometry的内置顶点不匹配,TetrahedronGeometry(1)的顶点是基于正四面体的标准坐标,并非手动估算的数值。
  • 这种方法也适用于其他Three.js凸面几何体(如CubeGeometry、OctahedronGeometry等),只要是凸多面体都可以用同样的逻辑提取数据构建Cannon刚体。

内容的提问来源于stack exchange,提问作者Samarth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 00:22:42