Pixel-Composer/scripts/node_crop_content/node_crop_content.gml

148 lines
4.5 KiB
Text
Raw Normal View History

2023-03-05 07:16:44 +01:00
function Node_Crop_Content(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
name = "Crop Content";
2024-08-18 06:16:20 +02:00
newInput(0, nodeValue_Surface("Surface in", self));
2023-03-05 07:16:44 +01:00
2024-08-18 06:16:20 +02:00
newInput(1, nodeValue_Bool("Active", self, true));
2023-03-05 07:16:44 +01:00
2024-08-18 09:13:41 +02:00
newInput(2, nodeValue_Enum_Scroll("Array Sizing", self, 1, [ "Largest, same size", "Independent" ]))
2024-08-07 11:48:39 +02:00
.setTooltip("Cropping mode for dealing with image array.");
2023-03-19 09:17:39 +01:00
2024-08-18 06:16:20 +02:00
newInput(3, nodeValue_Padding("Padding", self, [ 0, 0, 0, 0 ], "Add padding back after crop."));
2024-11-07 07:59:04 +01:00
newInput(4, nodeValue_Color("Background", self, cola(c_black, 0)));
2024-11-23 08:31:15 +01:00
2024-09-04 03:57:11 +02:00
newOutput(0, nodeValue_Output("Surface out", self, VALUE_TYPE.surface, noone));
2023-03-05 07:16:44 +01:00
newOutput(1, nodeValue_Output("Crop distance", self, VALUE_TYPE.integer, [ 0, 0, 0, 0 ]))
.setDisplay(VALUE_DISPLAY.padding);
newOutput(2, nodeValue_Output("Atlas", self, VALUE_TYPE.atlas, []));
2023-03-05 07:16:44 +01:00
input_display_list = [ 1,
2024-11-07 07:59:04 +01:00
["Surfaces", false], 0, 2, 4,
2023-03-19 09:17:39 +01:00
["Padding", false], 3,
2023-03-05 07:16:44 +01:00
]
2023-03-19 09:17:39 +01:00
attribute_surface_depth();
2023-03-05 07:16:44 +01:00
drag_side = -1;
drag_mx = 0;
drag_my = 0;
drag_sv = 0;
2024-11-07 07:59:04 +01:00
temp_surface = [ 0, 0 ];
2023-03-05 07:16:44 +01:00
static update = function() {
var _inSurf = getInputData(0);
var _active = getInputData(1);
var _array = getInputData(2);
var _padd = getInputData(3);
2024-11-07 07:59:04 +01:00
var _bg = getInputData(4);
2023-03-05 07:16:44 +01:00
2024-08-08 06:57:51 +02:00
var _outSurf = outputs[0].getValue();
2023-03-05 07:16:44 +01:00
surface_array_free(_outSurf);
if(!_active) {
_outSurf = surface_array_clone(_inSurf);
2024-08-08 06:57:51 +02:00
outputs[0].setValue(_outSurf);
2023-03-05 07:16:44 +01:00
return;
}
var _arr = is_array(_inSurf);
_array &= _arr;
2023-11-23 13:39:35 +01:00
if(!is_array(_inSurf) && !is_surface(_inSurf)) return;
if( is_array(_inSurf) && array_empty(_inSurf)) return;
2023-03-05 07:16:44 +01:00
if(!_arr) _inSurf = [ _inSurf ];
var _amo = array_length(_inSurf);
var minx = array_create(_amo);
var miny = array_create(_amo);
var maxx = array_create(_amo);
var maxy = array_create(_amo);
2023-03-19 09:17:39 +01:00
var cDep = attrDepth();
2023-03-05 07:16:44 +01:00
for( var j = 0; j < _amo; j++ ) {
2023-03-05 07:16:44 +01:00
var _surf = _inSurf[j];
var _dim = [ surface_get_width_safe(_surf), surface_get_height_safe(_surf) ];
2023-11-23 13:39:35 +01:00
var _minx = 0, _miny = 0, _maxx = _dim[0] - 1, _maxy = _dim[1] - 1;
2023-06-13 14:42:06 +02:00
2024-11-07 07:59:04 +01:00
temp_surface[0] = surface_verify(temp_surface[0], _dim[0], _dim[1], surface_r8unorm);
temp_surface[1] = surface_verify(temp_surface[1], _dim[0], _dim[1], surface_r8unorm);
2023-11-23 13:39:35 +01:00
surface_set_shader(temp_surface[0], sh_find_boundary_stretch_x);
2024-11-07 07:59:04 +01:00
shader_set_color("background", _bg);
2023-11-23 13:39:35 +01:00
shader_set_f("dimension", _dim);
2024-11-07 07:59:04 +01:00
2023-11-23 13:39:35 +01:00
draw_surface_safe(_surf);
surface_reset_shader();
surface_set_shader(temp_surface[1], sh_find_boundary_stretch_y);
2024-11-07 07:59:04 +01:00
shader_set_color("background", _bg);
2023-11-23 13:39:35 +01:00
shader_set_f("dimension", _dim);
2024-11-07 07:59:04 +01:00
2023-11-23 13:39:35 +01:00
draw_surface_safe(_surf);
surface_reset_shader();
2024-11-07 07:59:04 +01:00
var _buff0 = buffer_from_surface(temp_surface[0], false);
var _buff1 = buffer_from_surface(temp_surface[1], false);
for( ; _minx < _dim[0]; _minx++ ) if(buffer_read_at(_buff0, _minx, buffer_u8) > 0) break;
for( ; _maxx >= 0; _maxx-- ) if(buffer_read_at(_buff0, _maxx, buffer_u8) > 0) break;
for( ; _miny < _dim[1]; _miny++ ) if(buffer_read_at(_buff1, _dim[0] * _miny, buffer_u8) > 0) break;
for( ; _maxy >= 0; _maxy-- ) if(buffer_read_at(_buff1, _dim[0] * _maxy, buffer_u8) > 0) break;
buffer_delete(_buff0);
buffer_delete(_buff1);
2023-03-05 07:16:44 +01:00
if(_array) {
2023-03-05 07:16:44 +01:00
minx[j] = _minx;
miny[j] = _miny;
maxx[j] = _maxx;
maxy[j] = _maxy;
} else {
minx[0] = min(minx[0], _minx);
miny[0] = min(miny[0], _miny);
maxx[0] = max(maxx[0], _maxx);
maxy[0] = max(maxy[0], _maxy);
2023-03-05 07:16:44 +01:00
}
}
var res = [];
var crop = [];
var atlas = [];
2023-03-05 07:16:44 +01:00
for( var i = 0, n = _amo; i < n; i++ ) {
2023-03-05 07:16:44 +01:00
var _surf = _inSurf[i];
var _ind = _array == 0? 0 : i;
2023-03-05 07:16:44 +01:00
var resDim = [maxx[_ind] - minx[_ind] + 1, maxy[_ind] - miny[_ind] + 1];
resDim[DIMENSION.width] += _padd[PADDING.left] + _padd[PADDING.right];
resDim[DIMENSION.height] += _padd[PADDING.top] + _padd[PADDING.bottom];
res[i] = surface_create_valid(resDim[DIMENSION.width], resDim[DIMENSION.height], cDep);
crop[i] = [ surface_get_width_safe(_surf) - maxx[_ind] - 1, miny[_ind], minx[_ind], surface_get_height_safe(_surf) - maxy[_ind] - 1 ];
surface_set_shader(res[i], noone);
draw_surface_safe(_surf, -minx[_ind] + _padd[PADDING.left], -miny[_ind] + _padd[PADDING.top]);
surface_reset_shader();
atlas[i] = new SurfaceAtlas(res[i], minx[_ind], miny[_ind]);
2023-03-05 07:16:44 +01:00
}
if(!_arr) {
res = res[0];
crop = crop[0];
atlas = atlas[0];
}
2024-08-08 06:57:51 +02:00
outputs[0].setValue(res);
outputs[1].setValue(crop);
outputs[2].setValue(atlas);
2023-03-05 07:16:44 +01:00
}
}