From 0e49132cd9bcf7e30b79fc7141faf61786ad4e4d Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 5 Mar 2013 12:09:51 +0100 Subject: [PATCH] Added visibility state to SceneNode Former-commit-id: 5325e268a4276d6e2e3e72648641ca03225ab4da --- include/Nazara/3D/Camera.hpp | 2 +- include/Nazara/3D/Light.hpp | 3 +-- include/Nazara/3D/Model.hpp | 2 +- include/Nazara/3D/Scene.hpp | 3 +++ include/Nazara/3D/SceneNode.hpp | 9 ++++++-- include/Nazara/3D/SceneRoot.hpp | 3 +-- src/Nazara/3D/Camera.cpp | 14 ++++++------ src/Nazara/3D/Light.cpp | 16 +++++++------- src/Nazara/3D/Model.cpp | 38 ++++++++++++++++----------------- src/Nazara/3D/Scene.cpp | 35 +++++++++++++++--------------- src/Nazara/3D/SceneNode.cpp | 33 ++++++++++++++++++++++------ src/Nazara/3D/SceneRoot.cpp | 14 ++++++------ 12 files changed, 99 insertions(+), 73 deletions(-) diff --git a/include/Nazara/3D/Camera.hpp b/include/Nazara/3D/Camera.hpp index 7884b264e..d2c140ce0 100644 --- a/include/Nazara/3D/Camera.hpp +++ b/include/Nazara/3D/Camera.hpp @@ -51,12 +51,12 @@ class NAZARA_API NzCamera : public NzSceneNode private: void AddToRenderQueue(NzRenderQueue& renderQueue) const; void Invalidate(); - bool IsVisible(const NzFrustumf& frustum) const override; void Register(); void Unregister(); void UpdateFrustum() const; void UpdateProjectionMatrix() const; void UpdateViewMatrix() const; + bool VisibilityTest(const NzFrustumf& frustum) override; mutable NzFrustumf m_frustum; mutable NzMatrix4f m_projectionMatrix; diff --git a/include/Nazara/3D/Light.hpp b/include/Nazara/3D/Light.hpp index 19ac8aea2..3342c02a5 100644 --- a/include/Nazara/3D/Light.hpp +++ b/include/Nazara/3D/Light.hpp @@ -36,8 +36,6 @@ class NAZARA_API NzLight : public NzSceneNode nzSceneNodeType GetSceneNodeType() const; NzColor GetSpecularColor() const; - bool IsVisible(const NzFrustumf& frustum) const; - void SetAmbientColor(const NzColor& ambient); void SetAttenuation(float attenuation); void SetDiffuseColor(const NzColor& diffuse); @@ -52,6 +50,7 @@ class NAZARA_API NzLight : public NzSceneNode void Register(); void Unregister(); void UpdateFrustum(); + bool VisibilityTest(const NzFrustumf& frustum); nzLightType m_type; NzBoundingBoxf m_boundingBox; diff --git a/include/Nazara/3D/Model.hpp b/include/Nazara/3D/Model.hpp index cf543e9b5..0bf6f8b79 100644 --- a/include/Nazara/3D/Model.hpp +++ b/include/Nazara/3D/Model.hpp @@ -54,7 +54,6 @@ class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable bool IsAnimationEnabled() const; bool IsDrawEnabled() const; - bool IsVisible(const NzFrustumf& frustum) const override; bool LoadFromFile(const NzString& meshPath, const NzModelParameters& modelParameters = NzModelParameters()); bool LoadFromMemory(const void* data, std::size_t size, const NzModelParameters& modelParameters = NzModelParameters()); @@ -77,6 +76,7 @@ class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable void Unregister() override; void Update() override; void UpdateBoundingBox() const; + bool VisibilityTest(const NzFrustumf& frustum) override; std::vector m_materials; mutable NzBoundingBoxf m_boundingBox; diff --git a/include/Nazara/3D/Scene.hpp b/include/Nazara/3D/Scene.hpp index 5e49cedd8..86e36c5d7 100644 --- a/include/Nazara/3D/Scene.hpp +++ b/include/Nazara/3D/Scene.hpp @@ -10,10 +10,12 @@ #include #include #include +#include class NzCamera; class NzLight; class NzModel; +class NzRenderQueue; class NzSceneNode; struct NzSceneImpl; @@ -45,6 +47,7 @@ class NAZARA_API NzScene operator const NzSceneNode&() const; private: + void RecursiveFrustumCull(NzRenderQueue& renderQueue, const NzFrustumf& frustum, NzSceneNode* node); void SetActiveCamera(const NzCamera* camera); NzSceneImpl* m_impl; diff --git a/include/Nazara/3D/SceneNode.hpp b/include/Nazara/3D/SceneNode.hpp index 482d55da2..3501c366f 100644 --- a/include/Nazara/3D/SceneNode.hpp +++ b/include/Nazara/3D/SceneNode.hpp @@ -31,17 +31,22 @@ class NAZARA_API NzSceneNode : public NzNode NzScene* GetScene() const; virtual nzSceneNodeType GetSceneNodeType() const = 0; - virtual bool IsVisible(const NzFrustumf& frustum) const = 0; + bool IsVisible() const; protected: virtual void OnParenting(const NzNode* parent) override; + virtual void OnVisibilityChange(bool visibility); virtual void Register(); void SetScene(NzScene* scene); - virtual bool ShouldUpdateWhenVisible(); virtual void Unregister(); virtual void Update(); + virtual bool VisibilityTest(const NzFrustumf& frustum) = 0; NzScene* m_scene; + bool m_visible; + + private: + void UpdateVisibility(const NzFrustumf& frustum); }; #endif // NAZARA_SCENENODE_HPP diff --git a/include/Nazara/3D/SceneRoot.hpp b/include/Nazara/3D/SceneRoot.hpp index b1c34731e..1c944e27a 100644 --- a/include/Nazara/3D/SceneRoot.hpp +++ b/include/Nazara/3D/SceneRoot.hpp @@ -22,14 +22,13 @@ class NAZARA_API NzSceneRoot : public NzSceneNode const NzBoundingBoxf& GetBoundingBox() const override; nzSceneNodeType GetSceneNodeType() const override; - bool IsVisible(const NzFrustumf& frustum) const override; - private: NzSceneRoot(NzScene* scene); virtual ~NzSceneRoot(); void Register(); void Unregister(); + bool VisibilityTest(const NzFrustumf& frustum) override; }; #endif // NAZARA_SCENEROOT_HPP diff --git a/src/Nazara/3D/Camera.cpp b/src/Nazara/3D/Camera.cpp index 76a66f6c7..4115bfb88 100644 --- a/src/Nazara/3D/Camera.cpp +++ b/src/Nazara/3D/Camera.cpp @@ -216,13 +216,6 @@ void NzCamera::Invalidate() m_viewMatrixUpdated = false; } -bool NzCamera::IsVisible(const NzFrustumf& frustum) const -{ - NazaraUnused(frustum); - //NazaraInternalError("SceneNode::IsVisible() called on Camera"); - return false; -} - void NzCamera::Register() { } @@ -251,3 +244,10 @@ void NzCamera::UpdateViewMatrix() const m_viewMatrix.MakeLookAt(m_derivedPosition, m_derivedPosition + m_derivedRotation*NzVector3f::Forward(), m_upVector); m_viewMatrixUpdated = true; } + +bool NzCamera::VisibilityTest(const NzFrustumf& frustum) +{ + NazaraUnused(frustum); + //NazaraInternalError("SceneNode::IsVisible() called on Camera"); + return false; +} diff --git a/src/Nazara/3D/Light.cpp b/src/Nazara/3D/Light.cpp index 0ef739e60..5d15cfc05 100644 --- a/src/Nazara/3D/Light.cpp +++ b/src/Nazara/3D/Light.cpp @@ -179,14 +179,6 @@ NzColor NzLight::GetSpecularColor() const return m_specularColor; } -bool NzLight::IsVisible(const NzFrustumf& frustum) const -{ - NazaraUnused(frustum); - - ///FIXME: Pour l'instant toujours visible - return true; // Toujours visible -} - void NzLight::SetAmbientColor(const NzColor& ambient) { m_ambientColor = ambient; @@ -236,3 +228,11 @@ void NzLight::Register() void NzLight::Unregister() { } + +bool NzLight::VisibilityTest(const NzFrustumf& frustum) +{ + NazaraUnused(frustum); + + ///FIXME: Pour l'instant toujours visible + return true; // Toujours visible +} diff --git a/src/Nazara/3D/Model.cpp b/src/Nazara/3D/Model.cpp index 8708ffed0..656b9d33f 100644 --- a/src/Nazara/3D/Model.cpp +++ b/src/Nazara/3D/Model.cpp @@ -258,25 +258,6 @@ bool NzModel::IsDrawEnabled() const return m_drawEnabled; } -bool NzModel::IsVisible(const NzFrustumf& frustum) const -{ - #if NAZARA_3D_SAFE - if (!m_mesh) - { - NazaraError("Model has no mesh"); - return false; - } - #endif - - if (!m_drawEnabled) - return false; - - if (!m_boundingBoxUpdated) - UpdateBoundingBox(); - - return frustum.Contains(m_boundingBox); -} - bool NzModel::LoadFromFile(const NzString& meshPath, const NzModelParameters& modelParameters) { ///TODO: ResourceManager @@ -620,3 +601,22 @@ void NzModel::UpdateBoundingBox() const m_boundingBox.Update(m_transformMatrix); m_boundingBoxUpdated = true; } + +bool NzModel::VisibilityTest(const NzFrustumf& frustum) +{ + #if NAZARA_3D_SAFE + if (!m_mesh) + { + NazaraError("Model has no mesh"); + return false; + } + #endif + + if (!m_drawEnabled) + return false; + + if (!m_boundingBoxUpdated) + UpdateBoundingBox(); + + return frustum.Contains(m_boundingBox); +} diff --git a/src/Nazara/3D/Scene.cpp b/src/Nazara/3D/Scene.cpp index 6fa73faae..93d1f6899 100644 --- a/src/Nazara/3D/Scene.cpp +++ b/src/Nazara/3D/Scene.cpp @@ -36,23 +36,6 @@ namespace NzVector3f pos; }; - - void RecursiveFrustumCull(NzRenderQueue& renderQueue, const NzFrustumf& frustum, NzSceneNode* node) - { - for (NzNode* child : node->GetChilds()) - { - if (child->GetNodeType() == nzNodeType_Scene) - { - NzSceneNode* sceneNode = static_cast(child); - ///TODO: Empêcher le rendu des enfants si le parent est cullé selon un flag - if (sceneNode->IsVisible(frustum)) - sceneNode->AddToRenderQueue(renderQueue); - - if (sceneNode->HasChilds()) - RecursiveFrustumCull(renderQueue, frustum, sceneNode); - } - } - } } struct NzSceneImpl @@ -402,6 +385,24 @@ NzScene::operator const NzSceneNode&() const return m_impl->root; } +void NzScene::RecursiveFrustumCull(NzRenderQueue& renderQueue, const NzFrustumf& frustum, NzSceneNode* node) +{ + for (NzNode* child : node->GetChilds()) + { + if (child->GetNodeType() == nzNodeType_Scene) + { + NzSceneNode* sceneNode = static_cast(child); + ///TODO: Empêcher le rendu des enfants si le parent est cullé selon un flag + sceneNode->UpdateVisibility(frustum); + if (sceneNode->IsVisible()) + sceneNode->AddToRenderQueue(renderQueue); + + if (sceneNode->HasChilds()) + RecursiveFrustumCull(renderQueue, frustum, sceneNode); + } + } +} + void NzScene::SetActiveCamera(const NzCamera* camera) { m_impl->activeCamera = camera; diff --git a/src/Nazara/3D/SceneNode.cpp b/src/Nazara/3D/SceneNode.cpp index 3deb1db87..644da8306 100644 --- a/src/Nazara/3D/SceneNode.cpp +++ b/src/Nazara/3D/SceneNode.cpp @@ -7,13 +7,15 @@ #include NzSceneNode::NzSceneNode() : -m_scene(nullptr) +m_scene(nullptr), +m_visible(false) { } NzSceneNode::NzSceneNode(const NzSceneNode& node) : NzNode(node), -m_scene(node.m_scene) +m_scene(node.m_scene), +m_visible(false) { } @@ -29,6 +31,11 @@ NzScene* NzSceneNode::GetScene() const return m_scene; } +bool NzSceneNode::IsVisible() const +{ + return m_visible; +} + void NzSceneNode::OnParenting(const NzNode* parent) { if (parent) @@ -40,6 +47,13 @@ void NzSceneNode::OnParenting(const NzNode* parent) SetScene(nullptr); } +void NzSceneNode::OnVisibilityChange(bool visibility) +{ + NazaraUnused(visibility); + + ///TODO: Envoyer l'évènements aux listeners +} + void NzSceneNode::Register() { } @@ -63,11 +77,6 @@ void NzSceneNode::SetScene(NzScene* scene) } } -bool NzSceneNode::ShouldUpdateWhenVisible() -{ - return false; -} - void NzSceneNode::Unregister() { } @@ -75,3 +84,13 @@ void NzSceneNode::Unregister() void NzSceneNode::Update() { } + +void NzSceneNode::UpdateVisibility(const NzFrustumf& frustum) +{ + bool wasVisible = m_visible; + + m_visible = VisibilityTest(frustum); + + if (m_visible != wasVisible) + OnVisibilityChange(m_visible); +} diff --git a/src/Nazara/3D/SceneRoot.cpp b/src/Nazara/3D/SceneRoot.cpp index 4661222ab..49c966e83 100644 --- a/src/Nazara/3D/SceneRoot.cpp +++ b/src/Nazara/3D/SceneRoot.cpp @@ -31,13 +31,6 @@ nzSceneNodeType NzSceneRoot::GetSceneNodeType() const return nzSceneNodeType_Root; } -bool NzSceneRoot::IsVisible(const NzFrustumf& frustum) const -{ - NazaraUnused(frustum); - - return true; // Toujours visible -} - void NzSceneRoot::Register() { NazaraInternalError("SceneNode::Register() called on SceneRoot"); @@ -47,3 +40,10 @@ void NzSceneRoot::Unregister() { NazaraInternalError("SceneNode::Unregister() called on SceneRoot"); } + +bool NzSceneRoot::VisibilityTest(const NzFrustumf& frustum) +{ + NazaraUnused(frustum); + + return true; // Toujours visible +}