From f44b8ac7a195289cfe01dac921a2918916583704 Mon Sep 17 00:00:00 2001 From: t3du <32546729+t3du@users.noreply.github.com> Date: Thu, 19 Dec 2024 22:35:47 -0300 Subject: [PATCH 1/2] Add files via upload --- .../armory/logicnode/DrawRoundedRectNode.hx | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 armory/Sources/armory/logicnode/DrawRoundedRectNode.hx diff --git a/armory/Sources/armory/logicnode/DrawRoundedRectNode.hx b/armory/Sources/armory/logicnode/DrawRoundedRectNode.hx new file mode 100644 index 000000000..226da3c62 --- /dev/null +++ b/armory/Sources/armory/logicnode/DrawRoundedRectNode.hx @@ -0,0 +1,118 @@ +package armory.logicnode; + +import kha.Color; +import kha.math.Vector2; +import armory.renderpath.RenderToTexture; + +#if arm_ui +using zui.GraphicsExtension; +#end + +class DrawRoundedRectNode extends LogicNode { + + var vertices: Array; + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if arm_ui + RenderToTexture.ensure2DContext("DrawPolygonNode"); + + final anchorH: Int = inputs[4].get(); + final anchorV: Int = inputs[5].get(); + final x: Float = inputs[8].get(); + final y: Float = inputs[9].get(); + final width: Float = inputs[10].get(); + final height: Float = inputs[11].get(); + final drawx = x - 0.5 * width * anchorH; + final drawy = y - 0.5 * height * anchorV; + final angle: Float = inputs[12].get(); + + var vertArr: Dynamic = drawRoundedRect(drawx, drawy, width, height, inputs[7].get(), inputs[6].get()); + + if (vertices == null || vertices.length != vertArr.length) { + // Preallocate + vertices = []; + vertices.resize(vertArr.length); + for (i in 0...vertices.length) { + vertices[i] = new Vector2(); + } + } + + for (i in 0...vertArr.length) { + if (Std.isOfType(vertArr[i], iron.math.Vec4) || Std.isOfType(vertArr[i], iron.math.Vec3)){ + vertices[i].x = vertArr[i].x; + vertices[i].y = vertArr[i].y; + } else { + assert(Error, vertArr[i].length >= 2, "Array positions must be an array of two dimensions (X, Y)"); + vertices[i].x = vertArr[i][0]; + vertices[i].y = vertArr[i][1]; + } + } + + RenderToTexture.g.rotate(angle, x, y); + final colorVec = inputs[1].get(); + RenderToTexture.g.color = Color.fromFloats(colorVec.x, colorVec.y, colorVec.z, colorVec.w); + + if (inputs[2].get()) { + RenderToTexture.g.fillPolygon(0, 0, vertices); + } else { + RenderToTexture.g.drawPolygon(0, 0, vertices, inputs[3].get()); + } + #end + + RenderToTexture.g.rotate(-angle, x, y); + runOutput(0); + } + + function drawRoundedRect(x:Float, y:Float, width:Float, height:Float, radius:Float, segments:Int):Array> { + var vertices:Array> = []; + + vertices.push([x + radius, y]); + vertices.push([x + width - radius, y]); + + for (i in 0...segments) { + var angle:Float = Math.PI / 2 * (segments - i) / segments; + vertices.push([ + x + width - radius + Math.cos(angle) * radius, + y + radius - Math.sin(angle) * radius + ]); + } + + vertices.push([x + width, y + radius]); + vertices.push([x + width, y + height - radius]); + + for (i in 0...segments) { + var angle:Float = Math.PI / 2 * i / segments; + vertices.push([ + x + width - radius + Math.cos(angle) * radius, + y + height - radius + Math.sin(angle) * radius + ]); + } + + vertices.push([x + width - radius, y + height]); + vertices.push([x + radius, y + height]); + + for (i in 0...segments) { + var angle:Float = Math.PI / 2 * (segments - i) / segments; + vertices.push([ + x + radius - Math.cos(angle) * radius, + y + height - radius + Math.sin(angle) * radius + ]); + } + + vertices.push([x, y + height - radius]); + + for (i in 0...segments) { + var angle:Float = Math.PI / 2 * i / segments; + vertices.push([ + x + radius - Math.cos(angle) * radius, + y + radius - Math.sin(angle) * radius + ]); + } + + return vertices; + } +} From 3f892089b141ef517b7955169944fd6840f48a54 Mon Sep 17 00:00:00 2001 From: t3du <32546729+t3du@users.noreply.github.com> Date: Thu, 19 Dec 2024 22:36:40 -0300 Subject: [PATCH 2/2] Add files via upload --- .../logicnode/draw/LN_draw_rounded_rect.py | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 armory/blender/arm/logicnode/draw/LN_draw_rounded_rect.py diff --git a/armory/blender/arm/logicnode/draw/LN_draw_rounded_rect.py b/armory/blender/arm/logicnode/draw/LN_draw_rounded_rect.py new file mode 100644 index 000000000..f84a3ada3 --- /dev/null +++ b/armory/blender/arm/logicnode/draw/LN_draw_rounded_rect.py @@ -0,0 +1,48 @@ +from arm.logicnode.arm_nodes import * + + +class DrawRoundedRectNode(ArmLogicTreeNode): + """Draws a rectangle. + + @input Draw: Activate to draw the rectangle on this frame. The input must + be (indirectly) called from an `On Render2D` node. + @input Color: The color of the rectangle. + @input Filled: Whether the rectangle is filled or only the outline is drawn. + @input Strength: The line strength if the rectangle is not filled. + @input Left/Center/Right: Horizontal anchor point of the rectangel. + 0 = Left, 1 = Center, 2 = Right + @input Top/Middle/Bottom: Vertical anchor point of the rectangel. + 0 = Top, 1 = Middle, 2 = Bottom + @input Segments: number of points to consider for rounded rect corners. + @input Radius: radius of the rounded rect. + @input X/Y: Position of the anchor point in pixels. + @input Width/Height: Size of the rectangle in pixels. + @input Angle: Rotation angle in radians. Rectangle will be rotated cloclwiswe + at the anchor point. + + @output Out: Activated after the rectangle has been drawn. + + @see [`kha.graphics2.Graphics.drawRect()`](http://kha.tech/api/kha/graphics2/Graphics.html#drawRect). + @see [`kha.graphics2.Graphics.fillRect()`](http://kha.tech/api/kha/graphics2/Graphics.html#fillRect). + """ + bl_idname = 'LNDrawRoundedRectNode' + bl_label = 'Draw Rounded Rect' + arm_section = 'draw' + arm_version = 1 + + def arm_init(self, context): + self.add_input('ArmNodeSocketAction', 'Draw') + self.add_input('ArmColorSocket', 'Color', default_value=[1.0, 1.0, 1.0, 1.0]) + self.add_input('ArmBoolSocket', 'Filled', default_value=False) + self.add_input('ArmFloatSocket', 'Strength', default_value=1.0) + self.add_input('ArmIntSocket', '0/1/2 = Left/Center/Right', default_value=0) + self.add_input('ArmIntSocket', '0/1/2 = Top/Middle/Bottom', default_value=0) + self.add_input('ArmIntSocket', 'Segments', default_value=10) + self.add_input('ArmFloatSocket', 'Radius') + self.add_input('ArmFloatSocket', 'X') + self.add_input('ArmFloatSocket', 'Y') + self.add_input('ArmFloatSocket', 'Width') + self.add_input('ArmFloatSocket', 'Height') + self.add_input('ArmFloatSocket', 'Angle') + + self.add_output('ArmNodeSocketAction', 'Out')