Auto Connect Nodes

From C4 Engine Wiki

Jump to: navigation, search

After reviewing some of my PhysX documentation, it dawned on me that manually adding 2 connectors for each joint - one marker connected to 2 geometry nodes - is incredibly time consuming. So cue a new menu item in the Nodes menu - Connect Nodes.

This code snippet, identifies the nodes you have selected in the World Editor, node1 is the first node, it will then look for other selected nodes and check for connectors, if there isn't one, it will create a new one or reuse an existing blank one and link it to the selected node.

So, in practice, create 2 or more nodes in the World Editor, can be Geometry or Markers, make sure at least 2 are selected and select Connect Nodes from the bottom of the nodes menu.

The Code

In WorldEditor.h

Add the following around the provided line numbers line 101

kEditorMenuAttachNodes,

line 335

static void AttachNodesProc(MenuItem *item, void *data);

In WorldEditor.cpp Add the following around the provided line numbers

Line 691

  item = new MenuItem(table->GetString(StringID('MENU', 'LAYO', 'SETT')), &EditorSettingsProc, this);
  layoutMenu->AddMenuItem(item);
 
  // Begin Updated Code
  nodeMenu->AddMenuItem(new MenuItem(""));
 
  item = new MenuItem("Connect Nodes", &AttachNodesProc, this);
  nodeMenu->AddMenuItem(item);
  editorMenuItem<kEditorMenuAttachNodes> = item;
  // End Updated Code
 
  BuildPageMenu(titleFont, menuFont);
  BuildViewportItemList();

Line 797

  editorMenuItem<kEditorMenuAlignToGrid>->Enable();
 
  // Begin Updated Code
  editorMenuItem<kEditorMenuAttachNodes>->Enable();
  // End Updated Code
 
  editorMenuItem<kEditorMenuHideSelected>->Enable();

Line 846

  editorMenuItem<kEditorMenuAttachNodes>->Disable();
}

Line 2620

// Begin Updated Code
void Editor::AttachNodesProc(MenuItem *item, void *data)
{
  Editor *editor = static_cast<Editor *>(data);
  if (!editor->trackingTool)
  {
    Node *node1 = nullptr;
    long count = 0;
 
    const NodeReference *reference = editor->GetFirstSelectedNode();
    while (reference)
    {
      Node *node = reference->GetNode();
      if (node->GetNodeType() == kNodeGeometry || node->GetNodeType() == kNodeMarker)
      {
        if (!node1)
        {
          node1 = node;
        }
        else
        {
          Connector *connector = nullptr;
          long connectorCount = node1->GetConnectorCount();
 
          for (natural i = 0; i < connectorCount; i++)
          {
            ConnectorKey key = node1->GetConnector(i)->GetConnectorKey();
 
            if (!node1->GetConnectedNode(key) || node1->GetConnectedNode(key) == node)
            {
              connector = node1->GetConnector(i);
              if (!node1->GetConnectedNode(key)) node1->SetConnectedNode(connector->GetConnectorKey(), node);
              break;
            }
          }
 
          if (!connector && count < 10)
          {
            ResourceName name = "con";
            name += Text::IntegerToString(count);
            ConnectorKey key = Text::StringToType(name);
            node1->AddConnector(key, kTypeWildcard, node);
            count++;
          }
        }
      }
 
      reference = reference->Next();
    }
 
    node1->Invalidate();
    node1->Preprocess();
  }
}
// End Updated Code
 
void Editor::ShowAllProc(MenuItem *item, void *data)
Personal tools