From e125bf5fdba0d3e57c2bf41a3da041505a1e63d9 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Tue, 5 Sep 2023 20:28:33 -0400 Subject: [PATCH] Added skeleton creation --- Editor/src/ComponentsPanel/BonePanel.h | 36 ++++++++++++++++ .../src/ComponentsPanel/SkinnedModelPanel.h | 41 ++++++++++++++++--- Nuake/src/Scene/Components/BoneComponent.cpp | 8 ++++ Nuake/src/Scene/Components/BoneComponent.h | 15 +++++++ Nuake/src/Scene/Scene.cpp | 28 +++++++++++++ Nuake/src/Scene/Scene.h | 3 ++ 6 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 Editor/src/ComponentsPanel/BonePanel.h create mode 100644 Nuake/src/Scene/Components/BoneComponent.cpp create mode 100644 Nuake/src/Scene/Components/BoneComponent.h diff --git a/Editor/src/ComponentsPanel/BonePanel.h b/Editor/src/ComponentsPanel/BonePanel.h new file mode 100644 index 00000000..cd80a554 --- /dev/null +++ b/Editor/src/ComponentsPanel/BonePanel.h @@ -0,0 +1,36 @@ +#pragma once +#include "ComponentPanel.h" + +#include +#include +#include +#include + +class BonePanel : ComponentPanel +{ +public: + BonePanel() {} + + void Draw(Nuake::Entity entity) override + { + using namespace Nuake; + + if (!entity.HasComponent()) + return; + + auto& component = entity.GetComponent(); + BeginComponentTable(BONE, BoneComponent); + { + { + ImGui::Text("Name"); + ImGui::TableNextColumn(); + + ImGui::InputText("##BoneName", &component.Name); + ImGui::TableNextColumn(); + + ComponentTableReset(component.Name, ""); + } + } + EndComponentTable(); + } +}; \ No newline at end of file diff --git a/Editor/src/ComponentsPanel/SkinnedModelPanel.h b/Editor/src/ComponentsPanel/SkinnedModelPanel.h index 9bebded1..66d9b3da 100644 --- a/Editor/src/ComponentsPanel/SkinnedModelPanel.h +++ b/Editor/src/ComponentsPanel/SkinnedModelPanel.h @@ -12,8 +12,9 @@ class SkinnedModelPanel : ComponentPanel { private: - Scope _modelInspector; - bool _expanded = false; + Scope m_ModelInspector; + bool m_Expanded = false; + std::string m_QueuedModelPath; public: SkinnedModelPanel() @@ -45,9 +46,9 @@ public: { } - if (_expanded) + if (m_Expanded) { - _modelInspector->Draw(); + m_ModelInspector->Draw(); } if (ImGui::BeginDragDropTarget()) @@ -64,13 +65,41 @@ public: } else { - component.ModelPath = fullPath; - component.LoadModel(); + m_QueuedModelPath = fullPath; + ImGui::OpenPopup("Create Skeleton"); } } ImGui::EndDragDropTarget(); } + if (ImGui::BeginPopupModal("Create Skeleton", NULL, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::SetItemDefaultFocus(); + ImGui::Text("Would you like to create the skeleton structure in the scene tree?"); + ImGui::Separator(); + + if (ImGui::Button("OK", ImVec2(120, 0))) + { + component.ModelPath = m_QueuedModelPath; + component.LoadModel(); + + Scene* scene = entity.GetScene(); + scene->CreateSkeleton(entity); + + ImGui::CloseCurrentPopup(); + } + + ImGui::SetItemDefaultFocus(); + ImGui::SameLine(); + + if (ImGui::Button("Cancel", ImVec2(120, 0))) + { + ImGui::CloseCurrentPopup(); + } + + ImGui::EndPopup(); + } + ImGui::TableNextColumn(); ComponentTableReset(component.ModelPath, ""); } diff --git a/Nuake/src/Scene/Components/BoneComponent.cpp b/Nuake/src/Scene/Components/BoneComponent.cpp new file mode 100644 index 00000000..d97d1a95 --- /dev/null +++ b/Nuake/src/Scene/Components/BoneComponent.cpp @@ -0,0 +1,8 @@ +#include "src/Core/Core.h" + +#include "BoneComponent.h" + +namespace Nuake +{ + +} \ No newline at end of file diff --git a/Nuake/src/Scene/Components/BoneComponent.h b/Nuake/src/Scene/Components/BoneComponent.h new file mode 100644 index 00000000..2bb08862 --- /dev/null +++ b/Nuake/src/Scene/Components/BoneComponent.h @@ -0,0 +1,15 @@ +#pragma once +#include "src/Core/Core.h" + + +namespace Nuake +{ + class BoneComponent + { + public: + BoneComponent() = default; + ~BoneComponent() = default; + + std::string Name; + }; +} \ No newline at end of file diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index 58750a01..2a8d575c 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -24,6 +24,7 @@ #include "src/Scene/Components/WrenScriptComponent.h" #include "src/Scene/Components/BSPBrushComponent.h" #include "src/Scene/Components/InterfaceComponent.h" +#include "src/Scene/Components/SkinnedModelComponent.h" #include #include @@ -448,4 +449,31 @@ namespace Nuake return true; } + + void Scene::CreateSkeleton(Entity& entity) + { + // We cannot create a component if the entity doesn't have a skinned model + if (!entity.HasComponent()) + { + const std::string msg = "Cannot create a skeleton on entity: " + std::to_string(entity.GetID()); + Logger::Log(msg); + return; + } + + SkinnedModelComponent& component = entity.GetComponent(); + for (Ref& model : component.ModelResource->GetMeshes()) + { + auto& bones = model->GetBones(); + if (bones.size() > 0) + { + for (auto& bone : bones) + { + auto& parentComponent = entity.GetComponent(); + + Entity boneEntity = CreateEntity(bone.Name); + entity.AddChild(boneEntity); + } + } + } + } } diff --git a/Nuake/src/Scene/Scene.h b/Nuake/src/Scene/Scene.h index 33e03ac2..2d2cf74b 100644 --- a/Nuake/src/Scene/Scene.h +++ b/Nuake/src/Scene/Scene.h @@ -89,5 +89,8 @@ namespace Nuake json Serialize() override; bool Deserialize(const json& j) override; + + // Component specific utilies + void CreateSkeleton(Entity& entity); }; }