如何让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.js
TetrahedronGeometry的内置顶点不匹配,TetrahedronGeometry(1)的顶点是基于正四面体的标准坐标,并非手动估算的数值。 - 这种方法也适用于其他Three.js凸面几何体(如CubeGeometry、OctahedronGeometry等),只要是凸多面体都可以用同样的逻辑提取数据构建Cannon刚体。
内容的提问来源于stack exchange,提问作者Samarth
相关产品推荐
相关产品推荐

