mirror of
https://github.com/minetest/minetest.git
synced 2024-12-23 22:52:25 +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;
|
core::array<SWeight> Weights;
|
||||||
|
|
||||||
//! Unnecessary for loaders, will be overwritten on finalize
|
//! 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 GlobalAnimatedMatrix;
|
||||||
core::matrix4 LocalAnimatedMatrix;
|
core::matrix4 LocalAnimatedMatrix;
|
||||||
|
|
||||||
|
//! These should be set by loaders.
|
||||||
core::vector3df Animatedposition;
|
core::vector3df Animatedposition;
|
||||||
core::vector3df Animatedscale;
|
core::vector3df Animatedscale;
|
||||||
core::quaternion Animatedrotation;
|
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:
|
private:
|
||||||
//! Internal members used by CSkinnedMesh
|
//! Internal members used by CSkinnedMesh
|
||||||
friend class CSkinnedMesh;
|
friend class CSkinnedMesh;
|
||||||
|
@ -390,6 +390,7 @@ bool CB3DMeshFileLoader::readChunkVRTS(CSkinnedMesh::SJoint *inJoint)
|
|||||||
// Transform the Vertex position by nested node...
|
// Transform the Vertex position by nested node...
|
||||||
inJoint->GlobalMatrix.transformVect(Vertex.Pos);
|
inJoint->GlobalMatrix.transformVect(Vertex.Pos);
|
||||||
Vertex.Normal = inJoint->GlobalMatrix.rotateAndScaleVect(Vertex.Normal);
|
Vertex.Normal = inJoint->GlobalMatrix.rotateAndScaleVect(Vertex.Normal);
|
||||||
|
Vertex.Normal.normalize(); // renormalize: normal might have been skewed by scaling
|
||||||
|
|
||||||
// Add it...
|
// Add it...
|
||||||
BaseVertices.push_back(Vertex);
|
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.
|
// 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!
|
// 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->Animatedrotation.getMatrix_transposed(joint->LocalAnimatedMatrix);
|
||||||
|
|
||||||
// --- joint->LocalAnimatedMatrix *= joint->Animatedrotation.getMatrix() ---
|
// --- joint->LocalAnimatedMatrix *= joint->Animatedrotation.getMatrix() ---
|
||||||
@ -496,8 +497,8 @@ void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint)
|
|||||||
{
|
{
|
||||||
if (joint->Weights.size()) {
|
if (joint->Weights.size()) {
|
||||||
// Find this joints pull on vertices...
|
// Find this joints pull on vertices...
|
||||||
core::matrix4 jointVertexPull(core::matrix4::EM4CONST_NOTHING);
|
// Note: It is assumed that the global inversed matrix has been calculated at this point.
|
||||||
jointVertexPull.setbyproduct(joint->GlobalAnimatedMatrix, joint->GlobalInversedMatrix);
|
core::matrix4 jointVertexPull = joint->GlobalAnimatedMatrix * joint->GlobalInversedMatrix.value();
|
||||||
|
|
||||||
core::vector3df thisVertexMove, thisNormalMove;
|
core::vector3df thisVertexMove, thisNormalMove;
|
||||||
|
|
||||||
@ -510,8 +511,10 @@ void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint)
|
|||||||
// Pull this vertex...
|
// Pull this vertex...
|
||||||
jointVertexPull.transformVect(thisVertexMove, weight.StaticPos);
|
jointVertexPull.transformVect(thisVertexMove, weight.StaticPos);
|
||||||
|
|
||||||
if (AnimateNormals)
|
if (AnimateNormals) {
|
||||||
thisNormalMove = jointVertexPull.rotateAndScaleVect(weight.StaticNormal);
|
thisNormalMove = jointVertexPull.rotateAndScaleVect(weight.StaticNormal);
|
||||||
|
thisNormalMove.normalize(); // must renormalize after potentially scaling
|
||||||
|
}
|
||||||
|
|
||||||
if (!(*(weight.Moved))) {
|
if (!(*(weight.Moved))) {
|
||||||
*(weight.Moved) = true;
|
*(weight.Moved) = true;
|
||||||
@ -764,9 +767,9 @@ void CSkinnedMesh::calculateGlobalMatrices(SJoint *joint, SJoint *parentJoint)
|
|||||||
joint->LocalAnimatedMatrix = joint->LocalMatrix;
|
joint->LocalAnimatedMatrix = joint->LocalMatrix;
|
||||||
joint->GlobalAnimatedMatrix = joint->GlobalMatrix;
|
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 = joint->GlobalMatrix;
|
||||||
joint->GlobalInversedMatrix.makeInverse(); // slow
|
joint->GlobalInversedMatrix->makeInverse(); // slow
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 j = 0; j < joint->Children.size(); ++j)
|
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
|
// transforms the mesh vertices to the space of the bone
|
||||||
// When concatenated to the bone's transform, this provides the
|
// When concatenated to the bone's transform, this provides the
|
||||||
// world space coordinates of the mesh as affected by the bone
|
// world space coordinates of the mesh as affected by the bone
|
||||||
core::matrix4 &MatrixOffset = joint->GlobalInversedMatrix;
|
core::matrix4 MatrixOffset;
|
||||||
|
|
||||||
readMatrix(MatrixOffset);
|
readMatrix(MatrixOffset);
|
||||||
|
joint->GlobalInversedMatrix = MatrixOffset;
|
||||||
|
|
||||||
if (!checkForOneFollowingSemicolons()) {
|
if (!checkForOneFollowingSemicolons()) {
|
||||||
os::Printer::log("No finishing semicolon in Skin Weights found in x file", ELL_WARNING);
|
os::Printer::log("No finishing semicolon in Skin Weights found in x file", ELL_WARNING);
|
||||||
|
Loading…
Reference in New Issue
Block a user