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

Bugfix at matrix calculation at FBX import #19093

Merged
merged 4 commits into from
Apr 11, 2020
Merged

Bugfix at matrix calculation at FBX import #19093

merged 4 commits into from
Apr 11, 2020

Conversation

crest01
Copy link

@crest01 crest01 commented Apr 9, 2020

During FBX import the transformation matrix calculation uses the Matrix4.multiply() - function wrong, which causes objects to have a wrong local rotation.

New Pull request, since #19092 was created from the wrong branch.

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 9, 2020

Is it somehow possible to demonstrate the issue with an asset? I mean is it actually visible when loading a FBX file or is it more an internal thing?

@mrdoob mrdoob added this to the r116 milestone Apr 10, 2020
@mrdoob
Copy link
Owner

mrdoob commented Apr 10, 2020

@looeee any chance you could test this?

@looeee
Copy link
Collaborator

looeee commented Apr 10, 2020

@looeee any chance you could test this?

Sure, but I need more info.

@crest01 can you explain in detail why this fix is needed? And can you share any FBX files you are using to test it?

@crest01
Copy link
Author

crest01 commented Apr 10, 2020

matrix1.multiply( matrix2 ) modifies matrix1 in place, which i guess works as intended. In the FBXLoader this is now used as matrix3 = matrix1.multiply( matrix2 ), which becomes a problem, since matrix1 is used in a later calculation during the quite complicated fbx pose calculation process.

However, this only becomes apparent if the objects in a fbx have a local rotation.

Issues #15745 and #15097 might be related.

I have a simple test file of two goats staring at a tree:
goats_test.zip

Blender
image

Three.JS viewer
image

@crest01
Copy link
Author

crest01 commented Apr 10, 2020

Also i only dabble as a js developer, and my solution feels somewhat inelegant. I wouldn't mind some hints on how to refactor that...

@WestLangley
Copy link
Collaborator

matrix3 = matrix1.multiply( matrix2 )

Yikes. I would avoid using that pattern. It is very confusing.

One alternative is:

matrix3.copy( matrix1 ).multiply( matrix2 );

The matrix methods return this to support chaining.

var lParentGSM = new Matrix4();
var lParentGRSM = new Matrix4();

var lParentTM_inv = new Matrix4().getInverse( lParentTM );
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just new Matrix4() is probably OK here since getInverse is called on the identity matrix.

Copy link
Owner

Choose a reason for hiding this comment

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

Oh, I've just noticed this comment. Well, we can do further clean up PRs 🙂


var lLocalTWithAllPivotAndOffsetInfo = new THREE.Matrix4().copyPosition( lTransform );

var lGlobalTranslation = lParentGX.multiply( lLocalTWithAllPivotAndOffsetInfo );
var lGlobalTranslation = new Matrix4().multiply(lParentGX).multiply( lLocalTWithAllPivotAndOffsetInfo );
Copy link
Collaborator

Choose a reason for hiding this comment

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

Formatting: needs spaces in parens multiply( lParentGX )

lGlobalT.copyPosition( lGlobalTranslation );

lTransform = lGlobalT.multiply( lGlobalRS );
lTransform = new Matrix4().multiply(lGlobalT).multiply( lGlobalRS );
Copy link
Collaborator

Choose a reason for hiding this comment

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

Spaces in parens.

@looeee
Copy link
Collaborator

looeee commented Apr 11, 2020

Works great, good job!

Issues #15745 and #15097 might be related.

This does fix #15745. Unfortunately, files on #15097 were shared on some site that doesn't work now, but I think we can assume this fixes that too.

matrix3 = matrix1.multiply( matrix2 )

Yikes. I would avoid using that pattern. It is very confusing.

Yeah, I think I did it that way to avoid an extra copy. That was definitely premature optimization though. I've done some timing and this code is only adding a couple of ms to the total load time.

@WestLangley do you think the PR is OK as is, or would you prefer to use the matrix3.copy( matrix1 ).multiply( matrix2 ); pattern?

@mrdoob
Copy link
Owner

mrdoob commented Apr 11, 2020

I'll clean up the formatting post merge.

@mrdoob mrdoob merged commit 6cd829f into mrdoob:dev Apr 11, 2020
@WestLangley
Copy link
Collaborator

@looeee I prefer what I suggested, but I think you should do whatever you prefer. :-)

@mrdoob
Copy link
Owner

mrdoob commented Apr 11, 2020

@WestLangley I think the code you're talking about is the previous code and not the new code.

@looeee
Copy link
Collaborator

looeee commented Apr 11, 2020

OK, then I think this PR is fine. We can look at improving the readability of this function another time.

Thanks @crest01!

@mrdoob
Copy link
Owner

mrdoob commented Apr 12, 2020

@crest01 while you're at it, do you have any ideas about #15287?

@pikilipita
Copy link

Just wanted to say, this bugfix works great: no more issues with fbx generated from Cinema 4D, and no regression on other models.
That was a long standing issue, thanks a lot!

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.

7 participants