BsPrefab.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include "BsPrefab.h"
  2. #include "BsPrefabRTTI.h"
  3. #include "BsResources.h"
  4. #include "BsSceneObject.h"
  5. namespace BansheeEngine
  6. {
  7. Prefab::Prefab()
  8. :Resource(false)
  9. {
  10. }
  11. HPrefab Prefab::create(const HSceneObject& sceneObject)
  12. {
  13. assert(sceneObject->mPrefabLink != nullptr);
  14. PrefabPtr newPrefab = createEmpty();
  15. newPrefab->initialize(sceneObject);
  16. HPrefab handle = static_resource_cast<Prefab>(gResources()._createResourceHandle(newPrefab));
  17. sceneObject->mPrefabLink = handle;
  18. return handle;
  19. }
  20. PrefabPtr Prefab::createEmpty()
  21. {
  22. PrefabPtr newPrefab = bs_core_ptr<Prefab, PoolAlloc>(new (bs_alloc<Prefab, PoolAlloc>()) Prefab());
  23. newPrefab->_setThisPtr(newPrefab);
  24. return newPrefab;
  25. }
  26. void Prefab::generatePrefabIds(const HSceneObject& sceneObject)
  27. {
  28. Vector<HGameObject> objectsToId;
  29. Set<INT32> existingIds;
  30. Stack<HSceneObject> todo;
  31. todo.push(sceneObject);
  32. while (!todo.empty())
  33. {
  34. HSceneObject currentSO = todo.top();
  35. todo.pop();
  36. if (currentSO->mLinkId == -1)
  37. objectsToId.push_back(currentSO);
  38. else
  39. existingIds.insert(currentSO->mLinkId);
  40. for (auto& component : currentSO->mComponents)
  41. {
  42. if (component->mLinkId == -1)
  43. objectsToId.push_back(component);
  44. else
  45. existingIds.insert(component->mLinkId);
  46. }
  47. }
  48. auto setIter = existingIds.begin();
  49. INT32 nextId = 0;
  50. for (auto& object : objectsToId)
  51. {
  52. INT32 freeId = -1;
  53. for (; setIter != existingIds.end(); ++setIter)
  54. {
  55. if (nextId < (*setIter))
  56. freeId = nextId++;
  57. else
  58. nextId++;
  59. }
  60. if (freeId == -1)
  61. freeId = nextId++;
  62. object->mLinkId = freeId;
  63. }
  64. }
  65. void Prefab::initialize(const HSceneObject& sceneObject)
  66. {
  67. generatePrefabIds(sceneObject);
  68. sceneObject->setFlags(SOF_DontInstantiate);
  69. mRoot = sceneObject->clone();
  70. sceneObject->unsetFlags(SOF_DontInstantiate);
  71. }
  72. HSceneObject Prefab::instantiate()
  73. {
  74. if (mRoot == nullptr)
  75. return HSceneObject();
  76. HSceneObject clone = mRoot->clone();
  77. clone->instantiate();
  78. return clone;
  79. }
  80. RTTITypeBase* Prefab::getRTTIStatic()
  81. {
  82. return PrefabRTTI::instance();
  83. }
  84. RTTITypeBase* Prefab::getRTTI() const
  85. {
  86. return Prefab::getRTTIStatic();
  87. }
  88. }