소스 검색

Project library will not longer import native engine assets, instead they will be referenced directly to avoid issues with different UUIDs
Prefab diff generation now properly records and restores game object instance IDs
Updating and reverting to prefab will now properly keep the original scene object parent

BearishSun 10 년 전
부모
커밋
78a0850433

+ 0 - 2
BansheeCore/BansheeCore.vcxproj

@@ -305,7 +305,6 @@
     <ClInclude Include="Include\BsPrefab.h" />
     <ClInclude Include="Include\BsPrefabDiff.h" />
     <ClInclude Include="Include\BsPrefabDiffRTTI.h" />
-    <ClInclude Include="Include\BsPrefabImporter.h" />
     <ClInclude Include="Include\BsPrefabRTTI.h" />
     <ClInclude Include="Include\BsPrefabUtility.h" />
     <ClInclude Include="Include\BsRendererMeshData.h" />
@@ -469,7 +468,6 @@
     <ClCompile Include="Source\BsMeshUtility.cpp" />
     <ClCompile Include="Source\BsPrefab.cpp" />
     <ClCompile Include="Source\BsPrefabDiff.cpp" />
-    <ClCompile Include="Source\BsPrefabImporter.cpp" />
     <ClCompile Include="Source\BsPrefabUtility.cpp" />
     <ClCompile Include="Source\BsProfilerCPU.cpp" />
     <ClCompile Include="Source\BsDeferredCallManager.cpp" />

+ 0 - 6
BansheeCore/BansheeCore.vcxproj.filters

@@ -569,9 +569,6 @@
     <ClInclude Include="Include\BsStringTableRTTI.h">
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsPrefabImporter.h">
-      <Filter>Header Files\Importer</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsIconUtility.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -904,9 +901,6 @@
     <ClCompile Include="Source\BsStringTableManager.cpp">
       <Filter>Source Files\Localization</Filter>
     </ClCompile>
-    <ClCompile Include="Source\BsPrefabImporter.cpp">
-      <Filter>Source Files\Importer</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsIconUtility.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>

+ 0 - 27
BansheeCore/Include/BsPrefabImporter.h

@@ -1,27 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsSpecificImporter.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Importer using for importing Prefab resources.
-	 * 			Prefab resources are serialized engine objects ending in ".prefab" extension.
-	 */
-	class BS_CORE_EXPORT PrefabImporter : public SpecificImporter
-	{
-	public:
-		PrefabImporter();
-		virtual ~PrefabImporter();
-
-		/** @copydoc SpecificImporter::isExtensionSupported */
-		virtual bool isExtensionSupported(const WString& ext) const override;
-
-		/** @copydoc SpecificImporter::isMagicNumberSupported */
-		virtual bool isMagicNumberSupported(const UINT8* magicNumPtr, UINT32 numBytes) const override;
-
-		/** @copydoc SpecificImporter::import */
-		virtual ResourcePtr import(const Path& filePath, ConstImportOptionsPtr importOptions) override;
-	};
-}

+ 2 - 2
BansheeCore/Source/BsPrefab.cpp

@@ -47,6 +47,8 @@ namespace BansheeEngine
 		mRoot = sceneObject->clone();
 		sceneObject->unsetFlags(SOF_DontInstantiate);
 
+		mRoot->mParent = nullptr;
+
 		// Remove objects with "dont save" flag
 		Stack<HSceneObject> todo;
 		todo.push(mRoot);
@@ -87,8 +89,6 @@ namespace BansheeEngine
 		Stack<HSceneObject> todo;
 		todo.push(clone);
 
-		Vector<HSceneObject> prefabInstanceRoots;
-
 		while (!todo.empty())
 		{
 			HSceneObject current = todo.top();

+ 0 - 50
BansheeCore/Source/BsPrefabImporter.cpp

@@ -1,50 +0,0 @@
-#include "BsPrefabImporter.h"
-#include "BsFileSerializer.h"
-#include "BsResource.h"
-
-namespace BansheeEngine
-{
-	PrefabImporter::PrefabImporter()
-		:SpecificImporter()
-	{
-
-	}
-
-	PrefabImporter::~PrefabImporter()
-	{
-
-	}
-
-	bool PrefabImporter::isExtensionSupported(const WString& ext) const
-	{
-		WString lowerCaseExt = ext;
-		StringUtil::toLowerCase(lowerCaseExt);
-
-		return lowerCaseExt == L"prefab";
-	}
-
-	bool PrefabImporter::isMagicNumberSupported(const UINT8* magicNumPtr, UINT32 numBytes) const
-	{
-		return true; // No magic number of asset files, they must always rely on extension
-	}
-
-	ResourcePtr PrefabImporter::import(const Path& filePath, ConstImportOptionsPtr importOptions)
-	{
-		FileDecoder fs(filePath);
-		fs.skip(); // Skipped over saved resource data
-		std::shared_ptr<IReflectable> loadedData = fs.decode();
-
-		if (loadedData == nullptr)
-			BS_EXCEPT(InternalErrorException, "Unable to import resource.");
-
-		if (!loadedData->isDerivedFrom(Resource::getRTTIStatic()))
-			BS_EXCEPT(InternalErrorException, "Imported object doesn't derive from Resource.");
-
-		ResourcePtr resource = std::static_pointer_cast<Resource>(loadedData);
-
-		WString fileName = filePath.getWFilename(false);
-		resource->setName(fileName);
-
-		return resource;
-	}
-}

+ 46 - 15
BansheeCore/Source/BsPrefabUtility.cpp

@@ -19,9 +19,15 @@ namespace BansheeEngine
 		UnorderedMap<UINT32, GameObjectInstanceDataPtr> linkedInstanceData;
 		recordInstanceData(so, soProxy, linkedInstanceData);
 
-		so->destroy();
+		HSceneObject parent = so->getParent();
+
+		// This will destroy the object but keep it in the parent's child list
+		HSceneObject currentSO = so;
+		so->destroyInternal(currentSO, true);
 
 		HSceneObject newInstance = prefabLink->instantiate();
+		newInstance->mParent = parent;
+
 		restoreLinkedInstanceData(newInstance, linkedInstanceData);
 	}
 
@@ -75,9 +81,14 @@ namespace BansheeEngine
 				recordInstanceData(current, soProxy, linkedInstanceData);
 
 				PrefabDiffPtr prefabDiff = current->mPrefabDiff;
-				current->destroy();
+				HSceneObject parent = current->getParent();
+
+				// This will destroy the object but keep it in the parent's child list
+				current->destroyInternal(current, true);
 
 				HSceneObject newInstance = prefabLink->instantiate();
+				newInstance->mParent = parent;
+
 				if (prefabDiff != nullptr)
 					prefabDiff->apply(newInstance);
 
@@ -219,38 +230,59 @@ namespace BansheeEngine
 	void PrefabUtility::recordInstanceData(const HSceneObject& so, SceneObjectProxy& output,
 		UnorderedMap<UINT32, GameObjectInstanceDataPtr>& linkedInstanceData)
 	{
-		Stack<HSceneObject> todo;
-		todo.push(so);
+		struct StackData
+		{
+			HSceneObject so;
+			SceneObjectProxy* proxy;
+		};
+
+		Stack<StackData> todo;
+		todo.push({so, &output});
 
 		while (!todo.empty())
 		{
-			HSceneObject current = todo.top();
+			StackData curData = todo.top();
 			todo.pop();
 
-			output.instanceData = current->_getInstanceData();
-			output.linkId = current->getLinkId();
+			curData.proxy->instanceData = curData.so->_getInstanceData();
+			curData.proxy->linkId = curData.so->getLinkId();
 
-			linkedInstanceData[output.linkId] = output.instanceData;
+			linkedInstanceData[curData.proxy->linkId] = curData.proxy->instanceData;
 
-			const Vector<HComponent>& components = current->getComponents();
+			const Vector<HComponent>& components = curData.so->getComponents();
 			for (auto& component : components)
 			{
-				output.components.push_back(ComponentProxy());
+				curData.proxy->components.push_back(ComponentProxy());
 
-				ComponentProxy& componentProxy = output.components.back();
+				ComponentProxy& componentProxy = curData.proxy->components.back();
 				componentProxy.instanceData = component->_getInstanceData();
 				componentProxy.linkId = component->getLinkId();
 
 				linkedInstanceData[componentProxy.linkId] = componentProxy.instanceData;
 			}
 
-			UINT32 numChildren = current->getNumChildren();
+			UINT32 numChildren = curData.so->getNumChildren();
+			UINT32 numProxyChildren = 0;
 			for (UINT32 i = 0; i < numChildren; i++)
 			{
-				HSceneObject child = current->getChild(i);
+				HSceneObject child = curData.so->getChild(i);
 
 				if (child->mPrefabLinkUUID.empty())
-					todo.push(child);
+					numProxyChildren++;
+			}
+
+			curData.proxy->children.resize(numProxyChildren);
+
+			UINT32 proxyIdx = 0;
+			for (UINT32 i = 0; i < numChildren; i++)
+			{
+				HSceneObject child = curData.so->getChild(i);
+
+				if (child->mPrefabLinkUUID.empty())
+				{
+					todo.push({ child, &curData.proxy->children[proxyIdx] });
+					proxyIdx++;
+				}
 			}
 		}
 	}
@@ -332,7 +364,6 @@ namespace BansheeEngine
 						if (current.proxy->components[componentProxyIdx].linkId != -1)
 							continue;
 
-						assert(current.proxy->components[componentProxyIdx].linkId == -1);
 						component->_setInstanceData(current.proxy->components[componentProxyIdx].instanceData);
 						foundInstanceData = true;
 						break;

+ 0 - 2
BansheeEditor/BansheeEditor.vcxproj

@@ -360,7 +360,6 @@
     <ClInclude Include="Include\BsProjectResourceMeta.h" />
     <ClInclude Include="Include\BsProjectResourceMetaRTTI.h" />
     <ClInclude Include="Include\BsGUIVector2Field.h" />
-    <ClInclude Include="Include\BsResourceImporter.h" />
     <ClInclude Include="Include\BsSceneGrid.h" />
     <ClInclude Include="Include\BsSceneViewHandler.h" />
     <ClInclude Include="Include\BsSelection.h" />
@@ -438,7 +437,6 @@
     <ClCompile Include="Source\BsProjectLibrary.cpp" />
     <ClCompile Include="Source\BsProjectLibraryEntries.cpp" />
     <ClCompile Include="Source\BsProjectResourceMeta.cpp" />
-    <ClCompile Include="Source\BsResourceImporter.cpp" />
     <ClCompile Include="Source\BsSceneGrid.cpp" />
     <ClCompile Include="Source\BsSceneViewHandler.cpp" />
     <ClCompile Include="Source\BsSelection.cpp" />

+ 0 - 6
BansheeEditor/BansheeEditor.vcxproj.filters

@@ -219,9 +219,6 @@
     <ClInclude Include="Include\BsProjectResourceMeta.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsResourceImporter.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsSceneGrid.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -464,9 +461,6 @@
     <ClCompile Include="Source\BsProjectResourceMeta.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Source\BsResourceImporter.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsSceneGrid.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>

+ 5 - 0
BansheeEditor/Include/BsProjectLibrary.h

@@ -324,6 +324,11 @@ namespace BansheeEngine
 		 */
 		bool isUpToDate(ResourceEntry* resource) const;
 
+		/**
+		 * @brief	Checks is the resource a native engine resource that doesn't require importing.
+		 */
+		bool isNative(ResourceEntry* resource) const;
+
 		/**
 		 * @brief	Returns a path to a .meta file based on the resource path.
 		 *

+ 0 - 33
BansheeEditor/Include/BsResourceImporter.h

@@ -1,33 +0,0 @@
-#pragma once
-
-#include "BsEditorPrerequisites.h"
-#include "BsSpecificImporter.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Imports built-in Banshee resources (marked with .asset extension). 
-	 *			Essentially just does a pass-through as source asset to import and 
-	 *			resulting resource are one and the same.
-	 *
-	 * @note	This is useful in the project library where we sometimes want to save processed
-	 *			resources in the library.
-	 */
-	class BS_ED_EXPORT ResourceImporter : public SpecificImporter
-	{
-	public:
-		ResourceImporter();
-		virtual ~ResourceImporter();
-
-		/** @copydoc SpecificImporter::isExtensionSupported */
-		virtual bool isExtensionSupported(const WString& ext) const override;
-
-		/** @copydoc SpecificImporter::isMagicNumberSupported */
-		virtual bool isMagicNumberSupported(const UINT8* magicNumPtr, UINT32 numBytes) const override;
-
-		/** @copydoc SpecificImporter::import */
-		virtual ResourcePtr import(const Path& filePath, ConstImportOptionsPtr importOptions) override;
-
-		static const WString DEFAULT_EXTENSION;
-	};
-}

+ 0 - 8
BansheeEditor/Source/BsEditorApplication.cpp

@@ -7,7 +7,6 @@
 #include "BsUndoRedo.h"
 #include "BsFileSerializer.h"
 #include "BsFileSystem.h"
-#include "BsResourceImporter.h"
 #include "BsEditorWidgetLayout.h"
 #include "BsScenePicking.h"
 #include "BsSelection.h"
@@ -17,7 +16,6 @@
 #include "BsScriptCodeImporter.h"
 #include "BsShaderIncludeHandler.h"
 #include "BsDropDownWindowManager.h"
-#include "BsPrefabImporter.h"
 #include "BsProjectLibrary.h"
 #include "BsProjectSettings.h"
 #include "BsEditorSettings.h"
@@ -89,12 +87,6 @@ namespace BansheeEngine
 		ScriptCodeImporter* scriptCodeImporter = bs_new<ScriptCodeImporter>();
 		Importer::instance()._registerAssetImporter(scriptCodeImporter);
 
-		ResourceImporter* resourceImporter = bs_new<ResourceImporter>();
-		Importer::instance()._registerAssetImporter(resourceImporter);
-
-		PrefabImporter* prefabImporter = bs_new<PrefabImporter>();
-		Importer::instance()._registerAssetImporter(prefabImporter);
-
 		ProjectLibrary::startUp();
 
 		UndoRedo::startUp();

+ 31 - 10
BansheeEditor/Source/BsProjectLibrary.cpp

@@ -13,7 +13,6 @@
 #include "BsProjectLibraryEntries.h"
 #include "BsResource.h"
 #include "BsEditorApplication.h"
-#include "BsResourceImporter.h"
 #include "BsShader.h"
 #include <regex>
 
@@ -396,9 +395,12 @@ namespace BansheeEngine
 
 		if (!isUpToDate(resource) || forceReimport)
 		{
-			ImportOptionsPtr curImportOptions = nullptr;
+			// Note: If resource is native we just copy it to the internal folder. We could avoid the copy and 
+			// load the resource directly from the Resources folder but that requires complicating library code.
+			bool isNativeResource = isNative(resource);
 
-			if (importOptions == nullptr)
+			ImportOptionsPtr curImportOptions = nullptr;
+			if (importOptions == nullptr && !isNativeResource)
 			{
 				if (resource->meta != nullptr)
 					curImportOptions = resource->meta->getImportOptions();
@@ -409,9 +411,14 @@ namespace BansheeEngine
 				curImportOptions = importOptions;
 
 			HResource importedResource;
+
+			if (isNativeResource)
+				importedResource = gResources().load(resource->path);
+
 			if(resource->meta == nullptr)
 			{
-				importedResource = Importer::instance().import(resource->path, curImportOptions);
+				if (!isNativeResource)
+					importedResource = Importer::instance().import(resource->path, curImportOptions);
 
 				if (importedResource != nullptr)
 				{
@@ -431,8 +438,11 @@ namespace BansheeEngine
 			{
 				removeDependencies(resource);
 
-				importedResource = HResource(resource->meta->getUUID());
-				Importer::instance().reimport(importedResource, resource->path, curImportOptions);
+				if (!isNativeResource)
+				{
+					importedResource = HResource(resource->meta->getUUID());
+					Importer::instance().reimport(importedResource, resource->path, curImportOptions);
+				}
 			}
 
 			addDependencies(resource);
@@ -448,7 +458,9 @@ namespace BansheeEngine
 				internalResourcesPath.setFilename(toWString(importedResource.getUUID()) + L".asset");
 
 				gResources().save(importedResource, internalResourcesPath, true);
-				gResources().unload(importedResource);
+
+				if (!isNativeResource)
+					gResources().unload(importedResource);
 
 				mResourceManifest->registerResource(importedResource.getUUID(), internalResourcesPath);
 			}
@@ -630,9 +642,8 @@ namespace BansheeEngine
 		if (resource == nullptr)
 			return;
 
-		Path filePath;
-		if (!mResourceManifest->uuidToFilePath(resource.getUUID(), filePath))
-			return;
+		Path filePath = uuidToPath(resource.getUUID());
+		filePath.makeAbsolute(getResourcesFolder());
 
 		Resources::instance().save(resource, filePath, true);
 	}
@@ -887,6 +898,9 @@ namespace BansheeEngine
 			return;
 
 		ResourceEntry* resEntry = static_cast<ResourceEntry*>(entry);
+		if (resEntry->meta == nullptr)
+			return;
+
 		resEntry->meta->setIncludeInBuild(include);
 
 		Path metaPath = resEntry->path;
@@ -996,6 +1010,13 @@ namespace BansheeEngine
 		return fullPath.getWExtension() == L".meta";
 	}
 
+	bool ProjectLibrary::isNative(ResourceEntry* resource) const
+	{
+		WString extension = resource->path.getWExtension();
+
+		return extension == L".asset" || extension == L".prefab";
+	}
+
 	void ProjectLibrary::unloadLibrary()
 	{
 		if (!mIsLoaded)

+ 0 - 52
BansheeEditor/Source/BsResourceImporter.cpp

@@ -1,52 +0,0 @@
-#include "BsResourceImporter.h"
-#include "BsFileSerializer.h"
-#include "BsResource.h"
-
-namespace BansheeEngine
-{
-	const WString ResourceImporter::DEFAULT_EXTENSION = L"asset";
-
-	ResourceImporter::ResourceImporter()
-		:SpecificImporter()
-	{
-
-	}
-
-	ResourceImporter::~ResourceImporter()
-	{
-
-	}
-
-	bool ResourceImporter::isExtensionSupported(const WString& ext) const
-	{
-		WString lowerCaseExt = ext;
-		StringUtil::toLowerCase(lowerCaseExt);
-
-		return lowerCaseExt == DEFAULT_EXTENSION;
-	}
-
-	bool ResourceImporter::isMagicNumberSupported(const UINT8* magicNumPtr, UINT32 numBytes) const
-	{
-		return true; // No magic number of asset files, they must always rely on extension
-	}
-
-	ResourcePtr ResourceImporter::import(const Path& filePath, ConstImportOptionsPtr importOptions)
-	{
-		FileDecoder fs(filePath);
-		fs.skip(); // Skipped over saved resource data
-		std::shared_ptr<IReflectable> loadedData = fs.decode();
-
-		if (loadedData == nullptr)
-			BS_EXCEPT(InternalErrorException, "Unable to import resource.");
-
-		if (!loadedData->isDerivedFrom(Resource::getRTTIStatic()))
-			BS_EXCEPT(InternalErrorException, "Imported object doesn't derive from Resource.");
-
-		ResourcePtr resource = std::static_pointer_cast<Resource>(loadedData);
-
-		WString fileName = filePath.getWFilename(false);
-		resource->setName(fileName);
-
-		return resource;
-	}
-}