Add support for importing skeleton-only as Skinned Model (eg. from animation file to have skeleton for retargeting)

This commit is contained in:
Wojtek Figat
2023-05-04 15:43:44 +02:00
parent c91bc0d8c6
commit 71a5d56105
7 changed files with 94 additions and 43 deletions

View File

@@ -673,6 +673,15 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op
}
case ModelType::SkinnedModel:
{
// Add single node if imported skeleton is empty
if (data.Skeleton.Nodes.IsEmpty())
{
data.Skeleton.Nodes.Resize(1);
data.Skeleton.Nodes[0].Name = TEXT("Root");
data.Skeleton.Nodes[0].LocalTransform = Transform::Identity;
data.Skeleton.Nodes[0].ParentIndex = -1;
}
// Special case if imported model has no bones but has valid skeleton and meshes.
// We assume that every mesh uses a single bone. Copy nodes to bones.
if (data.Skeleton.Bones.IsEmpty() && Math::IsInRange(data.Skeleton.Nodes.Count(), 1, MAX_BONES_PER_MODEL))
@@ -700,16 +709,6 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op
}
// Validate
if (data.LODs.IsEmpty() || data.LODs[0].Meshes.IsEmpty())
{
errorMsg = TEXT("Imported model has no valid geometry.");
return true;
}
if (data.Skeleton.Nodes.IsEmpty() || data.Skeleton.Bones.IsEmpty())
{
errorMsg = TEXT("Imported model has no skeleton.");
return true;
}
if (data.Skeleton.Bones.Count() > MAX_BONES_PER_MODEL)
{
errorMsg = String::Format(TEXT("Imported model skeleton has too many bones. Imported: {0}, maximum supported: {1}. Please optimize your asset."), data.Skeleton.Bones.Count(), MAX_BONES_PER_MODEL);
@@ -720,7 +719,8 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op
LOG(Warning, "Imported skinned model has more than one LOD. Removing the lower LODs. Only single one is supported.");
data.LODs.Resize(1);
}
for (int32 i = 0; i < data.LODs[0].Meshes.Count(); i++)
const int32 meshesCount = data.LODs.Count() != 0 ? data.LODs[0].Meshes.Count() : 0;
for (int32 i = 0; i < meshesCount; i++)
{
const auto mesh = data.LODs[0].Meshes[i];
if (mesh->BlendIndices.IsEmpty() || mesh->BlendWeights.IsEmpty())
@@ -771,7 +771,7 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op
#endif
}
LOG(Info, "Imported skeleton has {0} bones, {3} nodes, {1} meshes and {2} material", data.Skeleton.Bones.Count(), data.LODs[0].Meshes.Count(), data.Materials.Count(), data.Nodes.Count());
LOG(Info, "Imported skeleton has {0} bones, {3} nodes, {1} meshes and {2} material", data.Skeleton.Bones.Count(), meshesCount, data.Materials.Count(), data.Nodes.Count());
break;
}
case ModelType::Animation: