如何在Three.js中获取网格模型尺寸?含Collada文件处理方法
Hey there! Let's walk through exactly how to get the precise physical dimensions of your .dae model in Three.js, and align it with real-world millimeters—since that's your end goal for comparing to actual objects.
核心思路
First, you're right that bounding boxes are the way to go, but we need to account for two key things:
- 模型的层级变换(比如缩放、旋转、父节点影响)
- Collada文件的原生单位(DAE可能用米、厘米或毫米定义尺寸)
步骤1:加载Collada模型
Start by loading your model with Three.js's ColladaLoader—make sure you're using the latest version of the loader from the addons folder:
import * as THREE from 'three'; import { ColladaLoader } from 'three/addons/loaders/ColladaLoader.js'; const scene = new THREE.Scene(); const loader = new ColladaLoader(); loader.load('your-model.dae', (collada) => { const model = collada.scene; scene.add(model); // 在这里处理尺寸计算 calculateRealWorldSize(model, collada); });
步骤2:计算模型的世界空间包围盒
Instead of calling geometry.computeBoundingBox() directly on individual meshes (which only gives local, untransformed dimensions), we'll use Box3.setFromObject() to get the entire model's bounding box in world space. This automatically accounts for all scaling, rotation, and position transformations applied to the model or its parent nodes.
步骤3:转换到毫米单位
Collada files often include unit metadata—we can use this to convert the raw bounding box values to millimeters. Here's the full calculation function:
function calculateRealWorldSize(model, collada) { // 确保模型的世界矩阵是最新的 model.updateMatrixWorld(true); // 创建包围盒并从模型获取边界 const boundingBox = new THREE.Box3().setFromObject(model); const rawSize = new THREE.Vector3(); boundingBox.getSize(rawSize); // 处理Collada的单位转换 const unit = collada.unit; let scaleToMM = 1; switch(unit.name) { case 'METER': scaleToMM = 1000; // 1米 = 1000毫米 break; case 'CENTIMETER': scaleToMM = 10; // 1厘米 = 10毫米 break; case 'MILLIMETER': scaleToMM = 1; break; default: console.warn('未知单位,默认按毫米处理'); } // 计算真实毫米尺寸 const realSizeMM = rawSize.multiplyScalar(scaleToMM); console.log('模型真实尺寸(毫米):'); console.log(`X轴: ${realSizeMM.x.toFixed(2)}mm`); console.log(`Y轴: ${realSizeMM.y.toFixed(2)}mm`); console.log(`Z轴: ${realSizeMM.z.toFixed(2)}mm`); return realSizeMM; }
关键注意事项
- 如果模型被手动缩放:If you've applied custom scaling to the model (e.g.,
model.scale.set(2,2,2)),setFromObject()will include that scaling in the bounding box. If you want the original design size (before your manual scaling), reset the scale to(1,1,1)temporarily before calculating, then reapply your scaling. - 层级模型支持:This method works even if your model is made of multiple nested meshes—
setFromObject()traverses all child objects automatically. - 未知单位的校准:If your DAE file doesn't include clear unit metadata, import a reference object (like a 100mm cube) and compare the calculated size to its known value to adjust the
scaleToMMfactor.
内容的提问来源于stack exchange,提问作者Jonathan Drummond

