Pixel-Composer/scripts/node_image_sheet/node_image_sheet.gml

425 lines
13 KiB
Plaintext
Raw Normal View History

2023-02-28 09:43:01 +01:00
function Node_Image_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
2023-01-25 06:49:00 +01:00
name = "Splice Spritesheet";
2022-01-13 05:24:03 +01:00
2024-03-14 14:35:19 +01:00
inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone);
2022-01-13 05:24:03 +01:00
2023-02-14 05:32:32 +01:00
inputs[| 1] = nodeValue("Sprite size", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 32, 32 ])
2022-01-13 05:24:03 +01:00
.setDisplay(VALUE_DISPLAY.vector);
2023-02-14 05:32:32 +01:00
inputs[| 2] = nodeValue("Row", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1); //unused
inputs[| 3] = nodeValue("Amount", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 1, 1 ])
2022-12-19 13:35:30 +01:00
.setDisplay(VALUE_DISPLAY.vector);
2022-01-13 05:24:03 +01:00
2023-02-14 05:32:32 +01:00
inputs[| 4] = nodeValue("Offset", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 0, 0 ])
2022-01-13 05:24:03 +01:00
.setDisplay(VALUE_DISPLAY.vector);
2023-02-14 05:32:32 +01:00
inputs[| 5] = nodeValue("Spacing", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 0, 0 ])
2022-01-13 05:24:03 +01:00
.setDisplay(VALUE_DISPLAY.vector);
2023-02-14 05:32:32 +01:00
inputs[| 6] = nodeValue("Padding", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [0, 0, 0, 0])
2022-01-13 05:24:03 +01:00
.setDisplay(VALUE_DISPLAY.padding);
2023-02-14 05:32:32 +01:00
inputs[| 7] = nodeValue("Output", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1)
2023-12-05 04:28:49 +01:00
.setDisplay(VALUE_DISPLAY.enum_scroll, [ "Animation", "Array" ]);
2022-01-13 05:24:03 +01:00
2023-02-14 05:32:32 +01:00
inputs[| 8] = nodeValue("Animation speed", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1);
2022-01-13 05:24:03 +01:00
2023-02-14 05:32:32 +01:00
inputs[| 9] = nodeValue("Orientation", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
2024-01-28 09:53:41 +01:00
.setDisplay(VALUE_DISPLAY.enum_scroll, [ new scrollItem("Horizontal", s_node_alignment, 0),
new scrollItem("Vertical", s_node_alignment, 1), ]);
2022-01-13 05:24:03 +01:00
2023-03-31 06:59:08 +02:00
inputs[| 10] = nodeValue("Auto fill", self, JUNCTION_CONNECT.input, VALUE_TYPE.trigger, 0, "Automatically set amount based on sprite size.")
2023-10-12 07:07:24 +02:00
.setDisplay(VALUE_DISPLAY.button, { name: "Auto fill", onClick: function() { #region
var _sur = getInputData(0);
2022-01-13 05:24:03 +01:00
if(!is_surface(_sur) || _sur == DEF_SURFACE) return;
2023-09-08 21:37:36 +02:00
var ww = surface_get_width_safe(_sur);
var hh = surface_get_height_safe(_sur);
2022-01-13 05:24:03 +01:00
var _size = getInputData(1);
var _offs = getInputData(4);
var _spac = getInputData(5);
var _orie = getInputData(9);
2022-01-13 05:24:03 +01:00
var sh_w = _size[0] + _spac[0];
var sh_h = _size[1] + _spac[1];
var fill_w = floor((ww - _offs[0]) / sh_w);
var fill_h = floor((hh - _offs[1]) / sh_h);
2022-12-19 13:35:30 +01:00
2023-10-12 07:07:24 +02:00
if(_orie == 0) inputs[| 3].setValue([ fill_w, fill_h ]);
else inputs[| 3].setValue([ fill_h, fill_w ]);
2022-01-13 05:24:03 +01:00
2023-10-12 07:07:24 +02:00
doUpdate();
} }); #endregion
2022-11-14 03:16:15 +01:00
2023-03-28 06:58:28 +02:00
inputs[| 11] = nodeValue("Sync animation", self, JUNCTION_CONNECT.input, VALUE_TYPE.trigger, 0)
.setDisplay(VALUE_DISPLAY.button, { name: "Sync frames", onClick: function() {
2023-06-04 12:38:40 +02:00
var _atl = outputs[| 1].getValue();
var _spd = getInputData(8);
2023-10-09 16:07:33 +02:00
TOTAL_FRAMES = max(1, _spd == 0? 1 : ceil(array_length(_atl) / _spd));
} });
2023-01-17 08:11:55 +01:00
2023-02-14 05:32:32 +01:00
inputs[| 12] = nodeValue("Filter empty output", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false);
2023-03-31 06:59:08 +02:00
inputs[| 13] = nodeValue("Filtered Pixel", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
.setDisplay(VALUE_DISPLAY.enum_scroll, [ "Transparent", "Color" ]);
inputs[| 14] = nodeValue("Filtered Color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_black)
2022-01-13 05:24:03 +01:00
input_display_list = [
2023-03-31 06:59:08 +02:00
["Sprite", false], 0, 1, 6,
["Sheet", false], 3, 10, 9, 4, 5,
2024-01-09 03:39:40 +01:00
["Output", false], 7, 8, 11,
["Filter Empty", true, 12], 13, 14,
2022-01-13 05:24:03 +01:00
];
2023-02-14 05:32:32 +01:00
outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
2022-01-13 05:24:03 +01:00
2023-10-06 11:51:11 +02:00
outputs[| 1] = nodeValue("Atlas Data", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, [])
2023-03-19 09:17:39 +01:00
.setArrayDepth(1);
attribute_surface_depth();
2022-12-19 13:35:30 +01:00
drag_type = 0;
drag_sx = 0;
drag_sy = 0;
drag_mx = 0;
drag_my = 0;
curr_off = [0, 0];
curr_dim = [0, 0];
curr_amo = [0, 0];
2022-01-13 05:24:03 +01:00
2023-11-25 08:54:35 +01:00
surf_array = [];
atls_array = [];
surf_size_w = 1;
surf_size_h = 1;
surf_space = 0;
surf_origin = 0;
sprite_pos = [];
2023-01-17 08:11:55 +01:00
sprite_valid = [];
2023-10-12 07:07:24 +02:00
spliceSurf = noone;
2023-01-17 08:11:55 +01:00
2023-11-26 13:16:38 +01:00
temp_surface = [ noone ];
static getPreviewValues = function() { return getInputData(0); }
2022-01-13 05:24:03 +01:00
2023-10-12 07:07:24 +02:00
static onValueFromUpdate = function() { _inSurf = noone; }
static onValueUpdate = function() { _inSurf = noone; }
function getSpritePosition(index) { #region
2022-12-19 13:35:30 +01:00
var _dim = curr_dim;
var _col = curr_amo[0];
var _off = curr_off;
2023-11-25 08:54:35 +01:00
var _spa = surf_space;
var _ori = surf_origin;
2022-01-13 05:24:03 +01:00
var _irow = floor(index / _col);
var _icol = safe_mod(index, _col);
var _x, _y;
var _x = _off[0] + _icol * (_dim[0] + _spa[0]);
var _y = _off[1] + _irow * (_dim[1] + _spa[1]);
2023-11-25 08:54:35 +01:00
if(_ori == 0) return [ _x, _y ];
else return [ _y, _x ];
} #endregion
2022-01-13 05:24:03 +01:00
2024-03-14 14:35:19 +01:00
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region
var _inSurf = getInputData(0);
2022-12-27 13:30:02 +01:00
if(!is_surface(_inSurf)) return;
2022-01-13 05:24:03 +01:00
var _out = getInputData(7);
var _spc = getInputData(5);
2023-02-14 05:32:32 +01:00
2022-12-19 13:35:30 +01:00
if(drag_type == 0) {
curr_dim = getInputData(1);
curr_amo = getInputData(3);
curr_off = getInputData(4);
2022-12-19 13:35:30 +01:00
}
2022-01-13 05:24:03 +01:00
2024-03-31 05:36:11 +02:00
var _amo = array_safe_get_fast(curr_amo, 0) * array_safe_get_fast(curr_amo, 1);
2022-12-27 13:30:02 +01:00
2023-11-25 08:54:35 +01:00
if(_amo < 256) {
for(var i = _amo - 1; i >= 0; i--) {
2024-03-31 05:36:11 +02:00
if(!array_safe_get_fast(sprite_valid, i, false))
2023-11-25 08:54:35 +01:00
continue;
2023-01-17 08:11:55 +01:00
2023-11-25 08:54:35 +01:00
var _f = sprite_pos[i];
var _fx0 = _x + _f[0] * _s;
var _fy0 = _y + _f[1] * _s;
var _fx1 = _fx0 + curr_dim[0] * _s;
var _fy1 = _fy0 + curr_dim[1] * _s;
draw_set_color(COLORS._main_accent);
draw_set_alpha(i == 0? 1 : 0.75);
draw_rectangle(_fx0, _fy0, _fx1 - 1, _fy1 - 1, true);
draw_set_alpha(1);
}
} else {
var _f = sprite_pos[0];
2022-12-19 13:35:30 +01:00
var _fx0 = _x + _f[0] * _s;
var _fy0 = _y + _f[1] * _s;
var _fx1 = _fx0 + curr_dim[0] * _s;
var _fy1 = _fy0 + curr_dim[1] * _s;
2022-01-13 05:24:03 +01:00
2022-11-18 03:20:31 +01:00
draw_set_color(COLORS._main_accent);
2022-12-19 13:35:30 +01:00
draw_rectangle(_fx0, _fy0, _fx1 - 1, _fy1 - 1, true);
2022-01-13 05:24:03 +01:00
}
2022-12-19 13:35:30 +01:00
var __ax = curr_off[0];
var __ay = curr_off[1];
var __aw = curr_dim[0];
var __ah = curr_dim[1];
var _ax = __ax * _s + _x;
var _ay = __ay * _s + _y;
var _aw = __aw * _s;
var _ah = __ah * _s;
var _bw = curr_amo[0] * (curr_dim[0] + _spc[0]) - _spc[0]; _bw *= _s;
var _bh = curr_amo[1] * (curr_dim[1] + _spc[1]) - _spc[1]; _bh *= _s;
2022-01-13 05:24:03 +01:00
2023-04-08 20:06:27 +02:00
draw_sprite_colored(THEME.anchor, 0, _ax, _ay);
draw_sprite_colored(THEME.anchor_selector, 0, _ax + _aw, _ay + _ah);
draw_sprite_colored(THEME.anchor_arrow, 0, _ax + _bw + _s * 4, _ay + _bh / 2);
draw_sprite_colored(THEME.anchor_arrow, 0, _ax + _bw / 2, _ay + _bh + _s * 4,, -90);
2022-12-19 13:35:30 +01:00
if(active) {
if(point_in_circle(_mx, _my, _ax + _aw, _ay + _ah, 8))
2023-04-08 20:06:27 +02:00
draw_sprite_colored(THEME.anchor_selector, 1, _ax + _aw, _ay + _ah);
2022-12-19 13:35:30 +01:00
else if(point_in_rectangle(_mx, _my, _ax - _aw, _ay - _ah, _ax + _aw, _ay + _ah))
2023-04-08 20:06:27 +02:00
draw_sprite_colored(THEME.anchor, 0, _ax, _ay, 1.25, c_white);
2022-12-19 13:35:30 +01:00
else if(point_in_circle(_mx, _my, _ax + _bw + _s * 4, _ay + _bh / 2, 8))
2023-04-08 20:06:27 +02:00
draw_sprite_colored(THEME.anchor_arrow, 1, _ax + _bw + _s * 4, _ay + _bh / 2);
2022-12-19 13:35:30 +01:00
else if(point_in_circle(_mx, _my, _ax + _bw / 2, _ay + _bh + _s * 4, 8))
2023-04-08 20:06:27 +02:00
draw_sprite_colored(THEME.anchor_arrow, 1, _ax + _bw / 2, _ay + _bh + _s * 4,, -90);
2022-12-19 13:35:30 +01:00
}
#region area
var __dim = getInputData(1);
var __amo = getInputData(3);
var __off = getInputData(4);
2022-12-19 13:35:30 +01:00
var _ax = __off[0] * _s + _x;
var _ay = __off[1] * _s + _y;
var _aw = __dim[0] * _s;
var _ah = __dim[1] * _s;
2023-11-25 08:54:35 +01:00
2022-12-19 13:35:30 +01:00
if(drag_type == 1) {
var _xx = value_snap(round(drag_sx + (_mx - drag_mx) / _s), _snx);
var _yy = value_snap(round(drag_sy + (_my - drag_my) / _s), _sny);
2023-12-05 04:28:49 +01:00
var off = [ _xx, _yy ];
2022-12-19 13:35:30 +01:00
curr_off = off;
if(mouse_release(mb_left)) {
drag_type = 0;
inputs[| 4].setValue(off);
}
} else if(drag_type == 2) {
var _dx = value_snap(round(abs((_mx - drag_mx) / _s)), _snx);
var _dy = value_snap(round(abs((_my - drag_my) / _s)), _sny);
var dim = [_dx, _dy];
curr_dim = dim;
2023-02-14 05:32:32 +01:00
if(key_mod_press(SHIFT)) {
2022-12-19 13:35:30 +01:00
dim[0] = max(_dx, _dy);
dim[1] = max(_dx, _dy);
2022-01-13 05:24:03 +01:00
}
2022-12-19 13:35:30 +01:00
if(mouse_release(mb_left)) {
drag_type = 0;
inputs[| 1].setValue(dim);
}
} else if(drag_type == 3) {
var _col = floor((abs(_mx - drag_mx) / _s - _spc[0]) / (__dim[0] + _spc[0]));
2023-12-05 04:28:49 +01:00
curr_amo = [ _col, curr_amo[1] ];
2022-01-13 05:24:03 +01:00
2022-12-19 13:35:30 +01:00
if(mouse_release(mb_left)) {
drag_type = 0;
inputs[| 3].setValue(curr_amo);
2022-01-13 05:24:03 +01:00
}
2022-12-19 13:35:30 +01:00
} else if(drag_type == 4) {
var _row = floor((abs(_my - drag_my) / _s - _spc[1]) / (__dim[1] + _spc[1]));
2023-12-05 04:28:49 +01:00
curr_amo = [ curr_amo[0], _row ];
2022-01-13 05:24:03 +01:00
2022-12-19 13:35:30 +01:00
if(mouse_release(mb_left)) {
drag_type = 0;
inputs[| 3].setValue(curr_amo);
2022-01-13 05:24:03 +01:00
}
2022-12-19 13:35:30 +01:00
}
2022-01-13 05:24:03 +01:00
2022-12-19 13:35:30 +01:00
if(mouse_press(mb_left, active)) {
if(point_in_circle(_mx, _my, _ax + _aw, _ay + _ah, 8)) { // drag size
drag_type = 2;
drag_mx = _ax;
drag_my = _ay;
} else if(point_in_rectangle(_mx, _my, _ax - _aw, _ay - _ah, _ax + _aw, _ay + _ah)) { // drag position
drag_type = 1;
drag_sx = __off[0];
drag_sy = __off[1];
drag_mx = _mx;
drag_my = _my;
} else if(point_in_circle(_mx, _my, _ax + _bw + _s * 4, _ay + _bh / 2, 8)) { // drag col
drag_type = 3;
drag_mx = _ax;
drag_my = _ay;
} else if(point_in_circle(_mx, _my, _ax + _bw / 2, _ay + _bh + _s * 4, 8)) { // drag row
drag_type = 4;
drag_mx = _ax;
drag_my = _ay;
}
2022-01-13 05:24:03 +01:00
}
2022-12-19 13:35:30 +01:00
#endregion
2023-10-12 07:07:24 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-10-12 07:07:24 +02:00
static step = function() { #region
var _out = getInputData(7);
var _flty = getInputData(13);
2023-03-31 06:59:08 +02:00
2023-01-17 08:11:55 +01:00
inputs[| 11].setVisible(!_out);
inputs[| 8].setVisible(!_out);
2024-01-09 03:39:40 +01:00
inputs[| 14].setVisible(_flty);
2023-10-12 07:07:24 +02:00
} #endregion
2023-01-17 08:11:55 +01:00
2023-10-12 07:07:24 +02:00
static spliceSprite = function() { #region
2023-11-25 08:54:35 +01:00
var _inSurf = getInputData(0);
if(!is_surface(_inSurf)) return;
2023-11-25 08:54:35 +01:00
spliceSurf = _inSurf;
2022-01-13 05:24:03 +01:00
var _outSurf = outputs[| 0].getValue();
var _out = getInputData(7);
2022-01-13 05:24:03 +01:00
var _dim = getInputData(1);
var _amo = getInputData(3);
var _off = getInputData(4);
2022-12-19 13:35:30 +01:00
var _total = _amo[0] * _amo[1];
var _pad = getInputData(6);
2022-01-13 05:24:03 +01:00
2023-11-26 13:16:38 +01:00
surf_space = getInputData(5);
surf_origin = getInputData(9);
2022-01-13 05:24:03 +01:00
var ww = _dim[0] + _pad[0] + _pad[2];
var hh = _dim[1] + _pad[1] + _pad[3];
2023-11-25 08:54:35 +01:00
var _resizeSurf = surf_size_w != ww || surf_size_h != hh;
surf_size_w = ww;
surf_size_h = hh;
var _filt = getInputData(12);
var _fltp = getInputData(13);
var _flcl = getInputData(14);
2023-03-31 06:59:08 +02:00
2023-03-19 09:17:39 +01:00
var cDep = attrDepth();
2022-12-27 13:30:02 +01:00
curr_dim = _dim;
2023-01-17 08:11:55 +01:00
curr_amo = is_array(_amo)? _amo : [1, 1];
2022-12-27 13:30:02 +01:00
curr_off = _off;
2023-01-17 08:11:55 +01:00
2023-11-25 08:54:35 +01:00
if(ww <= 1 || hh <= 1) return;
2023-01-17 08:11:55 +01:00
2023-11-25 08:54:35 +01:00
if(_filt) {
var filSize = 4;
2023-11-26 13:16:38 +01:00
temp_surface[0] = surface_verify(temp_surface[0], surface_get_width_safe(_inSurf), surface_get_height_safe(_inSurf));
surface_set_shader(temp_surface[0], sh_slice_spritesheet_empty_scan);
shader_set_dim("dimension", _inSurf);
2023-12-05 04:28:49 +01:00
shader_set_f("paddingStart", _off[0], _off[1]);
2023-11-26 13:16:38 +01:00
shader_set_f("spacing", surf_space[0], surf_space[1]);
shader_set_f("spriteDim", _dim[0], _dim[1]);
shader_set_color("color", _flcl);
shader_set_i("empty", !_fltp);
draw_surface(_inSurf, 0, 0);
surface_reset_shader();
2023-11-25 08:54:35 +01:00
}
var _atl = array_create(_total);
var _sar = array_create(_total);
var _arrAmo = 0;
for(var i = 0; i < _total; i++)
sprite_pos[i] = getSpritePosition(i);
2023-01-25 06:49:00 +01:00
for(var i = 0; i < _total; i++) {
2024-03-31 05:36:11 +02:00
var _s = array_safe_get_fast(surf_array, i);
2023-11-25 08:54:35 +01:00
2023-11-26 13:16:38 +01:00
if(!is_surface(_s))
_s = surface_create(ww, hh, cDep);
2023-11-25 08:54:35 +01:00
else if(surface_get_format(_s) != cDep) {
surface_free(_s);
_s = surface_create(ww, hh, cDep);
2023-11-26 13:16:38 +01:00
} else if(_resizeSurf)
surface_resize(_s, ww, hh);
2023-11-25 08:54:35 +01:00
2024-03-31 05:36:11 +02:00
var _a = array_safe_get_fast(atls_array, i, 0);
2023-11-25 08:54:35 +01:00
if(_a == 0) _a = new SurfaceAtlas(_s, 0, 0);
else _a.setSurface(_s);
var _spr_pos = sprite_pos[i];
2022-01-13 05:24:03 +01:00
2023-01-25 06:49:00 +01:00
surface_set_target(_s);
2023-11-25 08:54:35 +01:00
DRAW_CLEAR
draw_surface_part(_inSurf, _spr_pos[0], _spr_pos[1], _dim[0], _dim[1], _pad[2], _pad[1]);
2022-01-13 05:24:03 +01:00
surface_reset_target();
2023-11-25 08:54:35 +01:00
_a.x = _spr_pos[0];
_a.y = _spr_pos[1];
2022-01-13 05:24:03 +01:00
2023-11-25 08:54:35 +01:00
if(!_filt) {
_atl[_arrAmo] = _a;
_sar[_arrAmo] = _s;
_arrAmo++;
sprite_valid[i] = true;
continue;
}
2023-12-05 04:28:49 +01:00
var empPx = surface_get_pixel_ext(temp_surface[0], _spr_pos[0], _spr_pos[1]);
2023-11-26 13:16:38 +01:00
var empty = empPx == 0.;
2023-01-17 08:11:55 +01:00
2023-11-25 08:54:35 +01:00
if(!empty) {
_atl[_arrAmo] = _a;
_sar[_arrAmo] = _s;
_arrAmo++;
2022-01-13 05:24:03 +01:00
}
2023-11-25 08:54:35 +01:00
sprite_valid[i] = !empty;
2022-01-13 05:24:03 +01:00
}
2023-11-14 14:29:11 +01:00
2023-11-25 08:54:35 +01:00
for( var i = _arrAmo, n = array_length(surf_array); i < n; i++ )
if(is_surface(surf_array[i])) surface_free(surf_array[i]);
surf_array = array_create(_arrAmo);
array_copy(surf_array, 0, _sar, 0, _arrAmo);
atls_array = array_create(_arrAmo);
array_copy(atls_array, 0, _atl, 0, _arrAmo);
2023-03-19 09:17:39 +01:00
if(_out == 1) outputs[| 0].setValue(surf_array);
2023-11-25 08:54:35 +01:00
outputs[| 1].setValue(atls_array);
2023-10-12 07:07:24 +02:00
} #endregion
2023-01-25 06:49:00 +01:00
2023-10-12 07:07:24 +02:00
static update = function(frame = CURRENT_FRAME) { #region
spliceSprite();
2023-02-14 13:44:46 +01:00
2023-11-25 08:54:35 +01:00
var _out = getInputData(7);
2023-01-25 06:49:00 +01:00
if(_out == 1) {
update_on_frame = false;
return;
}
var _spd = getInputData(8);
2023-01-25 06:49:00 +01:00
update_on_frame = true;
2023-02-14 05:32:32 +01:00
if(array_length(surf_array)) {
2023-10-09 16:07:33 +02:00
var ind = safe_mod(CURRENT_FRAME * _spd, array_length(surf_array));
2024-03-31 05:36:11 +02:00
outputs[| 0].setValue(array_safe_get_fast(surf_array, ind));
2023-02-14 05:32:32 +01:00
}
2023-10-12 07:07:24 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
}