mirror of
https://github.com/Ttanasart-pt/Pixel-Composer.git
synced 2024-12-30 17:06:27 +01:00
266 lines
No EOL
6.6 KiB
Text
266 lines
No EOL
6.6 KiB
Text
// 2024-04-26 14:57:55
|
|
function Node_Path_Bridge(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
|
|
name = "Bridge Path";
|
|
w = 96;
|
|
|
|
inputs[| 0] = nodeValue("Path", self, JUNCTION_CONNECT.input, VALUE_TYPE.pathnode, noone)
|
|
.setVisible(true, true)
|
|
.rejectArray();
|
|
|
|
inputs[| 1] = nodeValue("Amount", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 4)
|
|
.rejectArray();
|
|
|
|
inputs[| 2] = nodeValue("Smooth", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false)
|
|
.rejectArray();
|
|
|
|
outputs[| 0] = nodeValue("Path", self, JUNCTION_CONNECT.output, VALUE_TYPE.pathnode, self);
|
|
|
|
input_display_list = [ 0,
|
|
["Bridge", false], 1, 2,
|
|
]
|
|
|
|
cached_pos = ds_map_create();
|
|
|
|
#region ---- path ----
|
|
anchors = [];
|
|
controls = [];
|
|
lengths = [];
|
|
lengthAccs = [];
|
|
boundary = [];
|
|
lengthTotal = [];
|
|
|
|
cached_pos = ds_map_create();
|
|
#endregion
|
|
|
|
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region
|
|
var _path = getInputData(0);
|
|
var _smt = getInputData(2);
|
|
if(_path && struct_has(_path, "drawOverlay")) _path.drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
|
|
|
|
var _amo = array_length(anchors);
|
|
var ox, oy, nx, ny;
|
|
var _p = new __vec2();
|
|
|
|
draw_set_color(COLORS._main_icon);
|
|
for( var i = 0, n = _amo; i < n; i++ ) {
|
|
var _a = anchors[i];
|
|
|
|
if(_smt) {
|
|
var _smp = 1 / 32;
|
|
for( var j = 0; j <= 1; j += _smp ) {
|
|
_p = getPointRatio(j, i, _p);
|
|
|
|
nx = _x + _p.x * _s;
|
|
ny = _y + _p.y * _s;
|
|
|
|
if(j > 0) draw_line_width(ox, oy, nx, ny, 3);
|
|
|
|
ox = nx;
|
|
oy = ny;
|
|
}
|
|
} else {
|
|
for( var j = 0, m = array_length(_a); j < m; j++ ) {
|
|
nx = _x + _a[j][0] * _s;
|
|
ny = _y + _a[j][1] * _s;
|
|
|
|
if(j) draw_line_width(ox, oy, nx, ny, 3);
|
|
|
|
ox = nx;
|
|
oy = ny;
|
|
}
|
|
}
|
|
}
|
|
} #endregion
|
|
|
|
static getLineCount = function() { return getInputData(1); }
|
|
|
|
static getSegmentCount = function(ind = 0) { return array_safe_length(array_safe_get_fast(anchors, ind)); }
|
|
|
|
static getLength = function(ind = 0) { return array_safe_get_fast(lengths, ind); }
|
|
|
|
static getAccuLength = function(ind = 0) { return array_safe_get_fast(lengthAccs, ind); }
|
|
|
|
static getBoundary = function(ind = 0) { return array_safe_get_fast(boundary, ind); }
|
|
|
|
static getPointRatio = function(_rat, ind = 0, out = undefined) { return getPointDistance(clamp(_rat, 0, 1) * getLength(ind), ind, out); }
|
|
|
|
static getPointDistance = function(_dist, ind = 0, out = undefined) { #region
|
|
if(out == undefined) out = new __vec2(); else { out.x = 0; out.y = 0; }
|
|
|
|
var _cKey = $"{_dist},{ind}";
|
|
if(ds_map_exists(cached_pos, _cKey)) {
|
|
var _p = cached_pos[? _cKey];
|
|
out.x = _p.x;
|
|
out.y = _p.y;
|
|
return out;
|
|
}
|
|
|
|
var _smt = getInputData(2);
|
|
var _a = anchors[ind];
|
|
var _la = lengthAccs[ind];
|
|
|
|
if(_dist == 0) {
|
|
var _p = _a[0];
|
|
out.x = _p[0];
|
|
out.y = _p[1];
|
|
|
|
cached_pos[? _cKey] = out.clone();
|
|
return out;
|
|
}
|
|
|
|
var _ind = 0;
|
|
var n = array_length(_la);
|
|
|
|
for(; _ind < n; _ind++ ) if(_dist < _la[_ind]) break;
|
|
|
|
if(_ind >= n) {
|
|
var _p = _a[_ind];
|
|
out.x = _p[0];
|
|
out.y = _p[1];
|
|
|
|
cached_pos[? _cKey] = out.clone();
|
|
return out;
|
|
}
|
|
|
|
var _d = _ind == 0? _dist : _dist - _la[_ind - 1];
|
|
var _rat = _d / (_la[_ind] - (_ind == 0? 0 : _la[_ind - 1]));
|
|
var p0 = _a[_ind];
|
|
var p1 = _a[_ind + 1];
|
|
|
|
if(_smt) {
|
|
var _cnt = controls[ind];
|
|
var _c0x = _cnt[_ind][0];
|
|
var _c0y = _cnt[_ind][1];
|
|
var _c1x = _cnt[_ind][2];
|
|
var _c1y = _cnt[_ind][3];
|
|
|
|
var _p = eval_bezier(_rat, p0[0], p0[1], p1[0], p1[1], _c0x, _c0y, _c1x, _c1y);
|
|
out.x = _p[0];
|
|
out.y = _p[1];
|
|
|
|
} else {
|
|
out.x = lerp(p0[0], p1[0], _rat);
|
|
out.y = lerp(p0[1], p1[1], _rat);
|
|
}
|
|
|
|
cached_pos[? _cKey] = out.clone();
|
|
|
|
return out;
|
|
} #endregion
|
|
|
|
static update = function() { #region
|
|
ds_map_clear(cached_pos);
|
|
|
|
var _path = getInputData(0);
|
|
var _amo = getInputData(1);
|
|
var _smt = getInputData(2);
|
|
|
|
if(_path == noone) return;
|
|
|
|
#region bridge
|
|
var _lines = _path.getLineCount();
|
|
var _p = new __vec2();
|
|
var _rat;
|
|
|
|
anchors = array_create(_amo);
|
|
lengths = array_create(_amo);
|
|
lengthAccs = array_create(_amo);
|
|
|
|
for( var i = 0; i < _amo; i++ ) {
|
|
var _a = array_create(_lines);
|
|
_rat = _amo == 1? 0.5 : i / (_amo - 1);
|
|
|
|
for( var j = 0; j < _lines; j++ ) {
|
|
_p = _path.getPointRatio(clamp(_rat, 0, 0.999), j, _p);
|
|
_a[j] = [ _p.x, _p.y ];
|
|
}
|
|
|
|
anchors[i] = _a;
|
|
|
|
if(_smt) {
|
|
var _cnt = array_create(_lines - 1);
|
|
|
|
for( var j = 0; j < _lines - 1; j++ ) _cnt[j] = [ 0, 0, 0, 0 ];
|
|
|
|
_cnt[0] = [ _a[0][0], _a[ 0][1], _a[0][0], _a[0][1] ];
|
|
_cnt[_lines - 2] = [ _a[_lines - 1][0], _a[_lines - 1][1], _a[_lines - 1][0], _a[_lines - 1][1] ];
|
|
|
|
for( var j = 1; j < _lines - 1; j++ ) {
|
|
var _a0 = _a[j - 1];
|
|
var _a1 = _a[j];
|
|
var _a2 = _a[j + 1];
|
|
|
|
var _dr = point_direction(_a0[0], _a0[1], _a2[0], _a2[1]);
|
|
var _ds0 = point_distance(_a1[0], _a1[1], _a0[0], _a0[1]) / 2;
|
|
var _ds2 = point_distance(_a1[0], _a1[1], _a2[0], _a2[1]) / 2;
|
|
|
|
var c0x = _a1[0] - lengthdir_x(_ds0, _dr);
|
|
var c0y = _a1[1] - lengthdir_y(_ds0, _dr);
|
|
var c1x = _a1[0] + lengthdir_x(_ds2, _dr);
|
|
var c1y = _a1[1] + lengthdir_y(_ds2, _dr);
|
|
|
|
_cnt[j - 1][2] = c0x;
|
|
_cnt[j - 1][3] = c0y;
|
|
_cnt[j][0] = c1x;
|
|
_cnt[j][1] = c1y;
|
|
}
|
|
|
|
controls[i] = _cnt;
|
|
|
|
var _l = 0, _la = [];
|
|
var ox, oy, nx, ny;
|
|
|
|
for( var j = 0; j < _lines - 1; j++ ) {
|
|
var _a0 = _a[j];
|
|
var _a1 = _a[j + 1];
|
|
var _c0x = _cnt[j][0];
|
|
var _c0y = _cnt[j][1];
|
|
var _c1x = _cnt[j][2];
|
|
var _c1y = _cnt[j][3];
|
|
|
|
var _smp = 1 / 32;
|
|
var _ll = 0;
|
|
|
|
for( var k = 0; k < 1; k += _smp ) {
|
|
var _p = eval_bezier(k, _a0[0], _a0[1], _a1[0], _a1[1], _c0x, _c0y, _c1x, _c1y);
|
|
nx = _p[0];
|
|
ny = _p[1];
|
|
|
|
if(k > 0) _ll += point_distance(ox, oy, nx, ny);
|
|
|
|
ox = nx;
|
|
oy = ny;
|
|
}
|
|
|
|
_l += _ll;
|
|
array_push(_la, _l);
|
|
}
|
|
|
|
lengths[i] = _l;
|
|
lengthAccs[i] = _la;
|
|
|
|
} else {
|
|
var _l = 0, _la = [];
|
|
var ox, oy, nx, ny;
|
|
|
|
for( var j = 0, m = array_length(_a); j < m; j++ ) {
|
|
nx = _a[j][0];
|
|
ny = _a[j][1];
|
|
|
|
if(j) {
|
|
var d = point_distance(ox, oy, nx, ny);
|
|
_l += d;
|
|
array_push(_la, _l);
|
|
}
|
|
|
|
ox = nx;
|
|
oy = ny;
|
|
}
|
|
|
|
lengths[i] = _l;
|
|
lengthAccs[i] = _la;
|
|
}
|
|
}
|
|
#endregion
|
|
} #endregion
|
|
} |