Extremely basic blend tree editing.
This commit is contained in:
		
							parent
							
								
									3fb2995b02
								
							
						
					
					
						commit
						5e34aaf3db
					
				@ -124,6 +124,7 @@ set(ozz_offline_test_objs
 | 
			
		||||
 | 
			
		||||
target_sources(runtests PRIVATE
 | 
			
		||||
        tests/AnimGraphResourceTests.cc
 | 
			
		||||
        tests/AnimGraphEditorTests.cc
 | 
			
		||||
        # tests/AnimGraphEvalTests.cc
 | 
			
		||||
        tests/NodeDescriptorTests.cc
 | 
			
		||||
        tests/SyncTrackTests.cc
 | 
			
		||||
 | 
			
		||||
@ -37,14 +37,6 @@ ImNodesPinShape sGetSocketShapeFromSocketType(const SocketType& socket_type) {
 | 
			
		||||
  return ImNodesPinShape_Quad;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int GetNodeInputSocketId(int node_index, int input_socket_index) {
 | 
			
		||||
  return node_index * 1000 + input_socket_index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int GetNodeOutputSocketId(int node_index, int output_socket_index) {
 | 
			
		||||
  return node_index * 1000 + 100 + output_socket_index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NodeSocketEditor(Socket& socket) {
 | 
			
		||||
  int mode_current = static_cast<int>(socket.m_type);
 | 
			
		||||
  ImGui::InputText("Name", &socket.m_name);
 | 
			
		||||
@ -61,20 +53,18 @@ void RemoveBlendTreeConnectionsForSocket(
 | 
			
		||||
    BlendTreeResource& blend_tree_resource,
 | 
			
		||||
    AnimNodeResource* node_resource,
 | 
			
		||||
    Socket& socket) {
 | 
			
		||||
  std::vector<BlendTreeConnectionResource>::const_iterator iter =
 | 
			
		||||
      blend_tree_resource.GetConnections().begin();
 | 
			
		||||
  const BlendTreeConnectionResource* connection =
 | 
			
		||||
      blend_tree_resource.FindConnectionForSocket(node_resource, socket.m_name);
 | 
			
		||||
  while (connection != nullptr) {
 | 
			
		||||
    blend_tree_resource.DisconnectSockets(
 | 
			
		||||
        blend_tree_resource.GetNode(connection->source_node_index),
 | 
			
		||||
        connection->source_socket_name,
 | 
			
		||||
        blend_tree_resource.GetNode(connection->target_node_index),
 | 
			
		||||
        connection->target_socket_name);
 | 
			
		||||
 | 
			
		||||
  while (iter != blend_tree_resource.GetConnections().end()) {
 | 
			
		||||
    // TODO adjust for refactor
 | 
			
		||||
    assert(false);
 | 
			
		||||
 | 
			
		||||
    //    AnimGraphConnectionResource& connection = *iter;
 | 
			
		||||
    //    if (connection.m_source_node == &node_resource
 | 
			
		||||
    //        && connection.m_source_socket == &socket) {
 | 
			
		||||
    //      iter = sGraphGresource.m_connections.erase(iter);
 | 
			
		||||
    //    } else {
 | 
			
		||||
    //      iter++;
 | 
			
		||||
    //    }
 | 
			
		||||
    connection = blend_tree_resource.FindConnectionForSocket(
 | 
			
		||||
        node_resource,
 | 
			
		||||
        socket.m_name);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -260,6 +250,12 @@ void AnimGraphEditorRenderSidebar(
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AnimGraphEditorClear() {
 | 
			
		||||
  sGraphGresource.Clear();
 | 
			
		||||
  sGraphGresource.m_blend_tree_resource.InitGraphConnectors();
 | 
			
		||||
  sGraphGresource.m_graph_type_name = "BlendTree";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
 | 
			
		||||
  ImGui::BeginMenuBar();
 | 
			
		||||
  if (ImGui::Button("Save")) {
 | 
			
		||||
@ -268,16 +264,9 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
 | 
			
		||||
  if (ImGui::Button("Load")) {
 | 
			
		||||
    sGraphGresource.LoadFromFile("editor_graph.json");
 | 
			
		||||
    sGraphLoadedThisFrame = true;
 | 
			
		||||
 | 
			
		||||
    //    for (size_t i = 0, n = sGraphGresource.m_nodes.size(); i < n; i++) {
 | 
			
		||||
    //      const AnimNodeResource& node_resource = sGraphGresource.m_nodes[i];
 | 
			
		||||
    //      ImNodes::SetNodeGridSpacePos(
 | 
			
		||||
    //          i,
 | 
			
		||||
    //          ImVec2(node_resource.m_position[0], node_resource.m_position[1]));
 | 
			
		||||
    //    }
 | 
			
		||||
  }
 | 
			
		||||
  if (ImGui::Button("Clear")) {
 | 
			
		||||
    sGraphGresource.Clear();
 | 
			
		||||
    AnimGraphEditorClear();
 | 
			
		||||
  }
 | 
			
		||||
  char graph_name_buffer[256];
 | 
			
		||||
  memset(graph_name_buffer, 0, sizeof(graph_name_buffer));
 | 
			
		||||
@ -323,7 +312,9 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
 | 
			
		||||
    for (size_t j = 0, ni = node_inputs.size(); j < ni; j++) {
 | 
			
		||||
      Socket& socket = node_inputs[j];
 | 
			
		||||
      ax::NodeEditor::BeginPin(
 | 
			
		||||
          GetNodeInputSocketId(static_cast<int>(node_id), static_cast<int>(j)),
 | 
			
		||||
          NodeIndexAndSocketIndexToInputPinId(
 | 
			
		||||
              static_cast<int>(node_id),
 | 
			
		||||
              static_cast<int>(j)),
 | 
			
		||||
          ax::NodeEditor::PinKind::Input);
 | 
			
		||||
      ImGui::Text("%s", socket.m_name.c_str());
 | 
			
		||||
      ax::NodeEditor::EndPin();
 | 
			
		||||
@ -335,13 +326,19 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
 | 
			
		||||
    for (size_t j = 0, ni = node_outputs.size(); j < ni; j++) {
 | 
			
		||||
      Socket& socket = node_outputs[j];
 | 
			
		||||
      ax::NodeEditor::BeginPin(
 | 
			
		||||
          GetNodeOutputSocketId(static_cast<int>(node_id), static_cast<int>(j)),
 | 
			
		||||
          NodeIndexAndSocketIndexToOutputPinId(
 | 
			
		||||
              static_cast<int>(node_id),
 | 
			
		||||
              static_cast<int>(j)),
 | 
			
		||||
          ax::NodeEditor::PinKind::Output);
 | 
			
		||||
      ImGui::Text("%s", socket.m_name.c_str());
 | 
			
		||||
      ax::NodeEditor::EndPin();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ax::NodeEditor::EndNode();
 | 
			
		||||
 | 
			
		||||
    ImVec2 node_position = ax::NodeEditor::GetNodePosition(node_id);
 | 
			
		||||
    node_resource->m_position[0] = node_position.x;
 | 
			
		||||
    node_resource->m_position[1] = node_position.y;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int link_id = 0;
 | 
			
		||||
@ -366,14 +363,14 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
 | 
			
		||||
        target_node_resource->m_socket_accessor->GetInputIndex(
 | 
			
		||||
            connection_resource->target_socket_name.c_str());
 | 
			
		||||
 | 
			
		||||
    int source_socket_id = GetNodeOutputSocketId(
 | 
			
		||||
    int source_socket_pin_id = NodeIndexAndSocketIndexToOutputPinId(
 | 
			
		||||
        static_cast<int>(connection_resource->source_node_index),
 | 
			
		||||
        source_socket_index);
 | 
			
		||||
    int target_socket_id = GetNodeInputSocketId(
 | 
			
		||||
    int target_socket_pin_id = NodeIndexAndSocketIndexToInputPinId(
 | 
			
		||||
        static_cast<int>(connection_resource->target_node_index),
 | 
			
		||||
        target_socket_index);
 | 
			
		||||
 | 
			
		||||
    ax::NodeEditor::Link(link_id++, source_socket_id, target_socket_id);
 | 
			
		||||
    ax::NodeEditor::Link(link_id++, source_socket_pin_id, target_socket_pin_id);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -385,6 +382,56 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
 | 
			
		||||
    if (ax::NodeEditor::QueryNewLink(&input_pin_id, &output_pin_id)) {
 | 
			
		||||
      if (input_pin_id && output_pin_id) {
 | 
			
		||||
        if (ax::NodeEditor::AcceptNewItem()) {
 | 
			
		||||
          int source_node_index;
 | 
			
		||||
          int source_node_socket_index;
 | 
			
		||||
 | 
			
		||||
          OutputPinIdToNodeIndexAndSocketIndex(
 | 
			
		||||
              input_pin_id.Get(),
 | 
			
		||||
              &source_node_index,
 | 
			
		||||
              &source_node_socket_index);
 | 
			
		||||
 | 
			
		||||
          const AnimNodeResource* source_node =
 | 
			
		||||
              sGraphGresource.m_blend_tree_resource.GetNode(source_node_index);
 | 
			
		||||
          if (source_node->m_socket_accessor->m_outputs.size()
 | 
			
		||||
              < source_node_socket_index) {
 | 
			
		||||
            source_node_socket_index = -1;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          int target_node_index;
 | 
			
		||||
          int target_node_socket_index;
 | 
			
		||||
 | 
			
		||||
          InputPinIdToNodeIndexAndSocketIndex(
 | 
			
		||||
              output_pin_id.Get(),
 | 
			
		||||
              &target_node_index,
 | 
			
		||||
              &target_node_socket_index);
 | 
			
		||||
 | 
			
		||||
          const AnimNodeResource* target_node =
 | 
			
		||||
              sGraphGresource.m_blend_tree_resource.GetNode(target_node_index);
 | 
			
		||||
          if (target_node->m_socket_accessor->m_inputs.size()
 | 
			
		||||
              < target_node_socket_index) {
 | 
			
		||||
            target_node_socket_index = -1;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if (source_node_socket_index == -1
 | 
			
		||||
              || target_node_socket_index == -1) {
 | 
			
		||||
            ax::NodeEditor::RejectNewItem();
 | 
			
		||||
          } else {
 | 
			
		||||
            const std::string& source_socket_name =
 | 
			
		||||
                source_node->m_socket_accessor
 | 
			
		||||
                    ->m_outputs[source_node_socket_index]
 | 
			
		||||
                    .m_name;
 | 
			
		||||
 | 
			
		||||
            const std::string& target_socket_name =
 | 
			
		||||
                target_node->m_socket_accessor
 | 
			
		||||
                    ->m_inputs[target_node_socket_index]
 | 
			
		||||
                    .m_name;
 | 
			
		||||
 | 
			
		||||
            sGraphGresource.m_blend_tree_resource.ConnectSockets(
 | 
			
		||||
                source_node,
 | 
			
		||||
                source_socket_name,
 | 
			
		||||
                target_node,
 | 
			
		||||
                target_socket_name);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@ -392,6 +439,64 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
 | 
			
		||||
  ax::NodeEditor::EndCreate();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // Popup menu
 | 
			
		||||
  {
 | 
			
		||||
    const bool open_popup = ImGui::IsMouseReleased(ImGuiMouseButton_Right);
 | 
			
		||||
 | 
			
		||||
    ImVec2 popup_mouse_position = ImGui::GetMousePos();
 | 
			
		||||
 | 
			
		||||
    ax::NodeEditor::Suspend();
 | 
			
		||||
    if (open_popup) {
 | 
			
		||||
      ImGui::OpenPopup("add node");
 | 
			
		||||
    }
 | 
			
		||||
    ax::NodeEditor::Resume();
 | 
			
		||||
 | 
			
		||||
    ax::NodeEditor::Suspend();
 | 
			
		||||
    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f));
 | 
			
		||||
    if (ImGui::BeginPopup("add node")) {
 | 
			
		||||
      std::string node_type_name = "";
 | 
			
		||||
      if (ImGui::MenuItem("AnimSampler")) {
 | 
			
		||||
        node_type_name = "AnimSampler";
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (ImGui::MenuItem("Blend2")) {
 | 
			
		||||
        node_type_name = "Blend2";
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (ImGui::MenuItem("SpeedScale")) {
 | 
			
		||||
        node_type_name = "SpeedScale";
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (ImGui::MenuItem("LockTranslationNode")) {
 | 
			
		||||
        node_type_name = "LockTranslationNode";
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (ImGui::MenuItem("MathAddNode")) {
 | 
			
		||||
        node_type_name = "MathAddNode";
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (ImGui::MenuItem("MathFloatToVec3Node")) {
 | 
			
		||||
        node_type_name = "MathFloatToVec3Node";
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (ImGui::MenuItem("ConstScalarNode")) {
 | 
			
		||||
        node_type_name = "ConstScalarNode";
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (node_type_name.empty()) {
 | 
			
		||||
        AnimNodeResource* node_resource =
 | 
			
		||||
            AnimNodeResourceFactory(node_type_name);
 | 
			
		||||
        size_t node_id = sGraphGresource.m_blend_tree_resource.GetNumNodes();
 | 
			
		||||
        ax::NodeEditor::SetNodePosition(node_id, popup_mouse_position);
 | 
			
		||||
        sGraphGresource.m_blend_tree_resource.AddNode(node_resource);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      ImGui::EndPopup();
 | 
			
		||||
    }
 | 
			
		||||
    ImGui::PopStyleVar();
 | 
			
		||||
    ax::NodeEditor::Resume();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ax::NodeEditor::End();
 | 
			
		||||
 | 
			
		||||
  sGraphLoadedThisFrame = false;
 | 
			
		||||
 | 
			
		||||
@ -33,10 +33,40 @@ SplitOutputAttributeId(int attribute_id, int* node_id, int* output_index) {
 | 
			
		||||
  *output_index = (attribute_id >> 23) - 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int NodeIndexAndSocketIndexToInputPinId(
 | 
			
		||||
    int node_index,
 | 
			
		||||
    int input_socket_index) {
 | 
			
		||||
  return node_index * 1000 + input_socket_index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int NodeIndexAndSocketIndexToOutputPinId(
 | 
			
		||||
    int node_index,
 | 
			
		||||
    int output_socket_index) {
 | 
			
		||||
  return node_index * 1000 + 500 + output_socket_index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void InputPinIdToNodeIndexAndSocketIndex(
 | 
			
		||||
    unsigned long input_pin_id,
 | 
			
		||||
    int* node_index,
 | 
			
		||||
    int* socket_index) {
 | 
			
		||||
  *socket_index = input_pin_id % 1000;
 | 
			
		||||
  *node_index = (input_pin_id - *socket_index) / 1000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void OutputPinIdToNodeIndexAndSocketIndex(
 | 
			
		||||
    unsigned long output_pin_id,
 | 
			
		||||
    int* node_index,
 | 
			
		||||
    int* socket_index) {
 | 
			
		||||
  *socket_index = ((output_pin_id - 500) % 1000);
 | 
			
		||||
  *node_index = (output_pin_id - *socket_index) / 1000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SyncTrackEditor(SyncTrack* sync_track);
 | 
			
		||||
 | 
			
		||||
void SkinnedMeshWidget(SkinnedMesh* skinned_mesh);
 | 
			
		||||
 | 
			
		||||
void AnimGraphEditorClear();
 | 
			
		||||
 | 
			
		||||
void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context);
 | 
			
		||||
 | 
			
		||||
void LegacyAnimGraphEditorUpdate();
 | 
			
		||||
 | 
			
		||||
@ -323,11 +323,13 @@ static bool sAnimGraphResourceBlendTreeFromJson(
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Graph outputs
 | 
			
		||||
  const json& graph_outputs = json_data["nodes"][0]["inputs"];
 | 
			
		||||
  for (const auto& graph_output : graph_outputs) {
 | 
			
		||||
    AnimNodeResource* graph_node = blend_tree_resource.GetNode(0);
 | 
			
		||||
    graph_node->m_socket_accessor->m_inputs.push_back(
 | 
			
		||||
        sJsonToSocket(graph_output));
 | 
			
		||||
  if (json_data["nodes"][0].contains("inputs")) {
 | 
			
		||||
    const json& graph_outputs = json_data["nodes"][0]["inputs"];
 | 
			
		||||
    for (const auto& graph_output : graph_outputs) {
 | 
			
		||||
      AnimNodeResource* graph_node = blend_tree_resource.GetNode(0);
 | 
			
		||||
      graph_node->m_socket_accessor->m_inputs.push_back(
 | 
			
		||||
          sJsonToSocket(graph_output));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Graph inputs (optional)
 | 
			
		||||
@ -573,6 +575,33 @@ bool BlendTreeResource::IsConnectionValid(
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const BlendTreeConnectionResource* BlendTreeResource::FindConnectionForSocket(
 | 
			
		||||
    const AnimNodeResource* node,
 | 
			
		||||
    const std::string& socket_name) const {
 | 
			
		||||
  int node_index = GetNodeIndex(node);
 | 
			
		||||
 | 
			
		||||
  std::vector<BlendTreeConnectionResource>::const_iterator connection_iter =
 | 
			
		||||
      std::find_if(
 | 
			
		||||
          m_connections.begin(),
 | 
			
		||||
          m_connections.end(),
 | 
			
		||||
          [node_index,
 | 
			
		||||
           socket_name](const BlendTreeConnectionResource& connection) {
 | 
			
		||||
            if ((connection.source_node_index == node_index
 | 
			
		||||
                 && connection.source_socket_name == socket_name)
 | 
			
		||||
                || (connection.target_node_index == node_index
 | 
			
		||||
                    && connection.target_socket_name == socket_name)) {
 | 
			
		||||
              return true;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
  if (connection_iter != m_connections.end()) {
 | 
			
		||||
    return &*connection_iter;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BlendTreeResource::UpdateTreeTopologyInfo() {
 | 
			
		||||
  // TODO: Updating eval order and subtrees may get slow with many nodes. An
 | 
			
		||||
  // iterative approach would scale better. But let's leave that optimization
 | 
			
		||||
@ -640,6 +669,8 @@ void BlendTreeResource::UpdateNodeSubtrees() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AnimGraphResource::LoadFromFile(const char* filename) {
 | 
			
		||||
  Clear();
 | 
			
		||||
 | 
			
		||||
  std::ifstream input_file;
 | 
			
		||||
  input_file.open(filename);
 | 
			
		||||
  std::stringstream buffer;
 | 
			
		||||
 | 
			
		||||
@ -154,11 +154,16 @@ struct BlendTreeResource {
 | 
			
		||||
      const AnimNodeResource* target_node,
 | 
			
		||||
      const std::string& target_socket_name) const;
 | 
			
		||||
 | 
			
		||||
  const BlendTreeConnectionResource* FindConnectionForSocket(
 | 
			
		||||
      const AnimNodeResource* node,
 | 
			
		||||
      const std::string& socket_name) const;
 | 
			
		||||
 | 
			
		||||
  bool IsSocketConnected(
 | 
			
		||||
      const AnimNodeResource* source_node,
 | 
			
		||||
      const std::string& socket_name) {
 | 
			
		||||
    assert(false && "Not yet implemented");
 | 
			
		||||
    return false;
 | 
			
		||||
      const AnimNodeResource* node,
 | 
			
		||||
      const std::string& socket_name) const {
 | 
			
		||||
    const BlendTreeConnectionResource* connection =
 | 
			
		||||
        FindConnectionForSocket(node, socket_name);
 | 
			
		||||
    return connection != nullptr;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  std::vector<Socket*> GetConstantNodeInputs(
 | 
			
		||||
 | 
			
		||||
@ -561,6 +561,7 @@ int main() {
 | 
			
		||||
  AnimData anim_graph_output;
 | 
			
		||||
  anim_graph_output.m_local_matrices.resize(
 | 
			
		||||
      skinned_mesh.m_skeleton.num_soa_joints());
 | 
			
		||||
  AnimGraphEditorClear();
 | 
			
		||||
 | 
			
		||||
  state.time.factor = 1.0f;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										40
									
								
								tests/AnimGraphEditorTests.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								tests/AnimGraphEditorTests.cc
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,40 @@
 | 
			
		||||
#include "AnimGraph/AnimGraphEditor.h"
 | 
			
		||||
#include "catch.hpp"
 | 
			
		||||
 | 
			
		||||
TEST_CASE("Node Socket To InputPin Conversion", "[animGraphEditor]") {
 | 
			
		||||
  int node_index = 321;
 | 
			
		||||
  int socket_index = 221;
 | 
			
		||||
  long socket_id;
 | 
			
		||||
 | 
			
		||||
  socket_id = NodeIndexAndSocketIndexToInputPinId(node_index, socket_index);
 | 
			
		||||
 | 
			
		||||
  int node_index_resolved;
 | 
			
		||||
  int socket_index_resolved;
 | 
			
		||||
 | 
			
		||||
  InputPinIdToNodeIndexAndSocketIndex(
 | 
			
		||||
      socket_id,
 | 
			
		||||
      &node_index_resolved,
 | 
			
		||||
      &socket_index_resolved);
 | 
			
		||||
 | 
			
		||||
  CHECK(node_index == node_index_resolved);
 | 
			
		||||
  CHECK(socket_index == socket_index_resolved);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_CASE("Node Socket To OutputPin Conversion", "[animGraphEditor]") {
 | 
			
		||||
  int node_index = 321;
 | 
			
		||||
  int socket_index = 221;
 | 
			
		||||
  long socket_id;
 | 
			
		||||
 | 
			
		||||
  socket_id = NodeIndexAndSocketIndexToOutputPinId(node_index, socket_index);
 | 
			
		||||
 | 
			
		||||
  int node_index_resolved;
 | 
			
		||||
  int socket_index_resolved;
 | 
			
		||||
 | 
			
		||||
  OutputPinIdToNodeIndexAndSocketIndex(
 | 
			
		||||
      socket_id,
 | 
			
		||||
      &node_index_resolved,
 | 
			
		||||
      &socket_index_resolved);
 | 
			
		||||
 | 
			
		||||
  CHECK(node_index == node_index_resolved);
 | 
			
		||||
  CHECK(socket_index == socket_index_resolved);
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user