SceneGraph.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <anki/scene/SceneGraph.h>
  6. #include <anki/scene/Camera.h>
  7. #include <anki/scene/ModelNode.h>
  8. #include <anki/scene/Sector.h>
  9. #include <anki/core/Trace.h>
  10. #include <anki/physics/PhysicsWorld.h>
  11. #include <anki/resource/ResourceManager.h>
  12. #include <anki/renderer/MainRenderer.h>
  13. #include <anki/misc/ConfigSet.h>
  14. #include <anki/util/ThreadPool.h>
  15. namespace anki
  16. {
  17. const U NODE_UPDATE_BATCH = 10;
  18. class UpdateSceneNodesCtx
  19. {
  20. public:
  21. SceneGraph* m_scene = nullptr;
  22. IntrusiveList<SceneNode>::Iterator m_crntNode;
  23. SpinLock m_crntNodeLock;
  24. F32 m_prevUpdateTime;
  25. F32 m_crntTime;
  26. };
  27. class UpdateSceneNodesTask : public ThreadPoolTask
  28. {
  29. public:
  30. UpdateSceneNodesCtx* m_ctx;
  31. Error operator()(U32 taskId, PtrSize threadsCount)
  32. {
  33. return m_ctx->m_scene->updateNodes(*m_ctx);
  34. }
  35. };
  36. SceneGraph::SceneGraph()
  37. {
  38. }
  39. SceneGraph::~SceneGraph()
  40. {
  41. Error err = iterateSceneNodes([&](SceneNode& s) -> Error {
  42. s.setMarkedForDeletion();
  43. return ErrorCode::NONE;
  44. });
  45. (void)err;
  46. deleteNodesMarkedForDeletion();
  47. if(m_sectors)
  48. {
  49. m_alloc.deleteInstance(m_sectors);
  50. m_sectors = nullptr;
  51. }
  52. }
  53. Error SceneGraph::init(AllocAlignedCallback allocCb,
  54. void* allocCbData,
  55. ThreadPool* threadpool,
  56. ThreadHive* threadHive,
  57. ResourceManager* resources,
  58. Input* input,
  59. const Timestamp* globalTimestamp,
  60. const ConfigSet& config)
  61. {
  62. m_globalTimestamp = globalTimestamp;
  63. m_threadpool = threadpool;
  64. m_threadHive = threadHive;
  65. m_resources = resources;
  66. m_objectsMarkedForDeletionCount.store(0);
  67. m_gr = &m_resources->getGrManager();
  68. m_physics = &m_resources->getPhysicsWorld();
  69. m_input = input;
  70. m_alloc = SceneAllocator<U8>(allocCb, allocCbData, 1024 * 10, 1.0, 0);
  71. m_frameAlloc = SceneFrameAllocator<U8>(allocCb, allocCbData, 1 * 1024 * 1024);
  72. ANKI_CHECK(m_events.create(this));
  73. m_sectors = m_alloc.newInstance<SectorGroup>(this);
  74. m_maxReflectionProxyDistance = config.getNumber("imageReflectionMaxDistance");
  75. m_componentLists.init(m_alloc);
  76. // Init the default main camera
  77. ANKI_CHECK(newSceneNode<PerspectiveCamera>("mainCamera", m_defaultMainCam));
  78. m_defaultMainCam->setAll(toRad(60.0), toRad(60.0), 0.1, 1000.0);
  79. m_mainCam = m_defaultMainCam;
  80. return ErrorCode::NONE;
  81. }
  82. Error SceneGraph::registerNode(SceneNode* node)
  83. {
  84. ANKI_ASSERT(node);
  85. // Add to dict if it has a name
  86. if(node->getName())
  87. {
  88. if(tryFindSceneNode(node->getName()))
  89. {
  90. ANKI_LOGE("Node with the same name already exists");
  91. return ErrorCode::USER_DATA;
  92. }
  93. m_nodesDict.pushBack(m_alloc, node->getName(), node);
  94. }
  95. // Add to vector
  96. m_nodes.pushBack(node);
  97. ++m_nodesCount;
  98. return ErrorCode::NONE;
  99. }
  100. void SceneGraph::unregisterNode(SceneNode* node)
  101. {
  102. // Remove from the graph
  103. m_nodes.erase(node);
  104. --m_nodesCount;
  105. if(m_mainCam != m_defaultMainCam && m_mainCam == node)
  106. {
  107. m_mainCam = m_defaultMainCam;
  108. }
  109. // Remove from dict
  110. if(node->getName())
  111. {
  112. auto it = m_nodesDict.find(node->getName());
  113. ANKI_ASSERT(it != m_nodesDict.getEnd());
  114. m_nodesDict.erase(m_alloc, it);
  115. }
  116. }
  117. SceneNode& SceneGraph::findSceneNode(const CString& name)
  118. {
  119. SceneNode* node = tryFindSceneNode(name);
  120. ANKI_ASSERT(node);
  121. return *node;
  122. }
  123. SceneNode* SceneGraph::tryFindSceneNode(const CString& name)
  124. {
  125. auto it = m_nodesDict.find(name);
  126. return (it == m_nodesDict.getEnd()) ? nullptr : (*it);
  127. }
  128. void SceneGraph::deleteNodesMarkedForDeletion()
  129. {
  130. /// Delete all nodes pending deletion. At this point all scene threads
  131. /// should have finished their tasks
  132. while(m_objectsMarkedForDeletionCount.load() > 0)
  133. {
  134. Bool found = false;
  135. auto it = m_nodes.begin();
  136. auto end = m_nodes.end();
  137. for(; it != end; ++it)
  138. {
  139. SceneNode& node = *it;
  140. if(node.getMarkedForDeletion())
  141. {
  142. // Delete node
  143. unregisterNode(&node);
  144. m_alloc.deleteInstance(&node);
  145. m_objectsMarkedForDeletionCount.fetchSub(1);
  146. found = true;
  147. break;
  148. }
  149. }
  150. (void)found;
  151. ANKI_ASSERT(found && "Something is wrong with marked for deletion");
  152. }
  153. }
  154. Error SceneGraph::update(F32 prevUpdateTime, F32 crntTime, MainRenderer& renderer)
  155. {
  156. ANKI_ASSERT(m_mainCam);
  157. ANKI_TRACE_START_EVENT(SCENE_UPDATE);
  158. m_timestamp = *m_globalTimestamp;
  159. // Reset the framepool
  160. m_frameAlloc.getMemoryPool().reset();
  161. // Delete stuff
  162. ANKI_TRACE_START_EVENT(SCENE_DELETE_STUFF);
  163. m_events.deleteEventsMarkedForDeletion();
  164. deleteNodesMarkedForDeletion();
  165. ANKI_TRACE_STOP_EVENT(SCENE_DELETE_STUFF);
  166. ThreadPool& threadPool = *m_threadpool;
  167. (void)threadPool;
  168. // Update
  169. ANKI_TRACE_START_EVENT(SCENE_PHYSICS_UPDATE);
  170. m_physics->updateAsync(crntTime - prevUpdateTime);
  171. m_physics->waitUpdate();
  172. ANKI_TRACE_STOP_EVENT(SCENE_PHYSICS_UPDATE);
  173. ANKI_TRACE_START_EVENT(SCENE_NODES_UPDATE);
  174. ANKI_CHECK(m_events.updateAllEvents(prevUpdateTime, crntTime));
  175. // Then the rest
  176. Array<UpdateSceneNodesTask, ThreadPool::MAX_THREADS> jobs2;
  177. UpdateSceneNodesCtx updateCtx;
  178. updateCtx.m_scene = this;
  179. updateCtx.m_crntNode = m_nodes.getBegin();
  180. updateCtx.m_prevUpdateTime = prevUpdateTime;
  181. updateCtx.m_crntTime = crntTime;
  182. for(U i = 0; i < threadPool.getThreadsCount(); i++)
  183. {
  184. UpdateSceneNodesTask& job = jobs2[i];
  185. job.m_ctx = &updateCtx;
  186. threadPool.assignNewTask(i, &job);
  187. }
  188. ANKI_CHECK(threadPool.waitForAllThreadsToFinish());
  189. ANKI_TRACE_STOP_EVENT(SCENE_NODES_UPDATE);
  190. doVisibilityTests(*m_mainCam, *this, renderer.getOffscreenRenderer());
  191. ANKI_TRACE_STOP_EVENT(SCENE_UPDATE);
  192. return ErrorCode::NONE;
  193. }
  194. Error SceneGraph::updateNode(F32 prevTime, F32 crntTime, SceneNode& node)
  195. {
  196. ANKI_TRACE_INC_COUNTER(SCENE_NODES_UPDATED, 1);
  197. Error err = ErrorCode::NONE;
  198. // Components update
  199. err = node.iterateComponents([&](SceneComponent& comp) -> Error {
  200. Bool updated = false;
  201. return comp.updateReal(node, prevTime, crntTime, updated);
  202. });
  203. // Update children
  204. if(!err)
  205. {
  206. err = node.visitChildren([&](SceneNode& child) -> Error { return updateNode(prevTime, crntTime, child); });
  207. }
  208. // Frame update
  209. if(!err)
  210. {
  211. err = node.frameUpdateComplete(prevTime, crntTime);
  212. }
  213. return err;
  214. }
  215. Error SceneGraph::updateNodes(UpdateSceneNodesCtx& ctx) const
  216. {
  217. ANKI_TRACE_START_EVENT(SCENE_NODES_UPDATE);
  218. IntrusiveList<SceneNode>::Iterator& it = ctx.m_crntNode;
  219. IntrusiveList<SceneNode>::ConstIterator end = m_nodes.getEnd();
  220. SpinLock& lock = ctx.m_crntNodeLock;
  221. Bool quit = false;
  222. Error err = ErrorCode::NONE;
  223. while(!quit && !err)
  224. {
  225. // Fetch a few scene nodes
  226. Array<SceneNode*, NODE_UPDATE_BATCH> nodes = {{
  227. nullptr,
  228. }};
  229. lock.lock();
  230. for(SceneNode*& node : nodes)
  231. {
  232. if(it != end)
  233. {
  234. node = &(*it);
  235. ++it;
  236. }
  237. }
  238. lock.unlock();
  239. // Process nodes
  240. U count = 0;
  241. for(U i = 0; i < nodes.getSize(); ++i)
  242. {
  243. if(nodes[i])
  244. {
  245. if(nodes[i]->getParent() == nullptr)
  246. {
  247. err = updateNode(ctx.m_prevUpdateTime, ctx.m_crntTime, *nodes[i]);
  248. }
  249. ++count;
  250. }
  251. }
  252. if(ANKI_UNLIKELY(count == 0))
  253. {
  254. quit = true;
  255. }
  256. }
  257. ANKI_TRACE_STOP_EVENT(SCENE_NODES_UPDATE);
  258. return err;
  259. }
  260. } // end namespace anki