Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Three.js Object3D missing isMesh, Material and Geometry Properties?

I'm using three.js r97, and Angular 7.

I can run and serve the application locally (works as it should), but I cannot build for production with the type errors.

error TS2339: Property 'isMesh' does not exist on type 'Object3D'.

error TS2339: Property 'material' does not exist on type 'Object3D'.

error TS2339: Property 'geometry' does not exist on type 'Object3D'.

The places this is occurring is after the object is loaded and I'm traversing the parts.

child.isMesh and the modifications that are made to the child object are throwing errors.

I'm new to typescript, not sure if there's a better way to handle the manipulations. From what I can tell, I'm not able to force a production build. Any suggestions to help resolve this issue would be appreciated.

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);


      });

I attempted to add an interface for Object3D and define the properties as follows:

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

Error still persists.

Edit: Update 2

I'm able to elminate the issue by supplying //@ts-ignore above each of the lines that is causing an issue. I'm not sure if this is bad practice, but it appears to work.

like image 649
user2355051 Avatar asked Nov 09 '18 17:11

user2355051


1 Answers

It looks like your TypeScript development configuration is different than your production configuration. There's no other reason why it would give you an error on build, but not when compiling on your local dev environment. (By the way, the error you're seeing is correct, because child is expected to be an Object3D, which does not have the .isMesh property.)

Instead of doing //@ts-ignore, you could assert the type of child to what you expect it to be:

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

You can learn more about type assertions in the TS documentation

like image 67
Marquizzo Avatar answered Nov 05 '22 19:11

Marquizzo