mirror of
https://github.com/minetest/minetest.git
synced 2024-12-23 06:32:23 +01:00
Refactor global inversed matrix usage (+ minor fix)
Thanks to GreenXenith and Josiah for spotting a bug here
This commit is contained in:
parent
224066c1d3
commit
d8274af670
@ -159,15 +159,17 @@ public:
|
||||
core::array<SWeight> Weights;
|
||||
|
||||
//! Unnecessary for loaders, will be overwritten on finalize
|
||||
core::matrix4 GlobalMatrix;
|
||||
core::matrix4 GlobalMatrix; // loaders may still choose to set this (temporarily) to calculate absolute vertex data.
|
||||
core::matrix4 GlobalAnimatedMatrix;
|
||||
core::matrix4 LocalAnimatedMatrix;
|
||||
|
||||
//! These should be set by loaders.
|
||||
core::vector3df Animatedposition;
|
||||
core::vector3df Animatedscale;
|
||||
core::quaternion Animatedrotation;
|
||||
|
||||
core::matrix4 GlobalInversedMatrix; // the x format pre-calculates this
|
||||
|
||||
// The .x and .gltf formats pre-calculate this
|
||||
std::optional<core::matrix4> GlobalInversedMatrix;
|
||||
private:
|
||||
//! Internal members used by CSkinnedMesh
|
||||
friend class CSkinnedMesh;
|
||||
|
@ -390,6 +390,7 @@ bool CB3DMeshFileLoader::readChunkVRTS(CSkinnedMesh::SJoint *inJoint)
|
||||
// Transform the Vertex position by nested node...
|
||||
inJoint->GlobalMatrix.transformVect(Vertex.Pos);
|
||||
Vertex.Normal = inJoint->GlobalMatrix.rotateAndScaleVect(Vertex.Normal);
|
||||
Vertex.Normal.normalize(); // renormalize: normal might have been skewed by scaling
|
||||
|
||||
// Add it...
|
||||
BaseVertices.push_back(Vertex);
|
||||
|
@ -222,6 +222,7 @@ void CSkinnedMesh::buildAllLocalAnimatedMatrices()
|
||||
|
||||
// IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched to getMatrix_transposed instead of getMatrix for downward compatibility.
|
||||
// Not tested so far if this was correct or wrong before quaternion fix!
|
||||
// Note that using getMatrix_transposed inverts the rotation.
|
||||
joint->Animatedrotation.getMatrix_transposed(joint->LocalAnimatedMatrix);
|
||||
|
||||
// --- joint->LocalAnimatedMatrix *= joint->Animatedrotation.getMatrix() ---
|
||||
@ -496,8 +497,8 @@ void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint)
|
||||
{
|
||||
if (joint->Weights.size()) {
|
||||
// Find this joints pull on vertices...
|
||||
core::matrix4 jointVertexPull(core::matrix4::EM4CONST_NOTHING);
|
||||
jointVertexPull.setbyproduct(joint->GlobalAnimatedMatrix, joint->GlobalInversedMatrix);
|
||||
// Note: It is assumed that the global inversed matrix has been calculated at this point.
|
||||
core::matrix4 jointVertexPull = joint->GlobalAnimatedMatrix * joint->GlobalInversedMatrix.value();
|
||||
|
||||
core::vector3df thisVertexMove, thisNormalMove;
|
||||
|
||||
@ -510,8 +511,10 @@ void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint)
|
||||
// Pull this vertex...
|
||||
jointVertexPull.transformVect(thisVertexMove, weight.StaticPos);
|
||||
|
||||
if (AnimateNormals)
|
||||
if (AnimateNormals) {
|
||||
thisNormalMove = jointVertexPull.rotateAndScaleVect(weight.StaticNormal);
|
||||
thisNormalMove.normalize(); // must renormalize after potentially scaling
|
||||
}
|
||||
|
||||
if (!(*(weight.Moved))) {
|
||||
*(weight.Moved) = true;
|
||||
@ -764,9 +767,9 @@ void CSkinnedMesh::calculateGlobalMatrices(SJoint *joint, SJoint *parentJoint)
|
||||
joint->LocalAnimatedMatrix = joint->LocalMatrix;
|
||||
joint->GlobalAnimatedMatrix = joint->GlobalMatrix;
|
||||
|
||||
if (joint->GlobalInversedMatrix.isIdentity()) { // might be pre calculated
|
||||
if (!joint->GlobalInversedMatrix.has_value()) { // might be pre calculated
|
||||
joint->GlobalInversedMatrix = joint->GlobalMatrix;
|
||||
joint->GlobalInversedMatrix.makeInverse(); // slow
|
||||
joint->GlobalInversedMatrix->makeInverse(); // slow
|
||||
}
|
||||
|
||||
for (u32 j = 0; j < joint->Children.size(); ++j)
|
||||
|
@ -990,9 +990,9 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh)
|
||||
// transforms the mesh vertices to the space of the bone
|
||||
// When concatenated to the bone's transform, this provides the
|
||||
// world space coordinates of the mesh as affected by the bone
|
||||
core::matrix4 &MatrixOffset = joint->GlobalInversedMatrix;
|
||||
|
||||
core::matrix4 MatrixOffset;
|
||||
readMatrix(MatrixOffset);
|
||||
joint->GlobalInversedMatrix = MatrixOffset;
|
||||
|
||||
if (!checkForOneFollowingSemicolons()) {
|
||||
os::Printer::log("No finishing semicolon in Skin Weights found in x file", ELL_WARNING);
|
||||
|
Loading…
Reference in New Issue
Block a user