Fix bounding boxes after f73fa05542
Skinning calculations must happen in bone-space.
Fixes f73fa05542
Reported by: langbart
Fixes #6168
Differential Revision: https://code.wildfiregames.com/D3927
This was SVN commit r25387.
This commit is contained in:
parent
781afea4b1
commit
100159548c
@ -33,7 +33,9 @@
|
||||
|
||||
void CModelDef::GetMaxBounds(CSkeletonAnimDef* anim, bool loop, CBoundingBoxAligned& result)
|
||||
{
|
||||
std::unordered_map<u32, CBoundingBoxAligned>::const_iterator it = m_MaxBoundsPerAnimDef.find(anim ? anim->m_UID : 0);
|
||||
const u32 animIndex = anim ? anim->m_UID : 0;
|
||||
|
||||
std::unordered_map<u32, CBoundingBoxAligned>::const_iterator it = m_MaxBoundsPerAnimDef.find(animIndex);
|
||||
if (it != m_MaxBoundsPerAnimDef.end())
|
||||
{
|
||||
result = it->second;
|
||||
@ -47,19 +49,28 @@ void CModelDef::GetMaxBounds(CSkeletonAnimDef* anim, bool loop, CBoundingBoxAlig
|
||||
{
|
||||
for (size_t i = 0; i < numverts; ++i)
|
||||
result += verts[i].m_Coords;
|
||||
m_MaxBoundsPerAnimDef[0] = result;
|
||||
m_MaxBoundsPerAnimDef[animIndex] = result;
|
||||
return;
|
||||
}
|
||||
ENSURE(anim->m_UID != 0);
|
||||
ENSURE(animIndex != 0);
|
||||
CMatrix3D* inverseBindBoneMatrix = GetInverseBindBoneMatrices();
|
||||
std::vector<CMatrix3D> boneMatrix(anim->GetNumKeys());
|
||||
// NB: by using frames, the bounds are technically pessimistic (since interpolation could end up outside of them).
|
||||
for (size_t j = 0; j < anim->GetNumFrames(); ++j)
|
||||
|
||||
const size_t numFrames = anim->GetNumFrames();
|
||||
const float frameTime = anim->GetFrameTime();
|
||||
const size_t numBones = GetNumBones();
|
||||
|
||||
// NB: by using frames, the bounds are technically pessimistic,
|
||||
// since interpolation between frames can put vertices farther.
|
||||
for (size_t j = 0; j < numFrames; ++j)
|
||||
{
|
||||
anim->BuildBoneMatrices(j*anim->GetFrameTime(), boneMatrix.data(), loop);
|
||||
anim->BuildBoneMatrices(j * frameTime, boneMatrix.data(), loop);
|
||||
for (size_t i = 0; i < numBones; ++i)
|
||||
boneMatrix[i] *= inverseBindBoneMatrix[i];
|
||||
for (size_t i = 0; i < numverts; ++i)
|
||||
result += SkinPoint(verts[i], boneMatrix.data());
|
||||
}
|
||||
m_MaxBoundsPerAnimDef[anim->m_UID] = result;
|
||||
m_MaxBoundsPerAnimDef[animIndex] = result;
|
||||
}
|
||||
|
||||
CVector3D CModelDef::SkinPoint(const SModelVertex& vtx,
|
||||
|
@ -28,19 +28,22 @@
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/FileIo.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
// Start IDs at 1 to leave 0 as a special value.
|
||||
u32 CSkeletonAnimDef::nextUID = 1;
|
||||
u32 g_NextSkeletonDefUID = 1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CSkeletonAnimDef constructor
|
||||
CSkeletonAnimDef::CSkeletonAnimDef() : m_FrameTime(0), m_NumKeys(0), m_NumFrames(0)
|
||||
{
|
||||
m_UID = nextUID++;
|
||||
m_UID = g_NextSkeletonDefUID++;
|
||||
// Log a warning if we ever overflow. Should that not result from a bug, bumping to u64 ought to suffice.
|
||||
if (nextUID == 0)
|
||||
if (g_NextSkeletonDefUID == 0)
|
||||
{
|
||||
// Reset to 1.
|
||||
nextUID++;
|
||||
g_NextSkeletonDefUID++;
|
||||
LOGWARNING("CSkeletonAnimDef unique ID overflowed to 0 - model-animation bounds may be incorrect.");
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,6 @@ public:
|
||||
// Unique identifier - used by CModelDef to cache bounds per-animDef.
|
||||
// (hopefully we won't run into the u32 limit too soon).
|
||||
u32 m_UID;
|
||||
static u32 nextUID;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user