From 6116c665c41ed83c9f3000c821b1c871c79f2c23 Mon Sep 17 00:00:00 2001 From: E1e5en Date: Tue, 13 Oct 2020 20:50:30 +0300 Subject: [PATCH] Modifying the Screen To World Space node Modifying the Screen To World Space node Input parameters: - Screen X - value of screen coordinates along the X axis (data type Int); - Screen Y - the value of the screen coordinates along the Y axis (data type Int). Options: - Separator Out - whether or not to separate the output parameters (vectors) into components (XYZ). Output parameters: - World - coordinates of a point in 3D space (Vector data type) - Direction - normalized direction vector from the camera towards the point/cursor indication (data type Vector). - X, Y, Z - components of the corresponding vectors (data type Float). --- .../logicnode/ScreenToWorldSpaceNode.hx | 70 +++++++++++++++---- .../math/LN_screen_to_world_space.py | 37 +++++++++- 2 files changed, 93 insertions(+), 14 deletions(-) diff --git a/Sources/armory/logicnode/ScreenToWorldSpaceNode.hx b/Sources/armory/logicnode/ScreenToWorldSpaceNode.hx index a5339f08..956a4409 100644 --- a/Sources/armory/logicnode/ScreenToWorldSpaceNode.hx +++ b/Sources/armory/logicnode/ScreenToWorldSpaceNode.hx @@ -1,30 +1,74 @@ package armory.logicnode; import iron.math.Vec4; -import iron.math.Mat4; +import iron.math.RayCaster; class ScreenToWorldSpaceNode extends LogicNode { - public var property0: String; - var v = new Vec4(); - var m = Mat4.identity(); + public var property0: Bool; // Separator Out public function new(tree: LogicTree) { super(tree); } override function get(from: Int): Dynamic { - var v1: Vec4 = inputs[0].get(); - - if (v1 == null) return null; + var vInput: Vec4 = new Vec4(); + vInput.x = inputs[0].get(); + vInput.y = inputs[1].get(); var cam = iron.Scene.active.camera; - v.setFrom(v1); - m.getInverse(cam.P); - v.applyproj(m); - m.getInverse(cam.V); - v.applyproj(m); + if (cam == null) return null; - return v; + // Separator Out + if (property0) { + switch (from) { + // World + case 0: { + return RayCaster.getRay(vInput.x, vInput.y, cam).origin; + } + // World X + case 1: { + return RayCaster.getRay(vInput.x, vInput.y, cam).origin.x; + } + // World Y + case 2: { + return RayCaster.getRay(vInput.x, vInput.y, cam).origin.y; + } + // World Z + case 3: { + return RayCaster.getRay(vInput.x, vInput.y, cam).origin.z; + } + // Direction + case 4: { + return RayCaster.getRay(vInput.x, vInput.y, cam).direction.normalize(); + } + // Direction X + case 5: { + return RayCaster.getRay(vInput.x, vInput.y, cam).direction.normalize().x; + } + // Direction Y + case 6: { + return RayCaster.getRay(vInput.x, vInput.y, cam).direction.normalize().y; + } + // Direction Z + case 7: { + return RayCaster.getRay(vInput.x, vInput.y, cam).direction.normalize().z; + } + } + } + else + { + switch (from) { + // World + case 0: { + return RayCaster.getRay(vInput.x, vInput.y, cam).origin; + } + // Direction + case 1: { + return RayCaster.getRay(vInput.x, vInput.y, cam).direction.normalize(); + } + } + } + return null; } } diff --git a/blender/arm/logicnode/math/LN_screen_to_world_space.py b/blender/arm/logicnode/math/LN_screen_to_world_space.py index e73bb354..b95ca8ee 100644 --- a/blender/arm/logicnode/math/LN_screen_to_world_space.py +++ b/blender/arm/logicnode/math/LN_screen_to_world_space.py @@ -4,11 +4,46 @@ class ScreenToWorldSpaceNode(ArmLogicTreeNode): """Transforms the given screen coordinates into world coordinates.""" bl_idname = 'LNScreenToWorldSpaceNode' bl_label = 'Screen To World Space' + node_index: StringProperty(name='Node Index', default='') arm_version = 1 + min_outputs = 2 + max_outputs = 8 + + # Separator + @property + def property0(self): + return True if self.property0_ else False + + property0_: BoolProperty(name='Separator Out', default=False) def init(self, context): super(ScreenToWorldSpaceNode, self).init(context) - self.add_input('NodeSocketVector', 'Screen') + self.add_input('NodeSocketInt', 'Screen X') + self.add_input('NodeSocketInt', 'Screen Y') self.add_output('NodeSocketVector', 'World') + self.add_output('NodeSocketVector', 'Direction') + + def draw_buttons(self, context, layout): + layout.prop(self, 'property0_') # Separator Out + if self.property0_: + if len(self.outputs) < self.max_outputs: + self.outputs.remove(self.outputs.values()[-1]) # Direction vector + self.add_output('NodeSocketFloat', 'X') # World X + self.add_output('NodeSocketFloat', 'Y') # World Y + self.add_output('NodeSocketFloat', 'Z') # World Z + self.add_output('NodeSocketVector', 'Direction') # Vector + self.add_output('NodeSocketFloat', 'X') # Direction X + self.add_output('NodeSocketFloat', 'Y') # Direction Y + self.add_output('NodeSocketFloat', 'Z') # Direction Z + else: + if len(self.outputs) == self.max_outputs: + self.outputs.remove(self.outputs.values()[-1]) # Z + self.outputs.remove(self.outputs.values()[-1]) # Y + self.outputs.remove(self.outputs.values()[-1]) # X + self.outputs.remove(self.outputs.values()[-1]) # Direction + self.outputs.remove(self.outputs.values()[-1]) # Z + self.outputs.remove(self.outputs.values()[-1]) # Y + self.outputs.remove(self.outputs.values()[-1]) # X + self.add_output('NodeSocketVector', 'Direction') add_node(ScreenToWorldSpaceNode, category=PKG_AS_CATEGORY, section='matrix')