From cda706e62ce766363aa77cde2de3491687b4e361 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Tue, 23 Apr 2024 19:59:51 -0400 Subject: [PATCH] Fixed broken skeletons when imported from a prefab --- Nuake/src/Resource/Prefab.h | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/Nuake/src/Resource/Prefab.h b/Nuake/src/Resource/Prefab.h index b42d4a10..47831de2 100644 --- a/Nuake/src/Resource/Prefab.h +++ b/Nuake/src/Resource/Prefab.h @@ -7,6 +7,7 @@ #include #include #include +#include namespace Nuake { @@ -109,11 +110,10 @@ namespace Nuake { uint32_t oldId = nameComponent.ID; uint32_t newId = OS::GetTime(); - nameComponent.Name = scene->GetUniqueEntityName(nameComponent.Name); + nameComponent.Name = nameComponent.Name; nameComponent.ID = newId; newIdsLut[oldId] = newId; - if (isRoot) { Root = entity; @@ -134,6 +134,36 @@ namespace Nuake { auto parent = Engine::GetCurrentScene()->GetEntityByID(newIdsLut[parentC.ParentID]); parent.AddChild(e); } + + // Since the bones point to an entity, and we are instancing a prefab, the new skeleton is gonna be pointing to the wrong + // bones, we need to remap the skeleton to the new entities. We are simply reussing the same map we are using for the + // reparenting. Pretty neat. + std::function recursiveBoneRemapping = [&recursiveBoneRemapping, &newIdsLut](SkeletonNode& currentBone) + { + for (SkeletonNode& bone : currentBone.Children) + { + bone.EntityHandle = newIdsLut[bone.EntityHandle]; + recursiveBoneRemapping(bone); + } + }; + + // Do the remapping of the skeleton + for (auto& e : Entities) + { + if (e.GetID() == Root.GetID() || !e.HasComponent()) + { + continue; + } + + auto& skinnedModelComponent = e.GetComponent(); + if (!skinnedModelComponent.ModelResource) + { + continue; + } + + SkeletonNode& currentBone = skinnedModelComponent.ModelResource->GetSkeletonRootNode(); + recursiveBoneRemapping(currentBone); + } } return true; }