From aa93cc5bf240f7099d7556f7b646ad7cad1d32bf Mon Sep 17 00:00:00 2001 From: Tanasart Date: Tue, 16 Jul 2024 09:29:46 +0700 Subject: [PATCH] - [Bake Path] Fix error when setting segment length to higher than 1. --- PixelComposer.resource_order | 1 + PixelComposer.yyp | 1 + scripts/array_functions/array_functions.gml | 6 +- scripts/node_line/node_line.gml | 732 ++++++++++-------- scripts/node_path_bake/node_path_bake.gml | 21 +- .../node_segment_filter.gml | 42 + .../node_segment_filter.yy | 13 + 7 files changed, 465 insertions(+), 351 deletions(-) create mode 100644 scripts/node_segment_filter/node_segment_filter.gml create mode 100644 scripts/node_segment_filter/node_segment_filter.yy diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index 251aac02b..12e70a52d 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -1047,6 +1047,7 @@ {"name":"node_scale","order":8,"path":"scripts/node_scale/node_scale.yy",}, {"name":"node_scatter_points","order":6,"path":"scripts/node_scatter_points/node_scatter_points.yy",}, {"name":"node_scatter","order":6,"path":"scripts/node_scatter/node_scatter.yy",}, + {"name":"node_segment_filter","order":21,"path":"scripts/node_segment_filter/node_segment_filter.yy",}, {"name":"node_sequence_anim","order":5,"path":"scripts/node_sequence_anim/node_sequence_anim.yy",}, {"name":"node_shadow_cast","order":14,"path":"scripts/node_shadow_cast/node_shadow_cast.yy",}, {"name":"node_shadow","order":13,"path":"scripts/node_shadow/node_shadow.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index 795b6f1a1..f017e1860 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -1457,6 +1457,7 @@ {"id":{"name":"node_scatter_points","path":"scripts/node_scatter_points/node_scatter_points.yy",},}, {"id":{"name":"node_scatter","path":"scripts/node_scatter/node_scatter.yy",},}, {"id":{"name":"node_sdf","path":"scripts/node_sdf/node_sdf.yy",},}, + {"id":{"name":"node_segment_filter","path":"scripts/node_segment_filter/node_segment_filter.yy",},}, {"id":{"name":"node_seperate_shape","path":"scripts/node_seperate_shape/node_seperate_shape.yy",},}, {"id":{"name":"node_sequence_anim","path":"scripts/node_sequence_anim/node_sequence_anim.yy",},}, {"id":{"name":"node_shadow_cast","path":"scripts/node_shadow_cast/node_shadow_cast.yy",},}, diff --git a/scripts/array_functions/array_functions.gml b/scripts/array_functions/array_functions.gml index ede08bb8e..a65719a4b 100644 --- a/scripts/array_functions/array_functions.gml +++ b/scripts/array_functions/array_functions.gml @@ -135,10 +135,8 @@ function array_overlap(arr0, arr1) { }); } -function array_empty(arr) { - INLINE - return is_array(arr) && array_length(arr) == 0; -} +function array_empty(arr) { INLINE return is_array(arr) && array_length(arr) == 0; } +function array_invalid(arr) { INLINE return !is_array(arr) || array_length(arr) == 0; } function array_find(arr, val) { INLINE diff --git a/scripts/node_line/node_line.gml b/scripts/node_line/node_line.gml index 81967d472..2f8845ca1 100644 --- a/scripts/node_line/node_line.gml +++ b/scripts/node_line/node_line.gml @@ -67,9 +67,16 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons inputs[| 26] = nodeValue("Clamp range", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false ); + inputs[| 27] = nodeValue("Data Type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "None", "Path", "Segments" ]); + + inputs[| 28] = nodeValue("Segments", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [[]]) + .setDisplay(VALUE_DISPLAY.vector) + .setArrayDepth(1); + input_display_list = [ ["Output", true], 0, 1, - ["Line data", false], 6, 7, 19, 2, 20, + ["Line data", false], 27, 6, 7, 28, 19, 2, 20, ["Line settings", false], 17, 3, 11, 12, 8, 25, 9, 26, 13, 14, ["Wiggle", false], 4, 5, ["Render", false], 10, 24, 15, 16, @@ -87,7 +94,7 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons attribute_surface_depth(); attribute_interpolation(); - static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { draw_set_color(COLORS._main_accent); for( var i = 0, n = array_length(lines); i < n; i++ ) { var points = lines[i]; @@ -109,9 +116,9 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons // draw_circle(x0, y0, 4, false); } } - } #endregion + } - static step = function() { #region + static step = function() { var px = !getInputData(17); var _tex = inputs[| 18].value_from != noone; var _flen = getInputData(19); @@ -128,13 +135,19 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons inputs[| 2].setVisible(!_flen); inputs[| 20].setVisible( _flen); - } #endregion + + var _dtype = getInputData(27); + + inputs[| 6].setVisible(_dtype == 0); + inputs[| 7].setVisible(_dtype == 1, _dtype == 1); + inputs[| 28].setVisible(_dtype == 2, _dtype == 2); + } - static onValueUpdate = function(index = 0) { #region + static onValueUpdate = function(index = 0) { if(index == 11) ds_map_clear(widthMap); - } #endregion + } - static processData = function(_outData, _data, _output_index, _array_index) { #region + static processData = function(_outData, _data, _output_index, _array_index) { #region data var _dim = _data[0]; var _bg = _data[1]; @@ -142,7 +155,7 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons var _wid = _data[3]; var _wig = _data[4]; var _sed = _data[5]; - var _ang = _data[6] % 360; + var _ang = _data[6]; var _pat = _data[7]; var _ratio = _data[8]; var _shift = _data[9]; @@ -156,6 +169,7 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons var _colP = _data[15]; var _colW = _data[16]; var _1px = _data[17]; + var _text = _data[18]; var _fixL = _data[19]; var _segL = _data[20]; @@ -168,8 +182,16 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons var _colb = _data[24]; var _ratInv = _data[25]; var _clamp = _data[26]; + + var _dtype = _data[27]; + var _segs = _data[28]; #endregion + /////// Guard clauses + if(_dtype == 1 && _pat == noone) return _outData; + if(_dtype == 2 && (array_invalid(_segs) || array_invalid(_segs[0]))) return _outData; + + if(IS_FIRST_FRAME || inputs[| 11].is_anim) ds_map_clear(widthMap); @@ -182,16 +204,8 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons var _rtStr = min(_rangeMin, _rangeMax); var _rtMax = max(_rangeMin, _rangeMax); - var _use_path = is_struct(_pat); - var _useTex = inputs[| 18].value_from != noone; - if(_useTex) { - _cap = false; - _1px = false; - } - - if(_ang < 0) _ang = 360 + _ang; - - inputs[| 6].setVisible(!_use_path); + var _useTex = is_surface(_text); + if(_useTex) { _cap = false; _1px = false; } random_set_seed(_sed); var _sedIndex = 0; @@ -204,214 +218,379 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons var _ow, _nw, _oa, _na, _oc, _nc, _owg, _nwg; var _pathData = []; - if(_use_path) { #region - var lineLen = 1; - if(struct_has(_pat, "getLineCount")) - lineLen = _pat.getLineCount(); - if(struct_has(_pat, "getPathData")) - _pathData = _pat.getPathData(); + switch(_dtype) { + case 0 : + _ang = (_ang % 360 + 360) % 360; - lines = array_verify(lines, lineLen); - var _lineAmo = 0; - - if(_rtMax > 0) - for( var i = 0; i < lineLen; i++ ) { - var _useDistance = _fixL && struct_has(_pat, "getLength"); - var _pathLength = _useDistance? _pat.getLength(i) : 1; - if(_pathLength == 0) continue; - - var _pathStr = _rtStr; - var _pathEnd = _rtMax; - - var _stepLen = min(_pathEnd, 1 / _seg); // Distance to move per step - if(_stepLen <= 0.00001) continue; - - var _total = _pathEnd; // Length remaining - var _total_prev = _total; // Use to prevent infinite loop - var _freeze = 0; // Use to prevent infinite loop - - var _prog_curr = _clamp? _shift : frac(_shift); // Pointer to the current position - var _prog_next = 0; - var _prog = _prog_curr + 1; // Record previous position to delete from _total - var _prog_total = 0; // Record the distance the pointer has moved so far - var points = []; - var pointAmo = 0; - var wght; - var _pathPng; + var x0, y0, x1, y1; + var _0 = point_rectangle_overlap(_dim[0], _dim[1], (_ang + 180) % 360); + var _1 = point_rectangle_overlap(_dim[0], _dim[1], _ang); + x0 = _0[0]; y0 = _0[1]; + x1 = _1[0]; y1 = _1[1]; - if(_useDistance) { - _pathStr *= _pathLength; - _pathEnd *= _pathLength; - _stepLen = min(_segL, _pathEnd); + var _l = point_distance(x0, y0, x1, y1); + var _d = point_direction(x0, y0, x1, y1); + var _od = _d, _nd = _d; + + var ww = _rtMax / _seg; + var _total = _rtMax; + var _prog_curr = frac(_shift) - ww; + var _prog = _prog_curr + 1; + var _prog_total = 0; + var points = []; + + while(_total > 0) { + if(_prog_curr >= 1) _prog_curr = 0; + else _prog_curr = min(_prog_curr + min(_total, ww), 1); + _prog_total += min(_total, ww); - _total *= _pathLength; - _total_prev = _total; + _nx = x0 + lengthdir_x(_l * _prog_curr, _d); + _ny = y0 + lengthdir_y(_l * _prog_curr, _d); - _prog_curr *= _pathLength; + var wgLen = random1D(_sed + _sedIndex, -_wig, _wig); _sedIndex++; + _nx += lengthdir_x(wgLen, _d + 90); + _ny += lengthdir_y(wgLen, _d + 90); + + if(_prog_total > _rtStr) //prevent drawing point before range start. + array_push(points, { x: _nx, y: _ny, prog: _prog_total / _rtMax, progCrop: _prog_curr, weight: 1 }); + + if(_prog_curr > _prog) + _total -= (_prog_curr - _prog); + _prog = _prog_curr; + _ox = _nx; + _oy = _ny; } - - var _segLength = struct_has(_pat, "getAccuLength")? _pat.getAccuLength(i) : []; - var _segLengthAmo = array_length(_segLength); - var _segIndex = 0; - var _segIndexPrev = 0; - - if(_segLengthAmo) - while(_prog_curr > _segLength[_segIndex]) { - _segIndex++; - if(_segIndex == _segLengthAmo) { - _segIndex = 0; - break; - } - } - - // print($"===== {_prog_curr} / {_segLength} : {_segIndex} - {_pathLength} ====="); - - while(true) { - wght = 1; - _segIndexPrev = _segIndex; - if(_useDistance) { - var segmentLength = array_safe_get_fast(_segLength, _segIndex, _pathLength); + lines = [ points ]; + break; + + case 1 : + var lineLen = 1; + if(struct_has(_pat, "getLineCount")) lineLen = _pat.getLineCount(); + if(struct_has(_pat, "getPathData")) _pathData = _pat.getPathData(); + + lines = array_verify(lines, lineLen); + var _lineAmo = 0; + + if(_rtMax > 0) + for( var i = 0; i < lineLen; i++ ) { + var _useDistance = _fixL && struct_has(_pat, "getLength"); + var _pathLength = _useDistance? _pat.getLength(i) : 1; + if(_pathLength == 0) continue; - _prog_next = min(_prog_curr + _stepLen, _pathLength, segmentLength); - _pathPng = _ratInv? _pathLength - _prog_curr : _prog_curr; + var _pathStr = _rtStr; + var _pathEnd = _rtMax; - //print($"{segmentLength}/{_pathLength} = {_prog_next}"); - if(_prog_next == segmentLength) _segIndex++; + var _stepLen = min(_pathEnd, 1 / _seg); // Distance to move per step + if(_stepLen <= 0.00001) continue; - var _pp = _clamp? clamp(_pathPng, 0, _pathLength) : _pathPng; - // print($"_pp = {_pp}, total = {_total}"); + var _total = _pathEnd; // Length remaining + var _total_prev = _total; // Use to prevent infinite loop + var _freeze = 0; // Use to prevent infinite loop - p = _pat.getPointDistance(_pp, i, p); - if(struct_has(_pat, "getWeightDistance")) - wght = _pat.getWeightDistance(_pp, i); + var _prog_curr = _clamp? _shift : frac(_shift); // Pointer to the current position + var _prog_next = 0; + var _prog = _prog_curr + 1; // Record previous position to delete from _total + var _prog_total = 0; // Record the distance the pointer has moved so far + var points = []; + var pointAmo = 0; + var wght; + var _pathPng; + + if(_useDistance) { + _pathStr *= _pathLength; + _pathEnd *= _pathLength; + _stepLen = min(_segL, _pathEnd); - } else { - _prog_next = min(_prog_curr + _stepLen, 1); //Move forward _stepLen or _total (if less) stop at 1 - _pathPng = _ratInv? 1 - _prog_curr : _prog_curr; - - var _pp = _clamp? clamp(_pathPng, 0, 1) : _pathPng - - p = _pat.getPointRatio(_pp, i, p); - if(struct_has(_pat, "getWeightRatio")) - wght = _pat.getWeightRatio(_pp, i); + _total *= _pathLength; + _total_prev = _total; + + _prog_curr *= _pathLength; } - _nx = p.x; - _ny = p.y; - // print($"{_nx}, {_ny}"); - - if(_total < _pathEnd) { //Do not wiggle the last point. - var _d = point_direction(_ox, _oy, _nx, _ny); - _nx += lengthdir_x(random1D(_sed + _sedIndex, -_wig, _wig), _d + 90); _sedIndex++; - _ny += lengthdir_y(random1D(_sed + _sedIndex, -_wig, _wig), _d + 90); _sedIndex++; - } - - if(_prog_total >= _pathStr) { //Do not add point before range start. Do this instead of starting at _rtStr to prevent wiggle. - points[pointAmo++] = { - x: _nx, - y: _ny, - prog: (_prog_total - _pathStr) / (_pathEnd - _pathStr), - progCrop: _prog_curr / _pathLength, - weight: wght + var _segLength = struct_has(_pat, "getAccuLength")? _pat.getAccuLength(i) : []; + var _segLengthAmo = array_length(_segLength); + var _segIndex = 0; + var _segIndexPrev = 0; + + if(_segLengthAmo) + while(_prog_curr > _segLength[_segIndex]) { + _segIndex++; + if(_segIndex == _segLengthAmo) { + _segIndex = 0; + break; } } - if(_total <= 0) break; + // print($"===== {_prog_curr} / {_segLength} : {_segIndex} - {_pathLength} ====="); - if(_prog_next == _prog_curr && _segIndexPrev == _segIndex) { /*print("Terminate line not moving");*/ break; } - else if(_prog_next > _prog_curr) { - _prog_total += _prog_next - _prog_curr; - _total -= _prog_next - _prog_curr; + while(true) { + wght = 1; + _segIndexPrev = _segIndex; + + if(_useDistance) { + var segmentLength = array_safe_get_fast(_segLength, _segIndex, _pathLength); + + _prog_next = min(_prog_curr + _stepLen, _pathLength, segmentLength); + _pathPng = _ratInv? _pathLength - _prog_curr : _prog_curr; + + //print($"{segmentLength}/{_pathLength} = {_prog_next}"); + if(_prog_next == segmentLength) _segIndex++; + + var _pp = _clamp? clamp(_pathPng, 0, _pathLength) : _pathPng; + // print($"_pp = {_pp}, total = {_total}"); + + p = _pat.getPointDistance(_pp, i, p); + if(struct_has(_pat, "getWeightDistance")) + wght = _pat.getWeightDistance(_pp, i); + + } else { + _prog_next = min(_prog_curr + _stepLen, 1); //Move forward _stepLen or _total (if less) stop at 1 + _pathPng = _ratInv? 1 - _prog_curr : _prog_curr; + + var _pp = _clamp? clamp(_pathPng, 0, 1) : _pathPng + + p = _pat.getPointRatio(_pp, i, p); + if(struct_has(_pat, "getWeightRatio")) + wght = _pat.getWeightRatio(_pp, i); + } + + _nx = p.x; + _ny = p.y; + // print($"{_nx}, {_ny}"); + + if(_total < _pathEnd) { //Do not wiggle the last point. + var _d = point_direction(_ox, _oy, _nx, _ny); + _nx += lengthdir_x(random1D(_sed + _sedIndex, -_wig, _wig), _d + 90); _sedIndex++; + _ny += lengthdir_y(random1D(_sed + _sedIndex, -_wig, _wig), _d + 90); _sedIndex++; + } + + if(_prog_total >= _pathStr) { //Do not add point before range start. Do this instead of starting at _rtStr to prevent wiggle. + points[pointAmo++] = { + x: _nx, + y: _ny, + prog: (_prog_total - _pathStr) / (_pathEnd - _pathStr), + progCrop: _prog_curr / _pathLength, + weight: wght + } + } + + if(_total <= 0) break; + + if(_prog_next == _prog_curr && _segIndexPrev == _segIndex) { /*print("Terminate line not moving");*/ break; } + else if(_prog_next > _prog_curr) { + _prog_total += _prog_next - _prog_curr; + _total -= _prog_next - _prog_curr; + } + _stepLen = min(_stepLen, _total); + + _prog_curr = _prog_next; + _ox = _nx; + _oy = _ny; + + if(_total_prev == _total && _segIndexPrev == _segIndex && ++_freeze > 16) { /*print("Terminate line not moving");*/ break; } + _total_prev = _total; + + if(_segIndex >= _segLengthAmo) { /*print("Terminate line finish last segment");*/ break; } } - _stepLen = min(_stepLen, _total); - - _prog_curr = _prog_next; - _ox = _nx; - _oy = _ny; - - if(_total_prev == _total && _segIndexPrev == _segIndex && ++_freeze > 16) { /*print("Terminate line not moving");*/ break; } - _total_prev = _total; - if(_segIndex >= _segLengthAmo) { /*print("Terminate line finish last segment");*/ break; } + array_resize(points, pointAmo); + + lines[_lineAmo++] = points; } - array_resize(points, pointAmo); + array_resize(lines, _lineAmo); + break; - lines[_lineAmo++] = points; + case 2 : + if(!is_array(_segs[0][0])) //spreaded single path + _segs = [ _segs ]; + lines = array_create(array_length(_segs)); + + for (var i = 0, n = array_length(_segs); i < n; i++) { + var _seg = _segs[i]; + if(array_empty(_seg)) continue; + + var _uselen = array_length(_seg[0]) >= 3; + var _lin = array_create(array_length(_seg)); + + if(_uselen) { + for (var j = 0, m = array_length(_seg); j < m; j++) + _lin[j] = { x: _seg[j][0], y: _seg[j][1], prog: _seg[j][2], progCrop: _seg[j][2], weight: 1 }; + + } else { + + var _l, _len = [ 0 ], _lenTotal = 0; + var ox = _seg[0][0], oy = _seg[0][1], nx, ny; + + for (var j = 1, m = array_length(_seg); j < m; j++) { + nx = _seg[j][0]; + ny = _seg[j][1]; + _l = point_distance(ox, oy, nx, ny); + + _len[j] = _l; + _lenTotal += _l; + + ox = nx; + oy = ny; + } + + for (var j = 0, m = array_length(_seg); j < m; j++) + _lin[j] = { x: _seg[j][0], y: _seg[j][1], prog: _len[j] / _lenTotal, progCrop: _len[j] / _lenTotal, weight: 1 }; + } + + lines[i] = _lin; + } + break; + } + + surface_set_target(_colorPass); + if(_bg) draw_clear_alpha(0, 1); + else DRAW_CLEAR + + if(_useTex) { + var tex = surface_get_texture(_tex); + + shader_set(sh_draw_mapping); + shader_set_2("position", _texPos); + shader_set_f("rotation", degtorad(_texRot)); + shader_set_2("scale", _texSca); + + shader_set_interpolation(_tex); } - array_resize(lines, _lineAmo); - #endregion - - } else { #region - var x0, y0, x1, y1; - var _0 = point_rectangle_overlap(_dim[0], _dim[1], (_ang + 180) % 360); - var _1 = point_rectangle_overlap(_dim[0], _dim[1], _ang); - x0 = _0[0]; y0 = _0[1]; - x1 = _1[0]; y1 = _1[1]; - - var _l = point_distance(x0, y0, x1, y1); - var _d = point_direction(x0, y0, x1, y1); - var _od = _d, _nd = _d; + for( var i = 0, n = array_length(lines); i < n; i++ ) { + var points = lines[i]; + if(array_length(points) < 2) continue; - var ww = _rtMax / _seg; - var _total = _rtMax; - var _prog_curr = frac(_shift) - ww; - var _prog = _prog_curr + 1; - var _prog_total = 0; - var points = []; + var _caps = []; - while(_total > 0) { - if(_prog_curr >= 1) _prog_curr = 0; - else _prog_curr = min(_prog_curr + min(_total, ww), 1); - _prog_total += min(_total, ww); + if(_useTex) draw_primitive_begin_texture(pr_trianglestrip, tex); + else draw_primitive_begin(pr_trianglestrip); + + random_set_seed(_sed + i); + var pxs = []; + var dat = array_safe_get_fast(_pathData, i, noone); + + var _col_base = dat == noone? _colb.eval(random(1)) : dat.color; + + for( var j = 0; j < array_length(points); j++ ) { + var p0 = points[j]; + var _nx = p0.x - 0.5 * _1px; + var _ny = p0.y - 0.5 * _1px; + var prog = p0.prog; + var prgc = p0.progCrop; + var _dir = j? point_direction(_ox, _oy, _nx, _ny) : 0; - _nx = x0 + lengthdir_x(_l * _prog_curr, _d); - _ny = y0 + lengthdir_y(_l * _prog_curr, _d); + var widProg = value_snap_real(_widap? prog : prgc, 0.01); - var wgLen = random1D(_sed + _sedIndex, -_wig, _wig); _sedIndex++; - _nx += lengthdir_x(wgLen, _d + 90); - _ny += lengthdir_y(wgLen, _d + 90); + _nw = random_range(_wid[0], _wid[1]); + if(!ds_map_exists(widthMap, widProg)) + widthMap[? widProg] = eval_curve_x(_widc, widProg, 0.1); + _nw *= widthMap[? widProg]; + _nw *= p0.weight; - if(_prog_total > _rtStr) //prevent drawing point before range start. - array_push(points, { x: _nx, y: _ny, prog: _prog_total / _rtMax, progCrop: _prog_curr, weight: 1 }); + _nc = colorMultiply(_col_base, _color.eval(_colP? prog : prgc)); - if(_prog_curr > _prog) - _total -= (_prog_curr - _prog); - _prog = _prog_curr; - _ox = _nx; - _oy = _ny; + if(_cap) { #region + if(j == 1) { + _d = _dir + 180; + _caps[0] = [ _oc, _ox, _oy, _ow / 2, _d - 90, _d ]; + _caps[1] = [ _oc, _ox, _oy, _ow / 2, _d, _d + 90 ]; + } + + if(j == array_length(points) - 1) { + _d = _dir; + _caps[2] = [ _nc, _nx, _ny, _nw / 2, _d - 90, _d ]; + _caps[3] = [ _nc, _nx, _ny, _nw / 2, _d, _d + 90 ]; + } + } #endregion + + if(_1px) { #region + if(j) { + var dst = point_distance(_ox, _oy, _nx, _ny); + if(dst <= 1 && i < array_length(points) - 1) continue; + draw_line_color(_ox, _oy, _nx, _ny, _oc, _nc); + } + + _ox = _nx; + _oy = _ny; + _oc = _nc; + #endregion + } else { #region + if(j) { + var _nd0 = _dir; + var _nd1 = _nd0; + + if(j < array_length(points) - 1) { + var p2 = points[j + 1]; + var _nnx = p2.x; + var _nny = p2.y; + + _nd1 = point_direction(_nx, _ny, _nnx, _nny); + _nd = _nd0 + angle_difference(_nd1, _nd0) / 2; + } else + _nd = _nd0; + + if(_useTex) { + var _len = array_length(points) - 1; + + var ox0 = _ox + lengthdir_x(_ow / 2, _od + 90); + var oy0 = _oy + lengthdir_y(_ow / 2, _od + 90); + var nx0 = _nx + lengthdir_x(_nw / 2, _nd + 90); + var ny0 = _ny + lengthdir_y(_nw / 2, _nd + 90); + + var ox1 = _ox + lengthdir_x(_ow / 2, _od + 90 + 180); + var oy1 = _oy + lengthdir_y(_ow / 2, _od + 90 + 180); + var nx1 = _nx + lengthdir_x(_nw / 2, _nd + 90 + 180); + var ny1 = _ny + lengthdir_y(_nw / 2, _nd + 90 + 180); + + draw_vertex_texture_color(ox0, oy0, 0, (j - 1) / _len, _oc, 1); + draw_vertex_texture_color(ox1, oy1, 1, (j - 1) / _len, _oc, 1); + draw_vertex_texture_color(nx0, ny0, 0, (j - 0) / _len, _nc, 1); + draw_vertex_texture_color(nx1, ny1, 1, (j - 0) / _len, _nc, 1); + + } else + draw_line_width2_angle(_ox, _oy, _nx, _ny, _ow, _nw, _od + 90, _nd + 90, _oc, _nc); + } else { + var p1 = points[j + 1]; + _nd = point_direction(_nx, _ny, p1.x, p1.y); + } + + _ox = _nx; + _oy = _ny; + _od = _nd; + _ow = _nw; + _oc = _nc; + } + #endregion + } + + draw_primitive_end(); + + for( var j = 0, m = array_length(_caps); j < m; j++ ) { + var _cps = _caps[j]; + draw_set_color(_cps[0]); + draw_circle_angle(_cps[1], _cps[2], _cps[3], _cps[4], _cps[5], _capP); + } } - - lines = [ points ]; - } #endregion - - #region draw - surface_set_target(_colorPass); + if(_useTex) shader_reset(); + surface_reset_target(); + + if(_colW && !_1px) { + + surface_set_target(_widthPass); if(_bg) draw_clear_alpha(0, 1); else DRAW_CLEAR - if(_useTex) { #region - var tex = surface_get_texture(_tex); - - shader_set(sh_draw_mapping); - shader_set_2("position", _texPos); - shader_set_f("rotation", degtorad(_texRot)); - shader_set_2("scale", _texSca); - - shader_set_interpolation(_tex); - } #endregion - for( var i = 0, n = array_length(lines); i < n; i++ ) { var points = lines[i]; if(array_length(points) < 2) continue; var _caps = []; - if(_useTex) draw_primitive_begin_texture(pr_trianglestrip, tex); - else draw_primitive_begin(pr_trianglestrip); + draw_primitive_begin(pr_trianglestrip); random_set_seed(_sed + i); var pxs = []; @@ -435,79 +614,45 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons _nw *= widthMap[? widProg]; _nw *= p0.weight; - _nc = colorMultiply(_col_base, _color.eval(_colP? prog : prgc)); - if(_cap) { #region if(j == 1) { _d = _dir + 180; - _caps[0] = [ _oc, _ox, _oy, _ow / 2, _d - 90, _d ]; - _caps[1] = [ _oc, _ox, _oy, _ow / 2, _d, _d + 90 ]; + _caps[0] = [ c_grey, _ox, _oy, _ow / 2, _d - 90, _d ]; + _caps[1] = [ c_grey, _ox, _oy, _ow / 2, _d, _d + 90 ]; } if(j == array_length(points) - 1) { _d = _dir; - _caps[2] = [ _nc, _nx, _ny, _nw / 2, _d - 90, _d ]; - _caps[3] = [ _nc, _nx, _ny, _nw / 2, _d, _d + 90 ]; + _caps[2] = [ c_grey, _nx, _ny, _nw / 2, _d - 90, _d ]; + _caps[3] = [ c_grey, _nx, _ny, _nw / 2, _d, _d + 90 ]; } } #endregion - if(_1px) { #region - if(j) { - var dst = point_distance(_ox, _oy, _nx, _ny); - if(dst <= 1 && i < array_length(points) - 1) continue; - draw_line_color(_ox, _oy, _nx, _ny, _oc, _nc); - } + if(j) { + var _nd0 = _dir; + var _nd1 = _nd0; - _ox = _nx; - _oy = _ny; - _oc = _nc; - #endregion - } else { #region - if(j) { - var _nd0 = _dir; - var _nd1 = _nd0; - - if(j < array_length(points) - 1) { - var p2 = points[j + 1]; - var _nnx = p2.x; - var _nny = p2.y; - - _nd1 = point_direction(_nx, _ny, _nnx, _nny); - _nd = _nd0 + angle_difference(_nd1, _nd0) / 2; - } else - _nd = _nd0; - - if(_useTex) { - var _len = array_length(points) - 1; - - var ox0 = _ox + lengthdir_x(_ow / 2, _od + 90); - var oy0 = _oy + lengthdir_y(_ow / 2, _od + 90); - var nx0 = _nx + lengthdir_x(_nw / 2, _nd + 90); - var ny0 = _ny + lengthdir_y(_nw / 2, _nd + 90); - - var ox1 = _ox + lengthdir_x(_ow / 2, _od + 90 + 180); - var oy1 = _oy + lengthdir_y(_ow / 2, _od + 90 + 180); - var nx1 = _nx + lengthdir_x(_nw / 2, _nd + 90 + 180); - var ny1 = _ny + lengthdir_y(_nw / 2, _nd + 90 + 180); - - draw_vertex_texture_color(ox0, oy0, 0, (j - 1) / _len, _oc, 1); - draw_vertex_texture_color(ox1, oy1, 1, (j - 1) / _len, _oc, 1); - draw_vertex_texture_color(nx0, ny0, 0, (j - 0) / _len, _nc, 1); - draw_vertex_texture_color(nx1, ny1, 1, (j - 0) / _len, _nc, 1); - - } else - draw_line_width2_angle(_ox, _oy, _nx, _ny, _ow, _nw, _od + 90, _nd + 90, _oc, _nc); - } else { - var p1 = points[j + 1]; - _nd = point_direction(_nx, _ny, p1.x, p1.y); - } + if(j < array_length(points) - 1) { + var p2 = points[j + 1]; + var _nnx = p2.x; + var _nny = p2.y; - _ox = _nx; - _oy = _ny; - _od = _nd; - _ow = _nw; - _oc = _nc; + _nd1 = point_direction(_nx, _ny, _nnx, _nny); + _nd = _nd0 + angle_difference(_nd1, _nd0) / 2; + } else + _nd = _nd0; + + draw_line_width2_angle_width(_ox, _oy, _nx, _ny, _ow, _nw, _od + 90, _nd + 90, c_white, c_white); + } else { + var p1 = points[j + 1]; + _nd = point_direction(_nx, _ny, p1.x, p1.y); } + + _ox = _nx; + _oy = _ny; + _od = _nd; + _ow = _nw; + #endregion } @@ -520,101 +665,10 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons } } - if(_useTex) shader_reset(); surface_reset_target(); - if(_colW && !_1px) { - - surface_set_target(_widthPass); - if(_bg) draw_clear_alpha(0, 1); - else DRAW_CLEAR - - for( var i = 0, n = array_length(lines); i < n; i++ ) { - var points = lines[i]; - if(array_length(points) < 2) continue; - - var _caps = []; - - draw_primitive_begin(pr_trianglestrip); - - random_set_seed(_sed + i); - var pxs = []; - var dat = array_safe_get_fast(_pathData, i, noone); - - var _col_base = dat == noone? _colb.eval(random(1)) : dat.color; - - for( var j = 0; j < array_length(points); j++ ) { - var p0 = points[j]; - var _nx = p0.x - 0.5 * _1px; - var _ny = p0.y - 0.5 * _1px; - var prog = p0.prog; - var prgc = p0.progCrop; - var _dir = j? point_direction(_ox, _oy, _nx, _ny) : 0; - - var widProg = value_snap_real(_widap? prog : prgc, 0.01); - - _nw = random_range(_wid[0], _wid[1]); - if(!ds_map_exists(widthMap, widProg)) - widthMap[? widProg] = eval_curve_x(_widc, widProg, 0.1); - _nw *= widthMap[? widProg]; - _nw *= p0.weight; - - if(_cap) { #region - if(j == 1) { - _d = _dir + 180; - _caps[0] = [ c_grey, _ox, _oy, _ow / 2, _d - 90, _d ]; - _caps[1] = [ c_grey, _ox, _oy, _ow / 2, _d, _d + 90 ]; - } - - if(j == array_length(points) - 1) { - _d = _dir; - _caps[2] = [ c_grey, _nx, _ny, _nw / 2, _d - 90, _d ]; - _caps[3] = [ c_grey, _nx, _ny, _nw / 2, _d, _d + 90 ]; - } - } #endregion - - if(j) { - var _nd0 = _dir; - var _nd1 = _nd0; - - if(j < array_length(points) - 1) { - var p2 = points[j + 1]; - var _nnx = p2.x; - var _nny = p2.y; - - _nd1 = point_direction(_nx, _ny, _nnx, _nny); - _nd = _nd0 + angle_difference(_nd1, _nd0) / 2; - } else - _nd = _nd0; - - draw_line_width2_angle_width(_ox, _oy, _nx, _ny, _ow, _nw, _od + 90, _nd + 90, c_white, c_white); - } else { - var p1 = points[j + 1]; - _nd = point_direction(_nx, _ny, p1.x, p1.y); - } - - _ox = _nx; - _oy = _ny; - _od = _nd; - _ow = _nw; - - #endregion - } - - draw_primitive_end(); - - for( var j = 0, m = array_length(_caps); j < m; j++ ) { - var _cps = _caps[j]; - draw_set_color(_cps[0]); - draw_circle_angle(_cps[1], _cps[2], _cps[3], _cps[4], _cps[5], _capP); - } - } - - surface_reset_target(); - - } - #endregion + } return [ _colorPass, _widthPass ]; - } #endregion + } } \ No newline at end of file diff --git a/scripts/node_path_bake/node_path_bake.gml b/scripts/node_path_bake/node_path_bake.gml index 3028b3b27..f3d370e23 100644 --- a/scripts/node_path_bake/node_path_bake.gml +++ b/scripts/node_path_bake/node_path_bake.gml @@ -1,13 +1,15 @@ function Node_Path_Bake(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Bake Path"; - setDimension(96, 48);; + setDimension(96, 48); inputs[| 0] = nodeValue("Path", self, JUNCTION_CONNECT.input, VALUE_TYPE.pathnode, noone) .setVisible(true, true); inputs[| 1] = nodeValue("Segment length", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1); - outputs[| 0] = nodeValue("Segment", self, JUNCTION_CONNECT.output, VALUE_TYPE.float, [[]]) + inputs[| 2] = nodeValue("Spread single path", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); + + outputs[| 0] = nodeValue("Segments", self, JUNCTION_CONNECT.output, VALUE_TYPE.float, [[]]) .setDisplay(VALUE_DISPLAY.vector) .setArrayDepth(1); @@ -20,7 +22,9 @@ function Node_Path_Bake(_x, _y, _group = noone) : Node(_x, _y, _group) construct var _segs = outputs[| 0].getValue(); var ox, oy, nx, ny; - if(path_amount == 1) _segs = [ _segs ]; + if(array_invalid(_segs) || array_invalid(_segs[0])) return; + if(!is_array(_segs[0][0])) _segs = [ _segs ]; + draw_set_color(COLORS._main_icon); for( var i = 0, n = array_length(_segs); i < n; i++ ) { @@ -41,6 +45,7 @@ function Node_Path_Bake(_x, _y, _group = noone) : Node(_x, _y, _group) construct static update = function() { var _path = getInputData(0); var _dist = getInputData(1); + var _sped = getInputData(2); if(_path == noone) return; if(_dist <= 0) return; @@ -54,17 +59,17 @@ function Node_Path_Bake(_x, _y, _group = noone) : Node(_x, _y, _group) construct for( var i = 0; i < _amo; i++ ) { var _len = _path.getLength(i); var _seg = []; + _segs[i] = _seg; + + if(_len == 0) continue; for( var j = 0; j <= _len; j += _dist ) { _p = _path.getPointDistance(j, i, _p); - - _seg[j] = [ _p.x, _p.y ]; + array_push(_seg, [ _p.x, _p.y, j / _len ]); } - - _segs[i] = _seg; } - if(_amo == 1) _segs = _segs[0]; + if(_sped && _amo == 1) _segs = _segs[0]; outputs[| 0].setValue(_segs); } diff --git a/scripts/node_segment_filter/node_segment_filter.gml b/scripts/node_segment_filter/node_segment_filter.gml new file mode 100644 index 000000000..c7ee45ed3 --- /dev/null +++ b/scripts/node_segment_filter/node_segment_filter.gml @@ -0,0 +1,42 @@ +function Node_Segment_Filter(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + name = "Segment Filter"; + + setDimension(96, 48); + + inputs[| 0] = nodeValue("Segments", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [[]]) + .setDisplay(VALUE_DISPLAY.vector) + .setArrayDepth(1); + + inputs[| 1] = nodeValue("Loop", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + outputs[| 0] = nodeValue("Segments", self, JUNCTION_CONNECT.output, VALUE_TYPE.float, [[]]) + .setVisible(false) + .setArrayDepth(1); + + input_display_list = [ + ["Segments", false], 0, + ["Filter", false], 1, + ]; + + path_preview_surface = noone; + + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + + } + + static update = function(frame = CURRENT_FRAME) { + var _segments = getInputData(0); + + if(!is_array(_segments) || array_empty(_segments) || !is_array(_segments[0])) return; + + if(!is_array(_segments[0][0])) //spreaded single path + _segments = [ _segments ]; + + + } + + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { + var bbox = drawGetBbox(xx, yy, _s); + + } +} \ No newline at end of file diff --git a/scripts/node_segment_filter/node_segment_filter.yy b/scripts/node_segment_filter/node_segment_filter.yy new file mode 100644 index 000000000..d9c28f730 --- /dev/null +++ b/scripts/node_segment_filter/node_segment_filter.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"", + "%Name":"node_segment_filter", + "isCompatibility":false, + "isDnD":false, + "name":"node_segment_filter", + "parent":{ + "name":"path", + "path":"folders/nodes/data/value/path.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file