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.
// 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<NzModel>(); // 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<NzLight>(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

View File

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

View File

@ -18,17 +18,19 @@ 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;
float GetAttenuation() const;
const NzBoundingVolumef& GetBoundingVolume() const;
NzColor GetColor() const;
float GetDiffuseFactor() const;
float GetInnerAngle() const;
@ -54,15 +56,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;

View File

@ -41,10 +41,12 @@ 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;
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 +86,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<NzMaterialRef> 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;

View File

@ -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<unsigned int, std::greater<unsigned int>> m_dyingParticles;
mutable std::vector<nzUInt8> m_buffer;
std::vector<NzParticleControllerRef> m_controllers;
std::vector<NzParticleEmitter*> m_emitters;
std::vector<NzParticleGeneratorRef> 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;

View File

@ -8,37 +8,49 @@
#define NAZARA_SCENE_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Core/Color.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Core/Updatable.hpp>
#include <Nazara/Graphics/AbstractBackground.hpp>
#include <Nazara/Graphics/AbstractRenderTechnique.hpp>
#include <Nazara/Graphics/SceneRoot.hpp>
#include <Nazara/Math/Frustum.hpp>
#include <memory>
#include <unordered_map>
#include <vector>
class NzAbstractRenderQueue;
class NzAbstractViewer;
class NzCamera;
class NzLight;
class NzModel;
class NzNode;
class NzRenderQueue;
class NzSceneNode;
struct NzSceneImpl;
class NAZARA_API NzScene
{
friend NzCamera;
friend NzSceneNode;
public:
NzScene();
~NzScene();
~NzScene() = default;
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 Draw();
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;
NzAbstractBackground* GetBackground() const;
NzVector3f GetBackward() const;
@ -47,7 +59,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;
@ -57,6 +70,11 @@ class NAZARA_API NzScene
void RegisterForUpdate(NzUpdatable* object);
void RemoveNode(NzSceneNode* node);
void RemoveNode(const NzString& name);
void RenderFrame();
void SetAmbientColor(const NzColor& color);
void SetBackground(NzAbstractBackground* background);
void SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique);
@ -72,9 +90,28 @@ 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);
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

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/Graphics/Enums.hpp>
#include <Nazara/Graphics/Scene.hpp>
#include <Nazara/Math/BoundingVolume.hpp>
#include <Nazara/Math/Frustum.hpp>
#include <Nazara/Utility/Node.hpp>
class NzAbstractRenderQueue;
class NzScene;
class NAZARA_API NzSceneNode : public NzNode
{
friend class NzScene;
friend NzScene;
public:
NzSceneNode();
@ -26,42 +28,59 @@ 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;
virtual const NzBoundingVolumef& GetBoundingVolume() const = 0;
virtual const NzBoundingVolumef& GetBoundingVolume() const;
NzVector3f GetDown() const;
NzVector3f GetForward() const;
NzVector3f GetLeft() const;
const NzString& GetName() const;
nzNodeType GetNodeType() const final;
NzVector3f GetRight() const;
NzScene* GetScene() const;
virtual nzSceneNodeType GetSceneNodeType() const = 0;
NzVector3f GetUp() const;
void InvalidateAABB();
virtual bool IsDrawable() const = 0;
bool IsDrawingEnabled() const;
bool IsVisible() const;
bool SetName(const NzString& name);
NzSceneNode& operator=(const NzSceneNode& sceneNode);
NzSceneNode& operator=(NzSceneNode&& sceneNode) = delete;
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);
virtual void Register();
void SetNameInternal(const NzString& name);
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;
private:
void UpdateVisibility(const NzFrustumf& frustum);
NzString m_name;
};
#endif // NAZARA_SCENENODE_HPP

View File

@ -10,14 +10,15 @@
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Graphics/SceneNode.hpp>
class NzScene;
class NAZARA_API NzSceneRoot : public NzSceneNode
{
friend struct NzSceneImpl;
friend NzScene;
public:
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override;
const NzBoundingVolumef& GetBoundingVolume() const override;
nzSceneNodeType GetSceneNodeType() const override;
bool IsDrawable() const;
@ -26,6 +27,10 @@ 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();
};

View File

@ -31,7 +31,6 @@ using NzSkeletalModelLoader = NzResourceLoader<NzSkeletalModel, NzSkeletalModelP
class NAZARA_API NzSkeletalModel : public NzModel, NzUpdatable
{
friend NzSkeletalModelLoader;
//friend class NzScene;
public:
NzSkeletalModel();
@ -42,6 +41,9 @@ class NAZARA_API NzSkeletalModel : public NzModel, NzUpdatable
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override;
void AdvanceAnimation(float elapsedTime);
NzSkeletalModel* Clone() const;
NzSkeletalModel* Create() const;
void EnableAnimation(bool animation);
NzAnimation* GetAnimation() const;
@ -69,10 +71,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;

View File

@ -22,7 +22,9 @@ class NAZARA_API NzSprite : public NzSceneNode
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override;
const NzBoundingVolumef& GetBoundingVolume() const override;
NzSprite* Clone() const;
NzSprite* Create() const;
const NzColor& GetColor() const;
NzMaterial* GetMaterial() const;
nzSceneNodeType GetSceneNodeType() const override;
@ -44,18 +46,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;
};

View File

@ -28,7 +28,9 @@ class NAZARA_API NzTextSprite : public NzSceneNode, NzAbstractAtlas::Listener
void Clear();
const NzBoundingVolumef& GetBoundingVolume() const override;
NzTextSprite* Clone() const;
NzTextSprite* Create() const;
const NzColor& GetColor() const;
NzMaterial* GetMaterial() const;
nzSceneNodeType GetSceneNodeType() const override;
@ -47,12 +49,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 +67,9 @@ class NAZARA_API NzTextSprite : public NzSceneNode, NzAbstractAtlas::Listener
mutable std::unordered_map<NzTexture*, RenderIndices> m_renderInfos;
mutable std::vector<NzVertexStruct_XY_Color> m_localVertices;
mutable std::vector<NzVertexStruct_XYZ_Color_UV> m_vertices;
mutable NzBoundingVolumef m_boundingVolume;
NzColor m_color;
NzMaterialRef m_material;
NzRectui m_localBounds;
mutable bool m_boundingVolumeUpdated;
mutable bool m_verticesUpdated;
};

View File

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

View File

@ -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;

View File

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

View File

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

View File

@ -14,11 +14,11 @@
#include <Nazara/Graphics/Debug.hpp>
///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),
@ -49,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
{
/*
@ -112,14 +120,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,31 +251,13 @@ bool NzLight::FrustumCull(const NzFrustumf& frustum) const
return false;
}
void NzLight::InvalidateNode()
void NzLight::MakeBoundingVolume() const
{
NzSceneNode::InvalidateNode();
m_boundingVolumeUpdated = false;
}
void NzLight::Register()
{
}
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
break;
case nzLightType_Point:
{
@ -308,7 +290,20 @@ void NzLight::UpdateBoundingVolume() const
break;
}
}
}
}
void NzLight::Register()
{
}
void NzLight::Unregister()
{
}
void NzLight::UpdateBoundingVolume() const
{
if (m_boundingVolume.IsNull())
MakeBoundingVolume();
switch (m_type)
{

View File

@ -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,22 +66,14 @@ void NzModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const
}
}
const NzBoundingVolumef& NzModel::GetBoundingVolume() const
NzModel* NzModel::Clone() const
{
#if NAZARA_GRAPHICS_SAFE
if (!m_mesh)
{
NazaraError("Model has no mesh");
return new NzModel(*this);
}
static NzBoundingVolumef dummy(nzExtend_Null);
return dummy;
}
#endif
if (!m_boundingVolumeUpdated)
UpdateBoundingVolume();
return m_boundingVolume;
NzModel* NzModel::Create() const
{
return new NzModel;
}
NzMaterial* NzModel::GetMaterial(const NzString& subMeshName) const
@ -414,23 +403,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;

View File

@ -7,6 +7,7 @@
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <Nazara/Graphics/ParticleMapper.hpp>
#include <Nazara/Graphics/Scene.hpp>
#include <cstdlib>
#include <memory>
#include <Nazara/Graphics/Debug.hpp>
@ -18,7 +19,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 +38,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 +130,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 +228,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 +296,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 +344,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;
}

View File

@ -9,57 +9,36 @@
#include <Nazara/Graphics/Camera.hpp>
#include <Nazara/Graphics/ColorBackground.hpp>
#include <Nazara/Graphics/RenderTechniques.hpp>
#include <Nazara/Graphics/SceneRoot.hpp>
#include <Nazara/Graphics/SkinningManager.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <functional>
#include <memory>
#include <set>
#include <vector>
#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)
{
m_impl->visibleUpdateList.push_back(object);
m_visibleUpdateList.push_back(object);
}
void NzScene::Clear()
{
m_nodeMap.clear();
m_nodes.clear();
}
void NzScene::Cull()
{
#if NAZARA_GRAPHICS_SAFE
if (!m_impl->viewer)
if (!m_viewer)
{
NazaraError("No viewer");
return;
@ -69,42 +48,40 @@ 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
///TODO: Light culling
}
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, falling back to \"" + m_renderTechnique->GetName() + '"');
}
else
{
@ -118,131 +95,154 @@ void NzScene::Draw()
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
{
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::RegisterForUpdate(NzUpdatable* object)
@ -255,32 +255,76 @@ void NzScene::RegisterForUpdate(NzUpdatable* object)
}
#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)
{
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();
}
}
@ -291,7 +335,7 @@ void NzScene::SetViewer(NzAbstractViewer& viewer)
void NzScene::SetUpdatePerSecond(unsigned int updatePerSecond)
{
m_impl->updatePerSecond = updatePerSecond;
m_updatePerSecond = updatePerSecond;
}
void NzScene::UnregisterForUpdate(NzUpdatable* object)
@ -304,20 +348,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();
}
@ -327,16 +371,68 @@ 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;
}
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)

View File

@ -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)
@ -83,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;
@ -129,6 +144,19 @@ bool NzSceneNode::IsVisible() const
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)
{
NzNode::operator=(sceneNode);
@ -145,6 +173,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)
@ -184,6 +219,11 @@ void NzSceneNode::Register()
{
}
void NzSceneNode::SetNameInternal(const NzString& name)
{
m_name = name;
}
void NzSceneNode::SetScene(NzScene* 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)
{
bool wasVisible = m_visible;

View File

@ -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,23 @@ 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();
}
void NzSceneRoot::Register()
{
NazaraInternalError("SceneNode::Register() called on SceneRoot");

View File

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

View File

@ -3,28 +3,26 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/Sprite.hpp>
#include <Nazara/Graphics/AbstractRenderQueue.hpp>
#include <Nazara/Graphics/AbstractViewer.hpp>
#include <Nazara/Graphics/Scene.hpp>
#include <cstring>
#include <memory>
#include <Nazara/Graphics/Debug.hpp>
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 +30,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,12 +48,14 @@ void NzSprite::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const
renderQueue->AddSprites(m_material, m_vertices, 1);
}
const NzBoundingVolumef& NzSprite::GetBoundingVolume() const
NzSprite* NzSprite::Clone() const
{
if (!m_boundingVolumeUpdated)
UpdateBoundingVolume();
return new NzSprite(*this);
}
return m_boundingVolume;
NzSprite* NzSprite::Create() const
{
return new NzSprite;
}
const NzColor& NzSprite::GetColor() const
@ -189,7 +187,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 +196,6 @@ void NzSprite::InvalidateNode()
{
NzSceneNode::InvalidateNode();
m_boundingVolumeUpdated = 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->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;
}
void NzSprite::UpdateVertices() const
@ -235,8 +222,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));

View File

@ -5,13 +5,14 @@
#include <Nazara/Graphics/TextSprite.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/SparsePtr.hpp>
#include <Nazara/Graphics/AbstractRenderQueue.hpp>
#include <Nazara/Graphics/AbstractViewer.hpp>
#include <Nazara/Graphics/Scene.hpp>
#include <memory>
#include <Nazara/Utility/Font.hpp>
#include <Nazara/Graphics/Debug.hpp>
NzTextSprite::NzTextSprite() :
m_boundingVolume(NzBoundingVolumef::Null()),
m_color(NzColor::White),
m_verticesUpdated(false)
{
@ -24,11 +25,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,12 +65,14 @@ void NzTextSprite::Clear()
m_vertices.clear();
}
const NzBoundingVolumef& NzTextSprite::GetBoundingVolume() const
NzTextSprite* NzTextSprite::Clone() const
{
if (!m_boundingVolumeUpdated)
UpdateBoundingVolume();
return new NzTextSprite(*this);
}
return m_boundingVolume;
NzTextSprite* NzTextSprite::Create() const
{
return new NzTextSprite;
}
const NzColor& NzTextSprite::GetColor() const
@ -266,7 +267,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 +284,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 +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
{
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<NzColor> colorPtr(&m_vertices[0].color, 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();
}
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;