diff --git a/Sources/armory/logicnode/MathNode.hx b/Sources/armory/logicnode/MathNode.hx index 56549307..4905c47e 100644 --- a/Sources/armory/logicnode/MathNode.hx +++ b/Sources/armory/logicnode/MathNode.hx @@ -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; } -} +} \ No newline at end of file diff --git a/blender/arm/logicnode/math/LN_math.py b/blender/arm/logicnode/math/LN_math.py index 2e21e698..442ca023 100644 --- a/blender/arm/logicnode/math/LN_math.py +++ b/blender/arm/logicnode/math/LN_math.py @@ -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]) \ No newline at end of file