Переглянути джерело

Uniform type change detection and input value fixes

Krzysztof Krysiński 6 місяців тому
батько
коміт
540b14be66

+ 1 - 1
src/Drawie

@@ -1 +1 @@
-Subproject commit f55664535230db4f22341724f7b5016af89947f2
+Subproject commit bfdfb763a00e7bcfa2e650899e58d5d42e388457

+ 28 - 24
src/PixiEditor.ChangeableDocument/Changeables/Graph/InputProperty.cs

@@ -42,7 +42,28 @@ public class InputProperty : IInputProperty
                 return FuncFactory(connectionValue);
             }
 
-            return connectionValue;
+            if (connectionValue.GetType() == ValueType)
+            {
+                return connectionValue;
+            }
+
+            if (connectionValue is Delegate func && ValueType.IsAssignableTo(typeof(Delegate)))
+            {
+                return FuncFactoryDelegate(func);
+            }
+
+            object target = connectionValue;
+            if (target is ShaderExpressionVariable shaderExpression)
+            {
+                target = shaderExpression.GetConstant();
+            }
+
+            if (!ConversionTable.TryConvert(target, ValueType, out object result))
+            {
+                return null;
+            }
+
+            return Validator.GetClosestValidValue(result);
         }
     }
 
@@ -94,17 +115,17 @@ public class InputProperty : IInputProperty
     {
         get
         {
-            if(Connection == null && lastConnectionHash != -1)
+            if (Connection == null && lastConnectionHash != -1)
             {
                 return true;
             }
-            
-            if(Connection != null && lastConnectionHash != Connection.GetHashCode())
+
+            if (Connection != null && lastConnectionHash != Connection.GetHashCode())
             {
                 lastConnectionHash = Connection.GetHashCode();
                 return true;
             }
-            
+
             if (Value is ICacheable cacheable)
             {
                 return cacheable.GetCacheHash() != _lastExecuteHash;
@@ -126,7 +147,6 @@ public class InputProperty : IInputProperty
 
     protected virtual void NonOverridenValueSet(object value)
     {
-
     }
 
     internal virtual void UpdateCache()
@@ -143,7 +163,7 @@ public class InputProperty : IInputProperty
         {
             _lastExecuteHash = Value.GetHashCode();
         }
-        
+
         lastConnectionHash = Connection?.GetHashCode() ?? -1;
     }
 
@@ -184,23 +204,7 @@ public class InputProperty<T> : InputProperty, IInputProperty<T>
             if (value is T tValue)
                 return tValue;
 
-            if (value is Delegate func && typeof(T).IsAssignableTo(typeof(Delegate)))
-            {
-                return (T)FuncFactoryDelegate(func);
-            }
-
-            object target = value;
-            if (value is ShaderExpressionVariable shaderExpression)
-            {
-                target = shaderExpression.GetConstant();
-            }
-
-            if (!ConversionTable.TryConvert(target, typeof(T), out object result))
-            {
-                return default;
-            }
-
-            return (T)Validator.GetClosestValidValue(result);
+            return (T)value;
         }
     }
 

+ 41 - 25
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/ShaderNode.cs

@@ -146,9 +146,9 @@ public class ShaderNode : RenderNode, IRenderInput, ICustomShaderNode
     private void RegenerateUniformInputs(string newShaderCode)
     {
         UniformDeclaration[]? declarations = Shader.GetUniformDeclarations(newShaderCode);
-        if(declarations == null) return;
+        if (declarations == null) return;
 
-        if(declarations.Length == 0)
+        if (declarations.Length == 0)
         {
             foreach (var input in uniformInputs)
             {
@@ -170,7 +170,7 @@ public class ShaderNode : RenderNode, IRenderInput, ICustomShaderNode
 
         foreach (var uniform in uniforms)
         {
-            if(IsBuiltInUniform(uniform.Name))
+            if (IsBuiltInUniform(uniform.Name))
             {
                 continue;
             }
@@ -227,33 +227,49 @@ public class ShaderNode : RenderNode, IRenderInput, ICustomShaderNode
                 value = expressionVariable.GetConstant();
             }
 
-            if (value is float floatValue)
+            if (input.Value.valueType == UniformValueType.Float)
             {
-                uniforms.Add(input.Key, new Uniform(input.Key, floatValue));
-            }
-            else if (value is double doubleValue)
-            {
-                uniforms.Add(input.Key, new Uniform(input.Key, (float)doubleValue));
-            }
-            else if (value is int intValue)
-            {
-                uniforms.Add(input.Key, new Uniform(input.Key, intValue));
+                if (value is float floatValue)
+                {
+                    uniforms.Add(input.Key, new Uniform(input.Key, floatValue));
+                }
+                else if (value is double doubleValue)
+                {
+                    uniforms.Add(input.Key, new Uniform(input.Key, (float)doubleValue));
+                }
+                else if (value is int intValue)
+                {
+                    uniforms.Add(input.Key, new Uniform(input.Key, (float)intValue));
+                }
             }
-            else if (value is VecD vector)
+            else if (input.Value.valueType == UniformValueType.Vector2)
             {
-                uniforms.Add(input.Key, new Uniform(input.Key, vector));
+                if (value is VecD vector)
+                {
+                    uniforms.Add(input.Key, new Uniform(input.Key, vector));
+                }
+                else if (value is VecI vecI)
+                {
+                    uniforms.Add(input.Key, new Uniform(input.Key, new VecD(vecI.X, vecI.Y)));
+                }
             }
-            else if (value is Color color)
+            else if (input.Value.valueType == UniformValueType.Color)
             {
-                uniforms.Add(input.Key, new Uniform(input.Key, color));
+                if (value is Color color)
+                {
+                    uniforms.Add(input.Key, new Uniform(input.Key, color));
+                }
             }
-            else if (value is Texture texture)
+            else if (input.Value.valueType == UniformValueType.Shader)
             {
-                var snapshot = texture.DrawingSurface.Snapshot();
-                Shader snapshotShader = snapshot.ToShader();
-                lastCustomImageShaders.Add(snapshotShader);
-                uniforms.Add(input.Key, new Uniform(input.Key, snapshotShader));
-                snapshot.Dispose();
+                if (value is Texture texture)
+                {
+                    var snapshot = texture.DrawingSurface.Snapshot();
+                    Shader snapshotShader = snapshot.ToShader();
+                    lastCustomImageShaders.Add(snapshotShader);
+                    uniforms.Add(input.Key, new Uniform(input.Key, snapshotShader));
+                    snapshot.Dispose();
+                }
             }
         }
     }
@@ -269,9 +285,9 @@ public class ShaderNode : RenderNode, IRenderInput, ICustomShaderNode
         {
             var result = Shader.Create(code, out string errors);
             result?.Dispose();
-            return new (string.IsNullOrWhiteSpace(errors), errors);
+            return new(string.IsNullOrWhiteSpace(errors), errors);
         }
 
-        return new (false, "Shader code must be a string");
+        return new(false, "Shader code must be a string");
     }
 }

+ 28 - 4
src/PixiEditor/Models/DocumentModels/DocumentUpdater.cs

@@ -537,8 +537,20 @@ internal class DocumentUpdater
     {
         NodeViewModel node = doc.StructureHelper.FindNode<NodeViewModel>(info.NodeId);
 
-        List<INodePropertyHandler> removedInputs =
-            node.Inputs.Where(x => !info.Inputs.Any(y => y.PropertyName == x.PropertyName)).ToList();
+        List<INodePropertyHandler> removedInputs = new List<INodePropertyHandler>();
+
+        foreach (var input in node.Inputs)
+        {
+            if (!info.Inputs.Any(x => x.PropertyName == input.PropertyName))
+            {
+                removedInputs.Add(input);
+            }
+
+            if(info.Inputs.FirstOrDefault(x => x.PropertyName == input.PropertyName && x.ValueType != input.PropertyType) is { } changedInput)
+            {
+                removedInputs.Add(input);
+            }
+        }
 
         foreach (var input in removedInputs)
         {
@@ -557,8 +569,20 @@ internal class DocumentUpdater
     {
         NodeViewModel node = doc.StructureHelper.FindNode<NodeViewModel>(info.NodeId);
 
-        List<INodePropertyHandler> removedOutputs =
-            node.Outputs.Where(x => !info.Outputs.Any(y => y.PropertyName == x.PropertyName)).ToList();
+        List<INodePropertyHandler> removedOutputs = new List<INodePropertyHandler>();
+
+        foreach (var output in node.Outputs)
+        {
+            if (!info.Outputs.Any(x => x.PropertyName == output.PropertyName))
+            {
+                removedOutputs.Add(output);
+            }
+
+            if(info.Outputs.FirstOrDefault(x => x.PropertyName == output.PropertyName && x.ValueType != output.Value.GetType()) is { } changedOutput)
+            {
+                removedOutputs.Add(output);
+            }
+        }
 
         foreach (var output in removedOutputs)
         {

+ 1 - 0
src/PixiEditor/Models/Handlers/INodePropertyHandler.cs

@@ -14,4 +14,5 @@ public interface INodePropertyHandler
 
     public event NodePropertyValueChanged ValueChanged;
     public INodeHandler Node { get; set; }
+    public Type PropertyType { get; }
 }