From 2e701de286041103a5eb253252deba26cfc794d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lera=20Elvo=C3=A9?= Date: Mon, 4 Dec 2023 16:19:59 +0300 Subject: [PATCH] add vector math nodes --- classes/deck/nodes/dictionary_get_key.gd | 45 ++++++++++++++++++ classes/deck/nodes/get_deck_var.gd | 2 +- classes/deck/nodes/obs_decompose_transform.gd | 43 +++++++++++++++++ classes/deck/nodes/obs_vector_to_position.gd | 28 +++++++++++ classes/deck/nodes/set_deck_var.gd | 12 ++--- classes/deck/nodes/vector_add.gd | 41 +++++++++++++++++ classes/deck/nodes/vector_compose.gd | 39 ++++++++++++++++ classes/deck/nodes/vector_decompose.gd | 36 +++++++++++++++ classes/deck/nodes/vector_dot.gd | 38 +++++++++++++++ classes/deck/nodes/vector_multiply.gd | 46 +++++++++++++++++++ classes/deck/nodes/vector_normalize.gd | 39 ++++++++++++++++ classes/deck/nodes/vector_subtract.gd | 41 +++++++++++++++++ 12 files changed, 403 insertions(+), 7 deletions(-) create mode 100644 classes/deck/nodes/dictionary_get_key.gd create mode 100644 classes/deck/nodes/obs_decompose_transform.gd create mode 100644 classes/deck/nodes/obs_vector_to_position.gd create mode 100644 classes/deck/nodes/vector_add.gd create mode 100644 classes/deck/nodes/vector_compose.gd create mode 100644 classes/deck/nodes/vector_decompose.gd create mode 100644 classes/deck/nodes/vector_dot.gd create mode 100644 classes/deck/nodes/vector_multiply.gd create mode 100644 classes/deck/nodes/vector_normalize.gd create mode 100644 classes/deck/nodes/vector_subtract.gd diff --git a/classes/deck/nodes/dictionary_get_key.gd b/classes/deck/nodes/dictionary_get_key.gd new file mode 100644 index 0000000..f49d26c --- /dev/null +++ b/classes/deck/nodes/dictionary_get_key.gd @@ -0,0 +1,45 @@ +extends DeckNode + + +func _init() -> void: + name = "Get Dictionary Key" + node_type = "dictionary_get_key" + description = "" + category = "general" + + add_input_port( + DeckType.Types.DICTIONARY, + "Dictionary" + ) + + add_input_port( + DeckType.Types.STRING, + "Key", + "field" + ) + + add_output_port( + DeckType.Types.ANY, + "Value" + ) + + +func _value_request(on_port: int) -> Variant: + var d = request_value(0) + if d == null: + return null + + var key = get_value_for_input_port(1) + if key == null: + return null + + return d.get(key) + + +func get_value_for_input_port(port: int) -> Variant: + if request_value(port) != null: + return request_value(port) + elif get_input_ports()[port].value_callback.get_object() && get_input_ports()[port].value_callback.call() != null: + return get_input_ports()[port].value_callback.call() + else: + return null diff --git a/classes/deck/nodes/get_deck_var.gd b/classes/deck/nodes/get_deck_var.gd index 44686f9..d71d9ba 100644 --- a/classes/deck/nodes/get_deck_var.gd +++ b/classes/deck/nodes/get_deck_var.gd @@ -16,4 +16,4 @@ func _init() -> void: func _value_request(from_port: int) -> Variant: var key = ports[0].value_callback.call() - return _belonging_to.variable_stack[key] + return _belonging_to.variable_stack.get(key) diff --git a/classes/deck/nodes/obs_decompose_transform.gd b/classes/deck/nodes/obs_decompose_transform.gd new file mode 100644 index 0000000..4645925 --- /dev/null +++ b/classes/deck/nodes/obs_decompose_transform.gd @@ -0,0 +1,43 @@ +extends DeckNode + + +func _init() -> void: + name = "Decompose OBS Transform" + node_type = "obs_decompose_transform" + description = "" + category = "obs" + + add_input_port( + DeckType.Types.DICTIONARY, + "Transform" + ) + + add_output_port( + DeckType.Types.NUMERIC, + "Rotation" + ) + + add_output_port( + DeckType.Types.NUMERIC, + "Position X" + ) + add_output_port( + DeckType.Types.NUMERIC, + "Position Y" + ) + + +func _value_request(on_port: int) -> Variant: + var t = request_value(0) + if t == null: + return null + + match on_port: + 0: + return (t as Dictionary).get("rotation") + 1: + return (t as Dictionary).get("position_x") + 2: + return (t as Dictionary).get("position_y") + _: + return null diff --git a/classes/deck/nodes/obs_vector_to_position.gd b/classes/deck/nodes/obs_vector_to_position.gd new file mode 100644 index 0000000..d9f3acd --- /dev/null +++ b/classes/deck/nodes/obs_vector_to_position.gd @@ -0,0 +1,28 @@ +extends DeckNode + + +func _init() -> void: + name = "Vector to OBS Position" + node_type = "obs_vector_to_position" + description = "" + category = "obs" + + add_input_port( + DeckType.Types.DICTIONARY, + "Vector" + ) + add_output_port( + DeckType.Types.DICTIONARY, + "Position" + ) + + +func _value_request(on_port: int) -> Variant: + var v = request_value(0) + if !v: + return null + + if !(v as Dictionary).has("x") || !(v as Dictionary).has("y"): + return null + + return {"position_x": v.x, "position_y": v.y} diff --git a/classes/deck/nodes/set_deck_var.gd b/classes/deck/nodes/set_deck_var.gd index 66ae632..cb13b66 100644 --- a/classes/deck/nodes/set_deck_var.gd +++ b/classes/deck/nodes/set_deck_var.gd @@ -36,8 +36,8 @@ func _receive(to_input_port: int, data: Variant, extra_data: Array = []) -> void if to_input_port != 2: return - var var_name: String = get_value_for_port(0, data) - var var_value: Variant = get_value_for_port(1, data) + var var_name: String = get_value_for_port(0) + var var_value: Variant = get_value_for_port(1) _belonging_to.variable_stack[var_name] = var_value @@ -45,10 +45,10 @@ func _receive(to_input_port: int, data: Variant, extra_data: Array = []) -> void # this can probably go into DeckNode with a different name that makes it clear # that it prioritizes call-time resolution -func get_value_for_port(port: int, data: Variant) -> Variant: +func get_value_for_port(port: int) -> Variant: if request_value(port) != null: return request_value(port) - elif ports[port].value_callback.call() != "": - return ports[port].value_callback.call() + elif get_input_ports()[port].value_callback.get_object() && get_input_ports()[port].value_callback.call() != null: + return get_input_ports()[port].value_callback.call() else: - return data + return null diff --git a/classes/deck/nodes/vector_add.gd b/classes/deck/nodes/vector_add.gd new file mode 100644 index 0000000..bcd7fe4 --- /dev/null +++ b/classes/deck/nodes/vector_add.gd @@ -0,0 +1,41 @@ +extends DeckNode + + +func _init() -> void: + name = "Add Vectors" + node_type = "vector_add" + description = "" + category = "math" + + add_input_port( + DeckType.Types.DICTIONARY, + "Vector A" + ) + add_input_port( + DeckType.Types.DICTIONARY, + "Vector B" + ) + add_output_port( + DeckType.Types.DICTIONARY, + "Result" + ) + + +func _value_request(on_port: int) -> Variant: + var va = request_value(0) + var vb = request_value(1) + + if !va || !vb: + return null + + if !(va as Dictionary).has("x") || !(va as Dictionary).has("y"): + return null + + if !(vb as Dictionary).has("x") || !(vb as Dictionary).has("y"): + return null + + var res := {} + res["x"] = va["x"] + vb["x"] + res["y"] = va["y"] + vb["y"] + + return res diff --git a/classes/deck/nodes/vector_compose.gd b/classes/deck/nodes/vector_compose.gd new file mode 100644 index 0000000..7fc1d9f --- /dev/null +++ b/classes/deck/nodes/vector_compose.gd @@ -0,0 +1,39 @@ +extends DeckNode + + +func _init() -> void: + name = "Compose Vector" + node_type = "vector_compose" + description = "" + category = "math" + + add_input_port( + DeckType.Types.NUMERIC, + "X", + "field" + ) + add_input_port( + DeckType.Types.NUMERIC, + "Y", + "field" + ) + + add_output_port( + DeckType.Types.DICTIONARY, + "Vector" + ) + + +func _value_request(on_port: int) -> Dictionary: + var x = float(get_value_for_input_port(0)) + var y = float(get_value_for_input_port(1)) + return {"x": x, "y": y} + + +func get_value_for_input_port(port: int) -> Variant: + if request_value(port) != null: + return request_value(port) + elif get_input_ports()[port].value_callback.get_object() && get_input_ports()[port].value_callback.call() != null: + return get_input_ports()[port].value_callback.call() + else: + return null diff --git a/classes/deck/nodes/vector_decompose.gd b/classes/deck/nodes/vector_decompose.gd new file mode 100644 index 0000000..87f351a --- /dev/null +++ b/classes/deck/nodes/vector_decompose.gd @@ -0,0 +1,36 @@ +extends DeckNode + + +func _init() -> void: + name = "Decompose Vector" + node_type = "vector_decompose" + description = "" + category = "math" + + add_input_port( + DeckType.Types.DICTIONARY, + "Vector" + ) + + add_output_port( + DeckType.Types.NUMERIC, + "X" + ) + add_output_port( + DeckType.Types.NUMERIC, + "Y" + ) + + +func _value_request(on_port: int) -> Variant: + var v = request_value(0) + if !v: + return null + + if !(v as Dictionary).has("x") || !(v as Dictionary).has("y"): + return null + + if on_port == 0: + return v.x + else: + return v.y diff --git a/classes/deck/nodes/vector_dot.gd b/classes/deck/nodes/vector_dot.gd new file mode 100644 index 0000000..bffff3c --- /dev/null +++ b/classes/deck/nodes/vector_dot.gd @@ -0,0 +1,38 @@ +extends DeckNode + + +func _init() -> void: + name = "Vector Dot Product" + node_type = "vector_dot" + description = "" + category = "math" + + add_input_port( + DeckType.Types.DICTIONARY, + "Vector A" + ) + add_input_port( + DeckType.Types.DICTIONARY, + "Vector B" + ) + + add_output_port( + DeckType.Types.NUMERIC, + "Dot" + ) + + +func _value_request(on_port: int) -> Variant: + var va = request_value(0) + var vb = request_value(1) + + if !va || !vb: + return null + + if !(va as Dictionary).has("x") || !(va as Dictionary).has("y"): + return null + + if !(vb as Dictionary).has("x") || !(vb as Dictionary).has("y"): + return null + + return va.x * vb.x + va.y * vb.y diff --git a/classes/deck/nodes/vector_multiply.gd b/classes/deck/nodes/vector_multiply.gd new file mode 100644 index 0000000..725ff71 --- /dev/null +++ b/classes/deck/nodes/vector_multiply.gd @@ -0,0 +1,46 @@ +extends DeckNode + + +func _init() -> void: + name = "Multiply Vector by Scalar" + node_type = "vector_multiply" + description = "" + category = "math" + + add_input_port( + DeckType.Types.DICTIONARY, + "Vector" + ) + add_input_port( + DeckType.Types.NUMERIC, + "Scalar", + "field" + ) + + add_output_port( + DeckType.Types.DICTIONARY, + "Result" + ) + + +func _value_request(on_port: int) -> Variant: + var v = request_value(0) + + if !v: + return null + + if !(v as Dictionary).has("x") || !(v as Dictionary).has("y"): + return null + + var s = float(get_value_for_input_port(1)) + + return {"x": v.x * s, "y": v.y * s} + + +func get_value_for_input_port(port: int) -> Variant: + if request_value(port) != null: + return request_value(port) + elif get_input_ports()[port].value_callback.get_object() && get_input_ports()[port].value_callback.call() != null: + return get_input_ports()[port].value_callback.call() + else: + return null diff --git a/classes/deck/nodes/vector_normalize.gd b/classes/deck/nodes/vector_normalize.gd new file mode 100644 index 0000000..88d865b --- /dev/null +++ b/classes/deck/nodes/vector_normalize.gd @@ -0,0 +1,39 @@ +extends DeckNode + + +func _init() -> void: + name = "Normalize Vector" + node_type = "vector_normalize" + description = "" + category = "math" + + add_input_port( + DeckType.Types.DICTIONARY, + "Vector" + ) + + add_output_port( + DeckType.Types.DICTIONARY, + "Result" + ) + + +func _value_request(on_port: int) -> Variant: + var v = request_value(0) + if !v: + return null + + if !(v as Dictionary).has("x") || !(v as Dictionary).has("y"): + return null + + var l: float = (v.x ** 2.0) + (v.y ** 2.0) + var res := {"x": v.x, "y": v.y} + if l != 0: + l = sqrt(l) + res.x = res.x / l + res.y = res.y / l + return res + + print("vector length is 0, can't normalize. returning null") + + return null diff --git a/classes/deck/nodes/vector_subtract.gd b/classes/deck/nodes/vector_subtract.gd new file mode 100644 index 0000000..560ebc7 --- /dev/null +++ b/classes/deck/nodes/vector_subtract.gd @@ -0,0 +1,41 @@ +extends DeckNode + + +func _init() -> void: + name = "Subtract Vectors" + node_type = "vector_subtract" + description = "" + category = "math" + + add_input_port( + DeckType.Types.DICTIONARY, + "Vector A" + ) + add_input_port( + DeckType.Types.DICTIONARY, + "Vector B" + ) + add_output_port( + DeckType.Types.DICTIONARY, + "Result" + ) + + +func _value_request(on_port: int) -> Variant: + var va = request_value(0) + var vb = request_value(1) + + if !va || !vb: + return null + + if !(va as Dictionary).has("x") || !(va as Dictionary).has("y"): + return null + + if !(vb as Dictionary).has("x") || !(vb as Dictionary).has("y"): + return null + + var res := {} + res["x"] = va["x"] - vb["x"] + res["y"] = va["y"] - vb["y"] + + return res