fix: animation-only FBX assets loadable; clip data viewer

Pure-animation FBX (no meshes, skeleton clips only) was rejected at
the cache layer: ParsedModel::Valid() required non-empty meshes, so
Model::FromParsed/LoadModel returned null and the asset never made it
into the cache. Animation assets are now first-class:

- ParsedModel::Valid() = meshes or clips non-empty; parse failures
  (both empty) still rejected. Empty-mesh consumers already guarded
  (rendering skips empty mesh loop, mesh collider falls back to Box)
- ParseFromDisk: fix null-deref when assimp returns a null scene
- AssetCache::Find(path) + AssetManager::GetModelByPath for panels
- Asset Browser hover card shows meshes/bones/clips for loaded models
- Inspector model line flags "animation-only" when meshes == 0
- Animation section: collapsible clip data table (name/duration/
  channel count) to verify bone-name matching of attached clips
This commit is contained in:
2026-10-04 02:31:30 +08:00
parent 2577809ee4
commit 175ce35def
6 changed files with 97 additions and 9 deletions
+14
View File
@@ -342,6 +342,20 @@ void AssetBrowserPanel::DrawFileList(const EditorContext& ctx,
state = "loaded";
}
ImGui::Text("state: %s", state);
// 已加载的 model 展开资产数据概览(meshes=0 即纯动画
// 容器;未加载不显示——查询不触发加载)
if (item.kind == Kind::Model)
{
if (const Engine::Model* m =
ctx.assets->GetModelByPath(assetPath);
m != nullptr)
{
ImGui::Text("meshes: %u, bones: %u, clips: %u",
static_cast<unsigned>(m->GetMeshes().size()),
m->GetBoneCount(),
static_cast<unsigned>(m->GetClips().size()));
}
}
}
ImGui::TextDisabled("%s", assetPath.c_str());
ImGui::EndTooltip();