Implemented Animation Clip asset and animation controller #410
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue