Merge remote-tracking branch 'origin/Scene-Update'

Former-commit-id: 4185e7a826476d3d5b4275b3900fe695bd791f3a
This commit is contained in:
Lynix 2015-01-25 16:35:18 +01:00
commit a185f03abc
26 changed files with 620 additions and 354 deletions

View File

@ -84,7 +84,7 @@ int main()
// Ensuite, nous allons rajouter un modèle à notre scène. // Ensuite, nous allons rajouter un modèle à notre scène.
// Les modèles représentent, globalement, tout ce qui est visible en trois dimensions. // 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 ?) // Nous choisirons ici un vaisseau spatial (Quoi de mieux pour une scène spatiale ?)
NzModel spaceship; NzModel* spaceship = scene.CreateNode<NzModel>(); // Création depuis la scène
// Une structure permettant de paramétrer le chargement des modèles // Une structure permettant de paramétrer le chargement des modèles
NzModelParameters params; NzModelParameters params;
@ -101,7 +101,7 @@ int main()
// On charge ensuite le modèle depuis son fichier // 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, ...) // 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::cout << "Failed to load spaceship" << std::endl;
std::getchar(); 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 // 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) // 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->GetVertexCount() << " sommets" << std::endl;
std::cout << mesh->GetTriangleCount() << " triangles" << 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 // 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, // 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) // 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 // On lui indique ensuite le chemin vers la normal map
if (!material->SetNormalMap("resources/Spaceship/Texture/normal.png")) if (!material->SetNormalMap("resources/Spaceship/Texture/normal.png"))
@ -129,10 +129,6 @@ int main()
std::cout << "Failed to load normal map" << std::endl; 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 // Nous avons besoin également d'une caméra, pour des raisons évidentes, celle-ci sera à l'écart du modèle
// regardant dans sa direction. // 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 // -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 // -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 // Nous créons une lumière directionnelle pour représenter la nébuleuse de notre skybox
NzLight nebulaLight(nzLightType_Directional); NzLight* nebulaLight = scene.CreateNode<NzLight>(nzLightType_Directional);
// Il nous faut ensuite configurer la lumière // 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 // 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 // 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)); nebulaLight->SetRotation(NzEulerAnglesf(0.f, 102.f, 0.f));
// Et nous ajoutons la lumière à la scène
nebulaLight.SetParent(scene);
// Nous allons maintenant créer la fenêtre, dans laquelle nous ferons nos rendus // Nous allons maintenant créer la fenêtre, dans laquelle nous ferons nos rendus
// Celle-ci demande des paramètres plus complexes // Celle-ci demande des paramètres plus complexes

View File

@ -9,12 +9,12 @@
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Graphics/AbstractViewer.hpp> #include <Nazara/Graphics/AbstractViewer.hpp>
#include <Nazara/Graphics/SceneNode.hpp>
#include <Nazara/Math/Frustum.hpp> #include <Nazara/Math/Frustum.hpp>
#include <Nazara/Math/Matrix4.hpp> #include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Math/Rect.hpp> #include <Nazara/Math/Rect.hpp>
#include <Nazara/Math/Vector3.hpp> #include <Nazara/Math/Vector3.hpp>
#include <Nazara/Renderer/RenderTarget.hpp> #include <Nazara/Renderer/RenderTarget.hpp>
#include <Nazara/Utility/Node.hpp>
class NAZARA_API NzCamera : public NzAbstractViewer, public NzNode, NzRenderTarget::Listener class NAZARA_API NzCamera : public NzAbstractViewer, public NzNode, NzRenderTarget::Listener
{ {

View File

@ -18,17 +18,19 @@ struct NzLightUniforms;
class NAZARA_API NzLight : public NzSceneNode class NAZARA_API NzLight : public NzSceneNode
{ {
public: public:
NzLight(nzLightType type); NzLight(nzLightType type = nzLightType_Point);
NzLight(const NzLight& light); NzLight(const NzLight& light);
~NzLight() = default; ~NzLight() = default;
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override;
NzLight* Clone() const;
NzLight* Create() const;
void Enable(const NzShader* shader, const NzLightUniforms& uniforms, int offset = 0) const; void Enable(const NzShader* shader, const NzLightUniforms& uniforms, int offset = 0) const;
float GetAmbientFactor() const; float GetAmbientFactor() const;
float GetAttenuation() const; float GetAttenuation() const;
const NzBoundingVolumef& GetBoundingVolume() const;
NzColor GetColor() const; NzColor GetColor() const;
float GetDiffuseFactor() const; float GetDiffuseFactor() const;
float GetInnerAngle() const; float GetInnerAngle() const;
@ -54,15 +56,13 @@ class NAZARA_API NzLight : public NzSceneNode
private: private:
bool FrustumCull(const NzFrustumf& frustum) const override; bool FrustumCull(const NzFrustumf& frustum) const override;
void InvalidateNode() override; void MakeBoundingVolume() const override;
void Register() override; void Register() override;
void Unregister() override; void Unregister() override;
void UpdateBoundingVolume() const; void UpdateBoundingVolume() const;
nzLightType m_type; nzLightType m_type;
mutable NzBoundingVolumef m_boundingVolume;
NzColor m_color; NzColor m_color;
mutable bool m_boundingVolumeUpdated;
float m_ambientFactor; float m_ambientFactor;
float m_attenuation; float m_attenuation;
float m_diffuseFactor; float m_diffuseFactor;

View File

@ -41,10 +41,12 @@ class NAZARA_API NzModel : public NzSceneNode
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override;
void AdvanceAnimation(float elapsedTime); void AdvanceAnimation(float elapsedTime);
NzModel* Clone() const;
NzModel* Create() const;
void EnableAnimation(bool animation); void EnableAnimation(bool animation);
NzAnimation* GetAnimation() const; NzAnimation* GetAnimation() const;
const NzBoundingVolumef& GetBoundingVolume() const;
NzMaterial* GetMaterial(const NzString& subMeshName) const; NzMaterial* GetMaterial(const NzString& subMeshName) const;
NzMaterial* GetMaterial(unsigned int matIndex) const; NzMaterial* GetMaterial(unsigned int matIndex) const;
NzMaterial* GetMaterial(unsigned int skinIndex, const NzString& subMeshName) const; NzMaterial* GetMaterial(unsigned int skinIndex, const NzString& subMeshName) const;
@ -84,13 +86,10 @@ class NAZARA_API NzModel : public NzSceneNode
NzModel& operator=(const NzModel& node); NzModel& operator=(const NzModel& node);
protected: protected:
void InvalidateNode() override; void MakeBoundingVolume() const override;
virtual void UpdateBoundingVolume() const;
std::vector<NzMaterialRef> m_materials; std::vector<NzMaterialRef> m_materials;
mutable NzBoundingVolumef m_boundingVolume;
NzMeshRef m_mesh; NzMeshRef m_mesh;
mutable bool m_boundingVolumeUpdated;
unsigned int m_matCount; unsigned int m_matCount;
unsigned int m_skin; unsigned int m_skin;
unsigned int m_skinCount; unsigned int m_skinCount;

View File

@ -43,7 +43,6 @@ class NAZARA_API NzParticleSystem : public NzSceneNode, NzUpdatable
void* GenerateParticle(); void* GenerateParticle();
void* GenerateParticles(unsigned int count); void* GenerateParticles(unsigned int count);
const NzBoundingVolumef& GetBoundingVolume() const override;
const NzParticleDeclaration* GetDeclaration() const; const NzParticleDeclaration* GetDeclaration() const;
float GetFixedStepSize() const; float GetFixedStepSize() const;
unsigned int GetMaxParticleCount() const; unsigned int GetMaxParticleCount() const;
@ -67,22 +66,19 @@ class NAZARA_API NzParticleSystem : public NzSceneNode, NzUpdatable
NzParticleSystem& operator=(const NzParticleSystem& emitter); NzParticleSystem& operator=(const NzParticleSystem& emitter);
private: private:
void GenerateAABB() const; void MakeBoundingVolume() const override;
void Register() override; void Register() override;
void ResizeBuffer(); void ResizeBuffer();
void Unregister() override; void Unregister() override;
void Update() override; void Update() override;
void UpdateBoundingVolume() const;
std::set<unsigned int, std::greater<unsigned int>> m_dyingParticles; std::set<unsigned int, std::greater<unsigned int>> m_dyingParticles;
mutable std::vector<nzUInt8> m_buffer; mutable std::vector<nzUInt8> m_buffer;
std::vector<NzParticleControllerRef> m_controllers; std::vector<NzParticleControllerRef> m_controllers;
std::vector<NzParticleEmitter*> m_emitters; std::vector<NzParticleEmitter*> m_emitters;
std::vector<NzParticleGeneratorRef> m_generators; std::vector<NzParticleGeneratorRef> m_generators;
mutable NzBoundingVolumef m_boundingVolume;
NzParticleDeclarationConstRef m_declaration; NzParticleDeclarationConstRef m_declaration;
NzParticleRendererRef m_renderer; NzParticleRendererRef m_renderer;
mutable bool m_boundingVolumeUpdated;
bool m_fixedStepEnabled; bool m_fixedStepEnabled;
bool m_processing; bool m_processing;
float m_stepAccumulator; float m_stepAccumulator;

View File

@ -8,37 +8,49 @@
#define NAZARA_SCENE_HPP #define NAZARA_SCENE_HPP
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Core/Color.hpp> #include <Nazara/Core/Color.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Core/Updatable.hpp> #include <Nazara/Core/Updatable.hpp>
#include <Nazara/Graphics/AbstractBackground.hpp> #include <Nazara/Graphics/AbstractBackground.hpp>
#include <Nazara/Graphics/AbstractRenderTechnique.hpp> #include <Nazara/Graphics/AbstractRenderTechnique.hpp>
#include <Nazara/Graphics/SceneRoot.hpp>
#include <Nazara/Math/Frustum.hpp> #include <Nazara/Math/Frustum.hpp>
#include <memory>
#include <unordered_map>
#include <vector>
class NzAbstractRenderQueue; class NzAbstractRenderQueue;
class NzAbstractViewer; class NzAbstractViewer;
class NzCamera;
class NzLight;
class NzModel;
class NzNode; class NzNode;
class NzRenderQueue;
class NzSceneNode; class NzSceneNode;
struct NzSceneImpl;
class NAZARA_API NzScene class NAZARA_API NzScene
{ {
friend NzCamera; friend NzSceneNode;
public: public:
NzScene(); NzScene();
~NzScene(); ~NzScene() = default;
void AddToVisibilityList(NzUpdatable* object); void AddToVisibilityList(NzUpdatable* object);
template<typename T, typename... Args> T* CreateNode(Args&&... args);
template<typename T, typename... Args> T* CreateNode(const NzString& name, Args&&... args);
template<typename T, typename... Args> T* CreateNode(const NzString& name, const NzString& templateNodeName);
void Clear();
void Cull(); void Cull();
void Draw(); void Draw();
void EnableBackground(bool enable); void EnableBackground(bool enable);
NzSceneNode* FindNode(const NzString& name);
const NzSceneNode* FindNode(const NzString& name) const;
template<typename T> T* FindNodeAs(const NzString& name);
template<typename T> const T* FindNodeAs(const NzString& name) const;
NzColor GetAmbientColor() const; NzColor GetAmbientColor() const;
NzAbstractBackground* GetBackground() const; NzAbstractBackground* GetBackground() const;
NzVector3f GetBackward() const; NzVector3f GetBackward() const;
@ -47,7 +59,8 @@ class NAZARA_API NzScene
NzVector3f GetLeft() const; NzVector3f GetLeft() const;
NzAbstractRenderTechnique* GetRenderTechnique() const; NzAbstractRenderTechnique* GetRenderTechnique() const;
NzVector3f GetRight() const; NzVector3f GetRight() const;
NzSceneNode& GetRoot() const; NzSceneNode& GetRoot();
const NzSceneNode& GetRoot() const;
NzAbstractViewer* GetViewer() const; NzAbstractViewer* GetViewer() const;
NzVector3f GetUp() const; NzVector3f GetUp() const;
float GetUpdateTime() const; float GetUpdateTime() const;
@ -57,6 +70,11 @@ class NAZARA_API NzScene
void RegisterForUpdate(NzUpdatable* object); void RegisterForUpdate(NzUpdatable* object);
void RemoveNode(NzSceneNode* node);
void RemoveNode(const NzString& name);
void RenderFrame();
void SetAmbientColor(const NzColor& color); void SetAmbientColor(const NzColor& color);
void SetBackground(NzAbstractBackground* background); void SetBackground(NzAbstractBackground* background);
void SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique); void SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique);
@ -72,9 +90,28 @@ class NAZARA_API NzScene
operator const NzSceneNode&() const; operator const NzSceneNode&() const;
private: private:
bool ChangeNodeName(NzSceneNode* node, const NzString& newName);
bool RegisterSceneNode(const NzString& name, NzSceneNode* node);
void RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node); void RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node);
NzSceneImpl* m_impl; mutable std::unique_ptr<NzAbstractBackground> m_background;
mutable std::unique_ptr<NzAbstractRenderTechnique> m_renderTechnique;
std::unordered_map<NzString, NzSceneNode*> m_nodeMap;
std::vector<std::unique_ptr<NzSceneNode>> m_nodes;
std::vector<NzUpdatable*> m_updateList;
std::vector<NzUpdatable*> 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;
}; };
#include <Nazara/Graphics/Scene.inl>
#endif // NAZARA_SCENE_HPP #endif // NAZARA_SCENE_HPP

View File

@ -0,0 +1,139 @@
// 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 <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/Debug.hpp>
///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<typename T>
constexpr nzSceneNodeType NzImplGetType()
{
return nzSceneNodeType_User;
}
template<>
inline constexpr nzSceneNodeType NzImplGetType<NzLight>()
{
return nzSceneNodeType_Light;
}
template<>
inline constexpr nzSceneNodeType NzImplGetType<NzModel>()
{
return nzSceneNodeType_Model;
}
template<>
inline constexpr nzSceneNodeType NzImplGetType<NzParticleEmitter>()
{
return nzSceneNodeType_ParticleEmitter;
}
template<>
inline constexpr nzSceneNodeType NzImplGetType<NzSceneRoot>()
{
return nzSceneNodeType_Root;
}
template<>
inline constexpr nzSceneNodeType NzImplGetType<NzSprite>()
{
return nzSceneNodeType_Sprite;
}
template<>
inline constexpr nzSceneNodeType NzImplGetType<NzTextSprite>()
{
return nzSceneNodeType_TextSprite;
}
template<typename T, typename... Args>
T* NzScene::CreateNode(Args&&... args)
{
std::unique_ptr<T> node(new T(std::forward<Args>(args)...));
if (!RegisterSceneNode(NzString(), node.get()))
return nullptr;
return node.release();
}
template<typename T, typename... Args>
T* NzScene::CreateNode(const NzString& name, Args&&... args)
{
std::unique_ptr<T> node(new T(std::forward<Args>(args)...));
if (!RegisterSceneNode(name, node.get()))
return nullptr;
return node.release();
}
template<typename T, typename... Args>
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 (sceneNode->GetSceneNodeType() != NzImplGetType<T>())
{
NazaraError("Scene node type of T (" + NzString::Number(NzImplGetType<T>()) + ") doesn't match template scene node type (" + NzString::Number(sceneNode->GetSceneNodeType()) + ")");
return nullptr;
}
std::unique_ptr<T> node(static_cast<T*>(sceneNode)->Copy());
if (!RegisterSceneNode(name, node.get()))
return nullptr;
return node.release();
}
template<typename T>
T* NzScene::FindNodeAs(const NzString& name)
{
NzSceneNode* sceneNode = FindNode(name);
if (!sceneNode)
return nullptr;
if (sceneNode->GetSceneNodeType() != NzImplGetType<T>())
{
NazaraError("Scene node type of T (" + NzString::Number(NzImplGetType<T>()) + ") doesn't match \"" + name + "\" scene node type (" + NzString::Number(sceneNode->GetSceneNodeType()) + ")");
return nullptr;
}
return static_cast<T*>(sceneNode);
}
template<typename T>
const T* NzScene::FindNodeAs(const NzString& name) const
{
const NzSceneNode* sceneNode = FindNode(name);
if (!sceneNode)
return nullptr;
if (sceneNode->GetSceneNodeType() != NzImplGetType<T>())
{
NazaraError("Scene node type of T (" + NzString::Number(NzImplGetType<T>()) + ") doesn't match \"" + name + "\" scene node type (" + NzString::Number(sceneNode->GetSceneNodeType()) + ")");
return nullptr;
}
return static_cast<const T*>(sceneNode);
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -9,14 +9,16 @@
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Graphics/Enums.hpp> #include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/Scene.hpp>
#include <Nazara/Math/BoundingVolume.hpp> #include <Nazara/Math/BoundingVolume.hpp>
#include <Nazara/Math/Frustum.hpp> #include <Nazara/Math/Frustum.hpp>
#include <Nazara/Utility/Node.hpp> #include <Nazara/Utility/Node.hpp>
class NzAbstractRenderQueue;
class NzScene;
class NAZARA_API NzSceneNode : public NzNode class NAZARA_API NzSceneNode : public NzNode
{ {
friend class NzScene; friend NzScene;
public: public:
NzSceneNode(); NzSceneNode();
@ -26,42 +28,59 @@ class NAZARA_API NzSceneNode : public NzNode
virtual void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const = 0; 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); void EnableDrawing(bool drawingEnabled);
NzVector3f GetBackward() const; NzVector3f GetBackward() const;
virtual const NzBoundingVolumef& GetBoundingVolume() const = 0; virtual const NzBoundingVolumef& GetBoundingVolume() const;
NzVector3f GetDown() const; NzVector3f GetDown() const;
NzVector3f GetForward() const; NzVector3f GetForward() const;
NzVector3f GetLeft() const; NzVector3f GetLeft() const;
const NzString& GetName() const;
nzNodeType GetNodeType() const final; nzNodeType GetNodeType() const final;
NzVector3f GetRight() const; NzVector3f GetRight() const;
NzScene* GetScene() const; NzScene* GetScene() const;
virtual nzSceneNodeType GetSceneNodeType() const = 0; virtual nzSceneNodeType GetSceneNodeType() const = 0;
NzVector3f GetUp() const; NzVector3f GetUp() const;
void InvalidateAABB();
virtual bool IsDrawable() const = 0; virtual bool IsDrawable() const = 0;
bool IsDrawingEnabled() const; bool IsDrawingEnabled() const;
bool IsVisible() const; bool IsVisible() const;
bool SetName(const NzString& name);
NzSceneNode& operator=(const NzSceneNode& sceneNode); NzSceneNode& operator=(const NzSceneNode& sceneNode);
NzSceneNode& operator=(NzSceneNode&& sceneNode) = delete; NzSceneNode& operator=(NzSceneNode&& sceneNode) = delete;
protected: protected:
virtual bool FrustumCull(const NzFrustumf& frustum) const; 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 OnParenting(const NzNode* parent) override;
virtual void OnVisibilityChange(bool visibility); virtual void OnVisibilityChange(bool visibility);
void RecursiveSetScene(NzScene* scene, NzNode* node); void RecursiveSetScene(NzScene* scene, NzNode* node);
virtual void Register(); virtual void Register();
void SetNameInternal(const NzString& name);
void SetScene(NzScene* scene); void SetScene(NzScene* scene);
virtual void Unregister(); virtual void Unregister();
virtual void Update(); virtual void Update();
virtual void UpdateBoundingVolume() const;
mutable NzBoundingVolumef m_boundingVolume;
NzScene* m_scene; NzScene* m_scene;
mutable bool m_boundingVolumeUpdated;
bool m_drawingEnabled; bool m_drawingEnabled;
bool m_visible; bool m_visible;
private: private:
void UpdateVisibility(const NzFrustumf& frustum); void UpdateVisibility(const NzFrustumf& frustum);
NzString m_name;
}; };
#endif // NAZARA_SCENENODE_HPP #endif // NAZARA_SCENENODE_HPP

View File

@ -10,14 +10,15 @@
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Graphics/SceneNode.hpp> #include <Nazara/Graphics/SceneNode.hpp>
class NzScene;
class NAZARA_API NzSceneRoot : public NzSceneNode class NAZARA_API NzSceneRoot : public NzSceneNode
{ {
friend struct NzSceneImpl; friend NzScene;
public: public:
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override;
const NzBoundingVolumef& GetBoundingVolume() const override;
nzSceneNodeType GetSceneNodeType() const override; nzSceneNodeType GetSceneNodeType() const override;
bool IsDrawable() const; bool IsDrawable() const;
@ -26,6 +27,10 @@ class NAZARA_API NzSceneRoot : public NzSceneNode
NzSceneRoot(NzScene* scene); NzSceneRoot(NzScene* scene);
virtual ~NzSceneRoot(); virtual ~NzSceneRoot();
NzSceneRoot* Clone() const;
NzSceneRoot* Create() const;
void MakeBoundingVolume() const override;
void Register(); void Register();
void Unregister(); void Unregister();
}; };

View File

@ -31,7 +31,6 @@ using NzSkeletalModelLoader = NzResourceLoader<NzSkeletalModel, NzSkeletalModelP
class NAZARA_API NzSkeletalModel : public NzModel, NzUpdatable class NAZARA_API NzSkeletalModel : public NzModel, NzUpdatable
{ {
friend NzSkeletalModelLoader; friend NzSkeletalModelLoader;
//friend class NzScene;
public: public:
NzSkeletalModel(); NzSkeletalModel();
@ -42,6 +41,9 @@ class NAZARA_API NzSkeletalModel : public NzModel, NzUpdatable
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override;
void AdvanceAnimation(float elapsedTime); void AdvanceAnimation(float elapsedTime);
NzSkeletalModel* Clone() const;
NzSkeletalModel* Create() const;
void EnableAnimation(bool animation); void EnableAnimation(bool animation);
NzAnimation* GetAnimation() const; NzAnimation* GetAnimation() const;
@ -69,10 +71,10 @@ class NAZARA_API NzSkeletalModel : public NzModel, NzUpdatable
NzSkeletalModel& operator=(NzSkeletalModel&& node); NzSkeletalModel& operator=(NzSkeletalModel&& node);
private: private:
void MakeBoundingVolume() const override;
void Register() override; void Register() override;
void Unregister() override; void Unregister() override;
void Update() override; void Update() override;
void UpdateBoundingVolume() const;
NzAnimationRef m_animation; NzAnimationRef m_animation;
NzSkeleton m_skeleton; NzSkeleton m_skeleton;

View File

@ -22,7 +22,9 @@ class NAZARA_API NzSprite : public NzSceneNode
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override;
const NzBoundingVolumef& GetBoundingVolume() const override; NzSprite* Clone() const;
NzSprite* Create() const;
const NzColor& GetColor() const; const NzColor& GetColor() const;
NzMaterial* GetMaterial() const; NzMaterial* GetMaterial() const;
nzSceneNodeType GetSceneNodeType() const override; nzSceneNodeType GetSceneNodeType() const override;
@ -44,18 +46,16 @@ class NAZARA_API NzSprite : public NzSceneNode
private: private:
void InvalidateNode() override; void InvalidateNode() override;
void MakeBoundingVolume() const override;
void Register() override; void Register() override;
void Unregister() override; void Unregister() override;
void UpdateBoundingVolume() const;
void UpdateVertices() const; void UpdateVertices() const;
mutable NzBoundingVolumef m_boundingVolume;
NzColor m_color; NzColor m_color;
NzMaterialRef m_material; NzMaterialRef m_material;
NzRectf m_textureCoords; NzRectf m_textureCoords;
NzVector2f m_size; NzVector2f m_size;
mutable NzVertexStruct_XYZ_Color_UV m_vertices[4]; mutable NzVertexStruct_XYZ_Color_UV m_vertices[4];
mutable bool m_boundingVolumeUpdated;
mutable bool m_verticesUpdated; mutable bool m_verticesUpdated;
}; };

View File

@ -28,7 +28,9 @@ class NAZARA_API NzTextSprite : public NzSceneNode, NzAbstractAtlas::Listener
void Clear(); void Clear();
const NzBoundingVolumef& GetBoundingVolume() const override; NzTextSprite* Clone() const;
NzTextSprite* Create() const;
const NzColor& GetColor() const; const NzColor& GetColor() const;
NzMaterial* GetMaterial() const; NzMaterial* GetMaterial() const;
nzSceneNodeType GetSceneNodeType() const override; nzSceneNodeType GetSceneNodeType() const override;
@ -47,12 +49,12 @@ class NAZARA_API NzTextSprite : public NzSceneNode, NzAbstractAtlas::Listener
private: private:
void ClearAtlases(); void ClearAtlases();
void InvalidateNode() override; void InvalidateNode() override;
void MakeBoundingVolume() const override;
bool OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata) override; bool OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata) override;
bool OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractImage* oldLayer, NzAbstractImage* newLayer, void* userdata) override; bool OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractImage* oldLayer, NzAbstractImage* newLayer, void* userdata) override;
void OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata) override; void OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata) override;
void Register() override; void Register() override;
void Unregister() override; void Unregister() override;
void UpdateBoundingVolume() const;
void UpdateVertices() const; void UpdateVertices() const;
struct RenderIndices struct RenderIndices
@ -65,11 +67,9 @@ class NAZARA_API NzTextSprite : public NzSceneNode, NzAbstractAtlas::Listener
mutable std::unordered_map<NzTexture*, RenderIndices> m_renderInfos; mutable std::unordered_map<NzTexture*, RenderIndices> m_renderInfos;
mutable std::vector<NzVertexStruct_XY_Color> m_localVertices; mutable std::vector<NzVertexStruct_XY_Color> m_localVertices;
mutable std::vector<NzVertexStruct_XYZ_Color_UV> m_vertices; mutable std::vector<NzVertexStruct_XYZ_Color_UV> m_vertices;
mutable NzBoundingVolumef m_boundingVolume;
NzColor m_color; NzColor m_color;
NzMaterialRef m_material; NzMaterialRef m_material;
NzRectui m_localBounds; NzRectui m_localBounds;
mutable bool m_boundingVolumeUpdated;
mutable bool m_verticesUpdated; mutable bool m_verticesUpdated;
}; };

View File

@ -9,12 +9,12 @@
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Graphics/AbstractViewer.hpp> #include <Nazara/Graphics/AbstractViewer.hpp>
#include <Nazara/Graphics/SceneNode.hpp>
#include <Nazara/Math/Frustum.hpp> #include <Nazara/Math/Frustum.hpp>
#include <Nazara/Math/Matrix4.hpp> #include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Math/Rect.hpp> #include <Nazara/Math/Rect.hpp>
#include <Nazara/Math/Vector3.hpp> #include <Nazara/Math/Vector3.hpp>
#include <Nazara/Renderer/RenderTarget.hpp> #include <Nazara/Renderer/RenderTarget.hpp>
#include <Nazara/Utility/Node.hpp>
class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget::Listener class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget::Listener
{ {

View File

@ -35,7 +35,6 @@ class NAZARA_API NzNode
NzQuaternionf GetInitialRotation() const; NzQuaternionf GetInitialRotation() const;
NzVector3f GetInitialScale() const; NzVector3f GetInitialScale() const;
virtual NzVector3f GetLeft() const; virtual NzVector3f GetLeft() const;
const NzString& GetName() const;
virtual nzNodeType GetNodeType() const; virtual nzNodeType GetNodeType() const;
const NzNode* GetParent() const; const NzNode* GetParent() const;
NzVector3f GetPosition(nzCoordSys coordSys = nzCoordSys_Global) 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 SetInitialScale(float scaleX, float scaleY, float scaleZ = 1.f);
void SetInitialPosition(const NzVector3f& translation); void SetInitialPosition(const NzVector3f& translation);
void SetInitialPosition(float translationX, float translationXY, float translationZ = 0.f); 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 = nullptr, bool keepDerived = false);
void SetParent(const NzNode& node, bool keepDerived = false); void SetParent(const NzNode& node, bool keepDerived = false);
void SetPosition(const NzVector3f& translation, nzCoordSys coordSys = nzCoordSys_Local); void SetPosition(const NzVector3f& translation, nzCoordSys coordSys = nzCoordSys_Local);
@ -103,7 +101,6 @@ class NAZARA_API NzNode
mutable NzQuaternionf m_derivedRotation; mutable NzQuaternionf m_derivedRotation;
NzQuaternionf m_initialRotation; NzQuaternionf m_initialRotation;
NzQuaternionf m_rotation; NzQuaternionf m_rotation;
NzString m_name;
mutable NzVector3f m_derivedPosition; mutable NzVector3f m_derivedPosition;
mutable NzVector3f m_derivedScale; mutable NzVector3f m_derivedScale;
NzVector3f m_initialPosition; NzVector3f m_initialPosition;

View File

@ -21,6 +21,7 @@
#include <Nazara/Graphics/Drawable.hpp> #include <Nazara/Graphics/Drawable.hpp>
#include <Nazara/Graphics/Light.hpp> #include <Nazara/Graphics/Light.hpp>
#include <Nazara/Graphics/Material.hpp> #include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/Scene.hpp>
#include <Nazara/Graphics/Sprite.hpp> #include <Nazara/Graphics/Sprite.hpp>
#include <Nazara/Renderer/Config.hpp> #include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/OpenGL.hpp> #include <Nazara/Renderer/OpenGL.hpp>

View File

@ -10,6 +10,7 @@
#include <Nazara/Graphics/Drawable.hpp> #include <Nazara/Graphics/Drawable.hpp>
#include <Nazara/Graphics/Light.hpp> #include <Nazara/Graphics/Light.hpp>
#include <Nazara/Graphics/Material.hpp> #include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/Scene.hpp>
#include <Nazara/Graphics/Sprite.hpp> #include <Nazara/Graphics/Sprite.hpp>
#include <Nazara/Renderer/Config.hpp> #include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Renderer.hpp> #include <Nazara/Renderer/Renderer.hpp>

View File

@ -14,11 +14,11 @@
#include <Nazara/Graphics/Debug.hpp> #include <Nazara/Graphics/Debug.hpp>
///TODO: Utilisation des UBOs ///TODO: Utilisation des UBOs
///TODO: Scale ?
NzLight::NzLight(nzLightType type) : NzLight::NzLight(nzLightType type) :
m_type(type), m_type(type),
m_color(NzColor::White), m_color(NzColor::White),
m_boundingVolumeUpdated(false),
m_ambientFactor((type == nzLightType_Directional) ? 0.2f : 0.f), m_ambientFactor((type == nzLightType_Directional) ? 0.2f : 0.f),
m_attenuation(0.9f), m_attenuation(0.9f),
m_diffuseFactor(1.f), m_diffuseFactor(1.f),
@ -31,9 +31,7 @@ m_radius(5.f)
NzLight::NzLight(const NzLight& light) : NzLight::NzLight(const NzLight& light) :
NzSceneNode(light), NzSceneNode(light),
m_type(light.m_type), m_type(light.m_type),
m_boundingVolume(light.m_boundingVolume),
m_color(light.m_color), m_color(light.m_color),
m_boundingVolumeUpdated(light.m_boundingVolumeUpdated),
m_ambientFactor(light.m_ambientFactor), m_ambientFactor(light.m_ambientFactor),
m_attenuation(light.m_attenuation), m_attenuation(light.m_attenuation),
m_diffuseFactor(light.m_diffuseFactor), m_diffuseFactor(light.m_diffuseFactor),
@ -49,6 +47,16 @@ void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const
renderQueue->AddLight(this); 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 void NzLight::Enable(const NzShader* shader, const NzLightUniforms& uniforms, int offset) const
{ {
/* /*
@ -112,14 +120,6 @@ float NzLight::GetAttenuation() const
return m_attenuation; return m_attenuation;
} }
const NzBoundingVolumef& NzLight::GetBoundingVolume() const
{
if (!m_boundingVolumeUpdated)
UpdateBoundingVolume();
return m_boundingVolume;
}
NzColor NzLight::GetColor() const NzColor NzLight::GetColor() const
{ {
return m_color; return m_color;
@ -251,11 +251,45 @@ bool NzLight::FrustumCull(const NzFrustumf& frustum) const
return false; 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() void NzLight::Register()
@ -269,46 +303,7 @@ void NzLight::Unregister()
void NzLight::UpdateBoundingVolume() const void NzLight::UpdateBoundingVolume() const
{ {
if (m_boundingVolume.IsNull()) if (m_boundingVolume.IsNull())
{ MakeBoundingVolume();
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;
}
}
}
switch (m_type) switch (m_type)
{ {

View File

@ -25,7 +25,6 @@ bool NzModelParameters::IsValid() const
} }
NzModel::NzModel() : NzModel::NzModel() :
m_boundingVolumeUpdated(true),
m_matCount(0), m_matCount(0),
m_skin(0), m_skin(0),
m_skinCount(1) m_skinCount(1)
@ -35,9 +34,7 @@ m_skinCount(1)
NzModel::NzModel(const NzModel& model) : NzModel::NzModel(const NzModel& model) :
NzSceneNode(model), NzSceneNode(model),
m_materials(model.m_materials), m_materials(model.m_materials),
m_boundingVolume(model.m_boundingVolume),
m_mesh(model.m_mesh), m_mesh(model.m_mesh),
m_boundingVolumeUpdated(model.m_boundingVolumeUpdated),
m_matCount(model.m_matCount), m_matCount(model.m_matCount),
m_skin(model.m_skin), m_skin(model.m_skin),
m_skinCount(model.m_skinCount) m_skinCount(model.m_skinCount)
@ -69,22 +66,14 @@ void NzModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const
} }
} }
const NzBoundingVolumef& NzModel::GetBoundingVolume() const NzModel* NzModel::Clone() const
{ {
#if NAZARA_GRAPHICS_SAFE return new NzModel(*this);
if (!m_mesh) }
{
NazaraError("Model has no mesh");
static NzBoundingVolumef dummy(nzExtend_Null); NzModel* NzModel::Create() const
return dummy; {
} return new NzModel;
#endif
if (!m_boundingVolumeUpdated)
UpdateBoundingVolume();
return m_boundingVolume;
} }
NzMaterial* NzModel::GetMaterial(const NzString& subMeshName) const NzMaterial* NzModel::GetMaterial(const NzString& subMeshName) const
@ -414,23 +403,12 @@ NzModel& NzModel::operator=(const NzModel& node)
return *this; return *this;
} }
void NzModel::InvalidateNode() void NzModel::MakeBoundingVolume() const
{ {
NzSceneNode::InvalidateNode(); if (m_mesh)
m_boundingVolumeUpdated = false;
}
void NzModel::UpdateBoundingVolume() const
{
if (m_boundingVolume.IsNull())
m_boundingVolume.Set(m_mesh->GetAABB()); m_boundingVolume.Set(m_mesh->GetAABB());
else
if (!m_transformMatrixUpdated) m_boundingVolume.MakeNull();
UpdateTransformMatrix();
m_boundingVolume.Update(m_transformMatrix);
m_boundingVolumeUpdated = true;
} }
NzModelLoader::LoaderList NzModel::s_loaders; NzModelLoader::LoaderList NzModel::s_loaders;

View File

@ -7,6 +7,7 @@
#include <Nazara/Core/ErrorFlags.hpp> #include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/StringStream.hpp> #include <Nazara/Core/StringStream.hpp>
#include <Nazara/Graphics/ParticleMapper.hpp> #include <Nazara/Graphics/ParticleMapper.hpp>
#include <Nazara/Graphics/Scene.hpp>
#include <cstdlib> #include <cstdlib>
#include <memory> #include <memory>
#include <Nazara/Graphics/Debug.hpp> #include <Nazara/Graphics/Debug.hpp>
@ -18,7 +19,6 @@ NzParticleSystem(maxParticleCount, NzParticleDeclaration::Get(layout))
NzParticleSystem::NzParticleSystem(unsigned int maxParticleCount, const NzParticleDeclaration* declaration) : NzParticleSystem::NzParticleSystem(unsigned int maxParticleCount, const NzParticleDeclaration* declaration) :
m_declaration(declaration), m_declaration(declaration),
m_boundingVolumeUpdated(false),
m_fixedStepEnabled(false), m_fixedStepEnabled(false),
m_processing(false), m_processing(false),
m_stepAccumulator(0.f), m_stepAccumulator(0.f),
@ -38,10 +38,8 @@ NzParticleSystem::NzParticleSystem(const NzParticleSystem& system) :
NzSceneNode(system), NzSceneNode(system),
m_controllers(system.m_controllers), m_controllers(system.m_controllers),
m_generators(system.m_generators), m_generators(system.m_generators),
m_boundingVolume(system.m_boundingVolume),
m_declaration(system.m_declaration), m_declaration(system.m_declaration),
m_renderer(system.m_renderer), m_renderer(system.m_renderer),
m_boundingVolumeUpdated(system.m_boundingVolumeUpdated),
m_fixedStepEnabled(system.m_fixedStepEnabled), m_fixedStepEnabled(system.m_fixedStepEnabled),
m_processing(false), m_processing(false),
m_stepAccumulator(0.f), m_stepAccumulator(0.f),
@ -132,14 +130,6 @@ void* NzParticleSystem::GenerateParticles(unsigned int count)
return ptr; return ptr;
} }
const NzBoundingVolumef& NzParticleSystem::GetBoundingVolume() const
{
if (!m_boundingVolumeUpdated)
UpdateBoundingVolume();
return m_boundingVolume;
}
const NzParticleDeclaration* NzParticleSystem::GetDeclaration() const const NzParticleDeclaration* NzParticleSystem::GetDeclaration() const
{ {
return m_declaration; return m_declaration;
@ -238,8 +228,6 @@ NzParticleSystem& NzParticleSystem::operator=(const NzParticleSystem& system)
NzSceneNode::operator=(system); NzSceneNode::operator=(system);
m_boundingVolume = system.m_boundingVolume;
m_boundingVolumeUpdated = system.m_boundingVolumeUpdated;
m_controllers = system.m_controllers; m_controllers = system.m_controllers;
m_declaration = system.m_declaration; m_declaration = system.m_declaration;
m_fixedStepEnabled = system.m_fixedStepEnabled; m_fixedStepEnabled = system.m_fixedStepEnabled;
@ -308,7 +296,7 @@ void NzParticleSystem::ApplyControllers(NzParticleMapper& mapper, unsigned int p
m_dyingParticles.clear(); 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) ///TODO: Calculer l'AABB (prendre la taille des particules en compte s'il y a)
m_boundingVolume.MakeInfinite(); m_boundingVolume.MakeInfinite();
@ -356,16 +344,3 @@ void NzParticleSystem::Update()
ApplyControllers(mapper, m_particleCount, elapsedTime, m_stepAccumulator); 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;
}

View File

@ -9,57 +9,36 @@
#include <Nazara/Graphics/Camera.hpp> #include <Nazara/Graphics/Camera.hpp>
#include <Nazara/Graphics/ColorBackground.hpp> #include <Nazara/Graphics/ColorBackground.hpp>
#include <Nazara/Graphics/RenderTechniques.hpp> #include <Nazara/Graphics/RenderTechniques.hpp>
#include <Nazara/Graphics/SceneRoot.hpp>
#include <Nazara/Graphics/SkinningManager.hpp> #include <Nazara/Graphics/SkinningManager.hpp>
#include <Nazara/Renderer/Config.hpp> #include <Nazara/Renderer/Config.hpp>
#include <functional> #include <functional>
#include <memory>
#include <set>
#include <vector>
#include <Nazara/Graphics/Debug.hpp> #include <Nazara/Graphics/Debug.hpp>
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<NzAbstractBackground> background;
std::unique_ptr<NzAbstractRenderTechnique> renderTechnique;
std::vector<NzUpdatable*> updateList;
std::vector<NzUpdatable*> 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) void NzScene::AddToVisibilityList(NzUpdatable* object)
{ {
m_impl->visibleUpdateList.push_back(object); m_visibleUpdateList.push_back(object);
}
void NzScene::Clear()
{
m_nodeMap.clear();
m_nodes.clear();
} }
void NzScene::Cull() void NzScene::Cull()
{ {
#if NAZARA_GRAPHICS_SAFE #if NAZARA_GRAPHICS_SAFE
if (!m_impl->viewer) if (!m_viewer)
{ {
NazaraError("No viewer"); NazaraError("No viewer");
return; return;
@ -69,42 +48,40 @@ void NzScene::Cull()
NzAbstractRenderQueue* renderQueue = GetRenderTechnique()->GetRenderQueue(); NzAbstractRenderQueue* renderQueue = GetRenderTechnique()->GetRenderQueue();
renderQueue->Clear(false); renderQueue->Clear(false);
m_impl->visibleUpdateList.clear(); m_visibleUpdateList.clear();
// Frustum culling // Frustum culling
RecursiveFrustumCull(renderQueue, m_impl->viewer->GetFrustum(), &m_impl->root); RecursiveFrustumCull(renderQueue, m_viewer->GetFrustum(), &m_root);
///TODO: Occlusion culling ///TODO: Occlusion culling
///TODO: Light culling
} }
void NzScene::Draw() void NzScene::Draw()
{ {
#if NAZARA_GRAPHICS_SAFE #if NAZARA_GRAPHICS_SAFE
if (!m_impl->viewer) if (!m_viewer)
{ {
NazaraError("No viewer"); NazaraError("No viewer");
return; return;
} }
#endif #endif
m_impl->viewer->ApplyView(); m_viewer->ApplyView();
try try
{ {
NzErrorFlags errFlags(nzErrorFlag_ThrowException); NzErrorFlags errFlags(nzErrorFlag_ThrowException, true);
m_impl->renderTechnique->Clear(this); m_renderTechnique->Clear(this);
m_impl->renderTechnique->Draw(this); m_renderTechnique->Draw(this);
} }
catch (const std::exception& e) 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)); m_renderTechnique.reset(NzRenderTechniques::GetByRanking(m_renderTechniqueRanking-1, &m_renderTechniqueRanking));
NazaraError("Render technique \"" + oldName + "\" failed, fallback to \"" + m_impl->renderTechnique->GetName() + '"'); NazaraError("Render technique \"" + oldName + "\" failed, falling back to \"" + m_renderTechnique->GetName() + '"');
} }
else else
{ {
@ -118,131 +95,154 @@ void NzScene::Draw()
void NzScene::EnableBackground(bool enable) void NzScene::EnableBackground(bool enable)
{ {
m_impl->backgroundEnabled = 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 NzColor NzScene::GetAmbientColor() const
{ {
return m_impl->ambientColor; return m_ambientColor;
} }
NzAbstractBackground* NzScene::GetBackground() const NzAbstractBackground* NzScene::GetBackground() const
{ {
if (!m_impl->background) if (!m_background)
m_impl->background.reset(new NzColorBackground); m_background.reset(new NzColorBackground);
return m_impl->background.get(); return m_background.get();
} }
NzVector3f NzScene::GetBackward() const NzVector3f NzScene::GetBackward() const
{ {
#if NAZARA_GRAPHICS_SAFE #if NAZARA_GRAPHICS_SAFE
if (!m_impl->viewer) if (!m_viewer)
{ {
NazaraError("No viewer"); NazaraError("No viewer");
return NzVector3f::Backward(); return NzVector3f::Backward();
} }
#endif #endif
return -m_impl->viewer->GetGlobalForward(); return -m_viewer->GetGlobalForward();
} }
NzVector3f NzScene::GetDown() const NzVector3f NzScene::GetDown() const
{ {
#if NAZARA_GRAPHICS_SAFE #if NAZARA_GRAPHICS_SAFE
if (!m_impl->viewer) if (!m_viewer)
{ {
NazaraError("No viewer"); NazaraError("No viewer");
return NzVector3f::Down(); return NzVector3f::Down();
} }
#endif #endif
return -m_impl->viewer->GetGlobalUp(); return -m_viewer->GetGlobalUp();
} }
NzVector3f NzScene::GetForward() const NzVector3f NzScene::GetForward() const
{ {
#if NAZARA_GRAPHICS_SAFE #if NAZARA_GRAPHICS_SAFE
if (!m_impl->viewer) if (!m_viewer)
{ {
NazaraError("No viewer"); NazaraError("No viewer");
return NzVector3f::Forward(); return NzVector3f::Forward();
} }
#endif #endif
return m_impl->viewer->GetGlobalForward(); return m_viewer->GetGlobalForward();
} }
NzVector3f NzScene::GetLeft() const NzVector3f NzScene::GetLeft() const
{ {
#if NAZARA_GRAPHICS_SAFE #if NAZARA_GRAPHICS_SAFE
if (!m_impl->viewer) if (!m_viewer)
{ {
NazaraError("No viewer"); NazaraError("No viewer");
return NzVector3f::Left(); return NzVector3f::Left();
} }
#endif #endif
return -m_impl->viewer->GetGlobalRight(); return -m_viewer->GetGlobalRight();
} }
NzAbstractRenderTechnique* NzScene::GetRenderTechnique() const NzAbstractRenderTechnique* NzScene::GetRenderTechnique() const
{ {
if (!m_impl->renderTechnique) if (!m_renderTechnique)
m_impl->renderTechnique.reset(NzRenderTechniques::GetByRanking(-1, &m_impl->renderTechniqueRanking)); m_renderTechnique.reset(NzRenderTechniques::GetByRanking(-1, &m_renderTechniqueRanking));
return m_impl->renderTechnique.get(); return m_renderTechnique.get();
} }
NzVector3f NzScene::GetRight() const NzVector3f NzScene::GetRight() const
{ {
#if NAZARA_GRAPHICS_SAFE #if NAZARA_GRAPHICS_SAFE
if (!m_impl->viewer) if (!m_viewer)
{ {
NazaraError("No viewer"); NazaraError("No viewer");
return NzVector3f::Right(); return NzVector3f::Right();
} }
#endif #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 NzAbstractViewer* NzScene::GetViewer() const
{ {
return m_impl->viewer; return m_viewer;
} }
NzVector3f NzScene::GetUp() const NzVector3f NzScene::GetUp() const
{ {
#if NAZARA_GRAPHICS_SAFE #if NAZARA_GRAPHICS_SAFE
if (!m_impl->viewer) if (!m_viewer)
{ {
NazaraError("No viewer"); NazaraError("No viewer");
return NzVector3f::Up(); return NzVector3f::Up();
} }
#endif #endif
return m_impl->viewer->GetGlobalUp(); return m_viewer->GetGlobalUp();
} }
float NzScene::GetUpdateTime() const float NzScene::GetUpdateTime() const
{ {
return m_impl->updateTime; return m_updateTime;
} }
unsigned int NzScene::GetUpdatePerSecond() const unsigned int NzScene::GetUpdatePerSecond() const
{ {
return m_impl->updatePerSecond; return m_updatePerSecond;
} }
bool NzScene::IsBackgroundEnabled() const bool NzScene::IsBackgroundEnabled() const
{ {
return m_impl->backgroundEnabled; return m_backgroundEnabled;
} }
void NzScene::RegisterForUpdate(NzUpdatable* object) void NzScene::RegisterForUpdate(NzUpdatable* object)
@ -255,32 +255,76 @@ void NzScene::RegisterForUpdate(NzUpdatable* object)
} }
#endif #endif
m_impl->updateList.push_back(object); 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<NzSceneNode> 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
{
NzErrorFlags errFlags(nzErrorFlag_ThrowException, true);
Update();
Cull();
UpdateVisible();
Draw();
}
catch (const std::exception& e)
{
NazaraError("Failed to render frame: " + NzString(e.what()));
}
} }
void NzScene::SetAmbientColor(const NzColor& color) void NzScene::SetAmbientColor(const NzColor& color)
{ {
m_impl->ambientColor = color; m_ambientColor = color;
} }
void NzScene::SetBackground(NzAbstractBackground* background) void NzScene::SetBackground(NzAbstractBackground* background)
{ {
m_impl->background.reset(background); m_background.reset(background);
} }
void NzScene::SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique) void NzScene::SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique)
{ {
m_impl->renderTechnique.reset(renderTechnique); m_renderTechnique.reset(renderTechnique);
} }
void NzScene::SetViewer(NzAbstractViewer* viewer) 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) // 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();
} }
} }
@ -291,7 +335,7 @@ void NzScene::SetViewer(NzAbstractViewer& viewer)
void NzScene::SetUpdatePerSecond(unsigned int updatePerSecond) void NzScene::SetUpdatePerSecond(unsigned int updatePerSecond)
{ {
m_impl->updatePerSecond = updatePerSecond; m_updatePerSecond = updatePerSecond;
} }
void NzScene::UnregisterForUpdate(NzUpdatable* object) void NzScene::UnregisterForUpdate(NzUpdatable* object)
@ -304,20 +348,20 @@ void NzScene::UnregisterForUpdate(NzUpdatable* object)
} }
#endif #endif
auto it = std::find(m_impl->updateList.begin(), m_impl->updateList.end(), object); auto it = std::find(m_updateList.begin(), m_updateList.end(), object);
if (it != m_impl->updateList.end()) if (it != m_updateList.end())
m_impl->updateList.erase(it); m_updateList.erase(it);
} }
void NzScene::Update() void NzScene::Update()
{ {
m_impl->update = (m_impl->updatePerSecond == 0 || m_impl->updateClock.GetMilliseconds() > 1000/m_impl->updatePerSecond); m_update = (m_updatePerSecond == 0 || m_updateClock.GetMilliseconds() > 1000/m_updatePerSecond);
if (m_impl->update) if (m_update)
{ {
m_impl->updateTime = m_impl->updateClock.GetSeconds(); m_updateTime = m_updateClock.GetSeconds();
m_impl->updateClock.Restart(); m_updateClock.Restart();
for (NzUpdatable* updatable : m_impl->updateList) for (NzUpdatable* updatable : m_updateList)
///TODO: Multihreading ///TODO: Multihreading
updatable->Update(); updatable->Update();
} }
@ -327,16 +371,68 @@ void NzScene::UpdateVisible()
{ {
NzSkinningManager::Skin(); NzSkinningManager::Skin();
if (m_impl->update) if (m_update)
{ {
for (NzUpdatable* node : m_impl->visibleUpdateList) for (NzUpdatable* node : m_visibleUpdateList)
node->Update(); node->Update();
} }
} }
NzScene::operator const NzSceneNode&() const NzScene::operator const NzSceneNode&() const
{ {
return m_impl->root; return m_root;
}
bool NzScene::ChangeNodeName(NzSceneNode* node, const NzString& newName)
{
#ifdef NAZARA_DEBUG
std::unique_ptr<NzSceneNode> 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())
{
if (m_nodeMap.find(name) != m_nodeMap.end())
{
NazaraError("Node " + name + " is already registred");
return false;
}
m_nodeMap[name] = node;
}
node->SetNameInternal(name);
node->SetParent(m_root, true);
m_nodes.emplace_back(node);
return true;
} }
void NzScene::RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node) void NzScene::RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node)

View File

@ -11,6 +11,7 @@
NzSceneNode::NzSceneNode() : NzSceneNode::NzSceneNode() :
m_scene(nullptr), m_scene(nullptr),
m_boundingVolumeUpdated(false),
m_drawingEnabled(true), m_drawingEnabled(true),
m_visible(false) m_visible(false)
{ {
@ -19,6 +20,7 @@ m_visible(false)
NzSceneNode::NzSceneNode(const NzSceneNode& sceneNode) : NzSceneNode::NzSceneNode(const NzSceneNode& sceneNode) :
NzNode(sceneNode), NzNode(sceneNode),
m_scene(nullptr), m_scene(nullptr),
m_boundingVolumeUpdated(false),
m_drawingEnabled(sceneNode.m_drawingEnabled), m_drawingEnabled(sceneNode.m_drawingEnabled),
m_visible(false) m_visible(false)
{ {
@ -44,6 +46,14 @@ NzVector3f NzSceneNode::GetBackward() const
return NzNode::GetBackward(); return NzNode::GetBackward();
} }
const NzBoundingVolumef& NzSceneNode::GetBoundingVolume() const
{
if (!m_boundingVolumeUpdated)
UpdateBoundingVolume();
return m_boundingVolume;
}
NzVector3f NzSceneNode::GetDown() const NzVector3f NzSceneNode::GetDown() const
{ {
if (m_scene) if (m_scene)
@ -83,6 +93,11 @@ NzVector3f NzSceneNode::GetLeft() const
return NzNode::GetLeft(); return NzNode::GetLeft();
} }
const NzString& NzSceneNode::GetName() const
{
return m_name;
}
nzNodeType NzSceneNode::GetNodeType() const nzNodeType NzSceneNode::GetNodeType() const
{ {
return nzNodeType_Scene; return nzNodeType_Scene;
@ -129,6 +144,19 @@ bool NzSceneNode::IsVisible() const
return m_visible; return m_visible;
} }
bool NzSceneNode::SetName(const NzString& 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) NzSceneNode& NzSceneNode::operator=(const NzSceneNode& sceneNode)
{ {
NzNode::operator=(sceneNode); NzNode::operator=(sceneNode);
@ -145,6 +173,13 @@ bool NzSceneNode::FrustumCull(const NzFrustumf& frustum) const
return frustum.Contains(GetBoundingVolume()); return frustum.Contains(GetBoundingVolume());
} }
void NzSceneNode::InvalidateNode()
{
NzNode::InvalidateNode();
m_boundingVolumeUpdated = false;
}
void NzSceneNode::OnParenting(const NzNode* parent) void NzSceneNode::OnParenting(const NzNode* parent)
{ {
if (parent) if (parent)
@ -184,6 +219,11 @@ void NzSceneNode::Register()
{ {
} }
void NzSceneNode::SetNameInternal(const NzString& name)
{
m_name = name;
}
void NzSceneNode::SetScene(NzScene* scene) void NzSceneNode::SetScene(NzScene* scene)
{ {
if (m_scene != scene) if (m_scene != scene)
@ -207,6 +247,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) void NzSceneNode::UpdateVisibility(const NzFrustumf& frustum)
{ {
bool wasVisible = m_visible; bool wasVisible = m_visible;

View File

@ -20,12 +20,6 @@ void NzSceneRoot::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const
NazaraInternalError("SceneNode::AddToRenderQueue() called on SceneRoot"); NazaraInternalError("SceneNode::AddToRenderQueue() called on SceneRoot");
} }
const NzBoundingVolumef& NzSceneRoot::GetBoundingVolume() const
{
static NzBoundingVolumef infinite(nzExtend_Infinite);
return infinite;
}
nzSceneNodeType NzSceneRoot::GetSceneNodeType() const nzSceneNodeType NzSceneRoot::GetSceneNodeType() const
{ {
return nzSceneNodeType_Root; return nzSceneNodeType_Root;
@ -36,6 +30,23 @@ bool NzSceneRoot::IsDrawable() const
return true; 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();
}
void NzSceneRoot::Register() void NzSceneRoot::Register()
{ {
NazaraInternalError("SceneNode::Register() called on SceneRoot"); NazaraInternalError("SceneNode::Register() called on SceneRoot");

View File

@ -7,6 +7,7 @@
#include <Nazara/Graphics/Camera.hpp> #include <Nazara/Graphics/Camera.hpp>
#include <Nazara/Graphics/Config.hpp> #include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/SkinningManager.hpp> #include <Nazara/Graphics/SkinningManager.hpp>
#include <Nazara/Graphics/Scene.hpp>
#include <Nazara/Utility/BufferMapper.hpp> #include <Nazara/Utility/BufferMapper.hpp>
#include <Nazara/Utility/MeshData.hpp> #include <Nazara/Utility/MeshData.hpp>
#include <Nazara/Utility/SkeletalMesh.hpp> #include <Nazara/Utility/SkeletalMesh.hpp>
@ -106,6 +107,16 @@ void NzSkeletalModel::AdvanceAnimation(float elapsedTime)
InvalidateBoundingVolume(); InvalidateBoundingVolume();
} }
NzSkeletalModel* NzSkeletalModel::Clone() const
{
return new NzSkeletalModel(*this);
}
NzSkeletalModel* NzSkeletalModel::Create() const
{
return new NzSkeletalModel;
}
void NzSkeletalModel::EnableAnimation(bool animation) void NzSkeletalModel::EnableAnimation(bool animation)
{ {
m_animationEnabled = animation; m_animationEnabled = animation;
@ -317,6 +328,11 @@ NzSkeletalModel& NzSkeletalModel::operator=(NzSkeletalModel&& node)
return *this; return *this;
} }
void NzSkeletalModel::MakeBoundingVolume() const
{
m_boundingVolume.Set(m_skeleton.GetAABB());
}
void NzSkeletalModel::Register() void NzSkeletalModel::Register()
{ {
m_scene->RegisterForUpdate(this); m_scene->RegisterForUpdate(this);
@ -333,16 +349,4 @@ void NzSkeletalModel::Update()
AdvanceAnimation(m_scene->GetUpdateTime()); 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; NzSkeletalModelLoader::LoaderList NzSkeletalModel::s_loaders;

View File

@ -3,28 +3,26 @@
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/Sprite.hpp> #include <Nazara/Graphics/Sprite.hpp>
#include <Nazara/Graphics/AbstractRenderQueue.hpp>
#include <Nazara/Graphics/AbstractViewer.hpp> #include <Nazara/Graphics/AbstractViewer.hpp>
#include <Nazara/Graphics/Scene.hpp>
#include <cstring> #include <cstring>
#include <memory> #include <memory>
#include <Nazara/Graphics/Debug.hpp> #include <Nazara/Graphics/Debug.hpp>
NzSprite::NzSprite() : NzSprite::NzSprite() :
m_boundingVolume(NzBoundingVolumef::Null()),
m_color(NzColor::White), m_color(NzColor::White),
m_textureCoords(0.f, 0.f, 1.f, 1.f), m_textureCoords(0.f, 0.f, 1.f, 1.f),
m_size(64.f, 64.f), m_size(64.f, 64.f),
m_boundingVolumeUpdated(true),
m_verticesUpdated(false) m_verticesUpdated(false)
{ {
SetDefaultMaterial(); SetDefaultMaterial();
} }
NzSprite::NzSprite(NzTexture* texture) : NzSprite::NzSprite(NzTexture* texture) :
m_boundingVolume(NzBoundingVolumef::Null()),
m_color(NzColor::White), m_color(NzColor::White),
m_textureCoords(0.f, 0.f, 1.f, 1.f), m_textureCoords(0.f, 0.f, 1.f, 1.f),
m_size(64.f, 64.f), m_size(64.f, 64.f),
m_boundingVolumeUpdated(false),
m_verticesUpdated(false) m_verticesUpdated(false)
{ {
SetTexture(texture, true); SetTexture(texture, true);
@ -32,13 +30,11 @@ m_verticesUpdated(false)
NzSprite::NzSprite(const NzSprite& sprite) : NzSprite::NzSprite(const NzSprite& sprite) :
NzSceneNode(sprite), NzSceneNode(sprite),
m_boundingVolume(sprite.m_boundingVolume),
m_color(sprite.m_color), m_color(sprite.m_color),
m_material(sprite.m_material), m_material(sprite.m_material),
m_textureCoords(sprite.m_textureCoords), m_textureCoords(sprite.m_textureCoords),
m_size(sprite.m_size), m_size(sprite.m_size),
m_vertices(sprite.m_vertices), m_vertices(sprite.m_vertices),
m_boundingVolumeUpdated(sprite.m_boundingVolumeUpdated),
m_verticesUpdated(sprite.m_verticesUpdated) m_verticesUpdated(sprite.m_verticesUpdated)
{ {
SetParent(sprite.GetParent()); SetParent(sprite.GetParent());
@ -52,12 +48,14 @@ void NzSprite::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const
renderQueue->AddSprites(m_material, m_vertices, 1); renderQueue->AddSprites(m_material, m_vertices, 1);
} }
const NzBoundingVolumef& NzSprite::GetBoundingVolume() const NzSprite* NzSprite::Clone() const
{ {
if (!m_boundingVolumeUpdated) return new NzSprite(*this);
UpdateBoundingVolume(); }
return m_boundingVolume; NzSprite* NzSprite::Create() const
{
return new NzSprite;
} }
const NzColor& NzSprite::GetColor() const const NzColor& NzSprite::GetColor() const
@ -189,7 +187,6 @@ NzSprite& NzSprite::operator=(const NzSprite& sprite)
m_size = sprite.m_size; 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 // 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; m_verticesUpdated = false;
return *this; return *this;
@ -199,7 +196,6 @@ void NzSprite::InvalidateNode()
{ {
NzSceneNode::InvalidateNode(); NzSceneNode::InvalidateNode();
m_boundingVolumeUpdated = false;
m_verticesUpdated = false; m_verticesUpdated = false;
} }
@ -213,21 +209,12 @@ void NzSprite::Unregister()
{ {
} }
void NzSprite::UpdateBoundingVolume() const void NzSprite::MakeBoundingVolume() const
{ {
if (m_boundingVolume.IsNull()) NzVector3f down = (m_scene) ? m_scene->GetDown() : NzVector3f::Down();
{ NzVector3f right = (m_scene) ? m_scene->GetRight() : NzVector3f::Right();
NzVector3f down = m_scene->GetDown();
NzVector3f right = m_scene->GetRight();
m_boundingVolume.Set(NzVector3f(0.f), m_size.x*right + m_size.y*down); 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;
} }
void NzSprite::UpdateVertices() const void NzSprite::UpdateVertices() const
@ -235,8 +222,8 @@ void NzSprite::UpdateVertices() const
if (!m_transformMatrixUpdated) if (!m_transformMatrixUpdated)
UpdateTransformMatrix(); UpdateTransformMatrix();
NzVector3f down = m_scene->GetDown(); NzVector3f down = (m_scene) ? m_scene->GetDown() : NzVector3f::Down();
NzVector3f right = m_scene->GetRight(); NzVector3f right = (m_scene) ? m_scene->GetRight() : NzVector3f::Right();
m_vertices[0].color = m_color; m_vertices[0].color = m_color;
m_vertices[0].position = m_transformMatrix.Transform(NzVector3f(0.f)); m_vertices[0].position = m_transformMatrix.Transform(NzVector3f(0.f));

View File

@ -5,13 +5,14 @@
#include <Nazara/Graphics/TextSprite.hpp> #include <Nazara/Graphics/TextSprite.hpp>
#include <Nazara/Core/CallOnExit.hpp> #include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/SparsePtr.hpp> #include <Nazara/Core/SparsePtr.hpp>
#include <Nazara/Graphics/AbstractRenderQueue.hpp>
#include <Nazara/Graphics/AbstractViewer.hpp> #include <Nazara/Graphics/AbstractViewer.hpp>
#include <Nazara/Graphics/Scene.hpp>
#include <memory> #include <memory>
#include <Nazara/Utility/Font.hpp> #include <Nazara/Utility/Font.hpp>
#include <Nazara/Graphics/Debug.hpp> #include <Nazara/Graphics/Debug.hpp>
NzTextSprite::NzTextSprite() : NzTextSprite::NzTextSprite() :
m_boundingVolume(NzBoundingVolumef::Null()),
m_color(NzColor::White), m_color(NzColor::White),
m_verticesUpdated(false) m_verticesUpdated(false)
{ {
@ -24,11 +25,9 @@ m_atlases(sprite.m_atlases),
m_renderInfos(sprite.m_renderInfos), m_renderInfos(sprite.m_renderInfos),
m_localVertices(sprite.m_localVertices), m_localVertices(sprite.m_localVertices),
m_vertices(sprite.m_vertices), m_vertices(sprite.m_vertices),
m_boundingVolume(sprite.m_boundingVolume),
m_color(sprite.m_color), m_color(sprite.m_color),
m_material(sprite.m_material), m_material(sprite.m_material),
m_localBounds(sprite.m_localBounds), m_localBounds(sprite.m_localBounds),
m_boundingVolumeUpdated(sprite.m_boundingVolumeUpdated),
m_verticesUpdated(sprite.m_verticesUpdated) m_verticesUpdated(sprite.m_verticesUpdated)
{ {
SetParent(sprite.GetParent()); SetParent(sprite.GetParent());
@ -66,12 +65,14 @@ void NzTextSprite::Clear()
m_vertices.clear(); m_vertices.clear();
} }
const NzBoundingVolumef& NzTextSprite::GetBoundingVolume() const NzTextSprite* NzTextSprite::Clone() const
{ {
if (!m_boundingVolumeUpdated) return new NzTextSprite(*this);
UpdateBoundingVolume(); }
return m_boundingVolume; NzTextSprite* NzTextSprite::Create() const
{
return new NzTextSprite;
} }
const NzColor& NzTextSprite::GetColor() const const NzColor& NzTextSprite::GetColor() const
@ -266,7 +267,6 @@ NzTextSprite& NzTextSprite::operator=(const NzTextSprite& text)
m_localVertices = text.m_localVertices; 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 // 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; m_verticesUpdated = false;
return *this; return *this;
@ -284,10 +284,21 @@ void NzTextSprite::InvalidateNode()
{ {
NzSceneNode::InvalidateNode(); NzSceneNode::InvalidateNode();
m_boundingVolumeUpdated = false;
m_verticesUpdated = 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) bool NzTextSprite::OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata)
{ {
NazaraUnused(userdata); NazaraUnused(userdata);
@ -373,34 +384,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 void NzTextSprite::UpdateVertices() const
{ {
if (!m_transformMatrixUpdated) if (!m_transformMatrixUpdated)
UpdateTransformMatrix(); UpdateTransformMatrix();
NzVector3f down = m_scene->GetDown(); NzVector3f down = (m_scene) ? m_scene->GetDown() : NzVector3f::Down();
NzVector3f right = m_scene->GetRight(); NzVector3f right = (m_scene) ? m_scene->GetRight() : NzVector3f::Right();
NzSparsePtr<NzColor> colorPtr(&m_vertices[0].color, sizeof(NzVertexStruct_XYZ_Color_UV)); NzSparsePtr<NzColor> colorPtr(&m_vertices[0].color, sizeof(NzVertexStruct_XYZ_Color_UV));
NzSparsePtr<NzVector3f> posPtr(&m_vertices[0].position, sizeof(NzVertexStruct_XYZ_Color_UV)); NzSparsePtr<NzVector3f> posPtr(&m_vertices[0].position, sizeof(NzVertexStruct_XYZ_Color_UV));

View File

@ -125,11 +125,6 @@ NzVector3f NzNode::GetLeft() const
return m_derivedRotation * NzVector3f::Left(); return m_derivedRotation * NzVector3f::Left();
} }
const NzString& NzNode::GetName() const
{
return m_name;
}
nzNodeType NzNode::GetNodeType() const nzNodeType NzNode::GetNodeType() const
{ {
return nzNodeType_Default; return nzNodeType_Default;
@ -413,11 +408,6 @@ void NzNode::SetInitialScale(float scaleX, float scaleY, float scaleZ)
InvalidateNode(); InvalidateNode();
} }
void NzNode::SetName(const NzString& name)
{
m_name = name;
}
void NzNode::SetParent(const NzNode* node, bool keepDerived) void NzNode::SetParent(const NzNode* node, bool keepDerived)
{ {
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE
@ -621,7 +611,6 @@ NzNode& NzNode::operator=(const NzNode& node)
m_initialPosition = node.m_initialPosition; m_initialPosition = node.m_initialPosition;
m_initialRotation = node.m_initialRotation; m_initialRotation = node.m_initialRotation;
m_initialScale = node.m_initialScale; m_initialScale = node.m_initialScale;
m_name = node.m_name;
m_position = node.m_position; m_position = node.m_position;
m_rotation = node.m_rotation; m_rotation = node.m_rotation;
m_scale = node.m_scale; m_scale = node.m_scale;