diff --git a/Source/Editor/Surface/Archetypes/Tools.cs b/Source/Editor/Surface/Archetypes/Tools.cs
index 2b63bdfb2..e5513b598 100644
--- a/Source/Editor/Surface/Archetypes/Tools.cs
+++ b/Source/Editor/Surface/Archetypes/Tools.cs
@@ -983,6 +983,103 @@ namespace FlaxEditor.Surface.Archetypes
}
}
+ private class RerouteNode : SurfaceNode
+ {
+ public static readonly Vector2 DefaultSize = new Vector2(16);
+
+ ///
+ protected override bool ShowTooltip => false;
+
+ ///
+ public RerouteNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch)
+ : base(id, context, nodeArch, groupArch)
+ {
+ Size = DefaultSize;
+ Title = string.Empty;
+ BackgroundColor = Color.Transparent;
+ }
+
+ ///
+ public override void OnSurfaceLoaded()
+ {
+ base.OnSurfaceLoaded();
+
+ var inputBox = GetBox(0);
+ var outputBox = GetBox(1);
+ inputBox.Location = Vector2.Zero;
+ outputBox.Location = Vector2.Zero;
+
+ UpdateBoxes();
+ }
+
+ ///
+ public override void ConnectionTick(Box box)
+ {
+ base.ConnectionTick(box);
+
+ UpdateBoxes();
+ }
+
+ private void UpdateBoxes()
+ {
+ var inputBox = GetBox(0);
+ var outputBox = GetBox(1);
+
+ inputBox.Visible = !inputBox.HasAnyConnection;
+ outputBox.Visible = !outputBox.HasAnyConnection;
+ }
+
+ ///
+ public override bool CanSelect(ref Vector2 location)
+ {
+ return new Rectangle(Location, DefaultSize).Contains(ref location);
+ }
+
+ ///
+ protected override void UpdateRectangles()
+ {
+ _headerRect = Rectangle.Empty;
+ _closeButtonRect = Rectangle.Empty;
+ _footerRect = Rectangle.Empty;
+ }
+
+ public override void Draw()
+ {
+ var style = Surface.Style;
+ var inputBox = GetBox(0);
+ var outputBox = GetBox(1);
+ var connectionColor = style.Colors.Default;
+ float barHorizontalOffset = -2;
+ float barHeight = 3;
+
+ if (inputBox.HasAnyConnection)
+ {
+ var hints = inputBox.Connections[0].ParentNode.Archetype.ConnectionsHints;
+ Surface.Style.GetConnectionColor(inputBox.Connections[0].CurrentType, hints, out connectionColor);
+ }
+
+ if (!inputBox.HasAnyConnection)
+ {
+ Render2D.FillRectangle(new Rectangle(-barHorizontalOffset - barHeight * 2, (DefaultSize.Y - barHeight) / 2, barHeight * 2, barHeight), connectionColor);
+ }
+
+ if (!outputBox.HasAnyConnection)
+ {
+ Render2D.FillRectangle(new Rectangle(DefaultSize.X + barHorizontalOffset, (DefaultSize.Y - barHeight) / 2, barHeight * 2, barHeight), connectionColor);
+ }
+
+ if (inputBox.HasAnyConnection && outputBox.HasAnyConnection)
+ {
+ var hints = inputBox.Connections[0].ParentNode.Archetype.ConnectionsHints;
+ Surface.Style.GetConnectionColor(inputBox.Connections[0].CurrentType, hints, out connectionColor);
+ SpriteHandle icon = style.Icons.BoxClose;
+ Render2D.DrawSprite(icon, new Rectangle(Vector2.Zero, DefaultSize), connectionColor);
+ }
+
+ base.Draw();
+ }
+ }
+
///
/// The nodes for that group.
///
@@ -1438,6 +1535,23 @@ namespace FlaxEditor.Surface.Archetypes
NodeElementArchetype.Factory.Input(0, string.Empty, true, typeof(object), 1),
}
},
+ new NodeArchetype
+ {
+ TypeID = 29,
+ Title = "Reroute",
+ Create = (id, context, arch, groupArch) => new RerouteNode(id, context, arch, groupArch),
+ Description = "Reroute a connection.",
+ Flags = NodeFlags.NoCloseButton | NodeFlags.NoSpawnViaGUI | NodeFlags.AllGraphs,
+ Size = RerouteNode.DefaultSize,
+ ConnectionsHints = ConnectionsHint.All,
+ IndependentBoxes = new int[] { 0 },
+ DependentBoxes = new int[] { 1 },
+ Elements = new[]
+ {
+ NodeElementArchetype.Factory.Input(0, string.Empty, true, null, 0),
+ NodeElementArchetype.Factory.Output(0, string.Empty, null, 1, true),
+ }
+ },
};
}
}
diff --git a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs
index 015b9213d..9690d5fd3 100644
--- a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs
+++ b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs
@@ -159,6 +159,7 @@ namespace FlaxEditor.Surface.ContextMenu
var start = font.GetCharPosition(_archetype.Title, 0);
var end = font.GetCharPosition(_archetype.Title, _archetype.Title.Length - 1);
_highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height));
+ _isFullMatch = true;
Visible = true;
}
else if (NodeArchetype.TryParseText != null && NodeArchetype.TryParseText(filterText, out var data))
diff --git a/Source/Editor/Surface/Elements/OutputBox.cs b/Source/Editor/Surface/Elements/OutputBox.cs
index 0c3ba8da4..16094d621 100644
--- a/Source/Editor/Surface/Elements/OutputBox.cs
+++ b/Source/Editor/Surface/Elements/OutputBox.cs
@@ -2,6 +2,7 @@
using FlaxEngine;
using FlaxEngine.GUI;
+using System;
namespace FlaxEditor.Surface.Elements
{
@@ -12,6 +13,11 @@ namespace FlaxEditor.Surface.Elements
[HideInEditor]
public class OutputBox : Box
{
+ ///
+ /// Distance for the mouse to be considered above the connection
+ ///
+ public float MouseOverConnectionDistance => 100f / Surface.ViewScale;
+
///
public OutputBox(SurfaceNode parentNode, NodeElementArchetype archetype)
: base(parentNode, archetype, archetype.Position + new Vector2(parentNode.Archetype.Size.X, 0))
@@ -43,23 +49,96 @@ namespace FlaxEditor.Surface.Elements
*/
}
+ ///
+ /// Checks if a point intersects a connection
+ ///
+ /// The other box.
+ /// The mouse position
+ public bool IntersectsConnection(Box targetBox, ref Vector2 mousePosition)
+ {
+ var startPos = Parent.PointToParent(Center);
+ Vector2 endPos = targetBox.Parent.PointToParent(targetBox.Center);
+ return IntersectsConnection(ref startPos, ref endPos, ref mousePosition, MouseOverConnectionDistance);
+ }
+
+ ///
+ /// Checks if a point intersects a bezier curve
+ ///
+ /// The start location.
+ /// The end location.
+ /// The point
+ /// Distance at which its an intersection
+ public static bool IntersectsConnection(ref Vector2 start, ref Vector2 end, ref Vector2 point, float distance)
+ {
+ // Pretty much a point in rectangle check
+ if ((point.X - start.X) * (end.X - point.X) < 0) return false;
+
+ float offset = Mathf.Sign(end.Y - start.Y) * distance;
+ if ((point.Y - (start.Y - offset)) * ((end.Y + offset) - point.Y) < 0) return false;
+
+ // Taken from the Render2D.DrawBezier code
+ float squaredDistance = distance;
+
+ var dst = (end - start) * new Vector2(0.5f, 0.05f);
+ Vector2 control1 = new Vector2(start.X + dst.X, start.Y + dst.Y);
+ Vector2 control2 = new Vector2(end.X - dst.X, end.Y + dst.Y);
+
+ Vector2 d1 = control1 - start;
+ Vector2 d2 = control2 - control1;
+ Vector2 d3 = end - control2;
+ float len = d1.Length + d2.Length + d3.Length;
+ int segmentCount = Math.Min(Math.Max(Mathf.CeilToInt(len * 0.05f), 1), 100);
+ float segmentCountInv = 1.0f / segmentCount;
+
+ Bezier(ref start, ref control1, ref control2, ref end, 0, out Vector2 p);
+ for (int i = 1; i <= segmentCount; i++)
+ {
+ Vector2 oldp = p;
+ float t = i * segmentCountInv;
+ Bezier(ref start, ref control1, ref control2, ref end, t, out p);
+
+ // Maybe it would be reasonable to return the point?
+ CollisionsHelper.ClosestPointPointLine(ref point, ref oldp, ref p, out Vector2 result);
+ if (Vector2.DistanceSquared(point, result) <= squaredDistance)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static void Bezier(ref Vector2 p0, ref Vector2 p1, ref Vector2 p2, ref Vector2 p3, float alpha, out Vector2 result)
+ {
+ Vector2.Lerp(ref p0, ref p1, alpha, out var p01);
+ Vector2.Lerp(ref p1, ref p2, alpha, out var p12);
+ Vector2.Lerp(ref p2, ref p3, alpha, out var p23);
+ Vector2.Lerp(ref p01, ref p12, alpha, out var p012);
+ Vector2.Lerp(ref p12, ref p23, alpha, out var p123);
+ Vector2.Lerp(ref p012, ref p123, alpha, out result);
+ }
+
///
/// Draw all connections coming from this box.
///
- public void DrawConnections()
+ public void DrawConnections(ref Vector2 mousePosition)
{
+ float mouseOverDistance = MouseOverConnectionDistance;
// Draw all the connections
- var center = Size * 0.5f;
- var tmp = PointToParent(ref center);
- var startPos = Parent.PointToParent(ref tmp);
+ var startPos = Parent.PointToParent(Center);
var startHighlight = ConnectionsHighlightIntensity;
for (int i = 0; i < Connections.Count; i++)
{
Box targetBox = Connections[i];
- tmp = targetBox.PointToParent(ref center);
- Vector2 endPos = targetBox.Parent.PointToParent(ref tmp);
+ Vector2 endPos = targetBox.Parent.PointToParent(targetBox.Center);
var highlight = 1 + Mathf.Max(startHighlight, targetBox.ConnectionsHighlightIntensity);
var color = _currentTypeColor * highlight;
+
+ // TODO: Figure out how to only draw the topmost connection
+ if (IntersectsConnection(ref startPos, ref endPos, ref mousePosition, mouseOverDistance))
+ {
+ highlight += 0.5f;
+ }
+
DrawConnection(ref startPos, ref endPos, ref color, highlight);
}
}
@@ -70,12 +149,9 @@ namespace FlaxEditor.Surface.Elements
public void DrawSelectedConnection(Box targetBox)
{
// Draw all the connections
- var center = Size * 0.5f;
- var tmp = PointToParent(ref center);
- var startPos = Parent.PointToParent(ref tmp);
- tmp = targetBox.PointToParent(ref center);
- Vector2 endPos = targetBox.Parent.PointToParent(ref tmp);
- DrawConnection(ref startPos, ref endPos, ref _currentTypeColor, 2);
+ var startPos = Parent.PointToParent(Center);
+ Vector2 endPos = targetBox.Parent.PointToParent(targetBox.Center);
+ DrawConnection(ref startPos, ref endPos, ref _currentTypeColor, 2.5f);
}
///
diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs
index 9ace32695..ff1d376e7 100644
--- a/Source/Editor/Surface/SurfaceNode.cs
+++ b/Source/Editor/Surface/SurfaceNode.cs
@@ -125,6 +125,7 @@ namespace FlaxEditor.Surface
AutoFocus = false;
TooltipText = nodeArch.Description;
CullChildren = false;
+ BackgroundColor = Style.Current.BackgroundNormal;
if (Archetype.DefaultValues != null)
{
@@ -552,19 +553,22 @@ namespace FlaxEditor.Surface
internal Box GetNextBox(Box box)
{
- int i = 0;
- for (; i < Elements.Count; i++)
+ // Get the one after it
+ for (int i = box.IndexInParent + 1; i < Elements.Count; i++)
{
- if (Elements[i] == box)
+ if (Elements[i] is Box b)
{
- // We found the box
- break;
+ return b;
}
}
- // Get the one after it
- i++;
- for (; i < Elements.Count; i++)
+ return null;
+ }
+
+ internal Box GetPreviousBox(Box box)
+ {
+ // Get the one before it
+ for (int i = box.IndexInParent - 1; i >= 0; i--)
{
if (Elements[i] is Box b)
{
@@ -754,29 +758,33 @@ namespace FlaxEditor.Surface
{
if (Elements[j] is OutputBox ob && ob.HasAnyConnection)
{
- ob.DrawConnections();
+ ob.DrawConnections(ref mousePosition);
}
}
+ }
+
+ ///
+ /// Draws all selected connections between surface objects related to this node.
+ ///
+ /// The index of the currently selected connection.
+ public void DrawSelectedConnections(int selectedConnectionIndex)
+ {
if (_isSelected)
{
- bool hasBoxesSelection = HasBoxesSelection;
- for (int j = 0; j < Elements.Count; j++)
+ if (HasBoxesSelection)
{
- if (Elements[j] is Box box && box.HasAnyConnection && (!hasBoxesSelection || box.IsSelected))
+ for (int j = 0; j < Elements.Count; j++)
{
- if (box is OutputBox ob)
+ if (Elements[j] is Box box && box.IsSelected && selectedConnectionIndex < box.Connections.Count)
{
- for (int i = 0; i < ob.Connections.Count; i++)
+ if (box is OutputBox ob)
{
- ob.DrawSelectedConnection(ob.Connections[i]);
+ ob.DrawSelectedConnection(ob.Connections[selectedConnectionIndex]);
}
- }
- else
- {
- for (int i = 0; i < box.Connections.Count; i++)
+ else
{
- if (box.Connections[i] is OutputBox outputBox)
+ if (box.Connections[selectedConnectionIndex] is OutputBox outputBox)
{
outputBox.DrawSelectedConnection(box);
}
@@ -784,6 +792,32 @@ namespace FlaxEditor.Surface
}
}
}
+ else
+ {
+ for (int j = 0; j < Elements.Count; j++)
+ {
+ if (Elements[j] is Box box)
+ {
+ if (box is OutputBox ob)
+ {
+ for (int i = 0; i < ob.Connections.Count; i++)
+ {
+ ob.DrawSelectedConnection(ob.Connections[i]);
+ }
+ }
+ else
+ {
+ for (int i = 0; i < box.Connections.Count; i++)
+ {
+ if (box.Connections[i] is OutputBox outputBox)
+ {
+ outputBox.DrawSelectedConnection(box);
+ }
+ }
+ }
+ }
+ }
+ }
}
}
@@ -943,7 +977,7 @@ namespace FlaxEditor.Surface
// Background
var backgroundRect = new Rectangle(Vector2.Zero, Size);
- Render2D.FillRectangle(backgroundRect, style.BackgroundNormal);
+ Render2D.FillRectangle(backgroundRect, BackgroundColor);
// Breakpoint hit
if (Breakpoint.Hit)
@@ -1006,7 +1040,7 @@ namespace FlaxEditor.Surface
}
// Secondary Context Menu
- if (button == MouseButton.Right && false)
+ if (button == MouseButton.Right)
{
if (!IsSelected)
Surface.Select(this);
diff --git a/Source/Editor/Surface/Undo/BoxHandle.cs b/Source/Editor/Surface/Undo/BoxHandle.cs
index f50adcfeb..4b77b95f7 100644
--- a/Source/Editor/Surface/Undo/BoxHandle.cs
+++ b/Source/Editor/Surface/Undo/BoxHandle.cs
@@ -10,7 +10,7 @@ namespace FlaxEditor.Surface.Undo
/// The helper structure for Surface node box handle.
///
[HideInEditor]
- public struct BoxHandle
+ public struct BoxHandle : IEquatable
{
private readonly uint _nodeId;
private readonly int _boxId;
@@ -51,5 +51,27 @@ namespace FlaxEditor.Surface.Undo
throw new Exception("Missing box.");
return box;
}
+
+ ///
+ public override bool Equals(object obj)
+ {
+ return obj is BoxHandle handle && Equals(handle);
+ }
+
+ ///
+ public bool Equals(BoxHandle other)
+ {
+ return _nodeId == other._nodeId &&
+ _boxId == other._boxId;
+ }
+
+ ///
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return (_nodeId.GetHashCode() * 397) ^ _boxId.GetHashCode();
+ }
+ }
}
}
diff --git a/Source/Editor/Surface/Undo/ConnectBoxesAction.cs b/Source/Editor/Surface/Undo/ConnectBoxesAction.cs
index c200f147d..cfd0e5c33 100644
--- a/Source/Editor/Surface/Undo/ConnectBoxesAction.cs
+++ b/Source/Editor/Surface/Undo/ConnectBoxesAction.cs
@@ -106,9 +106,12 @@ namespace FlaxEditor.Surface.Undo
}
for (int i = 0; i < output.Length; i++)
{
- var box = output[i].Get(context);
- oB.Connections.Add(box);
- box.Connections.Add(oB);
+ if (!output[i].Equals(_input))
+ {
+ var box = output[i].Get(context);
+ oB.Connections.Add(box);
+ box.Connections.Add(oB);
+ }
}
toUpdate.AddRange(iB.Connections);
diff --git a/Source/Editor/Surface/VisjectSurface.CopyPaste.cs b/Source/Editor/Surface/VisjectSurface.CopyPaste.cs
index 0d991191a..2fbdb815c 100644
--- a/Source/Editor/Surface/VisjectSurface.CopyPaste.cs
+++ b/Source/Editor/Surface/VisjectSurface.CopyPaste.cs
@@ -103,7 +103,7 @@ namespace FlaxEditor.Surface
{
for (int j = 0; j < node.Elements.Count; j++)
{
- if (node.Elements[j] is Box box)
+ if (node.Elements[j] is Box box && box.Connections.Count > 0)
{
var dataModelBox = new DataModelBox
{
diff --git a/Source/Editor/Surface/VisjectSurface.Draw.cs b/Source/Editor/Surface/VisjectSurface.Draw.cs
index 488324a0a..016e0083f 100644
--- a/Source/Editor/Surface/VisjectSurface.Draw.cs
+++ b/Source/Editor/Surface/VisjectSurface.Draw.cs
@@ -103,6 +103,7 @@ namespace FlaxEditor.Surface
for (int i = 0; i < Nodes.Count; i++)
{
Nodes[i].DrawConnections(ref mousePosition);
+ Nodes[i].DrawSelectedConnections(_selectedConnectionIndex);
}
}
diff --git a/Source/Editor/Surface/VisjectSurface.Input.cs b/Source/Editor/Surface/VisjectSurface.Input.cs
index dec89e143..996f9d2e0 100644
--- a/Source/Editor/Surface/VisjectSurface.Input.cs
+++ b/Source/Editor/Surface/VisjectSurface.Input.cs
@@ -274,12 +274,47 @@ namespace FlaxEditor.Surface
bool handled = base.OnMouseDoubleClick(location, button);
if (!handled)
CustomMouseDoubleClick?.Invoke(ref location, button, ref handled);
- if (handled)
+
+ if (!handled)
{
- return true;
+ var mousePos = _rootControl.PointFromParent(ref _mousePos);
+ if (IntersectsConnection(mousePos, out InputBox inputBox, out OutputBox outputBox))
+ {
+ if (Undo != null)
+ {
+ bool undoEnabled = Undo.Enabled;
+ Undo.Enabled = false;
+ var rerouteNode = Context.SpawnNode(7, 29, mousePos);
+ Undo.Enabled = undoEnabled;
+
+ var spawnNodeAction = new AddRemoveNodeAction(rerouteNode, true);
+
+ var disconnectBoxesAction = new ConnectBoxesAction(inputBox, outputBox, false);
+ inputBox.BreakConnection(outputBox);
+ disconnectBoxesAction.End();
+
+ var addConnectionsAction = new EditNodeConnections(Context, rerouteNode);
+ outputBox.CreateConnection(rerouteNode.GetBoxes().First(b => !b.IsOutput));
+ rerouteNode.GetBoxes().First(b => b.IsOutput).CreateConnection(inputBox);
+ addConnectionsAction.End();
+
+
+ Undo.AddAction(new MultiUndoAction(spawnNodeAction, disconnectBoxesAction, addConnectionsAction));
+ }
+ else
+ {
+ var rerouteNode = Context.SpawnNode(7, 29, mousePos);
+ inputBox.BreakConnection(outputBox);
+ outputBox.CreateConnection(rerouteNode.GetBoxes().First(b => !b.IsOutput));
+ rerouteNode.GetBoxes().First(b => b.IsOutput).CreateConnection(inputBox);
+ }
+ MarkAsEdited();
+
+ handled = true;
+ }
}
- return false;
+ return handled;
}
///
@@ -527,6 +562,81 @@ namespace FlaxEditor.Surface
}
return true;
}
+ if (key == KeyboardKeys.ArrowUp || key == KeyboardKeys.ArrowDown)
+ {
+ Box selectedBox = GetSelectedBox(SelectedNodes);
+ if (selectedBox == null) return true;
+
+ Box toSelect = (key == KeyboardKeys.ArrowUp) ?
+ selectedBox?.ParentNode.GetPreviousBox(selectedBox) :
+ selectedBox?.ParentNode.GetNextBox(selectedBox);
+
+ if (toSelect != null && toSelect.IsOutput == selectedBox.IsOutput)
+ {
+ Select(toSelect.ParentNode);
+ toSelect.ParentNode.SelectBox(toSelect);
+ }
+ }
+
+ if (key == KeyboardKeys.Tab)
+ {
+ Box selectedBox = GetSelectedBox(SelectedNodes);
+ if (selectedBox == null) return true;
+
+ int connectionCount = selectedBox.Connections.Count;
+ if (connectionCount == 0) return true;
+
+ if (Root.GetKey(KeyboardKeys.Shift))
+ {
+ _selectedConnectionIndex = ((_selectedConnectionIndex - 1) % connectionCount + connectionCount) % connectionCount;
+ }
+ else
+ {
+ _selectedConnectionIndex = (_selectedConnectionIndex + 1) % connectionCount;
+ }
+ }
+
+
+ if (key == KeyboardKeys.ArrowRight || key == KeyboardKeys.ArrowLeft)
+ {
+ Box selectedBox = GetSelectedBox(SelectedNodes);
+ if (selectedBox == null) return true;
+
+ Box toSelect = null;
+
+ if ((key == KeyboardKeys.ArrowRight && selectedBox.IsOutput) || (key == KeyboardKeys.ArrowLeft && !selectedBox.IsOutput))
+ {
+ if (_selectedConnectionIndex < 0 || _selectedConnectionIndex >= selectedBox.Connections.Count)
+ {
+ _selectedConnectionIndex = 0;
+ }
+ toSelect = selectedBox.Connections[_selectedConnectionIndex];
+ }
+ else
+ {
+ // Use the node with the closest Y-level
+ // Since there are cases like 3 nodes on one side and only 1 node on the other side
+
+ var elements = selectedBox.ParentNode.Elements;
+ float minDistance = float.PositiveInfinity;
+ for (int i = 0; i < elements.Count; i++)
+ {
+ if (elements[i] is Box box && box.IsOutput != selectedBox.IsOutput && Mathf.Abs(box.Y - selectedBox.Y) < minDistance)
+ {
+ toSelect = box;
+ minDistance = Mathf.Abs(box.Y - selectedBox.Y);
+ }
+ }
+ }
+
+ if (toSelect != null)
+ {
+ Select(toSelect.ParentNode);
+ toSelect.ParentNode.SelectBox(toSelect);
+
+ }
+ return true;
+ }
}
return false;
@@ -720,5 +830,31 @@ namespace FlaxEditor.Surface
yLocation
);
}
+
+ private bool IntersectsConnection(Vector2 mousePosition, out InputBox inputBox, out OutputBox outputBox)
+ {
+ for (int i = 0; i < Nodes.Count; i++)
+ {
+ for (int j = 0; j < Nodes[i].Elements.Count; j++)
+ {
+ if (Nodes[i].Elements[j] is OutputBox ob)
+ {
+ for (int k = 0; k < ob.Connections.Count; k++)
+ {
+ if (ob.IntersectsConnection(ob.Connections[k], ref mousePosition))
+ {
+ outputBox = ob;
+ inputBox = ob.Connections[k] as InputBox;
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ outputBox = null;
+ inputBox = null;
+ return false;
+ }
}
}
diff --git a/Source/Editor/Surface/VisjectSurface.cs b/Source/Editor/Surface/VisjectSurface.cs
index 33786c935..7a136ea38 100644
--- a/Source/Editor/Surface/VisjectSurface.cs
+++ b/Source/Editor/Surface/VisjectSurface.cs
@@ -39,6 +39,7 @@ namespace FlaxEditor.Surface
private GroupArchetype _customNodesGroup;
private List _customNodes;
private Action _onSave;
+ private int _selectedConnectionIndex;
internal int _isUpdatingBoxTypes;
@@ -362,6 +363,8 @@ namespace FlaxEditor.Surface
Context.ControlSpawned += OnSurfaceControlSpawned;
Context.ControlDeleted += OnSurfaceControlDeleted;
+ SelectionChanged += () => { _selectedConnectionIndex = 0; };
+
// Init drag handlers
DragHandlers.Add(_dragAssets = new DragAssets(ValidateDragItem));
DragHandlers.Add(_dragParameters = new DragNames(SurfaceParameter.DragPrefix, ValidateDragParameter));
diff --git a/Source/Engine/Engine/Time.h b/Source/Engine/Engine/Time.h
index 0d44afa22..eb176ae7c 100644
--- a/Source/Engine/Engine/Time.h
+++ b/Source/Engine/Engine/Time.h
@@ -121,8 +121,11 @@ public:
API_FIELD() static float PhysicsFPS;
///
- /// The target amount of the frames rendered per second (actual game FPS).
+ /// The target amount of the frames rendered per second (target game FPS).
///
+ ///
+ /// To get the actual game FPS use
+ ///
API_FIELD() static float DrawFPS;
///
diff --git a/Source/Engine/Visject/ShaderGraph.cpp b/Source/Engine/Visject/ShaderGraph.cpp
index 57c4d7746..abb83bd9b 100644
--- a/Source/Engine/Visject/ShaderGraph.cpp
+++ b/Source/Engine/Visject/ShaderGraph.cpp
@@ -770,6 +770,11 @@ void ShaderGenerator::ProcessGroupTools(Box* box, Node* node, Value& value)
#undef PLATFORM_CASE
break;
}
+ case 29:
+ {
+ value = tryGetValue(node->GetBox(0), Value::Zero);
+ break;
+ }
default:
break;
}
diff --git a/Source/Engine/Visject/VisjectGraph.cpp b/Source/Engine/Visject/VisjectGraph.cpp
index abe4436dd..8e15ce87b 100644
--- a/Source/Engine/Visject/VisjectGraph.cpp
+++ b/Source/Engine/Visject/VisjectGraph.cpp
@@ -738,6 +738,12 @@ void VisjectExecutor::ProcessGroupTools(Box* box, Node* node, Value& value)
value = Scripting::FindObject((Guid)node->Values[0]);
break;
}
+
+ case 29:
+ {
+ value = tryGetValue(node->GetBox(0), Value::Zero);
+ break;
+ }
default:
break;
}