From 2fec5e5dd3067de3698c71f208eeccdcc10c9a63 Mon Sep 17 00:00:00 2001 From: x2048 Date: Sun, 2 Jan 2022 20:41:03 +0100 Subject: [PATCH] Reset mesh animation state before recalculating normals (#90) --- include/ISkinnedMesh.h | 3 +++ source/Irrlicht/CMeshManipulator.cpp | 6 ++++++ source/Irrlicht/CSkinnedMesh.cpp | 18 ++++++++++++++++++ source/Irrlicht/CSkinnedMesh.h | 3 +++ 4 files changed, 30 insertions(+) diff --git a/include/ISkinnedMesh.h b/include/ISkinnedMesh.h index 8529ae1..44d05e5 100644 --- a/include/ISkinnedMesh.h +++ b/include/ISkinnedMesh.h @@ -82,6 +82,9 @@ namespace scene //! Refreshes vertex data cached in joints such as positions and normals virtual void refreshJointCache() = 0; + //! Moves the mesh into static position. + virtual void resetAnimation() = 0; + //! A vertex weight struct SWeight { diff --git a/source/Irrlicht/CMeshManipulator.cpp b/source/Irrlicht/CMeshManipulator.cpp index b9ddb05..f2beb37 100644 --- a/source/Irrlicht/CMeshManipulator.cpp +++ b/source/Irrlicht/CMeshManipulator.cpp @@ -147,6 +147,12 @@ void CMeshManipulator::recalculateNormals(scene::IMesh* mesh, bool smooth, bool if (!mesh) return; + if (mesh->getMeshType() == EAMT_SKINNED) + { + ISkinnedMesh *smesh = (ISkinnedMesh *) mesh; + smesh->resetAnimation(); + } + const u32 bcount = mesh->getMeshBufferCount(); for ( u32 b=0; bgetMeshBuffer(b), smooth, angleWeighted); diff --git a/source/Irrlicht/CSkinnedMesh.cpp b/source/Irrlicht/CSkinnedMesh.cpp index eb9fb27..e41d6c3 100644 --- a/source/Irrlicht/CSkinnedMesh.cpp +++ b/source/Irrlicht/CSkinnedMesh.cpp @@ -829,6 +829,24 @@ void CSkinnedMesh::refreshJointCache() } } +void CSkinnedMesh::resetAnimation() +{ + //copy from the cache to the mesh... + for (u32 i=0; iWeights.size(); ++j) + { + const u16 buffer_id=joint->Weights[j].buffer_id; + const u32 vertex_id=joint->Weights[j].vertex_id; + LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos = joint->Weights[j].StaticPos; + LocalBuffers[buffer_id]->getVertex(vertex_id)->Normal = joint->Weights[j].StaticNormal; + } + } + SkinnedLastFrame = false; + LastAnimatedFrame = -1; +} + void CSkinnedMesh::calculateGlobalMatrices(SJoint *joint,SJoint *parentJoint) { if (!joint && parentJoint) // bit of protection from endless loops diff --git a/source/Irrlicht/CSkinnedMesh.h b/source/Irrlicht/CSkinnedMesh.h index d8c05af..86d3a6b 100644 --- a/source/Irrlicht/CSkinnedMesh.h +++ b/source/Irrlicht/CSkinnedMesh.h @@ -116,6 +116,9 @@ namespace scene //! Refreshes vertex data cached in joints such as positions and normals virtual void refreshJointCache() _IRR_OVERRIDE_; + //! Moves the mesh into static position. + virtual void resetAnimation() _IRR_OVERRIDE_; + //Interface for the mesh loaders (finalize should lock these functions, and they should have some prefix like loader_ //these functions will use the needed arrays, set values, etc to help the loaders