mirror of
https://github.com/Ttanasart-pt/Pixel-Composer.git
synced 2024-12-28 16:06:20 +01:00
424 lines
No EOL
14 KiB
Text
424 lines
No EOL
14 KiB
Text
function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
|
|
name = "Path Shape";
|
|
setDimension(96, 48);
|
|
|
|
newInput(0, nodeValue_Vec2("Position", self, [ .5, .5 ]))
|
|
.setUnitRef(function() /*=>*/ {return DEF_SURF}, VALUE_UNIT.reference);
|
|
|
|
newInput(1, nodeValue_Vec2("Half Size", self, [ .5, .5 ]))
|
|
.setUnitRef(function() /*=>*/ {return DEF_SURF}, VALUE_UNIT.reference);
|
|
|
|
newInput(2, nodeValue_Rotation("Rotation", self, 0));
|
|
|
|
shapeScroll = [
|
|
new scrollItem("Rectangle", s_node_shape_type, 0),
|
|
new scrollItem("Trapezoid", s_node_shape_type, 2),
|
|
new scrollItem("Parallelogram", s_node_shape_type, 3),
|
|
-1,
|
|
new scrollItem("Ellipse", s_node_shape_type, 5),
|
|
new scrollItem("Arc", s_node_shape_type, 6),
|
|
new scrollItem("Squircle", s_node_shape_type, 11),
|
|
-1,
|
|
new scrollItem("Polygon", s_node_shape_type, 12),
|
|
new scrollItem("Star", s_node_shape_type, 13),
|
|
-1,
|
|
new scrollItem("Line", s_node_shape_type, 16),
|
|
new scrollItem("Curve", s_shape_curve, 0),
|
|
];
|
|
newInput(3, nodeValue_Enum_Scroll("Shape", self, 0, shapeScroll));
|
|
|
|
newInput(4, nodeValue_Float("Skew", self, .5))
|
|
.setDisplay(VALUE_DISPLAY.slider, { range: [ -1, 1, 0.01] });
|
|
|
|
newInput(5, nodeValue_Rotation_Range("Angle Range", self, [ 0, 90 ]));
|
|
|
|
newInput(6, nodeValue_Float("Factor", self, 4));
|
|
|
|
newInput(7, nodeValue_Int("Sides", self, 4));
|
|
|
|
newInput(8, nodeValue_Float("Inner Radius", self, .5));
|
|
|
|
newOutput(0, nodeValue_Output("Path data", self, VALUE_TYPE.pathnode, self));
|
|
|
|
input_display_list = [
|
|
["Transform", false], 0, 2, 1,
|
|
["Shape", false], 3, 4, 5, 6, 7, 8,
|
|
];
|
|
|
|
points = [];
|
|
lengths = [];
|
|
lengthAccs = [];
|
|
lengthTotal = 0;
|
|
boundary = new BoundingBox();
|
|
cached_pos = ds_map_create();
|
|
|
|
loop = true;
|
|
shape = 0;
|
|
posx = 0; posy = 0;
|
|
scax = 1; scay = 1;
|
|
rot = 0;
|
|
|
|
pa1 = 0;
|
|
pa2x = 0; pa2y = 0;
|
|
pa3 = 0;
|
|
|
|
preview_surf = noone;
|
|
|
|
static getLineCount = function() /*=>*/ {return 1};
|
|
static getSegmentCount = function() /*=>*/ {return array_length(lengths)};
|
|
static getBoundary = function() /*=>*/ {return boundary};
|
|
static getLength = function() /*=>*/ {return lengthTotal};
|
|
static getAccuLength = function() /*=>*/ {return lengthAccs};
|
|
|
|
static getPointRatio = function(_rat, _ind = 0, out = undefined) {
|
|
if(out == undefined) out = new __vec2();
|
|
_rat = frac(_rat);
|
|
|
|
switch(shapeScroll[shape].name) {
|
|
case "Rectangle" :
|
|
case "Trapezoid" :
|
|
case "Parallelogram" :
|
|
if(_rat <= .25) {
|
|
var r = _rat * 4;
|
|
out.x = lerp(points[0][0], points[1][0], r);
|
|
out.y = lerp(points[0][1], points[1][1], r);
|
|
} else if(_rat <= .50) {
|
|
var r = (_rat - .25) * 4;
|
|
out.x = lerp(points[1][0], points[2][0], r);
|
|
out.y = lerp(points[1][1], points[2][1], r);
|
|
} else if(_rat <= .75) {
|
|
var r = (_rat - .50) * 4;
|
|
out.x = lerp(points[2][0], points[3][0], r);
|
|
out.y = lerp(points[2][1], points[3][1], r);
|
|
} else {
|
|
var r = (_rat - .75) * 4;
|
|
out.x = lerp(points[3][0], points[0][0], r);
|
|
out.y = lerp(points[3][1], points[0][1], r);
|
|
}
|
|
break;
|
|
|
|
case "Ellipse" :
|
|
var a = 360 * _rat;
|
|
out.x = posx + lengthdir_x(scax, a);
|
|
out.y = posy + lengthdir_y(scay, a);
|
|
break;
|
|
|
|
case "Arc" :
|
|
var a = lerp_float_angle(pa2x, pa2y, _rat);
|
|
out.x = posx + lengthdir_x(scax, a);
|
|
out.y = posy + lengthdir_y(scay, a);
|
|
break;
|
|
|
|
case "Squircle" :
|
|
var a = 360 * _rat;
|
|
var r = 1 / power(power(dcos(a % 90), pa3) + power(dsin(a % 90), pa3), 1 / pa3);
|
|
|
|
out.x = posx + lengthdir_x(scax * r, a);
|
|
out.y = posy + lengthdir_y(scay * r, a);
|
|
break;
|
|
|
|
case "Polygon" :
|
|
case "Star" :
|
|
case "Line" :
|
|
case "Curve" :
|
|
return getPointDistance(_rat * lengthTotal, _ind, out);
|
|
|
|
}
|
|
|
|
point_vec2_rotate(out, posx, posy, rot);
|
|
return out;
|
|
}
|
|
|
|
static getPointDistance = function(_dist, _ind = 0, out = undefined) {
|
|
if(out == undefined) out = new __vec2();
|
|
_dist = safe_mod(_dist, lengthTotal);
|
|
|
|
var _d = _dist, l;
|
|
var np = array_length(points);
|
|
|
|
for( var i = 0, n = array_length(lengths); i < n; i++ ) {
|
|
l = lengths[i];
|
|
if(_d > l) { _d -= l; continue; }
|
|
|
|
var p0 = points[(i + 0) % np];
|
|
var p1 = points[(i + 1) % np];
|
|
|
|
out.x = lerp(p0[0], p1[0], _d / l);
|
|
out.y = lerp(p0[1], p1[1], _d / l);
|
|
break;
|
|
}
|
|
|
|
point_vec2_rotate(out, posx, posy, rot);
|
|
return out;
|
|
}
|
|
|
|
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
|
|
if(array_empty(points)) return;
|
|
|
|
var ox = _x + points[0][0] * _s, x0 = ox;
|
|
var oy = _y + points[0][1] * _s, y0 = oy;
|
|
var nx, ny;
|
|
|
|
draw_set_color(COLORS._main_accent);
|
|
for( var i = 1, n = array_length(points); i < n; i++ ) {
|
|
nx = _x + points[i][0] * _s;
|
|
ny = _y + points[i][1] * _s;
|
|
|
|
draw_line(ox, oy, nx, ny);
|
|
|
|
ox = nx;
|
|
oy = ny;
|
|
}
|
|
|
|
if(loop) draw_line(ox, oy, x0, y0);
|
|
|
|
var _px = _x + posx * _s;
|
|
var _py = _y + posy * _s;
|
|
|
|
var h = inputs[0].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); hover &= !h;
|
|
var h = inputs[2].drawOverlay(hover, active, _px, _py, _s, _mx, _my, _snx, _sny); hover &= !h;
|
|
var h = inputs[1].drawOverlay(hover, active, _px, _py, _s, _mx, _my, _snx, _sny); hover &= !h;
|
|
|
|
}
|
|
|
|
static update = function(frame = CURRENT_FRAME) {
|
|
var _pos = inputs[0].getValue();
|
|
var _rot = inputs[2].getValue();
|
|
var _sca = inputs[1].getValue();
|
|
var _pa1 = inputs[4].getValue();
|
|
var _aran = inputs[5].getValue();
|
|
var _pa3 = inputs[6].getValue();
|
|
var _sid = inputs[7].getValue();
|
|
var _inn = inputs[8].getValue();
|
|
|
|
shape = inputs[3].getValue();
|
|
posx = _pos[0];
|
|
posy = _pos[1];
|
|
rot = _rot;
|
|
scax = _sca[0];
|
|
scay = _sca[1];
|
|
|
|
pa1 = _pa1;
|
|
pa2x = _aran[0];
|
|
pa2y = _aran[1];
|
|
pa3 = _pa3;
|
|
|
|
var ox, oy, nx, ny, x0, y0;
|
|
|
|
inputs[4].setVisible(false);
|
|
inputs[5].setVisible(false);
|
|
inputs[6].setVisible(false);
|
|
inputs[7].setVisible(false);
|
|
inputs[8].setVisible(false);
|
|
|
|
switch(shapeScroll[shape].name) {
|
|
case "Rectangle" :
|
|
loop = true;
|
|
points = [
|
|
[ posx - scax, posy - scay ],
|
|
[ posx + scax, posy - scay ],
|
|
[ posx + scax, posy + scay ],
|
|
[ posx - scax, posy + scay ],
|
|
];
|
|
break;
|
|
|
|
case "Trapezoid" :
|
|
loop = true;
|
|
inputs[4].setVisible(true);
|
|
|
|
points = [
|
|
[ posx - scax * saturate(1 - _pa1), posy - scay ],
|
|
[ posx + scax * saturate(1 - _pa1), posy - scay ],
|
|
[ posx + scax * saturate(1 + _pa1), posy + scay ],
|
|
[ posx - scax * saturate(1 + _pa1), posy + scay ],
|
|
];
|
|
break;
|
|
|
|
case "Parallelogram" :
|
|
loop = true;
|
|
inputs[4].setVisible(true);
|
|
|
|
points = [
|
|
[ posx - scax * saturate(1 - _pa1), posy - scay ],
|
|
[ posx + scax * saturate(1 + _pa1), posy - scay ],
|
|
[ posx + scax * saturate(1 - _pa1), posy + scay ],
|
|
[ posx - scax * saturate(1 + _pa1), posy + scay ],
|
|
];
|
|
break;
|
|
|
|
case "Ellipse" :
|
|
loop = true;
|
|
var _st = 64;
|
|
var _as = 360 / _st;
|
|
points = array_create(_st);
|
|
|
|
for( var i = 0; i < _st; i++ ) {
|
|
nx = posx + lengthdir_x(scax, _as * i);
|
|
ny = posy + lengthdir_y(scay, _as * i);
|
|
points[i] = [ nx, ny ];
|
|
}
|
|
break;
|
|
|
|
case "Arc" :
|
|
loop = false;
|
|
inputs[5].setVisible(true);
|
|
|
|
var _st = 64;
|
|
var _as = 1 / (_st - 1);
|
|
points = array_create(_st);
|
|
|
|
for( var i = 0; i < _st; i++ ) {
|
|
var a = lerp_float_angle(_aran[0], _aran[1], i * _as);
|
|
nx = posx + lengthdir_x(scax, a);
|
|
ny = posy + lengthdir_y(scay, a);
|
|
points[i] = [ nx, ny ];
|
|
}
|
|
break;
|
|
|
|
case "Squircle" :
|
|
loop = true;
|
|
inputs[6].setVisible(true);
|
|
|
|
var _st = 64;
|
|
var _as = 360 / _st;
|
|
points = array_create(_st);
|
|
|
|
for( var i = 0; i < _st; i++ ) {
|
|
var a = _as * i;
|
|
var r = 1 / power(power(dcos(a % 90), pa3) + power(dsin(a % 90), pa3), 1 / pa3);
|
|
|
|
nx = posx + lengthdir_x(scax * r, a);
|
|
ny = posy + lengthdir_y(scay * r, a);
|
|
points[i] = [ nx, ny ];
|
|
}
|
|
break;
|
|
|
|
case "Polygon" :
|
|
loop = true;
|
|
inputs[7].setVisible(true);
|
|
|
|
var _st = _sid;
|
|
var _as = 360 / _st;
|
|
points = array_create(_st);
|
|
|
|
for( var i = 0; i < _st; i++ ) {
|
|
nx = posx + lengthdir_x(scax, _as * i);
|
|
ny = posy + lengthdir_y(scay, _as * i);
|
|
points[i] = [ nx, ny ];
|
|
}
|
|
break;
|
|
|
|
case "Star" :
|
|
loop = true;
|
|
inputs[7].setVisible(true);
|
|
inputs[8].setVisible(true);
|
|
|
|
var _st = _sid;
|
|
var _as = 360 / _st;
|
|
points = array_create(_st * 2);
|
|
|
|
for( var i = 0; i < _st; i++ ) {
|
|
nx = posx + lengthdir_x(scax, _as * i);
|
|
ny = posy + lengthdir_y(scay, _as * i);
|
|
points[i * 2 + 0] = [ nx, ny ];
|
|
|
|
nx = posx + lengthdir_x(scax * _inn, _as * i + _as / 2);
|
|
ny = posy + lengthdir_y(scay * _inn, _as * i + _as / 2);
|
|
points[i * 2 + 1] = [ nx, ny ];
|
|
}
|
|
break;
|
|
|
|
case "Line":
|
|
loop = false;
|
|
points = [
|
|
[ posx - scax, posy ],
|
|
[ posx + scax, posy ],
|
|
];
|
|
break;
|
|
|
|
case "Curve":
|
|
loop = false;
|
|
inputs[6].setVisible(true);
|
|
|
|
var _st = 64;
|
|
var _as = 180 / (_st - 1);
|
|
var _x0 = posx - scax;
|
|
var _x1 = posx + scax;
|
|
var _yy = posy;
|
|
|
|
points = array_create(_st);
|
|
for( var i = 0; i < _st; i++ ) {
|
|
points[i] = [
|
|
lerp(_x0, _x1, i / (_st - 1)),
|
|
_yy + dsin(i * _as) * pa3,
|
|
]
|
|
}
|
|
break;
|
|
}
|
|
|
|
var n = array_length(points);
|
|
lengths = array_create(n + loop);
|
|
|
|
if(n) {
|
|
for( var i = 0; i < n; i++ ) {
|
|
nx = points[i][0];
|
|
ny = points[i][1];
|
|
|
|
if(i) lengths[i - 1] = point_distance(ox, oy, nx, ny);
|
|
else { x0 = nx; y0 = ny; }
|
|
|
|
ox = nx;
|
|
oy = ny;
|
|
}
|
|
|
|
if(loop) lengths[n - 1] = point_distance(ox, oy, x0, y0);
|
|
}
|
|
|
|
var _len = array_length(lengths);
|
|
lengthTotal = 0;
|
|
lengthAccs = array_create(_len);
|
|
|
|
for( var i = 0; i < _len; i++ ) {
|
|
lengthTotal += lengths[i];
|
|
lengthAccs[i] = lengthTotal;
|
|
}
|
|
|
|
boundary = new BoundingBox(posx - scax, posy - scay, posx + scax, posy + scay);
|
|
|
|
preview_surf = surface_verify(preview_surf, 128, 128);
|
|
surface_set_target(preview_surf);
|
|
DRAW_CLEAR
|
|
|
|
var ox, x0;
|
|
var oy, y0;
|
|
var nx, ny;
|
|
var xx = posx - scax;
|
|
var yy = posy - scay;
|
|
var ww = scax * 2;
|
|
var hh = scay * 2;
|
|
draw_set_color(COLORS._main_accent);
|
|
|
|
if(array_length(points)) {
|
|
for( var i = 0, n = array_length(points); i < n; i++ ) {
|
|
nx = 4 + (points[i][0] - xx) / ww * 120;
|
|
ny = 4 + (points[i][1] - yy) / hh * 120;
|
|
|
|
if(i) draw_line_width(ox, oy, nx, ny, 8);
|
|
else { x0 = nx; y0 = ny; }
|
|
|
|
ox = nx;
|
|
oy = ny;
|
|
}
|
|
|
|
if(loop) draw_line_width(ox, oy, x0, y0, 8);
|
|
}
|
|
surface_reset_target();
|
|
}
|
|
|
|
static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) {
|
|
var bbox = drawGetBbox(xx, yy, _s);
|
|
draw_surface_bbox(preview_surf, bbox);
|
|
}
|
|
|
|
static getPreviewBoundingBox = function() { return BBOX().fromBoundingBox(boundary); }
|
|
} |