From eda4ef852d60d4b2952106bfe0c9485b9fbfeb34 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 02:55:49 +0100 Subject: [PATCH 01/23] Fixed Image::Get[Width|Height|Depth] returning 1 on invalid images Former-commit-id: 0822a90c3e4b29addcb74ab9a268fd88ff167f76 --- src/Nazara/Utility/Image.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 5fb12ff6f..407a376b3 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -11,12 +11,16 @@ #include ///TODO: Rajouter des warnings (Formats compressés avec les méthodes Copy/Update, tests taille dans Copy) -///TODO: Rendre les méthodes exception-safe +///TODO: Rendre les méthodes exception-safe (Virer toute cette merde de calcul de pointeurs, faire usage du RAII) +///FIXME: Gérer correctement les formats utilisant moins d'un octet par pixel namespace { inline unsigned int GetLevelSize(unsigned int size, nzUInt8 level) { + if (size == 0) // Possible dans le cas d'une image invalide + return 0; + return std::max(size >> level, 1U); } @@ -28,7 +32,7 @@ namespace bool NzImageParams::IsValid() const { - return true; + return true; // Rien à vérifier } NzImage::NzImage() : @@ -195,7 +199,7 @@ void NzImage::Copy(const NzImage& source, const NzBoxui& srcBox, const NzVector3 bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount) { - ReleaseImage(); + Destroy(); #if NAZARA_UTILITY_SAFE if (!NzPixelFormat::IsValid(format)) From e14789830ceaf245df3681096db4a3dc46f21fcc Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 02:56:05 +0100 Subject: [PATCH 02/23] Removed useless line Former-commit-id: 3499a0aa828a9886f55ad7c5da55e52ef930eb49 --- src/Nazara/Renderer/RenderWindow.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Nazara/Renderer/RenderWindow.cpp b/src/Nazara/Renderer/RenderWindow.cpp index 44e0fdf89..9580ccc56 100644 --- a/src/Nazara/Renderer/RenderWindow.cpp +++ b/src/Nazara/Renderer/RenderWindow.cpp @@ -320,4 +320,3 @@ void NzRenderWindow::OnWindowResized() { NotifySizeChange(); } - From df6fdf67847210ac40710ab9b851ccf70a9b6dd9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 02:57:30 +0100 Subject: [PATCH 03/23] Added a Size parameter to View class Allowing independent from rendertarget size Former-commit-id: c131b6dd95692c72a969bf0cc6edd997911bbe58 --- include/Nazara/Graphics/View.hpp | 4 ++++ src/Nazara/Graphics/View.cpp | 19 ++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Graphics/View.hpp b/include/Nazara/Graphics/View.hpp index 899c34de6..bc048aeb6 100644 --- a/include/Nazara/Graphics/View.hpp +++ b/include/Nazara/Graphics/View.hpp @@ -20,6 +20,7 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget { public: NzView(); + NzView(const NzVector2f& size); ~NzView(); void EnsureFrustumUpdate() const; @@ -32,6 +33,7 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget NzVector3f GetForward() const; const NzFrustumf& GetFrustum() const; const NzMatrix4f& GetProjectionMatrix() const; + const NzVector2f& GetSize() const; const NzRenderTarget* GetTarget() const; const NzRectf& GetTargetRegion() const; const NzMatrix4f& GetViewMatrix() const; @@ -39,6 +41,7 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget float GetZFar() const; float GetZNear() const; + void SetSize(const NzVector2f& size); void SetTarget(const NzRenderTarget* renderTarget); void SetTarget(const NzRenderTarget& renderTarget); void SetTargetRegion(const NzRectf& region); @@ -63,6 +66,7 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget mutable NzMatrix4f m_viewMatrix; NzRectf m_targetRegion; mutable NzRecti m_viewport; + NzVector2f m_size; const NzRenderTarget* m_target; mutable bool m_frustumUpdated; mutable bool m_projectionMatrixUpdated; diff --git a/src/Nazara/Graphics/View.cpp b/src/Nazara/Graphics/View.cpp index 3caa0b48f..44d00294c 100644 --- a/src/Nazara/Graphics/View.cpp +++ b/src/Nazara/Graphics/View.cpp @@ -10,6 +10,7 @@ NzView::NzView() : m_targetRegion(0.f, 0.f, 1.f, 1.f), +m_size(0.f), m_target(nullptr), m_frustumUpdated(false), m_projectionMatrixUpdated(false), @@ -20,6 +21,12 @@ m_zNear(-1.f) { } +NzView::NzView(const NzVector2f& size) : +NzView() // On délègue +{ + m_size = size; +} + NzView::~NzView() { if (m_target) @@ -256,10 +263,16 @@ void NzView::UpdateFrustum() const void NzView::UpdateProjectionMatrix() const { - if (!m_viewportUpdated) - UpdateViewport(); + if (m_size.x <= 0.f || m_size.y <= 0.f) // Si la taille est nulle, on prendra la taille du viewport + { + if (!m_viewportUpdated) + UpdateViewport(); + + m_projectionMatrix.MakeOrtho(0.f, m_viewport.width, 0.f, m_viewport.height, m_zNear, m_zFar); + } + else + m_projectionMatrix.MakeOrtho(0.f, m_size.x, 0.f, m_size.y, m_zNear, m_zFar); - m_projectionMatrix.MakeOrtho(m_viewport.x, m_viewport.x + m_viewport.width, m_viewport.y, m_viewport.y + m_viewport.height, m_zNear, m_zFar); m_projectionMatrixUpdated = true; } From 90e6bf4493b372556e68cedc84c11c95474fae79 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 02:58:01 +0100 Subject: [PATCH 04/23] Made Music class non copyable Former-commit-id: ccbd014514b3c9f59c3fee940cc307afb890f634 --- include/Nazara/Audio/Music.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Audio/Music.hpp b/include/Nazara/Audio/Music.hpp index bff875cb5..716d68cc0 100644 --- a/include/Nazara/Audio/Music.hpp +++ b/include/Nazara/Audio/Music.hpp @@ -26,7 +26,7 @@ using NzMusicLoader = NzResourceLoader; struct NzMusicImpl; -class NAZARA_API NzMusic : public NzSoundEmitter +class NAZARA_API NzMusic : public NzSoundEmitter, NzNonCopyable { friend NzMusicLoader; From c24e0ef8fac2d036b18fd02fadca7dbe7c11cd8f Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 02:58:52 +0100 Subject: [PATCH 05/23] Improved Music.cpp (Added comments) Former-commit-id: 0a4aabbafd3d76d280ac98332fa2059b1ad73b39 --- src/Nazara/Audio/Music.cpp | 41 +++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index f6704bf4d..aad189270 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -116,6 +116,7 @@ nzUInt32 NzMusic::GetPlayingOffset() const } #endif + ///TODO return 0; } @@ -131,6 +132,7 @@ nzSoundStatus NzMusic::GetStatus() const nzSoundStatus status = GetInternalStatus(); + // Pour compenser les éventuels retards (ou le laps de temps entre Play() et la mise en route du thread) if (m_impl->streaming && status == nzSoundStatus_Stopped) status = nzSoundStatus_Playing; @@ -180,14 +182,17 @@ void NzMusic::Play() } #endif + // Nous sommes déjà en train de jouer if (m_impl->streaming) { + // Peut-être sommes-nous en pause if (GetStatus() != nzSoundStatus_Playing) alSourcePlay(m_source); return; } + // Lancement du thread de streaming m_impl->stream->Seek(0); m_impl->streaming = true; m_impl->thread = NzThread(&NzMusic::MusicThread, this); @@ -195,6 +200,19 @@ void NzMusic::Play() return; } +void NzMusic::SetPlayingOffset(nzUInt32 offset) +{ + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return; + } + #endif + + ///TODO +} + void NzMusic::Stop() { #if NAZARA_AUDIO_SAFE @@ -217,39 +235,44 @@ bool NzMusic::FillAndQueueBuffer(unsigned int buffer) unsigned int sampleCount = m_impl->chunkSamples.size(); unsigned int sampleRead = 0; + // Lecture depuis le stream pour remplir le buffer for (;;) { sampleRead += m_impl->stream->Read(&m_impl->chunkSamples[sampleRead], sampleCount - sampleRead); - if (sampleRead < sampleCount && m_impl->loop) - m_impl->stream->Seek(0); - else - break; + if (sampleRead < sampleCount && !m_impl->loop) + break; // Fin du stream (On ne boucle pas) + + m_impl->stream->Seek(0); // On boucle au début du stream et on remplit à nouveau } + // Mise à jour du buffer (envoi à OpenAL) et placement dans la file d'attente if (sampleRead > 0) { alBufferData(buffer, m_impl->audioFormat, &m_impl->chunkSamples[0], sampleRead*sizeof(nzInt16), m_impl->sampleRate); alSourceQueueBuffers(m_source, 1, &buffer); } - return sampleRead != sampleCount; // Fin du fichier (N'arrive pas en cas de loop) + return sampleRead != sampleCount; // Fin du stream (N'arrive pas en cas de loop) } void NzMusic::MusicThread() { + // Allocation des buffers de streaming ALuint buffers[NAZARA_AUDIO_STREAMED_BUFFER_COUNT]; alGenBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers); for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMED_BUFFER_COUNT; ++i) { - if (FillAndQueueBuffer(buffers[i])) // Fin du fichier ? - break; // Nous avons atteint la fin du fichier, inutile de rajouter des buffers + if (FillAndQueueBuffer(buffers[i])) + break; // Nous avons atteint la fin du stream, inutile de rajouter des buffers } alSourcePlay(m_source); + // Boucle de lecture (remplissage de nouveaux buffers au fur et à mesure) while (m_impl->streaming) { + // La lecture s'est arrêtée, nous avons atteint la fin du stream nzSoundStatus status = GetInternalStatus(); if (status == nzSoundStatus_Stopped) { @@ -257,6 +280,7 @@ void NzMusic::MusicThread() break; } + // On traite les buffers lus ALint processedCount = 0; alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processedCount); @@ -268,11 +292,14 @@ void NzMusic::MusicThread() break; } + // On retourne dormir un peu NzThread::Sleep(50); } + // Arrêt de la lecture du son (dans le cas où ça ne serait pas déjà fait) alSourceStop(m_source); + // On supprime les buffers du stream ALint queuedBufferCount; alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queuedBufferCount); From bb95e6862a35e85ca7514cf941854732f99dbc40 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 02:59:56 +0100 Subject: [PATCH 06/23] Fixed sprites being rendered upside-down in 2D This is still waiting for a fix because it will be upside-down in 3D Former-commit-id: ca4bef616f3496db22349eb907ec32a0b6c3deb8 --- src/Nazara/Graphics/ForwardRenderTechnique.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 68726c809..896e7c70a 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -421,19 +421,19 @@ void NzForwardRenderTechnique::DrawSprites(const NzScene* scene) const NzVector3f center = sprite->GetPosition(); NzQuaternionf rotation = sprite->GetRotation(); - vertices->position = center + rotation * NzVector3f(-halfSize.x, -halfSize.y, 0.f); + vertices->position = center + rotation * NzVector3f(-halfSize.x, halfSize.y, 0.f); vertices->uv.Set(textureCoords.x, textureCoords.y + textureCoords.height); vertices++; - vertices->position = center + rotation * NzVector3f(halfSize.x, -halfSize.y, 0.f); + vertices->position = center + rotation * NzVector3f(halfSize.x, halfSize.y, 0.f); vertices->uv.Set(textureCoords.width, textureCoords.y + textureCoords.height); vertices++; - vertices->position = center + rotation * NzVector3f(-halfSize.x, halfSize.y, 0.f); + vertices->position = center + rotation * NzVector3f(-halfSize.x, -halfSize.y, 0.f); vertices->uv.Set(textureCoords.x, textureCoords.y); vertices++; - vertices->position = center + rotation * NzVector3f(halfSize.x, halfSize.y, 0.f); + vertices->position = center + rotation * NzVector3f(halfSize.x, -halfSize.y, 0.f); vertices->uv.Set(textureCoords.width, textureCoords.y); vertices++; } From 27e9996e7bea21d2723efbd9b25850e9650ffc3b Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:00:10 +0100 Subject: [PATCH 07/23] Improved error message Former-commit-id: 0315fe27119a0da88334ee67575e144c488d655c --- src/Nazara/Graphics/DeferredGeometryPass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index e1a008493..577afe5a0 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -228,7 +228,7 @@ bool NzDeferredGeometryPass::Resize(const NzVector2ui& dimensions) } catch (const std::exception& e) { - NazaraError("Failed to create G-Buffer RTT"); + NazaraError("Failed to create G-Buffer RTT: " + NzString(e.what())); return false; } } From 605bcc703851f25a93e4ba784ec70c13f259707e Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:00:19 +0100 Subject: [PATCH 08/23] Fixed possible warning Former-commit-id: fac12a042d206976109ffde42865c561b021ed93 --- src/Nazara/Graphics/DeferredBloomPass.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nazara/Graphics/DeferredBloomPass.cpp b/src/Nazara/Graphics/DeferredBloomPass.cpp index 9b66184dd..754a4b88c 100644 --- a/src/Nazara/Graphics/DeferredBloomPass.cpp +++ b/src/Nazara/Graphics/DeferredBloomPass.cpp @@ -10,9 +10,9 @@ NzDeferredBloomPass::NzDeferredBloomPass() : m_uniformUpdated(false), -m_brightLuminance(0.8), -m_brightMiddleGrey(0.5), -m_brightThreshold(0.8), +m_brightLuminance(0.8f), +m_brightMiddleGrey(0.5f), +m_brightThreshold(0.8f), m_blurPassCount(5) { m_bilinearSampler.SetAnisotropyLevel(1); From aa37c632cbea26bbd94007a520867a5c154d8d99 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:00:35 +0100 Subject: [PATCH 09/23] Fixed possible warning Former-commit-id: 4d14bf2cee4756db0720fda0d904d5bc7b2bafd9 --- src/Nazara/Graphics/Material.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 123db7ffc..3c9861acc 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -690,8 +690,8 @@ void NzMaterial::GenerateShader(nzUInt32 flags) const m_normalMap.IsValid() || m_heightMap.IsValid() || m_specularMap.IsValid()); list.SetParameter("TRANSFORM", m_transformEnabled); - list.SetParameter("FLAG_DEFERRED", static_cast(flags & nzShaderFlags_Deferred)); - list.SetParameter("FLAG_INSTANCING", static_cast(flags & nzShaderFlags_Instancing)); + list.SetParameter("FLAG_DEFERRED", static_cast((flags & nzShaderFlags_Deferred) != 0)); + list.SetParameter("FLAG_INSTANCING", static_cast((flags & nzShaderFlags_Instancing) != 0)); ShaderInstance& instance = m_shaders[flags]; instance.uberInstance = m_uberShader->Get(list); From 3db73921c2d082ee301827cc884c147f53cc71f7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:03:35 +0100 Subject: [PATCH 10/23] Made 2D nodes easier to use Former-commit-id: 80c0340b93c203bd874568c9d4fb5e2fc88a5860 --- include/Nazara/Utility/Node.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/Nazara/Utility/Node.hpp b/include/Nazara/Utility/Node.hpp index 290f3a933..4536739a7 100644 --- a/include/Nazara/Utility/Node.hpp +++ b/include/Nazara/Utility/Node.hpp @@ -50,13 +50,13 @@ class NAZARA_API NzNode NzNode& Interpolate(const NzNode& nodeA, const NzNode& nodeB, float interpolation, nzCoordSys coordSys = nzCoordSys_Global); NzNode& Move(const NzVector3f& movement, nzCoordSys coordSys = nzCoordSys_Local); - NzNode& Move(float movementX, float movementY, float movementZ, nzCoordSys coordSys = nzCoordSys_Local); + NzNode& Move(float movementX, float movementY, float movementZ = 0.f, nzCoordSys coordSys = nzCoordSys_Local); NzNode& Rotate(const NzQuaternionf& rotation, nzCoordSys coordSys = nzCoordSys_Local); NzNode& Scale(const NzVector3f& scale); NzNode& Scale(float scale); - NzNode& Scale(float scaleX, float scaleY, float scaleZ); + NzNode& Scale(float scaleX, float scaleY, float scaleZ = 1.f); void SetInheritRotation(bool inheritRotation); void SetInheritScale(bool inheritScale); @@ -64,18 +64,18 @@ class NAZARA_API NzNode void SetInitialRotation(const NzQuaternionf& quat); void SetInitialScale(const NzVector3f& scale); void SetInitialScale(float scale); - void SetInitialScale(float scaleX, float scaleY, float scaleZ); + void SetInitialScale(float scaleX, float scaleY, float scaleZ = 1.f); void SetInitialPosition(const NzVector3f& translation); - void SetInitialPosition(float translationX, float translationXY, float translationZ); + void SetInitialPosition(float translationX, float translationXY, float translationZ = 0.f); void SetName(const NzString& name); void SetParent(const NzNode* node = nullptr, bool keepDerived = false); void SetParent(const NzNode& node, bool keepDerived = false); void SetPosition(const NzVector3f& translation, nzCoordSys coordSys = nzCoordSys_Local); - void SetPosition(float translationX, float translationXY, float translationZ, nzCoordSys coordSys = nzCoordSys_Local); + void SetPosition(float translationX, float translationY, float translationZ = 0.f, nzCoordSys coordSys = nzCoordSys_Local); void SetRotation(const NzQuaternionf& quat, nzCoordSys coordSys = nzCoordSys_Local); void SetScale(const NzVector3f& scale, nzCoordSys coordSys = nzCoordSys_Local); void SetScale(float scale, nzCoordSys coordSys = nzCoordSys_Local); - void SetScale(float scaleX, float scaleY, float scaleZ, nzCoordSys coordSys = nzCoordSys_Local); + void SetScale(float scaleX, float scaleY, float scaleZ = 1.f, nzCoordSys coordSys = nzCoordSys_Local); void SetTransformMatrix(const NzMatrix4f& matrix); // Local -> global From b56e40f35a23b364312f9785781014f86a5e102f Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:03:45 +0100 Subject: [PATCH 11/23] Added comment Former-commit-id: 045a48cb1b0e798de31cd2aff0708324648da409 --- include/Nazara/Utility/Algorithm.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Nazara/Utility/Algorithm.hpp b/include/Nazara/Utility/Algorithm.hpp index 59812fca4..37d4a5705 100644 --- a/include/Nazara/Utility/Algorithm.hpp +++ b/include/Nazara/Utility/Algorithm.hpp @@ -32,6 +32,7 @@ NAZARA_API void NzComputePlaneIndexVertexCount(const NzVector2ui& subdivision, u NAZARA_API void NzComputeUvSphereIndexVertexCount(unsigned int sliceCount, unsigned int stackCount, unsigned int* indexCount, unsigned int* vertexCount); template NzBoxf NzComputeVerticesAABB(const T* vertices, unsigned int vertexCount); +///TODO: Remplacer le pointeur vertices par une structure composée de plusieurs SparsePtr NAZARA_API void NzGenerateBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); NAZARA_API void NzGenerateCone(float length, float radius, unsigned int subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); NAZARA_API void NzGenerateCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); From 5ae54677f1a3bd6690f157fd163b2e6038e76d70 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:04:04 +0100 Subject: [PATCH 12/23] Fixed Matrix4::IsIdentity() Former-commit-id: 7f3dfb47241ec2625e7ba02decb53ad5fd3d60ac --- include/Nazara/Math/Matrix4.inl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index a3fe4b53a..89363a31e 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -562,9 +562,9 @@ template bool NzMatrix4::IsIdentity() const { return (NzNumberEquals(m11, F(1.0)) && NzNumberEquals(m12, F(0.0)) && NzNumberEquals(m13, F(0.0)) && NzNumberEquals(m14, F(0.0)) && - NzNumberEquals(m11, F(0.0)) && NzNumberEquals(m12, F(1.0)) && NzNumberEquals(m13, F(0.0)) && NzNumberEquals(m14, F(0.0)) && - NzNumberEquals(m11, F(0.0)) && NzNumberEquals(m12, F(0.0)) && NzNumberEquals(m13, F(1.0)) && NzNumberEquals(m14, F(0.0)) && - NzNumberEquals(m11, F(0.0)) && NzNumberEquals(m12, F(0.0)) && NzNumberEquals(m13, F(0.0)) && NzNumberEquals(m14, F(1.0))); + NzNumberEquals(m21, F(0.0)) && NzNumberEquals(m22, F(1.0)) && NzNumberEquals(m23, F(0.0)) && NzNumberEquals(m24, F(0.0)) && + NzNumberEquals(m31, F(0.0)) && NzNumberEquals(m32, F(0.0)) && NzNumberEquals(m33, F(1.0)) && NzNumberEquals(m34, F(0.0)) && + NzNumberEquals(m41, F(0.0)) && NzNumberEquals(m42, F(0.0)) && NzNumberEquals(m43, F(0.0)) && NzNumberEquals(m44, F(1.0))); } template From 42b28e732c894ded6711176d9bb29ae45bf53a3e Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:04:24 +0100 Subject: [PATCH 13/23] Removed whitespace Former-commit-id: e7bfe92a625f6102abc4fe3b11b498c43b371ee9 --- include/Nazara/Renderer/RenderTarget.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Renderer/RenderTarget.hpp b/include/Nazara/Renderer/RenderTarget.hpp index c62d1c5b6..eaec9f2ce 100644 --- a/include/Nazara/Renderer/RenderTarget.hpp +++ b/include/Nazara/Renderer/RenderTarget.hpp @@ -61,7 +61,7 @@ class NAZARA_API NzRenderTarget private: mutable std::unordered_map m_listeners; - bool m_listenersLocked; + bool m_listenersLocked; }; #endif // NAZARA_RENDERTARGET_HPP From a51cbc1e4993cd19b9ca12d9ca76e6ebf08ffeb5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:05:27 +0100 Subject: [PATCH 14/23] Added Sprite::SetSize(float, float) overload Former-commit-id: 672a2e4f5c2a2d40b4af42c7ee4b7b37d3774117 --- include/Nazara/Graphics/Sprite.hpp | 1 + src/Nazara/Graphics/Sprite.cpp | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index 54ebb71a1..b383f1e44 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -32,6 +32,7 @@ class NAZARA_API NzSprite : public NzSceneNode void SetMaterial(NzMaterial* material, bool resizeSprite = true); void SetSize(const NzVector2f& size); + void SetSize(float sizeX, float sizeY); void SetTexture(NzTexture* texture, bool resizeSprite = true); void SetTextureCoords(const NzRectf& coords); void SetTextureRect(const NzRectui& rect); diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index 7d14a1a8e..df181ac5d 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -109,10 +109,17 @@ void NzSprite::SetMaterial(NzMaterial* material, bool resizeSprite) void NzSprite::SetSize(const NzVector2f& size) { m_size = size; + + // On invalide la bounding box m_boundingVolume.MakeNull(); m_boundingVolumeUpdated = false; } +void NzSprite::SetSize(float sizeX, float sizeY) +{ + SetSize(NzVector2f(sizeX, sizeY)); +} + void NzSprite::SetTexture(NzTexture* texture, bool resizeSprite) { std::unique_ptr material(new NzMaterial); From 15ddc29179242c6ad6f3e2cc1615cfe27083a0c0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:06:12 +0100 Subject: [PATCH 15/23] Added implicit conversion to SparsePtr Former-commit-id: 5116a5e7687706640cd5d2ef99f5c181e00ee841 --- include/Nazara/Core/SparsePtr.hpp | 2 ++ include/Nazara/Core/SparsePtr.inl | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/include/Nazara/Core/SparsePtr.hpp b/include/Nazara/Core/SparsePtr.hpp index aff3460ac..94c3f249f 100644 --- a/include/Nazara/Core/SparsePtr.hpp +++ b/include/Nazara/Core/SparsePtr.hpp @@ -22,6 +22,7 @@ class NzSparsePtr NzSparsePtr(); NzSparsePtr(T* ptr); NzSparsePtr(VoidPtr ptr, unsigned int stride); + template NzSparsePtr(const NzSparsePtr& ptr); NzSparsePtr(const NzSparsePtr& ptr) = default; ~NzSparsePtr() = default; @@ -32,6 +33,7 @@ class NzSparsePtr void Reset(T* ptr); void Reset(VoidPtr ptr, unsigned int stride); void Reset(const NzSparsePtr& ptr); + template void Reset(const NzSparsePtr& ptr); void SetPtr(VoidPtr ptr); void SetStride(unsigned int stride); diff --git a/include/Nazara/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index b98599bfd..ca0d7e328 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -22,6 +22,13 @@ NzSparsePtr::NzSparsePtr(VoidPtr ptr, unsigned int stride) Reset(ptr, stride); } +template +template +NzSparsePtr::NzSparsePtr(const NzSparsePtr& ptr) +{ + Reset(ptr); +} + template typename NzSparsePtr::VoidPtr NzSparsePtr::GetPtr() const { @@ -62,6 +69,16 @@ void NzSparsePtr::Reset(const NzSparsePtr& ptr) SetStride(ptr.GetStride()); } +template +template +void NzSparsePtr::Reset(const NzSparsePtr& ptr) +{ + static_assert(std::is_convertible::value, "Source type pointer cannot be implicitely converted to target type pointer"); + + SetPtr(static_cast(ptr.GetPtr())); + SetStride(ptr.GetStride()); +} + template void NzSparsePtr::SetPtr(VoidPtr ptr) { @@ -120,6 +137,7 @@ template NzSparsePtr& NzSparsePtr::operator+=(unsigned int count) { m_ptr += count*m_stride; + return *this; } @@ -127,6 +145,7 @@ template NzSparsePtr& NzSparsePtr::operator-=(unsigned int count) { m_ptr -= count*m_stride; + return *this; } @@ -134,6 +153,7 @@ template NzSparsePtr& NzSparsePtr::operator++() { m_ptr += m_stride; + return *this; } From 20607238df36ab5f63fd9467aec7e64c8b8f1d3c Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 11 Dec 2014 18:56:55 +0100 Subject: [PATCH 16/23] SparsePtr: Allowed negative stride Former-commit-id: 9ca3101347bdc071503ec9edb75b4f896a6dd2e0 --- include/Nazara/Core/SparsePtr.hpp | 20 ++++++++++---------- include/Nazara/Core/SparsePtr.inl | 18 +++++++++--------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/Nazara/Core/SparsePtr.hpp b/include/Nazara/Core/SparsePtr.hpp index 94c3f249f..74a64425d 100644 --- a/include/Nazara/Core/SparsePtr.hpp +++ b/include/Nazara/Core/SparsePtr.hpp @@ -21,34 +21,34 @@ class NzSparsePtr NzSparsePtr(); NzSparsePtr(T* ptr); - NzSparsePtr(VoidPtr ptr, unsigned int stride); + NzSparsePtr(VoidPtr ptr, int stride); template NzSparsePtr(const NzSparsePtr& ptr); NzSparsePtr(const NzSparsePtr& ptr) = default; ~NzSparsePtr() = default; VoidPtr GetPtr() const; - unsigned int GetStride() const; + int GetStride() const; void Reset(); void Reset(T* ptr); - void Reset(VoidPtr ptr, unsigned int stride); + void Reset(VoidPtr ptr, int stride); void Reset(const NzSparsePtr& ptr); template void Reset(const NzSparsePtr& ptr); void SetPtr(VoidPtr ptr); - void SetStride(unsigned int stride); + void SetStride(int stride); operator bool() const; operator T*() const; T& operator*() const; T& operator->() const; - T& operator[](unsigned int index) const; + T& operator[](int index) const; - NzSparsePtr operator+(unsigned int count) const; - NzSparsePtr operator-(unsigned int count) const; + NzSparsePtr operator+(int count) const; + NzSparsePtr operator-(int count) const; - NzSparsePtr& operator+=(unsigned int count); - NzSparsePtr& operator-=(unsigned int count); + NzSparsePtr& operator+=(int count); + NzSparsePtr& operator-=(int count); NzSparsePtr& operator++(); NzSparsePtr operator++(int); @@ -67,7 +67,7 @@ class NzSparsePtr private: BytePtr m_ptr; - unsigned int m_stride; + int m_stride; }; #include diff --git a/include/Nazara/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index ca0d7e328..661c9292a 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -17,7 +17,7 @@ NzSparsePtr::NzSparsePtr(T* ptr) } template -NzSparsePtr::NzSparsePtr(VoidPtr ptr, unsigned int stride) +NzSparsePtr::NzSparsePtr(VoidPtr ptr, int stride) { Reset(ptr, stride); } @@ -36,7 +36,7 @@ typename NzSparsePtr::VoidPtr NzSparsePtr::GetPtr() const } template -unsigned int NzSparsePtr::GetStride() const +int NzSparsePtr::GetStride() const { return m_stride; } @@ -56,7 +56,7 @@ void NzSparsePtr::Reset(T* ptr) } template -void NzSparsePtr::Reset(VoidPtr ptr, unsigned int stride) +void NzSparsePtr::Reset(VoidPtr ptr, int stride) { SetPtr(ptr); SetStride(stride); @@ -86,7 +86,7 @@ void NzSparsePtr::SetPtr(VoidPtr ptr) } template -void NzSparsePtr::SetStride(unsigned int stride) +void NzSparsePtr::SetStride(int stride) { m_stride = stride; } @@ -116,25 +116,25 @@ T& NzSparsePtr::operator->() const } template -T& NzSparsePtr::operator[](unsigned int index) const +T& NzSparsePtr::operator[](int index) const { return *reinterpret_cast(m_ptr + index*m_stride); } template -NzSparsePtr NzSparsePtr::operator+(unsigned int count) const +NzSparsePtr NzSparsePtr::operator+(int count) const { return NzSparsePtr(m_ptr + count*m_stride, m_stride); } template -NzSparsePtr NzSparsePtr::operator-(unsigned int count) const +NzSparsePtr NzSparsePtr::operator-(int count) const { return NzSparsePtr(m_ptr - count*m_stride, m_stride); } template -NzSparsePtr& NzSparsePtr::operator+=(unsigned int count) +NzSparsePtr& NzSparsePtr::operator+=(int count) { m_ptr += count*m_stride; @@ -142,7 +142,7 @@ NzSparsePtr& NzSparsePtr::operator+=(unsigned int count) } template -NzSparsePtr& NzSparsePtr::operator-=(unsigned int count) +NzSparsePtr& NzSparsePtr::operator-=(int count) { m_ptr -= count*m_stride; From 02643f944274a9acfeee18492f062f8f9cb8aa16 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Dec 2014 13:52:40 +0100 Subject: [PATCH 17/23] Improved Win32 code Former-commit-id: cfaecc7d8df56fa4cb2a27570531ffbce3fdfe87 --- src/Nazara/Utility/Win32/InputImpl.cpp | 4 ++-- src/Nazara/Utility/Win32/WindowImpl.cpp | 4 ++-- src/Nazara/Utility/Win32/WindowImpl.hpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Nazara/Utility/Win32/InputImpl.cpp b/src/Nazara/Utility/Win32/InputImpl.cpp index bafaf0f24..62337423d 100644 --- a/src/Nazara/Utility/Win32/InputImpl.cpp +++ b/src/Nazara/Utility/Win32/InputImpl.cpp @@ -222,7 +222,7 @@ NzVector2i NzEventImpl::GetMousePosition(const NzWindow& relativeTo) } else { - NazaraError("Window's handle is invalid"); + NazaraError("Invalid window handle"); // Attention que (-1, -1) est une position tout à fait valide et ne doit pas servir de test return NzVector2i(-1, -1); @@ -289,5 +289,5 @@ void NzEventImpl::SetMousePosition(int x, int y, const NzWindow& relativeTo) SetCursorPos(pos.x, pos.y); } else - NazaraError("Window's handle is invalid"); + NazaraError("Invalid window handle"); } diff --git a/src/Nazara/Utility/Win32/WindowImpl.cpp b/src/Nazara/Utility/Win32/WindowImpl.cpp index 64a1fae74..1da1b9251 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.cpp +++ b/src/Nazara/Utility/Win32/WindowImpl.cpp @@ -79,7 +79,7 @@ m_scrolling(0) { } -bool NzWindowImpl::Create(NzVideoMode mode, const NzString& title, nzUInt32 style) +bool NzWindowImpl::Create(const NzVideoMode& mode, const NzString& title, nzUInt32 style) { bool fullscreen = (style & nzWindowStyle_Fullscreen) != 0; DWORD win32Style, win32StyleEx; @@ -183,7 +183,7 @@ bool NzWindowImpl::Create(NzVideoMode mode, const NzString& title, nzUInt32 styl GetWindowRect(m_handle, &windowRect); m_position.Set(windowRect.left, windowRect.top); - m_size.Set(clientRect.right-clientRect.left, clientRect.bottom-clientRect.top); + m_size.Set(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top); return true; } diff --git a/src/Nazara/Utility/Win32/WindowImpl.hpp b/src/Nazara/Utility/Win32/WindowImpl.hpp index ebd91f9ee..1a726391d 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.hpp +++ b/src/Nazara/Utility/Win32/WindowImpl.hpp @@ -34,7 +34,7 @@ class NzWindowImpl : NzNonCopyable NzWindowImpl(NzWindow* parent); ~NzWindowImpl() = default; - bool Create(NzVideoMode mode, const NzString& title, nzUInt32 style); + bool Create(const NzVideoMode& mode, const NzString& title, nzUInt32 style); bool Create(NzWindowHandle handle); void Destroy(); From 1ee02d4fcf0969c7ed3b35dbca16dd81b0425963 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Dec 2014 13:53:59 +0100 Subject: [PATCH 18/23] Improved code, fixed missing includes Thanks to d@rk-marouane (@progdupeu.pl) Former-commit-id: 4147388501d4263e624f4c6402902ef071f88ffd --- include/Nazara/Core/Color.inl | 7 ++++--- src/Nazara/Utility/VideoMode.cpp | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Core/Color.inl b/include/Nazara/Core/Color.inl index 3357f5c20..662c86911 100644 --- a/include/Nazara/Core/Color.inl +++ b/include/Nazara/Core/Color.inl @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include @@ -235,7 +236,7 @@ inline void NzColor::ToCMYK(const NzColor& color, float* cyan, float* magenta, f float c, m, y; ToCMY(color, &c, &m, &y); - float k = std::min(std::min(std::min(1.f, c), m), y); + float k = std::min({1.f, c, m, y}); if (NzNumberEquals(k, 1.f)) { @@ -260,8 +261,8 @@ inline void NzColor::ToHSL(const NzColor& color, nzUInt8* hue, nzUInt8* saturati float g = color.g / 255.f; float b = color.b / 255.f; - float min = std::min(std::min(r, g), b); // Min. value of RGB - float max = std::max(std::max(r, g), b); // Max. value of RGB + float min = std::min({r, g, b}); // Min. value of RGB + float max = std::max({r, g, b}); // Max. value of RGB float deltaMax = max - min; //Delta RGB value diff --git a/src/Nazara/Utility/VideoMode.cpp b/src/Nazara/Utility/VideoMode.cpp index ce28eeed3..c3d2b81c1 100644 --- a/src/Nazara/Utility/VideoMode.cpp +++ b/src/Nazara/Utility/VideoMode.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include NzVideoMode::NzVideoMode() : From ba8aed916f90e77321a956599c176b1b1794a1d1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Dec 2014 13:54:44 +0100 Subject: [PATCH 20/23] Renamed unicode option to parseunicode Former-commit-id: 600c6fd480d9e96c90319b367545dd5199a10664 --- build/scripts/actions/unicode.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/scripts/actions/unicode.lua b/build/scripts/actions/unicode.lua index 4db23db8a..8105cb3a0 100644 --- a/build/scripts/actions/unicode.lua +++ b/build/scripts/actions/unicode.lua @@ -191,7 +191,7 @@ end newaction { - trigger = "unicode", + trigger = "parseunicode", description = "Parse the Unicode Character Data and put the useful informations into a header", execute = parseUnicodeData } From 58fbed1dbd36aa694cc8ef8c9e55c7905cd07f9e Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Dec 2014 13:56:01 +0100 Subject: [PATCH 22/23] Improved error message Former-commit-id: ca50bb0afe38364cb4f3bfe71b057fa8721337bd --- src/Nazara/Renderer/Renderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index c219f9c62..0552d8e38 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -1856,7 +1856,7 @@ bool NzRenderer::EnsureStateUpdate() default: { - NazaraInternalError("Unsupported component type"); + NazaraInternalError("Unsupported component type (0x" + NzString::Number(type, 16) + ')'); break; } } From e55c521e9677edc79d09f03394568d2d3e15a7ae Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Dec 2014 13:56:33 +0100 Subject: [PATCH 23/23] Added support for skeletal models (WIP) Former-commit-id: 6a6c2d9f2c68267df79dc48fa56450d2a563e323 --- include/Nazara/Graphics/SkeletalModel.hpp | 88 +++++ src/Nazara/Graphics/Loaders/Mesh/Loader.cpp | 63 ++++ src/Nazara/Graphics/SkeletalModel.cpp | 357 ++++++++++++++++++++ 3 files changed, 508 insertions(+) create mode 100644 include/Nazara/Graphics/SkeletalModel.hpp create mode 100644 src/Nazara/Graphics/SkeletalModel.cpp diff --git a/include/Nazara/Graphics/SkeletalModel.hpp b/include/Nazara/Graphics/SkeletalModel.hpp new file mode 100644 index 000000000..7938ba4c4 --- /dev/null +++ b/include/Nazara/Graphics/SkeletalModel.hpp @@ -0,0 +1,88 @@ +// Copyright (C) 2014 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_SKELETALMODEL_HPP +#define NAZARA_SKELETALMODEL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +struct NAZARA_API NzSkeletalModelParameters : public NzModelParameters +{ + bool loadAnimation = true; + NzAnimationParams animation; + + bool IsValid() const; +}; + +class NzSkeletalModel; + +using NzSkeletalModelLoader = NzResourceLoader; + +class NAZARA_API NzSkeletalModel : public NzModel, NzUpdatable +{ + friend NzSkeletalModelLoader; + //friend class NzScene; + + public: + NzSkeletalModel(); + NzSkeletalModel(const NzSkeletalModel& model); + NzSkeletalModel(NzSkeletalModel&& model); + ~NzSkeletalModel(); + + void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; + void AdvanceAnimation(float elapsedTime); + + void EnableAnimation(bool animation); + + NzAnimation* GetAnimation() const; + NzSkeleton* GetSkeleton(); + const NzSkeleton* GetSkeleton() const; + + bool HasAnimation() const; + + bool IsAnimated() const; + bool IsAnimationEnabled() const; + bool IsDrawable() const; + + bool LoadFromFile(const NzString& filePath, const NzSkeletalModelParameters& params = NzSkeletalModelParameters()); + bool LoadFromMemory(const void* data, std::size_t size, const NzSkeletalModelParameters& params = NzSkeletalModelParameters()); + bool LoadFromStream(NzInputStream& stream, const NzSkeletalModelParameters& params = NzSkeletalModelParameters()); + + void Reset(); + + bool SetAnimation(NzAnimation* animation); + void SetMesh(NzMesh* mesh) override; + bool SetSequence(const NzString& sequenceName); + void SetSequence(unsigned int sequenceIndex); + + NzSkeletalModel& operator=(const NzSkeletalModel& node); + NzSkeletalModel& operator=(NzSkeletalModel&& node); + + private: + void Register() override; + void Unregister() override; + void Update() override; + void UpdateBoundingVolume() const; + + NzAnimationRef m_animation; + NzSkeleton m_skeleton; + const NzSequence* m_currentSequence; + bool m_animationEnabled; + float m_interpolation; + unsigned int m_currentFrame; + unsigned int m_nextFrame; + + static NzSkeletalModelLoader::LoaderList s_loaders; +}; + +#endif // NAZARA_SKELETALMODEL_HPP diff --git a/src/Nazara/Graphics/Loaders/Mesh/Loader.cpp b/src/Nazara/Graphics/Loaders/Mesh/Loader.cpp index d64597248..2c2d5e514 100644 --- a/src/Nazara/Graphics/Loaders/Mesh/Loader.cpp +++ b/src/Nazara/Graphics/Loaders/Mesh/Loader.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -32,11 +33,71 @@ namespace } if (mesh->IsAnimable()) + { + NazaraError("Can't load animated mesh into static model"); + return false; + } + + // Nous ne pouvons plus avoir recours au smart pointeur à partir d'ici si nous voulons être exception-safe + NzMesh* meshPtr = mesh.get(); + + model->Reset(); + model->SetMesh(meshPtr); + mesh.release(); + + if (parameters.loadMaterials) + { + unsigned int matCount = model->GetMaterialCount(); + + for (unsigned int i = 0; i < matCount; ++i) + { + NzString mat = meshPtr->GetMaterial(i); + if (!mat.IsEmpty()) + { + std::unique_ptr material(new NzMaterial); + material->SetPersistent(false); + + if (material->LoadFromFile(mat, parameters.material)) + { + model->SetMaterial(i, material.get()); + material.release(); + } + else + NazaraWarning("Failed to load material #" + NzString::Number(i)); + } + } + } + + return true; + } + + nzTernary CheckAnimated(NzInputStream& stream, const NzSkeletalModelParameters& parameters) + { + NazaraUnused(stream); + NazaraUnused(parameters); + + return nzTernary_Unknown; + } + + bool LoadAnimated(NzSkeletalModel* model, NzInputStream& stream, const NzSkeletalModelParameters& parameters) + { + NazaraUnused(parameters); + + std::unique_ptr mesh(new NzMesh); + mesh->SetPersistent(false); + if (!mesh->LoadFromStream(stream, parameters.mesh)) + { + NazaraError("Failed to load model mesh"); + return false; + } + + if (!mesh->IsAnimable()) { NazaraError("Can't load static mesh into animated model"); return false; } + // Nous ne pouvons plus avoir recours au smart pointeur à partir d'ici si nous voulons être exception-safe NzMesh* meshPtr = mesh.get(); @@ -74,9 +135,11 @@ namespace void NzLoaders_Mesh_Register() { NzModelLoader::RegisterLoader(NzMeshLoader::IsExtensionSupported, CheckStatic, LoadStatic); + NzSkeletalModelLoader::RegisterLoader(NzMeshLoader::IsExtensionSupported, CheckAnimated, LoadAnimated); } void NzLoaders_Mesh_Unregister() { NzModelLoader::UnregisterLoader(NzMeshLoader::IsExtensionSupported, CheckStatic, LoadStatic); + NzSkeletalModelLoader::UnregisterLoader(NzMeshLoader::IsExtensionSupported, CheckAnimated, LoadAnimated); } diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp new file mode 100644 index 000000000..b7fe39f98 --- /dev/null +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -0,0 +1,357 @@ +// Copyright (C) 2014 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool NzSkeletalModelParameters::IsValid() const +{ + if (!NzModelParameters::IsValid()) + return false; + + if (loadAnimation && !animation.IsValid()) + return false; + + return true; +} + +NzSkeletalModel::NzSkeletalModel() : +m_currentSequence(nullptr), +m_animationEnabled(true) +{ +} + +NzSkeletalModel::NzSkeletalModel(const NzSkeletalModel& model) : +NzModel(model), +m_skeleton(model.m_skeleton), +m_currentSequence(model.m_currentSequence), +m_animationEnabled(model.m_animationEnabled), +m_interpolation(model.m_interpolation), +m_currentFrame(model.m_currentFrame), +m_nextFrame(model.m_nextFrame) +{ +} + +NzSkeletalModel::~NzSkeletalModel() +{ + Reset(); +} + +void NzSkeletalModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const +{ + const NzMatrix4f& transformMatrix = GetTransformMatrix(); + + unsigned int submeshCount = m_mesh->GetSubMeshCount(); + for (unsigned int i = 0; i < submeshCount; ++i) + { + const NzSkeletalMesh* mesh = static_cast(m_mesh->GetSubMesh(i)); + const NzMaterial* material = m_materials[mesh->GetMaterialIndex()]; + + NzMeshData meshData; + meshData.indexBuffer = mesh->GetIndexBuffer(); + meshData.primitiveMode = mesh->GetPrimitiveMode(); + meshData.vertexBuffer = NzSkinningManager::GetBuffer(mesh, &m_skeleton); + + renderQueue->AddMesh(material, meshData, m_skeleton.GetAABB(), transformMatrix); + } +} + +void NzSkeletalModel::AdvanceAnimation(float elapsedTime) +{ + #if NAZARA_GRAPHICS_SAFE + if (!m_animation) + { + NazaraError("Model has no animation"); + return; + } + #endif + + m_interpolation += m_currentSequence->frameRate * elapsedTime; + while (m_interpolation > 1.f) + { + m_interpolation -= 1.f; + + unsigned lastFrame = m_currentSequence->firstFrame + m_currentSequence->frameCount - 1; + if (m_nextFrame+1 > lastFrame) + { + 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 + { + m_currentFrame = m_nextFrame; + m_nextFrame++; + } + } + + m_animation->AnimateSkeleton(&m_skeleton, m_currentFrame, m_nextFrame, m_interpolation); + + InvalidateBoundingVolume(); +} + +void NzSkeletalModel::EnableAnimation(bool animation) +{ + m_animationEnabled = animation; +} + +NzAnimation* NzSkeletalModel::GetAnimation() const +{ + return m_animation; +} + +NzSkeleton* NzSkeletalModel::GetSkeleton() +{ + InvalidateBoundingVolume(); + + return &m_skeleton; +} + +const NzSkeleton* NzSkeletalModel::GetSkeleton() const +{ + return &m_skeleton; +} + +bool NzSkeletalModel::HasAnimation() const +{ + return m_animation != nullptr; +} + +bool NzSkeletalModel::IsAnimated() const +{ + return true; +} + +bool NzSkeletalModel::IsAnimationEnabled() const +{ + return m_animationEnabled; +} + +bool NzSkeletalModel::IsDrawable() const +{ + return m_mesh != nullptr && m_mesh->GetSubMeshCount() >= 1; +} + +bool NzSkeletalModel::LoadFromFile(const NzString& filePath, const NzSkeletalModelParameters& params) +{ + return NzSkeletalModelLoader::LoadFromFile(this, filePath, params); +} + +bool NzSkeletalModel::LoadFromMemory(const void* data, std::size_t size, const NzSkeletalModelParameters& params) +{ + return NzSkeletalModelLoader::LoadFromMemory(this, data, size, params); +} + +bool NzSkeletalModel::LoadFromStream(NzInputStream& stream, const NzSkeletalModelParameters& params) +{ + return NzSkeletalModelLoader::LoadFromStream(this, stream, params); +} + +void NzSkeletalModel::Reset() +{ + NzModel::Reset(); + + m_skeleton.Destroy(); + + if (m_scene) + m_scene->UnregisterForUpdate(this); +} + +bool NzSkeletalModel::SetAnimation(NzAnimation* animation) +{ + #if NAZARA_GRAPHICS_SAFE + if (!m_mesh) + { + NazaraError("Model has no mesh"); + return false; + } + + if (animation) + { + if (!animation->IsValid()) + { + NazaraError("Invalid animation"); + return false; + } + + if (animation->GetType() != m_mesh->GetAnimationType()) + { + NazaraError("Animation type must match mesh animation type"); + return false; + } + + if (animation->GetJointCount() != m_mesh->GetJointCount()) + { + NazaraError("Animation joint count must match mesh joint count"); + return false; + } + } + #endif + + m_animation = animation; + if (m_animation) + { + m_currentFrame = 0; + m_interpolation = 0.f; + + SetSequence(0); + + if (m_scene) + m_scene->RegisterForUpdate(this); + } + else if (m_scene) + m_scene->UnregisterForUpdate(this); + + return true; +} + +void NzSkeletalModel::SetMesh(NzMesh* mesh) +{ + #if NAZARA_GRAPHICS_SAFE + if (mesh && mesh->GetAnimationType() != nzAnimationType_Skeletal) + { + NazaraError("Mesh animation type must be skeletal"); + return; + } + #endif + + NzModel::SetMesh(mesh); + + if (m_mesh) + { + if (m_animation && m_animation->GetJointCount() != m_mesh->GetJointCount()) + { + NazaraWarning("Animation joint count is not matching new mesh joint count, disabling animation..."); + SetAnimation(nullptr); + } + + m_skeleton = *m_mesh->GetSkeleton(); // Copie du squelette template + } +} + +bool NzSkeletalModel::SetSequence(const NzString& sequenceName) +{ + ///TODO: Rendre cette erreur "safe" avec le nouveau système de gestions d'erreur (No-log) + #if NAZARA_GRAPHICS_SAFE + if (!m_animation) + { + NazaraError("Model has no animation"); + return false; + } + #endif + + const NzSequence* currentSequence = m_animation->GetSequence(sequenceName); + if (!currentSequence) + { + NazaraError("Sequence not found"); + return false; + } + + m_currentSequence = currentSequence; + m_nextFrame = m_currentSequence->firstFrame; + + return true; +} + +void NzSkeletalModel::SetSequence(unsigned int sequenceIndex) +{ + #if NAZARA_GRAPHICS_SAFE + if (!m_animation) + { + NazaraError("Model has no animation"); + return; + } + #endif + + const NzSequence* currentSequence = m_animation->GetSequence(sequenceIndex); + #if NAZARA_GRAPHICS_SAFE + if (!currentSequence) + { + NazaraError("Sequence not found"); + return; + } + #endif + + m_currentSequence = currentSequence; + m_nextFrame = m_currentSequence->firstFrame; +} + +NzSkeletalModel& NzSkeletalModel::operator=(const NzSkeletalModel& node) +{ + NzSkeletalModel::operator=(node); + + m_animation = node.m_animation; + m_animationEnabled = node.m_animationEnabled; + m_currentFrame = node.m_currentFrame; + m_currentSequence = node.m_currentSequence; + m_interpolation = node.m_interpolation; + m_nextFrame = node.m_nextFrame; + m_skeleton = node.m_skeleton; + + return *this; +} + +NzSkeletalModel& NzSkeletalModel::operator=(NzSkeletalModel&& node) +{ + NzModel::operator=(node); + + // Ressources + m_animation = std::move(node.m_animation); + m_skeleton = std::move(node.m_skeleton); + + // Paramètres + m_animationEnabled = node.m_animationEnabled; + m_currentFrame = node.m_currentFrame; + m_currentSequence = node.m_currentSequence; + m_interpolation = node.m_interpolation; + m_nextFrame = node.m_nextFrame; + + return *this; +} + +void NzSkeletalModel::Register() +{ + if (m_animation) + m_scene->RegisterForUpdate(this); +} + +void NzSkeletalModel::Unregister() +{ + m_scene->UnregisterForUpdate(this); +} + +void NzSkeletalModel::Update() +{ + if (m_animationEnabled && m_animation) + AdvanceAnimation(m_scene->GetUpdateTime()); +} + +void NzSkeletalModel::UpdateBoundingVolume() const +{ + if (m_boundingVolume.IsNull()) + m_boundingVolume.Set(m_skeleton.GetAABB()); + + if (!m_transformMatrixUpdated) + UpdateTransformMatrix(); + + m_boundingVolume.Update(m_transformMatrix); + m_boundingVolumeUpdated = true; +} + +NzSkeletalModelLoader::LoaderList NzSkeletalModel::s_loaders;