Upgrading the Math Node

- Dynamically change the number of arguments for the selected operation;
- Exp() operation added.
This commit is contained in:
E1e5en 2020-11-03 09:12:41 +03:00
parent e7fd3cef8a
commit 1352811bcd
2 changed files with 106 additions and 63 deletions

View file

@ -2,7 +2,7 @@ package armory.logicnode;
class MathNode extends LogicNode {
public var property0: String;
public var property0: String; // Operation
public var property1: String; // Clamp
public function new(tree: LogicTree) {
@ -10,63 +10,78 @@ class MathNode extends LogicNode {
}
override function get(from: Int): Dynamic {
var v1: Float = inputs[0].get();
var v2: Float = inputs[1].get();
var f = 0.0;
var r = 0.0;
switch (property0) {
case "Add":
f = v1 + v2;
case "Multiply":
f = v1 * v2;
case "Sine":
f = Math.sin(v1);
case "Cosine":
f = Math.cos(v1);
case "Max":
f = Math.max(v1, v2);
case "Min":
f = Math.min(v1, v2);
case "Abs":
f = Math.abs(v1);
case "Subtract":
f = v1 - v2;
case "Divide":
f = v1 / v2;
case "Tangent":
f = Math.tan(v1);
case "Arcsine":
f = Math.asin(v1);
case "Arccosine":
f = Math.acos(v1);
case "Arctangent":
f = Math.atan(v1);
case "Power":
f = Math.pow(v1, v2);
case "Logarithm":
f = Math.log(v1);
case "Round":
f = Math.round(v1);
case "Less Than":
f = v1 < v2 ? 1.0 : 0.0;
case "Greater Than":
f = v1 > v2 ? 1.0 : 0.0;
case "Modulo":
f = v1 % v2;
case "Arctan2":
f = Math.atan2(v1, v2);
case "Floor":
f = Math.floor(v1);
case "Ceil":
f = Math.ceil(v1);
case "Fract":
f = f - Std.int(f);
case "Square Root":
f = Math.sqrt(v1);
}
case "Sine":
r = Math.sin(inputs[0].get());
case "Cosine":
r = Math.cos(inputs[0].get());
case "Abs":
r = Math.abs(inputs[0].get());
case "Tangent":
r = Math.tan(inputs[0].get());
case "Arcsine":
r = Math.asin(inputs[0].get());
case "Arccosine":
r = Math.acos(inputs[0].get());
case "Arctangent":
r = Math.atan(inputs[0].get());
case "Logarithm":
r = Math.log(inputs[0].get());
case "Round":
r = Math.round(inputs[0].get());
case "Floor":
r = Math.floor(inputs[0].get());
case "Ceil":
r = Math.ceil(inputs[0].get());
case "Fract":
var v = inputs[0].get();
r = v - Std.int(v);
case "Square Root":
r = Math.sqrt(inputs[0].get());
case "Exp":
r = Math.exp(inputs[0].get());
case "Max":
r = Math.max(inputs[0].get(), inputs[1].get());
case "Min":
r = Math.min(inputs[0].get(), inputs[1].get());
case "Power":
r = Math.pow(inputs[0].get(), inputs[1].get());
case "Less Than":
r = inputs[0].get() < inputs[1].get() ? 1.0 : 0.0;
case "Greater Than":
r = inputs[0].get() > inputs[1].get() ? 1.0 : 0.0;
case "Modulo":
r = inputs[0].get() % inputs[1].get();
case "Arctan2":
r = Math.atan2(inputs[0].get(), inputs[1].get());
case "Add":
for (inp in inputs) r += inp.get();
case "Multiply":
r = inputs[0].get();
var i = 1;
while (i < inputs.length) {
r *= inputs[i].get();
i++;
}
case "Subtract":
r = inputs[0].get();
var i = 1;
while (i < inputs.length) {
r -= inputs[i].get();
i++;
}
case "Divide":
r = inputs[0].get();
var i = 1;
while (i < inputs.length) {
r /= inputs[i].get();
i++;
}
}
// Clamp
if (property1 == "true") r = r < 0.0 ? 0.0 : (r > 1.0 ? 1.0 : r);
if (property1 == "true") f = f < 0.0 ? 0.0 : (f > 1.0 ? 1.0 : f);
return f;
return r;
}
}
}

View file

@ -1,19 +1,18 @@
from arm.logicnode.arm_nodes import *
class MathNode(ArmLogicTreeNode):
"""Operates values. Some operations uses only the first input."""
"""Mathematical operations on values."""
bl_idname = 'LNMathNode'
bl_label = 'Math'
arm_version = 1
property0: EnumProperty(
items = [('Add', 'Add', 'Add'),
('Multiply', 'Multiply', 'Multiply'),
('Sine', 'Sine', 'Sine'),
('Sine', 'Sine', 'Sine'),
('Cosine', 'Cosine', 'Cosine'),
('Max', 'Maximum', 'Max'),
('Min', 'Minimum', 'Min'),
('Abs', 'Absolute', 'Abs'),
('Subtract', 'Subtract', 'Subtract'),
('Divide', 'Divide', 'Divide'),
('Tangent', 'Tangent', 'Tangent'),
@ -31,6 +30,7 @@ class MathNode(ArmLogicTreeNode):
('Ceil', 'Ceil', 'Ceil'),
('Fract', 'Fract', 'Fract'),
('Square Root', 'Square Root', 'Square Root'),
('Exp', 'Exponent', 'Exponent'),
],
name='', default='Add')
@ -40,12 +40,40 @@ class MathNode(ArmLogicTreeNode):
property1_: BoolProperty(name='Clamp', default=False)
def __init__(self):
array_nodes[str(id(self))] = self
def init(self, context):
super(MathNode, self).init(context)
self.add_input('NodeSocketFloat', 'Value 1', default_value=1.0)
self.add_input('NodeSocketFloat', 'Value 2', default_value=1.0)
self.add_input('NodeSocketFloat', 'Value 0', default_value=0.0)
self.add_input('NodeSocketFloat', 'Value 1', default_value=0.0)
self.add_output('NodeSocketFloat', 'Result')
def draw_buttons(self, context, layout):
layout.prop(self, 'property1_')
layout.prop(self, 'property0')
# Add, Subtract, Multiply, Divide
if (self.property0 == "Add") or (self.property0 == "Subtract") or (self.property0 == "Multiply") or (self.property0 == "Divide"):
while (len(self.inputs) < 2):
self.add_input('NodeSocketFloat', 'Value ' + str(len(self.inputs)))
row = layout.row(align=True)
column = row.column(align=True)
op = column.operator('arm.node_add_input', text='Add Value', icon='PLUS', emboss=True)
op.node_index = str(id(self))
op.socket_type = 'NodeSocketFloat'
op.name_format = 'Value {0}'
column = row.column(align=True)
op = column.operator('arm.node_remove_input', text='', icon='X', emboss=True)
op.node_index = str(id(self))
if len(self.inputs) == 2:
column.enabled = False
# Max, Min, Power, Arctan2, Modulo, Less Than, Greater Than
if (self.property0 == "Max") or (self.property0 == "Min") or (self.property0 == "Power") or (self.property0 == "Arctan2") or (self.property0 == "Modulo") or (self.property0 == "Less Than") or (self.property0 == "Greater Than"):
while (len(self.inputs) > 2):
self.inputs.remove(self.inputs.values()[-1])
while (len(self.inputs) < 2):
self.add_input('NodeSocketFloat', 'Value ' + str(len(self.inputs)))
# Sine, Cosine, Abs, Tangent, Arcsine, Arccosine, Arctangent, Logarithm, Round, Floor, Ceil, Square Root, Fract, Exponent
if (self.property0 == "Sine") or (self.property0 == "Cosine") or (self.property0 == "Abs") or (self.property0 == "Tangent") or (self.property0 == "Arcsine") or (self.property0 == "Arccosine") or (self.property0 == "Arctangent") or (self.property0 == "Logarithm") or (self.property0 == "Round") or (self.property0 == "Floor") or (self.property0 == "Ceil") or (self.property0 == "Square Root") or (self.property0 == "Fract") or (self.property0 == "Exp"):
while (len(self.inputs) > 1):
self.inputs.remove(self.inputs.values()[-1])