feat(animation): attach external animation files to a model
Animation-only FBX files (no mesh, clips only) could not be used: clips are keyed by node index into the parsed model's node table, so there was no path to get them onto a different model's skeleton. Add AssetManager::AttachAnimationClips: parses the container with the CPU-only path (no GPU upload -- empty meshes cannot build a Model), remaps each clip's channels to the target model's node indices by bone name, and appends to its clip list. Channels whose bone name is absent are skipped and counted; clips with zero matching channels are dropped. Same-source attach is idempotent via a new AnimationClip::sourcePath marker; name clashes get the file stem prefixed. Inspector Animation block gains an attach slot (UE Details semantics) listing model-container files plus a bullet list of attached sources; already-attached paths are replayed idempotently when the entity is selected, so clips survive restarts. The paths persist in the scene (Animation.Attached); the clips themselves stay runtime state. Limitations (documented, by design): same-skeleton retargeting only -- bone names must match between source and target (same DCC export or Mixamo-style per-animation downloads); cross-skeleton retargeting is out of scope.
This commit is contained in:
@@ -236,6 +236,14 @@ namespace Engine::Serialization {
|
||||
out << YAML::Key << "Loop" << YAML::Value << a->loop;
|
||||
out << YAML::Key << "Speed" << YAML::Value << a->speed;
|
||||
out << YAML::Key << "Active" << YAML::Value << a->active;
|
||||
// 外部动画源(编辑器 attach 列表):clip 本体运行时并入
|
||||
// Model 资产不落盘,加载端按此列表幂等重放
|
||||
out << YAML::Key << "Attached" << YAML::Value << YAML::Flow
|
||||
<< YAML::BeginSeq;
|
||||
for (const auto& p : a->attachedAnimPaths) {
|
||||
out << p;
|
||||
}
|
||||
out << YAML::EndSeq;
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
|
||||
@@ -556,6 +564,12 @@ namespace Engine::Serialization {
|
||||
a.loop = n["Loop"].as<bool>(a.loop);
|
||||
a.speed = n["Speed"].as<f32>(a.speed);
|
||||
a.active = n["Active"].as<bool>(true);
|
||||
if (const YAML::Node att = n["Attached"]) {
|
||||
for (const auto& it : att) {
|
||||
a.attachedAnimPaths.push_back(
|
||||
it.as<std::string>(""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (const YAML::Node n = comps["Camera"]) {
|
||||
|
||||
Reference in New Issue
Block a user