SceneNode.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. // Copyright (C) 2009-2022, 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/Components/SceneComponent.h>
  7. #include <AnKi/Util/Hierarchy.h>
  8. #include <AnKi/Util/BitMask.h>
  9. #include <AnKi/Util/BitSet.h>
  10. #include <AnKi/Util/List.h>
  11. #include <AnKi/Util/Enum.h>
  12. namespace anki {
  13. // Forward
  14. class ResourceManager;
  15. class ConfigSet;
  16. /// @addtogroup scene
  17. /// @{
  18. /// Interface class backbone of scene
  19. class SceneNode : public Hierarchy<SceneNode>, public IntrusiveListEnabled<SceneNode>
  20. {
  21. public:
  22. using Base = Hierarchy<SceneNode>;
  23. /// The one and only constructor.
  24. /// @param scene The owner scene.
  25. /// @param name The unique name of the node. If it's empty the the node is not searchable.
  26. SceneNode(SceneGraph* scene, CString name);
  27. /// Unregister node
  28. virtual ~SceneNode();
  29. /// A dummy init for those scene nodes that don't need it.
  30. Error init()
  31. {
  32. return Error::NONE;
  33. }
  34. SceneGraph& getSceneGraph()
  35. {
  36. return *m_scene;
  37. }
  38. const SceneGraph& getSceneGraph() const
  39. {
  40. return *m_scene;
  41. }
  42. const ConfigSet& getConfig() const;
  43. /// Return the name. It may be empty for nodes that we don't want to track
  44. CString getName() const
  45. {
  46. return (!m_name.isEmpty()) ? m_name.toCString() : CString();
  47. }
  48. U64 getUuid() const
  49. {
  50. return m_uuid;
  51. }
  52. Bool getMarkedForDeletion() const
  53. {
  54. return m_markedForDeletion;
  55. }
  56. void setMarkedForDeletion();
  57. Timestamp getGlobalTimestamp() const;
  58. Timestamp getComponentMaxTimestamp() const
  59. {
  60. return m_maxComponentTimestamp;
  61. }
  62. void setComponentMaxTimestamp(Timestamp maxComponentTimestamp)
  63. {
  64. ANKI_ASSERT(maxComponentTimestamp > 0);
  65. m_maxComponentTimestamp = maxComponentTimestamp;
  66. }
  67. SceneAllocator<U8> getAllocator() const;
  68. SceneFrameAllocator<U8> getFrameAllocator() const;
  69. void addChild(SceneNode* obj)
  70. {
  71. Base::addChild(getAllocator(), obj);
  72. }
  73. /// This is called by the scenegraph every frame after all component updates. By default it does nothing.
  74. /// @param prevUpdateTime Timestamp of the previous update
  75. /// @param crntTime Timestamp of this update
  76. virtual Error frameUpdate([[maybe_unused]] Second prevUpdateTime, [[maybe_unused]] Second crntTime)
  77. {
  78. return Error::NONE;
  79. }
  80. /// Iterate all components.
  81. template<typename TFunct>
  82. void iterateComponents(TFunct func) const
  83. {
  84. for(U32 i = 0; i < m_componentInfos.getSize(); ++i)
  85. {
  86. // Use the m_componentInfos to check if it's feedback component for possibly less cache misses
  87. func(*m_components[i], m_componentInfos[i].isFeedbackComponent());
  88. }
  89. }
  90. /// Iterate all components.
  91. template<typename TFunct>
  92. void iterateComponents(TFunct func)
  93. {
  94. for(U32 i = 0; i < m_componentInfos.getSize(); ++i)
  95. {
  96. // Use the m_componentInfos to check if it's feedback component for possibly less cache misses
  97. func(*m_components[i], m_componentInfos[i].isFeedbackComponent());
  98. }
  99. }
  100. /// Iterate all components of a specific type
  101. template<typename TComponent, typename TFunct>
  102. void iterateComponentsOfType(TFunct func) const
  103. {
  104. for(U32 i = 0; i < m_componentInfos.getSize(); ++i)
  105. {
  106. if(m_componentInfos[i].getComponentClassId() == TComponent::getStaticClassId())
  107. {
  108. func(static_cast<const TComponent&>(*m_components[i]));
  109. }
  110. }
  111. }
  112. /// Iterate all components of a specific type
  113. template<typename TComponent, typename TFunct>
  114. void iterateComponentsOfType(TFunct func)
  115. {
  116. for(U32 i = 0; i < m_componentInfos.getSize(); ++i)
  117. {
  118. if(m_componentInfos[i].getComponentClassId() == TComponent::getStaticClassId())
  119. {
  120. func(static_cast<TComponent&>(*m_components[i]));
  121. }
  122. }
  123. }
  124. /// Try geting a pointer to the first component of the requested type
  125. template<typename TComponent>
  126. const TComponent* tryGetFirstComponentOfType() const
  127. {
  128. for(U32 i = 0; i < m_componentInfos.getSize(); ++i)
  129. {
  130. if(m_componentInfos[i].getComponentClassId() == TComponent::getStaticClassId())
  131. {
  132. return static_cast<const TComponent*>(m_components[i]);
  133. }
  134. }
  135. return nullptr;
  136. }
  137. /// Try geting a pointer to the first component of the requested type
  138. template<typename TComponent>
  139. TComponent* tryGetFirstComponentOfType()
  140. {
  141. const TComponent* c = static_cast<const SceneNode*>(this)->tryGetFirstComponentOfType<TComponent>();
  142. return const_cast<TComponent*>(c);
  143. }
  144. /// Get a pointer to the first component of the requested type
  145. template<typename TComponent>
  146. const TComponent& getFirstComponentOfType() const
  147. {
  148. const TComponent* out = tryGetFirstComponentOfType<TComponent>();
  149. ANKI_ASSERT(out != nullptr);
  150. return *out;
  151. }
  152. /// Get a pointer to the first component of the requested type
  153. template<typename TComponent>
  154. TComponent& getFirstComponentOfType()
  155. {
  156. const TComponent& c = static_cast<const SceneNode*>(this)->getFirstComponentOfType<TComponent>();
  157. return const_cast<TComponent&>(c);
  158. }
  159. /// Try geting a pointer to the nth component of the requested type.
  160. template<typename TComponent>
  161. const TComponent* tryGetNthComponentOfType(U32 nth) const
  162. {
  163. I32 inth = I32(nth);
  164. for(U32 i = 0; i < m_componentInfos.getSize(); ++i)
  165. {
  166. if(m_componentInfos[i].getComponentClassId() == TComponent::getStaticClassId() && inth-- == 0)
  167. {
  168. return static_cast<const TComponent*>(m_components[i]);
  169. }
  170. }
  171. return nullptr;
  172. }
  173. /// Try geting a pointer to the nth component of the requested type.
  174. template<typename TComponent>
  175. TComponent* tryGetNthComponentOfType(U32 nth)
  176. {
  177. const TComponent* c = static_cast<const SceneNode*>(this)->tryGetNthComponentOfType<TComponent>(nth);
  178. return const_cast<TComponent*>(c);
  179. }
  180. template<typename TComponent>
  181. const TComponent& getNthComponentOfType(U32 nth) const
  182. {
  183. const TComponent* out = tryGetNthComponentOfType<TComponent>(nth);
  184. ANKI_ASSERT(out);
  185. return *out;
  186. }
  187. template<typename TComponent>
  188. TComponent& getNthComponentOfType(U32 nth)
  189. {
  190. TComponent* out = tryGetNthComponentOfType<TComponent>(nth);
  191. ANKI_ASSERT(out);
  192. return *out;
  193. }
  194. /// Get the nth component.
  195. template<typename TComponent>
  196. TComponent& getComponentAt(U32 idx)
  197. {
  198. ANKI_ASSERT(m_componentInfos[idx].getComponentClassId() == TComponent::getStaticClassId());
  199. SceneComponent* c = m_components[idx];
  200. return *static_cast<TComponent*>(c);
  201. }
  202. /// Get the nth component.
  203. template<typename TComponent>
  204. const TComponent& getComponentAt(U32 idx) const
  205. {
  206. ANKI_ASSERT(m_componentInfos[idx].getComponentClassId() == TComponent::getStaticClassId());
  207. const SceneComponent* c = m_components[idx];
  208. return *static_cast<const TComponent*>(c);
  209. }
  210. U32 getComponentCount() const
  211. {
  212. return m_components.getSize();
  213. }
  214. template<typename TComponent>
  215. U32 countComponentsOfType() const
  216. {
  217. U32 count = 0;
  218. iterateComponentsOfType<TComponent>([&]([[maybe_unused]] const TComponent& c) {
  219. ++count;
  220. });
  221. return count;
  222. }
  223. protected:
  224. /// Create and append a component to the components container. The SceneNode has the ownership.
  225. template<typename TComponent>
  226. TComponent* newComponent()
  227. {
  228. TComponent* comp = getAllocator().newInstance<TComponent>(this);
  229. m_components.emplaceBack(getAllocator(), comp);
  230. m_componentInfos.emplaceBack(getAllocator(), *comp);
  231. return comp;
  232. }
  233. ResourceManager& getResourceManager();
  234. private:
  235. /// This class packs a few info used by components.
  236. class ComponentsArrayElement
  237. {
  238. public:
  239. ComponentsArrayElement(const SceneComponent& comp)
  240. {
  241. m_classId = comp.getClassId() & 0x7F;
  242. ANKI_ASSERT(m_classId == comp.getClassId());
  243. m_feedbackComponent = comp.isFeedbackComponent();
  244. }
  245. ComponentsArrayElement(const ComponentsArrayElement& b)
  246. : m_feedbackComponent(b.m_feedbackComponent)
  247. , m_classId(b.m_classId)
  248. {
  249. }
  250. ComponentsArrayElement& operator=(const ComponentsArrayElement& b)
  251. {
  252. m_feedbackComponent = b.m_feedbackComponent;
  253. m_classId = b.m_classId;
  254. return *this;
  255. }
  256. U8 getComponentClassId() const
  257. {
  258. return m_classId;
  259. }
  260. Bool isFeedbackComponent() const
  261. {
  262. return m_feedbackComponent;
  263. }
  264. private:
  265. U8 m_feedbackComponent : 1;
  266. U8 m_classId : 7;
  267. };
  268. static_assert(sizeof(ComponentsArrayElement) == sizeof(U8), "Wrong size");
  269. SceneGraph* m_scene = nullptr;
  270. U64 m_uuid;
  271. String m_name; ///< A unique name.
  272. DynamicArray<SceneComponent*> m_components;
  273. DynamicArray<ComponentsArrayElement> m_componentInfos; ///< Same size as m_components. Used to iterate fast.
  274. Timestamp m_maxComponentTimestamp = 0;
  275. Bool m_markedForDeletion = false;
  276. };
  277. /// @}
  278. } // end namespace anki