From 8a3c410d605554444d83d5643d117c4dd97e3308 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 20 Jan 2015 20:35:16 +0100 Subject: [PATCH 01/13] Made bounding volume handing part of SceneNodes Former-commit-id: d09d06ac4515ce09aa16fd92dd045c2a06730a99 --- examples/FirstScene/main.cpp | 5 ++ include/Nazara/Graphics/Camera.hpp | 2 +- include/Nazara/Graphics/Light.hpp | 5 +- include/Nazara/Graphics/Model.hpp | 6 +- include/Nazara/Graphics/ParticleSystem.hpp | 6 +- include/Nazara/Graphics/SceneNode.hpp | 11 ++- include/Nazara/Graphics/SceneRoot.hpp | 2 +- include/Nazara/Graphics/SkeletalModel.hpp | 2 +- include/Nazara/Graphics/Sprite.hpp | 5 +- include/Nazara/Graphics/TextSprite.hpp | 5 +- include/Nazara/Graphics/View.hpp | 2 +- src/Nazara/Graphics/Light.cpp | 93 +++++++++------------- src/Nazara/Graphics/Model.cpp | 40 +--------- src/Nazara/Graphics/ParticleSystem.cpp | 28 +------ src/Nazara/Graphics/SceneNode.cpp | 29 +++++++ src/Nazara/Graphics/SceneRoot.cpp | 11 ++- src/Nazara/Graphics/SkeletalModel.cpp | 17 ++-- src/Nazara/Graphics/Sprite.cpp | 37 ++------- src/Nazara/Graphics/TextSprite.cpp | 50 ++++-------- 19 files changed, 127 insertions(+), 229 deletions(-) diff --git a/examples/FirstScene/main.cpp b/examples/FirstScene/main.cpp index 62a4425c8..45395cec9 100644 --- a/examples/FirstScene/main.cpp +++ b/examples/FirstScene/main.cpp @@ -225,6 +225,11 @@ int main() bool smoothMovement = true; NzVector3f targetPos = camera.GetPosition(); + NzTextSprite text; + text.SetParent(scene); + text.Update(NzSimpleTextDrawer::Draw("Hello world !", 72)); + text.Scale(0.1f); + // Début de la boucle de rendu du programme while (window.IsOpen()) { diff --git a/include/Nazara/Graphics/Camera.hpp b/include/Nazara/Graphics/Camera.hpp index 3cdb0eb41..e9b64d632 100644 --- a/include/Nazara/Graphics/Camera.hpp +++ b/include/Nazara/Graphics/Camera.hpp @@ -9,12 +9,12 @@ #include #include -#include #include #include #include #include #include +#include class NAZARA_API NzCamera : public NzAbstractViewer, public NzNode, NzRenderTarget::Listener { diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index 4a53eed94..9db57e7c6 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -28,7 +28,6 @@ class NAZARA_API NzLight : public NzSceneNode float GetAmbientFactor() const; float GetAttenuation() const; - const NzBoundingVolumef& GetBoundingVolume() const; NzColor GetColor() const; float GetDiffuseFactor() const; float GetInnerAngle() const; @@ -54,15 +53,13 @@ class NAZARA_API NzLight : public NzSceneNode private: bool FrustumCull(const NzFrustumf& frustum) const override; - void InvalidateNode() override; + void MakeBoundingVolume() const override; void Register() override; void Unregister() override; void UpdateBoundingVolume() const; nzLightType m_type; - mutable NzBoundingVolumef m_boundingVolume; NzColor m_color; - mutable bool m_boundingVolumeUpdated; float m_ambientFactor; float m_attenuation; float m_diffuseFactor; diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index 3249cdd48..5b193f5ee 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -44,7 +44,6 @@ class NAZARA_API NzModel : public NzSceneNode void EnableAnimation(bool animation); NzAnimation* GetAnimation() const; - const NzBoundingVolumef& GetBoundingVolume() const; NzMaterial* GetMaterial(const NzString& subMeshName) const; NzMaterial* GetMaterial(unsigned int matIndex) const; NzMaterial* GetMaterial(unsigned int skinIndex, const NzString& subMeshName) const; @@ -84,13 +83,10 @@ class NAZARA_API NzModel : public NzSceneNode NzModel& operator=(const NzModel& node); protected: - void InvalidateNode() override; - virtual void UpdateBoundingVolume() const; + void MakeBoundingVolume() const override; std::vector m_materials; - mutable NzBoundingVolumef m_boundingVolume; NzMeshRef m_mesh; - mutable bool m_boundingVolumeUpdated; unsigned int m_matCount; unsigned int m_skin; unsigned int m_skinCount; diff --git a/include/Nazara/Graphics/ParticleSystem.hpp b/include/Nazara/Graphics/ParticleSystem.hpp index 7537da429..b62fa368e 100644 --- a/include/Nazara/Graphics/ParticleSystem.hpp +++ b/include/Nazara/Graphics/ParticleSystem.hpp @@ -43,7 +43,6 @@ class NAZARA_API NzParticleSystem : public NzSceneNode, NzUpdatable void* GenerateParticle(); void* GenerateParticles(unsigned int count); - const NzBoundingVolumef& GetBoundingVolume() const override; const NzParticleDeclaration* GetDeclaration() const; float GetFixedStepSize() const; unsigned int GetMaxParticleCount() const; @@ -67,22 +66,19 @@ class NAZARA_API NzParticleSystem : public NzSceneNode, NzUpdatable NzParticleSystem& operator=(const NzParticleSystem& emitter); private: - void GenerateAABB() const; + void MakeBoundingVolume() const override; void Register() override; void ResizeBuffer(); void Unregister() override; void Update() override; - void UpdateBoundingVolume() const; std::set> m_dyingParticles; mutable std::vector m_buffer; std::vector m_controllers; std::vector m_emitters; std::vector m_generators; - mutable NzBoundingVolumef m_boundingVolume; NzParticleDeclarationConstRef m_declaration; NzParticleRendererRef m_renderer; - mutable bool m_boundingVolumeUpdated; bool m_fixedStepEnabled; bool m_processing; float m_stepAccumulator; diff --git a/include/Nazara/Graphics/SceneNode.hpp b/include/Nazara/Graphics/SceneNode.hpp index edfdf56e2..3cbfde9e9 100644 --- a/include/Nazara/Graphics/SceneNode.hpp +++ b/include/Nazara/Graphics/SceneNode.hpp @@ -14,6 +14,8 @@ #include #include +class NzScene; + class NAZARA_API NzSceneNode : public NzNode { friend class NzScene; @@ -29,7 +31,7 @@ class NAZARA_API NzSceneNode : public NzNode void EnableDrawing(bool drawingEnabled); NzVector3f GetBackward() const; - virtual const NzBoundingVolumef& GetBoundingVolume() const = 0; + virtual const NzBoundingVolumef& GetBoundingVolume() const; NzVector3f GetDown() const; NzVector3f GetForward() const; NzVector3f GetLeft() const; @@ -39,6 +41,8 @@ class NAZARA_API NzSceneNode : public NzNode virtual nzSceneNodeType GetSceneNodeType() const = 0; NzVector3f GetUp() const; + void InvalidateAABB(); + virtual bool IsDrawable() const = 0; bool IsDrawingEnabled() const; bool IsVisible() const; @@ -48,6 +52,8 @@ class NAZARA_API NzSceneNode : public NzNode protected: virtual bool FrustumCull(const NzFrustumf& frustum) const; + virtual void InvalidateNode() override; + virtual void MakeBoundingVolume() const = 0; virtual void OnParenting(const NzNode* parent) override; virtual void OnVisibilityChange(bool visibility); void RecursiveSetScene(NzScene* scene, NzNode* node); @@ -55,8 +61,11 @@ class NAZARA_API NzSceneNode : public NzNode void SetScene(NzScene* scene); virtual void Unregister(); virtual void Update(); + virtual void UpdateBoundingVolume() const; + mutable NzBoundingVolumef m_boundingVolume; NzScene* m_scene; + mutable bool m_boundingVolumeUpdated; bool m_drawingEnabled; bool m_visible; diff --git a/include/Nazara/Graphics/SceneRoot.hpp b/include/Nazara/Graphics/SceneRoot.hpp index 7b81fd5ac..9e09281ac 100644 --- a/include/Nazara/Graphics/SceneRoot.hpp +++ b/include/Nazara/Graphics/SceneRoot.hpp @@ -17,7 +17,6 @@ class NAZARA_API NzSceneRoot : public NzSceneNode public: void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; - const NzBoundingVolumef& GetBoundingVolume() const override; nzSceneNodeType GetSceneNodeType() const override; bool IsDrawable() const; @@ -26,6 +25,7 @@ class NAZARA_API NzSceneRoot : public NzSceneNode NzSceneRoot(NzScene* scene); virtual ~NzSceneRoot(); + void MakeBoundingVolume() const override; void Register(); void Unregister(); }; diff --git a/include/Nazara/Graphics/SkeletalModel.hpp b/include/Nazara/Graphics/SkeletalModel.hpp index 7938ba4c4..84c8e0f88 100644 --- a/include/Nazara/Graphics/SkeletalModel.hpp +++ b/include/Nazara/Graphics/SkeletalModel.hpp @@ -69,10 +69,10 @@ class NAZARA_API NzSkeletalModel : public NzModel, NzUpdatable NzSkeletalModel& operator=(NzSkeletalModel&& node); private: + void MakeBoundingVolume() const override; void Register() override; void Unregister() override; void Update() override; - void UpdateBoundingVolume() const; NzAnimationRef m_animation; NzSkeleton m_skeleton; diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index b3739cb07..69c51fa90 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -22,7 +22,6 @@ class NAZARA_API NzSprite : public NzSceneNode void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; - const NzBoundingVolumef& GetBoundingVolume() const override; const NzColor& GetColor() const; NzMaterial* GetMaterial() const; nzSceneNodeType GetSceneNodeType() const override; @@ -44,18 +43,16 @@ class NAZARA_API NzSprite : public NzSceneNode private: void InvalidateNode() override; + void MakeBoundingVolume() const override; void Register() override; void Unregister() override; - void UpdateBoundingVolume() const; void UpdateVertices() const; - mutable NzBoundingVolumef m_boundingVolume; NzColor m_color; NzMaterialRef m_material; NzRectf m_textureCoords; NzVector2f m_size; mutable NzVertexStruct_XYZ_Color_UV m_vertices[4]; - mutable bool m_boundingVolumeUpdated; mutable bool m_verticesUpdated; }; diff --git a/include/Nazara/Graphics/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp index 40e323d98..23ce1a7f3 100644 --- a/include/Nazara/Graphics/TextSprite.hpp +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -28,7 +28,6 @@ class NAZARA_API NzTextSprite : public NzSceneNode, NzAbstractAtlas::Listener void Clear(); - const NzBoundingVolumef& GetBoundingVolume() const override; const NzColor& GetColor() const; NzMaterial* GetMaterial() const; nzSceneNodeType GetSceneNodeType() const override; @@ -47,12 +46,12 @@ class NAZARA_API NzTextSprite : public NzSceneNode, NzAbstractAtlas::Listener private: void ClearAtlases(); void InvalidateNode() override; + void MakeBoundingVolume() const override; bool OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata) override; bool OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractImage* oldLayer, NzAbstractImage* newLayer, void* userdata) override; void OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata) override; void Register() override; void Unregister() override; - void UpdateBoundingVolume() const; void UpdateVertices() const; struct RenderIndices @@ -65,11 +64,9 @@ class NAZARA_API NzTextSprite : public NzSceneNode, NzAbstractAtlas::Listener mutable std::unordered_map m_renderInfos; mutable std::vector m_localVertices; mutable std::vector m_vertices; - mutable NzBoundingVolumef m_boundingVolume; NzColor m_color; NzMaterialRef m_material; NzRectui m_localBounds; - mutable bool m_boundingVolumeUpdated; mutable bool m_verticesUpdated; }; diff --git a/include/Nazara/Graphics/View.hpp b/include/Nazara/Graphics/View.hpp index b7f016afc..740bde621 100644 --- a/include/Nazara/Graphics/View.hpp +++ b/include/Nazara/Graphics/View.hpp @@ -9,12 +9,12 @@ #include #include -#include #include #include #include #include #include +#include class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget::Listener { diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index e3288adc2..73df7e784 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -14,11 +14,11 @@ #include ///TODO: Utilisation des UBOs +///TODO: Scale ? NzLight::NzLight(nzLightType type) : m_type(type), m_color(NzColor::White), -m_boundingVolumeUpdated(false), m_ambientFactor((type == nzLightType_Directional) ? 0.2f : 0.f), m_attenuation(0.9f), m_diffuseFactor(1.f), @@ -31,9 +31,7 @@ m_radius(5.f) NzLight::NzLight(const NzLight& light) : NzSceneNode(light), m_type(light.m_type), -m_boundingVolume(light.m_boundingVolume), m_color(light.m_color), -m_boundingVolumeUpdated(light.m_boundingVolumeUpdated), m_ambientFactor(light.m_ambientFactor), m_attenuation(light.m_attenuation), m_diffuseFactor(light.m_diffuseFactor), @@ -112,14 +110,6 @@ float NzLight::GetAttenuation() const return m_attenuation; } -const NzBoundingVolumef& NzLight::GetBoundingVolume() const -{ - if (!m_boundingVolumeUpdated) - UpdateBoundingVolume(); - - return m_boundingVolume; -} - NzColor NzLight::GetColor() const { return m_color; @@ -251,11 +241,45 @@ bool NzLight::FrustumCull(const NzFrustumf& frustum) const return false; } -void NzLight::InvalidateNode() +void NzLight::MakeBoundingVolume() const { - NzSceneNode::InvalidateNode(); + switch (m_type) + { + case nzLightType_Directional: + m_boundingVolume.MakeInfinite(); + break; - m_boundingVolumeUpdated = false; + case nzLightType_Point: + { + NzVector3f radius(m_radius); + m_boundingVolume.Set(-radius, radius); + break; + } + + case nzLightType_Spot: + { + // On forme une boite sur l'origine + NzBoxf box(NzVector3f::Zero()); + + // On calcule le reste des points + NzVector3f base(NzVector3f::Forward()*m_radius); + + // Il nous faut maintenant le rayon du cercle projeté à cette distance + // Tangente = Opposé/Adjaçent <=> Opposé = Adjaçent*Tangente + float radius = m_radius*std::tan(NzDegreeToRadian(m_outerAngle)); + NzVector3f lExtend = NzVector3f::Left()*radius; + NzVector3f uExtend = NzVector3f::Up()*radius; + + // Et on ajoute ensuite les quatres extrémités de la pyramide + box.ExtendTo(base + lExtend + uExtend); + box.ExtendTo(base + lExtend - uExtend); + box.ExtendTo(base - lExtend + uExtend); + box.ExtendTo(base - lExtend - uExtend); + + m_boundingVolume.Set(box); + break; + } + } } void NzLight::Register() @@ -269,46 +293,7 @@ void NzLight::Unregister() void NzLight::UpdateBoundingVolume() const { if (m_boundingVolume.IsNull()) - { - switch (m_type) - { - case nzLightType_Directional: - m_boundingVolume.MakeInfinite(); - m_boundingVolumeUpdated = true; - return; // Rien d'autre à faire - - case nzLightType_Point: - { - NzVector3f radius(m_radius); - m_boundingVolume.Set(-radius, radius); - break; - } - - case nzLightType_Spot: - { - // On forme une boite sur l'origine - NzBoxf box(NzVector3f::Zero()); - - // On calcule le reste des points - NzVector3f base(NzVector3f::Forward()*m_radius); - - // Il nous faut maintenant le rayon du cercle projeté à cette distance - // Tangente = Opposé/Adjaçent <=> Opposé = Adjaçent*Tangente - float radius = m_radius*std::tan(NzDegreeToRadian(m_outerAngle)); - NzVector3f lExtend = NzVector3f::Left()*radius; - NzVector3f uExtend = NzVector3f::Up()*radius; - - // Et on ajoute ensuite les quatres extrémités de la pyramide - box.ExtendTo(base + lExtend + uExtend); - box.ExtendTo(base + lExtend - uExtend); - box.ExtendTo(base - lExtend + uExtend); - box.ExtendTo(base - lExtend - uExtend); - - m_boundingVolume.Set(box); - break; - } - } - } + MakeBoundingVolume(); switch (m_type) { diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index cf32336b8..6bddc09cc 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -25,7 +25,6 @@ bool NzModelParameters::IsValid() const } NzModel::NzModel() : -m_boundingVolumeUpdated(true), m_matCount(0), m_skin(0), m_skinCount(1) @@ -35,9 +34,7 @@ m_skinCount(1) NzModel::NzModel(const NzModel& model) : NzSceneNode(model), m_materials(model.m_materials), -m_boundingVolume(model.m_boundingVolume), m_mesh(model.m_mesh), -m_boundingVolumeUpdated(model.m_boundingVolumeUpdated), m_matCount(model.m_matCount), m_skin(model.m_skin), m_skinCount(model.m_skinCount) @@ -69,24 +66,6 @@ void NzModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const } } -const NzBoundingVolumef& NzModel::GetBoundingVolume() const -{ - #if NAZARA_GRAPHICS_SAFE - if (!m_mesh) - { - NazaraError("Model has no mesh"); - - static NzBoundingVolumef dummy(nzExtend_Null); - return dummy; - } - #endif - - if (!m_boundingVolumeUpdated) - UpdateBoundingVolume(); - - return m_boundingVolume; -} - NzMaterial* NzModel::GetMaterial(const NzString& subMeshName) const { #if NAZARA_GRAPHICS_SAFE @@ -414,23 +393,12 @@ NzModel& NzModel::operator=(const NzModel& node) return *this; } -void NzModel::InvalidateNode() +void NzModel::MakeBoundingVolume() const { - NzSceneNode::InvalidateNode(); - - m_boundingVolumeUpdated = false; -} - -void NzModel::UpdateBoundingVolume() const -{ - if (m_boundingVolume.IsNull()) + if (m_mesh) m_boundingVolume.Set(m_mesh->GetAABB()); - - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); - - m_boundingVolume.Update(m_transformMatrix); - m_boundingVolumeUpdated = true; + else + m_boundingVolume.MakeNull(); } NzModelLoader::LoaderList NzModel::s_loaders; diff --git a/src/Nazara/Graphics/ParticleSystem.cpp b/src/Nazara/Graphics/ParticleSystem.cpp index b8533109b..1ded1113b 100644 --- a/src/Nazara/Graphics/ParticleSystem.cpp +++ b/src/Nazara/Graphics/ParticleSystem.cpp @@ -18,7 +18,6 @@ NzParticleSystem(maxParticleCount, NzParticleDeclaration::Get(layout)) NzParticleSystem::NzParticleSystem(unsigned int maxParticleCount, const NzParticleDeclaration* declaration) : m_declaration(declaration), -m_boundingVolumeUpdated(false), m_fixedStepEnabled(false), m_processing(false), m_stepAccumulator(0.f), @@ -38,10 +37,8 @@ NzParticleSystem::NzParticleSystem(const NzParticleSystem& system) : NzSceneNode(system), m_controllers(system.m_controllers), m_generators(system.m_generators), -m_boundingVolume(system.m_boundingVolume), m_declaration(system.m_declaration), m_renderer(system.m_renderer), -m_boundingVolumeUpdated(system.m_boundingVolumeUpdated), m_fixedStepEnabled(system.m_fixedStepEnabled), m_processing(false), m_stepAccumulator(0.f), @@ -132,14 +129,6 @@ void* NzParticleSystem::GenerateParticles(unsigned int count) return ptr; } -const NzBoundingVolumef& NzParticleSystem::GetBoundingVolume() const -{ - if (!m_boundingVolumeUpdated) - UpdateBoundingVolume(); - - return m_boundingVolume; -} - const NzParticleDeclaration* NzParticleSystem::GetDeclaration() const { return m_declaration; @@ -238,8 +227,6 @@ NzParticleSystem& NzParticleSystem::operator=(const NzParticleSystem& system) NzSceneNode::operator=(system); - m_boundingVolume = system.m_boundingVolume; - m_boundingVolumeUpdated = system.m_boundingVolumeUpdated; m_controllers = system.m_controllers; m_declaration = system.m_declaration; m_fixedStepEnabled = system.m_fixedStepEnabled; @@ -308,7 +295,7 @@ void NzParticleSystem::ApplyControllers(NzParticleMapper& mapper, unsigned int p m_dyingParticles.clear(); } -void NzParticleSystem::GenerateAABB() const +void NzParticleSystem::MakeBoundingVolume() const { ///TODO: Calculer l'AABB (prendre la taille des particules en compte s'il y a) m_boundingVolume.MakeInfinite(); @@ -356,16 +343,3 @@ void NzParticleSystem::Update() ApplyControllers(mapper, m_particleCount, elapsedTime, m_stepAccumulator); } } - -void NzParticleSystem::UpdateBoundingVolume() const -{ - if (m_boundingVolume.IsNull()) - GenerateAABB(); - - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); - - ///FIXME: Pourquoi est-ce que le particle system est un node ? Il serait trop coûteux de calculer les particules relativement - m_boundingVolume.Update(m_transformMatrix); - m_boundingVolumeUpdated = true; -} diff --git a/src/Nazara/Graphics/SceneNode.cpp b/src/Nazara/Graphics/SceneNode.cpp index d5ae7da72..29a343531 100644 --- a/src/Nazara/Graphics/SceneNode.cpp +++ b/src/Nazara/Graphics/SceneNode.cpp @@ -11,6 +11,7 @@ NzSceneNode::NzSceneNode() : m_scene(nullptr), +m_boundingVolumeUpdated(false), m_drawingEnabled(true), m_visible(false) { @@ -19,6 +20,7 @@ m_visible(false) NzSceneNode::NzSceneNode(const NzSceneNode& sceneNode) : NzNode(sceneNode), m_scene(nullptr), +m_boundingVolumeUpdated(false), m_drawingEnabled(sceneNode.m_drawingEnabled), m_visible(false) { @@ -44,6 +46,14 @@ NzVector3f NzSceneNode::GetBackward() const return NzNode::GetBackward(); } +const NzBoundingVolumef& NzSceneNode::GetBoundingVolume() const +{ + if (!m_boundingVolumeUpdated) + UpdateBoundingVolume(); + + return m_boundingVolume; +} + NzVector3f NzSceneNode::GetDown() const { if (m_scene) @@ -145,6 +155,13 @@ bool NzSceneNode::FrustumCull(const NzFrustumf& frustum) const return frustum.Contains(GetBoundingVolume()); } +void NzSceneNode::InvalidateNode() +{ + NzNode::InvalidateNode(); + + m_boundingVolumeUpdated = false; +} + void NzSceneNode::OnParenting(const NzNode* parent) { if (parent) @@ -207,6 +224,18 @@ void NzSceneNode::Update() { } +void NzSceneNode::UpdateBoundingVolume() const +{ + if (m_boundingVolume.IsNull()) + MakeBoundingVolume(); + + if (!m_transformMatrixUpdated) + UpdateTransformMatrix(); + + m_boundingVolume.Update(m_transformMatrix); + m_boundingVolumeUpdated = true; +} + void NzSceneNode::UpdateVisibility(const NzFrustumf& frustum) { bool wasVisible = m_visible; diff --git a/src/Nazara/Graphics/SceneRoot.cpp b/src/Nazara/Graphics/SceneRoot.cpp index 46e446eaa..5bb63f624 100644 --- a/src/Nazara/Graphics/SceneRoot.cpp +++ b/src/Nazara/Graphics/SceneRoot.cpp @@ -20,12 +20,6 @@ void NzSceneRoot::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const NazaraInternalError("SceneNode::AddToRenderQueue() called on SceneRoot"); } -const NzBoundingVolumef& NzSceneRoot::GetBoundingVolume() const -{ - static NzBoundingVolumef infinite(nzExtend_Infinite); - return infinite; -} - nzSceneNodeType NzSceneRoot::GetSceneNodeType() const { return nzSceneNodeType_Root; @@ -36,6 +30,11 @@ bool NzSceneRoot::IsDrawable() const return true; } +void NzSceneRoot::MakeBoundingVolume() const +{ + m_boundingVolume.MakeInfinite(); +} + void NzSceneRoot::Register() { NazaraInternalError("SceneNode::Register() called on SceneRoot"); diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index b7fe39f98..16b01f01f 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -325,6 +325,11 @@ NzSkeletalModel& NzSkeletalModel::operator=(NzSkeletalModel&& node) return *this; } +void NzSkeletalModel::MakeBoundingVolume() const +{ + m_boundingVolume.Set(m_skeleton.GetAABB()); +} + void NzSkeletalModel::Register() { if (m_animation) @@ -342,16 +347,4 @@ void NzSkeletalModel::Update() 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; diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index 983929d53..d660adc23 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -9,22 +9,18 @@ #include NzSprite::NzSprite() : -m_boundingVolume(NzBoundingVolumef::Null()), m_color(NzColor::White), m_textureCoords(0.f, 0.f, 1.f, 1.f), m_size(64.f, 64.f), -m_boundingVolumeUpdated(true), m_verticesUpdated(false) { SetDefaultMaterial(); } NzSprite::NzSprite(NzTexture* texture) : -m_boundingVolume(NzBoundingVolumef::Null()), m_color(NzColor::White), m_textureCoords(0.f, 0.f, 1.f, 1.f), m_size(64.f, 64.f), -m_boundingVolumeUpdated(false), m_verticesUpdated(false) { SetTexture(texture, true); @@ -32,13 +28,11 @@ m_verticesUpdated(false) NzSprite::NzSprite(const NzSprite& sprite) : NzSceneNode(sprite), -m_boundingVolume(sprite.m_boundingVolume), m_color(sprite.m_color), m_material(sprite.m_material), m_textureCoords(sprite.m_textureCoords), m_size(sprite.m_size), m_vertices(sprite.m_vertices), -m_boundingVolumeUpdated(sprite.m_boundingVolumeUpdated), m_verticesUpdated(sprite.m_verticesUpdated) { SetParent(sprite.GetParent()); @@ -52,14 +46,6 @@ void NzSprite::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const renderQueue->AddSprites(m_material, m_vertices, 1); } -const NzBoundingVolumef& NzSprite::GetBoundingVolume() const -{ - if (!m_boundingVolumeUpdated) - UpdateBoundingVolume(); - - return m_boundingVolume; -} - const NzColor& NzSprite::GetColor() const { return m_color; @@ -189,7 +175,6 @@ NzSprite& NzSprite::operator=(const NzSprite& sprite) m_size = sprite.m_size; // On ne copie pas les sommets finaux car il est très probable que nos paramètres soient modifiés et qu'ils doivent être régénérés de toute façon - m_boundingVolumeUpdated = false; m_verticesUpdated = false; return *this; @@ -199,7 +184,6 @@ void NzSprite::InvalidateNode() { NzSceneNode::InvalidateNode(); - m_boundingVolumeUpdated = false; m_verticesUpdated = false; } @@ -213,21 +197,12 @@ void NzSprite::Unregister() { } -void NzSprite::UpdateBoundingVolume() const +void NzSprite::MakeBoundingVolume() const { - if (m_boundingVolume.IsNull()) - { - NzVector3f down = m_scene->GetDown(); - NzVector3f right = m_scene->GetRight(); + NzVector3f down = (m_scene) ? m_scene->GetDown() : NzVector3f::Down(); + NzVector3f right = (m_scene) ? m_scene->GetRight() : NzVector3f::Right(); - m_boundingVolume.Set(NzVector3f(0.f), m_size.x*right + m_size.y*down); - } - - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); - - m_boundingVolume.Update(m_transformMatrix); - m_boundingVolumeUpdated = true; + m_boundingVolume.Set(NzVector3f(0.f), m_size.x*right + m_size.y*down); } void NzSprite::UpdateVertices() const @@ -235,8 +210,8 @@ void NzSprite::UpdateVertices() const if (!m_transformMatrixUpdated) UpdateTransformMatrix(); - NzVector3f down = m_scene->GetDown(); - NzVector3f right = m_scene->GetRight(); + NzVector3f down = (m_scene) ? m_scene->GetDown() : NzVector3f::Down(); + NzVector3f right = (m_scene) ? m_scene->GetRight() : NzVector3f::Right(); m_vertices[0].color = m_color; m_vertices[0].position = m_transformMatrix.Transform(NzVector3f(0.f)); diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 80def6d1f..ac3b67a35 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -11,7 +11,6 @@ #include NzTextSprite::NzTextSprite() : -m_boundingVolume(NzBoundingVolumef::Null()), m_color(NzColor::White), m_verticesUpdated(false) { @@ -24,11 +23,9 @@ m_atlases(sprite.m_atlases), m_renderInfos(sprite.m_renderInfos), m_localVertices(sprite.m_localVertices), m_vertices(sprite.m_vertices), -m_boundingVolume(sprite.m_boundingVolume), m_color(sprite.m_color), m_material(sprite.m_material), m_localBounds(sprite.m_localBounds), -m_boundingVolumeUpdated(sprite.m_boundingVolumeUpdated), m_verticesUpdated(sprite.m_verticesUpdated) { SetParent(sprite.GetParent()); @@ -66,14 +63,6 @@ void NzTextSprite::Clear() m_vertices.clear(); } -const NzBoundingVolumef& NzTextSprite::GetBoundingVolume() const -{ - if (!m_boundingVolumeUpdated) - UpdateBoundingVolume(); - - return m_boundingVolume; -} - const NzColor& NzTextSprite::GetColor() const { return m_color; @@ -266,7 +255,6 @@ NzTextSprite& NzTextSprite::operator=(const NzTextSprite& text) m_localVertices = text.m_localVertices; // On ne copie pas les sommets finaux car il est très probable que nos paramètres soient modifiés et qu'ils doivent être régénérés de toute façon - m_boundingVolumeUpdated = false; m_verticesUpdated = false; return *this; @@ -284,10 +272,21 @@ void NzTextSprite::InvalidateNode() { NzSceneNode::InvalidateNode(); - m_boundingVolumeUpdated = false; m_verticesUpdated = false; } +void NzTextSprite::MakeBoundingVolume() const +{ + NzVector3f down = (m_scene) ? m_scene->GetDown() : NzVector3f::Down(); + NzVector3f right = (m_scene) ? m_scene->GetRight() : NzVector3f::Right(); + + NzRectf bounds(m_localBounds); + NzVector2f max = bounds.GetMaximum(); + NzVector2f min = bounds.GetMinimum(); + + m_boundingVolume.Set(min.x*right + min.y*down, max.x*right + max.y*down); +} + bool NzTextSprite::OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata) { NazaraUnused(userdata); @@ -373,34 +372,13 @@ void NzTextSprite::Unregister() { } -void NzTextSprite::UpdateBoundingVolume() const -{ - if (m_boundingVolume.IsNull()) - { - NzVector3f down = m_scene->GetDown(); - NzVector3f right = m_scene->GetRight(); - - NzRectf bounds(m_localBounds); - NzVector2f max = bounds.GetMaximum(); - NzVector2f min = bounds.GetMinimum(); - - m_boundingVolume.Set(min.x*right + min.y*down, max.x*right + max.y*down); - } - - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); - - m_boundingVolume.Update(m_transformMatrix); - m_boundingVolumeUpdated = true; -} - void NzTextSprite::UpdateVertices() const { if (!m_transformMatrixUpdated) UpdateTransformMatrix(); - NzVector3f down = m_scene->GetDown(); - NzVector3f right = m_scene->GetRight(); + NzVector3f down = (m_scene) ? m_scene->GetDown() : NzVector3f::Down(); + NzVector3f right = (m_scene) ? m_scene->GetRight() : NzVector3f::Right(); NzSparsePtr colorPtr(&m_vertices[0].color, sizeof(NzVertexStruct_XYZ_Color_UV)); NzSparsePtr posPtr(&m_vertices[0].position, sizeof(NzVertexStruct_XYZ_Color_UV)); From b37ec10760911f01c60dbced98d4c30c314cc8b8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 22 Jan 2015 23:45:32 +0100 Subject: [PATCH 02/13] Oops. Former-commit-id: 81a0e9f5e6cf26ed18633cabbd916881ef6559f3 --- examples/FirstScene/main.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/examples/FirstScene/main.cpp b/examples/FirstScene/main.cpp index 45395cec9..62a4425c8 100644 --- a/examples/FirstScene/main.cpp +++ b/examples/FirstScene/main.cpp @@ -225,11 +225,6 @@ int main() bool smoothMovement = true; NzVector3f targetPos = camera.GetPosition(); - NzTextSprite text; - text.SetParent(scene); - text.Update(NzSimpleTextDrawer::Draw("Hello world !", 72)); - text.Scale(0.1f); - // Début de la boucle de rendu du programme while (window.IsOpen()) { From a39988ac46839b431fbfefae26c26454a6a954e6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 22 Jan 2015 23:46:55 +0100 Subject: [PATCH 03/13] Removed unused file Former-commit-id: 42b523c8da74800166935602755e554f26d7fa40 --- include/Nazara/Graphics/SceneLayer.hpp | 34 -------------------------- 1 file changed, 34 deletions(-) delete mode 100644 include/Nazara/Graphics/SceneLayer.hpp diff --git a/include/Nazara/Graphics/SceneLayer.hpp b/include/Nazara/Graphics/SceneLayer.hpp deleted file mode 100644 index 20fe359a2..000000000 --- a/include/Nazara/Graphics/SceneLayer.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// 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_SCENELAYER_HPP -#define NAZARA_SCENELAYER_HPP - -#include - -class NzAbstractRenderTechnique; -class NzAbstractViewer; - -class NAZARA_API NzSceneLayer -{ - public: - NzSceneLayer(); - ~NzSceneLayer(); - - void Draw(); - - nzUInt32 GetBufferClearFlags() const; - NzAbstractRenderQueue* GetRenderQueue() const; - NzAbstractRenderTechnique* GetRenderTechnique() const; - NzScene* GetScene() const; - NzAbstractViewer* GetViewer() const; - - void SetBufferClearFlags(nzUInt32 flags); - void SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique); - void SetViewer(NzAbstractViewer* viewer); -}; - -#endif // NAZARA_SCENELAYER_HPP From c5ec2af361181a179750275d94dd95bc2669b751 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 23 Jan 2015 00:02:33 +0100 Subject: [PATCH 04/13] (Scene) Added RenderFrame method Former-commit-id: ba02b2f0d65858fdabdedf5f0a9f7f9b1baa7268 --- include/Nazara/Graphics/Scene.hpp | 2 ++ src/Nazara/Graphics/Scene.cpp | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/Nazara/Graphics/Scene.hpp b/include/Nazara/Graphics/Scene.hpp index 8a9b1b89c..cabe82ebf 100644 --- a/include/Nazara/Graphics/Scene.hpp +++ b/include/Nazara/Graphics/Scene.hpp @@ -57,6 +57,8 @@ class NAZARA_API NzScene void RegisterForUpdate(NzUpdatable* object); + void RenderFrame(); + void SetAmbientColor(const NzColor& color); void SetBackground(NzAbstractBackground* background); void SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique); diff --git a/src/Nazara/Graphics/Scene.cpp b/src/Nazara/Graphics/Scene.cpp index e66a99f03..a89fc5d93 100644 --- a/src/Nazara/Graphics/Scene.cpp +++ b/src/Nazara/Graphics/Scene.cpp @@ -245,6 +245,22 @@ bool NzScene::IsBackgroundEnabled() const return m_impl->backgroundEnabled; } +void NzScene::RenderFrame() +{ + try + { + NzErrorFlags errFlags(nzErrorFlag_ThrowException, true); + Update(); + Cull(); + UpdateVisible(); + Draw(); + } + catch (const std::exception& e) + { + NazaraError("Failed to render frame: " + NzString(e.what())); + } +} + void NzScene::RegisterForUpdate(NzUpdatable* object) { #if NAZARA_GRAPHICS_SAFE From 1f043b61df95eba44721f57ddd44d1a875541c2f Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 23 Jan 2015 14:35:26 +0100 Subject: [PATCH 05/13] (Scene) Removed useless Pimpl idiom Former-commit-id: ffbca2a6b6e16792f58e77195a08911368f64f57 --- include/Nazara/Graphics/Scene.hpp | 25 ++- include/Nazara/Graphics/SceneNode.hpp | 2 +- include/Nazara/Graphics/SceneRoot.hpp | 4 +- .../Graphics/DeferredRenderTechnique.cpp | 1 + .../Graphics/ForwardRenderTechnique.cpp | 1 + src/Nazara/Graphics/ParticleSystem.cpp | 1 + src/Nazara/Graphics/Scene.cpp | 162 ++++++++---------- src/Nazara/Graphics/SkeletalModel.cpp | 1 + src/Nazara/Graphics/Sprite.cpp | 2 + src/Nazara/Graphics/TextSprite.cpp | 2 + 10 files changed, 103 insertions(+), 98 deletions(-) diff --git a/include/Nazara/Graphics/Scene.hpp b/include/Nazara/Graphics/Scene.hpp index cabe82ebf..f317207c0 100644 --- a/include/Nazara/Graphics/Scene.hpp +++ b/include/Nazara/Graphics/Scene.hpp @@ -8,11 +8,15 @@ #define NAZARA_SCENE_HPP #include +#include #include #include #include #include +#include #include +#include +#include class NzAbstractRenderQueue; class NzAbstractViewer; @@ -22,7 +26,6 @@ class NzModel; class NzNode; class NzRenderQueue; class NzSceneNode; -struct NzSceneImpl; class NAZARA_API NzScene { @@ -30,7 +33,7 @@ class NAZARA_API NzScene public: NzScene(); - ~NzScene(); + ~NzScene() = default; void AddToVisibilityList(NzUpdatable* object); @@ -47,7 +50,8 @@ class NAZARA_API NzScene NzVector3f GetLeft() const; NzAbstractRenderTechnique* GetRenderTechnique() const; NzVector3f GetRight() const; - NzSceneNode& GetRoot() const; + NzSceneNode& GetRoot(); + const NzSceneNode& GetRoot() const; NzAbstractViewer* GetViewer() const; NzVector3f GetUp() const; float GetUpdateTime() const; @@ -76,7 +80,20 @@ class NAZARA_API NzScene private: void RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node); - NzSceneImpl* m_impl; + mutable std::unique_ptr m_background; + mutable std::unique_ptr m_renderTechnique; + std::vector m_updateList; + std::vector m_visibleUpdateList; + NzClock m_updateClock; + NzColor m_ambientColor; + NzSceneRoot m_root; + NzAbstractViewer* m_viewer; + bool m_backgroundEnabled; + bool m_update; + float m_frameTime; + float m_updateTime; + mutable int m_renderTechniqueRanking; + unsigned int m_updatePerSecond; }; #endif // NAZARA_SCENE_HPP diff --git a/include/Nazara/Graphics/SceneNode.hpp b/include/Nazara/Graphics/SceneNode.hpp index 3cbfde9e9..ccb62806e 100644 --- a/include/Nazara/Graphics/SceneNode.hpp +++ b/include/Nazara/Graphics/SceneNode.hpp @@ -9,11 +9,11 @@ #include #include -#include #include #include #include +class NzAbstractRenderQueue; class NzScene; class NAZARA_API NzSceneNode : public NzNode diff --git a/include/Nazara/Graphics/SceneRoot.hpp b/include/Nazara/Graphics/SceneRoot.hpp index 9e09281ac..28aa9b20e 100644 --- a/include/Nazara/Graphics/SceneRoot.hpp +++ b/include/Nazara/Graphics/SceneRoot.hpp @@ -10,9 +10,11 @@ #include #include +class NzScene; + class NAZARA_API NzSceneRoot : public NzSceneNode { - friend struct NzSceneImpl; + friend NzScene; public: void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; diff --git a/src/Nazara/Graphics/DeferredRenderTechnique.cpp b/src/Nazara/Graphics/DeferredRenderTechnique.cpp index d05b39fe7..cb86db239 100644 --- a/src/Nazara/Graphics/DeferredRenderTechnique.cpp +++ b/src/Nazara/Graphics/DeferredRenderTechnique.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 09e4e7910..d5de9bc65 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Nazara/Graphics/ParticleSystem.cpp b/src/Nazara/Graphics/ParticleSystem.cpp index 1ded1113b..2fa2e9601 100644 --- a/src/Nazara/Graphics/ParticleSystem.cpp +++ b/src/Nazara/Graphics/ParticleSystem.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Nazara/Graphics/Scene.cpp b/src/Nazara/Graphics/Scene.cpp index a89fc5d93..33624d6bd 100644 --- a/src/Nazara/Graphics/Scene.cpp +++ b/src/Nazara/Graphics/Scene.cpp @@ -9,57 +9,30 @@ #include #include #include -#include #include #include #include -#include -#include -#include #include -struct NzSceneImpl +NzScene::NzScene() : +m_ambientColor(25, 25, 25), +m_root(this), +m_viewer(nullptr), +m_backgroundEnabled(true), +m_update(false), +m_updatePerSecond(60) { - NzSceneImpl(NzScene* scene) : - root(scene) - { - } - - std::unique_ptr background; - std::unique_ptr renderTechnique; - std::vector updateList; - std::vector visibleUpdateList; - NzClock updateClock; - NzColor ambientColor = NzColor(25,25,25); - NzSceneRoot root; - NzAbstractViewer* viewer = nullptr; - bool backgroundEnabled = true; - bool update = false; - float frameTime; - float updateTime; - int renderTechniqueRanking; - unsigned int updatePerSecond = 60; -}; - -NzScene::NzScene() -{ - m_impl = new NzSceneImpl(this); -} - -NzScene::~NzScene() -{ - delete m_impl; } void NzScene::AddToVisibilityList(NzUpdatable* object) { - m_impl->visibleUpdateList.push_back(object); + m_visibleUpdateList.push_back(object); } void NzScene::Cull() { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return; @@ -69,10 +42,10 @@ void NzScene::Cull() NzAbstractRenderQueue* renderQueue = GetRenderTechnique()->GetRenderQueue(); renderQueue->Clear(false); - m_impl->visibleUpdateList.clear(); + m_visibleUpdateList.clear(); // Frustum culling - RecursiveFrustumCull(renderQueue, m_impl->viewer->GetFrustum(), &m_impl->root); + RecursiveFrustumCull(renderQueue, m_viewer->GetFrustum(), &m_root); ///TODO: Occlusion culling @@ -82,29 +55,29 @@ void NzScene::Cull() void NzScene::Draw() { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return; } #endif - m_impl->viewer->ApplyView(); + m_viewer->ApplyView(); try { - NzErrorFlags errFlags(nzErrorFlag_ThrowException); - m_impl->renderTechnique->Clear(this); - m_impl->renderTechnique->Draw(this); + NzErrorFlags errFlags(nzErrorFlag_ThrowException, true); + m_renderTechnique->Clear(this); + m_renderTechnique->Draw(this); } catch (const std::exception& e) { - NzString oldName = m_impl->renderTechnique->GetName(); + NzString oldName = m_renderTechnique->GetName(); - if (m_impl->renderTechniqueRanking > 0) + if (m_renderTechniqueRanking > 0) { - m_impl->renderTechnique.reset(NzRenderTechniques::GetByRanking(m_impl->renderTechniqueRanking-1, &m_impl->renderTechniqueRanking)); - NazaraError("Render technique \"" + oldName + "\" failed, fallback to \"" + m_impl->renderTechnique->GetName() + '"'); + m_renderTechnique.reset(NzRenderTechniques::GetByRanking(m_renderTechniqueRanking-1, &m_renderTechniqueRanking)); + NazaraError("Render technique \"" + oldName + "\" failed, fallback to \"" + m_renderTechnique->GetName() + '"'); } else { @@ -118,131 +91,136 @@ void NzScene::Draw() void NzScene::EnableBackground(bool enable) { - m_impl->backgroundEnabled = enable; + m_backgroundEnabled = enable; } NzColor NzScene::GetAmbientColor() const { - return m_impl->ambientColor; + return m_ambientColor; } NzAbstractBackground* NzScene::GetBackground() const { - if (!m_impl->background) - m_impl->background.reset(new NzColorBackground); + if (!m_background) + m_background.reset(new NzColorBackground); - return m_impl->background.get(); + return m_background.get(); } NzVector3f NzScene::GetBackward() const { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return NzVector3f::Backward(); } #endif - return -m_impl->viewer->GetGlobalForward(); + return -m_viewer->GetGlobalForward(); } NzVector3f NzScene::GetDown() const { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return NzVector3f::Down(); } #endif - return -m_impl->viewer->GetGlobalUp(); + return -m_viewer->GetGlobalUp(); } NzVector3f NzScene::GetForward() const { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return NzVector3f::Forward(); } #endif - return m_impl->viewer->GetGlobalForward(); + return m_viewer->GetGlobalForward(); } NzVector3f NzScene::GetLeft() const { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return NzVector3f::Left(); } #endif - return -m_impl->viewer->GetGlobalRight(); + return -m_viewer->GetGlobalRight(); } NzAbstractRenderTechnique* NzScene::GetRenderTechnique() const { - if (!m_impl->renderTechnique) - m_impl->renderTechnique.reset(NzRenderTechniques::GetByRanking(-1, &m_impl->renderTechniqueRanking)); + if (!m_renderTechnique) + m_renderTechnique.reset(NzRenderTechniques::GetByRanking(-1, &m_renderTechniqueRanking)); - return m_impl->renderTechnique.get(); + return m_renderTechnique.get(); } NzVector3f NzScene::GetRight() const { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return NzVector3f::Right(); } #endif - return m_impl->viewer->GetGlobalRight(); + return m_viewer->GetGlobalRight(); } -NzSceneNode& NzScene::GetRoot() const +NzSceneNode& NzScene::GetRoot() { - return m_impl->root; + return m_root; +} + +const NzSceneNode& NzScene::GetRoot() const +{ + return m_root; } NzAbstractViewer* NzScene::GetViewer() const { - return m_impl->viewer; + return m_viewer; } NzVector3f NzScene::GetUp() const { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return NzVector3f::Up(); } #endif - return m_impl->viewer->GetGlobalUp(); + return m_viewer->GetGlobalUp(); } float NzScene::GetUpdateTime() const { - return m_impl->updateTime; + return m_updateTime; } unsigned int NzScene::GetUpdatePerSecond() const { - return m_impl->updatePerSecond; + return m_updatePerSecond; } bool NzScene::IsBackgroundEnabled() const { - return m_impl->backgroundEnabled; + return m_backgroundEnabled; } void NzScene::RenderFrame() @@ -271,32 +249,32 @@ void NzScene::RegisterForUpdate(NzUpdatable* object) } #endif - m_impl->updateList.push_back(object); + m_updateList.push_back(object); } void NzScene::SetAmbientColor(const NzColor& color) { - m_impl->ambientColor = color; + m_ambientColor = color; } void NzScene::SetBackground(NzAbstractBackground* background) { - m_impl->background.reset(background); + m_background.reset(background); } void NzScene::SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique) { - m_impl->renderTechnique.reset(renderTechnique); + m_renderTechnique.reset(renderTechnique); } void NzScene::SetViewer(NzAbstractViewer* viewer) { - if (m_impl->viewer != viewer) + if (m_viewer != viewer) { - m_impl->viewer = viewer; + m_viewer = viewer; // Invalidation de tous les nodes de la scène (utile pour la régénération des sommets dépendant du viewer) - m_impl->root.InvalidateNode(); + m_root.InvalidateNode(); } } @@ -307,7 +285,7 @@ void NzScene::SetViewer(NzAbstractViewer& viewer) void NzScene::SetUpdatePerSecond(unsigned int updatePerSecond) { - m_impl->updatePerSecond = updatePerSecond; + m_updatePerSecond = updatePerSecond; } void NzScene::UnregisterForUpdate(NzUpdatable* object) @@ -320,20 +298,20 @@ void NzScene::UnregisterForUpdate(NzUpdatable* object) } #endif - auto it = std::find(m_impl->updateList.begin(), m_impl->updateList.end(), object); - if (it != m_impl->updateList.end()) - m_impl->updateList.erase(it); + auto it = std::find(m_updateList.begin(), m_updateList.end(), object); + if (it != m_updateList.end()) + m_updateList.erase(it); } void NzScene::Update() { - m_impl->update = (m_impl->updatePerSecond == 0 || m_impl->updateClock.GetMilliseconds() > 1000/m_impl->updatePerSecond); - if (m_impl->update) + m_update = (m_updatePerSecond == 0 || m_updateClock.GetMilliseconds() > 1000/m_updatePerSecond); + if (m_update) { - m_impl->updateTime = m_impl->updateClock.GetSeconds(); - m_impl->updateClock.Restart(); + m_updateTime = m_updateClock.GetSeconds(); + m_updateClock.Restart(); - for (NzUpdatable* updatable : m_impl->updateList) + for (NzUpdatable* updatable : m_updateList) ///TODO: Multihreading updatable->Update(); } @@ -343,16 +321,16 @@ void NzScene::UpdateVisible() { NzSkinningManager::Skin(); - if (m_impl->update) + if (m_update) { - for (NzUpdatable* node : m_impl->visibleUpdateList) + for (NzUpdatable* node : m_visibleUpdateList) node->Update(); } } NzScene::operator const NzSceneNode&() const { - return m_impl->root; + return m_root; } void NzScene::RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node) diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index 16b01f01f..07e8b76ef 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index d660adc23..e3ec9752b 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -3,7 +3,9 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include +#include #include #include #include diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index ac3b67a35..fb0f64f1e 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -5,7 +5,9 @@ #include #include #include +#include #include +#include #include #include #include From cf12552358b9bbedf833581de04e6d61f19cfc17 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 23 Jan 2015 21:04:29 +0100 Subject: [PATCH 06/13] (SceneNode) Added virtual constructor idiom (Light) Added default constructor Former-commit-id: 591e6a8435d2cea6238e70c0058d381b8d547f3e --- include/Nazara/Graphics/Light.hpp | 5 ++++- include/Nazara/Graphics/Model.hpp | 3 +++ include/Nazara/Graphics/SceneNode.hpp | 4 ++++ include/Nazara/Graphics/SceneRoot.hpp | 3 +++ include/Nazara/Graphics/Sprite.hpp | 3 +++ include/Nazara/Graphics/TextSprite.hpp | 3 +++ src/Nazara/Graphics/Light.cpp | 10 ++++++++++ src/Nazara/Graphics/Model.cpp | 10 ++++++++++ src/Nazara/Graphics/SceneRoot.cpp | 12 ++++++++++++ src/Nazara/Graphics/Sprite.cpp | 10 ++++++++++ src/Nazara/Graphics/TextSprite.cpp | 10 ++++++++++ 11 files changed, 72 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index 9db57e7c6..40ec4e525 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -18,12 +18,15 @@ struct NzLightUniforms; class NAZARA_API NzLight : public NzSceneNode { public: - NzLight(nzLightType type); + NzLight(nzLightType type = nzLightType_Point); NzLight(const NzLight& light); ~NzLight() = default; void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; + NzLight* Clone() const; + NzLight* Create() const; + void Enable(const NzShader* shader, const NzLightUniforms& uniforms, int offset = 0) const; float GetAmbientFactor() const; diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index 5b193f5ee..d209530a1 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -41,6 +41,9 @@ class NAZARA_API NzModel : public NzSceneNode void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; void AdvanceAnimation(float elapsedTime); + NzModel* Clone() const; + NzModel* Create() const; + void EnableAnimation(bool animation); NzAnimation* GetAnimation() const; diff --git a/include/Nazara/Graphics/SceneNode.hpp b/include/Nazara/Graphics/SceneNode.hpp index ccb62806e..0a771a00e 100644 --- a/include/Nazara/Graphics/SceneNode.hpp +++ b/include/Nazara/Graphics/SceneNode.hpp @@ -28,6 +28,10 @@ class NAZARA_API NzSceneNode : public NzNode virtual void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const = 0; + // Idiôme "virtual constructor" + virtual NzSceneNode* Clone() const = 0; + virtual NzSceneNode* Create() const = 0; + void EnableDrawing(bool drawingEnabled); NzVector3f GetBackward() const; diff --git a/include/Nazara/Graphics/SceneRoot.hpp b/include/Nazara/Graphics/SceneRoot.hpp index 28aa9b20e..9e4f6b960 100644 --- a/include/Nazara/Graphics/SceneRoot.hpp +++ b/include/Nazara/Graphics/SceneRoot.hpp @@ -27,6 +27,9 @@ class NAZARA_API NzSceneRoot : public NzSceneNode NzSceneRoot(NzScene* scene); virtual ~NzSceneRoot(); + NzSceneRoot* Clone() const; + NzSceneRoot* Create() const; + void MakeBoundingVolume() const override; void Register(); void Unregister(); diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index 69c51fa90..2beb4c85d 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -22,6 +22,9 @@ class NAZARA_API NzSprite : public NzSceneNode void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; + NzSprite* Clone() const; + NzSprite* Create() const; + const NzColor& GetColor() const; NzMaterial* GetMaterial() const; nzSceneNodeType GetSceneNodeType() const override; diff --git a/include/Nazara/Graphics/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp index 23ce1a7f3..2b7f33e09 100644 --- a/include/Nazara/Graphics/TextSprite.hpp +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -28,6 +28,9 @@ class NAZARA_API NzTextSprite : public NzSceneNode, NzAbstractAtlas::Listener void Clear(); + NzTextSprite* Clone() const; + NzTextSprite* Create() const; + const NzColor& GetColor() const; NzMaterial* GetMaterial() const; nzSceneNodeType GetSceneNodeType() const override; diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index 73df7e784..3f2e7ad2d 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -47,6 +47,16 @@ void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const renderQueue->AddLight(this); } +NzLight* NzLight::Clone() const +{ + return new NzLight(*this); +} + +NzLight* NzLight::Create() const +{ + return new NzLight; +} + void NzLight::Enable(const NzShader* shader, const NzLightUniforms& uniforms, int offset) const { /* diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index 6bddc09cc..137dff795 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -66,6 +66,16 @@ void NzModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const } } +NzModel* NzModel::Clone() const +{ + return new NzModel(*this); +} + +NzModel* NzModel::Create() const +{ + return new NzModel; +} + NzMaterial* NzModel::GetMaterial(const NzString& subMeshName) const { #if NAZARA_GRAPHICS_SAFE diff --git a/src/Nazara/Graphics/SceneRoot.cpp b/src/Nazara/Graphics/SceneRoot.cpp index 5bb63f624..cdf9f5eb5 100644 --- a/src/Nazara/Graphics/SceneRoot.cpp +++ b/src/Nazara/Graphics/SceneRoot.cpp @@ -30,6 +30,18 @@ bool NzSceneRoot::IsDrawable() const return true; } +NzSceneRoot* NzSceneRoot::Clone() const +{ + NazaraInternalError("SceneNode::Clone() called on SceneRoot"); + return nullptr; +} + +NzSceneRoot* NzSceneRoot::Create() const +{ + NazaraInternalError("SceneNode::Create() called on SceneRoot"); + return nullptr; +} + void NzSceneRoot::MakeBoundingVolume() const { m_boundingVolume.MakeInfinite(); diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index e3ec9752b..716bf9d5b 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -48,6 +48,16 @@ void NzSprite::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const renderQueue->AddSprites(m_material, m_vertices, 1); } +NzSprite* NzSprite::Clone() const +{ + return new NzSprite(*this); +} + +NzSprite* NzSprite::Create() const +{ + return new NzSprite; +} + const NzColor& NzSprite::GetColor() const { return m_color; diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index fb0f64f1e..f6fbb33fd 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -65,6 +65,16 @@ void NzTextSprite::Clear() m_vertices.clear(); } +NzTextSprite* NzTextSprite::Clone() const +{ + return new NzTextSprite(*this); +} + +NzTextSprite* NzTextSprite::Create() const +{ + return new NzTextSprite; +} + const NzColor& NzTextSprite::GetColor() const { return m_color; From 0a7711d85bec7ae6e9d2678a80a44d28a0044091 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 23 Jan 2015 22:35:41 +0100 Subject: [PATCH 07/13] (Scene) Added CreateNode and Clear methods Former-commit-id: de92f4a4be45e5cbd1d2d83191300e0b46764f0e --- examples/FirstScene/main.cpp | 23 +++---- include/Nazara/Graphics/Scene.hpp | 13 ++++ include/Nazara/Graphics/Scene.inl | 107 ++++++++++++++++++++++++++++++ src/Nazara/Graphics/Scene.cpp | 29 +++++++- 4 files changed, 154 insertions(+), 18 deletions(-) create mode 100644 include/Nazara/Graphics/Scene.inl diff --git a/examples/FirstScene/main.cpp b/examples/FirstScene/main.cpp index 62a4425c8..9ed702a69 100644 --- a/examples/FirstScene/main.cpp +++ b/examples/FirstScene/main.cpp @@ -84,7 +84,7 @@ int main() // Ensuite, nous allons rajouter un modèle à notre scène. // Les modèles représentent, globalement, tout ce qui est visible en trois dimensions. // Nous choisirons ici un vaisseau spatial (Quoi de mieux pour une scène spatiale ?) - NzModel spaceship; + NzModel* spaceship = scene.CreateNode(); // Création depuis la scène // Une structure permettant de paramétrer le chargement des modèles NzModelParameters params; @@ -101,7 +101,7 @@ int main() // On charge ensuite le modèle depuis son fichier // Le moteur va charger le fichier et essayer de retrouver les fichiers associés (comme les matériaux, textures, ...) - if (!spaceship.LoadFromFile("resources/Spaceship/spaceship.obj", params)) + if (!spaceship->LoadFromFile("resources/Spaceship/spaceship.obj", params)) { std::cout << "Failed to load spaceship" << std::endl; std::getchar(); @@ -111,7 +111,7 @@ int main() // Nous voulons afficher quelques statistiques relatives au modèle, comme le nombre de sommets et de triangles // Pour cela, nous devons accéder au mesh (maillage 3D) - NzMesh* mesh = spaceship.GetMesh(); + NzMesh* mesh = spaceship->GetMesh(); std::cout << mesh->GetVertexCount() << " sommets" << std::endl; std::cout << mesh->GetTriangleCount() << " triangles" << std::endl; @@ -119,7 +119,7 @@ int main() // En revanche, le format OBJ ne précise pas l'utilisation d'une normal map, nous devons donc la charger manuellement // Pour commencer on récupère le matériau du mesh, celui-ci en possède plusieurs mais celui qui nous intéresse, // celui de la coque, est le second (Cela est bien entendu lié au modèle en lui-même) - NzMaterial* material = spaceship.GetMaterial(1); + NzMaterial* material = spaceship->GetMaterial(1); // On lui indique ensuite le chemin vers la normal map if (!material->SetNormalMap("resources/Spaceship/Texture/normal.png")) @@ -129,10 +129,6 @@ int main() std::cout << "Failed to load normal map" << std::endl; } - // Il nous reste à attacher le modèle à la scène, ce qui se fait simplement via cet appel - spaceship.SetParent(scene); - // Et voilà, à partir de maintenant le modèle fait partie de la hiérarchie de la scène, et sera donc rendu avec cette dernière - // Nous avons besoin également d'une caméra, pour des raisons évidentes, celle-ci sera à l'écart du modèle // regardant dans sa direction. @@ -164,18 +160,15 @@ int main() // -PointLight: Lumière située à un endroit précis, envoyant de la lumière finie dans toutes les directions // -SpotLight: Lumière située à un endroit précis, envoyant de la lumière vers un endroit donné, avec un angle de diffusion - // Nous choisissons une lumière directionnelle représentant la nébuleuse de notre skybox - NzLight nebulaLight(nzLightType_Directional); + // Nous créons une lumière directionnelle pour représenter la nébuleuse de notre skybox + NzLight* nebulaLight = scene.CreateNode(nzLightType_Directional); // Il nous faut ensuite configurer la lumière // Pour commencer, sa couleur, la nébuleuse étant d'une couleur jaune, j'ai choisi ces valeurs - nebulaLight.SetColor(NzColor(255, 182, 90)); + nebulaLight->SetColor(NzColor(255, 182, 90)); // Nous appliquons ensuite une rotation de sorte que la lumière dans la même direction que la nébuleuse - nebulaLight.SetRotation(NzEulerAnglesf(0.f, 102.f, 0.f)); - - // Et nous ajoutons la lumière à la scène - nebulaLight.SetParent(scene); + nebulaLight->SetRotation(NzEulerAnglesf(0.f, 102.f, 0.f)); // Nous allons maintenant créer la fenêtre, dans laquelle nous ferons nos rendus // Celle-ci demande des paramètres plus complexes diff --git a/include/Nazara/Graphics/Scene.hpp b/include/Nazara/Graphics/Scene.hpp index f317207c0..03b37bfc4 100644 --- a/include/Nazara/Graphics/Scene.hpp +++ b/include/Nazara/Graphics/Scene.hpp @@ -10,12 +10,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include class NzAbstractRenderQueue; @@ -37,6 +39,12 @@ class NAZARA_API NzScene void AddToVisibilityList(NzUpdatable* object); + template T* CreateNode(Args&&... args); + template T* CreateNode(const NzString& name, Args&&... args); + template T* CreateNode(const NzString& name, const NzString& templateNodeName); + + void Clear(); + void Cull(); void Draw(); @@ -78,10 +86,13 @@ class NAZARA_API NzScene operator const NzSceneNode&() const; private: + bool RegisterSceneNode(const NzString& name, NzSceneNode* node); void RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node); mutable std::unique_ptr m_background; mutable std::unique_ptr m_renderTechnique; + std::unordered_map m_nodeMap; + std::vector> m_nodes; std::vector m_updateList; std::vector m_visibleUpdateList; NzClock m_updateClock; @@ -96,4 +107,6 @@ class NAZARA_API NzScene unsigned int m_updatePerSecond; }; +#include + #endif // NAZARA_SCENE_HPP diff --git a/include/Nazara/Graphics/Scene.inl b/include/Nazara/Graphics/Scene.inl new file mode 100644 index 000000000..3ac7be7af --- /dev/null +++ b/include/Nazara/Graphics/Scene.inl @@ -0,0 +1,107 @@ +// Copyright (C) 2015 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 + +///TODO: Déplacer vers SceneNode et exposer + +// Pour être sûr que ce code soit à jour +static_assert(nzSceneNodeType_Max == 6, "Please update the code below"); + +class NzLight; +class NzModel; +class NzParticleEmitter; +class NzSceneRoot; +class NzSprite; +class NzTextSprite; + +template +constexpr nzSceneNodeType NzImplGetType() +{ + return nzSceneNodeType_User; +} + +template<> +inline constexpr nzSceneNodeType NzImplGetType() +{ + return nzSceneNodeType_Light; +} + +template<> +inline constexpr nzSceneNodeType NzImplGetType() +{ + return nzSceneNodeType_Model; +} + +template<> +inline constexpr nzSceneNodeType NzImplGetType() +{ + return nzSceneNodeType_ParticleEmitter; +} + +template<> +inline constexpr nzSceneNodeType NzImplGetType() +{ + return nzSceneNodeType_Root; +} + +template<> +inline constexpr nzSceneNodeType NzImplGetType() +{ + return nzSceneNodeType_Sprite; +} + +template<> +inline constexpr nzSceneNodeType NzImplGetType() +{ + return nzSceneNodeType_TextSprite; +} + + +template +T* NzScene::CreateNode(Args&&... args) +{ + std::unique_ptr node(new T(std::forward(args)...)); + if (!RegisterSceneNode(NzString(), node.get())) + return nullptr; + + return node.release(); +} + +template +T* NzScene::CreateNode(const NzString& name, Args&&... args) +{ + std::unique_ptr node(new T(std::forward(args)...)); + if (!RegisterSceneNode(name, node.get())) + return nullptr; + + return node.release(); +} + +template +T* NzScene::CreateNode(const NzString& name, const NzString& templateNodeName) +{ + auto it = m_nodeMap.find(templateNodeName); + if (it == m_nodeMap.end()) + { + NazaraError("Node \"" + templateNodeName + "\" is not registred"); + return nullptr; + } + + NzSceneNode* sceneNode = it->second; + if (NzImplGetType() != sceneNode->GetSceneNodeType()) + { + NazaraError("Scene node type of T (" + NzString::Number(NzImplGetType()) + ") doesn't match template scene node type (" + NzString::Number(sceneNode->GetSceneNodeType()) + ")"); + return nullptr; + } + + std::unique_ptr node(static_cast(sceneNode)->Copy()); + if (!RegisterSceneNode(name, node.get())) + return nullptr; + + return node.release(); +} + +#include diff --git a/src/Nazara/Graphics/Scene.cpp b/src/Nazara/Graphics/Scene.cpp index 33624d6bd..4b86cdda5 100644 --- a/src/Nazara/Graphics/Scene.cpp +++ b/src/Nazara/Graphics/Scene.cpp @@ -29,6 +29,12 @@ void NzScene::AddToVisibilityList(NzUpdatable* object) m_visibleUpdateList.push_back(object); } +void NzScene::Clear() +{ + m_nodeMap.clear(); + m_nodes.clear(); +} + void NzScene::Cull() { #if NAZARA_GRAPHICS_SAFE @@ -48,8 +54,6 @@ void NzScene::Cull() RecursiveFrustumCull(renderQueue, m_viewer->GetFrustum(), &m_root); ///TODO: Occlusion culling - - ///TODO: Light culling } void NzScene::Draw() @@ -77,7 +81,7 @@ void NzScene::Draw() if (m_renderTechniqueRanking > 0) { m_renderTechnique.reset(NzRenderTechniques::GetByRanking(m_renderTechniqueRanking-1, &m_renderTechniqueRanking)); - NazaraError("Render technique \"" + oldName + "\" failed, fallback to \"" + m_renderTechnique->GetName() + '"'); + NazaraError("Render technique \"" + oldName + "\" failed, falling back to \"" + m_renderTechnique->GetName() + '"'); } else { @@ -333,6 +337,25 @@ NzScene::operator const NzSceneNode&() const return m_root; } +bool NzScene::RegisterSceneNode(const NzString& name, NzSceneNode* node) +{ + if (!name.IsEmpty()) + { + if (m_nodeMap.find(name) != m_nodeMap.end()) + { + NazaraError("Node " + name + " is already registred"); + return false; + } + + m_nodeMap[name] = node; + } + + node->SetParent(m_root, true); + + m_nodes.emplace_back(node); + return true; +} + void NzScene::RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node) { for (NzNode* child : node->GetChilds()) From e46cb43ef556d56e4a7bd62616d5eca5ccab08d8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 24 Jan 2015 12:03:24 +0100 Subject: [PATCH 08/13] Removed useless code Former-commit-id: 8e65848eed8c3ceb829a7c556f4686676ea946f4 --- include/Nazara/Graphics/Scene.hpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/Nazara/Graphics/Scene.hpp b/include/Nazara/Graphics/Scene.hpp index 03b37bfc4..e07e3086b 100644 --- a/include/Nazara/Graphics/Scene.hpp +++ b/include/Nazara/Graphics/Scene.hpp @@ -22,17 +22,11 @@ class NzAbstractRenderQueue; class NzAbstractViewer; -class NzCamera; -class NzLight; -class NzModel; class NzNode; -class NzRenderQueue; class NzSceneNode; class NAZARA_API NzScene { - friend NzCamera; - public: NzScene(); ~NzScene() = default; From 090263d847b9fa1ad5af8f91535a576b3dbdd033 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 24 Jan 2015 14:13:11 +0100 Subject: [PATCH 09/13] Moved name attribute from Node to SceneNode Former-commit-id: 6f920af67cd6c339d132a67b364742fdf172d5e9 --- include/Nazara/Graphics/SceneNode.hpp | 7 ++++++- include/Nazara/Utility/Node.hpp | 3 --- src/Nazara/Graphics/SceneNode.cpp | 10 ++++++++++ src/Nazara/Utility/Node.cpp | 11 ----------- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/include/Nazara/Graphics/SceneNode.hpp b/include/Nazara/Graphics/SceneNode.hpp index 0a771a00e..8c99787ad 100644 --- a/include/Nazara/Graphics/SceneNode.hpp +++ b/include/Nazara/Graphics/SceneNode.hpp @@ -18,7 +18,7 @@ class NzScene; class NAZARA_API NzSceneNode : public NzNode { - friend class NzScene; + friend NzScene; public: NzSceneNode(); @@ -39,6 +39,7 @@ class NAZARA_API NzSceneNode : public NzNode NzVector3f GetDown() const; NzVector3f GetForward() const; NzVector3f GetLeft() const; + const NzString& GetName() const; nzNodeType GetNodeType() const final; NzVector3f GetRight() const; NzScene* GetScene() const; @@ -51,6 +52,8 @@ class NAZARA_API NzSceneNode : public NzNode bool IsDrawingEnabled() const; bool IsVisible() const; + void SetName(const NzString& name); + NzSceneNode& operator=(const NzSceneNode& sceneNode); NzSceneNode& operator=(NzSceneNode&& sceneNode) = delete; @@ -75,6 +78,8 @@ class NAZARA_API NzSceneNode : public NzNode private: void UpdateVisibility(const NzFrustumf& frustum); + + NzString m_name; }; #endif // NAZARA_SCENENODE_HPP diff --git a/include/Nazara/Utility/Node.hpp b/include/Nazara/Utility/Node.hpp index 11f9d1f15..44ec8dd84 100644 --- a/include/Nazara/Utility/Node.hpp +++ b/include/Nazara/Utility/Node.hpp @@ -35,7 +35,6 @@ class NAZARA_API NzNode NzQuaternionf GetInitialRotation() const; NzVector3f GetInitialScale() const; virtual NzVector3f GetLeft() const; - const NzString& GetName() const; virtual nzNodeType GetNodeType() const; const NzNode* GetParent() const; NzVector3f GetPosition(nzCoordSys coordSys = nzCoordSys_Global) const; @@ -67,7 +66,6 @@ class NAZARA_API NzNode void SetInitialScale(float scaleX, float scaleY, float scaleZ = 1.f); void SetInitialPosition(const NzVector3f& translation); 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); @@ -103,7 +101,6 @@ class NAZARA_API NzNode mutable NzQuaternionf m_derivedRotation; NzQuaternionf m_initialRotation; NzQuaternionf m_rotation; - NzString m_name; mutable NzVector3f m_derivedPosition; mutable NzVector3f m_derivedScale; NzVector3f m_initialPosition; diff --git a/src/Nazara/Graphics/SceneNode.cpp b/src/Nazara/Graphics/SceneNode.cpp index 29a343531..0c795d956 100644 --- a/src/Nazara/Graphics/SceneNode.cpp +++ b/src/Nazara/Graphics/SceneNode.cpp @@ -93,6 +93,11 @@ NzVector3f NzSceneNode::GetLeft() const return NzNode::GetLeft(); } +const NzString& NzSceneNode::GetName() const +{ + return m_name; +} + nzNodeType NzSceneNode::GetNodeType() const { return nzNodeType_Scene; @@ -139,6 +144,11 @@ bool NzSceneNode::IsVisible() const return m_visible; } +void NzSceneNode::SetName(const NzString& name) +{ + m_name = name; +} + NzSceneNode& NzSceneNode::operator=(const NzSceneNode& sceneNode) { NzNode::operator=(sceneNode); diff --git a/src/Nazara/Utility/Node.cpp b/src/Nazara/Utility/Node.cpp index b9105aece..85a2ca168 100644 --- a/src/Nazara/Utility/Node.cpp +++ b/src/Nazara/Utility/Node.cpp @@ -125,11 +125,6 @@ NzVector3f NzNode::GetLeft() const return m_derivedRotation * NzVector3f::Left(); } -const NzString& NzNode::GetName() const -{ - return m_name; -} - nzNodeType NzNode::GetNodeType() const { return nzNodeType_Default; @@ -413,11 +408,6 @@ void NzNode::SetInitialScale(float scaleX, float scaleY, float scaleZ) InvalidateNode(); } -void NzNode::SetName(const NzString& name) -{ - m_name = name; -} - void NzNode::SetParent(const NzNode* node, bool keepDerived) { #if NAZARA_UTILITY_SAFE @@ -621,7 +611,6 @@ NzNode& NzNode::operator=(const NzNode& node) m_initialPosition = node.m_initialPosition; m_initialRotation = node.m_initialRotation; m_initialScale = node.m_initialScale; - m_name = node.m_name; m_position = node.m_position; m_rotation = node.m_rotation; m_scale = node.m_scale; From 9ebd023848db5f2f311289eb184521e0cc6db46b Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 24 Jan 2015 16:42:49 +0100 Subject: [PATCH 10/13] (SkeletalModel) Added virtual constructor implementation Former-commit-id: 4a7f356e14f629a728a77f94db7e26c6c4af3b72 --- include/Nazara/Graphics/SkeletalModel.hpp | 4 +++- src/Nazara/Graphics/SkeletalModel.cpp | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/SkeletalModel.hpp b/include/Nazara/Graphics/SkeletalModel.hpp index 84c8e0f88..157b3dd1c 100644 --- a/include/Nazara/Graphics/SkeletalModel.hpp +++ b/include/Nazara/Graphics/SkeletalModel.hpp @@ -31,7 +31,6 @@ using NzSkeletalModelLoader = NzResourceLoader Date: Sat, 24 Jan 2015 22:00:55 +0100 Subject: [PATCH 11/13] (Scene) Added FindNode(As) and RemoveNode methods Former-commit-id: 35b0d6a61e99383fffa8048b3c0f6a48b8f0f66c --- include/Nazara/Graphics/Scene.hpp | 8 ++++ include/Nazara/Graphics/Scene.inl | 34 ++++++++++++++- src/Nazara/Graphics/Scene.cpp | 72 +++++++++++++++++++++++++------ 3 files changed, 100 insertions(+), 14 deletions(-) diff --git a/include/Nazara/Graphics/Scene.hpp b/include/Nazara/Graphics/Scene.hpp index e07e3086b..60dd21d43 100644 --- a/include/Nazara/Graphics/Scene.hpp +++ b/include/Nazara/Graphics/Scene.hpp @@ -44,6 +44,11 @@ class NAZARA_API NzScene void EnableBackground(bool enable); + NzSceneNode* FindNode(const NzString& name); + const NzSceneNode* FindNode(const NzString& name) const; + template T* FindNodeAs(const NzString& name); + template const T* FindNodeAs(const NzString& name) const; + NzColor GetAmbientColor() const; NzAbstractBackground* GetBackground() const; NzVector3f GetBackward() const; @@ -63,6 +68,9 @@ class NAZARA_API NzScene void RegisterForUpdate(NzUpdatable* object); + void RemoveNode(NzSceneNode* node); + void RemoveNode(const NzString& name); + void RenderFrame(); void SetAmbientColor(const NzColor& color); diff --git a/include/Nazara/Graphics/Scene.inl b/include/Nazara/Graphics/Scene.inl index 3ac7be7af..2231d1364 100644 --- a/include/Nazara/Graphics/Scene.inl +++ b/include/Nazara/Graphics/Scene.inl @@ -91,7 +91,7 @@ T* NzScene::CreateNode(const NzString& name, const NzString& templateNodeName) } NzSceneNode* sceneNode = it->second; - if (NzImplGetType() != sceneNode->GetSceneNodeType()) + if (sceneNode->GetSceneNodeType() != NzImplGetType()) { NazaraError("Scene node type of T (" + NzString::Number(NzImplGetType()) + ") doesn't match template scene node type (" + NzString::Number(sceneNode->GetSceneNodeType()) + ")"); return nullptr; @@ -104,4 +104,36 @@ T* NzScene::CreateNode(const NzString& name, const NzString& templateNodeName) return node.release(); } +template +T* NzScene::FindNodeAs(const NzString& name) +{ + NzSceneNode* sceneNode = FindNode(name); + if (!sceneNode) + return nullptr; + + if (sceneNode->GetSceneNodeType() != NzImplGetType()) + { + NazaraError("Scene node type of T (" + NzString::Number(NzImplGetType()) + ") doesn't match \"" + name + "\" scene node type (" + NzString::Number(sceneNode->GetSceneNodeType()) + ")"); + return nullptr; + } + + return static_cast(sceneNode); +} + +template +const T* NzScene::FindNodeAs(const NzString& name) const +{ + const NzSceneNode* sceneNode = FindNode(name); + if (!sceneNode) + return nullptr; + + if (sceneNode->GetSceneNodeType() != NzImplGetType()) + { + NazaraError("Scene node type of T (" + NzString::Number(NzImplGetType()) + ") doesn't match \"" + name + "\" scene node type (" + NzString::Number(sceneNode->GetSceneNodeType()) + ")"); + return nullptr; + } + + return static_cast(sceneNode); +} + #include diff --git a/src/Nazara/Graphics/Scene.cpp b/src/Nazara/Graphics/Scene.cpp index 4b86cdda5..55c2165fe 100644 --- a/src/Nazara/Graphics/Scene.cpp +++ b/src/Nazara/Graphics/Scene.cpp @@ -98,6 +98,24 @@ void NzScene::EnableBackground(bool enable) m_backgroundEnabled = enable; } +NzSceneNode* NzScene::FindNode(const NzString& name) +{ + auto it = m_nodeMap.find(name); + if (it == m_nodeMap.end()) + return nullptr; + + return it->second; +} + +const NzSceneNode* NzScene::FindNode(const NzString& name) const +{ + auto it = m_nodeMap.find(name); + if (it == m_nodeMap.end()) + return nullptr; + + return it->second; +} + NzColor NzScene::GetAmbientColor() const { return m_ambientColor; @@ -227,6 +245,47 @@ bool NzScene::IsBackgroundEnabled() const return m_backgroundEnabled; } +void NzScene::RegisterForUpdate(NzUpdatable* object) +{ + #if NAZARA_GRAPHICS_SAFE + if (!object) + { + NazaraError("Invalid object"); + return; + } + #endif + + m_updateList.push_back(object); +} + +void NzScene::RemoveNode(NzSceneNode* node) +{ + if (!node) + return; + + // C'est moche mais je n'ai pas d'autre choix que d'utiliser un std::unique_ptr pour utiliser std::find + std::unique_ptr ptr(node); + auto it = std::find(m_nodes.begin(), m_nodes.end(), ptr); + ptr.release(); + + if (it == m_nodes.end()) + { + NazaraError("This scene node doesn't belong to this scene"); + return; + } + + NzString nodeName = node->GetName(); + if (!nodeName.IsEmpty()) + m_nodeMap.erase(nodeName); + + m_nodes.erase(it); +} + +void NzScene::RemoveNode(const NzString& name) +{ + RemoveNode(FindNode(name)); +} + void NzScene::RenderFrame() { try @@ -243,19 +302,6 @@ void NzScene::RenderFrame() } } -void NzScene::RegisterForUpdate(NzUpdatable* object) -{ - #if NAZARA_GRAPHICS_SAFE - if (!object) - { - NazaraError("Invalid object"); - return; - } - #endif - - m_updateList.push_back(object); -} - void NzScene::SetAmbientColor(const NzColor& color) { m_ambientColor = color; From bc6dd440099a04aefac61f84d6797e40bba08d73 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 25 Jan 2015 16:34:19 +0100 Subject: [PATCH 12/13] Made SceneNode name change reflect on the Scene Former-commit-id: b924b0b9d103e4fce6ab2faf952b9153d49cce06 --- include/Nazara/Graphics/Scene.hpp | 3 +++ include/Nazara/Graphics/SceneNode.hpp | 3 ++- src/Nazara/Graphics/Scene.cpp | 33 +++++++++++++++++++++++++++ src/Nazara/Graphics/SceneNode.cpp | 17 ++++++++++++-- 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Graphics/Scene.hpp b/include/Nazara/Graphics/Scene.hpp index 60dd21d43..b0e51575d 100644 --- a/include/Nazara/Graphics/Scene.hpp +++ b/include/Nazara/Graphics/Scene.hpp @@ -27,6 +27,8 @@ class NzSceneNode; class NAZARA_API NzScene { + friend NzSceneNode; + public: NzScene(); ~NzScene() = default; @@ -88,6 +90,7 @@ class NAZARA_API NzScene operator const NzSceneNode&() const; private: + bool ChangeNodeName(NzSceneNode* node, const NzString& newName); bool RegisterSceneNode(const NzString& name, NzSceneNode* node); void RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node); diff --git a/include/Nazara/Graphics/SceneNode.hpp b/include/Nazara/Graphics/SceneNode.hpp index 8c99787ad..b695a5d57 100644 --- a/include/Nazara/Graphics/SceneNode.hpp +++ b/include/Nazara/Graphics/SceneNode.hpp @@ -52,7 +52,7 @@ class NAZARA_API NzSceneNode : public NzNode bool IsDrawingEnabled() const; bool IsVisible() const; - void SetName(const NzString& name); + bool SetName(const NzString& name); NzSceneNode& operator=(const NzSceneNode& sceneNode); NzSceneNode& operator=(NzSceneNode&& sceneNode) = delete; @@ -65,6 +65,7 @@ class NAZARA_API NzSceneNode : public NzNode virtual void OnVisibilityChange(bool visibility); void RecursiveSetScene(NzScene* scene, NzNode* node); virtual void Register(); + void SetNameInternal(const NzString& name); void SetScene(NzScene* scene); virtual void Unregister(); virtual void Update(); diff --git a/src/Nazara/Graphics/Scene.cpp b/src/Nazara/Graphics/Scene.cpp index 55c2165fe..d40344810 100644 --- a/src/Nazara/Graphics/Scene.cpp +++ b/src/Nazara/Graphics/Scene.cpp @@ -383,6 +383,38 @@ NzScene::operator const NzSceneNode&() const return m_root; } +bool NzScene::ChangeNodeName(NzSceneNode* node, const NzString& newName) +{ + #ifdef NAZARA_DEBUG + std::unique_ptr ptr(node); + auto it = std::find(m_nodes.begin(), m_nodes.end(), ptr); + ptr.release(); + + if (it == m_nodes.end()) + { + NazaraInternalError("Node isn't part of the scene"); + return false; + } + #endif + + if (!newName.IsEmpty()) + { + auto pair = m_nodeMap.insert(std::make_pair(newName, node)); + if (!pair.second) + { + NazaraError("Name \"" + newName + "\" is already in use"); + return false; + } + } + + NzString oldName = node->GetName(); + if (!oldName.IsEmpty()) + m_nodeMap.erase(oldName); + + node->SetNameInternal(newName); + return true; +} + bool NzScene::RegisterSceneNode(const NzString& name, NzSceneNode* node) { if (!name.IsEmpty()) @@ -396,6 +428,7 @@ bool NzScene::RegisterSceneNode(const NzString& name, NzSceneNode* node) m_nodeMap[name] = node; } + node->SetNameInternal(name); node->SetParent(m_root, true); m_nodes.emplace_back(node); diff --git a/src/Nazara/Graphics/SceneNode.cpp b/src/Nazara/Graphics/SceneNode.cpp index 0c795d956..bace91038 100644 --- a/src/Nazara/Graphics/SceneNode.cpp +++ b/src/Nazara/Graphics/SceneNode.cpp @@ -144,9 +144,17 @@ bool NzSceneNode::IsVisible() const return m_visible; } -void NzSceneNode::SetName(const NzString& name) +bool NzSceneNode::SetName(const NzString& name) { - m_name = name; + if (m_scene) + // On demande à la scène de changer notre nom + return m_scene->ChangeNodeName(this, name); + else + { + // Pas de scène ? Changeons notre nom nous-même + SetNameInternal(name); + return true; + } } NzSceneNode& NzSceneNode::operator=(const NzSceneNode& sceneNode) @@ -211,6 +219,11 @@ void NzSceneNode::Register() { } +void NzSceneNode::SetNameInternal(const NzString& name) +{ + m_name = name; +} + void NzSceneNode::SetScene(NzScene* scene) { if (m_scene != scene) From 4a2f386c8010ebab069d59ba0d50270fef354bfb Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 25 Jan 2015 16:34:34 +0100 Subject: [PATCH 13/13] (Drawable) Made destructor virtual Former-commit-id: ab35592cf015a3056de5d533b29d3c469cb29d29 --- include/Nazara/Graphics/Drawable.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/Drawable.hpp b/include/Nazara/Graphics/Drawable.hpp index 97841eebb..3c45939df 100644 --- a/include/Nazara/Graphics/Drawable.hpp +++ b/include/Nazara/Graphics/Drawable.hpp @@ -13,7 +13,7 @@ class NAZARA_API NzDrawable { public: NzDrawable() = default; - ~NzDrawable(); + virtual ~NzDrawable(); virtual void Draw() const = 0; };