Mesh no longer contains the animation

Former-commit-id: 5dfcfe50f9c82310303120031a0def594fafd4f7
This commit is contained in:
Lynix 2012-11-27 22:02:45 +01:00
parent 53730b532d
commit 7ad24eff08
6 changed files with 29 additions and 217 deletions

View File

@ -33,7 +33,7 @@ class NAZARA_API NzKeyframeMesh final : public NzSubMesh
bool GetVertex(NzMeshVertex* dest, unsigned int frameIndex, unsigned int vertexIndex, bool queryUV = true) const;
const NzVertexBuffer* GetVertexBuffer() const override;
void Interpolate(unsigned int frameA, unsigned int frameB, float interpolation) const;
void Interpolate(const NzAnimation* animation, unsigned int frameA, unsigned int frameB, float interpolation) const;
bool IsAnimated() const override;
bool IsValid();

View File

@ -49,7 +49,7 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener
bool AddSubMesh(NzSubMesh* subMesh);
bool AddSubMesh(const NzString& identifier, NzSubMesh* subMesh);
void Animate(unsigned int frameA, unsigned int frameB, float interpolation) const;
void Animate(const NzAnimation* animation, unsigned int frameA, unsigned int frameB, float interpolation) const;
bool CreateKeyframe();
bool CreateSkeletal(unsigned int jointCount);
@ -57,9 +57,7 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener
void Destroy();
const NzAxisAlignedBox& GetAABB() const;
const NzAnimation* GetAnimation() const;
nzAnimationType GetAnimationType() const;
unsigned int GetFrameCount() const;
unsigned int GetJointCount() const;
NzString GetMaterial(unsigned int index) const;
unsigned int GetMaterialCount() const;
@ -73,7 +71,6 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener
int GetSubMeshIndex(const NzString& identifier) const;
unsigned int GetVertexCount() const;
bool HasAnimation() const;
bool HasSubMesh(const NzString& identifier) const;
bool HasSubMesh(unsigned int index = 0) const;
@ -89,7 +86,6 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener
void RemoveSubMesh(const NzString& identifier);
void RemoveSubMesh(unsigned int index);
bool SetAnimation(const NzAnimation* animation);
void SetMaterial(unsigned int matIndex, const NzString& materialPath);
void SetMaterialCount(unsigned int matCount);
@ -98,7 +94,6 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener
static const NzVertexDeclaration* GetDeclaration();
private:
void OnResourceCreated(const NzResource* resource, int index) override;
void OnResourceReleased(const NzResource* resource, int index) override;
NzMeshImpl* m_impl = nullptr;

View File

@ -222,16 +222,22 @@ const NzVertexBuffer* NzKeyframeMesh::GetVertexBuffer() const
return m_impl->vertexBuffer;
}
void NzKeyframeMesh::Interpolate(unsigned int frameA, unsigned int frameB, float interpolation) const
void NzKeyframeMesh::Interpolate(const NzAnimation* animation, unsigned int frameA, unsigned int frameB, float interpolation) const
{
#if NAZARA_UTILITY_SAFE
if (!m_parent->HasAnimation())
if (!animation || !animation->IsValid())
{
NazaraError("Parent mesh has no animation");
NazaraError("Animation must be valid");
return;
}
unsigned int frameCount = m_parent->GetFrameCount();
if (animation->GetType() != nzAnimationType_Keyframe)
{
NazaraError("Animation must be of keyframe type");
return;
}
unsigned int frameCount = animation->GetFrameCount();
if (frameA >= frameCount)
{
NazaraError("Frame A is out of range (" + NzString::Number(frameA) + " >= " + NzString::Number(frameCount) + ')');

View File

@ -100,76 +100,6 @@ namespace
}
}
/// Chargement des animations
if (animated)
{
NzAnimation* animation = new NzAnimation;
if (animation->CreateKeyframe(endFrame-startFrame+1))
{
// Décodage des séquences
///TODO: Optimiser le calcul
char last[16];
stream.SetCursorPos(header.offset_frames + startFrame*header.framesize + 2*sizeof(NzVector3f));
stream.Read(last, 16*sizeof(char));
int pos = std::strlen(last)-1;
for (unsigned int j = 0; j < 2; ++j)
{
if (!std::isdigit(last[pos]))
break;
pos--;
}
last[pos+1] = '\0';
NzSequence sequence;
sequence.firstFrame = startFrame;
sequence.frameCount = 0;
sequence.frameRate = 10; // Par défaut pour les animations MD2
sequence.name = last;
char name[16];
for (unsigned int i = startFrame; i <= endFrame; ++i)
{
stream.SetCursorPos(header.offset_frames + i*header.framesize + 2*sizeof(NzVector3f));
stream.Read(name, 16*sizeof(char));
pos = std::strlen(name)-1;
for (unsigned int j = 0; j < 2; ++j)
{
if (!std::isdigit(name[pos]))
break;
pos--;
}
name[pos+1] = '\0';
if (std::strcmp(name, last) != 0) // Si les deux frames n'ont pas le même nom
{
std::strcpy(last, name);
// Alors on enregistre la séquence actuelle
animation->AddSequence(sequence);
// Et on initialise la séquence suivante
sequence.firstFrame = i;
sequence.frameCount = 0;
sequence.name = last;
}
sequence.frameCount++;
}
// On ajoute la dernière frame (Qui n'a pas été traitée par la boucle)
animation->AddSequence(sequence);
mesh->SetAnimation(animation);
animation->SetPersistent(false);
}
else
NazaraInternalError("Failed to create animaton");
}
/// Chargement des submesh
// Actuellement le loader ne charge qu'un submesh
// TODO: Utiliser les commandes OpenGL pour créer des indices et accélérer le rendu

View File

@ -314,21 +314,6 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
}
subMesh.release();
// Animation
// Il est peut-être éventuellement possible que la probabilité que l'animation ait le même nom soit non-nulle.
if (!baseDir.IsEmpty())
{
baseDir.Replace(".md5mesh", ".md5anim", -8, NzString::CaseInsensitive);
if (NzFile::Exists(baseDir))
{
std::unique_ptr<NzAnimation> animation(new NzAnimation);
if (animation->LoadFromFile(baseDir) && mesh->SetAnimation(animation.get()))
animation.release();
else
NazaraWarning("Failed to load mesh's animation");
}
}
}
}
else

View File

@ -46,7 +46,6 @@ struct NzMeshImpl
nzAnimationType animationType;
NzAxisAlignedBox aabb;
NzSkeleton skeleton; // Uniquement pour les animations squelettiques
const NzAnimation* animation = nullptr;
unsigned int jointCount; // Uniquement pour les animations squelettiques
};
@ -72,7 +71,7 @@ bool NzMesh::AddSubMesh(NzSubMesh* subMesh)
if (subMesh->GetAnimationType() != m_impl->animationType)
{
NazaraError("Submesh's animation type must match mesh animation type");
NazaraError("Submesh animation type must match mesh animation type");
return false;
}
#endif
@ -115,7 +114,7 @@ bool NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh)
if (m_impl->animationType != subMesh->GetAnimationType())
{
NazaraError("Submesh's animation type must match mesh animation type");
NazaraError("Submesh animation type must match mesh animation type");
return false;
}
#endif
@ -131,7 +130,7 @@ bool NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh)
return true;
}
void NzMesh::Animate(unsigned int frameA, unsigned int frameB, float interpolation) const
void NzMesh::Animate(const NzAnimation* animation, unsigned int frameA, unsigned int frameB, float interpolation) const
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
@ -140,13 +139,19 @@ void NzMesh::Animate(unsigned int frameA, unsigned int frameB, float interpolati
return;
}
if (!m_impl->animation)
if (!animation || !animation->IsValid())
{
NazaraError("Mesh has no animation");
NazaraError("Animation must be valid");
return;
}
unsigned int frameCount = m_impl->animation->GetFrameCount();
if (animation->GetType() != m_impl->animationType)
{
NazaraError("Animation type must match mesh animation type");
return;
}
unsigned int frameCount = animation->GetFrameCount();
if (frameA >= frameCount)
{
NazaraError("Frame A is out of range (" + NzString::Number(frameA) + " >= " + NzString::Number(frameCount) + ')');
@ -174,12 +179,12 @@ void NzMesh::Animate(unsigned int frameA, unsigned int frameB, float interpolati
for (NzSubMesh* subMesh : m_impl->subMeshes)
{
NzKeyframeMesh* keyframeMesh = static_cast<NzKeyframeMesh*>(subMesh);
keyframeMesh->Interpolate(frameA, frameB, interpolation);
keyframeMesh->InterpolateImpl(frameA, frameB, interpolation);
}
break;
case nzAnimationType_Skeletal:
m_impl->animation->AnimateSkeleton(&m_impl->skeleton, frameA, frameB, interpolation);
animation->AnimateSkeleton(&m_impl->skeleton, frameA, frameB, interpolation);
for (NzSubMesh* subMesh : m_impl->subMeshes)
{
NzSkeletalMesh* skeletalMesh = static_cast<NzSkeletalMesh*>(subMesh);
@ -243,9 +248,6 @@ void NzMesh::Destroy()
{
NotifyDestroy();
if (m_impl->animation)
m_impl->animation->RemoveResourceListener(this);
for (NzSubMesh* subMesh : m_impl->subMeshes)
subMesh->RemoveResourceListener(this);
@ -273,19 +275,6 @@ const NzAxisAlignedBox& NzMesh::GetAABB() const
return m_impl->aabb;
}
const NzAnimation* NzMesh::GetAnimation() const
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Mesh not created");
return nullptr;
}
#endif
return m_impl->animation;
}
nzAnimationType NzMesh::GetAnimationType() const
{
#if NAZARA_UTILITY_SAFE
@ -299,25 +288,6 @@ nzAnimationType NzMesh::GetAnimationType() const
return m_impl->animationType;
}
unsigned int NzMesh::GetFrameCount() const
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Mesh not created");
return 0;
}
if (!m_impl->animation)
{
NazaraError("Mesh has no animation");
return 0;
}
#endif
return m_impl->animation->GetFrameCount();
}
unsigned int NzMesh::GetJointCount() const
{
#if NAZARA_UTILITY_SAFE
@ -557,19 +527,6 @@ void NzMesh::InvalidateAABB() const
m_impl->aabb.SetNull();
}
bool NzMesh::HasAnimation() const
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Mesh not created");
return false;
}
#endif
return m_impl->animation != nullptr;
}
bool NzMesh::HasSubMesh(const NzString& identifier) const
{
#if NAZARA_UTILITY_SAFE
@ -688,48 +645,6 @@ void NzMesh::RemoveSubMesh(unsigned int index)
m_impl->aabb.SetNull(); // On invalide l'AABB
}
bool NzMesh::SetAnimation(const NzAnimation* animation)
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Mesh not created");
return false;
}
if (m_impl->animationType == nzAnimationType_Static)
{
NazaraError("Static meshes cannot have animation");
return false;
}
#endif
if (animation == m_impl->animation)
return true;
if (m_impl->animation)
m_impl->animation->RemoveResourceListener(this);
if (animation)
{
#if NAZARA_UTILITY_SAFE
if (animation->GetType() != m_impl->animationType)
{
NazaraError("Animation's type must match mesh animation type");
m_impl->animation = nullptr;
return false;
}
#endif
animation->AddResourceListener(this);
}
m_impl->animation = animation;
return true;
}
void NzMesh::SetMaterial(unsigned int matIndex, const NzString& materialPath)
{
#if NAZARA_UTILITY_SAFE
@ -824,30 +739,11 @@ const NzVertexDeclaration* NzMesh::GetDeclaration()
return &declaration;
}
void NzMesh::OnResourceCreated(const NzResource* resource, int index)
{
NazaraUnused(index);
if (resource == m_impl->animation)
{
#if NAZARA_UTILITY_SAFE
if (m_impl->animation->GetType() != m_impl->animationType)
{
NazaraError("Animation's type must match mesh animation type");
m_impl->animation->RemoveResourceListener(this);
m_impl->animation = nullptr;
}
#endif
}
}
void NzMesh::OnResourceReleased(const NzResource* resource, int index)
{
if (resource == m_impl->animation)
SetAnimation(nullptr);
else
RemoveSubMesh(index);
NazaraUnused(resource);
RemoveSubMesh(index);
}
NzMeshLoader::LoaderList NzMesh::s_loaders;