你的GLB模型使用的是 Z轴朝上、Y轴向前 的坐标系,而Three.js默认使用 Y轴朝上、Z轴向前 的坐标系。这会导致模型在场景中显示方向错误。
| 坐标系 | 朝上轴 | 向前轴 | 右轴 | 常见软件 |
|---|---|---|---|---|
| Three.js (Y-up) | Y | Z | X | Three.js 默认 |
| GLB模型 (Z-up) | Z | Y | X | Blender, 3ds Max, CAD |
创建了 src/utils/coordinateConverter.ts 文件,包含以下功能:
convertCoordinateSystem(model, from, to) - 坐标系转换autoConvertModelCoordinates(model) - 自动检测并转换createCoordinateAxes(size) - 创建坐标系参考轴(调试用)applyCoordinateConversion(group, config) - 应用转换到模型组y-up: Three.js 默认坐标系z-up: Blender/3ds Max 默认坐标系z-up-forward-x: 某些CAD软件坐标系// 导入转换工具
import { convertCoordinateSystem } from '../utils/coordinateConverter'
// 在模型加载函数中应用转换
async function loadModel() {
const loader = new GLTFLoader()
const gltf = await loader.loadAsync(props.modelUrl)
const model = gltf.scene
// 计算包围盒并居中
const box = new THREE.Box3().setFromObject(model)
const center = box.getCenter(new THREE.Vector3())
model.position.sub(center)
// 坐标系转换:Z-up → Y-up
const convertedModel = convertCoordinateSystem(model, 'z-up', 'y-up')
const group = new THREE.Group()
group.add(convertedModel)
group.position.set(0, 0, 0)
group.rotation.y = THREE.MathUtils.degToRad(5)
map.add(group)
modelGroup = group
}
Z-up 到 Y-up 的转换实际上是绕 X 轴旋转 -90 度:
model.rotation.x = -Math.PI / 2
或者使用矩阵变换:
const matrix = new THREE.Matrix4().makeRotationX(-Math.PI / 2)
model.applyMatrix4(matrix)
// 在 Map3DScene.vue 中取消注释
const axes = createCoordinateAxes(100)
group.add(axes)
转换前后检查模型尺寸:
const box = new THREE.Box3().setFromObject(model)
const size = box.getSize(new THREE.Vector3())
console.log(`模型尺寸: (${size.x}, ${size.y}, ${size.z})`)
项目中的变换面板可以实时调整模型位置、旋转和缩放。
创建了两个测试页面:
test-project.html - 项目整体测试test-coordinate.html - 坐标系转换专门测试Q: 转换后模型方向还是不对? A: 检查模型的原始坐标系,可能需要调整旋转角度或使用自动检测功能。
Q: 如何知道模型是什么坐标系?
A: 查看模型导出软件的设置,或使用 autoConvertModelCoordinates 函数自动检测。
Q: 转换会影响模型动画吗? A: 不会,坐标系转换只影响静态模型的初始方向。