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

Import: guess original bind pose from inverseBindMatrices #941

Merged
merged 2 commits into from
Mar 17, 2020
Merged

Import: guess original bind pose from inverseBindMatrices #941

merged 2 commits into from
Mar 17, 2020

Conversation

scurest
Copy link
Contributor

@scurest scurest commented Feb 23, 2020

Try to guess the original bind pose for bones from the inverse bind matrices. This puts skinned meshes in edit mode back much closer to how they were before the vnode stuff went in.

out

This assumes the inverse bind matrices were computed the obvious way

(bind matrix for bone b) =
    (bind local for (child of) skeleton root) *
    ... *
    (bind local for grandparent of b) *
    (bind local for parent of b) *
    (bind local for b)

(inverse bind matrix for bone b) = inverse((bind matrix for bone b))

Any scale is just discarded since edit bones don't have scales. If we can't guess the original bind local for a bone, we fallback to using the value from the default/rest pose.

Possible problems?

This worked for all the files I tested with (I re-tested with all the models fire posted, CesiumMan, Monster, etc.)

However I'm sort of nervous about how it will work on "weirder" glTF files, so I thought to add an import option (on by default) to enable this. If you don't want to add it though, I can just drop the second commit.

Possible problems:

  • The glTF might just not contain enough info to reconstruct the bind local (eg. no skin.skeleton, "gaps" in the joint tree like X -> Y -> Z where X and Z are joints but Y isn't)
  • A node might have more than one inverse bind matrix if its used in multiple skins (this will use whichever one comes last)
  • inverseBindMatrices might not actually contain the "real" inverse bind matrices computed with the formula above (eg. the inverse binds might be pre-applied so inverseBindMatrices are all 1)
  • And sometimes it's apparently better to retarget onto the default pose even if we can find the original pose (Brainstem is the only case I found)

brainout

@scurest
Copy link
Contributor Author

scurest commented Feb 23, 2020

What's everybody else thinks about adding the import option for this? I'm kind of undecided (/_\)

@julienduroure julienduroure added enhancement New feature or request importer This involves or affects the import process Skinning_&_Rigging labels Feb 25, 2020
@scurest
Copy link
Contributor Author

scurest commented Mar 9, 2020

I retested with #946 applied and all the bones looked okay except for the model from #848

out

The problem appears to be

inverseBindMatrices might not actually contain the "real" inverse bind matrices computed with the formula above

because some leaf bones inexplicably have an inverseBindMatrix of 1, which means they all wind up at the origin.

Since the code to guess the original bind pose isn't perfect, let
the user choose to disable it.
@julienduroure
Copy link
Collaborator

Well, with option to use the guess or not, I think we can commit

@scurest
Copy link
Contributor Author

scurest commented Mar 12, 2020

Yeah, I also came down on the option being a good idea. And even for the RubyRose model, it's still slightly better than how it was in 2.82 even with the option on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request importer This involves or affects the import process Skinning_&_Rigging
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants