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);
// 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);

View File

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

View File

@ -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<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;
}
}