Skip to content

Conversation

@jeffreylanters
Copy link

The Object3D typings we're missing the material.

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 13, 2019

This seems to be a misunderstanding. Object3D does not have a material property.

@jeffreylanters
Copy link
Author

jeffreylanters commented Mar 13, 2019

This seems to be a misunderstanding. Object3D does not have a material property.

But it does work, when I log an Object3D object, I'll see and can set the material.

Screenshot 2019-03-13 at 11 18 31

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 13, 2019

It looks like you are working with an instance of Mesh.

@jeffreylanters
Copy link
Author

The variable comes straight out of the object loader, it's untouched. There might my another mistyping?

image

@jeffreylanters
Copy link
Author

When I log the Object3D
Screenshot 2019-03-13 at 11 30 52

The material does exist
Screenshot 2019-03-13 at 11 31 09

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 13, 2019

Mesh is derived from Object3D. I think if you study the source code of Object3D and Mesh, things should become more clear:

function Object3D() {
Object.defineProperty( this, 'id', { value: object3DId ++ } );
this.uuid = _Math.generateUUID();
this.name = '';
this.type = 'Object3D';
this.parent = null;
this.children = [];
this.up = Object3D.DefaultUp.clone();
var position = new Vector3();
var rotation = new Euler();
var quaternion = new Quaternion();
var scale = new Vector3( 1, 1, 1 );
function onRotationChange() {
quaternion.setFromEuler( rotation, false );
}
function onQuaternionChange() {
rotation.setFromQuaternion( quaternion, undefined, false );
}
rotation.onChange( onRotationChange );
quaternion.onChange( onQuaternionChange );
Object.defineProperties( this, {
position: {
configurable: true,
enumerable: true,
value: position
},
rotation: {
configurable: true,
enumerable: true,
value: rotation
},
quaternion: {
configurable: true,
enumerable: true,
value: quaternion
},
scale: {
configurable: true,
enumerable: true,
value: scale
},
modelViewMatrix: {
value: new Matrix4()
},
normalMatrix: {
value: new Matrix3()
}
} );
this.matrix = new Matrix4();
this.matrixWorld = new Matrix4();
this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;
this.matrixWorldNeedsUpdate = false;
this.layers = new Layers();
this.visible = true;
this.castShadow = false;
this.receiveShadow = false;
this.frustumCulled = true;
this.renderOrder = 0;
this.userData = {};
}

function Mesh( geometry, material ) {
Object3D.call( this );
this.type = 'Mesh';
this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
this.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );
this.drawMode = TrianglesDrawMode;
this.updateMorphTargets();
}

@jeffreylanters
Copy link
Author

Okay, I see what you mean. But still, the ObjectLoader packed in the module, returns an object with the Typescript Type Object3D, and it does contain material, but it's not typed.

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 13, 2019

returns an object with the Typescript Type Object3D, and it does contain material, but it's not typed.

Then there is a problem in ObjectLoader.d.ts. The onLoad() callback of ObjectLoader.load() can return many different types of objects e.g. Scene, Mesh, LineSegments etc.. All these classes are derived from Object3D. It would not make sense to put all the properties of these classes to Object3D.d.ts, right? Instead, the following line needs to be changed:

onLoad?: (object: Object3D) => void,

@jeffreylanters
Copy link
Author

jeffreylanters commented Mar 13, 2019

I see what is going on. Thanks for clearing it up! A solution for this could be a generic key of type, function to keep it more strict.

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 13, 2019

Similar to this code?

parse<T extends Object3D>(json: any, onLoad?: (object: Object3D) => void): T;

@mrdoob
Copy link
Owner

mrdoob commented Mar 13, 2019

It would not make sense to put all the properties of these classes to Object3D.d.ts, right?

Wouldn't this work?

onLoad?: (object: Scene | Mesh | Line | LineSegments | Points) => void,

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 14, 2019

As an alternative, I think it would also work to define a generic type derived from Object3D.

onLoad?: <T extends Object3D>(object: T) => void,

Not sure which approach is better 🤔

@mrdoob
Copy link
Owner

mrdoob commented Mar 15, 2019

Not sure which approach is better 🤔

@jeffreylanters you choose 🙂

@mrdoob mrdoob added this to the r103 milestone Mar 15, 2019
@jeffreylanters
Copy link
Author

As an alternative, I think it would also work to define a generic type derived from Object3D.

onLoad?: <T extends Object3D>(object: T) => void,

Not sure which approach is better 🤔

Like I said before, I think a generic approach would be the best way to go. I think this looks is perfect. Thanks for thinking with me!

Jeffrey Lanters added 2 commits March 15, 2019 10:04
Turned the onLoad parameter of the ObjectLoader.load function a generic type of Object3D so users can define which kind of object they are loaded so it stays typed.
@jeffreylanters
Copy link
Author

I've updated the PR.

@Mugen87 Mugen87 changed the title Added missing material typing on Object3D ObjectLoader: Fix TS definition of load() Mar 15, 2019
@Mugen87 Mugen87 changed the title ObjectLoader: Fix TS definition of load() ObjectLoader: Fix TS definition of .load() Mar 15, 2019
@mrdoob mrdoob merged commit a185fa1 into mrdoob:dev Mar 15, 2019
@mrdoob
Copy link
Owner

mrdoob commented Mar 15, 2019

Thanks!

@jeffreylanters jeffreylanters deleted the patch-1 branch March 16, 2019 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants