ThreeJS中如何手动设置加载的GLTF模型的枢轴点?
解决Three.js中GLTF模型枢轴点偏移的问题
当然可以手动调整模型的枢轴点或中心位置,下面提供两种实用的解决方法:
方法一:直接修正几何体的中心
这种方法通过修改模型几何体的顶点数据,将模型的几何中心对齐到局部坐标系原点,适合需要让模型自身围绕中心旋转的场景。
gltfLoader.load('assets/models/coin/scene.gltf', (gltf) => { const root = gltf.scene; // 保留原有的阴影与材质处理逻辑 root.traverse(function(node){ if ( node.isMesh ) { node.castShadow = true; node.receiveShadow = true; if(node.material.map) { node.material.map.anisotropy = 16; } // 计算当前网格的包围盒 const boundingBox = new THREE.Box3().setFromObject(node); const meshCenter = boundingBox.getCenter(new THREE.Vector3()); // 平移几何体,让网格中心对齐局部原点 node.geometry.translate(-meshCenter.x, -meshCenter.y, -meshCenter.z); // 更新几何体的边界信息 node.geometry.computeBoundingBox(); node.geometry.computeBoundingSphere(); } }) root.position.set(0, 0, 0); root.scale.set(20, 20, 20); coinBox = new THREE.BoxHelper( root, 0xffff00 ); scene.add(coinBox); coin = root; scene.add(root); // 枢轴点可视化逻辑 const circleGeometry = new THREE.CircleGeometry(3, 64); const circleMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 }); const circleMesh = new THREE.Mesh(circleGeometry, circleMaterial); circleMesh.position.copy(root.position); circleMesh.position.y += 1; scene.add(circleMesh); });
说明:如果模型包含多个子网格,每个网格都会被单独调整到自身的几何中心。若需要让整个模型围绕整体中心旋转,建议使用第二种方法。
方法二:通过父对象重新定义枢轴
这种方法无需修改原始几何体,而是通过创建一个空的Object3D作为父对象,将模型挂载到父对象下并调整位置,让模型中心对齐父对象原点,后续旋转父对象即可实现围绕模型中心旋转的效果。
gltfLoader.load('assets/models/coin/scene.gltf', (gltf) => { const root = gltf.scene; // 保留原有的阴影与材质处理逻辑 root.traverse(function(node){ if ( node.isMesh ) { node.castShadow = true; node.receiveShadow = true; if(node.material.map) { node.material.map.anisotropy = 16; } } }) root.scale.set(20, 20, 20); // 计算整个模型的包围盒与中心 const modelBoundingBox = new THREE.Box3().setFromObject(root); const modelCenter = modelBoundingBox.getCenter(new THREE.Vector3()); // 创建空对象作为新的枢轴载体 const pivot = new THREE.Object3D(); // 调整模型位置,让模型中心对齐枢轴原点 root.position.sub(modelCenter); pivot.add(root); // 设置枢轴的世界位置(对应原模型的初始位置) pivot.position.set(0, 0, 0); coinBox = new THREE.BoxHelper( pivot, 0xffff00 ); scene.add(coinBox); coin = pivot; // 后续旋转coin即旋转枢轴,模型会围绕中心转动 scene.add(pivot); // 枢轴点可视化逻辑 const circleGeometry = new THREE.CircleGeometry(3, 64); const circleMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 }); const circleMesh = new THREE.Mesh(circleGeometry, circleMaterial); circleMesh.position.copy(pivot.position); circleMesh.position.y += 1; scene.add(circleMesh); });
说明:这种方法灵活性更高,若需要自定义枢轴位置,只需调整root.position.sub(modelCenter)这一步的偏移量即可,比如想让模型围绕底部中心旋转,就可以修改偏移的y值。
内容的提问来源于stack exchange,提问作者SunAwtCanvas
相关产品推荐
相关产品推荐

