Three.js Object3D 缺少 isMesh、Material 和 Geometry 属性?

Posted

技术标签:

【中文标题】Three.js Object3D 缺少 isMesh、Material 和 Geometry 属性?【英文标题】:Three.js Object3D missing isMesh, Material and Geometry Properties? 【发布时间】:2019-04-13 08:00:36 【问题描述】:

我正在使用 three.js r97 和 Angular 7。

我可以在本地运行和提供应用程序(按应有的方式工作),但由于类型错误,我无法为生产构建。

错误 TS2339:“Object3D”类型上不存在属性“isMesh”。

错误 TS2339:“Object3D”类型上不存在属性“材料”。

错误 TS2339:“Object3D”类型上不存在属性“几何”。

发生这种情况的地方是在加载对象并且我正在遍历部件之后。

child.isMesh 和对子对象所做的修改会引发错误。

我是 typescript 的新手,不确定是否有更好的方法来处理这些操作。据我所知,我无法强制进行生产构建。任何有助于解决此问题的建议将不胜感激。

this.loader = new THREE.FBXLoader();
      this.loader.load('assets/models/C4D_Export.fbx', object => 

          object.traverse( child => 

              if( child.type == "Group")
                  child.name = 'ToolGroup';
              
              if ( child.isMesh ) 

                  const oldMat = child.material;
                  //CONVERT MATERIAL TO STANDARD MATERIAL.
                  child.material = new THREE.MeshStandardMaterial(
                      color: oldMat.color,
                      map: oldMat.map,
                  );

                  child.castShadow = true;
                  child.receiveShadow = true;
                  child.material.combine = THREE.MixOperation;
                  child.material.envMap = envMap;
                  child.material.shininess=10;
                  child.material.refractionRatio=1;
                  child.material.reflectivity=1;
                  //child.material.normalMap = texture;
                  //child.material.normalMapType = 0;
                  child.material.metalness=1;
                  child.geometry.applyMatrix(new THREE.Matrix4().makeTranslation(5, 0, 0));
                  //child.material.color.setHex( 0xffffff );

                  var f2 = gui.addFolder('Position'+child.name);
                      f2.add(controller, 'positionX', -50, 50).onChange( function() 
                         child.position.x = (controller.positionX);
                      );
                      f2.add(controller, 'positionY', -50, 50).onChange( function() 
                         child.position.y = (controller.positionY);
                      );
                      f2.add(controller, 'positionZ', -50, 50).onChange( function() 
                         child.position.z = (controller.positionZ);
                      );

                  var sphereAxis = new THREE.AxesHelper(200);
                  child.add(sphereAxis);

              

          );

          object.position.y = -20;
          object.scale.set(1,1,1);
          object.rotation.z = (-90*(Math.PI/180));
          objholder.add(object);


      );

我尝试为 Object3D 添加一个接口并定义如下属性:

interface Object3D
    isMesh?: any,
    geometry?: any,
    material?: any,

错误仍然存​​在。

编辑:更新 2

我可以通过在导致问题的每一行上方提供//@ts-ignore 来消除问题。我不确定这是否是不好的做法,但它似乎有效。

【问题讨论】:

【参考方案1】:

看起来您的 TypeScript 开发配置与您的生产配置不同。没有其他原因会导致您在构建时出错,但在本地开发环境中编译时不会。 (顺便说一句,您看到的错误是正确的,因为 child 应该是一个 Object3D,它没有 .isMesh 属性。)

您可以将 child 的类型声明为您期望的类型,而不是 //@ts-ignore

if ( child.isMesh ) // Error: property .isMesh does not exist in Object3D

if ( (<any> child).isMesh ) // No error, but there's no type-checking with <any>

if ( (<THREE.Mesh> child).isMesh ) // No error, and you get access to Mesh props

您可以了解更多关于type assertions in the TS documentation

【讨论】:

Marquizzo,dev 和 prod 的设置相同。开发时我使用 ng serve,出现错误,但应用程序编译并显示我的更改。运行 ng build --prod 时,该错误会导致编译失败并且永远不会创建文件。我会检查一下,感谢您的洞察力。 我更喜欢 if(child instanceof THREE.Mesh) 作为 linter eslint 似乎更喜欢 'if ((child as THREE.Mesh).isMesh)' 到 'if (( child).isMesh)'

以上是关于Three.js Object3D 缺少 isMesh、Material 和 Geometry 属性?的主要内容,如果未能解决你的问题,请参考以下文章

Three.js源码解读一:Object3D

three.js 在它的中心围绕 Y 轴旋转 Object3d

有啥方法可以从 three.js Object3D 中获取边界框?

Three.js Object3d 圆柱体旋转以对齐向量

一些关于three.js的摘抄笔记

Three.js typescript definitely typed 文件