Implemented Animation Clip asset and animation controller #410
|
@ -103,10 +103,10 @@ namespace SHADE
|
||||||
/*-------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------*/
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
/*-------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
Handle<Node> Target;
|
||||||
ConditionType Condition;
|
ConditionType Condition;
|
||||||
AnimParam Param;
|
AnimParam Param;
|
||||||
std::string ParamName;
|
std::string ParamName;
|
||||||
Handle<Node> Target;
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------*/
|
||||||
/* Usage Functions */
|
/* Usage Functions */
|
||||||
|
|
|
@ -38,6 +38,25 @@ namespace SHADE
|
||||||
void SHAnimationControllerEditor::Init()
|
void SHAnimationControllerEditor::Init()
|
||||||
{
|
{
|
||||||
SHEditorWindow::Init();
|
SHEditorWindow::Init();
|
||||||
|
|
||||||
|
SHAnimationController controller;
|
||||||
|
auto n1 = controller.CreateNode();
|
||||||
|
auto n2 = controller.CreateNode();
|
||||||
|
auto n3 = controller.CreateNode();
|
||||||
|
|
||||||
|
n1->Name = "N1";
|
||||||
|
n2->Name = "N2";
|
||||||
|
n3->Name = "N3";
|
||||||
|
|
||||||
|
SHAnimationController::Transition t;
|
||||||
|
t.Target = n3;
|
||||||
|
|
||||||
|
n1->Transitions.emplace_back(t);
|
||||||
|
n2->Transitions.emplace_back(t);
|
||||||
|
t.Target = n1;
|
||||||
|
n3->Transitions.emplace_back(t);
|
||||||
|
|
||||||
|
Open(controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAnimationControllerEditor::Update()
|
void SHAnimationControllerEditor::Update()
|
||||||
|
@ -46,79 +65,17 @@ namespace SHADE
|
||||||
|
|
||||||
if (Begin())
|
if (Begin())
|
||||||
{
|
{
|
||||||
drawMenuBar();
|
|
||||||
|
|
||||||
ImNodes::BeginNodeEditor();
|
// Only render the node editor if there is controller data
|
||||||
|
if (controllerData.has_value())
|
||||||
{
|
{
|
||||||
/* Pre Process Nodes */
|
drawActiveMenuBar();
|
||||||
std::unordered_map<Handle<SHAnimationController::Node>, int> inputAttribCount;
|
drawNodeEditor();
|
||||||
std::unordered_map<Handle<SHAnimationController::Node>, int> outputAttribCount;
|
}
|
||||||
for (auto node : controller.GetNodes())
|
else
|
||||||
{
|
{
|
||||||
// Have at least one for each
|
SHEditorUI::CenteredText("No animation controller is selected.");
|
||||||
inputAttribCount[node] = 1;
|
|
||||||
outputAttribCount[node] = 1;
|
|
||||||
}
|
}
|
||||||
for (auto node : controller.GetNodes())
|
|
||||||
{
|
|
||||||
for (auto transition : node->Transitions)
|
|
||||||
{
|
|
||||||
++inputAttribCount[transition.Target];
|
|
||||||
}
|
|
||||||
outputAttribCount[node] += node->Transitions.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Draw Nodes */
|
|
||||||
int id = 0;
|
|
||||||
for (auto node : controller.GetNodes())
|
|
||||||
{
|
|
||||||
// Draw the node
|
|
||||||
ImNodes::BeginNode(id);
|
|
||||||
{
|
|
||||||
// Title
|
|
||||||
ImNodes::BeginNodeTitleBar();
|
|
||||||
{
|
|
||||||
ImGui::TextUnformatted(node->Name.c_str());
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::Button(ICON_MD_EDIT);
|
|
||||||
}
|
|
||||||
ImNodes::EndNodeTitleBar();
|
|
||||||
|
|
||||||
// Body
|
|
||||||
ImGui::Text("Clip");
|
|
||||||
ImGui::SameLine();
|
|
||||||
std::array<char, 255> buffer = { '\0' };
|
|
||||||
ImGui::PushItemWidth(80.0f);
|
|
||||||
ImGui::InputText("", buffer.data(), buffer.size());
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
|
|
||||||
// Input Nodes
|
|
||||||
for (int i = 0; i < inputAttribCount[node]; ++i)
|
|
||||||
{
|
|
||||||
NodeAttributeIndex nidx;
|
|
||||||
nidx.OwnerNodeIndex = id;
|
|
||||||
nidx.AttributeIndex = i;
|
|
||||||
ImNodes::BeginInputAttribute(nidx.Raw);
|
|
||||||
ImNodes::EndInputAttribute();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output Nodes
|
|
||||||
for (int i = 0; i < outputAttribCount[node]; ++i)
|
|
||||||
{
|
|
||||||
NodeAttributeIndex nidx;
|
|
||||||
nidx.OwnerNodeIndex = id;
|
|
||||||
nidx.AttributeIndex = inputAttribCount[node] + i;
|
|
||||||
ImNodes::BeginOutputAttribute(nidx.Raw);
|
|
||||||
ImNodes::EndOutputAttribute();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImNodes::EndNode();
|
|
||||||
++id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImNodes::MiniMap(0.2f, ImNodesMiniMapLocation_BottomRight);
|
|
||||||
ImNodes::EndNodeEditor();
|
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
@ -128,19 +85,246 @@ namespace SHADE
|
||||||
SHEditorWindow::Exit();
|
SHEditorWindow::Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHAnimationControllerEditor::Open(const SHAnimationController& controller)
|
||||||
|
{
|
||||||
|
controllerData = deserialise(controller);
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
void SHAnimationControllerEditor::drawMenuBar()
|
void SHAnimationControllerEditor::drawActiveMenuBar()
|
||||||
{
|
{
|
||||||
if (ImGui::BeginMenuBar())
|
if (ImGui::BeginMenuBar())
|
||||||
{
|
{
|
||||||
|
if (ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data()))
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
if (ImGui::Button(std::format("{} Add", ICON_MD_ADD).data()))
|
if (ImGui::Button(std::format("{} Add", ICON_MD_ADD).data()))
|
||||||
{
|
{
|
||||||
controller.CreateNode();
|
createNode(controllerData.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndMenuBar();
|
ImGui::EndMenuBar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHAnimationControllerEditor::drawNodeEditor()
|
||||||
|
{
|
||||||
|
static constexpr float NODE_WIDTH = 80.0f;
|
||||||
|
|
||||||
|
ImNodes::BeginNodeEditor();
|
||||||
|
{
|
||||||
|
/* Draw Nodes */
|
||||||
|
for (auto& node : controllerData->Nodes)
|
||||||
|
{
|
||||||
|
// Draw the node
|
||||||
|
ImNodes::BeginNode(node.Index);
|
||||||
|
{
|
||||||
|
// Title
|
||||||
|
ImNodes::BeginNodeTitleBar();
|
||||||
|
{
|
||||||
|
if (node.EditingName)
|
||||||
|
{
|
||||||
|
if (ImGui::Button(ICON_MD_DONE))
|
||||||
|
{
|
||||||
|
node.EditingName = false;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
static constexpr float TEXT_FIELD_PADDING = 15.0f;
|
||||||
|
ImGui::SetNextItemWidth(std::max(ImGui::CalcTextSize(node.Name.c_str()).x + TEXT_FIELD_PADDING, NODE_WIDTH));
|
||||||
|
SHEditorUI::InputTextField("", node.Name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ImGui::Button(ICON_MD_EDIT))
|
||||||
|
{
|
||||||
|
node.EditingName = true;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Text(node.Name.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImNodes::EndNodeTitleBar();
|
||||||
|
|
||||||
|
// Body
|
||||||
|
ImGui::Text("Clip");
|
||||||
|
ImGui::SameLine();
|
||||||
|
std::array<char, 255> buffer = { '\0' };
|
||||||
|
ImGui::SetNextItemWidth(std::max(NODE_WIDTH, ImGui::CalcTextSize(buffer.data()).x));
|
||||||
|
ImGui::InputText("", buffer.data(), buffer.size());
|
||||||
|
|
||||||
|
// Input Nodes
|
||||||
|
for (auto inputAttrib : node.InputAttribs)
|
||||||
|
{
|
||||||
|
drawInputNode(inputAttrib.Raw, ImNodesPinShape_CircleFilled);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render an extra input
|
||||||
|
drawInputNode(getExtraInputAttrib(node.Index).Raw, ImNodesPinShape_Circle);
|
||||||
|
|
||||||
|
// Output Nodes
|
||||||
|
for (auto outputAttrib : node.OutputAttribs)
|
||||||
|
{
|
||||||
|
drawOutputNode(outputAttrib.Raw, node.Index, ImNodesPinShape_TriangleFilled);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render an extra output
|
||||||
|
drawOutputNode(getExtraOutputAttrib(node.Index).Raw, node.Index, ImNodesPinShape_Triangle);
|
||||||
|
}
|
||||||
|
ImNodes::EndNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw links
|
||||||
|
for (auto link : controllerData->Links)
|
||||||
|
{
|
||||||
|
ImNodes::Link(link.first, link.second.SourceAttrib.Raw, link.second.DestAttrib.Raw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImNodes::MiniMap(0.2f, ImNodesMiniMapLocation_BottomRight);
|
||||||
|
ImNodes::EndNodeEditor();
|
||||||
|
|
||||||
|
int sourceAttrib, destAttrib;
|
||||||
|
if (ImNodes::IsLinkCreated(&sourceAttrib, &destAttrib))
|
||||||
|
{
|
||||||
|
// Get the two indices
|
||||||
|
NodeAttributeIndex sourceAttribIndex, destAttribIndex;
|
||||||
|
sourceAttribIndex.Raw = static_cast<uint16_t>(sourceAttrib);
|
||||||
|
destAttribIndex.Raw = static_cast<uint16_t>(destAttrib);
|
||||||
|
|
||||||
|
// Ensure that we can access the nodes
|
||||||
|
if (controllerData->IndexToNodeMap.contains(sourceAttribIndex.OwnerNodeIndex) &&
|
||||||
|
controllerData->IndexToNodeMap.contains(destAttribIndex.OwnerNodeIndex))
|
||||||
|
{
|
||||||
|
// Retrieve the nodes
|
||||||
|
auto inputNodeIter = controllerData->IndexToNodeMap[sourceAttribIndex.OwnerNodeIndex];
|
||||||
|
auto outputNodeIter = *controllerData->IndexToNodeMap[destAttribIndex.OwnerNodeIndex];
|
||||||
|
|
||||||
|
// Create link
|
||||||
|
createLink
|
||||||
|
(
|
||||||
|
controllerData.value(),
|
||||||
|
controllerData->IndexToNodeMap[sourceAttribIndex.OwnerNodeIndex],
|
||||||
|
controllerData->IndexToNodeMap[destAttribIndex.OwnerNodeIndex]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SHAnimationControllerEditor::NodeAttributeIndex SHAnimationControllerEditor::getExtraInputAttrib(uint32_t nodeIndex)
|
||||||
|
{
|
||||||
|
NodeAttributeIndex extraInputAttrib;
|
||||||
|
extraInputAttrib.OwnerNodeIndex = nodeIndex;
|
||||||
|
extraInputAttrib.AttributeIndex = std::numeric_limits<int8_t>::lowest();
|
||||||
|
return extraInputAttrib;
|
||||||
|
}
|
||||||
|
SHAnimationControllerEditor::NodeAttributeIndex SHAnimationControllerEditor::getExtraOutputAttrib(uint32_t nodeIndex)
|
||||||
|
{
|
||||||
|
NodeAttributeIndex extraOutputAttrib;
|
||||||
|
extraOutputAttrib.OwnerNodeIndex = nodeIndex;
|
||||||
|
extraOutputAttrib.AttributeIndex = std::numeric_limits<int8_t>::max();
|
||||||
|
return extraOutputAttrib;
|
||||||
|
}
|
||||||
|
void SHAnimationControllerEditor::drawInputNode(int id, ImNodesPinShape_ pinShape)
|
||||||
|
{
|
||||||
|
ImNodes::BeginInputAttribute(id, pinShape);
|
||||||
|
ImGui::Text("Input");
|
||||||
|
ImNodes::EndInputAttribute();
|
||||||
|
}
|
||||||
|
void SHAnimationControllerEditor::drawOutputNode(int id, int parentNodeId, ImNodesPinShape_ pinShape)
|
||||||
|
{
|
||||||
|
static char const* TITLE = "Output";
|
||||||
|
static float RIGHT_PADDING = 20.0f;
|
||||||
|
|
||||||
|
ImNodes::BeginOutputAttribute(id, ImNodesPinShape_TriangleFilled);
|
||||||
|
ImGui::Indent(ImNodes::GetNodeDimensions(parentNodeId).x - ImGui::CalcTextSize(TITLE).x - RIGHT_PADDING);
|
||||||
|
ImGui::Text(TITLE);
|
||||||
|
ImNodes::EndOutputAttribute();
|
||||||
|
}
|
||||||
|
std::list<SHAnimationControllerEditor::Node>::iterator SHAnimationControllerEditor::createNode(AnimControllerData& data)
|
||||||
|
{
|
||||||
|
Node localNode;
|
||||||
|
localNode.Index = data.NextNodeIndex++;
|
||||||
|
data.Nodes.emplace_back(std::move(localNode));
|
||||||
|
|
||||||
|
// Update the node map
|
||||||
|
auto nodeIter = --data.Nodes.end();
|
||||||
|
data.IndexToNodeMap[localNode.Index] = nodeIter;
|
||||||
|
|
||||||
|
return nodeIter;
|
||||||
|
}
|
||||||
|
void SHAnimationControllerEditor::createLink(AnimControllerData& data, std::list<Node>::iterator sourceNode, std::list<Node>::iterator destNode)
|
||||||
|
{
|
||||||
|
// Update source node's output attributes
|
||||||
|
NodeAttributeIndex attribIndex;
|
||||||
|
attribIndex.OwnerNodeIndex = sourceNode->Index;
|
||||||
|
attribIndex.AttributeIndex = static_cast<int8_t>(sourceNode->OutputAttribs.size() + 1);
|
||||||
|
sourceNode->OutputAttribs.emplace_back(attribIndex);
|
||||||
|
|
||||||
|
// Update target node's input attributes
|
||||||
|
attribIndex.OwnerNodeIndex = destNode->Index;
|
||||||
|
attribIndex.AttributeIndex = static_cast<int8_t>(-(destNode->InputAttribs.size() + 1));
|
||||||
|
destNode->InputAttribs.emplace_back(attribIndex);
|
||||||
|
|
||||||
|
// Create link
|
||||||
|
LinkData link;
|
||||||
|
link.SourceNode = sourceNode;
|
||||||
|
link.TargetNode = destNode;
|
||||||
|
link.SourceAttrib = sourceNode->OutputAttribs.back();
|
||||||
|
link.DestAttrib = destNode->InputAttribs.back();
|
||||||
|
NodeLinkIndex linkIdx;
|
||||||
|
linkIdx.SourceAttribute = link.SourceAttrib;
|
||||||
|
linkIdx.DestinationAttribute = link.DestAttrib;
|
||||||
|
|
||||||
|
data.Links.emplace(linkIdx.Raw, std::move(link));
|
||||||
|
sourceNode->Transitions.emplace_back(linkIdx);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Static Helper Functions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
SHAnimationControllerEditor::AnimControllerData SHAnimationControllerEditor::deserialise(const SHAnimationController& controller)
|
||||||
|
{
|
||||||
|
AnimControllerData data;
|
||||||
|
|
||||||
|
// Maps controller nodes to data nodes
|
||||||
|
std::unordered_map<Handle<SHAnimationController::Node>, std::list<Node>::iterator> nodeMap;
|
||||||
|
|
||||||
|
// Load anim parameters
|
||||||
|
data.Params = controller.GetParams();
|
||||||
|
|
||||||
|
// Load nodes and links
|
||||||
|
for (auto node : controller.GetNodes())
|
||||||
|
{
|
||||||
|
auto localNode = createNode(data);
|
||||||
|
localNode->Name = node->Name;
|
||||||
|
localNode->Clip = node->Clip;
|
||||||
|
nodeMap.emplace(node, localNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load links
|
||||||
|
for (auto node : controller.GetNodes())
|
||||||
|
{
|
||||||
|
// Get the corresponding data node
|
||||||
|
auto dataNodeIter = nodeMap[node];
|
||||||
|
|
||||||
|
for (auto transition : node->Transitions)
|
||||||
|
{
|
||||||
|
// Invalid node check
|
||||||
|
if (!nodeMap.contains(transition.Target))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Get the target node
|
||||||
|
auto targetNodeIter = nodeMap[transition.Target];
|
||||||
|
|
||||||
|
// Create link
|
||||||
|
createLink(data, dataNodeIter, targetNodeIter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
SHAnimationController SHAnimationControllerEditor::serialise(const AnimControllerData& data)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -13,6 +13,9 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
|
|
||||||
// STL Includes
|
// STL Includes
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <optional>
|
||||||
|
// External Dependencies
|
||||||
|
#include <imnodes.h>
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
#include "Editor/EditorWindow/SHEditorWindow.h"
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
@ -39,22 +42,28 @@ namespace SHADE
|
||||||
void Update() override;
|
void Update() override;
|
||||||
void Exit() override;
|
void Exit() override;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Usage Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void Open(const SHAnimationController& controller);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
using NodeIndex = uint8_t;
|
||||||
union NodeAttributeIndex
|
union NodeAttributeIndex
|
||||||
{
|
{
|
||||||
int16_t Raw;
|
uint16_t Raw;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint8_t OwnerNodeIndex;
|
NodeIndex OwnerNodeIndex;
|
||||||
uint8_t AttributeIndex;
|
int8_t AttributeIndex; // Negative is input, positive is output
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
union NodeLinkIndex
|
union NodeLinkIndex
|
||||||
{
|
{
|
||||||
int32_t Raw;
|
uint32_t Raw;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
NodeAttributeIndex SourceAttribute;
|
NodeAttributeIndex SourceAttribute;
|
||||||
|
@ -62,17 +71,55 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Node
|
||||||
|
{
|
||||||
|
NodeIndex Index;
|
||||||
|
std::string Name = "Unnamed Node";
|
||||||
|
Handle<SHAnimationClip> Clip;
|
||||||
|
std::vector<NodeAttributeIndex> InputAttribs;
|
||||||
|
std::vector<NodeAttributeIndex> OutputAttribs;
|
||||||
|
std::vector<NodeLinkIndex> Transitions;
|
||||||
|
bool EditingName = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LinkData
|
||||||
|
{
|
||||||
|
std::list<Node>::iterator SourceNode;
|
||||||
|
std::list<Node>::iterator TargetNode;
|
||||||
|
NodeAttributeIndex SourceAttrib;
|
||||||
|
NodeAttributeIndex DestAttrib;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AnimControllerData
|
||||||
|
{
|
||||||
|
std::list<Node> Nodes;
|
||||||
|
std::unordered_map<std::string, SHAnimationController::AnimParam::Type> Params;
|
||||||
|
std::unordered_map<uint32_t, LinkData> Links;
|
||||||
|
int NextNodeIndex = 0; // Index to use for newly created nodes
|
||||||
|
std::unordered_map<NodeIndex, std::list<Node>::iterator> IndexToNodeMap;
|
||||||
|
};
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
SHAnimationController controller;
|
std::optional<AnimControllerData> controllerData;
|
||||||
std::vector<std::vector<NodeAttributeIndex>> inputNodesMap;
|
|
||||||
std::vector<std::vector<NodeAttributeIndex>> outputNodesMap;
|
|
||||||
std::vector<NodeLinkIndex> linkIndices; // Encodes details of the link in the node index
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
void drawMenuBar();
|
void drawActiveMenuBar();
|
||||||
|
void drawNodeEditor();
|
||||||
|
NodeAttributeIndex getExtraInputAttrib(uint32_t nodeIndex);
|
||||||
|
NodeAttributeIndex getExtraOutputAttrib(uint32_t nodeIndex);
|
||||||
|
void drawInputNode(int id, ImNodesPinShape_ pinShape);
|
||||||
|
void drawOutputNode(int id, int parentNodeId, ImNodesPinShape_ pinShape);
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Static Helper Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
static std::list<Node>::iterator createNode(AnimControllerData& data);
|
||||||
|
static void createLink(AnimControllerData& data, std::list<Node>::iterator sourceNode, std::list<Node>::iterator destNode);
|
||||||
|
static AnimControllerData deserialise(const SHAnimationController& controller);
|
||||||
|
static SHAnimationController serialise(const AnimControllerData& data);
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -137,6 +137,15 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
ImGui::Text(title.c_str());
|
ImGui::Text(title.c_str());
|
||||||
}
|
}
|
||||||
|
void SHEditorUI::CenteredText(const std::string& text)
|
||||||
|
{
|
||||||
|
const auto WINDOW_SIZE = ImGui::GetWindowSize();
|
||||||
|
const auto TEXT_SIZE = ImGui::CalcTextSize(text.c_str());
|
||||||
|
|
||||||
|
ImGui::SetCursorPosX((WINDOW_SIZE.x - TEXT_SIZE.x) * 0.5f);
|
||||||
|
ImGui::SetCursorPosY((WINDOW_SIZE.y - TEXT_SIZE.y) * 0.5f);
|
||||||
|
ImGui::Text(text.c_str());
|
||||||
|
}
|
||||||
bool SHEditorUI::SmallButton(const std::string& title)
|
bool SHEditorUI::SmallButton(const std::string& title)
|
||||||
{
|
{
|
||||||
return ImGui::SmallButton(title.c_str());
|
return ImGui::SmallButton(title.c_str());
|
||||||
|
|
|
@ -150,6 +150,12 @@ namespace SHADE
|
||||||
/// <param name="title">Text to display.</param>
|
/// <param name="title">Text to display.</param>
|
||||||
static void Text(const std::string& title);
|
static void Text(const std::string& title);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Renders a text widget that is vertically and horizontally centered in the current
|
||||||
|
/// window.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text">Text to display.</param>
|
||||||
|
static void CenteredText(const std::string& text);
|
||||||
|
/// <summary>
|
||||||
/// Creates a small inline button widget.
|
/// Creates a small inline button widget.
|
||||||
/// <br/>
|
/// <br/>
|
||||||
/// Wraps up ImGui::SmallButton().
|
/// Wraps up ImGui::SmallButton().
|
||||||
|
|
Loading…
Reference in New Issue