Implemented saving of animation controller from editor

This commit is contained in:
Kah Wei 2023-03-07 20:29:57 +08:00
parent ff27925f2d
commit dc32c5c9aa
4 changed files with 73 additions and 12 deletions

View File

@ -118,8 +118,8 @@ namespace SHADE
nodes.emplace_back(node); nodes.emplace_back(node);
// If there is no start node, this is the first node so make it the starting node // If there is no start node, this is the first node so make it the starting node
if (!startNode) if (!StartingNode)
startNode = node; StartingNode = node;
return node; return node;
} }
@ -132,8 +132,8 @@ namespace SHADE
throw std::invalid_argument("[SHAnimationController] Attempted to delete a node that doesn't belong."); throw std::invalid_argument("[SHAnimationController] Attempted to delete a node that doesn't belong.");
// Remove if it is a start node // Remove if it is a start node
if (startNode == node) if (StartingNode == node)
startNode = {}; StartingNode = {};
// Remove from nodes // Remove from nodes
nodes.erase(iter); nodes.erase(iter);

View File

@ -146,6 +146,11 @@ namespace SHADE
float ClipPlaybackTime; float ClipPlaybackTime;
}; };
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
Handle<Node> StartingNode;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Lifecycle Functions */ /* Lifecycle Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -186,11 +191,11 @@ namespace SHADE
/// </summary> /// </summary>
/// <param name="name">Name of the parameter.</param> /// <param name="name">Name of the parameter.</param>
void RemoveParameter(const std::string& name); void RemoveParameter(const std::string& name);
void SetStartingNode(Handle<Node> node);
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Getters */ /* Getters */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Handle<Node> GetStartingNode() const noexcept { return startNode; }
const std::unordered_map<std::string, AnimParam::Type>& GetParams() const noexcept { return parameters; } const std::unordered_map<std::string, AnimParam::Type>& GetParams() const noexcept { return parameters; }
const std::vector<Handle<Node>>& GetNodes() const noexcept { return nodes; } const std::vector<Handle<Node>>& GetNodes() const noexcept { return nodes; }
@ -199,7 +204,6 @@ namespace SHADE
/* Data Members */ /* Data Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
// State machine // State machine
Handle<Node> startNode;
std::vector<Handle<Node>> nodes; std::vector<Handle<Node>> nodes;
std::unordered_map<std::string, AnimParam::Type> parameters; std::unordered_map<std::string, AnimParam::Type> parameters;

View File

@ -169,7 +169,7 @@ namespace SHADE
animInstanceData.Params.emplace(param.first, SHAnimationController::AnimParam(param.second)); animInstanceData.Params.emplace(param.first, SHAnimationController::AnimParam(param.second));
} }
// First Node // First Node
animInstanceData.CurrentNode = animController->GetStartingNode(); animInstanceData.CurrentNode = animController->StartingNode;
// Playback Time // Playback Time
animInstanceData.ClipPlaybackTime = 0.0f; animInstanceData.ClipPlaybackTime = 0.0f;

View File

@ -160,7 +160,7 @@ namespace SHADE
// Save Button // Save Button
if (ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data())) 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 // Discard Button
if (ImGui::Button(std::format("{} Discard Changes", ICON_MD_CANCEL).data())) if (ImGui::Button(std::format("{} Discard Changes", ICON_MD_CANCEL).data()))
@ -855,15 +855,72 @@ namespace SHADE
} }
// Mark starting node // 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; return data;
} }
SHAnimationController SHAnimationControllerEditor::serialise(const AnimControllerData& data) SHAnimationController SHAnimationControllerEditor::serialise(const AnimControllerData& data)
{ {
return {}; SHAnimationController controller;
// Maps data nodes to controller nodes
std::unordered_map<NodeIndex, Handle<SHAnimationController::Node>> 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;
} }
} }