Browse Source

Added HSV and HSL modes to separate/combine color nodes

CPKreuz 1 year ago
parent
commit
51aeed5eaa

+ 23 - 12
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/CombineSeparate/CombineColorNode.cs

@@ -10,32 +10,43 @@ public class CombineColorNode : Node
 {
     public FuncOutputProperty<Color> Color { get; }
 
-    public FuncInputProperty<double> R { get; }
+    public InputProperty<CombineSeparateColorMode> Mode { get; }
 
-    public FuncInputProperty<double> G { get; }
+    public FuncInputProperty<double> RH { get; }
 
-    public FuncInputProperty<double> B { get; }
+    public FuncInputProperty<double> GS { get; }
+
+    public FuncInputProperty<double> BVL { get; }
 
     public FuncInputProperty<double> A { get; }
 
     public CombineColorNode()
     {
         Color = CreateFuncOutput(nameof(Color), "COLOR", GetColor);
+        Mode = CreateInput("Mode", "MODE", CombineSeparateColorMode.RGB);
 
-        R = CreateFuncInput("R", "R", 0d);
-        G = CreateFuncInput("G", "G", 0d);
-        B = CreateFuncInput("B", "B", 0d);
+        // TODO: Mode based naming
+        RH = CreateFuncInput("R", "RH", 0d);
+        GS = CreateFuncInput("G", "GS", 0d);
+        BVL = CreateFuncInput("B", "BVL", 0d);
         A = CreateFuncInput("A", "A", 0d);
     }
 
     private Color GetColor(FuncContext ctx)
     {
-        var r = R.Value(ctx) * 255;
-        var g = G.Value(ctx) * 255;
-        var b = B.Value(ctx) * 255;
-        var a = A.Value(ctx) * 255;
-
-        return new Color((byte)r, (byte)g, (byte)b, (byte)a);
+        var mode = Mode.Value;
+        
+        var rh = RH.Value(ctx);
+        var gs = GS.Value(ctx);
+        var bvl = BVL.Value(ctx);
+        var a = (byte)(A.Value(ctx) * 255);
+
+        return mode switch
+        {
+            CombineSeparateColorMode.RGB => new Color((byte)(rh * 255), (byte)(gs * 255), (byte)(bvl * 255), a),
+            CombineSeparateColorMode.HSV => DrawingApi.Core.ColorsImpl.Color.FromHsv((float)(rh * 360d), (float)gs, (float)bvl, a),
+            CombineSeparateColorMode.HSL => DrawingApi.Core.ColorsImpl.Color.FromHsl((float)(rh * 360d), (float)gs, (float)bvl, a)
+        };
     }
 
 

+ 8 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/CombineSeparate/CombineSeparateColorMode.cs

@@ -0,0 +1,8 @@
+namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.CombineSeparate;
+
+public enum CombineSeparateColorMode
+{
+    RGB,
+    HSV,
+    HSL
+}

+ 69 - 15
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/CombineSeparate/SeparateColorNode.cs

@@ -1,4 +1,5 @@
-using PixiEditor.ChangeableDocument.Rendering;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Context;
+using PixiEditor.ChangeableDocument.Rendering;
 using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 
@@ -7,23 +8,77 @@ namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.CombineSeparate;
 [NodeInfo("SeparateColor", "SEPARATE_COLOR_NODE")]
 public class SeparateColorNode : Node
 {
-    public FuncInputProperty<Color> Color { get; }
-    
-    public FuncOutputProperty<double> R { get; }
-    
-    public FuncOutputProperty<double> G { get; }
-    
-    public FuncOutputProperty<double> B { get; }
-    
+    public FuncOutputProperty<double> RH { get; }
+
+    public FuncOutputProperty<double> GS { get; }
+
+    public FuncOutputProperty<double> BVL { get; }
+
     public FuncOutputProperty<double> A { get; }
-    
+
+    public InputProperty<CombineSeparateColorMode> Mode { get; }
+
+    public FuncInputProperty<Color> Color { get; }
+
     public SeparateColorNode()
     {
-        Color = CreateFuncInput(nameof(Color), "COLOR", new Color());
-        R = CreateFuncOutput(nameof(R), "R", ctx => Color.Value(ctx).R / 255d);
-        G = CreateFuncOutput(nameof(G), "G", ctx => Color.Value(ctx).G / 255d);
-        B = CreateFuncOutput(nameof(B), "B", ctx => Color.Value(ctx).B / 255d);
+        // TODO: Mode based naming
+        RH = CreateFuncOutput(nameof(RH), "RH", GetRHValue);
+        GS = CreateFuncOutput(nameof(GS), "GS", GetGSValue);
+        BVL = CreateFuncOutput(nameof(BVL), "BVL", GetBVLValue);
         A = CreateFuncOutput(nameof(A), "A", ctx => Color.Value(ctx).A / 255d);
+        Mode = CreateInput("Mode", "MODE", CombineSeparateColorMode.RGB);
+        Color = CreateFuncInput(nameof(Color), "COLOR", new Color());
+    }
+
+    private double GetRHValue(FuncContext ctx) => Mode.Value switch
+    {
+        CombineSeparateColorMode.RGB => Color.Value(ctx).R / 255d,
+        CombineSeparateColorMode.HSV or CombineSeparateColorMode.HSL => GetHue(Color.Value(ctx))
+    };
+
+    private double GetHue(Color color)
+    {
+        color.ToHsv(out var hue, out _, out _);
+        return hue / 360d;
+    }
+
+    private double GetGSValue(FuncContext ctx) => Mode.Value switch
+    {
+        CombineSeparateColorMode.RGB => Color.Value(ctx).G / 255d,
+        CombineSeparateColorMode.HSV => GetHsvSaturation(Color.Value(ctx)),
+        CombineSeparateColorMode.HSL => GetHslSaturation(Color.Value(ctx))
+    };
+
+    private double GetHsvSaturation(Color color)
+    {
+        color.ToHsv(out _, out var saturation, out _);
+        return saturation;
+    }
+
+    private double GetHslSaturation(Color color)
+    {
+        color.ToHsl(out _, out var saturation, out _);
+        return saturation;
+    }
+
+    private double GetBVLValue(FuncContext ctx) => Mode.Value switch
+    {
+        CombineSeparateColorMode.RGB => Color.Value(ctx).B / 255d,
+        CombineSeparateColorMode.HSV => GetValue(Color.Value(ctx)),
+        CombineSeparateColorMode.HSL => GetLightness(Color.Value(ctx))
+    };
+
+    private double GetValue(Color color)
+    {
+        color.ToHsv(out _, out _, out var value);
+        return value;
+    }
+    
+    private double GetLightness(Color color)
+    {
+        color.ToHsl(out _, out _, out var lightness);
+        return lightness;
     }
 
     protected override Surface? OnExecute(RenderingContext context)
@@ -31,6 +86,5 @@ public class SeparateColorNode : Node
         return null;
     }
 
-
     public override Node CreateCopy() => new SeparateColorNode();
 }