From 39cad3e6180b25318b215182f931dff9a378ed67 Mon Sep 17 00:00:00 2001 From: x2048 Date: Tue, 16 Nov 2021 12:30:31 +0100 Subject: [PATCH] Fix updating of vertex normals for animated meshes (#77) Updates cached positions and normals of animated vertices from the mesh. Useful when using meshManipulator to update the normals. --- include/ISkinnedMesh.h | 3 +++ source/Irrlicht/CMeshManipulator.cpp | 7 +++++++ source/Irrlicht/CSkinnedMesh.cpp | 15 +++++++++++++++ source/Irrlicht/CSkinnedMesh.h | 3 +++ 4 files changed, 28 insertions(+) diff --git a/include/ISkinnedMesh.h b/include/ISkinnedMesh.h index 783b26eb..8529ae16 100644 --- a/include/ISkinnedMesh.h +++ b/include/ISkinnedMesh.h @@ -79,6 +79,9 @@ namespace scene /* This feature is not implemented in Irrlicht yet */ virtual bool setHardwareSkinning(bool on) = 0; + //! Refreshes vertex data cached in joints such as positions and normals + virtual void refreshJointCache() = 0; + //! A vertex weight struct SWeight { diff --git a/source/Irrlicht/CMeshManipulator.cpp b/source/Irrlicht/CMeshManipulator.cpp index f177fc26..b9ddb05e 100644 --- a/source/Irrlicht/CMeshManipulator.cpp +++ b/source/Irrlicht/CMeshManipulator.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in irrlicht.h #include "CMeshManipulator.h" +#include "ISkinnedMesh.h" #include "SMesh.h" #include "CMeshBuffer.h" #include "SAnimatedMesh.h" @@ -149,6 +150,12 @@ void CMeshManipulator::recalculateNormals(scene::IMesh* mesh, bool smooth, bool const u32 bcount = mesh->getMeshBufferCount(); for ( u32 b=0; bgetMeshBuffer(b), smooth, angleWeighted); + + if (mesh->getMeshType() == EAMT_SKINNED) + { + ISkinnedMesh *smesh = (ISkinnedMesh *) mesh; + smesh->refreshJointCache(); + } } diff --git a/source/Irrlicht/CSkinnedMesh.cpp b/source/Irrlicht/CSkinnedMesh.cpp index bc94759f..31b84508 100644 --- a/source/Irrlicht/CSkinnedMesh.cpp +++ b/source/Irrlicht/CSkinnedMesh.cpp @@ -813,6 +813,21 @@ bool CSkinnedMesh::setHardwareSkinning(bool on) return HardwareSkinning; } +void CSkinnedMesh::refreshJointCache() +{ + //copy cache from 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; + joint->Weights[j].StaticPos = LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos; + joint->Weights[j].StaticNormal = LocalBuffers[buffer_id]->getVertex(vertex_id)->Normal; + } + } +} void CSkinnedMesh::calculateGlobalMatrices(SJoint *joint,SJoint *parentJoint) { diff --git a/source/Irrlicht/CSkinnedMesh.h b/source/Irrlicht/CSkinnedMesh.h index b39aa87b..d8c05af8 100644 --- a/source/Irrlicht/CSkinnedMesh.h +++ b/source/Irrlicht/CSkinnedMesh.h @@ -113,6 +113,9 @@ namespace scene //! (This feature is not implemented in irrlicht yet) virtual bool setHardwareSkinning(bool on) _IRR_OVERRIDE_; + //! Refreshes vertex data cached in joints such as positions and normals + virtual void refreshJointCache() _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