diff --git a/scripts/node_shape/node_shape.gml b/scripts/node_shape/node_shape.gml index 0c196cd41..6fa0efe2e 100644 --- a/scripts/node_shape/node_shape.gml +++ b/scripts/node_shape/node_shape.gml @@ -137,14 +137,14 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con newInput(35, nodeValue_Vec2("Point 3", self, [ 1, 0 ])) .setUnitRef(onSurfaceSize, VALUE_UNIT.reference); - // newInput(36, nodeValue_Vec2("Point 3", self, [ 1, 0 ])) + newInput(36, nodeValue_Enum_Button("Corner Shape", self, 0, [ "Round", "Cut" ])) newOutput(0, nodeValue_Output("Surface out", self, VALUE_TYPE.surface, noone)); input_display_list = [ ["Output", false], 0, 6, ["Transform", false], 15, 3, 16, 17, 19, 28, - ["Shape", false], 14, 2, 32, 33, 35, 34, /**/ 9, 4, 13, 5, 7, 8, 21, 22, 23, 24, 25, 26, 27, 30, 31, + ["Shape", false], 14, 2, 32, 33, 35, 34, /**/ 9, 4, 13, 5, 7, 8, 21, 22, 23, 24, 25, 26, 27, 30, 31, 36, ["Render", true], 10, 18, ["Height", true, 12], 29, 20, ["Background", true, 1], 11, @@ -331,6 +331,7 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con inputs[33].setVisible(false); inputs[34].setVisible(false); inputs[35].setVisible(false); + inputs[36].setVisible(false); _outSurf = surface_verify(_outSurf, _dim[0], _dim[1], attrDepth()); use_path = _path != noone && struct_has(_path, "getPointRatio"); @@ -412,6 +413,7 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con case "Rectangle" : inputs[ 9].setVisible( true); inputs[18].setVisible(false); + inputs[36].setVisible( true); shader_set_i("shape", 0); break; @@ -443,9 +445,10 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con break; case "Regular polygon" : - inputs[4].setVisible(true); - inputs[7].setVisible(true); - inputs[9].setVisible(true); + inputs[ 4].setVisible(true); + inputs[ 7].setVisible(true); + inputs[ 9].setVisible(true); + inputs[36].setVisible(true); shader_set_i("shape", 2); shader_set_i("sides", _data[4]); @@ -453,10 +456,11 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con break; case "Star" : - inputs[4].setVisible(true); - inputs[5].setVisible(true); - inputs[7].setVisible(true); - inputs[9].setVisible(true); + inputs[ 4].setVisible(true); + inputs[ 5].setVisible(true); + inputs[ 7].setVisible(true); + inputs[ 9].setVisible(true); + inputs[36].setVisible(true); inputs[5].name = "Inner radius"; @@ -467,8 +471,8 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con break; case "Arc" : - inputs[5].setVisible(true); - inputs[8].setVisible(true); + inputs[ 5].setVisible(true); + inputs[ 8].setVisible(true); inputs[30].setVisible(true); inputs[5].name = "Inner radius"; @@ -499,6 +503,7 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con case "Cross" : inputs[ 9].setVisible(true); inputs[13].setVisible(true); + inputs[36].setVisible(true); inputs[13].name = "Outer radius"; @@ -588,6 +593,7 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con inputs[32].setVisible(true); inputs[33].setVisible(true); inputs[34].setVisible(true); + inputs[36].setVisible(true); shader_set_i("shape", 20); shader_set_2("point1", _data[32]); @@ -638,6 +644,7 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con shader_set_f("corner", _corner); shader_set_f("w_curve", _curve); shader_set_i("w_amount", array_length(_curve)); + shader_set_i("cornerShape", _data[36]); shader_set_2("center", _center); shader_set_2("scale", _scale ); diff --git a/shaders/sh_shape/sh_shape.fsh b/shaders/sh_shape/sh_shape.fsh index 73789290e..247c5be93 100644 --- a/shaders/sh_shape/sh_shape.fsh +++ b/shaders/sh_shape/sh_shape.fsh @@ -53,6 +53,7 @@ uniform vec2 point2; uniform float thickness; uniform vec4 bgColor; +uniform int cornerShape; #define PI 3.14159265359 #define TAU 6.283185307179586 @@ -164,17 +165,19 @@ float curveEval(in float[CURVE_MAX] curve, in int amo, in float _x) { float sdRegularPolygon(in vec2 p, in float r, in int n, in float ang ) { // these 4 lines can be precomputed for a given shape - float an = PI / float(n); + float an = PI / float(n); vec2 acs = vec2(cos(an), sin(an)); // reduce to first sector float bn = mod(atan(p.x, p.y) + PI - ang, 2.0 * an) - an; p = length(p) * vec2(cos(bn), abs(sin(bn))); - + // line sdf p -= r * acs; p.y += clamp( -p.y, 0.0, r * acs.y); - return length(p) * sign(p.x); + float c = cornerShape == 0? length(p) : abs(p.x) + abs(p.y); + + return c * sign(p.x); } // signed distance to a n-star polygon with external angle en @@ -192,7 +195,9 @@ float sdStar(in vec2 p, in float r, in int n, in float m, in float ang) { //m=[2 // line sdf p -= r * acs; p += ecs * clamp( -dot(p, ecs), 0.0, r * acs.y / ecs.y); - return length(p)*sign(p.x); + float c = cornerShape == 0? length(p) : abs(p.x) + abs(p.y); + + return c * sign(p.x); } // sca is the sin/cos of the orientation @@ -209,9 +214,15 @@ float sdArc( in vec2 p, in vec2 sca, in vec2 scb, in float ra, in float rb ) { } float sdSegment( in vec2 p, in vec2 a, in vec2 b ) { - vec2 pa = p - a, ba = b - a; - float h = clamp( dot(pa, ba) / dot(ba, ba), 0.0, 1.0 ); - return length( pa - ba * h ); + vec2 pa = p - a, ba = b - a; + float h = clamp( dot(pa, ba) / dot(ba, ba), 0.0, 1.0 ); + vec2 p2 = pa - ba * h; + if(cornerShape == 0) return length(p2); + + float rr = atan(ba.x, ba.y) + PI / 4.; + p2 *= mat2(cos(rr), -sin(rr), sin(rr), cos(rr)); + + return abs(p2.x) + abs(p2.y); } float sdRoundBox( in vec2 p, in vec2 b, in vec4 r ) { @@ -221,9 +232,15 @@ float sdRoundBox( in vec2 p, in vec2 b, in vec4 r ) { return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x; } +float sdCircle(in vec2 p) { + return length(p) - 1.; +} + float sdBox( in vec2 p, in vec2 b ) { - vec2 d = abs(p) - b; - return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0); + vec2 d = abs(p) - b; + float c = cornerShape == 0? length(max(d, 0.)) : max(d.x, 0.) + max(d.y, 0.); + + return c + min(max(d.x, d.y), 0.); } float sdTearDrop( vec2 p, float r1, float r2, float h ) { @@ -242,7 +259,9 @@ float sdCross( in vec2 p, in vec2 b, float r ) { vec2 q = p - b; float k = max(q.y, q.x); vec2 w = (k > 0.0) ? q : vec2(b.y - p.x, -k); - return sign(k) * length(max(w, 0.0)) + r; + + float c = cornerShape == 0? length(max(w, 0.)) : max(w.x, 0.) + max(w.y, 0.); + return sign(k) * c + r; } float sdVesica(vec2 p, float r, float d) { @@ -288,7 +307,6 @@ float sdGear(vec2 p, float s, int teeth, vec2 teethSize, float teethAngle, float _p = _p - vec2(1. - teeth_w, .0); s1 = sdRoundBox(_p, vec2(teeth_w, teeth_h), vec4(corner / 2., corner / 2., 0., 0.)); - // d = min(d, s1); d = smin(d, s1, irad); } @@ -302,7 +320,7 @@ float sdRhombus( in vec2 p, in vec2 b ) { float h = clamp( ndot(b - 2.0 * p,b) / dot(b, b), -1.0, 1.0 ); float d = length( p - 0.5 * b * vec2(1.0 - h, 1.0 + h) ); - + return d * sign( p.x * b.y + p.y * b.x - b.x * b.y ); } @@ -423,7 +441,8 @@ float sdHalf(vec2 p, vec2 point, float angle) { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void main() { - vec2 coord = (v_vTexcoord - center) * mat2(cos(rotation), -sin(rotation), sin(rotation), cos(rotation)) / scale; + vec2 coordUni = (v_vTexcoord - center) * mat2(cos(rotation), -sin(rotation), sin(rotation), cos(rotation)); + vec2 coord = coordUni / scale; vec2 ratio = dimension / dimension.y; float d; @@ -432,22 +451,10 @@ void main() { if(tile == 1) coord = mod(coord + 1., 2.) - 1.; - if(shape == 0) { - d = sdBox( (v_vTexcoord - center) * mat2(cos(rotation), -sin(rotation), sin(rotation), cos(rotation)) * ratio, (scale * ratio - corner)); - d -= corner; - - } else if(shape == 1) { - d = length(coord) - 1.; - - } else if(shape == 2) { - d = sdRegularPolygon( coord, 0.9 - corner, sides, angle ); - d -= corner; - - } else if(shape == 3) { - d = sdStar( coord, 0.9 - corner, sides, 2. + inner * (float(sides) - 2.), angle ); - d -= corner; - - } + if(shape == 0) { d = sdBox( coordUni * ratio, (scale * ratio - corner)) - corner; } + else if(shape == 1) { d = sdCircle( coord); } + else if(shape == 2) { d = sdRegularPolygon(coord, 0.9 - corner, sides, angle ) - corner; } + else if(shape == 3) { d = sdStar( coord, 0.9 - corner, sides, 2. + inner * (float(sides) - 2.), angle ) - corner; } else if(shape == 4) { d = sdArc( coord, vec2(sin(angle), cos(angle)), angle_range, 1. - inner, inner ); } else if(shape == 5) { d = sdTearDrop( coord + vec2(0., 0.5), stRad, edRad, 1. ); } else if(shape == 6) { d = sdCross( coord, vec2(1. + corner, outer), corner ); }