Skip to content
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

Prevent the code to fail when loading models without the "materials" property or having a mesh primitive without the material association #3287

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

alexdaube
Copy link
Contributor

Fixes #3279

  • Couple of null checks in the model and primitive-node constructors
  • In space-opera, the material panel will shot "No materials" when the panel does not have any selectable materials found in the active model.

…hout breaking the model and primitive-node constructors. Arranging the material panel in space-opera to fit that change.
Copy link
Collaborator

@elalish elalish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this looks great. I especially appreciate all the added tests!

@alexdaube alexdaube requested a review from elalish March 18, 2022 22:10
Copy link
Collaborator

@elalish elalish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I wonder if khronos_SimpleTriangle would work; it's a lot smaller and will load faster in the tests.

@alexdaube
Copy link
Contributor Author

Thanks! I wonder if khronos_SimpleTriangle would work; it's a lot smaller and will load faster in the tests.

On the surface it would seems so, but khronos_SimpleTriangle generate a Default material in the correlatedSceneGraph object, which is not the case of the vase glb.

@elalish
Copy link
Collaborator

elalish commented Mar 21, 2022

hmm, that's interesting. I thought we always generated a default material when none were specified. Can you take a look and let me know what the difference is? I'd like to make sure we're fixing this properly.

@alexdaube
Copy link
Contributor Author

It does seems a bit fishy. I will check it out tomorrow morning no problem. Today is a bit busy on my end.

@alexdaube
Copy link
Contributor Author

Looking at the associations in the gltf object generated from the ThreeGLTFParser, the triangle file has 2 associations (material and mesh) and the vase only has 1 (mesh). Looking at the code, the gltf.materials array and the default material is only added when there is a material in the associations.

Screen Shot 2022-03-22 at 2 36 36 PM

What would you suggest we do with this?

@elalish
Copy link
Collaborator

elalish commented Mar 22, 2022

Hmm, sounds like the bug might be in the GLTFLoader (since it's supposed to create a default material association, and apparently fails to). I think for now we should go ahead and create our default material also in the case there is no material association at all, for robustness. Separately, it'd be interesting to know why GLTFLoader has weird behavior here.

@alexdaube
Copy link
Contributor Author

I took a deeper look into this and I haven't quite put my finger on exactly what is going on here.
So far, I know that the default material is indeed being created and put in the associations object by the GLTFLoader.
It somehow is not in the associations object when we try to access it through the parser in the CorrelatedSceneGraph. So obviously something is happening in between. We can actually see that the Material is associated to the mesh found in the associations object. I will continue debugging this when I find a bit more free time.

@alexdaube
Copy link
Contributor Author

I wanted to get to this last week so it could be included in the next release, but I have been indisposed by Covid unfortunately.

Anyways, it seems like the associations entry to the DefaultMaterial is set in different places which explains the inconsistency. For the Triangle files it is done here, which is called when we load the meshes in the loader.
https://github.com/mrdoob/three.js/blob/8921bfaee413e809cb2d27f0aec917408d690a0f/examples/jsm/loaders/GLTFLoader.js#L3114

For the Vase(new file) it is done here, which is called when we load a material.
https://github.com/mrdoob/three.js/blob/8921bfaee413e809cb2d27f0aec917408d690a0f/examples/jsm/loaders/GLTFLoader.js#L3304

The problem that we have in model-viewer with this is that CorrelatedSceneGraph and PrimitiveNode objects are instantiated before loadMaterial is first called and this association is made in the Model constructor I believe.

I could probably address the issue by adding this block of code, which uses the parser's cached DefaultMaterial to setup the association.

Screen Shot 2022-03-30 at 6 47 21 PM

The cache attribute is not public in the interface, so I am guessing this snippet is not exactly how we should use the library. I am not sure what direction you want to take with this? Perhaps this should be only fix/addressed three.js?

@elalish
Copy link
Collaborator

elalish commented Mar 30, 2022

I wanted to get to this last week so it could be included in the next release, but I have been indisposed by Covid unfortunately.

No problem! Get well soon.

The cache attribute is not public in the interface, so I am guessing this snippet is not exactly how we should use the library. I am not sure what direction you want to take with this? Perhaps this should be only fix/addressed three.js?

Indeed, let's not mess with the internals of three.js. You make it sound like something is happening too soon? Might this just be a race condition of some kind on our side? Maybe we just haven't awaited the right thing.

@elalish
Copy link
Collaborator

elalish commented May 2, 2022

Ping; did you ever find a deeper cause here? Would love to merge a fix for the root problem.

@alexdaube
Copy link
Contributor Author

I haven't had much time to check this any further.

Off memory, I think it was basically that in this particular case three.js is only creating the associations for the default material once loadMaterial is being called which in model viewer happens after the constructors cited above. So the race condition assessment sounds about right, though I find it a bit weird as of why this association is done in different places in the three.js GTLFLoader's code to be honest.

I will try to make some time on Friday to try to find a good solution for this.

@elalish
Copy link
Collaborator

elalish commented Jul 18, 2022

I'm still interested in what's going on here. Have you gotten stuck?

@alexdaube
Copy link
Contributor Author

Sorry for the slow response (on vacation for the past few weeks).

I didn't put any time into this since March as my plate got really full, but I am interested in finding a good solution here. Let me put this back into my personal task board and come back to you with this.

@elalish
Copy link
Collaborator

elalish commented Jan 19, 2023

It looks like this is actually a three.js bug that needs to be fixed upstream. Should we merge the rest of this PR?

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.

Support models lacking the "materials" property or primitive/material association
2 participants