Kaynağa Gözat

Added interface for importing multiple resources from the same file

BearishSun 10 yıl önce
ebeveyn
işleme
5f2dc49c86

+ 34 - 3
BansheeCore/Include/BsImporter.h

@@ -11,6 +11,16 @@ namespace BansheeEngine
 	 *  @{
 	 */
 
+	/** 
+	 * Contains a resource that was imported from a file that contains multiple resources (e.g. an animation from an FBX 
+	 * file). 
+	 */
+	struct SubResource
+	{
+		String name; /**< Unique name of the sub-resource. */
+		HResource value; /**< Contents of the sub-resource. */
+	};
+
 	/** Module responsible for importing various asset types and converting them to types usable by the engine. */
 	class BS_CORE_EXPORT Importer : public Module<Importer>
 	{
@@ -19,11 +29,13 @@ namespace BansheeEngine
 		~Importer(); 
 
 		/**
-		 * Imports a resource at the specified location, and returns the loaded data.
+		 * Imports a resource at the specified location, and returns the loaded data. If file contains more than one
+		 * resource only the primary resource is imported (e.g. for an FBX a mesh would be imported, but animations ignored).
 		 *
 		 * @param[in]	inputFilePath	Pathname of the input file.
 		 * @param[in]	importOptions	(optional) Options for controlling the import. Caller must ensure import options 
 		 *								actually match the type of the importer used for the file type.
+		 * @return						Imported resource.
 		 *
 		 * @see		createImportOptions
 		 */
@@ -36,6 +48,21 @@ namespace BansheeEngine
 			return static_resource_cast<T>(import(inputFilePath, importOptions));
 		}
 
+		/**
+		 * Imports a resource at the specified location, and returns the loaded data. This method returns all imported
+		 * resources, which is relevant for files that can contain multiple resources (e.g. an FBX which may contain both
+		 * a mesh and animations). 
+		 *
+		 * @param[in]	inputFilePath	Pathname of the input file.
+		 * @param[in]	importOptions	(optional) Options for controlling the import. Caller must ensure import options 
+		 *								actually match the type of the importer used for the file type.
+		 * @return						A list of all imported resources. The primary resource is always the first returned
+		 *								resource.
+		 *
+		 * @see		createImportOptions
+		 */
+		Vector<SubResource> importAll(const Path& inputFilePath, ConstImportOptionsPtr importOptions = nullptr);
+
 		/**
 		 * Imports a resource and replaces the contents of the provided existing resource with new imported data.
 		 *
@@ -99,9 +126,13 @@ namespace BansheeEngine
 		 */
 		void _registerAssetImporter(SpecificImporter* importer);
 	private:
-		Vector<SpecificImporter*> mAssetImporters;
-
+		/** 
+		 * Searches available importers and attempts to find one that can import the file of the provided type. Returns null
+		 * if one cannot be found.
+		 */
 		SpecificImporter* getImporterForFile(const Path& inputFilePath) const;
+
+		Vector<SpecificImporter*> mAssetImporters;
 	};
 
 	/** Provides easier access to Importer. */

+ 22 - 2
BansheeCore/Include/BsSpecificImporter.h

@@ -11,6 +11,16 @@ namespace BansheeEngine
 	 *  @{
 	 */
 
+	/** 
+	 * Contains a resource that was imported from a file that contains multiple resources (e.g. an animation from an FBX 
+	 * file). 
+	 */
+	struct SubResourceRaw
+	{
+		String name; /**< Unique name of the sub-resource. */
+		SPtr<Resource> value; /**< Contents of the sub-resource. */
+	};
+
 	/**
 	 * Abstract class that is to be specialized in convertinga certain asset type into an engine usable resource. 
 	 * (e.g. a .png file into an engine usable texture).
@@ -35,14 +45,24 @@ namespace BansheeEngine
 		virtual bool isMagicNumberSupported(const UINT8* magicNumPtr, UINT32 numBytes) const = 0; 
 
 		/**
-		 * Imports the given file.
+		 * Imports the given file. If file contains more than one resource only the primary resource is imported (e.g. for
+		 * an FBX a mesh would be imported, but animations ignored).
 		 *
 		 * @param[in]	filePath	Pathname of the file, with file extension.
-		 *
 		 * @return					null if it fails, otherwise the loaded object.
 		 */
 		virtual ResourcePtr import(const Path& filePath, ConstImportOptionsPtr importOptions) = 0;
 
+		/**
+		 * Imports the given file. This method returns all imported resources, which is relevant for files that can contain
+		 * multiple resources (e.g. an FBX which may contain both a mesh and animations). 
+		 *
+		 * @param[in]	filePath	Pathname of the file, with file extension.
+		 * @return					Empty array if it fails, otherwise the loaded objects. First element is always the 
+		 *							primary resource.
+		 */
+		virtual Vector<SubResourceRaw> importAll(const Path& filePath, ConstImportOptionsPtr importOptions);
+
 		/**
 		 * Creates import options specific for this importer. Import options are provided when calling import() in order 
 		 * to customize the import, and provide additional information.

+ 39 - 0
BansheeCore/Source/BsImporter.cpp

@@ -52,6 +52,8 @@ namespace BansheeEngine
 		return false;
 	}
 
+	
+
 	HResource Importer::import(const Path& inputFilePath, ConstImportOptionsPtr importOptions)
 	{
 		if(!FileSystem::isFile(inputFilePath))
@@ -80,6 +82,43 @@ namespace BansheeEngine
 		return gResources()._createResourceHandle(importedResource);
 	}
 
+	Vector<SubResource> Importer::importAll(const Path& inputFilePath, ConstImportOptionsPtr importOptions)
+	{
+		if (!FileSystem::isFile(inputFilePath))
+		{
+			LOGWRN("Trying to import asset that doesn't exists. Asset path: " + inputFilePath.toString());
+			return Vector<SubResource>();
+		}
+
+		SpecificImporter* importer = getImporterForFile(inputFilePath);
+		if (importer == nullptr)
+			return Vector<SubResource>();
+
+		if (importOptions == nullptr)
+			importOptions = importer->getDefaultImportOptions();
+		else
+		{
+			ConstImportOptionsPtr defaultImportOptions = importer->getDefaultImportOptions();
+			if (importOptions->getTypeId() != defaultImportOptions->getTypeId())
+			{
+				BS_EXCEPT(InvalidParametersException, "Provided import options is not of valid type. " \
+					"Expected: " + defaultImportOptions->getTypeName() + ". Got: " + importOptions->getTypeName() + ".");
+			}
+		}
+
+		Vector<SubResource> output;
+
+		Vector<SubResourceRaw> importedResource = importer->importAll(inputFilePath, importOptions);
+		for(auto& entry : importedResource)
+		{
+			HResource handle = gResources()._createResourceHandle(entry.value);
+
+			output.push_back({ entry.name, handle });
+		}
+
+		return output;
+	}
+
 	void Importer::reimport(HResource& existingResource, const Path& inputFilePath, ConstImportOptionsPtr importOptions)
 	{
 		if(!FileSystem::isFile(inputFilePath))

+ 9 - 0
BansheeCore/Source/BsSpecificImporter.cpp

@@ -6,6 +6,15 @@
 
 namespace BansheeEngine
 {
+	Vector<SubResourceRaw> SpecificImporter::importAll(const Path& filePath, ConstImportOptionsPtr importOptions)
+	{
+		ResourcePtr resource = import(filePath, importOptions);
+		if (resource == nullptr)
+			return Vector<SubResourceRaw>();
+
+		return { { "primary", resource } };;
+	}
+
 	ImportOptionsPtr SpecificImporter::createImportOptions() const
 	{
 		return bs_shared_ptr_new<ImportOptions>();