BsSceneManager.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Scene/BsSceneManager.h"
  4. #include "Scene/BsSceneObject.h"
  5. #include "Scene/BsComponent.h"
  6. #include "Renderer/BsRenderable.h"
  7. #include "Renderer/BsCamera.h"
  8. #include "Renderer/BsLight.h"
  9. #include "Renderer/BsReflectionProbe.h"
  10. #include "RenderAPI/BsViewport.h"
  11. #include "Scene/BsGameObjectManager.h"
  12. #include "RenderAPI/BsRenderTarget.h"
  13. #include "Renderer/BsLightProbeVolume.h"
  14. namespace bs
  15. {
  16. enum ListType
  17. {
  18. ActiveList = 0,
  19. InactiveList = 1,
  20. UninitializedList = 2
  21. };
  22. SceneManager::SceneManager()
  23. {
  24. mRootNode = SceneObject::createInternal("SceneRoot");
  25. }
  26. SceneManager::~SceneManager()
  27. {
  28. if (mRootNode != nullptr && !mRootNode.isDestroyed())
  29. mRootNode->destroy(true);
  30. }
  31. void SceneManager::clearScene(bool forceAll)
  32. {
  33. UINT32 numChildren = mRootNode->getNumChildren();
  34. UINT32 curIdx = 0;
  35. for (UINT32 i = 0; i < numChildren; i++)
  36. {
  37. HSceneObject child = mRootNode->getChild(curIdx);
  38. if (forceAll || !child->hasFlag(SOF_Persistent))
  39. child->destroy();
  40. else
  41. curIdx++;
  42. }
  43. GameObjectManager::instance().destroyQueuedObjects();
  44. HSceneObject newRoot = SceneObject::createInternal("SceneRoot");
  45. _setRootNode(newRoot);
  46. }
  47. void SceneManager::_setRootNode(const HSceneObject& root)
  48. {
  49. if (root == nullptr)
  50. return;
  51. HSceneObject oldRoot = mRootNode;
  52. UINT32 numChildren = oldRoot->getNumChildren();
  53. // Make sure to keep persistent objects
  54. bs_frame_mark();
  55. {
  56. FrameVector<HSceneObject> toRemove;
  57. for (UINT32 i = 0; i < numChildren; i++)
  58. {
  59. HSceneObject child = oldRoot->getChild(i);
  60. if (child->hasFlag(SOF_Persistent))
  61. toRemove.push_back(child);
  62. }
  63. for (auto& entry : toRemove)
  64. entry->setParent(root, false);
  65. }
  66. bs_frame_clear();
  67. mRootNode = root;
  68. mRootNode->_setParent(HSceneObject());
  69. oldRoot->destroy();
  70. }
  71. void SceneManager::_registerRenderable(const SPtr<Renderable>& renderable, const HSceneObject& so)
  72. {
  73. mRenderables[renderable.get()] = SceneRenderableData(renderable, so);
  74. }
  75. void SceneManager::_unregisterRenderable(const SPtr<Renderable>& renderable)
  76. {
  77. mRenderables.erase(renderable.get());
  78. }
  79. void SceneManager::_registerLight(const SPtr<Light>& light, const HSceneObject& so)
  80. {
  81. mLights[light.get()] = SceneLightData(light, so);
  82. }
  83. void SceneManager::_unregisterLight(const SPtr<Light>& light)
  84. {
  85. mLights.erase(light.get());
  86. }
  87. void SceneManager::_registerCamera(const SPtr<Camera>& camera, const HSceneObject& so)
  88. {
  89. mCameras[camera.get()] = SceneCameraData(camera, so);
  90. }
  91. void SceneManager::_unregisterCamera(const SPtr<Camera>& camera)
  92. {
  93. mCameras.erase(camera.get());
  94. auto iterFind = std::find_if(mMainCameras.begin(), mMainCameras.end(),
  95. [&](const SceneCameraData& x)
  96. {
  97. return x.camera == camera;
  98. });
  99. if (iterFind != mMainCameras.end())
  100. mMainCameras.erase(iterFind);
  101. }
  102. void SceneManager::_registerReflectionProbe(const SPtr<ReflectionProbe>& probe, const HSceneObject& so)
  103. {
  104. mReflectionProbes[probe.get()] = SceneReflectionProbeData(probe, so);
  105. }
  106. void SceneManager::_unregisterReflectionProbe(const SPtr<ReflectionProbe>& probe)
  107. {
  108. mReflectionProbes.erase(probe.get());
  109. }
  110. void SceneManager::_registerLightProbeVolume(const SPtr<LightProbeVolume>& volume, const HSceneObject& so)
  111. {
  112. mLightProbeVolumes[volume.get()] = SceneLightProbeVolumeData(volume, so);
  113. }
  114. void SceneManager::_unregisterLightProbeVolume(const SPtr<LightProbeVolume>& volume)
  115. {
  116. mLightProbeVolumes.erase(volume.get());
  117. }
  118. void SceneManager::_notifyMainCameraStateChanged(const SPtr<Camera>& camera)
  119. {
  120. auto iterFind = std::find_if(mMainCameras.begin(), mMainCameras.end(),
  121. [&](const SceneCameraData& entry)
  122. {
  123. return entry.camera == camera;
  124. });
  125. SPtr<Viewport> viewport = camera->getViewport();
  126. if (camera->isMain())
  127. {
  128. if (iterFind == mMainCameras.end())
  129. mMainCameras.push_back(mCameras[camera.get()]);
  130. viewport->setTarget(mMainRT);
  131. }
  132. else
  133. {
  134. if (iterFind != mMainCameras.end())
  135. mMainCameras.erase(iterFind);
  136. if (viewport->getTarget() == mMainRT)
  137. viewport->setTarget(nullptr);
  138. }
  139. }
  140. void SceneManager::_updateCoreObjectTransforms()
  141. {
  142. for (auto& renderablePair : mRenderables)
  143. {
  144. SPtr<Renderable> renderable = renderablePair.second.renderable;
  145. HSceneObject so = renderablePair.second.sceneObject;
  146. if (so->getMobility() != renderable->getMobility())
  147. renderable->setMobility(so->getMobility());
  148. renderable->_updateTransform(so);
  149. if (so->getActive() != renderable->getIsActive())
  150. renderable->setIsActive(so->getActive());
  151. }
  152. for (auto& cameraPair : mCameras)
  153. {
  154. SPtr<Camera> handler = cameraPair.second.camera;
  155. HSceneObject so = cameraPair.second.sceneObject;
  156. UINT32 curHash = so->getTransformHash();
  157. if (curHash != handler->_getLastModifiedHash())
  158. {
  159. handler->setPosition(so->getWorldPosition());
  160. handler->setRotation(so->getWorldRotation());
  161. handler->_setLastModifiedHash(curHash);
  162. }
  163. if (so->getActive() != handler->getIsActive())
  164. {
  165. handler->setIsActive(so->getActive());
  166. }
  167. }
  168. for (auto& lightPair : mLights)
  169. {
  170. SPtr<Light> handler = lightPair.second.light;
  171. HSceneObject so = lightPair.second.sceneObject;
  172. if (so->getMobility() != handler->getMobility())
  173. handler->setMobility(so->getMobility());
  174. UINT32 curHash = so->getTransformHash();
  175. if (curHash != handler->_getLastModifiedHash())
  176. {
  177. handler->setPosition(so->getWorldPosition());
  178. handler->setRotation(so->getWorldRotation());
  179. handler->_setLastModifiedHash(curHash);
  180. }
  181. if (so->getActive() != handler->getIsActive())
  182. {
  183. handler->setIsActive(so->getActive());
  184. }
  185. }
  186. for (auto& probePair : mReflectionProbes)
  187. {
  188. SPtr<ReflectionProbe> probe = probePair.second.probe;
  189. HSceneObject so = probePair.second.sceneObject;
  190. UINT32 curHash = so->getTransformHash();
  191. if (curHash != probe->_getLastModifiedHash())
  192. {
  193. probe->setPosition(so->getWorldPosition());
  194. probe->setRotation(so->getWorldRotation());
  195. probe->_setLastModifiedHash(curHash);
  196. }
  197. if (so->getActive() != probe->getIsActive())
  198. {
  199. probe->setIsActive(so->getActive());
  200. }
  201. }
  202. for (auto& volumePair : mLightProbeVolumes)
  203. {
  204. SPtr<LightProbeVolume> volume = volumePair.second.volume;
  205. HSceneObject so = volumePair.second.sceneObject;
  206. volume->_updateTransform(so);
  207. if (so->getActive() != volume->getIsActive())
  208. volume->setIsActive(so->getActive());
  209. }
  210. }
  211. SceneCameraData SceneManager::getMainCamera() const
  212. {
  213. if (mMainCameras.size() > 0)
  214. return mMainCameras[0];
  215. return SceneCameraData();
  216. }
  217. void SceneManager::setMainRenderTarget(const SPtr<RenderTarget>& rt)
  218. {
  219. if (mMainRT == rt)
  220. return;
  221. mMainRTResizedConn.disconnect();
  222. if (rt != nullptr)
  223. mMainRTResizedConn = rt->onResized.connect(std::bind(&SceneManager::onMainRenderTargetResized, this));
  224. mMainRT = rt;
  225. float aspect = 1.0f;
  226. if (rt != nullptr)
  227. {
  228. auto& rtProps = rt->getProperties();
  229. aspect = rtProps.width / (float)rtProps.height;
  230. }
  231. for (auto& entry : mMainCameras)
  232. {
  233. entry.camera->getViewport()->setTarget(rt);
  234. entry.camera->setAspectRatio(aspect);
  235. }
  236. }
  237. void SceneManager::setComponentState(ComponentState state)
  238. {
  239. if (mComponentState == state)
  240. return;
  241. // Wake up all components with onInitialize/onEnable events if moving to running or paused state
  242. if(state == ComponentState::Running || state == ComponentState::Paused)
  243. {
  244. if(mComponentState == ComponentState::Stopped)
  245. {
  246. // Trigger enable on all components that don't have AlwaysRun flag (at this point those will be all
  247. // inactive components that have active scene object parents)
  248. for(auto& entry : mInactiveComponents)
  249. {
  250. if (entry->sceneObject()->getActive())
  251. entry->onEnabled();
  252. }
  253. // Initialize and enable uninitialized components
  254. for(auto& entry : mUnintializedComponents)
  255. {
  256. entry->onInitialized();
  257. if (entry->sceneObject()->getActive())
  258. {
  259. entry->onEnabled();
  260. UINT32 idx = (UINT32)mActiveComponents.size();
  261. mActiveComponents.push_back(entry);
  262. entry->setSceneManagerId(encodeComponentId(idx, ActiveList));
  263. }
  264. else
  265. {
  266. UINT32 idx = (UINT32)mInactiveComponents.size();
  267. mInactiveComponents.push_back(entry);
  268. entry->setSceneManagerId(encodeComponentId(idx, InactiveList));
  269. }
  270. }
  271. mUnintializedComponents.clear();
  272. }
  273. }
  274. // Start updates on all active components
  275. if (state == ComponentState::Running)
  276. {
  277. // Move from inactive to active list
  278. for(INT32 i = 0; i < (INT32)mInactiveComponents.size(); i++)
  279. {
  280. HComponent component = mInactiveComponents[i];
  281. if (!component->sceneObject()->getActive())
  282. continue;
  283. removeFromInactiveList(component);
  284. i--; // Keep the same index next iteration to process the component we just swapped
  285. UINT32 activeIdx = (UINT32)mActiveComponents.size();
  286. mActiveComponents.push_back(component);
  287. component->setSceneManagerId(encodeComponentId(activeIdx, ActiveList));
  288. }
  289. }
  290. // Stop updates on all active components
  291. else if(state == ComponentState::Paused || state == ComponentState::Stopped)
  292. {
  293. // Trigger onDisable events if stopping
  294. if (state == ComponentState::Stopped)
  295. {
  296. for (INT32 i = 0; i < (INT32)mActiveComponents.size(); i++)
  297. {
  298. HComponent component = mActiveComponents[i];
  299. bool alwaysRun = component->hasFlag(ComponentFlag::AlwaysRun);
  300. if (alwaysRun)
  301. continue;
  302. component->onDisabled();
  303. }
  304. }
  305. // Move from active to inactive list
  306. for (INT32 i = 0; i < (INT32)mActiveComponents.size(); i++)
  307. {
  308. HComponent component = mActiveComponents[i];
  309. bool alwaysRun = component->hasFlag(ComponentFlag::AlwaysRun);
  310. if (alwaysRun)
  311. continue;
  312. removeFromActiveList(component);
  313. i--; // Keep the same index next iteration to process the component we just swapped
  314. UINT32 inactiveIdx = (UINT32)mInactiveComponents.size();
  315. mInactiveComponents.push_back(component);
  316. component->setSceneManagerId(encodeComponentId(inactiveIdx, InactiveList));
  317. }
  318. }
  319. mComponentState = state;
  320. }
  321. void SceneManager::_notifyComponentCreated(const HComponent& component, bool parentActive)
  322. {
  323. component->onCreated();
  324. bool alwaysRun = component->hasFlag(ComponentFlag::AlwaysRun);
  325. if(alwaysRun || mComponentState != ComponentState::Stopped)
  326. {
  327. component->onInitialized();
  328. if (parentActive)
  329. {
  330. component->onEnabled();
  331. UINT32 idx = (UINT32)mActiveComponents.size();
  332. mActiveComponents.push_back(component);
  333. component->setSceneManagerId(encodeComponentId(idx, ActiveList));
  334. }
  335. else
  336. {
  337. UINT32 idx = (UINT32)mInactiveComponents.size();
  338. mInactiveComponents.push_back(component);
  339. component->setSceneManagerId(encodeComponentId(idx, InactiveList));
  340. }
  341. }
  342. else // Stopped
  343. {
  344. UINT32 idx = (UINT32)mUnintializedComponents.size();
  345. mUnintializedComponents.push_back(component);
  346. component->setSceneManagerId(encodeComponentId(idx, UninitializedList));
  347. }
  348. }
  349. void SceneManager::_notifyComponentActivated(const HComponent& component, bool triggerEvent)
  350. {
  351. bool alwaysRun = component->hasFlag(ComponentFlag::AlwaysRun);
  352. if (alwaysRun || mComponentState == ComponentState::Running || mComponentState == ComponentState::Paused)
  353. {
  354. if (triggerEvent)
  355. component->onEnabled();
  356. removeFromInactiveList(component);
  357. UINT32 activeIdx = (UINT32)mActiveComponents.size();
  358. mActiveComponents.push_back(component);
  359. component->setSceneManagerId(encodeComponentId(activeIdx, ActiveList));
  360. }
  361. }
  362. void SceneManager::_notifyComponentDeactivated(const HComponent& component, bool triggerEvent)
  363. {
  364. bool alwaysRun = component->hasFlag(ComponentFlag::AlwaysRun);
  365. if (alwaysRun || mComponentState == ComponentState::Running || mComponentState == ComponentState::Paused)
  366. {
  367. if (triggerEvent)
  368. component->onDisabled();
  369. removeFromActiveList(component);
  370. UINT32 inactiveIdx = (UINT32)mInactiveComponents.size();
  371. mInactiveComponents.push_back(component);
  372. component->setSceneManagerId(encodeComponentId(inactiveIdx, InactiveList));
  373. }
  374. }
  375. void SceneManager::_notifyComponentDestroyed(const HComponent& component)
  376. {
  377. UINT32 listType;
  378. UINT32 idx;
  379. decodeComponentId(component->getSceneManagerId(), idx, listType);
  380. switch(listType)
  381. {
  382. case ActiveList:
  383. removeFromActiveList(component);
  384. break;
  385. case InactiveList:
  386. removeFromInactiveList(component);
  387. break;
  388. case UninitializedList:
  389. removeFromUninitializedList(component);
  390. break;
  391. default:
  392. assert(false);
  393. break;
  394. }
  395. bool alwaysRun = component->hasFlag(ComponentFlag::AlwaysRun);
  396. bool isEnabled = component->sceneObject()->getActive() && (alwaysRun || mComponentState != ComponentState::Stopped);
  397. if (isEnabled)
  398. component->onDisabled();
  399. component->onDestroyed();
  400. }
  401. void SceneManager::removeFromActiveList(const HComponent& component)
  402. {
  403. UINT32 listType;
  404. UINT32 idx;
  405. decodeComponentId(component->getSceneManagerId(), idx, listType);
  406. UINT32 lastIdx;
  407. decodeComponentId(mActiveComponents.back()->getSceneManagerId(), lastIdx, listType);
  408. assert(mActiveComponents[idx] == component);
  409. if (idx != lastIdx)
  410. {
  411. std::swap(mActiveComponents[idx], mActiveComponents[lastIdx]);
  412. mActiveComponents[idx]->setSceneManagerId(encodeComponentId(idx, ActiveList));
  413. }
  414. mActiveComponents.erase(mActiveComponents.end() - 1);
  415. }
  416. void SceneManager::removeFromInactiveList(const HComponent& component)
  417. {
  418. UINT32 listType;
  419. UINT32 idx;
  420. decodeComponentId(component->getSceneManagerId(), idx, listType);
  421. UINT32 lastIdx;
  422. decodeComponentId(mInactiveComponents.back()->getSceneManagerId(), lastIdx, listType);
  423. assert(mInactiveComponents[idx] == component);
  424. if (idx != lastIdx)
  425. {
  426. std::swap(mInactiveComponents[idx], mInactiveComponents[lastIdx]);
  427. mInactiveComponents[idx]->setSceneManagerId(encodeComponentId(idx, InactiveList));
  428. }
  429. mInactiveComponents.erase(mInactiveComponents.end() - 1);
  430. }
  431. void SceneManager::removeFromUninitializedList(const HComponent& component)
  432. {
  433. UINT32 listType;
  434. UINT32 idx;
  435. decodeComponentId(component->getSceneManagerId(), idx, listType);
  436. UINT32 lastIdx;
  437. decodeComponentId(mUnintializedComponents.back()->getSceneManagerId(), lastIdx, listType);
  438. assert(mUnintializedComponents[idx] == component);
  439. if (idx != lastIdx)
  440. {
  441. std::swap(mUnintializedComponents[idx], mUnintializedComponents[lastIdx]);
  442. mUnintializedComponents[idx]->setSceneManagerId(encodeComponentId(idx, UninitializedList));
  443. }
  444. mUnintializedComponents.erase(mUnintializedComponents.end() - 1);
  445. }
  446. UINT32 SceneManager::encodeComponentId(UINT32 idx, UINT32 type)
  447. {
  448. assert(idx <= (0x3FFFFFFF));
  449. return (type << 30) | idx;
  450. }
  451. void SceneManager::decodeComponentId(UINT32 id, UINT32& idx, UINT32& type)
  452. {
  453. idx = id & 0x3FFFFFFF;
  454. type = id >> 30;
  455. }
  456. void SceneManager::_update()
  457. {
  458. // Note: Eventually perform updates based on component types and/or on component priority. Right now we just
  459. // iterate in an undefined order, but it wouldn't be hard to change it.
  460. for (auto& entry : mActiveComponents)
  461. entry->update();
  462. GameObjectManager::instance().destroyQueuedObjects();
  463. }
  464. void SceneManager::registerNewSO(const HSceneObject& node)
  465. {
  466. if(mRootNode)
  467. node->setParent(mRootNode);
  468. }
  469. void SceneManager::onMainRenderTargetResized()
  470. {
  471. auto& rtProps = mMainRT->getProperties();
  472. float aspect = rtProps.width / (float)rtProps.height;
  473. for (auto& entry : mMainCameras)
  474. entry.camera->setAspectRatio(aspect);
  475. }
  476. SceneManager& gSceneManager()
  477. {
  478. return SceneManager::instance();
  479. }
  480. }