在Autodesk Forge Viewer中加载Three.js模型遇Object3D实例判定问题
问题分析与解决方案:Forge Viewer中外部Three.js与内置Three.js的冲突
兄弟,这个问题我太熟了——本质上是你引入的外部Three.js库和Forge Viewer内置的Three.js不是同一个上下文,导致类型校验失败!
问题根源拆解
Forge Viewer本身就内置了一套Three.js(而且版本可能和你自己加的不一样):
- 你用外部
THREEE.ObjectLoader加载出来的Object3D,属于你引入的那个Three.js实例的构造函数 - 而Viewer内部识别的
THREE.Object3D是它自己内置版本的构造函数 - 在JavaScript里,不同上下文的构造函数是完全独立的,哪怕名字一样,
instanceof也会返回false,Viewer自然没法正确识别这个对象
可行解决方案
方案一:直接使用Viewer内置的Three.js(最推荐)
完全不需要自己引入外部Three.js,Forge Viewer已经把内置的Three.js上下文暴露出来了,直接用就行:
loadThreeJs() { // 取Viewer内置的Three.js上下文,不用自己引入的THREEE const THREE = this.viewer.impl.threejs; const loader = new THREE.ObjectLoader(); loader.load('./assets/MVP-TW-CCTV TOWER.json', (obj) => { console.log(obj) var object3DInside = obj.children[0].children[0]; console.log(object3DInside) // 不需要靠setTimeout瞎等,确保Viewer初始化完成后再调用 this.addScene(object3DInside); }, (xhr) => { console.log((xhr.loaded / xhr.total * 100) + '% loaded'); }); }
这样加载出来的Object3D就是Viewer内置Three.js的实例,自然能被正确识别和渲染。
方案二:同步外部Three.js版本与Viewer内置版本(不推荐)
如果你一定要用自己引入的Three.js,必须保证它的版本和Viewer内置的完全一致:
- 先通过
this.viewer.impl.threejs.REVISION查看Viewer内置Three.js的版本号 - 安装对应版本的Three.js(比如
npm install three@xxx) - 确保代码里只使用这个同步版本的Three.js
不过这种方法维护成本很高,Viewer版本更新时内置Three.js可能跟着升级,你得同步修改依赖版本。
额外优化:替换掉不靠谱的setTimeout
你代码里用setTimeout来等待初始化是个隐患,最好监听Viewer的初始化完成事件,确保时机正确:
// 在Viewer初始化完成后再加载模型 this.viewer.addEventListener(Autodesk.Viewing.INITIALIZED_EVENT, () => { this.loadThreeJs(); });
内容的提问来源于stack exchange,提问作者Paxton.Huynh
相关产品推荐
相关产品推荐

