diff --git a/include/Nazara/Utility/Animation.hpp b/include/Nazara/Utility/Animation.hpp index 21f461ac2..6fa964d35 100644 --- a/include/Nazara/Utility/Animation.hpp +++ b/include/Nazara/Utility/Animation.hpp @@ -44,6 +44,8 @@ class NAZARA_API NzAnimation : public NzResource bool CreateSkeletal(unsigned int frameCount, unsigned int jointCount); void Destroy(); + void EnableLoopPointInterpolation(bool loopPointInterpolation); + unsigned int GetFrameCount() const; unsigned int GetJointCount() const; NzSequence* GetSequence(const NzString& sequenceName); @@ -59,6 +61,7 @@ class NAZARA_API NzAnimation : public NzResource bool HasSequence(const NzString& sequenceName) const; bool HasSequence(unsigned int index = 0) const; + bool IsLoopPointInterpolationEnabled() const; bool IsValid() const; bool LoadFromFile(const NzString& filePath, const NzAnimationParams& params = NzAnimationParams()); diff --git a/src/Nazara/3D/Model.cpp b/src/Nazara/3D/Model.cpp index 0faa2dc88..6cb84fad6 100644 --- a/src/Nazara/3D/Model.cpp +++ b/src/Nazara/3D/Model.cpp @@ -424,8 +424,16 @@ void NzModel::Update(float elapsedTime) unsigned lastFrame = m_currentSequence->firstFrame + m_currentSequence->frameCount - 1; if (m_nextFrame+1 > lastFrame) { - m_currentFrame = m_currentSequence->firstFrame; - m_nextFrame = m_currentFrame+1; + if (m_animation->IsLoopPointInterpolationEnabled()) + { + m_currentFrame = m_nextFrame; + m_nextFrame = m_currentSequence->firstFrame; + } + else + { + m_currentFrame = m_currentSequence->firstFrame; + m_nextFrame = m_currentFrame+1; + } } else { diff --git a/src/Nazara/Utility/Animation.cpp b/src/Nazara/Utility/Animation.cpp index fb8643833..da7a5552a 100644 --- a/src/Nazara/Utility/Animation.cpp +++ b/src/Nazara/Utility/Animation.cpp @@ -16,6 +16,7 @@ struct NzAnimationImpl std::vector sequences; std::vector sequenceJoints; // Uniquement pour les animations squelettiques nzAnimationType type; + bool loopPointInterpolation = false; unsigned int frameCount; unsigned int jointCount; // Uniquement pour les animations squelettiques }; @@ -206,6 +207,19 @@ void NzAnimation::Destroy() } } +void NzAnimation::EnableLoopPointInterpolation(bool loopPointInterpolation) +{ + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return; + } + #endif + + m_impl->loopPointInterpolation = loopPointInterpolation; +} + unsigned int NzAnimation::GetFrameCount() const { #if NAZARA_UTILITY_SAFE @@ -435,6 +449,19 @@ bool NzAnimation::HasSequence(unsigned int index) const return index >= m_impl->sequences.size(); } +bool NzAnimation::IsLoopPointInterpolationEnabled() const +{ + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return false; + } + #endif + + return m_impl->loopPointInterpolation; +} + bool NzAnimation::IsValid() const { return m_impl != nullptr; diff --git a/src/Nazara/Utility/Loaders/MD2/Loader.cpp b/src/Nazara/Utility/Loaders/MD2/Loader.cpp index 792c26583..af5fa05d8 100644 --- a/src/Nazara/Utility/Loaders/MD2/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD2/Loader.cpp @@ -266,6 +266,9 @@ namespace return false; } + // Le MD2 requiert une interpolation de la dernière à la première frame (en cas de loop) + animation->EnableLoopPointInterpolation(true); + // Décodage des séquences ///TODO: Optimiser le calcul char last[16];