diff --git a/include/Nazara/Utility/KeyframeMesh.hpp b/include/Nazara/Utility/KeyframeMesh.hpp index 6c47a3421..0ece85e77 100644 --- a/include/Nazara/Utility/KeyframeMesh.hpp +++ b/include/Nazara/Utility/KeyframeMesh.hpp @@ -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(); diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 5832d848c..020e8fe65 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -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; diff --git a/src/Nazara/Utility/KeyframeMesh.cpp b/src/Nazara/Utility/KeyframeMesh.cpp index fbd08fcb6..cc165f083 100644 --- a/src/Nazara/Utility/KeyframeMesh.cpp +++ b/src/Nazara/Utility/KeyframeMesh.cpp @@ -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) + ')'); diff --git a/src/Nazara/Utility/Loaders/MD2/Loader.cpp b/src/Nazara/Utility/Loaders/MD2/Loader.cpp index fca60d4b0..0a7f7bac4 100644 --- a/src/Nazara/Utility/Loaders/MD2/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD2/Loader.cpp @@ -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 diff --git a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp index b8afa6fe2..a1dbdf1e3 100644 --- a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp +++ b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp @@ -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 animation(new NzAnimation); - if (animation->LoadFromFile(baseDir) && mesh->SetAnimation(animation.get())) - animation.release(); - else - NazaraWarning("Failed to load mesh's animation"); - } - } } } else diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index d62f83105..253f6fe9b 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -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(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(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;