Mesh no longer contains the animation
Former-commit-id: 5dfcfe50f9c82310303120031a0def594fafd4f7
This commit is contained in:
parent
53730b532d
commit
7ad24eff08
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) + ')');
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue