Implemented Animation Clip asset and animation controller #410

Merged
XiaoQiDigipen merged 66 commits from SP3-22-AnimationController into main 2023-03-09 16:19:40 +08:00
4 changed files with 73 additions and 12 deletions
Showing only changes of commit dc32c5c9aa - Show all commits

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

@ -145,6 +145,11 @@ namespace SHADE
std::unordered_map<std::string, AnimParam> Params; std::unordered_map<std::string, AnimParam> Params;
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

@ -3,7 +3,7 @@
\author Tng Kah Wei, kahwei.tng, 390009620 \author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu \par email: kahwei.tng\@digipen.edu
\date Mar 1, 2023 \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. Copyright (C) 2023 DigiPen Institute of Technology.
@ -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;
} }
} }