SceneGraph.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  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. #include <AnKi/Scene/SceneGraph.h>
  6. #include <AnKi/Scene/RenderStateBucket.h>
  7. #include <AnKi/Physics/PhysicsWorld.h>
  8. #include <AnKi/Resource/ResourceManager.h>
  9. #include <AnKi/Util/CVarSet.h>
  10. #include <AnKi/Core/StatsSet.h>
  11. #include <AnKi/Util/Tracer.h>
  12. #include <AnKi/Util/HighRezTimer.h>
  13. #include <AnKi/Core/App.h>
  14. #include <AnKi/Scene/StatsUiNode.h>
  15. #include <AnKi/Scene/DeveloperConsoleUiNode.h>
  16. #include <AnKi/Scene/EditorUiNode.h>
  17. #include <AnKi/Scene/Components/BodyComponent.h>
  18. #include <AnKi/Scene/Components/CameraComponent.h>
  19. #include <AnKi/Scene/Components/DecalComponent.h>
  20. #include <AnKi/Scene/Components/FogDensityComponent.h>
  21. #include <AnKi/Scene/Components/GlobalIlluminationProbeComponent.h>
  22. #include <AnKi/Scene/Components/JointComponent.h>
  23. #include <AnKi/Scene/Components/LensFlareComponent.h>
  24. #include <AnKi/Scene/Components/LightComponent.h>
  25. #include <AnKi/Scene/Components/MoveComponent.h>
  26. #include <AnKi/Scene/Components/ParticleEmitter2Component.h>
  27. #include <AnKi/Scene/Components/PlayerControllerComponent.h>
  28. #include <AnKi/Scene/Components/ReflectionProbeComponent.h>
  29. #include <AnKi/Scene/Components/ScriptComponent.h>
  30. #include <AnKi/Scene/Components/SkinComponent.h>
  31. #include <AnKi/Scene/Components/SkyboxComponent.h>
  32. #include <AnKi/Scene/Components/TriggerComponent.h>
  33. #include <AnKi/Scene/Components/UiComponent.h>
  34. #include <AnKi/Scene/Components/MeshComponent.h>
  35. #include <AnKi/Scene/Components/MaterialComponent.h>
  36. namespace anki {
  37. ANKI_SVAR(SceneUpdateTime, StatCategory::kTime, "All scene update", StatFlag::kMilisecond | StatFlag::kShowAverage | StatFlag::kMainThreadUpdates)
  38. ANKI_SVAR(SceneComponentsUpdated, StatCategory::kScene, "Scene components updated per frame", StatFlag::kZeroEveryFrame)
  39. ANKI_SVAR(SceneNodesUpdated, StatCategory::kScene, "Scene nodes updated per frame", StatFlag::kZeroEveryFrame)
  40. constexpr U32 kUpdateNodeBatchSize = 10;
  41. class SceneGraph::UpdateSceneNodesCtx
  42. {
  43. public:
  44. class PerThread
  45. {
  46. public:
  47. DynamicArray<SceneNode*, MemoryPoolPtrWrapper<StackMemoryPool>> m_nodesForDeletion;
  48. LightComponent* m_dirLightComponent = nullptr;
  49. SkyboxComponent* m_skyboxComponent = nullptr;
  50. Vec3 m_sceneMin = Vec3(kMaxF32);
  51. Vec3 m_sceneMax = Vec3(kMinF32);
  52. Bool m_multipleDirLights = false;
  53. Bool m_multipleSkyboxes = false;
  54. PerThread()
  55. : m_nodesForDeletion(&SceneGraph::getSingleton().m_framePool)
  56. {
  57. }
  58. };
  59. IntrusiveList<SceneNode>::Iterator m_crntNode;
  60. SpinLock m_crntNodeLock;
  61. Second m_prevUpdateTime = 0.0;
  62. Second m_crntTime = 0.0;
  63. DynamicArray<PerThread, MemoryPoolPtrWrapper<StackMemoryPool>> m_perThread;
  64. Bool m_forceUpdateSceneBounds = false;
  65. UpdateSceneNodesCtx(U32 threadCount)
  66. : m_perThread(&SceneGraph::getSingleton().m_framePool)
  67. {
  68. m_perThread.resize(threadCount);
  69. }
  70. };
  71. SceneGraph::SceneGraph()
  72. {
  73. }
  74. SceneGraph::~SceneGraph()
  75. {
  76. while(!m_nodesForRegistration.isEmpty())
  77. {
  78. deleteInstance(SceneMemoryPool::getSingleton(), m_nodesForRegistration.popBack());
  79. }
  80. while(!m_nodes.isEmpty())
  81. {
  82. deleteInstance(SceneMemoryPool::getSingleton(), m_nodes.popBack());
  83. }
  84. #define ANKI_CAT_TYPE(arrayName, gpuSceneType, id, cvarName) GpuSceneArrays::arrayName::freeSingleton();
  85. #include <AnKi/Scene/GpuSceneArrays.def.h>
  86. RenderStateBucketContainer::freeSingleton();
  87. }
  88. Error SceneGraph::init(AllocAlignedCallback allocCallback, void* allocCallbackData)
  89. {
  90. SceneMemoryPool::allocateSingleton(allocCallback, allocCallbackData);
  91. m_framePool.init(allocCallback, allocCallbackData, 1_MB, 2.0, 0, true, "SceneGraphFramePool");
  92. #define ANKI_CAT_TYPE(arrayName, gpuSceneType, id, cvarName) GpuSceneArrays::arrayName::allocateSingleton(U32(cvarName));
  93. #include <AnKi/Scene/GpuSceneArrays.def.h>
  94. // Init the default main camera
  95. m_defaultMainCam = newSceneNode<SceneNode>("_MainCamera");
  96. CameraComponent* camc = m_defaultMainCam->newComponent<CameraComponent>();
  97. camc->setPerspective(0.1f, 1000.0f, toRad(60.0f), (1080.0f / 1920.0f) * toRad(60.0f));
  98. m_mainCam = m_defaultMainCam;
  99. RenderStateBucketContainer::allocateSingleton();
  100. // Construct a few common nodes
  101. if(g_cvarCoreDisplayStats > 0)
  102. {
  103. StatsUiNode* statsNode = newSceneNode<StatsUiNode>("_StatsUi");
  104. statsNode->setFpsOnly(g_cvarCoreDisplayStats == 1);
  105. }
  106. newSceneNode<DeveloperConsoleUiNode>("_DevConsole");
  107. EditorUiNode* editorNode = newSceneNode<EditorUiNode>("_Editor");
  108. editorNode->getFirstComponentOfType<UiComponent>().setEnabled(false);
  109. m_editorUi = editorNode;
  110. return Error::kNone;
  111. }
  112. SceneNode& SceneGraph::findSceneNode(const CString& name)
  113. {
  114. SceneNode* node = tryFindSceneNode(name);
  115. ANKI_ASSERT(node);
  116. return *node;
  117. }
  118. SceneNode* SceneGraph::tryFindSceneNode(const CString& name)
  119. {
  120. // Search registered nodes
  121. auto it = m_nodesDict.find(name);
  122. if(it != m_nodesDict.getEnd())
  123. {
  124. return *it;
  125. }
  126. // Didn't found it, search those up for registration
  127. LockGuard lock(m_nodesForRegistrationMtx);
  128. for(SceneNode& node : m_nodesForRegistration)
  129. {
  130. if(node.getName() == name)
  131. {
  132. return &node;
  133. }
  134. }
  135. return nullptr;
  136. }
  137. void SceneGraph::update(Second prevUpdateTime, Second crntTime)
  138. {
  139. ANKI_ASSERT(m_mainCam);
  140. ANKI_TRACE_SCOPED_EVENT(SceneUpdate);
  141. const Second startUpdateTime = HighRezTimer::getCurrentTime();
  142. // Reset the framepool
  143. m_framePool.reset();
  144. // Register new nodes
  145. while(!m_nodesForRegistration.isEmpty())
  146. {
  147. SceneNode* node = m_nodesForRegistration.popFront();
  148. // Add to dict if it has a name
  149. if(node->getName() != "Unnamed")
  150. {
  151. if(m_nodesDict.find(node->getName()) != m_nodesDict.getEnd())
  152. {
  153. ANKI_SCENE_LOGE("Node with the same name already exists. New node will not be searchable: %s", node->getName().cstr());
  154. }
  155. else
  156. {
  157. m_nodesDict.emplace(node->getName(), node);
  158. }
  159. }
  160. // Add to list
  161. m_nodes.pushBack(node);
  162. ++m_nodesCount;
  163. }
  164. // Re-index renamed nodes
  165. for(auto& pair : m_nodesRenamed)
  166. {
  167. SceneNode& node = *pair.first;
  168. CString oldName = pair.second;
  169. auto it = m_nodesDict.find(oldName);
  170. if(it != m_nodesDict.getEnd())
  171. {
  172. m_nodesDict.erase(it);
  173. }
  174. else
  175. {
  176. ANKI_ASSERT(oldName == "Unnamed" && "Didn't found the SceneNode and its name wasn't unnamed");
  177. }
  178. if(node.getName() != "Unnamed")
  179. {
  180. if(m_nodesDict.find(node.getName()) != m_nodesDict.getEnd())
  181. {
  182. ANKI_SCENE_LOGE("Node with the same name already exists. New node will not be searchable: %s", node.getName().cstr());
  183. }
  184. else
  185. {
  186. m_nodesDict.emplace(node.getName(), &node);
  187. }
  188. }
  189. }
  190. m_nodesRenamed.destroy();
  191. // Update physics
  192. PhysicsWorld::getSingleton().update(crntTime - prevUpdateTime);
  193. // Before the update wake some threads with dummy work
  194. for(U i = 0; i < 2; i++)
  195. {
  196. CoreThreadJobManager::getSingleton().dispatchTask([]([[maybe_unused]] U32 tid) {});
  197. }
  198. // Update events
  199. {
  200. ANKI_TRACE_SCOPED_EVENT(EventsUpdate);
  201. m_events.updateAllEvents(prevUpdateTime, crntTime);
  202. }
  203. // Update events and scene nodes
  204. UpdateSceneNodesCtx updateCtx(CoreThreadJobManager::getSingleton().getThreadCount());
  205. {
  206. ANKI_TRACE_SCOPED_EVENT(SceneNodesUpdate);
  207. updateCtx.m_crntNode = m_nodes.getBegin();
  208. updateCtx.m_prevUpdateTime = prevUpdateTime;
  209. updateCtx.m_crntTime = crntTime;
  210. updateCtx.m_forceUpdateSceneBounds = (m_frame % kForceSetSceneBoundsFrameCount) == 0;
  211. for(U i = 0; i < CoreThreadJobManager::getSingleton().getThreadCount(); i++)
  212. {
  213. CoreThreadJobManager::getSingleton().dispatchTask([this, &updateCtx](U32 tid) {
  214. updateNodes(tid, updateCtx);
  215. });
  216. }
  217. CoreThreadJobManager::getSingleton().waitForAllTasksToFinish();
  218. }
  219. // Update scene bounds
  220. {
  221. Vec3 sceneMin = Vec3(kMaxF32);
  222. Vec3 sceneMax = Vec3(kMinF32);
  223. for(U32 tid = 0; tid < updateCtx.m_perThread.getSize(); ++tid)
  224. {
  225. const UpdateSceneNodesCtx::PerThread& thread = updateCtx.m_perThread[tid];
  226. sceneMin = sceneMin.min(thread.m_sceneMin);
  227. sceneMax = sceneMax.max(thread.m_sceneMax);
  228. }
  229. if(sceneMin.x() != kMaxF32)
  230. {
  231. if(updateCtx.m_forceUpdateSceneBounds)
  232. {
  233. m_sceneMin = sceneMin;
  234. m_sceneMax = sceneMax;
  235. }
  236. else
  237. {
  238. m_sceneMin = m_sceneMin.min(sceneMin);
  239. m_sceneMax = m_sceneMax.max(sceneMax);
  240. }
  241. }
  242. }
  243. // Set some unique components
  244. {
  245. m_activeDirLight = nullptr;
  246. m_activeSkybox = nullptr;
  247. Bool bMultipleDirLights = false;
  248. Bool bMultipleSkyboxes = false;
  249. for(U32 tid = 0; tid < updateCtx.m_perThread.getSize(); ++tid)
  250. {
  251. const UpdateSceneNodesCtx::PerThread& thread = updateCtx.m_perThread[tid];
  252. bMultipleDirLights = bMultipleDirLights || thread.m_multipleDirLights;
  253. bMultipleSkyboxes = bMultipleSkyboxes || thread.m_multipleSkyboxes;
  254. if(thread.m_dirLightComponent)
  255. {
  256. if(m_activeDirLight)
  257. {
  258. bMultipleDirLights = true;
  259. if(thread.m_dirLightComponent->getUuid() < m_activeDirLight->getUuid())
  260. {
  261. m_activeDirLight = thread.m_dirLightComponent;
  262. }
  263. }
  264. else
  265. {
  266. m_activeDirLight = thread.m_dirLightComponent;
  267. }
  268. }
  269. if(thread.m_skyboxComponent)
  270. {
  271. if(m_activeSkybox)
  272. {
  273. bMultipleSkyboxes = true;
  274. if(thread.m_skyboxComponent->getUuid() < m_activeSkybox->getUuid())
  275. {
  276. m_activeSkybox = thread.m_skyboxComponent;
  277. }
  278. }
  279. else
  280. {
  281. m_activeSkybox = thread.m_skyboxComponent;
  282. }
  283. }
  284. }
  285. if(bMultipleDirLights)
  286. {
  287. ANKI_SCENE_LOGW("There are multiple dir lights in the scene. Choosing one to be active");
  288. }
  289. if(bMultipleSkyboxes)
  290. {
  291. ANKI_SCENE_LOGW("There are multiple skyboxes in the scene. Choosing one to be active");
  292. }
  293. }
  294. // Cleanup
  295. for(U32 tid = 0; tid < updateCtx.m_perThread.getSize(); ++tid)
  296. {
  297. const auto& thread = updateCtx.m_perThread[tid];
  298. for(SceneNode* node : thread.m_nodesForDeletion)
  299. {
  300. // Remove from the graph
  301. m_nodes.erase(node);
  302. ANKI_ASSERT(m_nodesCount > 0);
  303. --m_nodesCount;
  304. if(m_mainCam != m_defaultMainCam && m_mainCam == node)
  305. {
  306. m_mainCam = m_defaultMainCam;
  307. }
  308. // Remove from dict
  309. if(node->getName() != "Unnamed")
  310. {
  311. auto it = m_nodesDict.find(node->getName());
  312. ANKI_ASSERT(it != m_nodesDict.getEnd());
  313. if(*it == node)
  314. {
  315. m_nodesDict.erase(it);
  316. }
  317. }
  318. deleteInstance(SceneMemoryPool::getSingleton(), node);
  319. }
  320. }
  321. // Misc
  322. #define ANKI_CAT_TYPE(arrayName, gpuSceneType, id, cvarName) GpuSceneArrays::arrayName::getSingleton().flush();
  323. #include <AnKi/Scene/GpuSceneArrays.def.h>
  324. g_svarSceneUpdateTime.set((HighRezTimer::getCurrentTime() - startUpdateTime) * 1000.0);
  325. ++m_frame;
  326. }
  327. void SceneGraph::updateNode(U32 tid, SceneNode& node, UpdateSceneNodesCtx& ctx)
  328. {
  329. ANKI_TRACE_INC_COUNTER(SceneNodeUpdated, 1);
  330. UpdateSceneNodesCtx::PerThread& thread = ctx.m_perThread[tid];
  331. // Components update
  332. SceneComponentUpdateInfo componentUpdateInfo(ctx.m_prevUpdateTime, ctx.m_crntTime, ctx.m_forceUpdateSceneBounds, m_checkForResourceUpdates);
  333. componentUpdateInfo.m_framePool = &m_framePool;
  334. U32 sceneComponentUpdatedCount = 0;
  335. node.iterateComponents([&](SceneComponent& comp) {
  336. componentUpdateInfo.m_node = &node;
  337. Bool updated = false;
  338. comp.update(componentUpdateInfo, updated);
  339. if(updated)
  340. {
  341. ANKI_TRACE_INC_COUNTER(SceneComponentUpdated, 1);
  342. comp.setTimestamp(GlobalFrameIndex::getSingleton().m_value);
  343. ++sceneComponentUpdatedCount;
  344. }
  345. if(comp.getType() == SceneComponentType::kLight)
  346. {
  347. LightComponent& lc = static_cast<LightComponent&>(comp);
  348. if(lc.getLightComponentType() == LightComponentType::kDirectional)
  349. {
  350. if(thread.m_dirLightComponent)
  351. {
  352. thread.m_multipleDirLights = true;
  353. // Try to choose the same dir light in a deterministic way
  354. if(lc.getUuid() < thread.m_dirLightComponent->getUuid())
  355. {
  356. ctx.m_perThread[tid].m_dirLightComponent = &lc;
  357. }
  358. }
  359. else
  360. {
  361. ctx.m_perThread[tid].m_dirLightComponent = &lc;
  362. }
  363. }
  364. }
  365. else if(comp.getType() == SceneComponentType::kSkybox)
  366. {
  367. SkyboxComponent& skyc = static_cast<SkyboxComponent&>(comp);
  368. if(thread.m_skyboxComponent)
  369. {
  370. thread.m_multipleSkyboxes = true;
  371. // Try to choose the same skybox in a deterministic way
  372. if(skyc.getUuid() < thread.m_skyboxComponent->getUuid())
  373. {
  374. ctx.m_perThread[tid].m_skyboxComponent = &skyc;
  375. }
  376. }
  377. else
  378. {
  379. ctx.m_perThread[tid].m_skyboxComponent = &skyc;
  380. }
  381. }
  382. });
  383. // Frame update
  384. {
  385. if(sceneComponentUpdatedCount)
  386. {
  387. node.setComponentMaxTimestamp(GlobalFrameIndex::getSingleton().m_value);
  388. g_svarSceneComponentsUpdated.increment(sceneComponentUpdatedCount);
  389. g_svarSceneNodesUpdated.increment(1);
  390. }
  391. else
  392. {
  393. // No components or nothing updated, don't change the timestamp
  394. }
  395. node.frameUpdate(ctx.m_prevUpdateTime, ctx.m_crntTime);
  396. }
  397. // Update children
  398. node.visitChildrenMaxDepth(0, [&](SceneNode& child) {
  399. updateNode(tid, child, ctx);
  400. return FunctorContinue::kContinue;
  401. });
  402. ctx.m_perThread[tid].m_sceneMin = ctx.m_perThread[tid].m_sceneMin.min(componentUpdateInfo.m_sceneMin);
  403. ctx.m_perThread[tid].m_sceneMax = ctx.m_perThread[tid].m_sceneMax.max(componentUpdateInfo.m_sceneMax);
  404. }
  405. void SceneGraph::updateNodes(U32 tid, UpdateSceneNodesCtx& ctx)
  406. {
  407. ANKI_TRACE_SCOPED_EVENT(SceneNodeUpdate);
  408. IntrusiveList<SceneNode>::ConstIterator end = m_nodes.getEnd();
  409. Bool quit = false;
  410. while(!quit)
  411. {
  412. // Fetch a batch of scene nodes that don't have parent
  413. Array<SceneNode*, kUpdateNodeBatchSize> batch;
  414. U batchSize = 0;
  415. {
  416. LockGuard<SpinLock> lock(ctx.m_crntNodeLock);
  417. while(1)
  418. {
  419. if(batchSize == batch.getSize())
  420. {
  421. break;
  422. }
  423. if(ctx.m_crntNode == end)
  424. {
  425. quit = true;
  426. break;
  427. }
  428. SceneNode& node = *ctx.m_crntNode;
  429. if(node.isMarkedForDeletion())
  430. {
  431. ctx.m_perThread[tid].m_nodesForDeletion.emplaceBack(&node);
  432. }
  433. else if(node.getParent() == nullptr)
  434. {
  435. batch[batchSize++] = &node;
  436. }
  437. else
  438. {
  439. // Ignore
  440. }
  441. ++ctx.m_crntNode;
  442. }
  443. }
  444. // Process nodes
  445. for(U i = 0; i < batchSize; ++i)
  446. {
  447. updateNode(tid, *batch[i], ctx);
  448. }
  449. }
  450. }
  451. const SceneNode& SceneGraph::getActiveCameraNode() const
  452. {
  453. ANKI_ASSERT(m_mainCam);
  454. if(ANKI_EXPECT(m_mainCam->hasComponent<CameraComponent>()))
  455. {
  456. return *m_mainCam;
  457. }
  458. else
  459. {
  460. return *m_defaultMainCam;
  461. }
  462. }
  463. void SceneGraph::setActiveCameraNode(SceneNode* cam)
  464. {
  465. if(cam)
  466. {
  467. m_mainCam = cam;
  468. }
  469. else
  470. {
  471. m_mainCam = m_defaultMainCam;
  472. }
  473. }
  474. void SceneGraph::sceneNodeChangedName(SceneNode& node, CString oldName)
  475. {
  476. LockGuard lock(m_nodesForRegistrationMtx);
  477. m_nodesRenamed.emplaceBack(std::pair(&node, oldName));
  478. }
  479. Error SceneGraph::saveToTextFile(CString filename)
  480. {
  481. File file;
  482. ANKI_CHECK(file.open(filename, FileOpenFlag::kWrite));
  483. TextSceneSerializer serializer(&file, true);
  484. U32 version = kSceneBinaryVersion;
  485. ANKI_SERIALIZE(version, 1);
  486. #define ANKI_DEFINE_SCENE_COMPONENT(name, weight, sceneNodeCanHaveMany, icon, serializable) \
  487. if(serializable) \
  488. { \
  489. U32 name##Count = m_componentArrays.get##name##s().getSize(); \
  490. ANKI_SERIALIZE(name##Count, 1); \
  491. for(SceneComponent & comp : m_componentArrays.get##name##s()) \
  492. { \
  493. U32 uuid = comp.getUuid(); \
  494. ANKI_SERIALIZE(uuid, 1); \
  495. ANKI_CHECK(comp.serialize(serializer)); \
  496. } \
  497. }
  498. #include <AnKi/Scene/Components/SceneComponentClasses.def.h>
  499. // Scene nodes
  500. Error err = Error::kNone;
  501. visitNodes([&](SceneNode& node) {
  502. if(node.getParent() != nullptr)
  503. {
  504. // Skip non-root nodes
  505. return FunctorContinue::kContinue;
  506. }
  507. node.visitThisAndChildren([&](SceneNode& node) {
  508. err = node.serializeCommon(serializer);
  509. if(err)
  510. {
  511. return FunctorContinue::kStop;
  512. }
  513. return FunctorContinue::kContinue;
  514. });
  515. if(err)
  516. {
  517. return FunctorContinue::kStop;
  518. }
  519. return FunctorContinue::kContinue;
  520. });
  521. if(err)
  522. {
  523. return err;
  524. }
  525. return Error::kNone;
  526. }
  527. } // end namespace anki