PrefabImporter.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. //
  2. // Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
  3. // LICENSE: Atomic Game Engine Editor and Tools EULA
  4. // Please see LICENSE_ATOMIC_EDITOR_AND_TOOLS.md in repository root for
  5. // license information: https://github.com/AtomicGameEngine/AtomicGameEngine
  6. //
  7. #include <Atomic/Resource/ResourceCache.h>
  8. #include <Atomic/Resource/XMLFile.h>
  9. #include <Atomic/Scene/Scene.h>
  10. #include <Atomic/Scene/PrefabEvents.h>
  11. #include <Atomic/Scene/PrefabComponent.h>
  12. #include <Atomic/Atomic2D/AnimatedSprite2D.h>
  13. #include <Atomic/IO/FileSystem.h>
  14. #include "Asset.h"
  15. #include "AssetDatabase.h"
  16. #include "PrefabImporter.h"
  17. namespace ToolCore
  18. {
  19. PrefabImporter::PrefabImporter(Context* context, Asset* asset) : AssetImporter(context, asset)
  20. {
  21. SubscribeToEvent(E_PREFABSAVE, HANDLER(PrefabImporter, HandlePrefabSave));
  22. }
  23. PrefabImporter::~PrefabImporter()
  24. {
  25. }
  26. void PrefabImporter::SetDefaults()
  27. {
  28. AssetImporter::SetDefaults();
  29. }
  30. bool PrefabImporter::Preload()
  31. {
  32. if (!asset_)
  33. return false;
  34. preloadResourceScene_ = new Scene(context_);
  35. SharedPtr<File> file(new File(context_, asset_->GetCachePath()));
  36. preloadResourceScene_->LoadAsyncXML(file, LOAD_RESOURCES_ONLY);
  37. return true;
  38. }
  39. void PrefabImporter::HandlePrefabSave(StringHash eventType, VariantMap& eventData)
  40. {
  41. using namespace PrefabSave;
  42. PrefabComponent* component = static_cast<PrefabComponent*>(eventData[P_PREFABCOMPONENT].GetPtr());
  43. if (component->GetPrefabGUID() != asset_->GetGUID())
  44. return;
  45. Node* node = component->GetNode();
  46. if (!node)
  47. return;
  48. // flip temporary root children and components to not be temporary for save
  49. const Vector<SharedPtr<Component>>& rootComponents = node->GetComponents();
  50. const Vector<SharedPtr<Node> >& children = node->GetChildren();
  51. PODVector<Component*> tempComponents;
  52. PODVector<Node*> tempChildren;
  53. PODVector<Node*> filterNodes;
  54. for (unsigned i = 0; i < rootComponents.Size(); i++)
  55. {
  56. if (rootComponents[i]->IsTemporary())
  57. {
  58. rootComponents[i]->SetTemporary(false);
  59. tempComponents.Push(rootComponents[i]);
  60. // Animated sprites contain a temporary node we don't want to save in the prefab
  61. // it would be nice if this was general purpose because have to test this when
  62. // breaking node as well
  63. if (rootComponents[i]->GetType() == AnimatedSprite2D::GetTypeStatic())
  64. {
  65. AnimatedSprite2D* asprite = (AnimatedSprite2D*) rootComponents[i].Get();
  66. if (asprite->GetRootNode())
  67. filterNodes.Push(asprite->GetRootNode());
  68. }
  69. }
  70. }
  71. for (unsigned i = 0; i < children.Size(); i++)
  72. {
  73. if (filterNodes.Contains(children[i].Get()))
  74. continue;
  75. if (children[i]->IsTemporary())
  76. {
  77. children[i]->SetTemporary(false);
  78. tempChildren.Push(children[i]);
  79. }
  80. }
  81. // store original transform
  82. Vector3 pos = node->GetPosition();
  83. Quaternion rot = node->GetRotation();
  84. Vector3 scale = node->GetScale();
  85. node->SetPosition(Vector3::ZERO);
  86. node->SetRotation(Quaternion::IDENTITY);
  87. node->SetScale(Vector3::ONE);
  88. component->SetTemporary(true);
  89. SharedPtr<File> file(new File(context_, asset_->GetPath(), FILE_WRITE));
  90. node->SaveXML(*file);
  91. file->Close();
  92. component->SetTemporary(false);
  93. // restore
  94. node->SetPosition(pos);
  95. node->SetRotation(rot);
  96. node->SetScale(scale);
  97. for (unsigned i = 0; i < tempComponents.Size(); i++)
  98. {
  99. tempComponents[i]->SetTemporary(true);
  100. }
  101. for (unsigned i = 0; i < tempChildren.Size(); i++)
  102. {
  103. tempChildren[i]->SetTemporary(true);
  104. }
  105. FileSystem* fs = GetSubsystem<FileSystem>();
  106. fs->Copy(asset_->GetPath(), asset_->GetCachePath());
  107. // reload it immediately so it is ready for use
  108. // TODO: The resource cache is reloading after this reload due to catching the file cache
  109. ResourceCache* cache = GetSubsystem<ResourceCache>();
  110. XMLFile* xmlfile = cache->GetResource<XMLFile>(asset_->GetGUID());
  111. cache->ReloadResource(xmlfile);
  112. VariantMap changedData;
  113. changedData[PrefabChanged::P_GUID] = asset_->GetGUID();
  114. SendEvent(E_PREFABCHANGED, changedData);
  115. }
  116. bool PrefabImporter::Import()
  117. {
  118. FileSystem* fs = GetSubsystem<FileSystem>();
  119. fs->Copy(asset_->GetPath(), asset_->GetCachePath());
  120. return true;
  121. }
  122. bool PrefabImporter::LoadSettingsInternal(JSONValue& jsonRoot)
  123. {
  124. if (!AssetImporter::LoadSettingsInternal(jsonRoot))
  125. return false;
  126. JSONValue import = jsonRoot.Get("PrefabImporter");
  127. return true;
  128. }
  129. bool PrefabImporter::SaveSettingsInternal(JSONValue& jsonRoot)
  130. {
  131. if (!AssetImporter::SaveSettingsInternal(jsonRoot))
  132. return false;
  133. JSONValue import(JSONValue::emptyObject);
  134. jsonRoot.Set("PrefabImporter", import);
  135. return true;
  136. }
  137. Node* PrefabImporter::InstantiateNode(Node* parent, const String& name)
  138. {
  139. Node* node = parent->CreateChild(asset_->GetName());
  140. PrefabComponent* pc = node->CreateComponent<PrefabComponent>();
  141. pc->SetPrefabGUID(asset_->GetGUID());
  142. return node;
  143. }
  144. }