From d7b7f8566511eedd4a91c1cccbdd03e14bc7b2b0 Mon Sep 17 00:00:00 2001 From: Tanasart Date: Sun, 27 Oct 2024 12:06:46 +0700 Subject: [PATCH] [Draw line, random shape, poly shape] Add antialiasing option (SSAA) --- datafiles/data/Actions/icons.afdesign~lock~ | Bin 110 -> 110 bytes scripts/node_line/node_line.gml | 35 ++++-- .../node_random_shape/node_random_shape.gml | 105 ++++++++++-------- .../node_shape_polygon/node_shape_polygon.gml | 62 +++++++---- scripts/node_value/node_value.gml | 1 - scripts/pathnodeBox/pathnodeBox.gml | 4 +- .../preview_overlay_scalar.gml | 2 +- .../preview_overlay_vector.gml | 2 +- 8 files changed, 126 insertions(+), 85 deletions(-) diff --git a/datafiles/data/Actions/icons.afdesign~lock~ b/datafiles/data/Actions/icons.afdesign~lock~ index cce0de6099dd2d3d684900cb92339726ceb2953f..56ef01166e831eafcab09f070dc7af32ae7e5a61 100644 GIT binary patch delta 20 acmd1H(_Ge+A*/ {return getDimension(index)}, VALUE_UNIT.reference); - + + newInput(34, nodeValue_Enum_Scroll("SSAA", self, 0, [ "None", "2x", "4x", "8x" ])); + input_display_list = [ ["Output", true], 0, 1, 30, 31, ["Line data", false], 27, 6, 7, 28, 32, 33, 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, + ["Render", false], 10, 24, 15, 16, 34, ["Texture", false], 18, 21, 22, 23, 29, ]; @@ -93,6 +95,8 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons lines = []; line_data = []; + temp_surfaces = [ noone ]; + widthMap = ds_map_create(); attribute_surface_depth(); @@ -221,6 +225,7 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons var _pnt0 = _data[32]; var _pnt1 = _data[33]; + var _aa = power(2, _data[34]); #endregion /////// Check data @@ -536,7 +541,10 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons var _padx = _pbbox * (_ppadd[2] - minx); var _pady = _pbbox * (_ppadd[1] - miny); - surface_set_target(_colorPass); + temp_surfaces[0] = surface_verify(temp_surfaces[0], _surfDim[0] * _aa, _surfDim[1] * _aa, attrDepth()); + var _cPassAA = temp_surfaces[0]; + + surface_set_target(_cPassAA); if(_bg) draw_clear_alpha(0, 1); else DRAW_CLEAR @@ -607,7 +615,7 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons 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); + draw_line_color(_ox * _aa, _oy * _aa, _nx * _aa, _ny * _aa, _oc, _nc); } _ox = _nx; @@ -642,13 +650,13 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons 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); + draw_vertex_texture_color(ox0 * _aa, oy0 * _aa, 0, (j - 1) / _len, _oc, 1); + draw_vertex_texture_color(ox1 * _aa, oy1 * _aa, 1, (j - 1) / _len, _oc, 1); + draw_vertex_texture_color(nx0 * _aa, ny0 * _aa, 0, (j - 0) / _len, _nc, 1); + draw_vertex_texture_color(nx1 * _aa, ny1 * _aa, 1, (j - 0) / _len, _nc, 1); } else - draw_line_width2_angle(_ox, _oy, _nx, _ny, _ow, _nw, _od + 90, _nd + 90, _oc, _nc); + draw_line_width2_angle(_ox * _aa, _oy * _aa, _nx * _aa, _ny * _aa, _ow * _aa, _nw * _aa, _od + 90, _nd + 90, _oc, _nc); } else { var p1 = points[j + 1]; _nd = point_direction(_nx, _ny, p1.x + _padx, p1.y + _pady); @@ -675,15 +683,20 @@ function Node_Line(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons 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); + draw_circle_angle(_cps[1] * _aa, _cps[2] * _aa, _cps[3] * _aa, _cps[4], _cps[5], _capP); } } if(_useTex) shader_reset(); surface_reset_target(); + surface_set_shader(_colorPass, sh_downsample, true, BLEND.over); + shader_set_dim("dimension", _cPassAA); + shader_set_f("down", _aa); + draw_surface(_cPassAA, 0, 0); + surface_reset_shader(); + if(_colW && !_1px) { - surface_set_target(_widthPass); if(_bg) draw_clear_alpha(0, 1); else DRAW_CLEAR diff --git a/scripts/node_random_shape/node_random_shape.gml b/scripts/node_random_shape/node_random_shape.gml index bd5e0deee..ec7c55939 100644 --- a/scripts/node_random_shape/node_random_shape.gml +++ b/scripts/node_random_shape/node_random_shape.gml @@ -6,13 +6,18 @@ function Node_Random_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro newInput(1, nodeValue_Int("Seed", self, seed_random(6))) .setDisplay(VALUE_DISPLAY._default, { side_button : button(function() { randomize(); inputs[1].setValue(seed_random(6)); }).setIcon(THEME.icon_random, 0, COLORS._main_icon) }); + newInput(2, nodeValue_Enum_Scroll("SSAA", self, 0, [ "None", "2x", "4x", "8x" ])); + newOutput(0, nodeValue_Output("Surface out", self, VALUE_TYPE.surface, noone)); input_display_list = [ ["Output", false], 0, - ["Shape", false], 1 + ["Shape", false], 1, + ["Render", false], 2, ] + temp_surfaces = [ noone ]; + function surfaceContentRatio(_surf) { var s = 0; var _sw = surface_get_width_safe(_surf); @@ -32,8 +37,11 @@ function Node_Random_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro return s / total; } - function generateShape(_dim) { - var _shap = surface_create(_dim[0], _dim[1]); + function generateShape(_dim, _aa = 1) { + var _sw = _dim[0] * _aa; + var _sh = _dim[1] * _aa; + + var _shap = surface_create(_sw, _sh); surface_set_target(_shap); DRAW_CLEAR draw_set_color(c_white); @@ -43,46 +51,38 @@ function Node_Random_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro repeat(_amou) { var _side = min(_dim[0], _dim[1]); var _size = irandom_range(_side * 0.25, _side * 0.75); - var _shape = surface_create(_size, _size); + var _shape = surface_create(_size * _aa, _size * _aa); surface_set_target(_shape); DRAW_CLEAR draw_set_color(c_white); - var _cx = _size / 2; - var _cy = _size / 2; - var _sx = _size / 2; - var _sy = _size / 2; - - var _x0 = _cx - _sx; - var _y0 = _cy - _sy; - var _x1 = _cx + _sx; - var _y1 = _cy + _sy; - - var _r = irandom(4) * 2; + var _x1 = _size * _aa; + var _y1 = _size * _aa; + var _r = irandom(4) * 2 * _aa; switch(irandom(2)) { - case 0 : draw_roundrect_ext(_x0, _y0, _x1, _y1, _r, _r, false); break; - case 1 : draw_ellipse(_x0, _y0, _x1, _y1, false); break; - case 2 : draw_triangle((_x0 + _x1) / 2, _y0, _x0, _y1, _x1, _y1, false); break; + case 0 : draw_roundrect_ext(0, 0, _x1, _y1, _r, _r, false); break; + case 1 : draw_ellipse(0, 0, _x1, _y1, false); break; + case 2 : draw_triangle(_x1 / 2, 0, 0, _y1, _x1, _y1, false); break; } surface_reset_target(); - var _sx = irandom_range(_dim[0] / 2 - _size / 2, _dim[0] / 2 + _size / 2); - var _sy = irandom_range(_dim[1] / 2 - _size / 2, _dim[1] / 2 + _size / 2); - draw_surface_safe(_shape, _sx - _size / 2, _sy - _size / 2); + var _sx = irandom_range(_dim[0] / 2 - _size, _dim[0] / 2) * _aa; + var _sy = irandom_range(_dim[1] / 2 - _size, _dim[1] / 2) * _aa; + draw_surface_safe(_shape, _sx, _sy); surface_free(_shape); } surface_reset_target(); - var _surf = surface_create(_dim[0], _dim[1]); + var _surf = surface_create(_sw, _sh); surface_set_target(_surf); DRAW_CLEAR - draw_surface_ext_safe(_shap, 0, 0, 1, 1, 0, c_white, 1); - draw_surface_ext_safe(_shap, _dim[0], 0, -1, 1, 0, c_white, 1); - draw_surface_ext_safe(_shap, 0, _dim[1], 1, -1, 0, c_white, 1); - draw_surface_ext_safe(_shap, _dim[0], _dim[1], -1, -1, 0, c_white, 1); + draw_surface_ext_safe(_shap, 0, 0, 1, 1, 0, c_white, 1); + draw_surface_ext_safe(_shap, _sw, 0, -1, 1, 0, c_white, 1); + draw_surface_ext_safe(_shap, 0, _sh, 1, -1, 0, c_white, 1); + draw_surface_ext_safe(_shap, _sw, _sh, -1, -1, 0, c_white, 1); surface_reset_target(); surface_free(_shap); @@ -92,63 +92,72 @@ function Node_Random_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro static processData = function(_outSurf, _data, _output_index, _array_index) { var _dim = _data[0]; var _seed = _data[1]; + var _aa = power(2, _data[2]); random_set_seed(_seed); - var _surf = generateShape(_dim); - var _prog; + var _adim = [ _dim[0] * _aa, _dim[1] * _aa ]; + var _surf = generateShape(_dim, _aa); var _side = irandom(2); + var _prog = _surf; if(random(1) < 0.5) { - _prog = surface_create(_dim[0], _dim[1]); + _prog = surface_create(_adim[0], _adim[1]); var _size = [ _dim[0] * .75, _dim[1] * 0.75 ]; - var _subs = generateShape(_size); - var _sx = _dim[0] / 2; - var _sy = _dim[1] / 2; + var _subs = generateShape(_size, _aa); + var _sx = _adim[0] / 2; + var _sy = _adim[1] / 2; switch(_side) { - case 0 : _sx = irandom_range(_dim[0] / 2 - _size[0] / 2, _dim[0] / 2 + _size[0] / 2); break; - case 1 : _sy = irandom_range(_dim[1] / 2 - _size[1] / 2, _dim[1] / 2 + _size[1] / 2); break; + case 0 : _sx = irandom_range(_dim[0] / 2 - _size[0], _dim[0] / 2) * _aa; break; + case 1 : _sy = irandom_range(_dim[1] / 2 - _size[1], _dim[1] / 2) * _aa; break; } surface_set_target(_prog); DRAW_CLEAR if(random(1) < 0.5) { shader_set(sh_rsh_rotate); - shader_set_f("dimension", _dim[0], _dim[1]); + shader_set_f("dimension", _adim[0], _adim[1]); draw_surface_safe(_surf); shader_reset(); } else draw_surface_safe(_surf); BLEND_SUBTRACT - draw_surface_safe(_subs, _sx - _size[0] / 2, _sy - _size[1] / 2); + draw_surface_safe(_subs, _sx, _sy); BLEND_NORMAL surface_reset_target(); + surface_free(_subs); surface_free(_surf); - } else - _prog = _surf; + } - var _rat = surfaceContentRatio(_prog); - - if(_rat < 0.2) { - surface_free(_prog); - _prog = generateShape(_dim); - } + // if(surfaceContentRatio(_prog) < 0.2) { + // surface_free(_prog); + // _prog = generateShape(_adim); + // } var _corn = surface_create(_dim[0], _dim[1]); - surface_set_shader(_corn, sh_rsh_corner, true, BLEND.add); - shader_set_f("dimension", _dim[0], _dim[1]); + temp_surfaces[0] = surface_verify(temp_surfaces[0], _adim[0], _adim[1]); + var _cPassAA = temp_surfaces[0]; + + surface_set_shader(_cPassAA, sh_rsh_corner, true, BLEND.add); + shader_set_f("dimension", _adim[0], _adim[1]); shader_set_i("type", choose(0, 0, 1, 1, 1)); draw_surface_safe(_prog); - if(_side == 1) draw_surface_ext_safe(_prog, 0, _dim[1], 1, -1, 0, c_white, 1); - if(_side == 2) draw_surface_ext_safe(_prog, _dim[0], 0, -1, 1, 0, c_white, 1); + if(_side == 1) draw_surface_ext_safe(_prog, 0, _adim[1], 1, -1, 0, c_white, 1); + if(_side == 2) draw_surface_ext_safe(_prog, _adim[0], 0, -1, 1, 0, c_white, 1); surface_reset_shader(); surface_free(_prog); + surface_set_shader(_corn, sh_downsample, true, BLEND.over); + shader_set_dim("dimension", _cPassAA); + shader_set_f("down", _aa); + draw_surface(_cPassAA, 0, 0); + surface_reset_shader(); + return _corn; } } diff --git a/scripts/node_shape_polygon/node_shape_polygon.gml b/scripts/node_shape_polygon/node_shape_polygon.gml index 0813fade5..3ff85023c 100644 --- a/scripts/node_shape_polygon/node_shape_polygon.gml +++ b/scripts/node_shape_polygon/node_shape_polygon.gml @@ -67,6 +67,10 @@ function Node_Shape_Polygon(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr newInput(23, nodeValue_Palette("Shape Palette", self, [ cola(c_white) ])); + newInput(24, nodeValue_Enum_Scroll("SSAA", self, 0, [ "None", "2x", "4x", "8x" ])); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + newOutput(0, nodeValue_Output("Surface out", self, VALUE_TYPE.surface, noone)); newOutput(1, nodeValue_Output("Mesh", self, VALUE_TYPE.mesh, noone)); @@ -78,7 +82,7 @@ function Node_Shape_Polygon(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr ["Transform", false], 5, 6, 7, ["Shape", false], 4, 8, 9, 10, 11, 12, 13, 14, 15, 17, ["Piecewise", false], 18, 22, - ["Render", true], 3, 23, 19, 20, 21, + ["Render", true], 3, 23, 19, 20, 21, 24, ["Background", true, 1], 2, ]; @@ -86,6 +90,8 @@ function Node_Shape_Polygon(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr node_draw_transform_init(); + temp_surfaces = [ noone ]; + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { if(array_length(current_data) != array_length(inputs)) return; if(process_amount > 1) return; @@ -98,12 +104,12 @@ function Node_Shape_Polygon(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr path.draw(_x, _y, _s); } - static vertex_apply = function(_p, _pos, _rot, _color = c_white, _alpha = 1) { + static vertex_apply = function(_p, _pos, _rot, _color = c_white, _alpha = 1, _aa = 1) { var p = point_rotate(_p.x, _p.y, 0, 0, _rot); _p.x = _pos[0] + p[0]; _p.y = _pos[1] + p[1]; - draw_vertex_color(_p.x, _p.y, _color, _alpha); + draw_vertex_color(_p.x * _aa, _p.y * _aa, _color, _alpha); } mesh = new Mesh(); @@ -131,6 +137,7 @@ function Node_Shape_Polygon(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr var _prot = _data[18]; var _psca = _data[22]; var _pall = _data[23]; + var _aa = power(2, _data[24]); inputs[ 8].setVisible(false); inputs[ 9].setVisible(false); @@ -190,6 +197,9 @@ function Node_Shape_Polygon(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr var _outSurf = surface_verify(_outData[0], _dim[0], _dim[1], attrDepth()); + temp_surfaces[0] = surface_verify(temp_surfaces[0], _dim[0] * _aa, _dim[1] * _aa, attrDepth()); + var _cPassAA = temp_surfaces[0]; + var data = { side: _side, inner: _inner, @@ -206,7 +216,7 @@ function Node_Shape_Polygon(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr var tri1 = colorMultiply(_shc, _data[20]); var tri2 = colorMultiply(_shc, _data[21]); - surface_set_target(_outSurf); + surface_set_target(_cPassAA); if(_bg) draw_clear(_bgc); else DRAW_CLEAR @@ -221,9 +231,9 @@ function Node_Shape_Polygon(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr var p1 = tri[1]; var p2 = tri[2]; - draw_vertex(p0.x, p0.y); - draw_vertex(p1.x, p1.y); - draw_vertex(p2.x, p2.y); + draw_vertex(p0.x * _aa, p0.y * _aa); + draw_vertex(p1.x * _aa, p1.y * _aa); + draw_vertex(p2.x * _aa, p2.y * _aa); } } else { @@ -258,20 +268,24 @@ function Node_Shape_Polygon(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr var _tri = points[i].triangles; for( var j = 0; j < array_length(_tri); j++ ) { var tri = _tri[j]; - var cx = (tri[0].x + tri[1].x + tri[2].x) / 3; - var cy = (tri[0].y + tri[1].y + tri[2].y) / 3; + var t0 = tri[0]; + var t1 = tri[1]; + var t2 = tri[2]; - var p = point_rotate(tri[0].x - cx, tri[0].y - cy, 0, 0, _prot); - tri[0].x = cx + _psca * p[0]; - tri[0].y = cy + _psca * p[1]; + var cx = (t0.x + t1.x + t2.x) / 3; + var cy = (t0.y + t1.y + t2.y) / 3; - var p = point_rotate(tri[1].x - cx, tri[1].y - cy, 0, 0, _prot); - tri[1].x = cx + _psca * p[0]; - tri[1].y = cy + _psca * p[1]; + var p = point_rotate(t0.x - cx, t0.y - cy, 0, 0, _prot); + t0.x = cx + _psca * p[0]; + t0.y = cy + _psca * p[1]; - var p = point_rotate(tri[2].x - cx, tri[2].y - cy, 0, 0, _prot); - tri[2].x = cx + _psca * p[0]; - tri[2].y = cy + _psca * p[1]; + var p = point_rotate(t1.x - cx, t1.y - cy, 0, 0, _prot); + t1.x = cx + _psca * p[0]; + t1.y = cy + _psca * p[1]; + + var p = point_rotate(t2.x - cx, t2.y - cy, 0, 0, _prot); + t2.x = cx + _psca * p[0]; + t2.y = cy + _psca * p[1]; } } @@ -304,9 +318,9 @@ function Node_Shape_Polygon(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr var shapeind = shapetyp == SHAPE_TYPE.rectangle? floor(j / 2) : j; var trc = array_safe_get(_pall, shapeind % _plen, c_white) - vertex_apply(tri[0], _pos, _rot, colorMultiply(trc, tri0)); - vertex_apply(tri[1], _pos, _rot, colorMultiply(trc, tri1)); - vertex_apply(tri[2], _pos, _rot, colorMultiply(trc, tri2)); + vertex_apply(tri[0], _pos, _rot, colorMultiply(trc, tri0), 1, _aa); + vertex_apply(tri[1], _pos, _rot, colorMultiply(trc, tri1), 1, _aa); + vertex_apply(tri[2], _pos, _rot, colorMultiply(trc, tri2), 1, _aa); array_push(mesh.triangles, tri); } @@ -319,6 +333,12 @@ function Node_Shape_Polygon(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr surface_reset_target(); + surface_set_shader(_outSurf, sh_downsample, true, BLEND.over); + shader_set_dim("dimension", _cPassAA); + shader_set_f("down", _aa); + draw_surface(_cPassAA, 0, 0); + surface_reset_shader(); + return [ _outSurf, mesh, path ]; } } \ No newline at end of file diff --git a/scripts/node_value/node_value.gml b/scripts/node_value/node_value.gml index 29167262d..bb9a7d944 100644 --- a/scripts/node_value/node_value.gml +++ b/scripts/node_value/node_value.gml @@ -1512,7 +1512,6 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru INLINE var res = false; - // _val = unit.invApply(_val); if(PANEL_INSPECTOR && PANEL_INSPECTOR.inspectGroup == 1) { var ind = self.index; diff --git a/scripts/pathnodeBox/pathnodeBox.gml b/scripts/pathnodeBox/pathnodeBox.gml index 11a5f74df..42b5632b4 100644 --- a/scripts/pathnodeBox/pathnodeBox.gml +++ b/scripts/pathnodeBox/pathnodeBox.gml @@ -52,7 +52,7 @@ function pathnodeBox(_junction) : widget() constructor { if(mouse_click(mb_left, iactive)) bi = 2; - if(mouse_press(mb_left, iactive)) + if(mouse_press(mb_left, iactive) && is(_path, Node)) PANEL_GRAPH.setFocusingNode(_path); } @@ -62,7 +62,7 @@ function pathnodeBox(_junction) : widget() constructor { draw_sprite_ext(ic, 0, x + iw / 2, y + h / 2, _s, _s); draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text_sub); - draw_text_add(x + iw + ui(4 + 8), y + h / 2, _path.getDisplayName()); + draw_text_add(x + iw + ui(4 + 8), y + h / 2, is(_path, Node)? _path.getDisplayName() : "Path"); } return h; diff --git a/scripts/preview_overlay_scalar/preview_overlay_scalar.gml b/scripts/preview_overlay_scalar/preview_overlay_scalar.gml index fc5c0c5dc..c207dd129 100644 --- a/scripts/preview_overlay_scalar/preview_overlay_scalar.gml +++ b/scripts/preview_overlay_scalar/preview_overlay_scalar.gml @@ -20,7 +20,7 @@ function preview_overlay_scalar(interact, active, _x, _y, _s, _mx, _my, _snx, _s _dist = round(_dist); _dist *= _sign; - if(setValueInspector( _dist )) + if(setValueInspector( unit.invApply(_dist) )) UNDO_HOLDING = true; if(mouse_release(mb_left)) { diff --git a/scripts/preview_overlay_vector/preview_overlay_vector.gml b/scripts/preview_overlay_vector/preview_overlay_vector.gml index db1145d7a..7dc60bea5 100644 --- a/scripts/preview_overlay_vector/preview_overlay_vector.gml +++ b/scripts/preview_overlay_vector/preview_overlay_vector.gml @@ -39,7 +39,7 @@ function preview_overlay_vector(interact, active, _x, _y, _s, _mx, _my, _snx, _s _val[1] = _ny; } - if(setValueInspector( _val )) + if(setValueInspector( unit.invApply(_val) )) UNDO_HOLDING = true; if(mouse_release(mb_left)) {