SceneGraph.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. #include "anki/scene/SceneGraph.h"
  2. #include "anki/scene/Camera.h"
  3. #include "anki/scene/ModelNode.h"
  4. #include "anki/util/Exception.h"
  5. #include "anki/core/Threadpool.h"
  6. #include "anki/core/Counters.h"
  7. #include "anki/renderer/Renderer.h"
  8. #include "anki/misc/Xml.h"
  9. #include "anki/physics/RigidBody.h"
  10. namespace anki {
  11. //==============================================================================
  12. // Misc =
  13. //==============================================================================
  14. //==============================================================================
  15. struct UpdateMoveComponentsJob: ThreadpoolTask
  16. {
  17. SceneGraph* scene = nullptr;
  18. void operator()(ThreadId threadId, U threadsCount)
  19. {
  20. /*U64 start, end;
  21. ANKI_ASSERT(scene);
  22. choseStartEnd(
  23. threadId, threadsCount, scene->getSceneNodesCount(), start, end);
  24. scene->iterateSceneNodes(start, end, [](SceneNode& sn)
  25. {
  26. MoveComponent* m = sn.getMoveComponent();
  27. if(m)
  28. {
  29. m->update();
  30. }
  31. });*/
  32. }
  33. };
  34. //==============================================================================
  35. static void updateSceneNode(SceneNode& sn, F32 prevUpdateTime,
  36. F32 crntTime, SectorGroup& sectorGroup)
  37. {
  38. sn.frameUpdate(prevUpdateTime, crntTime, getGlobTimestamp());
  39. // Movable
  40. MoveComponent* m = sn.getMoveComponent();
  41. if(m)
  42. {
  43. m->reset();
  44. m->updateReal(sn, prevUpdateTime, crntTime);
  45. }
  46. // Do some spatial stuff
  47. SpatialComponent* sp = sn.getSpatialComponent();
  48. if(sp)
  49. {
  50. sp->reset();
  51. sp->updateReal(sn, prevUpdateTime, crntTime);
  52. }
  53. // Do some frustumable stuff
  54. FrustumComponent* fr = sn.getFrustumComponent();
  55. if(fr)
  56. {
  57. fr->reset();
  58. fr->updateReal(sn, prevUpdateTime, crntTime);
  59. }
  60. // Do some renderable stuff
  61. RenderComponent* r = sn.getRenderComponent();
  62. if(r)
  63. {
  64. r->reset();
  65. r->updateReal(sn, prevUpdateTime, crntTime);
  66. }
  67. }
  68. //==============================================================================
  69. struct UpdateSceneNodesJob: ThreadpoolTask
  70. {
  71. SceneGraph* scene = nullptr;
  72. F32 prevUpdateTime;
  73. F32 crntTime;
  74. SectorGroup* sectorGroup;
  75. void operator()(ThreadId threadId, U threadsCount)
  76. {
  77. ANKI_ASSERT(scene);
  78. U64 start, end;
  79. choseStartEnd(
  80. threadId, threadsCount, scene->getSceneNodesCount(), start, end);
  81. scene->iterateSceneNodes(start, end, [&](SceneNode& sn)
  82. {
  83. updateSceneNode(sn, prevUpdateTime, crntTime, *sectorGroup);
  84. });
  85. }
  86. };
  87. //==============================================================================
  88. // Scene =
  89. //==============================================================================
  90. //==============================================================================
  91. SceneGraph::SceneGraph()
  92. : alloc(ANKI_SCENE_ALLOCATOR_SIZE),
  93. frameAlloc(ANKI_SCENE_FRAME_ALLOCATOR_SIZE),
  94. nodes(alloc),
  95. dict(10, DictionaryHasher(), DictionaryEqual(), alloc),
  96. physics(this),
  97. sectorGroup(this),
  98. events(this)
  99. {
  100. nodes.reserve(ANKI_SCENE_OPTIMAL_SCENE_NODES_COUNT);
  101. ambientCol = Vec3(0.0);
  102. }
  103. //==============================================================================
  104. SceneGraph::~SceneGraph()
  105. {}
  106. //==============================================================================
  107. void SceneGraph::registerNode(SceneNode* node)
  108. {
  109. ANKI_ASSERT(node);
  110. // Add to dict if it has name
  111. if(node->getName())
  112. {
  113. if(dict.find(node->getName()) != dict.end())
  114. {
  115. throw ANKI_EXCEPTION("Node with the same name already exists: "
  116. + node->getName());
  117. }
  118. dict[node->getName()] = node;
  119. }
  120. // Add to vector
  121. ANKI_ASSERT(std::find(nodes.begin(), nodes.end(), node) == nodes.end());
  122. nodes.push_back(node);
  123. }
  124. //==============================================================================
  125. void SceneGraph::unregisterNode(SceneNode* node)
  126. {
  127. // Remove from vector
  128. auto it = nodes.begin();
  129. for(; it != nodes.end(); it++)
  130. {
  131. if((*it) == node)
  132. {
  133. break;
  134. }
  135. }
  136. ANKI_ASSERT(it != nodes.end());
  137. nodes.erase(it);
  138. // Remove from dict
  139. if(node->getName())
  140. {
  141. auto it = dict.find(node->getName());
  142. ANKI_ASSERT(it != dict.end());
  143. dict.erase(it);
  144. }
  145. }
  146. //==============================================================================
  147. SceneNode& SceneGraph::findSceneNode(const char* name)
  148. {
  149. ANKI_ASSERT(dict.find(name) != dict.end());
  150. return *(dict.find(name))->second;
  151. }
  152. //==============================================================================
  153. SceneNode* SceneGraph::tryFindSceneNode(const char* name)
  154. {
  155. auto it = dict.find(name);
  156. return (it == dict.end()) ? nullptr : it->second;
  157. }
  158. //==============================================================================
  159. void SceneGraph::deleteNodesMarkedForDeletion()
  160. {
  161. /// Delete all nodes pending deletion. At this point all scene threads
  162. /// should have finished their tasks
  163. while(nodesMarkedForDeletionCount > 0)
  164. {
  165. // First gather the nodes that will be de
  166. SceneFrameVector<decltype(nodes)::iterator> forDeletion;
  167. for(auto it = nodes.begin(); it != nodes.end(); it++)
  168. {
  169. if((*it)->isMarkedForDeletion())
  170. {
  171. forDeletion.push_back(it);
  172. }
  173. }
  174. // Now delete
  175. for(auto& it : forDeletion)
  176. {
  177. // Disable events for that node
  178. events.iterateEvents([&](Event& e)
  179. {
  180. if(e.getSceneNode() == *it)
  181. {
  182. e.markForDeletion();
  183. }
  184. });
  185. // Remove it
  186. unregisterNode(*it);
  187. SceneAllocator<SceneNode> al = alloc;
  188. alloc.destroy(*it);
  189. alloc.deallocate(*it, 1);
  190. ++nodesMarkedForDeletionCount;
  191. }
  192. }
  193. }
  194. //==============================================================================
  195. void SceneGraph::update(F32 prevUpdateTime, F32 crntTime, Renderer& renderer)
  196. {
  197. ANKI_ASSERT(mainCam);
  198. ANKI_COUNTER_START_TIMER(C_SCENE_UPDATE_TIME);
  199. //
  200. // Sync point. Here we wait for all scene's threads
  201. //
  202. // Reset the framepool
  203. frameAlloc.reset();
  204. // Delete nodes
  205. deleteNodesMarkedForDeletion();
  206. // Sync updates
  207. iterateSceneNodes([&](SceneNode& sn)
  208. {
  209. RigidBody* body = sn.getRigidBody();
  210. if(body)
  211. {
  212. body->syncUpdate(sn, prevUpdateTime, crntTime);
  213. }
  214. });
  215. Threadpool& threadPool = ThreadpoolSingleton::get();
  216. (void)threadPool;
  217. // XXX Do that in parallel
  218. physics.update(prevUpdateTime, crntTime);
  219. renderer.getTiler().updateTiles(*mainCam);
  220. events.updateAllEvents(prevUpdateTime, crntTime);
  221. // Then the rest
  222. #if 0
  223. for(SceneNode* n : nodes)
  224. {
  225. updateSceneNode(*n, prevUpdateTime, crntTime, sectorGroup);
  226. }
  227. #else
  228. Array<UpdateSceneNodesJob, Threadpool::MAX_THREADS> jobs2;
  229. for(U i = 0; i < threadPool.getThreadsCount(); i++)
  230. {
  231. UpdateSceneNodesJob& job = jobs2[i];
  232. job.scene = this;
  233. job.prevUpdateTime = prevUpdateTime;
  234. job.crntTime = crntTime;
  235. job.sectorGroup = &sectorGroup;
  236. threadPool.assignNewTask(i, &job);
  237. }
  238. threadPool.waitForAllThreadsToFinish();
  239. #endif
  240. doVisibilityTests(*mainCam, *this, renderer);
  241. /*sectorGroup.doVisibilityTests(*mainCam,
  242. VisibilityTest(VT_RENDERABLES | VT_LIGHTS), &r);*/
  243. ANKI_COUNTER_STOP_TIMER_INC(C_SCENE_UPDATE_TIME);
  244. }
  245. //==============================================================================
  246. void SceneGraph::load(const char* filename)
  247. {
  248. try
  249. {
  250. XmlDocument doc;
  251. doc.loadFile(ANKI_R(filename));
  252. XmlElement rootEl = doc.getChildElement("scene");
  253. // Model nodes
  254. //
  255. XmlElement mdlNodeEl = rootEl.getChildElement("modelNode");
  256. do
  257. {
  258. XmlElement el, el1;
  259. // <name>
  260. el = mdlNodeEl.getChildElement("name");
  261. std::string name = el.getText();
  262. // <model>
  263. el = mdlNodeEl.getChildElement("model");
  264. // <instancesCount>
  265. el1 = mdlNodeEl.getChildElementOptional("instancesCount");
  266. U32 instancesCount = (el1) ? el1.getInt() : 1;
  267. if(instancesCount > ANKI_MAX_INSTANCES)
  268. {
  269. throw ANKI_EXCEPTION("Too many instances");
  270. }
  271. ModelNode* node;
  272. newSceneNode(node, name.c_str(), el.getText(), instancesCount);
  273. // <transform>
  274. el = mdlNodeEl.getChildElement("transform");
  275. U i = 0;
  276. do
  277. {
  278. if(i == 0)
  279. {
  280. node->setLocalTransform(Transform(el.getMat4()));
  281. node->setInstanceLocalTransform(
  282. i, Transform(el.getMat4()));
  283. }
  284. else
  285. {
  286. node->setInstanceLocalTransform(i, Transform(el.getMat4()));
  287. }
  288. // Advance
  289. el = el.getNextSiblingElement("transform");
  290. ++i;
  291. }
  292. while(el && i < instancesCount);
  293. if(i != instancesCount)
  294. {
  295. throw ANKI_EXCEPTION("instancesCount does not match "
  296. "with transform");
  297. }
  298. // Advance
  299. mdlNodeEl = mdlNodeEl.getNextSiblingElement("modelNode");
  300. } while(mdlNodeEl);
  301. }
  302. catch(const std::exception& e)
  303. {
  304. throw ANKI_EXCEPTION("Scene loading failed") << e;
  305. }
  306. }
  307. } // end namespace anki