BsSceneManager.cpp 15 KB

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