Add support for importing assets into custom formats with AssetsImportingManager

This commit is contained in:
Wojtek Figat
2021-04-15 16:48:01 +02:00
parent 18901ba66f
commit 653cdd8654
7 changed files with 75 additions and 83 deletions

View File

@@ -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()

View File

@@ -21,9 +21,9 @@ namespace FlaxEditor.Content.Import
public string OutputPath;
/// <summary>
/// Flag set to true for binary assets handled by the engine internally.
/// Flag set to true for the assets handled by the engine internally.
/// </summary>
public bool IsBinaryAsset;
public bool IsInBuilt;
/// <summary>
/// Flag used to skip showing import settings dialog to used. Can be used for importing assets from code by plugins.

View File

@@ -878,10 +878,12 @@ namespace FlaxEditor
/// Checks if can import asset with the given extension.
/// </summary>
/// <param name="extension">The file extension.</param>
/// <param name="outputExtension">The output file extension (flax, json, etc.).</param>
/// <returns>True if can import files with given extension, otherwise false.</returns>
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;
}
/// <summary>
@@ -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);

View File

@@ -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)

View File

@@ -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);
}
/// <summary>
@@ -243,10 +241,10 @@ namespace FlaxEditor.Modules
/// </summary>
/// <param name="inputPath">The input path.</param>
/// <param name="outputPath">The output path.</param>
/// <param name="isBinaryAsset">True if output file is a binary asset.</param>
/// <param name="isInBuilt">True if use in-built importer (engine backend).</param>
/// <param name="skipSettingsDialog">True if skip any popup dialogs showing for import options adjusting. Can be used when importing files from code.</param>
/// <param name="settings">Import settings to override. Use null to skip this value.</param>
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,
});

View File

@@ -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));

View File

@@ -111,12 +111,6 @@ public:
/// <param name="writer">The json metadata writer.</param>
void AddMeta(JsonWriter& writer) const;
/// <summary>
/// Save asset file data to the hard drive
/// </summary>
/// <returns>Saving result</returns>
CreateAssetResult Save();
private:
void ApplyChanges();
@@ -130,12 +124,17 @@ struct AssetImporter
public:
/// <summary>
/// Extension of the file to import with that importer
/// Extension of the file to import with that importer (without leading dot).
/// </summary>
String FileExtension;
/// <summary>
/// Call asset importing process
/// Extension of the output file as output with that importer (without leading dot).
/// </summary>
String ResultExtension;
/// <summary>
/// Callback for the asset importing process.
/// </summary>
CreateAssetFunction Callback;
};