Browse Source

Fixed matrix row-column in shader context

Krzysztof Krysiński 1 month ago
parent
commit
b79ccac0ef

+ 1 - 1
src/Drawie

@@ -1 +1 @@
-Subproject commit 0aaaed404a98c5b482066dce8e02ca62c4242f8c
+Subproject commit a9fa6e00850ed1ec88eb57e0af7e36179ef3b24c

+ 12 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Context/FuncContext.cs

@@ -388,4 +388,16 @@ public class FuncContext
 
         return Builder.AssignNewFloat3x3(matrixExpression);
     }
+
+    public void AssignTo<T>(T variable, Expression assignment) where T : ShaderExpressionVariable
+    {
+        if (!HasContext) throw new NoNodeFuncContextException();
+
+        if (assignment is null)
+        {
+            throw new ArgumentNullException(nameof(assignment));
+        }
+
+        Builder.AssignVariable(variable, assignment);
+    }
 }

+ 4 - 4
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Matrix/ComposeMatrixNode.cs

@@ -46,13 +46,13 @@ public class ComposeMatrixNode : Node
         {
             var composed = context.NewFloat3x3(
                 context.GetValue(ScaleX),
-                context.GetValue(SkewX),
-                context.GetValue(TransX),
                 context.GetValue(SkewY),
-                context.GetValue(ScaleY),
-                context.GetValue(TransY),
                 context.GetValue(Persp0),
+                context.GetValue(SkewX),
+                context.GetValue(ScaleY),
                 context.GetValue(Persp1),
+                context.GetValue(TransX),
+                context.GetValue(TransY),
                 context.GetValue(Persp2)
             );
 

+ 20 - 5
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Matrix/RotateNode.cs

@@ -22,6 +22,7 @@ public class RotateNode : Matrix3X3BaseNode
     protected override Float3x3 CalculateMatrix(FuncContext ctx, Float3x3 input)
     {
         Float1 angle = ctx.GetValue(Angle);
+
         Float2 center = ctx.GetValue(Center);
 
         Float1 one = new Float1("") { ConstantValue = 1.0 };
@@ -29,18 +30,32 @@ public class RotateNode : Matrix3X3BaseNode
 
         if (ctx.HasContext)
         {
+            if (RotationType.Value == Nodes.Matrix.RotationType.Degrees)
+            {
+                angle = ctx.NewFloat1(ShaderMath.DegreesToRadians(angle));
+            }
+
             var rotationMatrix = ctx.NewFloat3x3(
-                ShaderMath.Cos(angle), new Expression($"-{ShaderMath.Sin(angle).ExpressionValue}"), new Expression($"{center.X.ExpressionValue} * (1.0 - {ShaderMath.Cos(angle)}) + {center.Y.ExpressionValue} * {ShaderMath.Sin(angle)}"),
-                ShaderMath.Sin(angle), ShaderMath.Cos(angle), new Expression($"{center.Y.ExpressionValue} * (1.0 - {ShaderMath.Cos(angle)}) - {center.X.ExpressionValue} * {ShaderMath.Sin(angle)}"),
-                zero, zero, one
+                ShaderMath.Cos(angle), ShaderMath.Sin(angle), zero,
+                new Expression($"-{ShaderMath.Sin(angle).ExpressionValue}"), ShaderMath.Cos(angle), zero,
+                new Expression(
+                    $"{center.X.ExpressionValue} * (1.0 - {ShaderMath.Cos(angle)}) + {center.Y.ExpressionValue} * {ShaderMath.Sin(angle)}"), // m02 → col 2, row 0
+                new Expression(
+                    $"{center.Y.ExpressionValue} * (1.0 - {ShaderMath.Cos(angle)}) - {center.X.ExpressionValue} * {ShaderMath.Sin(angle)}"), // m12 → col 2, row 1
+                one
             );
+
             return ctx.NewFloat3x3(ShaderMath.PostConcat(input, rotationMatrix));
         }
 
         Matrix3X3 rotationContextlessMatrix = RotationType.Value switch
         {
-            Nodes.Matrix.RotationType.Degrees => Matrix3X3.CreateRotationDegrees((float)(angle.GetConstant() as double? ?? 0.0), (float)(center.X.GetConstant() as double? ?? 0), (float)(center.Y.GetConstant() as double? ?? 0)),
-            Nodes.Matrix.RotationType.Radians => Matrix3X3.CreateRotation((float)(angle.GetConstant() as double? ?? 0.0), (float)(center.X.GetConstant() as double? ?? 0), (float)(center.Y.GetConstant() as double? ?? 0)),
+            Nodes.Matrix.RotationType.Degrees => Matrix3X3.CreateRotationDegrees(
+                (float)(angle.GetConstant() as double? ?? 0.0), (float)(center.X.GetConstant() as double? ?? 0),
+                (float)(center.Y.GetConstant() as double? ?? 0)),
+            Nodes.Matrix.RotationType.Radians => Matrix3X3.CreateRotation(
+                (float)(angle.GetConstant() as double? ?? 0.0), (float)(center.X.GetConstant() as double? ?? 0),
+                (float)(center.Y.GetConstant() as double? ?? 0)),
             _ => throw new ArgumentOutOfRangeException()
         };
 

+ 6 - 3
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Matrix/ScaleNode.cs

@@ -28,10 +28,13 @@ public class ScaleNode : Matrix3X3BaseNode
         if (ctx.HasContext)
         {
             var scaleMatrix = ctx.NewFloat3x3(
-                scale.X, zero, new Expression($"{center.X.ExpressionValue} * (1.0 - {scale.X.ExpressionValue})"),
-                zero, scale.Y, new Expression($"{center.Y.ExpressionValue} * (1.0 - {scale.Y.ExpressionValue})"),
-                zero, zero, one
+                scale.X, zero, zero,
+                zero, scale.Y, zero,
+                new Expression($"{center.X.ExpressionValue} * (1.0 - {scale.X.ExpressionValue})"),
+                new Expression($"{center.Y.ExpressionValue} * (1.0 - {scale.Y.ExpressionValue})"),
+                one
             );
+
             return ctx.NewFloat3x3(ShaderMath.PostConcat(input, scaleMatrix));
         }
 

+ 12 - 7
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Matrix/SkewNode.cs

@@ -22,20 +22,25 @@ public class SkewNode : Matrix3X3BaseNode
         Float1 one = new Float1("") { ConstantValue = 1.0 };
         Float1 zero = new Float1("") { ConstantValue = 0.0 };
 
-        var skewMatrix = ctx.NewFloat3x3(
-            one, skew.X, zero,
-            skew.Y, one, zero,
-            zero, zero, one
-        );
-
         if (ctx.HasContext)
         {
+            var skewMatrix = ctx.NewFloat3x3(
+                one, skew.Y, zero,
+                skew.X, one, zero,
+                zero, zero, one
+            );
+
             return ctx.NewFloat3x3(ShaderMath.PostConcat(input, skewMatrix));
         }
 
+        Matrix3X3 skewContextlessMatrix = Matrix3X3.CreateSkew(
+            (float)(skew.X.GetConstant() as double? ?? 0.0),
+            (float)(skew.Y.GetConstant() as double? ?? 0.0)
+        );
+
         return new Float3x3("")
         {
-            ConstantValue = input.ConstantValue.PostConcat(skewMatrix.ConstantValue)
+            ConstantValue = input.ConstantValue.PostConcat(skewContextlessMatrix)
         };
     }
 

+ 24 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Matrix/TransformNode.cs

@@ -11,6 +11,30 @@ namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Matrix;
 [NodeInfo("Transform")]
 public class TransformNode : Matrix3X3BaseNode
 {
+    public FuncInputProperty<Float2> Position { get; }
+    public FuncOutputProperty<Float2> TransformedPosition { get; }
+
+    public TransformNode()
+    {
+        Position = CreateFuncInput<Float2>("Position", "POSITION", VecD.Zero);
+        TransformedPosition =
+            CreateFuncOutput<Float2>("TransformedPosition", "TRANSFORMED_POSITION", TransformPosition);
+    }
+
+    private Float2 TransformPosition(FuncContext arg)
+    {
+        if (arg.HasContext)
+        {
+            Float3x3 matrix = CalculateMatrix(arg, arg.GetValue(Input));
+            Float2 position = arg.GetValue(Position);
+            Float3 toTransform = arg.Builder.ConstructFloat3(position.X, position.Y, new Float1("") { ConstantValue = 1 });
+            Float3 transformed = arg.Builder.AssignNewFloat3(new Expression($"{matrix.ExpressionValue} * {toTransform.ExpressionValue}"));
+            return arg.Builder.AssignNewFloat2(new Expression($"{transformed.ExpressionValue}.xy / {transformed.ExpressionValue}.z"));
+        }
+
+        return null;
+    }
+
     public override Node CreateCopy()
     {
         return new TransformNode();