SceneComponent.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Scene/Common.h>
  7. #include <AnKi/Scene/SceneSerializer.h>
  8. #include <AnKi/Util/Functions.h>
  9. #include <AnKi/Util/BitMask.h>
  10. #include <AnKi/Util/Enum.h>
  11. #include <AnKi/Core/Common.h>
  12. namespace anki {
  13. enum class SceneComponentType : U8
  14. {
  15. #define ANKI_DEFINE_SCENE_COMPONENT(name, weight, sceneNodeCanHaveMany, icon, serializable) k##name,
  16. #include <AnKi/Scene/Components/SceneComponentClasses.def.h>
  17. kCount,
  18. kFirst = 0
  19. };
  20. ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(SceneComponentType)
  21. enum class SceneComponentTypeMask : U32
  22. {
  23. kNone = 0,
  24. #define ANKI_DEFINE_SCENE_COMPONENT(name, weight, sceneNodeCanHaveMany, icon, serializable) k##name = 1 << U32(SceneComponentType::k##name),
  25. #include <AnKi/Scene/Components/SceneComponentClasses.def.h>
  26. };
  27. ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(SceneComponentTypeMask)
  28. class SceneComponentType2
  29. {
  30. public:
  31. #define ANKI_DEFINE_SCENE_COMPONENT(name, weight, sceneNodeCanHaveMany, icon, serializable) \
  32. static constexpr SceneComponentType k##name##Component = SceneComponentType::k##name;
  33. #include <AnKi/Scene/Components/SceneComponentClasses.def.h>
  34. };
  35. #define ANKI_SCENE_COMPONENT(className) \
  36. public: \
  37. static constexpr SceneComponentType kClassType = SceneComponentType2::k##className; \
  38. \
  39. private:
  40. // Component names
  41. inline Array<const Char*, U32(SceneComponentType::kCount)> kSceneComponentTypeName = {
  42. #define ANKI_DEFINE_SCENE_COMPONENT(name, weight, sceneNodeCanHaveMany, icon, serializable) ANKI_STRINGIZE(name)
  43. #define ANKI_SCENE_COMPONENT_SEPARATOR ,
  44. #include <AnKi/Scene/Components/SceneComponentClasses.def.h>
  45. };
  46. // Just a flag per component
  47. inline Array<Bool, U32(SceneComponentType::kCount)> kSceneComponentSceneNodeCanHaveMany = {
  48. #define ANKI_DEFINE_SCENE_COMPONENT(name, weight, sceneNodeCanHaveMany, icon, serializable) sceneNodeCanHaveMany
  49. #define ANKI_SCENE_COMPONENT_SEPARATOR ,
  50. #include <AnKi/Scene/Components/SceneComponentClasses.def.h>
  51. };
  52. // Passed to SceneComponent::update.
  53. class SceneComponentUpdateInfo
  54. {
  55. friend class SceneGraph;
  56. public:
  57. SceneNode* m_node = nullptr;
  58. const Second m_previousTime;
  59. const Second m_currentTime;
  60. const Second m_dt;
  61. const Bool m_forceUpdateSceneBounds;
  62. const Bool m_checkForResourceUpdates;
  63. StackMemoryPool* m_framePool = nullptr;
  64. SceneComponentUpdateInfo(Second prevTime, Second crntTime, Bool forceUpdateSceneBounds, Bool checkForResourceUpdates)
  65. : m_previousTime(prevTime)
  66. , m_currentTime(crntTime)
  67. , m_dt(crntTime - prevTime)
  68. , m_forceUpdateSceneBounds(forceUpdateSceneBounds)
  69. , m_checkForResourceUpdates(checkForResourceUpdates)
  70. {
  71. }
  72. void updateSceneBounds(Vec3 aabbMin, Vec3 aabbMax)
  73. {
  74. ANKI_ASSERT(aabbMin <= aabbMax);
  75. m_sceneMin = m_sceneMin.min(aabbMin);
  76. m_sceneMax = m_sceneMax.max(aabbMax);
  77. }
  78. private:
  79. Vec3 m_sceneMin = Vec3(kMaxF32);
  80. Vec3 m_sceneMax = Vec3(kMinF32);
  81. };
  82. // Scene node component.
  83. class SceneComponent
  84. {
  85. public:
  86. SceneComponent(SceneNode* node, SceneComponentType type);
  87. virtual ~SceneComponent() = default;
  88. SceneComponentType getType() const
  89. {
  90. return SceneComponentType(m_type);
  91. }
  92. Timestamp getTimestamp() const
  93. {
  94. return m_timestamp;
  95. }
  96. U32 getUuid() const
  97. {
  98. return m_uuid;
  99. }
  100. ANKI_INTERNAL U32 getArrayIndex() const
  101. {
  102. ANKI_ASSERT(m_arrayIdx != kMaxU32 >> 8u);
  103. return m_arrayIdx;
  104. }
  105. ANKI_INTERNAL void setArrayIndex(U32 idx)
  106. {
  107. m_arrayIdx = idx & (kMaxU32 >> 8u);
  108. ANKI_ASSERT(m_arrayIdx == idx);
  109. }
  110. ANKI_INTERNAL virtual void onDestroy([[maybe_unused]] SceneNode& node)
  111. {
  112. }
  113. ANKI_INTERNAL virtual void update(SceneComponentUpdateInfo& info, Bool& updated) = 0;
  114. ANKI_INTERNAL virtual void onOtherComponentRemovedOrAdded([[maybe_unused]] SceneComponent* other, [[maybe_unused]] Bool added)
  115. {
  116. }
  117. // Don't call it directly.
  118. ANKI_INTERNAL void setTimestamp(Timestamp timestamp)
  119. {
  120. ANKI_ASSERT(timestamp > 0);
  121. ANKI_ASSERT(timestamp >= m_timestamp);
  122. m_timestamp = timestamp;
  123. }
  124. static constexpr F32 getUpdateOrderWeight(SceneComponentType type)
  125. {
  126. return m_updateOrderWeights[type];
  127. }
  128. Bool updatedThisFrame() const
  129. {
  130. return m_timestamp == GlobalFrameIndex::getSingleton().m_value;
  131. }
  132. virtual Error serialize([[maybe_unused]] SceneSerializer& serializer)
  133. {
  134. return Error::kNone;
  135. }
  136. protected:
  137. U32 regenerateUuid();
  138. // A convenience function for components to keep tabs on other components of a SceneNode
  139. template<typename TComponent>
  140. static void bookkeepComponent(SceneDynamicArray<TComponent*>& arr, SceneComponent* other, Bool added, Bool& firstDirty)
  141. {
  142. ANKI_ASSERT(other);
  143. ANKI_ASSERT(other->getType() == TComponent::kClassType);
  144. if(added)
  145. {
  146. for(auto it = arr.getBegin(); it != arr.getEnd(); ++it)
  147. {
  148. ANKI_ASSERT(*it != other);
  149. }
  150. arr.emplaceBack(static_cast<TComponent*>(other));
  151. firstDirty = arr.getSize() == 1;
  152. }
  153. else
  154. {
  155. [[maybe_unused]] Bool found = false;
  156. for(auto it = arr.getBegin(); it != arr.getEnd(); ++it)
  157. {
  158. if(*it == other)
  159. {
  160. firstDirty = it == arr.getBegin();
  161. arr.erase(it);
  162. found = true;
  163. break;
  164. }
  165. }
  166. ANKI_ASSERT(found);
  167. }
  168. }
  169. // A convenience function for components to keep tabs on other components of a SceneNode
  170. template<typename TComponent>
  171. static void bookkeepComponent(TComponent*& ptr, SceneComponent* other, Bool added)
  172. {
  173. ANKI_ASSERT(other);
  174. ANKI_ASSERT(other->getType() == TComponent::kClassType);
  175. if(added)
  176. {
  177. ANKI_ASSERT(ptr == nullptr);
  178. ptr = static_cast<TComponent*>(other);
  179. }
  180. else
  181. {
  182. ANKI_ASSERT(ptr == other);
  183. ptr = nullptr;
  184. }
  185. }
  186. private:
  187. Timestamp m_timestamp = 1; ///< Indicates when an update happened
  188. U32 m_uuid = 0;
  189. U32 m_arrayIdx : 24 = kMaxU32 >> 8u;
  190. U32 m_type : 8 = 0; ///< Cache the type ID.
  191. static constexpr Array<F32, U32(SceneComponentType::kCount)> m_updateOrderWeights = {
  192. #define ANKI_DEFINE_SCENE_COMPONENT(name, weight, sceneNodeCanHaveMany, icon, serializable) weight
  193. #define ANKI_SCENE_COMPONENT_SEPARATOR ,
  194. #include <AnKi/Scene/Components/SceneComponentClasses.def.h>
  195. };
  196. };
  197. } // end namespace anki