diff --git a/Source/Editor/Surface/Archetypes/Function.cs b/Source/Editor/Surface/Archetypes/Function.cs index e9d73ae68..5c3ee7217 100644 --- a/Source/Editor/Surface/Archetypes/Function.cs +++ b/Source/Editor/Surface/Archetypes/Function.cs @@ -745,12 +745,12 @@ namespace FlaxEditor.Surface.Archetypes base.OnDestroy(); } - internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint) + internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint, VisjectSurfaceContext context) { return false; } - internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint) + internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint, VisjectSurfaceContext context) { return inputType.IsVoid; } @@ -1162,7 +1162,7 @@ namespace FlaxEditor.Surface.Archetypes base.OnDestroy(); } - internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint) + internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint, VisjectSurfaceContext context) { if (nodeArch.Tag is not ScriptMemberInfo memberInfo) return false; @@ -1188,7 +1188,7 @@ namespace FlaxEditor.Surface.Archetypes return false; } - internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint) + internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint, VisjectSurfaceContext context) { if (nodeArch.Tag is not ScriptMemberInfo memberInfo) return false; @@ -1836,12 +1836,12 @@ namespace FlaxEditor.Surface.Archetypes base.OnDestroy(); } - internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint) + internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint, VisjectSurfaceContext context) { return false; } - internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint) + internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint, VisjectSurfaceContext context) { return inputType.IsVoid; } @@ -1982,7 +1982,7 @@ namespace FlaxEditor.Surface.Archetypes UpdateSignature(); } - internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint) + internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint, VisjectSurfaceContext context) { var scriptType = TypeUtils.GetType((string)nodeArch.DefaultValues[0]); if (scriptType == ScriptType.Null) @@ -2011,7 +2011,7 @@ namespace FlaxEditor.Surface.Archetypes return false; } - internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint) + internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint, VisjectSurfaceContext context) { var scriptType = TypeUtils.GetType((string)nodeArch.DefaultValues[0]); if (scriptType == ScriptType.Null) @@ -2093,7 +2093,7 @@ namespace FlaxEditor.Surface.Archetypes UpdateSignature(); } - internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint) + internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint, VisjectSurfaceContext context) { if (outputType.IsVoid) return true; @@ -2130,7 +2130,7 @@ namespace FlaxEditor.Surface.Archetypes return false; } - internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint) + internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint, VisjectSurfaceContext context) { return inputType.IsVoid; } @@ -2353,7 +2353,7 @@ namespace FlaxEditor.Surface.Archetypes base.OnDestroy(); } - internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint) + internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint, VisjectSurfaceContext context) { // Event based nodes always have a pulse input, so it's always compatible with void if (outputType.IsVoid) @@ -2373,7 +2373,7 @@ namespace FlaxEditor.Surface.Archetypes return false; } - internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint) + internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint, VisjectSurfaceContext context) { // Event based nodes always have a pulse output, so it's always compatible with void if (inputType.IsVoid) diff --git a/Source/Editor/Surface/Archetypes/Packing.cs b/Source/Editor/Surface/Archetypes/Packing.cs index 6b9e72e7e..d5102dbbc 100644 --- a/Source/Editor/Surface/Archetypes/Packing.cs +++ b/Source/Editor/Surface/Archetypes/Packing.cs @@ -217,7 +217,7 @@ namespace FlaxEditor.Surface.Archetypes { } - internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint) + internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint, VisjectSurfaceContext context) { var typeName = (string)nodeArch.DefaultValues[0]; var type = TypeUtils.GetType(typeName); @@ -234,7 +234,7 @@ namespace FlaxEditor.Surface.Archetypes return false; } - internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint) + internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint, VisjectSurfaceContext context) { var typeName = (string)nodeArch.DefaultValues[0]; var type = TypeUtils.GetType(typeName); @@ -255,7 +255,7 @@ namespace FlaxEditor.Surface.Archetypes { } - internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint) + internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint, VisjectSurfaceContext context) { var typeName = (string)nodeArch.DefaultValues[0]; var type = TypeUtils.GetType(typeName); @@ -267,7 +267,7 @@ namespace FlaxEditor.Surface.Archetypes return false; } - internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint) + internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint, VisjectSurfaceContext context) { var typeName = (string)nodeArch.DefaultValues[0]; var type = TypeUtils.GetType(typeName); diff --git a/Source/Editor/Surface/Archetypes/Parameters.cs b/Source/Editor/Surface/Archetypes/Parameters.cs index c7f343cfb..0e382a68e 100644 --- a/Source/Editor/Surface/Archetypes/Parameters.cs +++ b/Source/Editor/Surface/Archetypes/Parameters.cs @@ -490,6 +490,56 @@ namespace FlaxEditor.Surface.Archetypes _combobox.Width = Width - 30; } } + + internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint, VisjectSurfaceContext context) + { + if (inputType == ScriptType.Object) + return true; + + SurfaceParameter parameter = context.GetParameter((Guid)nodeArch.DefaultValues[0]); + ScriptType type = parameter?.Type ?? ScriptType.Null; + + if (parameter == null || type == ScriptType.Null || parameter.Type.Type == null) + return false; + if (DefaultPrototypes == null || !DefaultPrototypes.TryGetValue(parameter.Type.Type, out var elements)) + { + return VisjectSurface.FullCastCheck(inputType, type, hint); + } + if (elements == null) + return false; + + for (var i = 0; i < elements.Length; i++) + { + if(elements[i].Type != NodeElementType.Output) + continue; + + if (VisjectSurface.FullCastCheck(elements[i].ConnectionsType, inputType, hint)) + return true; + } + return false; + } + + internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint, VisjectSurfaceContext context) + { + SurfaceParameter parameter = context.GetParameter((Guid)nodeArch.DefaultValues[0]); + ScriptType type = parameter?.Type ?? ScriptType.Null; + + if (parameter == null || type == ScriptType.Null) + return false; + if (parameter.Type.Type == null || DefaultPrototypes == null || !DefaultPrototypes.TryGetValue(parameter.Type.Type, out var elements)) + return false; + if (elements == null) + return false; + + for (var i = 0; i < elements.Length; i++) + { + if(elements[i].Type != NodeElementType.Input) + continue; + if (VisjectSurface.FullCastCheck(elements[i].ConnectionsType, outputType, hint)) + return true; + } + return false; + } } /// @@ -675,6 +725,53 @@ namespace FlaxEditor.Surface.Archetypes /// protected override bool UseNormalMaps => false; + + internal new static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint, VisjectSurfaceContext context) + { + if (inputType == ScriptType.Object) + return true; + + SurfaceParameter parameter = context.GetParameter((Guid)nodeArch.DefaultValues[0]); + ScriptType type = parameter?.Type ?? ScriptType.Null; + + if (parameter == null || type == ScriptType.Null) + return false; + if (parameter.Type.Type == null || DefaultPrototypesParticleEmitter == null || !DefaultPrototypesParticleEmitter.TryGetValue(parameter.Type.Type, out var elements)) + return false; + if (elements == null) + return false; + + for (var i = 0; i < elements.Length; i++) + { + if(elements[i].Type != NodeElementType.Output) + continue; + if (VisjectSurface.FullCastCheck(elements[i].ConnectionsType, inputType, hint)) + return true; + } + return false; + } + + internal new static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint, VisjectSurfaceContext context) + { + SurfaceParameter parameter = context.GetParameter((Guid)nodeArch.DefaultValues[0]); + ScriptType type = parameter?.Type ?? ScriptType.Null; + + if (parameter == null || type == ScriptType.Null) + return false; + if (parameter.Type.Type == null || DefaultPrototypesParticleEmitter == null || !DefaultPrototypesParticleEmitter.TryGetValue(parameter.Type.Type, out var elements)) + return false; + if (elements == null) + return false; + + for (var i = 0; i < elements.Length; i++) + { + if(elements[i].Type != NodeElementType.Input) + continue; + if (VisjectSurface.FullCastCheck(elements[i].ConnectionsType, outputType, hint)) + return true; + } + return false; + } } /// @@ -692,6 +789,22 @@ namespace FlaxEditor.Surface.Archetypes /// protected override bool UseNormalMaps => false; + + internal new static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint, VisjectSurfaceContext context) + { + if (inputType == ScriptType.Object) + return true; + + SurfaceParameter parameter = context.GetParameter((Guid)nodeArch.DefaultValues[0]); + ScriptType type = parameter?.Type ?? ScriptType.Null; + + return VisjectSurface.FullCastCheck(inputType, type, hint); + } + + internal new static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint, VisjectSurfaceContext context) + { + return false; + } } /// @@ -874,6 +987,22 @@ namespace FlaxEditor.Surface.Archetypes _combobox.Width = Width - 50; } } + + internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint, VisjectSurfaceContext context) + { + return inputType == ScriptType.Void; + } + + internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint, VisjectSurfaceContext context) + { + if (outputType == ScriptType.Void) + return true; + + SurfaceParameter parameter = context.GetParameter((Guid)nodeArch.DefaultValues[0]); + ScriptType type = parameter?.Type ?? ScriptType.Null; + + return VisjectSurface.FullCastCheck(outputType, type, hint); + } } /// @@ -885,6 +1014,8 @@ namespace FlaxEditor.Surface.Archetypes { TypeID = 1, Create = (id, context, arch, groupArch) => new SurfaceNodeParamsGet(id, context, arch, groupArch), + IsInputCompatible = SurfaceNodeParamsGet.IsInputCompatible, + IsOutputCompatible = SurfaceNodeParamsGet.IsOutputCompatible, Title = "Get Parameter", Description = "Parameter value getter", Flags = NodeFlags.MaterialGraph | NodeFlags.AnimGraph, @@ -902,6 +1033,8 @@ namespace FlaxEditor.Surface.Archetypes { TypeID = 2, Create = (id, context, arch, groupArch) => new SurfaceNodeParamsGetParticleEmitter(id, context, arch, groupArch), + IsInputCompatible = SurfaceNodeParamsGetParticleEmitter.IsInputCompatible, + IsOutputCompatible = SurfaceNodeParamsGetParticleEmitter.IsOutputCompatible, Title = "Get Parameter", Description = "Parameter value getter", Flags = NodeFlags.ParticleEmitterGraph, @@ -919,6 +1052,8 @@ namespace FlaxEditor.Surface.Archetypes { TypeID = 3, Create = (id, context, arch, groupArch) => new SurfaceNodeParamsGetVisualScript(id, context, arch, groupArch), + IsInputCompatible = SurfaceNodeParamsGetVisualScript.IsInputCompatible, + IsOutputCompatible = SurfaceNodeParamsGetVisualScript.IsOutputCompatible, Title = "Get Parameter", Description = "Parameter value getter", Flags = NodeFlags.VisualScriptGraph, @@ -936,6 +1071,8 @@ namespace FlaxEditor.Surface.Archetypes { TypeID = 4, Create = (id, context, arch, groupArch) => new SurfaceNodeParamsSet(id, context, arch, groupArch), + IsInputCompatible = SurfaceNodeParamsSet.IsInputCompatible, + IsOutputCompatible = SurfaceNodeParamsSet.IsOutputCompatible, Title = "Set Parameter", Description = "Parameter value setter", Flags = NodeFlags.VisualScriptGraph, diff --git a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs index 7fd583202..37da7d74d 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs @@ -110,11 +110,11 @@ namespace FlaxEditor.Surface.ContextMenu bool isCompatible = false; if (startBox.IsOutput && _archetype.IsInputCompatible != null) { - isCompatible |= _archetype.IsInputCompatible.Invoke(_archetype, startBox.CurrentType, _archetype.ConnectionsHints); + isCompatible |= _archetype.IsInputCompatible.Invoke(_archetype, startBox.CurrentType, _archetype.ConnectionsHints, startBox.ParentNode.Context); } else if (!startBox.IsOutput && _archetype.IsOutputCompatible != null) { - isCompatible |= _archetype.IsOutputCompatible.Invoke(_archetype, startBox.CurrentType, startBox.ParentNode.Archetype.ConnectionsHints); + isCompatible |= _archetype.IsOutputCompatible.Invoke(_archetype, startBox.CurrentType, startBox.ParentNode.Archetype.ConnectionsHints, startBox.ParentNode.Context); } else if (_archetype.Elements != null) { diff --git a/Source/Editor/Surface/NodeArchetype.cs b/Source/Editor/Surface/NodeArchetype.cs index fe54268e2..0284fc76d 100644 --- a/Source/Editor/Surface/NodeArchetype.cs +++ b/Source/Editor/Surface/NodeArchetype.cs @@ -92,7 +92,7 @@ namespace FlaxEditor.Surface /// /// Checks if the given type is compatible with the given node archetype. Used for custom nodes /// - public delegate bool IsCompatible(NodeArchetype nodeArch, ScriptType portType, ConnectionsHint hint); + public delegate bool IsCompatible(NodeArchetype nodeArch, ScriptType portType, ConnectionsHint hint, VisjectSurfaceContext context); /// /// Unique node type ID within a single group.