Fix model tool importing to use temp file only for Assimp

This commit is contained in:
Wojtek Figat
2024-04-16 14:38:12 +02:00
parent 5fd808af19
commit daf3671233
6 changed files with 58 additions and 44 deletions

View File

@@ -9,6 +9,7 @@
#include "Engine/Platform/FileSystem.h"
#include "Engine/Platform/File.h"
#include "Engine/Tools/TextureTool/TextureTool.h"
#include "Engine/Utilities/AnsiPathTempFile.h"
// Import Assimp library
// Source: https://github.com/assimp/assimp
@@ -157,7 +158,7 @@ struct AssimpImporterData
Array<AssimpBone> Bones;
Dictionary<int32, Array<int32>> MeshIndexToNodeIndex;
AssimpImporterData(const char* path, const ModelTool::Options& options)
AssimpImporterData(const StringView& path, const ModelTool::Options& options)
: Path(path)
, Options(options)
{
@@ -735,7 +736,7 @@ void ImportAnimation(int32 index, ModelData& data, AssimpImporterData& importerD
}
}
bool ModelTool::ImportDataAssimp(const char* path, ModelData& data, Options& options, String& errorMsg)
bool ModelTool::ImportDataAssimp(const String& path, ModelData& data, Options& options, String& errorMsg)
{
static bool AssimpInited = false;
if (!AssimpInited)
@@ -784,7 +785,10 @@ bool ModelTool::ImportDataAssimp(const char* path, ModelData& data, Options& opt
context.AssimpImporter.SetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
// Import file
context.Scene = context.AssimpImporter.ReadFile(path, flags);
{
AnsiPathTempFile tempFile(path);
context.Scene = context.AssimpImporter.ReadFile(tempFile.Path.Get(), flags);
}
if (context.Scene == nullptr)
{
LOG_STR(Warning, String(context.AssimpImporter.GetErrorString()));

View File

@@ -816,7 +816,7 @@ void BakeTransforms(FbxScene* scene)
scene->GetRootNode()->ConvertPivotAnimationRecursive(nullptr, FbxNode::eDestinationPivot, frameRate, false);
}
bool ModelTool::ImportDataAutodeskFbxSdk(const char* path, ImportedModelData& data, Options& options, String& errorMsg)
bool ModelTool::ImportDataAutodeskFbxSdk(const String& path, ImportedModelData& data, Options& options, String& errorMsg)
{
ScopeLock lock(FbxSdkManager::Locker);
@@ -836,7 +836,7 @@ bool ModelTool::ImportDataAutodeskFbxSdk(const char* path, ImportedModelData& da
auto ios = FbxSdkManager::Manager->GetIOSettings();
ios->SetBoolProp(IMP_FBX_MODEL, importMeshes);
ios->SetBoolProp(IMP_FBX_ANIMATION, importAnimations);
if (!importer->Initialize(path, -1, ios))
if (!importer->Initialize(StringAnsi(path), -1, ios))
{
errorMsg = String::Format(TEXT("Failed to initialize FBX importer. {0}"), String(importer->GetStatus().GetErrorString()));
return false;

View File

@@ -103,7 +103,7 @@ struct OpenFbxImporterData
Array<const ofbx::Material*> Materials;
Array<MaterialSlotEntry> ImportedMaterials;
OpenFbxImporterData(const char* path, const ModelTool::Options& options, ofbx::IScene* scene)
OpenFbxImporterData(const String& path, const ModelTool::Options& options, ofbx::IScene* scene)
: Scene(scene)
, ScenePtr(scene)
, Path(path)
@@ -1114,11 +1114,11 @@ static Float3 FbxVectorFromAxisAndSign(int axis, int sign)
return { 0.f, 0.f, 0.f };
}
bool ModelTool::ImportDataOpenFBX(const char* path, ModelData& data, Options& options, String& errorMsg)
bool ModelTool::ImportDataOpenFBX(const String& path, ModelData& data, Options& options, String& errorMsg)
{
// Import file
Array<byte> fileData;
if (File::ReadAllBytes(String(path), fileData))
if (File::ReadAllBytes(path, fileData))
{
errorMsg = TEXT("Cannot load file.");
return true;

View File

@@ -471,64 +471,37 @@ bool ModelTool::ImportData(const String& path, ModelData& data, Options& options
options.MergeMeshes = false; // Meshes merging doesn't make sense when we want to import each mesh individually
// TODO: maybe we could update meshes merger to collapse meshes within the same name if splitting is enabled?
// Validate path
// Note: Assimp/Autodesk supports only ANSI characters in imported file path
StringAnsi importPath;
String tmpPath;
if (path.IsANSI() == false)
{
// Use temporary file
LOG(Warning, "Model Tool doesn't support importing files from paths using non ASNI characters. Using temporary file.");
FileSystem::GetTempFilePath(tmpPath);
if (tmpPath.IsANSI() == false || FileSystem::CopyFile(tmpPath, path))
{
errorMsg = TEXT("Path with non ANSI characters is invalid.");
return true;
}
importPath = tmpPath.ToStringAnsi();
}
else
{
importPath = path.ToStringAnsi();
}
// Call importing backend
#if (USE_AUTODESK_FBX_SDK || USE_OPEN_FBX) && USE_ASSIMP
if (path.EndsWith(TEXT(".fbx"), StringSearchCase::IgnoreCase))
{
#if USE_AUTODESK_FBX_SDK
if (ImportDataAutodeskFbxSdk(importPath.Get(), data, options, errorMsg))
if (ImportDataAutodeskFbxSdk(path, data, options, errorMsg))
return true;
#elif USE_OPEN_FBX
if (ImportDataOpenFBX(importPath.Get(), data, options, errorMsg))
if (ImportDataOpenFBX(path, data, options, errorMsg))
return true;
#endif
}
else
{
if (ImportDataAssimp(importPath.Get(), data, options, errorMsg))
if (ImportDataAssimp(path, data, options, errorMsg))
return true;
}
#elif USE_ASSIMP
if (ImportDataAssimp(importPath.Get(), data, options, errorMsg))
if (ImportDataAssimp(path, data, options, errorMsg))
return true;
#elif USE_AUTODESK_FBX_SDK
if (ImportDataAutodeskFbxSdk(importPath.Get(), data, options, errorMsg))
if (ImportDataAutodeskFbxSdk(path, data, options, errorMsg))
return true;
#elif USE_OPEN_FBX
if (ImportDataOpenFBX(importPath.Get(), data, options, errorMsg))
if (ImportDataOpenFBX(path, data, options, errorMsg))
return true;
#else
LOG(Error, "Compiled without model importing backend.");
return true;
#endif
// Remove temporary file
if (tmpPath.HasChars() && FileSystem::FileExists(tmpPath))
{
FileSystem::DeleteFile(tmpPath);
}
// Remove namespace prefixes from the nodes names
{
for (auto& node : data.Nodes)

View File

@@ -386,13 +386,13 @@ public:
private:
static void CalculateBoneOffsetMatrix(const Array<SkeletonNode>& nodes, Matrix& offsetMatrix, int32 nodeIndex);
#if USE_ASSIMP
static bool ImportDataAssimp(const char* path, ModelData& data, Options& options, String& errorMsg);
static bool ImportDataAssimp(const String& path, ModelData& data, Options& options, String& errorMsg);
#endif
#if USE_AUTODESK_FBX_SDK
static bool ImportDataAutodeskFbxSdk(const char* path, ModelData& data, Options& options, String& errorMsg);
static bool ImportDataAutodeskFbxSdk(const String& path, ModelData& data, Options& options, String& errorMsg);
#endif
#if USE_OPEN_FBX
static bool ImportDataOpenFBX(const char* path, ModelData& data, Options& options, String& errorMsg);
static bool ImportDataOpenFBX(const String& path, ModelData& data, Options& options, String& errorMsg);
#endif
#endif
};