From 653cdd86546f70fbe683ef722512cd3c24825c4d Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 15 Apr 2021 16:48:01 +0200 Subject: [PATCH] Add support for importing assets into custom formats with `AssetsImportingManager` --- .../Editor/Content/Import/ImportFileEntry.cs | 3 +- Source/Editor/Content/Import/Request.cs | 4 +- Source/Editor/Editor.cs | 8 +- .../Editor/Managed/ManagedEditor.Internal.cpp | 5 +- .../Editor/Modules/ContentImportingModule.cs | 16 ++- .../AssetsImportingManager.cpp | 107 ++++++++---------- Source/Engine/ContentImporters/Types.h | 15 ++- 7 files changed, 75 insertions(+), 83 deletions(-) diff --git a/Source/Editor/Content/Import/ImportFileEntry.cs b/Source/Editor/Content/Import/ImportFileEntry.cs index 80cab94d3..5d21d3726 100644 --- a/Source/Editor/Content/Import/ImportFileEntry.cs +++ b/Source/Editor/Content/Import/ImportFileEntry.cs @@ -116,8 +116,7 @@ namespace FlaxEditor.Content.Import if (FileTypes.TryGetValue(extension, out ImportFileEntryHandler createDelegate)) return createDelegate(ref request); - // Use default type - return request.IsBinaryAsset ? new AssetImportEntry(ref request) : new ImportFileEntry(ref request); + return request.IsInBuilt ? new AssetImportEntry(ref request) : new ImportFileEntry(ref request); } internal static void RegisterDefaultTypes() diff --git a/Source/Editor/Content/Import/Request.cs b/Source/Editor/Content/Import/Request.cs index b9da30afb..d38b0bfd0 100644 --- a/Source/Editor/Content/Import/Request.cs +++ b/Source/Editor/Content/Import/Request.cs @@ -21,9 +21,9 @@ namespace FlaxEditor.Content.Import public string OutputPath; /// - /// Flag set to true for binary assets handled by the engine internally. + /// Flag set to true for the assets handled by the engine internally. /// - public bool IsBinaryAsset; + public bool IsInBuilt; /// /// Flag used to skip showing import settings dialog to used. Can be used for importing assets from code by plugins. diff --git a/Source/Editor/Editor.cs b/Source/Editor/Editor.cs index 8f90d203f..9a9500b7b 100644 --- a/Source/Editor/Editor.cs +++ b/Source/Editor/Editor.cs @@ -878,10 +878,12 @@ namespace FlaxEditor /// Checks if can import asset with the given extension. /// /// The file extension. + /// The output file extension (flax, json, etc.). /// True if can import files with given extension, otherwise false. - public static bool CanImport(string extension) + public static bool CanImport(string extension, out string outputExtension) { - return Internal_CanImport(extension); + outputExtension = Internal_CanImport(extension); + return outputExtension != null; } /// @@ -1369,7 +1371,7 @@ namespace FlaxEditor internal static extern bool Internal_CreateVisualScript(string outputPath, string baseTypename); [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern bool Internal_CanImport(string extension); + internal static extern string Internal_CanImport(string extension); [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool Internal_CanExport(string path); diff --git a/Source/Editor/Managed/ManagedEditor.Internal.cpp b/Source/Editor/Managed/ManagedEditor.Internal.cpp index 73a65f0f5..66f5a3c67 100644 --- a/Source/Editor/Managed/ManagedEditor.Internal.cpp +++ b/Source/Editor/Managed/ManagedEditor.Internal.cpp @@ -521,13 +521,14 @@ public: return AssetsImportingManager::Create(AssetsImportingManager::CreateVisualScriptTag, outputPath, &baseTypename); } - static bool CanImport(MonoString* extensionObj) + static MonoString* CanImport(MonoString* extensionObj) { String extension; MUtils::ToString(extensionObj, extension); if (extension.Length() > 0 && extension[0] == '.') extension.Remove(0, 1); - return AssetsImportingManager::GetImporter(extension) != nullptr; + const AssetImporter* importer = AssetsImportingManager::GetImporter(extension); + return importer ? MUtils::ToString(importer->ResultExtension) : nullptr; } static bool Import(MonoString* inputPathObj, MonoString* outputPathObj, void* arg) diff --git a/Source/Editor/Modules/ContentImportingModule.cs b/Source/Editor/Modules/ContentImportingModule.cs index d5ec4b69f..424868fd8 100644 --- a/Source/Editor/Modules/ContentImportingModule.cs +++ b/Source/Editor/Modules/ContentImportingModule.cs @@ -193,12 +193,10 @@ namespace FlaxEditor.Modules var extension = System.IO.Path.GetExtension(inputPath) ?? string.Empty; // Check if given file extension is a binary asset (.flax files) and can be imported by the engine - bool isBinaryAsset = Editor.CanImport(extension); - string outputExtension; - if (isBinaryAsset) + bool isBuilt = Editor.CanImport(extension, out var outputExtension); + if (isBuilt) { - // Flax it up! - outputExtension = ".flax"; + outputExtension = '.' + outputExtension; if (!targetLocation.CanHaveAssets) { @@ -234,7 +232,7 @@ namespace FlaxEditor.Modules var shortName = System.IO.Path.GetFileNameWithoutExtension(inputPath); var outputPath = System.IO.Path.Combine(targetLocation.Path, shortName + outputExtension); - Import(inputPath, outputPath, isBinaryAsset, skipSettingsDialog, settings); + Import(inputPath, outputPath, isBuilt, skipSettingsDialog, settings); } /// @@ -243,10 +241,10 @@ namespace FlaxEditor.Modules /// /// The input path. /// The output path. - /// True if output file is a binary asset. + /// True if use in-built importer (engine backend). /// True if skip any popup dialogs showing for import options adjusting. Can be used when importing files from code. /// Import settings to override. Use null to skip this value. - private void Import(string inputPath, string outputPath, bool isBinaryAsset, bool skipSettingsDialog = false, object settings = null) + private void Import(string inputPath, string outputPath, bool isInBuilt, bool skipSettingsDialog = false, object settings = null) { lock (_requests) { @@ -254,7 +252,7 @@ namespace FlaxEditor.Modules { InputPath = inputPath, OutputPath = outputPath, - IsBinaryAsset = isBinaryAsset, + IsInBuilt = isInBuilt, SkipSettingsDialog = skipSettingsDialog, Settings = settings, }); diff --git a/Source/Engine/ContentImporters/AssetsImportingManager.cpp b/Source/Engine/ContentImporters/AssetsImportingManager.cpp index f1d048ca5..c08f9863f 100644 --- a/Source/Engine/ContentImporters/AssetsImportingManager.cpp +++ b/Source/Engine/ContentImporters/AssetsImportingManager.cpp @@ -91,6 +91,10 @@ CreateAssetResult CreateAssetContext::Run(const CreateAssetFunction& callback) if (result != CreateAssetResult::Ok) return result; + // Skip for non-flax assets (eg. json resource or custom asset type) + if (!TargetAssetPath.EndsWith(ASSET_FILES_EXTENSION)) + return CreateAssetResult::Ok; + // Validate assigned TypeID if (Data.Header.TypeName.IsEmpty()) { @@ -112,8 +116,7 @@ CreateAssetResult CreateAssetContext::Run(const CreateAssetFunction& callback) } // Save file - result = Save(); - + result = FlaxStorage::Create(OutputPath, Data) ? CreateAssetResult::CannotSaveFile : CreateAssetResult::Ok; if (result == CreateAssetResult::Ok) { _applyChangesResult = CreateAssetResult::Abort; @@ -161,11 +164,6 @@ void CreateAssetContext::AddMeta(JsonWriter& writer) const writer.String(Platform::GetUserName()); } -CreateAssetResult CreateAssetContext::Save() -{ - return FlaxStorage::Create(OutputPath, Data) ? CreateAssetResult::CannotSaveFile : CreateAssetResult::Ok; -} - void CreateAssetContext::ApplyChanges() { // Get access @@ -231,8 +229,6 @@ bool AssetsImportingManager::Create(const String& tag, const StringView& outputP bool AssetsImportingManager::Import(const StringView& inputPath, const StringView& outputPath, Guid& assetId, void* arg) { - ASSERT(outputPath.EndsWith(StringView(ASSET_FILES_EXTENSION))); - LOG(Info, "Importing file '{0}' to '{1}'...", inputPath, outputPath); // Check if input file exists @@ -246,8 +242,7 @@ bool AssetsImportingManager::Import(const StringView& inputPath, const StringVie const String extension = FileSystem::GetExtension(inputPath).ToLower(); // Special case for raw assets - const String assetExtension = ASSET_FILES_EXTENSION; - if (assetExtension.Compare(extension, StringSearchCase::IgnoreCase) == 0) + if (StringView(ASSET_FILES_EXTENSION).Compare(StringView(extension), StringSearchCase::IgnoreCase) == 0) { // Simply copy file (content layer will resolve duplicated IDs, etc.) return FileSystem::CopyFile(outputPath, inputPath); @@ -266,8 +261,6 @@ bool AssetsImportingManager::Import(const StringView& inputPath, const StringVie bool AssetsImportingManager::ImportIfEdited(const StringView& inputPath, const StringView& outputPath, Guid& assetId, void* arg) { - ASSERT(outputPath.EndsWith(StringView(ASSET_FILES_EXTENSION))); - // Check if asset not exists if (!FileSystem::FileExists(outputPath)) { @@ -383,64 +376,64 @@ bool AssetsImportingManagerService::Init() AssetImporter InBuildImporters[] = { // Textures and Cube Textures - { TEXT("tga"), ImportTexture::Import }, - { TEXT("dds"), ImportTexture::Import }, - { TEXT("png"), ImportTexture::Import }, - { TEXT("bmp"), ImportTexture::Import }, - { TEXT("gif"), ImportTexture::Import }, - { TEXT("tiff"), ImportTexture::Import }, - { TEXT("tif"), ImportTexture::Import }, - { TEXT("jpeg"), ImportTexture::Import }, - { TEXT("jpg"), ImportTexture::Import }, - { TEXT("hdr"), ImportTexture::Import }, - { TEXT("raw"), ImportTexture::Import }, + { TEXT("tga"), ASSET_FILES_EXTENSION, ImportTexture::Import }, + { TEXT("dds"), ASSET_FILES_EXTENSION, ImportTexture::Import }, + { TEXT("png"), ASSET_FILES_EXTENSION, ImportTexture::Import }, + { TEXT("bmp"), ASSET_FILES_EXTENSION, ImportTexture::Import }, + { TEXT("gif"), ASSET_FILES_EXTENSION, ImportTexture::Import }, + { TEXT("tiff"), ASSET_FILES_EXTENSION, ImportTexture::Import }, + { TEXT("tif"), ASSET_FILES_EXTENSION, ImportTexture::Import }, + { TEXT("jpeg"), ASSET_FILES_EXTENSION, ImportTexture::Import }, + { TEXT("jpg"), ASSET_FILES_EXTENSION, ImportTexture::Import }, + { TEXT("hdr"), ASSET_FILES_EXTENSION, ImportTexture::Import }, + { TEXT("raw"), ASSET_FILES_EXTENSION, ImportTexture::Import }, // IES Profiles - { TEXT("ies"), ImportTexture::ImportIES }, + { TEXT("ies"), ASSET_FILES_EXTENSION, ImportTexture::ImportIES }, // Shaders - { TEXT("shader"), ImportShader::Import }, + { TEXT("shader"), ASSET_FILES_EXTENSION, ImportShader::Import }, // Audio - { TEXT("wav"), ImportAudio::ImportWav }, - { TEXT("mp3"), ImportAudio::ImportMp3 }, + { TEXT("wav"), ASSET_FILES_EXTENSION, ImportAudio::ImportWav }, + { TEXT("mp3"), ASSET_FILES_EXTENSION, ImportAudio::ImportMp3 }, #if COMPILE_WITH_OGG_VORBIS - { TEXT("ogg"), ImportAudio::ImportOgg }, + { TEXT("ogg"), ASSET_FILES_EXTENSION, ImportAudio::ImportOgg }, #endif // Fonts - { TEXT("ttf"), ImportFont::Import }, - { TEXT("otf"), ImportFont::Import }, + { TEXT("ttf"), ASSET_FILES_EXTENSION, ImportFont::Import }, + { TEXT("otf"), ASSET_FILES_EXTENSION, ImportFont::Import }, // Models - { TEXT("obj"), ImportModelFile::Import }, - { TEXT("fbx"), ImportModelFile::Import }, - { TEXT("x"), ImportModelFile::Import }, - { TEXT("dae"), ImportModelFile::Import }, - { TEXT("gltf"), ImportModelFile::Import }, - { TEXT("glb"), ImportModelFile::Import }, + { TEXT("obj"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("fbx"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("x"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("dae"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("gltf"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("glb"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, // Models (untested formats - may fail :/) - { TEXT("blend"), ImportModelFile::Import }, - { TEXT("bvh"), ImportModelFile::Import }, - { TEXT("ase"), ImportModelFile::Import }, - { TEXT("ply"), ImportModelFile::Import }, - { TEXT("dxf"), ImportModelFile::Import }, - { TEXT("ifc"), ImportModelFile::Import }, - { TEXT("nff"), ImportModelFile::Import }, - { TEXT("smd"), ImportModelFile::Import }, - { TEXT("vta"), ImportModelFile::Import }, - { TEXT("mdl"), ImportModelFile::Import }, - { TEXT("md2"), ImportModelFile::Import }, - { TEXT("md3"), ImportModelFile::Import }, - { TEXT("md5mesh"), ImportModelFile::Import }, - { TEXT("q3o"), ImportModelFile::Import }, - { TEXT("q3s"), ImportModelFile::Import }, - { TEXT("ac"), ImportModelFile::Import }, - { TEXT("stl"), ImportModelFile::Import }, - { TEXT("lwo"), ImportModelFile::Import }, - { TEXT("lws"), ImportModelFile::Import }, - { TEXT("lxo"), ImportModelFile::Import }, + { TEXT("blend"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("bvh"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("ase"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("ply"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("dxf"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("ifc"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("nff"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("smd"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("vta"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("mdl"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("md2"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("md3"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("md5mesh"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("q3o"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("q3s"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("ac"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("stl"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("lwo"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("lws"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, + { TEXT("lxo"), ASSET_FILES_EXTENSION, ImportModelFile::Import }, }; AssetsImportingManager::Importers.Add(InBuildImporters, ARRAY_COUNT(InBuildImporters)); diff --git a/Source/Engine/ContentImporters/Types.h b/Source/Engine/ContentImporters/Types.h index 051b865d8..92aa7f533 100644 --- a/Source/Engine/ContentImporters/Types.h +++ b/Source/Engine/ContentImporters/Types.h @@ -111,12 +111,6 @@ public: /// The json metadata writer. void AddMeta(JsonWriter& writer) const; - /// - /// Save asset file data to the hard drive - /// - /// Saving result - CreateAssetResult Save(); - private: void ApplyChanges(); @@ -130,12 +124,17 @@ struct AssetImporter public: /// - /// Extension of the file to import with that importer + /// Extension of the file to import with that importer (without leading dot). /// String FileExtension; /// - /// Call asset importing process + /// Extension of the output file as output with that importer (without leading dot). + /// + String ResultExtension; + + /// + /// Callback for the asset importing process. /// CreateAssetFunction Callback; };