Three.js: GLTFLoader: primitive type .extras

Created on 21 Jun 2018  路  11Comments  路  Source: mrdoob/three.js

Description of the problem

From #14315

Currently GLTFLoader just sets .extras property to Three.js object's .userData.

if ( nodeDef.extras ) node.userData = nodeDef.extras;

But .extras type in glTF is any while .userData type in Three.js is object. If .extras have primitive type value, like integer or strings, .userData will have invalid type value in Three.js.

I'm thinking of .userData.glTF (or .userData.extras) instead of .userData to set .extras to.

if ( nodeDef.extras ) node.userData.glTF = nodeDef.extras;

Another option is to set like { value: *.extras } to .userData if .extras is non-object.

if ( nodeDef.extras ) {

    node.userData = ( typeof nodeDef.extras === 'object' )
        ? nodeDef.extras
        : { value: nodeDef.extras };

}

Any thoughts?

/cc @donmccurdy @wlinna

(BTW, we should replace if ( *.extras ) with if ( *.extras !== undefined ) because .extras can be 0, false, or empty strings ''.)

Three.js version
  • [x] Dev
Browser
  • [x] All of them
  • [ ] Chrome
  • [ ] Firefox
  • [ ] Internet Explorer
OS
  • [x] All of them
  • [ ] Windows
  • [ ] macOS
  • [ ] Linux
  • [ ] Android
  • [ ] iOS
Hardware Requirements (graphics card, VR Device, ...)
Loaders Suggestion

Most helpful comment

Thus, I'd prefer extras to be simply assigned to userData field, and primitive types would be handled as a special case.

+1. While technically allowed, no tools are doing this. Better to establish clear best practice that it be an object, and perhaps even disallow primitive extras types in a future version of glTF. If extras is a primitive type, we could log a warning and ignore it, but until/unless it causes a real issue I'd vote to avoid adding specific code for the case at all.

All 11 comments

What about

.userData {
  mine {}
  yours {}
  jonathans {}
  glTFs {
    extras
    ...
  }
}

Is extras the only thing that should be stored here? (Maybe extensions?)

    node.userData = ( typeof nodeDef.extras === 'object' )
        ? nodeDef.extras
        : { value: nodeDef.extras };

console.log(myNode.userData) // { value: 'extras' } who's is this, GLTFLoader is not part of three.js

The "value" key in this case may be vague. It could be useful to have it in a name space so it doesn't collide with other possible data that belongs to the user.

Although I like the idea of a 'custom' name in userData for imports, it doesn't feel intuitive when a user exports a scene and data defined in userData suddenly becomes available in userData.glTF.*...or am I missing something?

I think I like userData.glTF 馃憣

Yeah, I prefer .userData.glTF too but one concern. How we should export .userData.

If we import .extras as .userData.glTF and export .userData as .extras, we'll get .userData.glTF.glTF.glTF... if we repeatedly import and export.

Would it be possible to export .userData.glTF as .extras?

Would it be possible to export .userData.glTF as .extras?

What about userDataitself then? Shouldn't userData be exported as extras?

It could be useful to have it in a name space so it doesn't collide with other possible data that belongs to the user.

Why is this a concern though? At import time there can't be any existing data (?). Also, according to the specification, extras is "application-specific data", so user is in control of extras anyway, right?

From my perspective, extras would be mapped perfectly to userData, if it wasn't for the slightly differing type. And after the model is loaded, it shouldn't matter anymore what it was before. For example, suppose some user has exported models in a modeling software to formats A and B. They both contain the same metadata. It would be confusing, if in Three.js one model would have its metadata in .userData.A and the other in .userData.B.

Thus, I'd prefer extras to be simply assigned to userData field, and primitive types would be handled as a special case.

Thus, I'd prefer extras to be simply assigned to userData field, and primitive types would be handled as a special case.

+1. While technically allowed, no tools are doing this. Better to establish clear best practice that it be an object, and perhaps even disallow primitive extras types in a future version of glTF. If extras is a primitive type, we could log a warning and ignore it, but until/unless it causes a real issue I'd vote to avoid adding specific code for the case at all.

Does glTF spec have a plan to disallow primitive extras types?

No, I think this is the first time I've heard it could be a primitive. See https://github.com/KhronosGroup/glTF/issues/1120.

OK. I agreed with ignoring primitive extras with warning so far. I'll make a PR. And let's keep an eye on that thread.

We've merged #14518, and the glTF spec has been amended to say that extras should be objects as best practice (https://github.com/KhronosGroup/glTF/pull/1451). I think this can be resolved.

Was this page helpful?
0 / 5 - 0 ratings