Forge Viewer添加自定义模型片段后位置异常问题咨询
问题
我通过以下代码在Forge Viewer中添加包含多个网格的自定义模型:
let cameras = camerasJSON.cameras[0]; let sceneBuilder = await viewer.loadExtension('Autodesk.Viewing.SceneBuilder'); let modelBuilder = await sceneBuilder.addNewModel({ modelNameOverride: 'Cameras', conserveMemory: false }) cameras.forEach(camera => { const sphereGeometry = new THREE.BufferGeometry().fromGeometry(new THREE.SphereGeometry(1, 8, 8)); const sphereMaterial = new THREE.MeshPhongMaterial({ color: new THREE.Color(0, 1, 0) }); let p = [+camera[2]/1000, +camera[3]/1000, +camera[4]/1000] const sphereTransform = new THREE.Matrix4().compose( new THREE.Vector3(...p), new THREE.Quaternion(0,0,0,1), new THREE.Vector3(1, 1, 1) ); let mesh = new THREE.Mesh(sphereGeometry, sphereMaterial); mesh.matrix = sphereTransform mesh.dbId = camera[0].split('_')[1]; modelBuilder.addMesh(mesh); })
随后用以下代码获取点击片段的位置:
event.selections[0].model.getInstanceTree().enumNodeFragments(event.selections[0].dbIdArray[0], function (frag) { let fragProxy = viewer.impl.getFragmentProxy(viewer.model, frag); let matrix = new THREE.Matrix4(); fragProxy.getWorldMatrix(matrix); let position = new THREE.Vector3().setFromMatrixPosition(matrix); console.log(position); });
实际获取的位置(及变换矩阵)与初始设置不匹配。创建的绿色球体显示位置正确,但获取到的片段位置完全不符,即使相对位置也不对(模型已炸开以便观察)。移除全局偏移无效果,主模型不存在此问题。不确定是位置获取方式错误,还是片段在添加时位置被篡改。
原因与解决方法
错误点1:获取片段代理时用错模型对象
你在获取fragProxy时使用了viewer.model,但自定义模型是通过SceneBuilder添加的独立模型实例,正确的模型对象应该是选中事件返回的event.selections[0].model。错误点2:直接赋值
mesh.matrix的方式易导致矩阵不同步
Forge的SceneBuilder更推荐通过设置mesh.position、mesh.quaternion、mesh.scale来定义变换,再手动更新矩阵,避免内部矩阵状态不同步。
修正后的获取位置代码
const selectedModel = event.selections[0].model; selectedModel.getInstanceTree().enumNodeFragments(event.selections[0].dbIdArray[0], function (frag) { let fragProxy = viewer.impl.getFragmentProxy(selectedModel, frag); let matrix = new THREE.Matrix4(); fragProxy.getWorldMatrix(matrix); let position = new THREE.Vector3().setFromMatrixPosition(matrix); console.log(position); });
优化后的自定义模型添加代码
cameras.forEach(camera => { const sphereGeometry = new THREE.BufferGeometry().fromGeometry(new THREE.SphereGeometry(1, 8, 8)); const sphereMaterial = new THREE.MeshPhongMaterial({ color: new THREE.Color(0, 1, 0) }); let p = [+camera[2]/1000, +camera[3]/1000, +camera[4]/1000] let mesh = new THREE.Mesh(sphereGeometry, sphereMaterial); // 直接设置位置、旋转、缩放 mesh.position.set(...p); mesh.quaternion.set(0, 0, 0, 1); mesh.scale.set(1, 1, 1); // 手动更新矩阵确保状态同步 mesh.updateMatrix(); mesh.dbId = camera[0].split('_')[1]; modelBuilder.addMesh(mesh); })
内容的提问来源于stack exchange,提问作者Roma M
相关产品推荐
相关产品推荐

