SceneGraph.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  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/Components/BodyComponent.h>
  17. #include <AnKi/Scene/Components/CameraComponent.h>
  18. #include <AnKi/Scene/Components/DecalComponent.h>
  19. #include <AnKi/Scene/Components/FogDensityComponent.h>
  20. #include <AnKi/Scene/Components/GlobalIlluminationProbeComponent.h>
  21. #include <AnKi/Scene/Components/JointComponent.h>
  22. #include <AnKi/Scene/Components/LensFlareComponent.h>
  23. #include <AnKi/Scene/Components/LightComponent.h>
  24. #include <AnKi/Scene/Components/MoveComponent.h>
  25. #include <AnKi/Scene/Components/ParticleEmitterComponent.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. // Init the default main camera
  93. m_defaultMainCam = newSceneNode<SceneNode>("mainCamera");
  94. CameraComponent* camc = m_defaultMainCam->newComponent<CameraComponent>();
  95. camc->setPerspective(0.1f, 1000.0f, toRad(60.0f), (1080.0f / 1920.0f) * toRad(60.0f));
  96. m_mainCam = m_defaultMainCam;
  97. #define ANKI_CAT_TYPE(arrayName, gpuSceneType, id, cvarName) GpuSceneArrays::arrayName::allocateSingleton(U32(cvarName));
  98. #include <AnKi/Scene/GpuSceneArrays.def.h>
  99. RenderStateBucketContainer::allocateSingleton();
  100. // Construct a few common nodex
  101. if(g_cvarCoreDisplayStats > 0)
  102. {
  103. StatsUiNode* statsNode = newSceneNode<StatsUiNode>("_StatsUi");
  104. statsNode->setFpsOnly(g_cvarCoreDisplayStats == 1);
  105. }
  106. newSceneNode<DeveloperConsoleUiNode>("_DevConsole");
  107. return Error::kNone;
  108. }
  109. SceneNode& SceneGraph::findSceneNode(const CString& name)
  110. {
  111. SceneNode* node = tryFindSceneNode(name);
  112. ANKI_ASSERT(node);
  113. return *node;
  114. }
  115. SceneNode* SceneGraph::tryFindSceneNode(const CString& name)
  116. {
  117. // Search registered nodes
  118. auto it = m_nodesDict.find(name);
  119. if(it != m_nodesDict.getEnd())
  120. {
  121. return *it;
  122. }
  123. // Didn't found it, search those up for registration
  124. LockGuard lock(m_nodesForRegistrationMtx);
  125. for(SceneNode& node : m_nodesForRegistration)
  126. {
  127. if(node.getName() == name)
  128. {
  129. return &node;
  130. }
  131. }
  132. return nullptr;
  133. }
  134. void SceneGraph::update(Second prevUpdateTime, Second crntTime)
  135. {
  136. ANKI_ASSERT(m_mainCam);
  137. ANKI_TRACE_SCOPED_EVENT(SceneUpdate);
  138. const Second startUpdateTime = HighRezTimer::getCurrentTime();
  139. // Reset the framepool
  140. m_framePool.reset();
  141. // Register new nodes
  142. while(!m_nodesForRegistration.isEmpty())
  143. {
  144. SceneNode* node = m_nodesForRegistration.popFront();
  145. // Add to dict if it has a name
  146. if(node->getName() != "Unnamed")
  147. {
  148. if(m_nodesDict.find(node->getName()) != m_nodesDict.getEnd())
  149. {
  150. ANKI_SCENE_LOGE("Node with the same name already exists. New node will not be searchable: %s", node->getName().cstr());
  151. }
  152. else
  153. {
  154. m_nodesDict.emplace(node->getName(), node);
  155. }
  156. }
  157. // Add to list
  158. m_nodes.pushBack(node);
  159. ++m_nodesCount;
  160. }
  161. // Re-index renamed nodes
  162. for(auto& pair : m_nodesRenamed)
  163. {
  164. SceneNode& node = *pair.first;
  165. CString oldName = pair.second;
  166. auto it = m_nodesDict.find(oldName);
  167. if(it != m_nodesDict.getEnd())
  168. {
  169. m_nodesDict.erase(it);
  170. }
  171. else
  172. {
  173. ANKI_ASSERT(oldName == "Unnamed" && "Didn't found the SceneNode and its name wasn't unnamed");
  174. }
  175. if(node.getName() != "Unnamed")
  176. {
  177. if(m_nodesDict.find(node.getName()) != m_nodesDict.getEnd())
  178. {
  179. ANKI_SCENE_LOGE("Node with the same name already exists. New node will not be searchable: %s", node.getName().cstr());
  180. }
  181. else
  182. {
  183. m_nodesDict.emplace(node.getName(), &node);
  184. }
  185. }
  186. }
  187. m_nodesRenamed.destroy();
  188. // Update physics
  189. PhysicsWorld::getSingleton().update(crntTime - prevUpdateTime);
  190. // Before the update wake some threads with dummy work
  191. for(U i = 0; i < 2; i++)
  192. {
  193. CoreThreadJobManager::getSingleton().dispatchTask([]([[maybe_unused]] U32 tid) {});
  194. }
  195. // Update events
  196. {
  197. ANKI_TRACE_SCOPED_EVENT(EventsUpdate);
  198. m_events.updateAllEvents(prevUpdateTime, crntTime);
  199. }
  200. // Update events and scene nodes
  201. UpdateSceneNodesCtx updateCtx(CoreThreadJobManager::getSingleton().getThreadCount());
  202. {
  203. ANKI_TRACE_SCOPED_EVENT(SceneNodesUpdate);
  204. updateCtx.m_crntNode = m_nodes.getBegin();
  205. updateCtx.m_prevUpdateTime = prevUpdateTime;
  206. updateCtx.m_crntTime = crntTime;
  207. updateCtx.m_forceUpdateSceneBounds = (m_frame % kForceSetSceneBoundsFrameCount) == 0;
  208. for(U i = 0; i < CoreThreadJobManager::getSingleton().getThreadCount(); i++)
  209. {
  210. CoreThreadJobManager::getSingleton().dispatchTask([this, &updateCtx](U32 tid) {
  211. updateNodes(tid, updateCtx);
  212. });
  213. }
  214. CoreThreadJobManager::getSingleton().waitForAllTasksToFinish();
  215. }
  216. // Update scene bounds
  217. {
  218. Vec3 sceneMin = Vec3(kMaxF32);
  219. Vec3 sceneMax = Vec3(kMinF32);
  220. for(U32 tid = 0; tid < updateCtx.m_perThread.getSize(); ++tid)
  221. {
  222. const UpdateSceneNodesCtx::PerThread& thread = updateCtx.m_perThread[tid];
  223. sceneMin = sceneMin.min(thread.m_sceneMin);
  224. sceneMax = sceneMax.max(thread.m_sceneMax);
  225. }
  226. if(sceneMin.x() != kMaxF32)
  227. {
  228. if(updateCtx.m_forceUpdateSceneBounds)
  229. {
  230. m_sceneMin = sceneMin;
  231. m_sceneMax = sceneMax;
  232. }
  233. else
  234. {
  235. m_sceneMin = m_sceneMin.min(sceneMin);
  236. m_sceneMax = m_sceneMax.max(sceneMax);
  237. }
  238. }
  239. }
  240. // Set some unique components
  241. {
  242. m_activeDirLight = nullptr;
  243. m_activeSkybox = nullptr;
  244. Bool bMultipleDirLights = false;
  245. Bool bMultipleSkyboxes = false;
  246. for(U32 tid = 0; tid < updateCtx.m_perThread.getSize(); ++tid)
  247. {
  248. const UpdateSceneNodesCtx::PerThread& thread = updateCtx.m_perThread[tid];
  249. bMultipleDirLights = bMultipleDirLights || thread.m_multipleDirLights;
  250. bMultipleSkyboxes = bMultipleSkyboxes || thread.m_multipleSkyboxes;
  251. if(thread.m_dirLightComponent)
  252. {
  253. if(m_activeDirLight)
  254. {
  255. bMultipleDirLights = true;
  256. if(thread.m_dirLightComponent->getUuid() < m_activeDirLight->getUuid())
  257. {
  258. m_activeDirLight = thread.m_dirLightComponent;
  259. }
  260. }
  261. else
  262. {
  263. m_activeDirLight = thread.m_dirLightComponent;
  264. }
  265. }
  266. if(thread.m_skyboxComponent)
  267. {
  268. if(m_activeSkybox)
  269. {
  270. bMultipleSkyboxes = true;
  271. if(thread.m_skyboxComponent->getUuid() < m_activeSkybox->getUuid())
  272. {
  273. m_activeSkybox = thread.m_skyboxComponent;
  274. }
  275. }
  276. else
  277. {
  278. m_activeSkybox = thread.m_skyboxComponent;
  279. }
  280. }
  281. }
  282. if(bMultipleDirLights)
  283. {
  284. ANKI_SCENE_LOGW("There are multiple dir lights in the scene. Choosing one to be active");
  285. }
  286. if(bMultipleSkyboxes)
  287. {
  288. ANKI_SCENE_LOGW("There are multiple skyboxes in the scene. Choosing one to be active");
  289. }
  290. }
  291. // Cleanup
  292. for(U32 tid = 0; tid < updateCtx.m_perThread.getSize(); ++tid)
  293. {
  294. const auto& thread = updateCtx.m_perThread[tid];
  295. for(SceneNode* node : thread.m_nodesForDeletion)
  296. {
  297. // Remove from the graph
  298. m_nodes.erase(node);
  299. ANKI_ASSERT(m_nodesCount > 0);
  300. --m_nodesCount;
  301. if(m_mainCam != m_defaultMainCam && m_mainCam == node)
  302. {
  303. m_mainCam = m_defaultMainCam;
  304. }
  305. // Remove from dict
  306. if(node->getName() != "Unnamed")
  307. {
  308. auto it = m_nodesDict.find(node->getName());
  309. ANKI_ASSERT(it != m_nodesDict.getEnd());
  310. if(*it == node)
  311. {
  312. m_nodesDict.erase(it);
  313. }
  314. }
  315. deleteInstance(SceneMemoryPool::getSingleton(), node);
  316. }
  317. }
  318. // Misc
  319. #define ANKI_CAT_TYPE(arrayName, gpuSceneType, id, cvarName) GpuSceneArrays::arrayName::getSingleton().flush();
  320. #include <AnKi/Scene/GpuSceneArrays.def.h>
  321. g_svarSceneUpdateTime.set((HighRezTimer::getCurrentTime() - startUpdateTime) * 1000.0);
  322. ++m_frame;
  323. }
  324. void SceneGraph::updateNode(U32 tid, SceneNode& node, UpdateSceneNodesCtx& ctx)
  325. {
  326. ANKI_TRACE_INC_COUNTER(SceneNodeUpdated, 1);
  327. UpdateSceneNodesCtx::PerThread& thread = ctx.m_perThread[tid];
  328. // Components update
  329. SceneComponentUpdateInfo componentUpdateInfo(ctx.m_prevUpdateTime, ctx.m_crntTime, ctx.m_forceUpdateSceneBounds);
  330. componentUpdateInfo.m_framePool = &m_framePool;
  331. U32 sceneComponentUpdatedCount = 0;
  332. node.iterateComponents([&](SceneComponent& comp) {
  333. componentUpdateInfo.m_node = &node;
  334. Bool updated = false;
  335. comp.update(componentUpdateInfo, updated);
  336. if(updated)
  337. {
  338. ANKI_TRACE_INC_COUNTER(SceneComponentUpdated, 1);
  339. comp.setTimestamp(GlobalFrameIndex::getSingleton().m_value);
  340. ++sceneComponentUpdatedCount;
  341. }
  342. if(comp.getType() == SceneComponentType::kLight)
  343. {
  344. LightComponent& lc = static_cast<LightComponent&>(comp);
  345. if(lc.getLightComponentType() == LightComponentType::kDirectional)
  346. {
  347. if(thread.m_dirLightComponent)
  348. {
  349. thread.m_multipleDirLights = true;
  350. // Try to choose the same dir light in a deterministic way
  351. if(lc.getUuid() < thread.m_dirLightComponent->getUuid())
  352. {
  353. ctx.m_perThread[tid].m_dirLightComponent = &lc;
  354. }
  355. }
  356. else
  357. {
  358. ctx.m_perThread[tid].m_dirLightComponent = &lc;
  359. }
  360. }
  361. }
  362. else if(comp.getType() == SceneComponentType::kSkybox)
  363. {
  364. SkyboxComponent& skyc = static_cast<SkyboxComponent&>(comp);
  365. if(thread.m_skyboxComponent)
  366. {
  367. thread.m_multipleSkyboxes = true;
  368. // Try to choose the same skybox in a deterministic way
  369. if(skyc.getUuid() < thread.m_skyboxComponent->getUuid())
  370. {
  371. ctx.m_perThread[tid].m_skyboxComponent = &skyc;
  372. }
  373. }
  374. else
  375. {
  376. ctx.m_perThread[tid].m_skyboxComponent = &skyc;
  377. }
  378. }
  379. });
  380. // Frame update
  381. {
  382. if(sceneComponentUpdatedCount)
  383. {
  384. node.setComponentMaxTimestamp(GlobalFrameIndex::getSingleton().m_value);
  385. g_svarSceneComponentsUpdated.increment(sceneComponentUpdatedCount);
  386. g_svarSceneNodesUpdated.increment(1);
  387. }
  388. else
  389. {
  390. // No components or nothing updated, don't change the timestamp
  391. }
  392. node.frameUpdate(ctx.m_prevUpdateTime, ctx.m_crntTime);
  393. }
  394. // Update children
  395. node.visitChildrenMaxDepth(0, [&](SceneNode& child) {
  396. updateNode(tid, child, ctx);
  397. return true;
  398. });
  399. ctx.m_perThread[tid].m_sceneMin = ctx.m_perThread[tid].m_sceneMin.min(componentUpdateInfo.m_sceneMin);
  400. ctx.m_perThread[tid].m_sceneMax = ctx.m_perThread[tid].m_sceneMax.max(componentUpdateInfo.m_sceneMax);
  401. }
  402. void SceneGraph::updateNodes(U32 tid, UpdateSceneNodesCtx& ctx)
  403. {
  404. ANKI_TRACE_SCOPED_EVENT(SceneNodeUpdate);
  405. IntrusiveList<SceneNode>::ConstIterator end = m_nodes.getEnd();
  406. Bool quit = false;
  407. while(!quit)
  408. {
  409. // Fetch a batch of scene nodes that don't have parent
  410. Array<SceneNode*, kUpdateNodeBatchSize> batch;
  411. U batchSize = 0;
  412. {
  413. LockGuard<SpinLock> lock(ctx.m_crntNodeLock);
  414. while(1)
  415. {
  416. if(batchSize == batch.getSize())
  417. {
  418. break;
  419. }
  420. if(ctx.m_crntNode == end)
  421. {
  422. quit = true;
  423. break;
  424. }
  425. SceneNode& node = *ctx.m_crntNode;
  426. if(node.isMarkedForDeletion())
  427. {
  428. ctx.m_perThread[tid].m_nodesForDeletion.emplaceBack(&node);
  429. }
  430. else if(node.getParent() == nullptr)
  431. {
  432. batch[batchSize++] = &node;
  433. }
  434. else
  435. {
  436. // Ignore
  437. }
  438. ++ctx.m_crntNode;
  439. }
  440. }
  441. // Process nodes
  442. for(U i = 0; i < batchSize; ++i)
  443. {
  444. updateNode(tid, *batch[i], ctx);
  445. }
  446. }
  447. }
  448. const SceneNode& SceneGraph::getActiveCameraNode() const
  449. {
  450. ANKI_ASSERT(m_mainCam);
  451. if(ANKI_EXPECT(m_mainCam->hasComponent<CameraComponent>()))
  452. {
  453. return *m_mainCam;
  454. }
  455. else
  456. {
  457. return *m_defaultMainCam;
  458. }
  459. }
  460. void SceneGraph::setActiveCameraNode(SceneNode* cam)
  461. {
  462. if(cam)
  463. {
  464. m_mainCam = cam;
  465. }
  466. else
  467. {
  468. m_mainCam = m_defaultMainCam;
  469. }
  470. }
  471. void SceneGraph::sceneNodeChangedName(SceneNode& node, CString oldName)
  472. {
  473. LockGuard lock(m_nodesForRegistrationMtx);
  474. m_nodesRenamed.emplaceBack(std::pair(&node, oldName));
  475. }
  476. } // end namespace anki