diff --git a/src/AnimGraphEditor.cc b/src/AnimGraphEditor.cc index 9679161..eba40a4 100644 --- a/src/AnimGraphEditor.cc +++ b/src/AnimGraphEditor.cc @@ -7,7 +7,7 @@ #include "AnimGraphResource.h" #include "imnodes.h" -using namespace AnimGraphCode; +using namespace AniGraph; ImNodesPinShape sGetSocketShapeFromSocketType(const SocketType& socket_type) { switch (socket_type) { diff --git a/src/AnimGraphResource.cc b/src/AnimGraphResource.cc index f23bd04..40c0c3a 100644 --- a/src/AnimGraphResource.cc +++ b/src/AnimGraphResource.cc @@ -8,7 +8,7 @@ #include "3rdparty/json/json.hpp" -namespace AnimGraphCode { +namespace AniGraph { using json = nlohmann::json; @@ -351,7 +351,7 @@ bool AnimGraphResource::loadFromFile(const char* filename) { return true; } -void AnimGraph::UpdateOrderedNodes() { +void AnimGraph::updateOrderedNodes() { std::vector node_index_stack; node_index_stack.push_back(0); @@ -387,7 +387,7 @@ void AnimGraph::UpdateOrderedNodes() { } } -void AnimGraph::MarkActiveNodes() { +void AnimGraph::markActiveNodes() { for (size_t i = 0, n = m_nodes.size(); i < n; i++) { m_nodes[i]->m_state = AnimNodeEvalState::Deactivated; } @@ -403,7 +403,7 @@ void AnimGraph::MarkActiveNodes() { for (size_t i = 0, n = m_eval_ordered_nodes.size(); i < n; i++) { AnimNode* node = m_eval_ordered_nodes[i]; - if (CheckIsNodeActive(node)) { + if (checkIsNodeActive(node)) { int node_index = node->m_index; node->MarkActiveInputs(m_node_inputs[node_index]); @@ -418,7 +418,7 @@ void AnimGraph::MarkActiveNodes() { } } -void AnimGraph::EvalSyncTracks() { +void AnimGraph::evalSyncTracks() { for (size_t i = m_eval_ordered_nodes.size() - 1; i >= 0; i--) { AnimNode* node = m_eval_ordered_nodes[i]; int node_index = node->m_index; @@ -430,7 +430,7 @@ void AnimGraph::EvalSyncTracks() { } } -void AnimGraph::UpdateTime(float dt) { +void AnimGraph::updateTime(float dt) { const std::vector graph_output_inputs = m_node_inputs[0]; for (size_t i = 0, n = graph_output_inputs.size(); i < n; i++) { AnimNode* node = m_eval_ordered_nodes[i]; @@ -464,7 +464,7 @@ void AnimGraph::UpdateTime(float dt) { } } -void AnimGraph::Evaluate() { +void AnimGraph::evaluate() { for (size_t i = m_eval_ordered_nodes.size() - 1; i >= 0; i--) { AnimNode* node = m_eval_ordered_nodes[i]; if (node->m_state == AnimNodeEvalState::Deactivated) { @@ -475,7 +475,7 @@ void AnimGraph::Evaluate() { } } -void* AnimGraph::GetOutput(const std::string& name) const { +void* AnimGraph::getOutput(const std::string& name) const { Socket* socket = m_socket_accessor->FindInputSocket(name); if (socket == nullptr) { return nullptr; @@ -484,7 +484,7 @@ void* AnimGraph::GetOutput(const std::string& name) const { return socket->m_value.ptr; } -void* AnimGraph::GetInput(const std::string& name) const { +void* AnimGraph::getInput(const std::string& name) const { Socket* socket = m_socket_accessor->FindOutputSocket(name); if (socket == nullptr) { return nullptr; @@ -493,4 +493,4 @@ void* AnimGraph::GetInput(const std::string& name) const { return *(socket->m_value.ptr_ptr); } -} // namespace AnimGraphCode \ No newline at end of file +} // namespace AniGraph \ No newline at end of file diff --git a/src/AnimGraphResource.h b/src/AnimGraphResource.h index 1013f13..ac0e96f 100644 --- a/src/AnimGraphResource.h +++ b/src/AnimGraphResource.h @@ -14,19 +14,11 @@ #include "SyncTrack.h" -namespace AnimGraphCode { +namespace AniGraph { -enum class SocketType { - SocketTypeUndefined, - SocketTypeBool, - SocketTypeAnimation, - SocketTypeFloat, - SocketTypeVec3, - SocketTypeQuat, - SocketTypeString -}; - -enum SocketFlags { SocketFlagAffectsTime = 1 }; +// +// Data types +// struct AnimData { float m_bone_transforms[16]; @@ -55,7 +47,18 @@ SplitOutputAttributeId(int attribute_id, int* node_id, int* output_index) { *output_index = (attribute_id >> 23) - 1; } -struct AnimNodeResource; + +enum class SocketType { + SocketTypeUndefined, + SocketTypeBool, + SocketTypeAnimation, + SocketTypeFloat, + SocketTypeVec3, + SocketTypeQuat, + SocketTypeString +}; + +enum SocketFlags { SocketFlagAffectsTime = 1 }; struct Socket { std::string m_name; @@ -77,7 +80,6 @@ struct AnimNodeResource { std::string m_type_name; AnimNode* m_anim_node = nullptr; NodeSocketAccessorBase* m_socket_accessor = nullptr; - float m_position[2] = {0.f, 0.f}; }; @@ -140,6 +142,10 @@ struct AnimNode { struct NodeSocketAccessorBase { + std::vector m_properties; + std::vector m_inputs; + std::vector m_outputs; + NodeSocketAccessorBase() {} virtual ~NodeSocketAccessorBase() {} @@ -319,10 +325,6 @@ struct NodeSocketAccessorBase { size_t GetOutputIndex(const std::string& name) { return GetSocketIndex(m_outputs, name); } - - std::vector m_properties; - std::vector m_inputs; - std::vector m_outputs; }; template @@ -337,6 +339,9 @@ struct NodeRegistry { AnimNode* node); }; +// +// BlendTreeNode +// struct BlendTreeNode : public AnimNode {}; template <> @@ -344,6 +349,9 @@ struct NodeSocketAccessor : public NodeSocketAccessorBase { NodeSocketAccessor(AnimNode* node_) {} }; +// +// Blend2Node +// struct Blend2Node : public AnimNode { AnimData m_input0; AnimData m_input1; @@ -351,7 +359,6 @@ struct Blend2Node : public AnimNode { float m_blend_weight = 0.f; bool m_sync_blend = false; - virtual void MarkActiveInputs(const std::vector& inputs) override { for (size_t i = 0, n = inputs.size(); i < n; i++) { AnimNode* input_node = inputs[i].m_node; @@ -421,6 +428,9 @@ struct NodeSocketAccessor : public NodeSocketAccessorBase { } }; +// +// SpeedScaleNode +// struct SpeedScaleNode : public AnimNode { AnimData m_input; AnimData* m_output = nullptr; @@ -447,6 +457,9 @@ struct NodeSocketAccessor : public NodeSocketAccessorBase { } }; +// +// AnimSamplerNode +// struct AnimSamplerNode : public AnimNode { AnimData* m_output = nullptr; std::string m_filename; @@ -462,6 +475,9 @@ struct NodeSocketAccessor : public NodeSocketAccessorBase { } }; +// +// AnimGraphResource +// struct AnimGraphConnection { int m_source_node_index; int m_source_socket_index; @@ -490,7 +506,6 @@ struct AnimGraphResource { bool loadFromFile(const char* filename); AnimNodeResource& getGraphOutputNode() { return m_nodes[0]; } - AnimNodeResource& getGraphInputNode() { return m_nodes[1]; } size_t addNode(AnimNodeResource node_resource) { @@ -596,7 +611,22 @@ static inline AnimNodeResource AnimNodeResourceFactory( return result; } +// +// AnimGraph (Runtime) +// struct AnimGraph { + AnimData m_local_transforms; + + std::vector m_nodes; + std::vector m_eval_ordered_nodes; + std::vector > m_node_inputs; + NodeSocketAccessorBase* m_socket_accessor; + char* m_input_buffer = nullptr; + char* m_output_buffer = nullptr; + + std::vector& getGraphOutputs() { return m_socket_accessor->m_inputs; } + std::vector& getGraphInputs() { return m_socket_accessor->m_outputs; } + ~AnimGraph() { delete[] m_input_buffer; delete[] m_output_buffer; @@ -608,15 +638,15 @@ struct AnimGraph { delete m_socket_accessor; } - void UpdateOrderedNodes(); - void MarkActiveNodes(); - bool CheckIsNodeActive(AnimNode* node) { + void updateOrderedNodes(); + void markActiveNodes(); + bool checkIsNodeActive(AnimNode* node) { return node->m_state != AnimNodeEvalState::Deactivated; } - void EvalSyncTracks(); - void UpdateTime(float dt); - void Evaluate(); - void Reset() { + void evalSyncTracks(); + void updateTime(float dt); + void evaluate(); + void reset() { for (size_t i = 0, n = m_nodes.size(); i < n; i++) { m_nodes[i]->m_time_now = 0.f; m_nodes[i]->m_time_last = 0.f; @@ -624,20 +654,9 @@ struct AnimGraph { } } - AnimData m_local_transforms; - std::vector m_nodes; - std::vector m_eval_ordered_nodes; - std::vector > m_node_inputs; - NodeSocketAccessorBase* m_socket_accessor; - char* m_input_buffer = nullptr; - char* m_output_buffer = nullptr; - - std::vector& GetGraphOutputs() { return m_socket_accessor->m_inputs; } - std::vector& GetGraphInputs() { return m_socket_accessor->m_outputs; } - - void* GetOutput(const std::string& name) const; - void* GetInput(const std::string& name) const; + void* getOutput(const std::string& name) const; + void* getInput(const std::string& name) const; int getNodeEvalOrderIndex(const AnimNode* node) { for (size_t i = 0, n = m_eval_ordered_nodes.size(); i < n; i++) { @@ -715,7 +734,7 @@ struct AnimGraph { // inputs int input_block_size = 0; - std::vector& graph_inputs = result.GetGraphInputs(); + std::vector& graph_inputs = result.getGraphInputs(); for (int i = 0; i < graph_inputs.size(); i++) { input_block_size += sizeof(void*); } @@ -733,7 +752,7 @@ struct AnimGraph { // outputs int output_block_size = 0; - std::vector& graph_outputs = result.GetGraphOutputs(); + std::vector& graph_outputs = result.getGraphOutputs(); for (int i = 0; i < graph_outputs.size(); i++) { output_block_size += graph_outputs[i].m_type_size; } @@ -846,13 +865,13 @@ struct AnimGraph { } } - result.UpdateOrderedNodes(); - result.Reset(); + result.updateOrderedNodes(); + result.reset(); return result; } }; -} // namespace AnimGraphCode +} // namespace AniGraph #endif //ANIMTESTBED_ANIMGRAPHRESOURCE_H diff --git a/tests/AnimGraphResourceTests.cc b/tests/AnimGraphResourceTests.cc index 87ac201..9ea8003 100644 --- a/tests/AnimGraphResourceTests.cc +++ b/tests/AnimGraphResourceTests.cc @@ -5,7 +5,7 @@ #include "AnimGraphResource.h" #include "catch.hpp" -using namespace AnimGraphCode; +using namespace AniGraph; TEST_CASE("BasicGraph", "[AnimGraphResource]") { AnimGraphResource graph_resource; @@ -87,7 +87,7 @@ TEST_CASE("BasicGraph", "[AnimGraphResource]") { CHECK(graph.m_socket_accessor->FindInputSocket("GraphOutput")); CHECK( reinterpret_cast(blend2_instance->m_output) - == graph.GetOutput("GraphOutput")); + == graph.getOutput("GraphOutput")); // check node input dependencies size_t anim_sampler_index0 = anim_sampler_instance0->m_index; @@ -194,14 +194,14 @@ TEST_CASE("ResourceSaveLoadGraphInputs", "[AnimGraphResource]") { AnimGraph anim_graph = AnimGraph::createFromResource(graph_resource_loaded); REQUIRE( - anim_graph.GetOutput("GraphOutput") == anim_graph.m_output_buffer); + anim_graph.getOutput("GraphOutput") == anim_graph.m_output_buffer); REQUIRE( - anim_graph.GetOutput("SomeFloatOutput") + anim_graph.getOutput("SomeFloatOutput") == anim_graph.m_output_buffer + sizeof(AnimData)); - REQUIRE(anim_graph.GetInput("GraphAnimInput") == nullptr); - REQUIRE(anim_graph.GetInput("GraphFloatInput") == nullptr); - REQUIRE(anim_graph.GetInput("GraphBoolInput") == nullptr); + REQUIRE(anim_graph.getInput("GraphAnimInput") == nullptr); + REQUIRE(anim_graph.getInput("GraphFloatInput") == nullptr); + REQUIRE(anim_graph.getInput("GraphBoolInput") == nullptr); } } @@ -217,15 +217,15 @@ TEST_CASE("ResourceSaveLoadGraphInputs", "[AnimGraphResource]") { AnimGraph anim_graph = AnimGraph::createFromResource(graph_resource_origin); - void* graph_anim_input_ptr = anim_graph.GetInput("GraphAnimInput"); - void* graph_output_ptr = anim_graph.GetOutput("GraphOutput"); + void* graph_anim_input_ptr = anim_graph.getInput("GraphAnimInput"); + void* graph_output_ptr = anim_graph.getOutput("GraphOutput"); REQUIRE(graph_anim_input_ptr == graph_output_ptr); REQUIRE(graph_output_ptr == anim_graph.m_output_buffer); REQUIRE( - anim_graph.GetInput("GraphAnimInput") - == anim_graph.GetOutput("GraphOutput")); + anim_graph.getInput("GraphAnimInput") + == anim_graph.getOutput("GraphOutput")); } } @@ -267,12 +267,12 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") { AnimGraph anim_graph = AnimGraph::createFromResource(graph_resource); THEN("Writing to the input pointer changes the value of the output.") { - float* float_input_ptr = (float*)anim_graph.GetInput("GraphFloatInput"); + float* float_input_ptr = (float*)anim_graph.getInput("GraphFloatInput"); REQUIRE(float_input_ptr != nullptr); *float_input_ptr = 23.123f; float* float_output_ptr = - (float*)anim_graph.GetOutput("GraphFloatOutput"); + (float*)anim_graph.getOutput("GraphFloatOutput"); REQUIRE(float_output_ptr != nullptr); CHECK(*float_output_ptr == Approx(23.123f)); } @@ -298,7 +298,7 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") { REQUIRE( *anim_graph.m_socket_accessor->m_outputs[0].m_value.ptr_ptr == &blend2_node->m_blend_weight); - float* float_input_ptr = (float*)anim_graph.GetInput("GraphFloatInput"); + float* float_input_ptr = (float*)anim_graph.getInput("GraphFloatInput"); REQUIRE(float_input_ptr == &blend2_node->m_blend_weight); } @@ -331,21 +331,21 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") { dynamic_cast(anim_graph.m_nodes[blend2_node_index]); AnimData* graph_input0 = - (AnimData*)anim_graph.GetInput("GraphAnimInput0"); + (AnimData*)anim_graph.getInput("GraphAnimInput0"); REQUIRE(graph_input0 == &blend2_node->m_input0); REQUIRE( anim_graph.m_nodes[1] == anim_graph.getAnimNodeForInput(blend2_node_index, "Input0")); AnimData* graph_input1 = - (AnimData*)anim_graph.GetInput("GraphAnimInput1"); + (AnimData*)anim_graph.getInput("GraphAnimInput1"); REQUIRE(graph_input1 == &blend2_node->m_input1); REQUIRE( anim_graph.m_nodes[1] == anim_graph.getAnimNodeForInput(blend2_node_index, "Input1")); AnimData* graph_output = - (AnimData*)anim_graph.GetOutput("GraphAnimOutput"); + (AnimData*)anim_graph.getOutput("GraphAnimOutput"); REQUIRE(graph_output == blend2_node->m_output); REQUIRE( anim_graph.m_nodes[blend2_node_index] @@ -418,14 +418,14 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") { // check connectivity // AnimData* graph_input0 = - (AnimData*)anim_graph.GetInput("GraphAnimInput0"); + (AnimData*)anim_graph.getInput("GraphAnimInput0"); REQUIRE(graph_input0 == &blend2_node->m_input0); REQUIRE( anim_graph.m_nodes[1] == anim_graph.getAnimNodeForInput(blend2_node_index, "Input0")); AnimData* graph_input1 = - (AnimData*)anim_graph.GetInput("GraphAnimInput1"); + (AnimData*)anim_graph.getInput("GraphAnimInput1"); REQUIRE(graph_input1 == nullptr); REQUIRE(sampler_node->m_output == &speed_scale_node->m_input); @@ -439,7 +439,7 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") { == anim_graph.getAnimNodeForInput(blend2_node_index, "Input1")); AnimData* graph_output = - (AnimData*)anim_graph.GetOutput("GraphAnimOutput"); + (AnimData*)anim_graph.getOutput("GraphAnimOutput"); REQUIRE(graph_output == blend2_node->m_output); REQUIRE( anim_graph.m_nodes[blend2_node_index] @@ -462,7 +462,7 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") { WHEN("Instantiating graph") { AnimGraph anim_graph = AnimGraph::createFromResource(graph_resource); float* blend_weight_input = - reinterpret_cast(anim_graph.GetInput("GraphFloatInput")); + reinterpret_cast(anim_graph.getInput("GraphFloatInput")); Blend2Node* blend2_node = dynamic_cast(anim_graph.m_nodes[blend2_node_index]); @@ -473,43 +473,43 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") { WHEN("Setting weight to 0. and marking nodes active.") { *blend_weight_input = 0.; - anim_graph.MarkActiveNodes(); + anim_graph.markActiveNodes(); THEN("Speed scale and sampler node are inactive") { - REQUIRE(anim_graph.CheckIsNodeActive(speed_scale_node) == false); - REQUIRE(anim_graph.CheckIsNodeActive(sampler_node) == false); + REQUIRE(anim_graph.checkIsNodeActive(speed_scale_node) == false); + REQUIRE(anim_graph.checkIsNodeActive(sampler_node) == false); } } WHEN("Setting weight to 0. and marking nodes active") { *blend_weight_input = 0.1; - anim_graph.MarkActiveNodes(); + anim_graph.markActiveNodes(); THEN("Speed scale and sampler nodes are active") { - REQUIRE(anim_graph.CheckIsNodeActive(speed_scale_node) == true); - REQUIRE(anim_graph.CheckIsNodeActive(sampler_node) == true); + REQUIRE(anim_graph.checkIsNodeActive(speed_scale_node) == true); + REQUIRE(anim_graph.checkIsNodeActive(sampler_node) == true); } } WHEN("Setting weight to 1. and marking nodes active") { *blend_weight_input = 1.0; - anim_graph.MarkActiveNodes(); + anim_graph.markActiveNodes(); THEN("Speed scale and sampler nodes are active") { - REQUIRE(anim_graph.CheckIsNodeActive(speed_scale_node) == true); - REQUIRE(anim_graph.CheckIsNodeActive(sampler_node) == true); + REQUIRE(anim_graph.checkIsNodeActive(speed_scale_node) == true); + REQUIRE(anim_graph.checkIsNodeActive(sampler_node) == true); } } WHEN("Updating time with dt = 0.3f and speed scale = 1.0f") { float* speed_scale_input = - reinterpret_cast(anim_graph.GetInput("SpeedScaleInput")); + reinterpret_cast(anim_graph.getInput("SpeedScaleInput")); *blend_weight_input = 0.1; *speed_scale_input = 1.0f; - anim_graph.MarkActiveNodes(); - anim_graph.UpdateTime(0.3f); + anim_graph.markActiveNodes(); + anim_graph.updateTime(0.3f); THEN ("Anim sampler node time now must be 0.3f") { REQUIRE(sampler_node->m_time_now == Approx(0.3f)); @@ -518,13 +518,13 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") { WHEN("Updating time with dt = 0.3f and speed scale = 1.3f") { float* speed_scale_input = - reinterpret_cast(anim_graph.GetInput("SpeedScaleInput")); + reinterpret_cast(anim_graph.getInput("SpeedScaleInput")); *blend_weight_input = 0.1; *speed_scale_input = 1.3f; - anim_graph.MarkActiveNodes(); - anim_graph.UpdateTime(0.3f); + anim_graph.markActiveNodes(); + anim_graph.updateTime(0.3f); THEN ("Anim sampler node time now must be 0.39f") { REQUIRE(sampler_node->m_time_now == Approx(0.39f));