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