From dc32c5c9aafe437c846c6a0d670901c4ace8dc02 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 7 Mar 2023 20:29:57 +0800 Subject: [PATCH] Implemented saving of animation controller from editor --- .../src/Animation/SHAnimationController.cpp | 8 +-- .../src/Animation/SHAnimationController.h | 8 ++- .../src/Animation/SHAnimatorComponent.cpp | 2 +- .../Animation/SHAnimationControllerEditor.cpp | 67 +++++++++++++++++-- 4 files changed, 73 insertions(+), 12 deletions(-) diff --git a/SHADE_Engine/src/Animation/SHAnimationController.cpp b/SHADE_Engine/src/Animation/SHAnimationController.cpp index 9da907bf..ef15f223 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationController.cpp @@ -118,8 +118,8 @@ namespace SHADE nodes.emplace_back(node); // If there is no start node, this is the first node so make it the starting node - if (!startNode) - startNode = node; + if (!StartingNode) + StartingNode = node; return node; } @@ -132,8 +132,8 @@ namespace SHADE throw std::invalid_argument("[SHAnimationController] Attempted to delete a node that doesn't belong."); // Remove if it is a start node - if (startNode == node) - startNode = {}; + if (StartingNode == node) + StartingNode = {}; // Remove from nodes nodes.erase(iter); diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h index 64210481..7708d0c9 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.h +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -145,6 +145,11 @@ namespace SHADE std::unordered_map Params; float ClipPlaybackTime; }; + + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + Handle StartingNode; /*---------------------------------------------------------------------------------*/ /* Lifecycle Functions */ @@ -186,11 +191,11 @@ namespace SHADE /// /// Name of the parameter. void RemoveParameter(const std::string& name); + void SetStartingNode(Handle node); /*---------------------------------------------------------------------------------*/ /* Getters */ /*---------------------------------------------------------------------------------*/ - Handle GetStartingNode() const noexcept { return startNode; } const std::unordered_map& GetParams() const noexcept { return parameters; } const std::vector>& GetNodes() const noexcept { return nodes; } @@ -199,7 +204,6 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ // State machine - Handle startNode; std::vector> nodes; std::unordered_map parameters; diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index 1ab5c894..0059d721 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -169,7 +169,7 @@ namespace SHADE animInstanceData.Params.emplace(param.first, SHAnimationController::AnimParam(param.second)); } // First Node - animInstanceData.CurrentNode = animController->GetStartingNode(); + animInstanceData.CurrentNode = animController->StartingNode; // Playback Time animInstanceData.ClipPlaybackTime = 0.0f; diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp index 9659f036..a67c6a67 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp @@ -3,7 +3,7 @@ \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu \date Mar 1, 2023 -\brief Contains the definition of SHAnimationControllerEditor's functions. +\brief Contains the definition of SHAnimationControllerEditor's functions. Copyright (C) 2023 DigiPen Institute of Technology. @@ -160,7 +160,7 @@ namespace SHADE // Save Button if (ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data())) { - // TODO: Actually save the resource + controller = serialise(controllerData.value()); // TODO: Actually save the resource } // Discard Button if (ImGui::Button(std::format("{} Discard Changes", ICON_MD_CANCEL).data())) @@ -855,15 +855,72 @@ namespace SHADE } // Mark starting node - if (nodeMap.contains(controller.GetStartingNode())) + if (nodeMap.contains(controller.StartingNode)) { - data.StartingNode = nodeMap[controller.GetStartingNode()]->Index; + data.StartingNode = nodeMap[controller.StartingNode]->Index; } return data; } SHAnimationController SHAnimationControllerEditor::serialise(const AnimControllerData& data) { - return {}; + SHAnimationController controller; + + // Maps data nodes to controller nodes + std::unordered_map> nodeMap; + + // Create all nodes first + for (const auto& node : data.Nodes) + { + auto newNode = controller.CreateNode(); + newNode->Name = node.Name; + newNode->Clip = node.Clip; + + nodeMap[node.Index] = newNode; + } + + // Create links + for (const auto& node : data.Nodes) + { + // Get controller node + auto controllerNode = nodeMap[node.Index]; + + for (auto link : node.Transitions) + { + // Ignore invalid link + if (!nodeMap.contains(link.SourceAttribute.OwnerNodeIndex) || !nodeMap.contains(link.DestinationAttribute.OwnerNodeIndex)) + continue; + + // Get link data + const LinkData& LINK_DATA = data.Links.at(link.Raw); + + SHAnimationController::Transition transition; + transition.Target = nodeMap[link.DestinationAttribute.OwnerNodeIndex]; + + if (data.Params.contains(LINK_DATA.ParamName)) + { + transition.Condition = LINK_DATA.Condition; + transition.ParamName = LINK_DATA.ParamName; + transition.Param.ParamType = data.Params.at(LINK_DATA.ParamName); + transition.Param.Value = LINK_DATA.ParamThresholdValue; + } + + controllerNode->Transitions.emplace_back(std::move(transition)); + } + } + + // Starting Node + if (nodeMap.contains(data.StartingNode)) + { + controller.StartingNode = nodeMap[data.StartingNode]; + } + + // Parameters + for (auto param : data.Params) + { + controller.AddParameter(param.first, param.second); + } + + return controller; } } \ No newline at end of file