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

Some more fixes for compressed meshes #83704

Merged
merged 1 commit into from
Oct 24, 2023

Conversation

clayjohn
Copy link
Member

@clayjohn clayjohn commented Oct 20, 2023

This cleans up a few more cases of uint32_t->uint64_t

Importantly this fixes an edge case in the axis-angle compression by using the pre-existing Basis methods instead

Fixes: #83240
Fixes: #83526

This might help #83667, but I wasn't able to reproduce, so I don't know for sure.

For posterity, most of the changes here are just cleaning up uint32_t->uint64_t and other QoL changes I caught while debugging. The biggest change is the change to _get_axis_angle(). Instead of using the small helper function, I switched to using Basis::_get_axis_angle() which has the proper check for if the matrix is symmetrical. The issue we were running into was that some meshes contain bogus tangents (#83240 is full of them). This can happen with meshes that don't have UVs set up for normalmapping and have the "generate_tangents" flag checked by default.

Sfter spending hours trying to understand the math behind the compression and find any source for the original code. I stumbled on https://en.wikipedia.org/wiki/Rotation_matrix#Conversion_from_rotation_matrix_to_axis%E2%80%93angle which explains everything perfectly and derives the steps exactly how we have them laid out in the code. It contains this important warning:

This does not work if R is symmetric. ... In this case, it is necessary to diagonalize R and find the eigenvector corresponding to an eigenvalue of 1.

In searching for is_symmetric(), I found diagonalize() which led me to Basis::_get_axis_angle() which contained all the proper checks and cleaning to properly handle bogus tangents. Accordingly, I switched over to using Basis entirely and everything works nicely.

@@ -1399,7 +1397,7 @@ Array RenderingServer::_get_array_from_surface(uint64_t p_format, Vector<uint8_t
tangentsw[j * 4 + 3] = tan.w;
}
ret[RS::ARRAY_NORMAL] = normals;
ret[RS::ARRAY_FORMAT_TANGENT] = tangents;
ret[RS::ARRAY_TANGENT] = tangents;
Copy link
Member Author

Choose a reason for hiding this comment

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

This alone fixes #83526. What a silly mistake

servers/rendering_server.h Outdated Show resolved Hide resolved
scene/resources/mesh.cpp Outdated Show resolved Hide resolved
@fire
Copy link
Member

fire commented Oct 21, 2023

I looked at these compressed mesh fixes, but I wasn't able to see anything obviously wrong.

scene/resources/mesh.cpp Outdated Show resolved Hide resolved
@clayjohn
Copy link
Member Author

Updated based on comments!

scene/resources/mesh.cpp Outdated Show resolved Hide resolved
This cleans up a few more cases of uint32_t->uint64_t

Importantly this fixes an edge case in the axis-angle compression by
using the pre-existing Basis methods instead
@clayjohn
Copy link
Member Author

Fixed up the error message and rebased!

@akien-mga akien-mga merged commit 261fe7c into godotengine:master Oct 24, 2023
15 checks passed
@akien-mga
Copy link
Member

Thanks!

@clayjohn clayjohn deleted the misc-mesh-fixes branch October 25, 2023 20:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants