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.
This commit is contained in:
x2048 2021-11-16 12:30:31 +01:00 committed by GitHub
parent 81bae5b717
commit 39cad3e618
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 0 deletions

View File

@ -79,6 +79,9 @@ namespace scene
/* This feature is not implemented in Irrlicht yet */ /* This feature is not implemented in Irrlicht yet */
virtual bool setHardwareSkinning(bool on) = 0; virtual bool setHardwareSkinning(bool on) = 0;
//! Refreshes vertex data cached in joints such as positions and normals
virtual void refreshJointCache() = 0;
//! A vertex weight //! A vertex weight
struct SWeight struct SWeight
{ {

View File

@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in irrlicht.h // For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CMeshManipulator.h" #include "CMeshManipulator.h"
#include "ISkinnedMesh.h"
#include "SMesh.h" #include "SMesh.h"
#include "CMeshBuffer.h" #include "CMeshBuffer.h"
#include "SAnimatedMesh.h" #include "SAnimatedMesh.h"
@ -149,6 +150,12 @@ void CMeshManipulator::recalculateNormals(scene::IMesh* mesh, bool smooth, bool
const u32 bcount = mesh->getMeshBufferCount(); const u32 bcount = mesh->getMeshBufferCount();
for ( u32 b=0; b<bcount; ++b) for ( u32 b=0; b<bcount; ++b)
recalculateNormals(mesh->getMeshBuffer(b), smooth, angleWeighted); recalculateNormals(mesh->getMeshBuffer(b), smooth, angleWeighted);
if (mesh->getMeshType() == EAMT_SKINNED)
{
ISkinnedMesh *smesh = (ISkinnedMesh *) mesh;
smesh->refreshJointCache();
}
} }

View File

@ -813,6 +813,21 @@ bool CSkinnedMesh::setHardwareSkinning(bool on)
return HardwareSkinning; return HardwareSkinning;
} }
void CSkinnedMesh::refreshJointCache()
{
//copy cache from the mesh...
for (u32 i=0; i<AllJoints.size(); ++i)
{
SJoint *joint=AllJoints[i];
for (u32 j=0; j<joint->Weights.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) void CSkinnedMesh::calculateGlobalMatrices(SJoint *joint,SJoint *parentJoint)
{ {

View File

@ -113,6 +113,9 @@ namespace scene
//! (This feature is not implemented in irrlicht yet) //! (This feature is not implemented in irrlicht yet)
virtual bool setHardwareSkinning(bool on) _IRR_OVERRIDE_; 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_ //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 //these functions will use the needed arrays, set values, etc to help the loaders