Nazara Engine  0.4
A fast, complete, cross-platform API designed for game development
InstancedRenderable.hpp
1 // Copyright (C) 2017 Jérôme Leclercq
2 // This file is part of the "Nazara Engine - Graphics module"
3 // For conditions of distribution and use, see copyright notice in Config.hpp
4 
5 #pragma once
6 
7 #ifndef NAZARA_INSTANCEDRENDERABLE_HPP
8 #define NAZARA_INSTANCEDRENDERABLE_HPP
9 
10 #include <Nazara/Core/ObjectLibrary.hpp>
11 #include <Nazara/Core/ObjectRef.hpp>
12 #include <Nazara/Core/RefCounted.hpp>
13 #include <Nazara/Core/Signal.hpp>
14 #include <Nazara/Graphics/Config.hpp>
15 #include <Nazara/Graphics/CullingList.hpp>
16 #include <Nazara/Graphics/Material.hpp>
17 #include <Nazara/Math/BoundingVolume.hpp>
18 #include <Nazara/Math/Frustum.hpp>
19 #include <Nazara/Math/Matrix4.hpp>
20 
21 namespace Nz
22 {
23  class AbstractRenderQueue;
24  class InstancedRenderable;
25 
26  using InstancedRenderableConstRef = ObjectRef<const InstancedRenderable>;
27  using InstancedRenderableLibrary = ObjectLibrary<InstancedRenderable>;
28  using InstancedRenderableRef = ObjectRef<InstancedRenderable>;
29 
30  class NAZARA_GRAPHICS_API InstancedRenderable : public RefCounted
31  {
32  public:
33  struct InstanceData;
34 
35  inline InstancedRenderable();
36  inline InstancedRenderable(const InstancedRenderable& renderable);
37  InstancedRenderable(InstancedRenderable&& renderable) = delete;
38  virtual ~InstancedRenderable();
39 
40  virtual void AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const = 0;
41 
42  virtual bool Cull(const Frustumf& frustum, const InstanceData& instanceData) const;
43 
44  inline void EnsureBoundingVolumeUpdated() const;
45 
46  virtual const BoundingVolumef& GetBoundingVolume() const;
47 
48  inline const MaterialRef& GetMaterial(std::size_t matIndex = 0) const;
49  inline const MaterialRef& GetMaterial(std::size_t skinIndex, std::size_t matIndex) const;
50  inline std::size_t GetMaterialCount() const;
51  inline std::size_t GetSkin() const;
52  inline std::size_t GetSkinCount() const;
53 
54  virtual void InvalidateData(InstanceData* instanceData, UInt32 flags) const;
55 
56  inline void SetSkin(std::size_t skinIndex);
57  inline void SetSkinCount(std::size_t skinCount);
58 
59  virtual void UpdateBoundingVolume(InstanceData* instanceData) const;
60  virtual void UpdateData(InstanceData* instanceData) const;
61 
62  inline InstancedRenderable& operator=(const InstancedRenderable& renderable);
63  InstancedRenderable& operator=(InstancedRenderable&& renderable) = delete;
64 
65  // Signals:
66  NazaraSignal(OnInstancedRenderableInvalidateBoundingVolume, const InstancedRenderable* /*instancedRenderable*/);
67  NazaraSignal(OnInstancedRenderableInvalidateData, const InstancedRenderable* /*instancedRenderable*/, UInt32 /*flags*/);
68  NazaraSignal(OnInstancedRenderableInvalidateMaterial, const InstancedRenderable* /*instancedRenderable*/, std::size_t /*skinIndex*/, std::size_t /*matIndex*/, const MaterialRef& /*newMat*/);
69  NazaraSignal(OnInstancedRenderableRelease, const InstancedRenderable* /*instancedRenderable*/);
70  NazaraSignal(OnInstancedRenderableResetMaterials, const InstancedRenderable* /*instancedRenderable*/, std::size_t /*newMaterialCount*/);
71  NazaraSignal(OnInstancedRenderableSkinChange, const InstancedRenderable* /*instancedRenderable*/, std::size_t /*newSkinIndex*/);
72 
73  struct InstanceData
74  {
75  InstanceData(const Matrix4f& transformationMatrix) :
76  localMatrix(transformationMatrix),
77  flags(0)
78  {
79  }
80 
81  InstanceData(InstanceData&& instanceData) noexcept = default;
82 
83  InstanceData& operator=(InstanceData&& instanceData) noexcept
84  {
85  data = std::move(instanceData.data);
86  flags = instanceData.flags;
87  renderOrder = instanceData.renderOrder;
88  localMatrix = instanceData.localMatrix;
89  transformMatrix = instanceData.transformMatrix;
90  volume = instanceData.volume;
91 
92  return *this;
93  }
94 
95  std::vector<UInt8> data;
96  BoundingVolumef volume;
97  Matrix4f localMatrix;
98  mutable Matrix4f transformMatrix;
99  UInt32 flags;
100  int renderOrder;
101  };
102 
103  protected:
104  inline void InvalidateBoundingVolume();
105  inline void InvalidateInstanceData(UInt32 flags);
106 
107  virtual void MakeBoundingVolume() const = 0;
108 
109  inline void ResetMaterials(std::size_t matCount, std::size_t skinCount = 1);
110 
111  inline void SetMaterial(std::size_t matIndex, MaterialRef material);
112  inline void SetMaterial(std::size_t skinIndex, std::size_t matIndex, MaterialRef material);
113 
114  mutable BoundingVolumef m_boundingVolume;
115 
116  private:
117  inline void UpdateBoundingVolume() const;
118 
119  std::size_t m_matCount;
120  std::size_t m_skin;
121  std::size_t m_skinCount;
122  std::vector<MaterialRef> m_materials;
123  mutable bool m_boundingVolumeUpdated;
124 
125  static InstancedRenderableLibrary::LibraryMap s_library;
126  };
127 }
128 
129 #include <Nazara/Graphics/InstancedRenderable.inl>
130 
131 #endif // NAZARA_INSTANCEDRENDERABLE_HPP
Math class that represents a frustum in the three dimensional vector space.
Definition: Frustum.hpp:24
TODO: Inherit SoundEmitter from Node.
Definition: Algorithm.hpp:12
Graphics class that represents the rendering queue for our scene.
Definition: AbstractRenderQueue.hpp:26
Graphics class that represents an instancer renderable.
Definition: InstancedRenderable.hpp:30
Core class that represents a reference with a counter.
Definition: RefCounted.hpp:21