SceneGraph.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  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/PlayerControllerComponent.h>
  27. #include <AnKi/Scene/Components/ReflectionProbeComponent.h>
  28. #include <AnKi/Scene/Components/ScriptComponent.h>
  29. #include <AnKi/Scene/Components/SkinComponent.h>
  30. #include <AnKi/Scene/Components/SkyboxComponent.h>
  31. #include <AnKi/Scene/Components/TriggerComponent.h>
  32. #include <AnKi/Scene/Components/UiComponent.h>
  33. #include <AnKi/Scene/Components/MeshComponent.h>
  34. #include <AnKi/Scene/Components/MaterialComponent.h>
  35. namespace anki {
  36. static StatCounter g_sceneUpdateTimeStatVar(StatCategory::kTime, "All scene update",
  37. StatFlag::kMilisecond | StatFlag::kShowAverage | StatFlag::kMainThreadUpdates);
  38. static StatCounter g_sceneComponentsUpdatedStatVar(StatCategory::kScene, "Scene components updated per frame", StatFlag::kZeroEveryFrame);
  39. static StatCounter g_sceneNodesUpdatedStatVar(StatCategory::kScene, "Scene nodes updated per frame", StatFlag::kZeroEveryFrame);
  40. constexpr U32 kUpdateNodeBatchSize = 10;
  41. class SceneGraph::UpdateSceneNodesCtx
  42. {
  43. public:
  44. IntrusiveList<SceneNode>::Iterator m_crntNode;
  45. SpinLock m_crntNodeLock;
  46. Second m_prevUpdateTime;
  47. Second m_crntTime;
  48. DynamicArray<SceneNode*, MemoryPoolPtrWrapper<StackMemoryPool>> m_nodesForDeletion;
  49. UpdateSceneNodesCtx()
  50. : m_nodesForDeletion(&SceneGraph::getSingleton().m_framePool)
  51. {
  52. }
  53. };
  54. SceneGraph::SceneGraph()
  55. {
  56. }
  57. SceneGraph::~SceneGraph()
  58. {
  59. while(!m_nodesForRegistration.isEmpty())
  60. {
  61. deleteInstance(SceneMemoryPool::getSingleton(), m_nodesForRegistration.popBack());
  62. }
  63. while(!m_nodes.isEmpty())
  64. {
  65. deleteInstance(SceneMemoryPool::getSingleton(), m_nodes.popBack());
  66. }
  67. #define ANKI_CAT_TYPE(arrayName, gpuSceneType, id, cvarName) GpuSceneArrays::arrayName::freeSingleton();
  68. #include <AnKi/Scene/GpuSceneArrays.def.h>
  69. RenderStateBucketContainer::freeSingleton();
  70. }
  71. Error SceneGraph::init(AllocAlignedCallback allocCallback, void* allocCallbackData)
  72. {
  73. SceneMemoryPool::allocateSingleton(allocCallback, allocCallbackData);
  74. m_framePool.init(allocCallback, allocCallbackData, 1_MB, 2.0, 0, true, "SceneGraphFramePool");
  75. // Init the default main camera
  76. m_defaultMainCam = newSceneNode<SceneNode>("mainCamera");
  77. CameraComponent* camc = m_defaultMainCam->newComponent<CameraComponent>();
  78. camc->setPerspective(0.1f, 1000.0f, toRad(60.0f), (1080.0f / 1920.0f) * toRad(60.0f));
  79. m_mainCam = m_defaultMainCam;
  80. #define ANKI_CAT_TYPE(arrayName, gpuSceneType, id, cvarName) GpuSceneArrays::arrayName::allocateSingleton(U32(cvarName));
  81. #include <AnKi/Scene/GpuSceneArrays.def.h>
  82. RenderStateBucketContainer::allocateSingleton();
  83. // Construct a few common nodex
  84. if(g_displayStatsCVar > 0)
  85. {
  86. StatsUiNode* statsNode = newSceneNode<StatsUiNode>("_StatsUi");
  87. statsNode->setFpsOnly(g_displayStatsCVar == 1);
  88. }
  89. newSceneNode<DeveloperConsoleUiNode>("_DevConsole");
  90. return Error::kNone;
  91. }
  92. SceneNode& SceneGraph::findSceneNode(const CString& name)
  93. {
  94. SceneNode* node = tryFindSceneNode(name);
  95. ANKI_ASSERT(node);
  96. return *node;
  97. }
  98. SceneNode* SceneGraph::tryFindSceneNode(const CString& name)
  99. {
  100. // Search registered nodes
  101. auto it = m_nodesDict.find(name);
  102. if(it != m_nodesDict.getEnd())
  103. {
  104. return *it;
  105. }
  106. // Didn't found it, search those up for registration
  107. LockGuard lock(m_nodesForRegistrationMtx);
  108. for(SceneNode& node : m_nodesForRegistration)
  109. {
  110. if(node.getName() == name)
  111. {
  112. return &node;
  113. }
  114. }
  115. return nullptr;
  116. }
  117. void SceneGraph::update(Second prevUpdateTime, Second crntTime)
  118. {
  119. ANKI_ASSERT(m_mainCam);
  120. ANKI_TRACE_SCOPED_EVENT(SceneUpdate);
  121. const Second startUpdateTime = HighRezTimer::getCurrentTime();
  122. // Reset the framepool
  123. m_framePool.reset();
  124. // Register new nodes
  125. while(!m_nodesForRegistration.isEmpty())
  126. {
  127. SceneNode* node = m_nodesForRegistration.popFront();
  128. // Add to dict if it has a name
  129. if(node->getName())
  130. {
  131. if(tryFindSceneNode(node->getName()))
  132. {
  133. ANKI_SCENE_LOGE("Node with the same name already exists. New node will not be searchable: %s", node->getName().cstr());
  134. }
  135. else
  136. {
  137. m_nodesDict.emplace(node->getName(), node);
  138. }
  139. }
  140. // Add to list
  141. m_nodes.pushBack(node);
  142. ++m_nodesCount;
  143. }
  144. // Update physics
  145. PhysicsWorld::getSingleton().update(crntTime - prevUpdateTime);
  146. // Before the update wake some threads with dummy work
  147. for(U i = 0; i < 2; i++)
  148. {
  149. CoreThreadJobManager::getSingleton().dispatchTask([]([[maybe_unused]] U32 tid) {});
  150. }
  151. // Update events and scene nodes
  152. UpdateSceneNodesCtx updateCtx;
  153. {
  154. ANKI_TRACE_SCOPED_EVENT(SceneNodesUpdate);
  155. m_events.updateAllEvents(prevUpdateTime, crntTime);
  156. updateCtx.m_crntNode = m_nodes.getBegin();
  157. updateCtx.m_prevUpdateTime = prevUpdateTime;
  158. updateCtx.m_crntTime = crntTime;
  159. for(U i = 0; i < CoreThreadJobManager::getSingleton().getThreadCount(); i++)
  160. {
  161. CoreThreadJobManager::getSingleton().dispatchTask([this, &updateCtx]([[maybe_unused]] U32 tid) {
  162. updateNodes(updateCtx);
  163. });
  164. }
  165. CoreThreadJobManager::getSingleton().waitForAllTasksToFinish();
  166. }
  167. // Cleanup
  168. for(SceneNode* node : updateCtx.m_nodesForDeletion)
  169. {
  170. // Remove from the graph
  171. m_nodes.erase(node);
  172. ANKI_ASSERT(m_nodesCount > 0);
  173. --m_nodesCount;
  174. if(m_mainCam != m_defaultMainCam && m_mainCam == node)
  175. {
  176. m_mainCam = m_defaultMainCam;
  177. }
  178. // Remove from dict
  179. if(node->getName())
  180. {
  181. auto it = m_nodesDict.find(node->getName());
  182. ANKI_ASSERT(it != m_nodesDict.getEnd());
  183. if(*it == node)
  184. {
  185. m_nodesDict.erase(it);
  186. }
  187. }
  188. deleteInstance(SceneMemoryPool::getSingleton(), node);
  189. }
  190. updateCtx.m_nodesForDeletion.destroy();
  191. #define ANKI_CAT_TYPE(arrayName, gpuSceneType, id, cvarName) GpuSceneArrays::arrayName::getSingleton().flush();
  192. #include <AnKi/Scene/GpuSceneArrays.def.h>
  193. g_sceneUpdateTimeStatVar.set((HighRezTimer::getCurrentTime() - startUpdateTime) * 1000.0);
  194. }
  195. void SceneGraph::updateNode(Second prevTime, Second crntTime, SceneNode& node)
  196. {
  197. ANKI_TRACE_INC_COUNTER(SceneNodeUpdated, 1);
  198. // Components update
  199. SceneComponentUpdateInfo componentUpdateInfo(prevTime, crntTime);
  200. componentUpdateInfo.m_framePool = &m_framePool;
  201. U32 sceneComponentUpdatedCount = 0;
  202. node.iterateComponents([&](SceneComponent& comp) {
  203. componentUpdateInfo.m_node = &node;
  204. Bool updated = false;
  205. comp.update(componentUpdateInfo, updated);
  206. if(updated)
  207. {
  208. ANKI_TRACE_INC_COUNTER(SceneComponentUpdated, 1);
  209. comp.setTimestamp(GlobalFrameIndex::getSingleton().m_value);
  210. ++sceneComponentUpdatedCount;
  211. }
  212. });
  213. // Update children
  214. node.visitChildrenMaxDepth(0, [&](SceneNode& child) {
  215. updateNode(prevTime, crntTime, child);
  216. return true;
  217. });
  218. // Frame update
  219. {
  220. if(sceneComponentUpdatedCount)
  221. {
  222. node.setComponentMaxTimestamp(GlobalFrameIndex::getSingleton().m_value);
  223. g_sceneComponentsUpdatedStatVar.increment(sceneComponentUpdatedCount);
  224. g_sceneNodesUpdatedStatVar.increment(1);
  225. }
  226. else
  227. {
  228. // No components or nothing updated, don't change the timestamp
  229. }
  230. node.frameUpdate(prevTime, crntTime);
  231. }
  232. }
  233. void SceneGraph::updateNodes(UpdateSceneNodesCtx& ctx)
  234. {
  235. ANKI_TRACE_SCOPED_EVENT(SceneNodeUpdate);
  236. IntrusiveList<SceneNode>::ConstIterator end = m_nodes.getEnd();
  237. Bool quit = false;
  238. while(!quit)
  239. {
  240. // Fetch a batch of scene nodes that don't have parent
  241. Array<SceneNode*, kUpdateNodeBatchSize> batch;
  242. U batchSize = 0;
  243. {
  244. LockGuard<SpinLock> lock(ctx.m_crntNodeLock);
  245. while(1)
  246. {
  247. if(batchSize == batch.getSize())
  248. {
  249. break;
  250. }
  251. if(ctx.m_crntNode == end)
  252. {
  253. quit = true;
  254. break;
  255. }
  256. SceneNode& node = *ctx.m_crntNode;
  257. if(node.isMarkedForDeletion())
  258. {
  259. ctx.m_nodesForDeletion.emplaceBack(&node);
  260. }
  261. else if(node.getParent() == nullptr)
  262. {
  263. batch[batchSize++] = &node;
  264. }
  265. else
  266. {
  267. // Ignore
  268. }
  269. ++ctx.m_crntNode;
  270. }
  271. }
  272. // Process nodes
  273. for(U i = 0; i < batchSize; ++i)
  274. {
  275. updateNode(ctx.m_prevUpdateTime, ctx.m_crntTime, *batch[i]);
  276. }
  277. }
  278. }
  279. LightComponent* SceneGraph::getDirectionalLight() const
  280. {
  281. LightComponent* out = (m_dirLights.getSize()) ? m_dirLights[0] : nullptr;
  282. if(out)
  283. {
  284. ANKI_ASSERT(out->getLightComponentType() == LightComponentType::kDirectional);
  285. }
  286. return out;
  287. }
  288. } // end namespace anki