question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Struggling with Invalid Matrix

See original GitHub issue

I’ve been struggling with matrices lately, and I’m wondering whether Matrix4x4.Decompose is too strict or the matrix is truly poorly formed.

I’m using the SceneBuilder API to put together a node hierarchy. For each node, I set the local matrix like so:

var nb = nodeBuilder.CreateNode(bone.Name);
nb.UseTranslation().Value = bone.Position;
nb.UseRotation().Value = bone.Rotation;
nb.UseScale().Value = bone.Scale;

Then, I create a mesh, and calculate the inverse bind matrices:

var nb = nodeBuilders[bb.BoneIndex];
var wm = nb.WorldMatrix;
Matrix4x4.Invert(wm, out Matrix4x4 wmi);
wmi.M44 = 1; // force to be one
return (nb, wmi);

Note: Somehow M44 becomes 0.999999, which is probably due to a precision error caused during the Invert method, and the gltf validator doesn’t like this so I forced it to a 1.

Now when I save the gltf file, I get a complaint that a matrix is invalid. I commented out the part that throws the exception just to force the file to save and I can inspect it on my own.

I believe this is due to the Matrix4x4.Decompose function returning false. I think it returns false because the determinant of the rotation part of the matrix is <0.985 as opposed to 1.0 and that’s enough to fail the “DecomposeEpsilon” threshold. When I use the gltf validator provided by Khronos, it says the file is valid.

I guess the question is whether these matrices are good enough and the Decompose method is too strict. I also wonder where the imprecison comes from. The local matrices are created from proper position, rotation, and scale data. Maybe if the hierarchy is deep enough, then computing the world matrix loses precision after so many local matrices are multiplied together.

I just wanted to get your thoughts on this, and what we can do about this. I have attached an example gltf. grnGltf.zip

Thanks!

I also posted a similar issue in the dotnet repo where Decompose returns false in an even simpler example. I was hoping someone could explain how precision was lost, and what to do about it. Initially I thought it was a bug, but now I think either the threshold is too strict, or there are precision problems. https://github.com/dotnet/runtime/issues/34874

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:24 (24 by maintainers)

github_iconTop GitHub Comments

1reaction
vpenadescommented, Apr 22, 2020

I understand the difference between SxR and RxS is that in the latter, the uneven scaling is applied to the axes on an already unaligned matrix (because it was previously rotated) and that produces a skewed matrix. It is not possible to do with a single local matrix. But it is possible to do with a rotated parent node, and an unevenly scaled child node.

I also realize now that the columns/rows of orthogonal matrices are not just orthogonal

Yes, that’s why my original code for matrix normalization used columns instead of rows. But I’ve made some further checks, and for some reason, it only works well if applied to rows.

I don’t think the double matrix4x4 made much of a difference in the end and can probably be removed.

It doesn’t hurt either, and I believe it can be useful to improve precission with long hierarchy chains, so I’ll probably leave it.

By the way, here’s my implementation of skipping matrices…

That class looks very much like Transforms.AffineTransform, maybe I could add that functionality to it.

0reactions
ptasevcommented, Apr 22, 2020

Yes, I think you’re right. I just wish I could find something that explains this mathematically in the context of TRS matrices. I also realize now that the columns/rows of orthogonal matrices are not just orthogonal, but also orthonormal so I’ve been using that term wrong, and scaled matrices are not orthogonal.

Anyway, I think this is the correct solution. I don’t think the double matrix4x4 made much of a difference in the end and can probably be removed.

By the way, here’s my implementation of skipping matrices, and using only SRT parts to create a world matrix. The code is really ugly since I put it together really fast for my testing. https://gist.github.com/ptasev/bce22ca61d9da83a702c2011229b76ab

Read more comments on GitHub >

github_iconTop Results From Across the Web

Solved: Invalid Matrix Token
What is an "invalid matrix token" error? What does it mean? When I try to instantiate a matrix in my script like m...
Read more >
Problems of Matrix Organizations
A power struggle in a matrix is qualitatively different from that in a traditionally structured hierarchy because in the latter it is clearly...
Read more >
Getting errors and incorrect matrix form. - MATLAB Answers
I have been able to clear my function of errors so that it returns an answer, however its not coming back as a...
Read more >
tensorflow Invalid argument: In[0] is not a matrix
The error message gives a clue to the problem: neither W nor x1 is a 2-D matrix—in fact, both are 1-D vectors—and the ......
Read more >
Invalid Matrix
Ignoring invalid matrix assigned to GUI.matrix - the matrix needs to be invertible. Did you scale by 0 on Z-axis?
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found