diff --git a/src/assets/item.cpp b/src/assets/item.cpp index 2f8596d..7a08273 100644 --- a/src/assets/item.cpp +++ b/src/assets/item.cpp @@ -48,13 +48,32 @@ std::shared_ptr assets::Item::LoadFromFile(const std::string& path } else if (command == "attach") { - iss >> item->bone; - glm::vec3 position; - glm::vec3 angles; - iss >> position.x >> position.y >> position.z >> angles.x >> angles.y >> angles.z; + std::string target; + iss >> target; - item->bone_offset.position = position; - item->bone_offset.rotation = glm::quat(glm::radians(angles)); + if (target == "loc") + { + std::string sk_name, loc_name; + iss >> sk_name >> loc_name; + + auto sk = assets::CacheManager::GetSkeleton("data/" + sk_name + ".sk"); + auto loc = sk->GetLocation(loc_name); + if (!loc) + throw std::runtime_error("Invalid skeleton location: " + loc_name); + + item->bone = loc->bone_name; + item->bone_offset = loc->offset; + } + else + { + item->bone = target; + glm::vec3 position; + glm::vec3 angles; + iss >> position.x >> position.y >> position.z >> angles.x >> angles.y >> angles.z; + + item->bone_offset.position = position; + item->bone_offset.rotation = glm::quat(glm::radians(angles)); + } // ParseTransform(iss, item->bone_offset); } diff --git a/src/assets/skeleton.cpp b/src/assets/skeleton.cpp index b7d7f2f..4a58ed7 100644 --- a/src/assets/skeleton.cpp +++ b/src/assets/skeleton.cpp @@ -66,6 +66,18 @@ std::shared_ptr assets::Skeleton::LoadFromFile(const std collision::SetShapeMaterial(*hitbone.col_shape, collision::PM_FLESH); } + else if (command == "loc") + { + std::string loc_name, bone_name; + iss >> loc_name >> bone_name; + + auto& loc = skeleton->locations_[loc_name]; + ParseTransform(iss, loc.offset); + + loc.bone_name = bone_name; + int bone_idx = skeleton->GetBoneIndex(bone_name); + loc.bone_idx = bone_idx >= 0 ? bone_idx : 0; + } }); skeleton->AddAimBones(); @@ -107,6 +119,15 @@ const assets::Animation* assets::Skeleton::GetAnimation(const std::string& name) return GetAnimation(GetAnimationIdx(name)); } +const assets::SkeletonLocation* assets::Skeleton::GetLocation(const std::string& name) const +{ + auto it = locations_.find(name); + if (it == locations_.end()) + return nullptr; + + return &it->second; +} + void assets::Skeleton::AddBone(const std::string& name, const std::string& parent_name, const Transform& transform) { int index = static_cast(bones_.size()); diff --git a/src/assets/skeleton.hpp b/src/assets/skeleton.hpp index 13dc8da..5d6e147 100644 --- a/src/assets/skeleton.hpp +++ b/src/assets/skeleton.hpp @@ -39,6 +39,13 @@ struct HitBone std::unique_ptr col_shape; }; +struct SkeletonLocation +{ + size_t bone_idx = 0; + std::string bone_name; + Transform offset; +}; + class Skeleton { public: @@ -56,6 +63,7 @@ public: const std::vector& GetAimBones() const { return aim_bones_; } const std::vector& GetHitBones() const { return hit_bones_; } + const SkeletonLocation* GetLocation(const std::string& name) const; private: void AddBone(const std::string& name, const std::string& parent_name, const Transform& transform); @@ -74,6 +82,7 @@ private: std::vector aim_bones_; std::vector hit_bones_; + std::map locations_; }; } // namespace assets \ No newline at end of file