-
Notifications
You must be signed in to change notification settings - Fork 170
Expand file tree
/
Copy pathMath2NodeViewModel.cs
More file actions
104 lines (94 loc) · 3.98 KB
/
Math2NodeViewModel.cs
File metadata and controls
104 lines (94 loc) · 3.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using DynamicData;
using ExampleShaderEditorApp.Model;
using ExampleShaderEditorApp.ViewModels.Editors;
using NodeNetwork.Toolkit.ValueNode;
using NodeNetwork.ViewModels;
using NodeNetwork.Views;
using ReactiveUI;
namespace ExampleShaderEditorApp.ViewModels.Nodes
{
public class Math2NodeViewModel : ShaderNodeViewModel
{
static Math2NodeViewModel()
{
Splat.Locator.CurrentMutable.Register(() => new NodeView(), typeof(IViewFor<Math2NodeViewModel>));
}
public enum MathOperation
{
Add,
Subtract,
Multiply,
Divide,
Power,
Minimum,
Maximum,
LessThan,
GreaterThan,
Modulo
}
public ValueNodeInputViewModel<object> OperationInput { get; } = new ValueNodeInputViewModel<object>();
public ShaderNodeInputViewModel InputA { get; } = new ShaderNodeInputViewModel(typeof(float));
public ShaderNodeInputViewModel InputB { get; } = new ShaderNodeInputViewModel(typeof(float));
public ShaderNodeOutputViewModel Result { get; } = new ShaderNodeOutputViewModel();
public Math2NodeViewModel()
{
this.Name = "Math 2";
this.Category = NodeCategory.Math;
OperationInput.Editor = new EnumEditorViewModel(typeof(MathOperation));
OperationInput.Port.IsVisible = false;
EditableInputs().Add(OperationInput);
InputA.Name = "A";
InputA.Editor = new FloatEditorViewModel();
EditableInputs().Add(InputA);
InputB.Name = "B";
InputB.Editor = new FloatEditorViewModel();
EditableInputs().Add(InputB);
Result.Name = "Result";
Result.ReturnType = typeof(float);
Result.Value = this.WhenAnyValue(vm => vm.InputA.Value, vm => vm.InputB.Value, vm => vm.OperationInput.Value)
.Select(t =>
{
if (t.Item1 == null || t.Item2 == null)
{
return null;
}
return BuildMathOperation(t.Item1, t.Item2, (MathOperation) t.Item3);
});
EditableOutputs().Add(Result);
}
private ShaderFunc BuildMathOperation(ShaderFunc a, ShaderFunc b, MathOperation operation)
{
switch (operation)
{
case MathOperation.Add:
return new ShaderFunc(() => $"({a.Compile()}) + ({b.Compile()})");
case MathOperation.Subtract:
return new ShaderFunc(() => $"({a.Compile()}) - ({b.Compile()})");
case MathOperation.Multiply:
return new ShaderFunc(() => $"({a.Compile()}) * ({b.Compile()})");
case MathOperation.Divide:
return new ShaderFunc(() => $"({a.Compile()}) / ({b.Compile()})");
case MathOperation.Power:
return new ShaderFunc(() => $"pow(({a.Compile()}), ({b.Compile()}))");
case MathOperation.Minimum:
return new ShaderFunc(() => $"min(({a.Compile()}), ({b.Compile()}))");
case MathOperation.Maximum:
return new ShaderFunc(() => $"max(({a.Compile()}), ({b.Compile()}))");
case MathOperation.LessThan:
return new ShaderFunc(() => $"({a.Compile()}) < ({b.Compile()}) ? 1 : 0");
case MathOperation.GreaterThan:
return new ShaderFunc(() => $"({a.Compile()}) > ({b.Compile()}) ? 1 : 0");
case MathOperation.Modulo:
return new ShaderFunc(() => $"mod(({a.Compile()}), ({b.Compile()}))");
default:
throw new Exception("Unsupported math operation");
}
}
}
}