From 9380d2d77cd82c72c5ee852e27ee554df29b1a09 Mon Sep 17 00:00:00 2001 From: MakhamDev Date: Mon, 2 Oct 2023 09:53:30 +0700 Subject: [PATCH] [Particle, VFX] Improve curve evaluation performance. --- datafiles/data/themes/default.zip | Bin 4057982 -> 4057982 bytes scripts/__VFX/__VFX.gml | 104 +++++--- .../_node_VFX_spawner/_node_VFX_spawner.gml | 62 ++++- .../curve_bezier_function.gml | 67 ++++-- scripts/locale_data/locale_data.gml | 10 + scripts/nodeValue_drawer/nodeValue_drawer.gml | 2 +- scripts/node_value/node_value.gml | 4 + scripts/random_function/random_function.gml | 223 ++++++++++-------- .../surface_functions/surface_functions.gml | 4 +- scripts/vectorBox/vectorBox.gml | 48 ++-- 10 files changed, 337 insertions(+), 187 deletions(-) diff --git a/datafiles/data/themes/default.zip b/datafiles/data/themes/default.zip index ba1c3c0aa2ba35118527f56d78c9a785f6b20531..049a8633e391c9950652c9ae374ecee7d573739f 100644 GIT binary patch delta 1856 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 diff --git a/scripts/__VFX/__VFX.gml b/scripts/__VFX/__VFX.gml index cc23a1cb9..032feb009 100644 --- a/scripts/__VFX/__VFX.gml +++ b/scripts/__VFX/__VFX.gml @@ -24,10 +24,23 @@ function __part(_node) constructor { turning = 0; turnSpd = 0; + drawx = 0; + drawy = 0; + drawrot = 0; + drawsx = 0; + drawsy = 0; + accel = 0; spVec = [ 0, 0 ]; - wig_pos = 0; + //wig_psx = new wiggleMap(seed, 1, PROJECT.animator.frames_total); + //wig_psy = new wiggleMap(seed, 1, PROJECT.animator.frames_total); + + //wig_scx = new wiggleMap(seed, 1, PROJECT.animator.frames_total); + //wig_scy = new wiggleMap(seed, 1, PROJECT.animator.frames_total); + + //wig_rot = new wiggleMap(seed, 1, PROJECT.animator.frames_total); + //wig_dir = new wiggleMap(seed, 1, PROJECT.animator.frames_total); boundary_data = -1; @@ -64,7 +77,7 @@ function __part(_node) constructor { ground_bounce = 0; ground_friction = 1; - static create = function(_surf, _x, _y, _life) { + static create = function(_surf, _x, _y, _life) { #region active = true; surf = _surf; x = _x; @@ -76,9 +89,9 @@ function __part(_node) constructor { life = _life; life_total = life; node.onPartCreate(self); - } + } #endregion - static setPhysic = function(_sx, _sy, _ac, _g, _gDir, _wig_pos, _turn, _turnSpd) { + static setPhysic = function(_sx, _sy, _ac, _g, _gDir, _turn, _turnSpd) { #region speedx = _sx; speedy = _sy; accel = _ac; @@ -90,20 +103,34 @@ function __part(_node) constructor { turning = _turn; turnSpd = _turnSpd; - wig_pos = _wig_pos; - spVec[0] = point_distance(0, 0, speedx, speedy); spVec[1] = point_direction(0, 0, speedx, speedy); - } + } #endregion - static setGround = function(_ground, _ground_offset, _ground_bounce, _ground_frict) { + static setWiggle = function(wiggle_maps) { #region + //wig_psx.check(_wig_pos[0], _wig_pos[1], seed + 10); + //wig_psy.check(_wig_pos[0], _wig_pos[1], seed + 20); + //wig_rot.check(_wig_rot[0], _wig_rot[1], seed + 30); + //wig_scx.check(_wig_sca[0], _wig_sca[1], seed + 40); + //wig_scy.check(_wig_sca[0], _wig_sca[1], seed + 50); + //wig_dir.check(_wig_dir[0], _wig_dir[1], seed + 60); + + wig_psx = wiggle_maps.wig_psx; + wig_psy = wiggle_maps.wig_psy; + wig_rot = wiggle_maps.wig_rot; + wig_scx = wiggle_maps.wig_scx; + wig_scy = wiggle_maps.wig_scy; + wig_dir = wiggle_maps.wig_dir; + } #endregion + + static setGround = function(_ground, _ground_offset, _ground_bounce, _ground_frict) { #region ground = _ground; ground_y = y + _ground_offset; ground_bounce = _ground_bounce; ground_friction = clamp(1 - _ground_frict, 0, 1); - } + } #endregion - static setTransform = function(_scx, _scy, _sct, _rot, _rots, _follow) { + static setTransform = function(_scx, _scy, _sct, _rot, _rots, _follow) { #region sc_sx = _scx; sc_sy = _scy; sct = _sct; @@ -111,23 +138,23 @@ function __part(_node) constructor { rot = _rot; rot_s = _rots; follow = _follow; - } + } #endregion - static setDraw = function(_col, _blend, _alp, _fade) { + static setDraw = function(_col, _blend, _alp, _fade) { #region col = _col; blend = _blend; alp = _alp; alp_draw = _alp; alp_fade = _fade; - } + } #endregion - static kill = function() { + static kill = function() { #region active = false; node.onPartDestroy(self); - } + } #endregion - static step = function() { + static step = function() { #region if(!active) return; x += speedx; @@ -145,10 +172,9 @@ function __part(_node) constructor { var dirr = point_direction(0, 0, speedx, speedy); var diss = point_distance(0, 0, speedx, speedy); diss = max(0, diss + accel); - + if(speedx != 0 || speedy != 0) { - if(wig_pos != 0) - dirr += random_range(-wig_pos, wig_pos); + dirr += wig_dir.get(seed + life); if(turning != 0) { var trn = turnSpd? turning * diss : turning; @@ -173,9 +199,21 @@ function __part(_node) constructor { prevx = x; prevy = y; - } + + drawx = x; + drawy = y; + drawrot = rot; + drawsx = sc_sx; + drawsy = sc_sy; + + drawx += wig_psx.get(seed + life); + drawy += wig_psy.get(seed + life); + drawrot += wig_rot.get(seed + life); + drawsx += wig_scy.get(seed + life); + drawsy += wig_scy.get(seed + life); + } #endregion - static draw = function(exact, surf_w, surf_h) { + static draw = function(exact, surf_w, surf_h) { #region var ss = surf; if(is_array(surf)) { var ind = abs(round((life_total - life) * anim_speed)); @@ -201,9 +239,9 @@ function __part(_node) constructor { if(!is_surface(surface)) return; var lifeRat = 1 - life / life_total; - var scCurve = eval_curve_x(sct, lifeRat); - scx = sc_sx * scCurve; - scy = sc_sy * scCurve; + var scCurve = sct.get(lifeRat); + scx = drawsx * scCurve; + scy = drawsy * scCurve; var _xx, _yy; var s_w = surface_get_width_safe(surface) * scx; @@ -211,8 +249,8 @@ function __part(_node) constructor { if(boundary_data == -1) { var _pp = point_rotate(-s_w / 2, -s_h / 2, 0, 0, rot); - _xx = x + _pp[0]; - _yy = y + _pp[1]; + _xx = drawx + _pp[0]; + _yy = drawy + _pp[1]; } else { var ww = boundary_data[2] + boundary_data[0]; var hh = boundary_data[3] + boundary_data[1]; @@ -222,8 +260,8 @@ function __part(_node) constructor { var _pp = point_rotate(-cx, -cy, 0, 0, rot); - _xx = x + cx + _pp[0] * scx; - _yy = y + cy + _pp[1] * scy; + _xx = drawx + cx + _pp[0] * scx; + _yy = drawy + cy + _pp[1] * scy; } if(exact) { @@ -240,12 +278,12 @@ function __part(_node) constructor { var cc = (col == -1)? c_white : col.eval(lifeRat); if(blend != c_white) cc = colorMultiply(blend, cc); - alp_draw = alp * eval_curve_x(alp_fade, lifeRat); + alp_draw = alp * alp_fade.get(lifeRat); - draw_surface_ext_safe(surface, _xx, _yy, scx, scy, rot, cc, alp_draw); - } + draw_surface_ext_safe(surface, _xx, _yy, scx, scy, drawrot, cc, alp_draw); + } #endregion - static getPivot = function() { + static getPivot = function() { #region if(boundary_data == -1) return [x, y]; @@ -255,7 +293,7 @@ function __part(_node) constructor { var cy = y + boundary_data[1] + hh / 2; return [cx, cy]; - } + } #endregion } #region helper diff --git a/scripts/_node_VFX_spawner/_node_VFX_spawner.gml b/scripts/_node_VFX_spawner/_node_VFX_spawner.gml index e49776cc0..abf45e4de 100644 --- a/scripts/_node_VFX_spawner/_node_VFX_spawner.gml +++ b/scripts/_node_VFX_spawner/_node_VFX_spawner.gml @@ -60,8 +60,8 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co .setDisplay(VALUE_DISPLAY.range, { linked : true }) .rejectArray(); - inputs[| 20] = nodeValue("Wiggle", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0 ] ) - .setDisplay(VALUE_DISPLAY.range, { linked : true }) + inputs[| 20] = nodeValue("Direction wiggle", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0 ] ) + .setDisplay(VALUE_DISPLAY.vector, { label: [ "Amplitude", "Period" ], linkable: false, per_line: true }) .rejectArray(); inputs[| 21] = nodeValue("Loop", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true ) @@ -132,16 +132,29 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co .rejectArray() .setDisplay(VALUE_DISPLAY.slider, [ 0, 1, 0.01 ]); + inputs[| 41] = nodeValue("Position wiggle", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0 ] ) + .setDisplay(VALUE_DISPLAY.vector, { label: [ "Amplitude", "Period" ], linkable: false, per_line: true }) + .rejectArray(); + + inputs[| 42] = nodeValue("Rotation wiggle", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0 ] ) + .setDisplay(VALUE_DISPLAY.vector, { label: [ "Amplitude", "Period" ], linkable: false, per_line: true }) + .rejectArray(); + + inputs[| 43] = nodeValue("Scale wiggle", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0 ] ) + .setDisplay(VALUE_DISPLAY.vector, { label: [ "Amplitude", "Period" ], linkable: false, per_line: true }) + .rejectArray(); + input_len = ds_list_size(inputs); input_display_list = [ 32, ["Sprite", false], 0, 22, 23, 26, ["Spawn", true], 27, 16, 1, 2, 3, 4, 30, 31, 24, 25, 5, ["Movement", true], 29, 6, 18, - ["Physics", true], 7, 19, 33, 20, 34, 35, 36, + ["Physics", true], 7, 19, 33, 34, 35, 36, ["Ground", true], 37, 38, 39, 40, ["Rotation", true], 15, 8, 9, ["Scale", true], 10, 17, 11, + ["Wiggles", true], 20, 41, 42, 43, ["Color", true], 12, 28, 13, 14, ["Render", true], 21 ]; @@ -161,7 +174,19 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co current_data = []; surface_cache = {}; - for(var i = 0; i < attributes.part_amount; i++) + wiggle_maps = { + wig_psx: new wiggleMap(seed, 1, 1000), + wig_psy: new wiggleMap(seed, 1, 1000), + wig_scx: new wiggleMap(seed, 1, 1000), + wig_scy: new wiggleMap(seed, 1, 1000), + wig_rot: new wiggleMap(seed, 1, 1000), + wig_dir: new wiggleMap(seed, 1, 1000), + }; + + curve_scale = noone; + curve_alpha = noone; + + for( var i = 0; i < attributes.part_amount; i++ ) parts[i] = new __part(self); static spawn = function(_time = PROJECT.animator.current_frame, _pos = -1) { #region @@ -184,7 +209,6 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co var _accel = current_data[ 7]; var _grav = current_data[19]; var _gvDir = current_data[33]; - var _wigg = current_data[20]; var _turn = current_data[34]; var _turnBi = current_data[35]; var _turnSc = current_data[36]; @@ -194,12 +218,10 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co var _rotation_speed = current_data[ 9]; var _scale = current_data[10]; var _size = current_data[17]; - var _scale_time = current_data[11]; var _color = current_data[12]; var _blend = current_data[28]; var _alpha = current_data[13]; - var _fade = current_data[14]; var _arr_type = current_data[22]; var _anim_speed = current_data[23]; @@ -304,12 +326,12 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co if(_turnBi) _trn *= choose(-1, 1); var _gravity = random_range(_grav[0], _grav[1]); - var _wiggle = random_range(_wigg[0], _wigg[1]); - part.setPhysic(_vx, _vy, _acc, _gravity, _gvDir, _wiggle, _trn, _turnSc); + part.setPhysic(_vx, _vy, _acc, _gravity, _gvDir, _trn, _turnSc); + part.setWiggle(wiggle_maps); part.setGround(_ground, _ground_offset, _ground_bounce, _ground_frict); - part.setTransform(_scx, _scy, _scale_time, _rot, _rot_spd, _follow); - part.setDraw(_color, _bld, _alp, _fade); + part.setTransform(_scx, _scy, curve_scale, _rot, _rot_spd, _follow); + part.setDraw(_color, _bld, _alp, curve_alpha); spawn_index = safe_mod(spawn_index + 1, attributes.part_amount); onSpawn(_time, part); @@ -332,6 +354,24 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co render(); seed = inputs[| 32].getValue(); + var _wigg_pos = inputs[| 41].getValue(); + var _wigg_rot = inputs[| 42].getValue(); + var _wigg_sca = inputs[| 43].getValue(); + var _wigg_dir = inputs[| 20].getValue(); + + wiggle_maps.wig_psx.check(_wigg_pos[0], _wigg_pos[1], seed + 10); + wiggle_maps.wig_psy.check(_wigg_pos[0], _wigg_pos[1], seed + 20); + wiggle_maps.wig_rot.check(_wigg_rot[0], _wigg_rot[1], seed + 30); + wiggle_maps.wig_scx.check(_wigg_sca[0], _wigg_sca[1], seed + 40); + wiggle_maps.wig_scy.check(_wigg_sca[0], _wigg_sca[1], seed + 50); + wiggle_maps.wig_dir.check(_wigg_dir[0], _wigg_dir[1], seed + 60); + + var _curve_sca = inputs[| 11].getValue(); + var _curve_alp = inputs[| 14].getValue(); + + curve_scale = new curveMap(_curve_sca, PROJECT.animator.frames_total); + curve_alpha = new curveMap(_curve_alp, PROJECT.animator.frames_total); + var keys = variable_struct_get_names(surface_cache); for( var i = 0, n = array_length(keys); i < n; i++ ) surface_free_safe(surface_cache[$ keys[i]]); diff --git a/scripts/curve_bezier_function/curve_bezier_function.gml b/scripts/curve_bezier_function/curve_bezier_function.gml index 1d8622b78..1122dc940 100644 --- a/scripts/curve_bezier_function/curve_bezier_function.gml +++ b/scripts/curve_bezier_function/curve_bezier_function.gml @@ -4,7 +4,7 @@ #macro CURVE_DEF_10 [0, 0, 0, 1, 1/3, -1/3, /**/ -1/3, 1/3, 1, 0, 0, 0] #macro CURVE_DEF_11 [0, 0, 0, 1, 1/3, 0, /**/ -1/3, 0, 1, 1, 0, 0] -function draw_curve(x0, y0, _w, _h, _bz, miny = 0, maxy = 1) { +function draw_curve(x0, y0, _w, _h, _bz, miny = 0, maxy = 1) { #region var segments = array_length(_bz) / 6 - 1; for( var i = 0; i < segments; i++ ) { @@ -30,9 +30,9 @@ function draw_curve(x0, y0, _w, _h, _bz, miny = 0, maxy = 1) { draw_curve_segment(dx0, y0, dw, _h, [_y0, ax0, ay0, bx1, by1, _y1], smp, miny, maxy); } -} +} #endregion -function draw_curve_segment(x0, y0, _w, _h, _bz, SAMPLE = 32, miny = 0, maxy = 1) { +function draw_curve_segment(x0, y0, _w, _h, _bz, SAMPLE = 32, miny = 0, maxy = 1) { #region var _ox, _oy; for(var i = 0; i <= SAMPLE; i++) { @@ -50,9 +50,9 @@ function draw_curve_segment(x0, y0, _w, _h, _bz, SAMPLE = 32, miny = 0, maxy = 1 _ox = _nx; _oy = _ny; } -} +} #endregion -function eval_curve_segment_t_position(t, _bz) { +function eval_curve_segment_t_position(t, _bz) { #region return [ power(1 - t, 3) * 0 + 3 * power(1 - t, 2) * t * _bz[1] @@ -64,16 +64,16 @@ function eval_curve_segment_t_position(t, _bz) { + 3 * (1 - t) * power(t, 2) * _bz[4] + power(t, 3) * _bz[5] ]; -} +} #endregion -function eval_curve_segment_t(_bz, t) { +function eval_curve_segment_t(_bz, t) { #region return power(1 - t, 3) * _bz[0] + 3 * power(1 - t, 2) * t * _bz[2] + 3 * (1 - t) * power(t, 2) * _bz[4] + power(t, 3) * _bz[5]; -} +} #endregion -function eval_curve_x(_bz, _x, _prec = 0.00001) { +function eval_curve_x(_bz, _x, _tolr = 0.00001) { #region static _CURVE_DEF_01 = [0, 0, 0, 0, 1/3, 1/3, /**/ -1/3, -1/3, 1, 1, 0, 0]; static _CURVE_DEF_10 = [0, 0, 0, 1, 1/3, -1/3, /**/ -1/3, 1/3, 1, 0, 0, 0]; static _CURVE_DEF_11 = [0, 0, 0, 1, 1/3, 0, /**/ -1/3, 0, 1, 1, 0, 0]; @@ -104,13 +104,13 @@ function eval_curve_x(_bz, _x, _prec = 0.00001) { if(_x < _x0) continue; if(_x > _x1) continue; - return eval_curve_segment_x([_y0, ax0, ay0, bx1, by1, _y1], (_x - _x0) / (_x1 - _x0)); + return eval_curve_segment_x([_y0, ax0, ay0, bx1, by1, _y1], (_x - _x0) / (_x1 - _x0), _tolr); } return array_safe_get(_bz, array_length(_bz) - 3); -} +} #endregion -function eval_curve_segment_x(_bz, _x, _prec = 0.00001) { +function eval_curve_segment_x(_bz, _x, _tolr = 0.00001) { #region var st = 0; var ed = 1; @@ -127,7 +127,7 @@ function eval_curve_segment_x(_bz, _x, _prec = 0.00001) { + 3 * (1 - _xt) * power(_xt, 2) * _bz[3] + power(_xt, 3) * 1; - if(abs(_ftx - _x) < _prec) + if(abs(_ftx - _x) < _tolr) return eval_curve_segment_t(_bz, _xt); if(_xt < _x) @@ -152,24 +152,39 @@ function eval_curve_segment_x(_bz, _x, _prec = 0.00001) { _xt -= _ftx / slope; - if(abs(_ftx) < _prec) + if(abs(_ftx) < _tolr) break; } _xt = clamp(_xt, 0, 1); return eval_curve_segment_t(_bz, _xt); -} +} #endregion -function bezier_range(bz) { - return [ min(bz[0], bz[2], bz[4], bz[5]), max(bz[0], bz[2], bz[4], bz[5]) ]; -} +function bezier_range(bz) { return [ min(bz[0], bz[2], bz[4], bz[5]), max(bz[0], bz[2], bz[4], bz[5]) ]; } -function ease_cubic_in(rat) { - return power(rat, 3); -} -function ease_cubic_out(rat) { - return 1 - power(1 - rat, 3); -} -function ease_cubic_inout(rat) { - return rat < 0.5 ? 4 * power(rat, 3) : 1 - power(-2 * rat + 2, 3) / 2; +function ease_cubic_in(rat) { return power(rat, 3); } +function ease_cubic_out(rat) { return 1 - power(1 - rat, 3); } +function ease_cubic_inout(rat) { return rat < 0.5 ? 4 * power(rat, 3) : 1 - power(-2 * rat + 2, 3) / 2; } + +function curveMap(_bz, _prec = 32, _tolr = 0.00001) constructor { + bz = _bz; + prec = _prec; + size = 1 / _prec; + tolr = _tolr; + + map = array_create(_prec); + for( var i = 0; i < _prec; i++ ) + map[i] = eval_curve_x(bz, i * size, tolr); + + static get = function(i) { #region + gml_pragma("forceinline"); + + var _ind = clamp(i, 0, 1) * (prec - 1); + var _indL = floor(_ind); + var _indH = ceil(_ind); + var _indF = frac(_ind); + + if(_indL == _indH) return map[_ind]; + return lerp(map[_indL], map[_indH], _indF); + } #endregion } \ No newline at end of file diff --git a/scripts/locale_data/locale_data.gml b/scripts/locale_data/locale_data.gml index 74cff1ab8..db6b88011 100644 --- a/scripts/locale_data/locale_data.gml +++ b/scripts/locale_data/locale_data.gml @@ -73,6 +73,8 @@ function __txt_node_name(node, def = "") { gml_pragma("forceinline"); + if(TESTING) return def; + if(!struct_has(LOCALE.node, node)) return def; @@ -83,6 +85,8 @@ function __txt_node_tooltip(node, def = "") { gml_pragma("forceinline"); + if(TESTING) return def; + if(!struct_has(LOCALE.node, node)) return def; @@ -93,6 +97,8 @@ function __txt_junction_name(node, type, index, def = "") { gml_pragma("forceinline"); + if(TESTING) return def; + if(!struct_has(LOCALE.node, node)) return def; @@ -107,6 +113,8 @@ function __txt_junction_tooltip(node, type, index, def = "") { gml_pragma("forceinline"); + if(TESTING) return def; + if(!struct_has(LOCALE.node, node)) return def; @@ -121,6 +129,8 @@ function __txt_junction_data(node, type, index, def = []) { gml_pragma("forceinline"); + if(TESTING) return def; + if(!struct_has(LOCALE.node, node)) return def; diff --git a/scripts/nodeValue_drawer/nodeValue_drawer.gml b/scripts/nodeValue_drawer/nodeValue_drawer.gml index 5d4d58072..b6eb8e768 100644 --- a/scripts/nodeValue_drawer/nodeValue_drawer.gml +++ b/scripts/nodeValue_drawer/nodeValue_drawer.gml @@ -69,7 +69,7 @@ function drawWidget(xx, yy, ww, _m, jun, global_var = true, _hover = false, _foc if(visi_hold != noone && mouse_release(mb_left)) visi_hold = noone; - var cc = COLORS._main_text_inner; + var cc = COLORS._main_text; if(jun.expUse) { var expValid = jun.expTree != noone && jun.expTree.validate(); cc = expValid? COLORS._main_value_positive : COLORS._main_value_negative; diff --git a/scripts/node_value/node_value.gml b/scripts/node_value/node_value.gml index 4e5c96273..d251ca1b9 100644 --- a/scripts/node_value/node_value.gml +++ b/scripts/node_value/node_value.gml @@ -759,6 +759,10 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return setValueDirect(val, index); }, unit ); + if(struct_has(display_data, "label")) editWidget.axis = display_data.label; + if(struct_has(display_data, "linkable")) editWidget.linkable = display_data.linkable; + if(struct_has(display_data, "per_line")) editWidget.per_line = display_data.per_line; + if(type == VALUE_TYPE.integer) editWidget.setSlideSpeed(1); extra_data = { linked : false, side_button : noone }; diff --git a/scripts/random_function/random_function.gml b/scripts/random_function/random_function.gml index ace0b9917..3fb61c8a2 100644 --- a/scripts/random_function/random_function.gml +++ b/scripts/random_function/random_function.gml @@ -1,97 +1,4 @@ -function irandom_seed(val, seed) { - random_set_seed(floor(seed)); - return irandom(val); -} - -function irandom_range_seed(from, to, seed) { - random_set_seed(floor(seed)); - return irandom_range(from, to); -} - -function random_seed(val, seed) { - random_set_seed(floor(seed)); - var _s0 = random(val); - - random_set_seed(floor(seed) + 1); - var _s1 = random(val); - - return lerp(_s0, _s1, frac(seed)); -} - -function random_range_seed(from, to, seed) { - random_set_seed(floor(seed)); - var _s0 = random_range(from, to); - - random_set_seed(floor(seed) + 1); - var _s1 = random_range(from, to); - - return lerp(_s0, _s1, frac(seed)); -} - -function random1D(seed, startRange = 0, endRange = 1) { - if(startRange == endRange) return startRange; - - var _f = frac(seed); - if(_f == 0) { - random_set_seed(PROJECT.seed + seed); - return random_range(startRange, endRange); - } - - random_set_seed(PROJECT.seed + floor(seed)); - var f1 = random_range(startRange, endRange); - - random_set_seed(PROJECT.seed + floor(seed) + 1); - var f2 = random_range(startRange, endRange); - - return lerp(f1, f2, _f); -} - -function perlin1D(seed, scale = 1, octave = 1, startRange = 0, endRange = 1) { - var amp = power(2., octave - 1.) / (power(2., octave) - 1.); - var val = 0; - - repeat(octave) { - val = random1D(seed * scale) * amp; - scale *= 2; - amp /= 2; - } - - return lerp(startRange, endRange, val); -} - -function wiggle(_min = 0, _max = 1, _freq = 1, _time = 0, _seed = 0, _octave = 1) { - _freq = max(1, _freq); - - var sdMin = floor(_time / _freq) * _freq; - var sdMax = sdMin + _freq; - - var _x0 = perlin1D(PROJECT.seed + _seed + sdMin, 1, _octave); - var _x1 = perlin1D(PROJECT.seed + _seed + sdMax, 1, _octave); - - var t = (_time - sdMin) / (sdMax - sdMin); - t = -(cos(pi * t) - 1) / 2; - var _lrp = lerp(_x0, _x1, t); - return lerp(_min, _max, _lrp); -} - -function getWiggle(_min = 0, _max = 1, _freq = 1, _time = 0, _seed = 0, startTime = noone, endTime = noone) { - _freq = max(1, _freq); - - var sdMin = floor(_time / _freq) * _freq; - var sdMax = sdMin + _freq; - if(endTime) //Clip at ending - sdMax = min(endTime, sdMax); - - var _x0 = (startTime != noone && sdMin <= startTime)? 0.5 : random1D(PROJECT.seed + _seed + sdMin); - var _x1 = (endTime != noone && sdMax >= endTime)? 0.5 : random1D(PROJECT.seed + _seed + sdMax); - - var t = (_time - sdMin) / (sdMax - sdMin); - t = -(cos(pi * t) - 1) / 2; - var _lrp = lerp(_x0, _x1, t); - return lerp(_min, _max, _lrp); -} - -function UUID_generate(length = 32) { +function UUID_generate(length = 32) { #region randomize(); static str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; static month = "JFRAMJYASOND" @@ -107,4 +14,130 @@ function UUID_generate(length = 32) { repeat(length - string_length(_id)) _id += string_char_at(str, irandom_range(1, string_length(str))); return _id; -} \ No newline at end of file +} #endregion + +function irandom_seed(val, seed) { #region + random_set_seed(floor(seed)); + return irandom(val); +} #endregion + +function irandom_range_seed(from, to, seed) { #region + random_set_seed(floor(seed)); + return irandom_range(from, to); +} #endregion + +function random_seed(val, seed) { #region + random_set_seed(floor(seed)); + var _s0 = random(val); + + random_set_seed(floor(seed) + 1); + var _s1 = random(val); + + return lerp(_s0, _s1, frac(seed)); +} #endregion + +function random_range_seed(from, to, seed) { #region + random_set_seed(floor(seed)); + var _s0 = random_range(from, to); + + random_set_seed(floor(seed) + 1); + var _s1 = random_range(from, to); + + return lerp(_s0, _s1, frac(seed)); +} #endregion + +function random1D(seed, startRange = 0, endRange = 1) { #region + if(startRange == endRange) return startRange; + + var _f = frac(seed); + if(_f == 0) { + random_set_seed(PROJECT.seed + seed); + return random_range(startRange, endRange); + } + + random_set_seed(PROJECT.seed + floor(seed)); + var f1 = random_range(startRange, endRange); + + random_set_seed(PROJECT.seed + floor(seed) + 1); + var f2 = random_range(startRange, endRange); + + return lerp(f1, f2, _f); +} #endregion + +function perlin1D(seed, scale = 1, octave = 1, startRange = 0, endRange = 1) { #region + var amp = power(2., octave - 1.) / (power(2., octave) - 1.); + var val = 0; + + repeat(octave) { + val = random1D(seed * scale) * amp; + scale *= 2; + amp /= 2; + } + + return lerp(startRange, endRange, val); +} #endregion + +function wiggle(_min = 0, _max = 1, _freq = 1, _time = 0, _seed = 0, _octave = 1) { #region + _freq = max(1, _freq); + + var sdMin = floor(_time / _freq) * _freq; + var sdMax = sdMin + _freq; + + var _x0 = perlin1D(PROJECT.seed + _seed + sdMin, 1, _octave); + var _x1 = perlin1D(PROJECT.seed + _seed + sdMax, 1, _octave); + + var t = (_time - sdMin) / (sdMax - sdMin); + t = -(cos(pi * t) - 1) / 2; + var _lrp = lerp(_x0, _x1, t); + return lerp(_min, _max, _lrp); +} #endregion + +function getWiggle(_min = 0, _max = 1, _freq = 1, _time = 0, _seed = 0, startTime = noone, endTime = noone) { #region + _freq = max(1, _freq); + + var sdMin = floor(_time / _freq) * _freq; + var sdMax = sdMin + _freq; + if(endTime) //Clip at ending + sdMax = min(endTime, sdMax); + + var _x0 = (startTime != noone && sdMin <= startTime)? 0.5 : random1D(PROJECT.seed + _seed + sdMin); + var _x1 = (endTime != noone && sdMax >= endTime)? 0.5 : random1D(PROJECT.seed + _seed + sdMax); + + var t = (_time - sdMin) / (sdMax - sdMin); + t = -(cos(pi * t) - 1) / 2; + var _lrp = lerp(_x0, _x1, t); + return lerp(_min, _max, _lrp); +} #endregion + +function wiggleMap(_seed, _freq, _length) constructor { #region + seed = _seed; + freq = _freq; + len = _length; + amp = 1; + map = array_create(_length); + + static generate = function() { + gml_pragma("forceinline"); + + for(var i = 0; i < len; i++) map[i] = wiggle(-1, 1, freq, i, seed); + } + + static check = function(_amp, _freq, _seed) { + gml_pragma("forceinline"); + + amp = _amp; + if(seed == _seed && freq == _freq) return; + + //print($"Check {seed}:{_seed}, {freq}:{_freq} ({irandom(999999)})"); + seed = _seed; + freq = _freq; + generate(); + } + + static get = function(i) { + gml_pragma("forceinline"); + + if(amp == 0) return 0; + return map[abs(i) % len] * amp; + } +} #endregion \ No newline at end of file diff --git a/scripts/surface_functions/surface_functions.gml b/scripts/surface_functions/surface_functions.gml index 4f2ee7dc6..be78e93fd 100644 --- a/scripts/surface_functions/surface_functions.gml +++ b/scripts/surface_functions/surface_functions.gml @@ -154,8 +154,8 @@ function is_surface(s) { if(!s) return false; if(!surface_exists(s)) return false; - if(surface_get_width_safe(s) <= 0) return false; - if(surface_get_height_safe(s) <= 0) return false; + //if(surface_get_width_safe(s) <= 0) return false; + //if(surface_get_height_safe(s) <= 0) return false; return true; } diff --git a/scripts/vectorBox/vectorBox.gml b/scripts/vectorBox/vectorBox.gml index 47d1ccdd0..82530fb09 100644 --- a/scripts/vectorBox/vectorBox.gml +++ b/scripts/vectorBox/vectorBox.gml @@ -7,6 +7,9 @@ function vectorBox(_size, _onModify, _unit = noone) : widget() constructor { size = _size; onModify = _onModify; unit = _unit; + + linkable = true; + per_line = false; current_value = []; extra_data = { linked : false, side_button : noone }; @@ -87,7 +90,7 @@ function vectorBox(_size, _onModify, _unit = noone) : widget() constructor { x = _x; y = _y; w = _w; - h = _h; + h = per_line? (_h + ui(8)) * size - ui(8) : _h; if(struct_has(_extra_data, "linked")) extra_data.linked = _extra_data.linked; if(struct_has(_extra_data, "side_button")) extra_data.side_button = _extra_data.side_button; @@ -113,37 +116,44 @@ function vectorBox(_size, _onModify, _unit = noone) : widget() constructor { _w -= ui(40); } - var _icon_blend = extra_data.linked? COLORS._main_accent : (link_inactive_color == noone? COLORS._main_icon : link_inactive_color); - var bx = _x; - var by = _y + _h / 2 - ui(32 / 2); - if(buttonInstant(THEME.button_hide, bx + ui(4), by + ui(4), ui(24), ui(24), _m, active, hover, tooltip, THEME.value_link, extra_data.linked, _icon_blend) == 2) { - extra_data.linked = !extra_data.linked; - _extra_data.linked = extra_data.linked; + if(linkable) { + var _icon_blend = extra_data.linked? COLORS._main_accent : (link_inactive_color == noone? COLORS._main_icon : link_inactive_color); + var bx = _x; + var by = _y + _h / 2 - ui(32 / 2); + if(buttonInstant(THEME.button_hide, bx + ui(4), by + ui(4), ui(24), ui(24), _m, active, hover, tooltip, THEME.value_link, extra_data.linked, _icon_blend) == 2) { + extra_data.linked = !extra_data.linked; + _extra_data.linked = extra_data.linked; - if(extra_data.linked) { - onModify(0, _data[0]); - onModify(1, _data[0]); + if(extra_data.linked) { + onModify(0, _data[0]); + onModify(1, _data[0]); + } } + + _x += ui(28); + _w -= ui(28); } - _x += ui(28); - _w -= ui(28); - var sz = min(size, array_length(_data)); - var ww = _w / sz; + var ww = per_line? _w : _w / sz; + for(var i = 0; i < sz; i++) { - tb[i].setFocusHover(active, hover); + draw_set_font(f_p0); + var lw = max(ui(24), string_width(axis[i]) + ui(16)); - var bx = _x + ww * i; - tb[i].draw(bx + ui(24), _y, ww - ui(24), _h, _data[i], _m); + var bx = per_line? _x : _x + ww * i; + var by = per_line? _y + (_h + ui(8)) * i : _y; + + tb[i].setFocusHover(active, hover); + tb[i].draw(bx + lw, by, ww - lw, _h, _data[i], _m); draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text_inner); - draw_text(bx + ui(8), _y + _h / 2, axis[i]); + draw_text_add(bx + ui(8), by + _h / 2, axis[i]); } resetFocus(); - return _h; + return h; } static apply = function() {