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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 06:05:24