-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GLTFLoader plugin system, first round #19144
Conversation
Supporting chaining, also, would be nice for consistency. new GLTFLoader()
.register( FooMaterialExtensionPlugin )
.register( BarMaterialExtensionPlugin )
.load( ... ); |
Good catch. I had forgotten to do that in this PR tho I did in the previous PR. Updated. |
This is great! I don't have anything to add, other than I'd love to have a |
All is ok with CI here, freezing was fixed #19147 |
Thanks for working on this! A couple notes:
Other than these two issues I was able to get my extension running without changing GLTFLoader.js 🎉 |
For pt1, the way Babylon.JS works is it permits this:
(which doesn't work with this PR but probably could be made to work?) |
... oh, the magic of JavaScript. The arrow function doesn't work but this does work:
So the only issue is the warning; suppressing this might be slightly awkward though with the current interface because the plugins must be created after the parser, but to create the parser we need the extension list. Maybe this can work with a second pass like this (after setPlugins call):
|
This is a GLTFLoader plugin for THREE.js that works with mrdoob/three.js#19144. Once that PR goes through we will be able to stop maintaining a custom GLTFLoader build (modulo Basis/KTX2 changes that are still a bit in flux...).
@zeux Good catch! Yes, I think we should be able to pass parameter to plugin. I'll update. |
I updated to resolve 1. so far.
Arrow function seems to work here. What type of error do you see? |
@takahirox That comment was referring to old version of the code with ‘new’; with callbacks I believe arrow functions should work just fine. |
OK, thanks. And also I updated to resolve 2. |
Thanks! Confirmed that the new code fixes all issues for my use case. Looks like all that's left is for @donmccurdy to review this? |
examples/js/loaders/GLTFLoader.js
Outdated
@@ -2160,6 +2270,18 @@ THREE.GLTFLoader = ( function () { | |||
|
|||
} | |||
|
|||
materialType = this._invokeOne( function ( ext ) { | |||
|
|||
return ext.getMaterialType && ext.getMaterialType(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getMaterialType()
should take an argument materialDef
or materialIndex
so that you can optionally use it to determine if a material applies to just this material definition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed – I'd vote for materialIndex
for consistency with load methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me. Added materialIndex
, thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple small comments but I think this is close! Thank you @takahirox!
examples/js/loaders/GLTFLoader.js
Outdated
@@ -110,10 +113,35 @@ THREE.GLTFLoader = ( function () { | |||
|
|||
}, | |||
|
|||
register: function ( callback ) { | |||
|
|||
if ( ! this.pluginCallbacks.includes( callback ) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's avoid array methods missing from IE11 if we can, see #19293. It is simpler if the only polyfill GLTFLoader requires is the Promise API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was missing IE11 doesn't support includes()
. Replaced with indexOf()
, thanks.
|
||
this.plugins = plugins; | ||
|
||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't intend for users to call setPlugins or setExtensions, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I don't expect users to call them.
examples/js/loaders/GLTFLoader.js
Outdated
@@ -2160,6 +2270,18 @@ THREE.GLTFLoader = ( function () { | |||
|
|||
} | |||
|
|||
materialType = this._invokeOne( function ( ext ) { | |||
|
|||
return ext.getMaterialType && ext.getMaterialType(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed – I'd vote for materialIndex
for consistency with load methods.
Would it be OK to just have an I realize that not all plugins will be related to glTF extensions, but I don't think it's necessary to try to separate the two concepts inside the loader, when they behave the same way. |
My plan is, Let me confirm my understanding. Are you suggesting we would be better to have only one object even before we finish converting? |
Ok, I'm fine with having both during the transition. Once that is finished I think I would prefer to have only |
Can we get a status update on this PR? I'm assuming we're waiting on tests, examples, and fixing merge conflicts? Is there more that needs to be figured out for the API? |
I think I have reflected all the comments to the code. Let me know if I have missed anything. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extensions are go! 🚀
Weeeeeeee!! |
Thanks! |
Thanks for merging. By the way, I should have noted about I think we definitely should have In this PR we use Probably we need workaround or something. Let's discuss more closely when we move Light extension to the new system. |
That makes sense, sounds like nodes should use |
This thread is already closed, I'd like to continue the discussion in a new open thread. Probably it will be a good opportunity when moving light extension to the new system. |
We can use |
I thought there could be a case where an extension in a node points to a mesh/camera and the core node points to another mesh/camera as fallback, meaning either one should be created depending on whether the extension is supported. But it seems to unlikely happen in possible custom extensions or future Khronos glTF extensions? If so,
|
Here's what I did for an internal Hubs hackathon: Hubs-Foundation/three.js@hubs/master...MozillaReality:hubs/feature/plugin-api I needed to swap out all the Object3D types for one with an ECS mixin. We don't have this requirement anymore, but it was a useful thought exercise. These were the hooks I implemented:
So even though I don't have concrete uses for these now, here are my thoughts on how you might use these methods:
I don't think any of these are final APIs, but maybe it's useful to see how I broke it apart. I think the text extension would be a good one to focus on for designing an API. The text extension isn't going to touch the mesh loading part of the GLTFLoader. It really just needs to alter what Object3D is returned from loadNode and I think that'd be a good starting point. |
From #18484.
This PR adds hook points to GLTFLoader for the extensibility and rewrite clearcoat extension with the new system as the first extension handler. Let's make follow up PRs to move the other existing extension handlers to the new system one by one and add other necessary hook points for them.
API and example
Hook points this PR adds
loadMaterial
extendMaterialParams
getMaterialType
loadBufferView
for @zeux's MESHOPT extensionloadMesh
for @feiss's text mesh extension