2023-02-28 09:43:01 +01:00
|
|
|
function Node_Seperate_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
|
2023-01-25 06:49:00 +01:00
|
|
|
name = "Separate Shape";
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2024-08-18 09:13:41 +02:00
|
|
|
newInput(0, nodeValue_Surface("Surface in", self))
|
2023-02-14 05:32:32 +01:00
|
|
|
.rejectArray();
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2024-08-18 09:13:41 +02:00
|
|
|
newInput(1, nodeValue_Float("Tolerance", self, 0.2))
|
2023-10-08 04:14:35 +02:00
|
|
|
.setDisplay(VALUE_DISPLAY.slider, { range: [ 0, 1, 0.01 ], update_stat: SLIDER_UPDATE.release })
|
2023-02-14 05:32:32 +01:00
|
|
|
.rejectArray();
|
2023-01-25 06:49:00 +01:00
|
|
|
|
2024-08-18 09:13:41 +02:00
|
|
|
newInput(2, nodeValue_Bool("Override color", self, false))
|
2023-02-14 05:32:32 +01:00
|
|
|
.rejectArray();
|
2023-01-25 06:49:00 +01:00
|
|
|
|
2024-08-18 09:13:41 +02:00
|
|
|
newInput(3, nodeValue_Color("Color", self, c_white))
|
2023-02-14 05:32:32 +01:00
|
|
|
.rejectArray();
|
2023-01-25 06:49:00 +01:00
|
|
|
|
2024-08-18 09:13:41 +02:00
|
|
|
newInput(4, nodeValue_Bool("Ignore blank", self, true, "Skip empty and black shape."))
|
2023-02-14 05:32:32 +01:00
|
|
|
.rejectArray();
|
2022-01-17 02:19:01 +01:00
|
|
|
|
2024-08-18 09:13:41 +02:00
|
|
|
newInput(5, nodeValue_Enum_Button("Mode", self, 0 , [ "Greyscale", "Alpha" ] ))
|
2024-06-02 05:28:43 +02:00
|
|
|
|
2024-09-04 03:57:11 +02:00
|
|
|
newOutput(0, nodeValue_Output("Surface out", self, VALUE_TYPE.surface, noone));
|
2023-01-17 08:11:55 +01:00
|
|
|
|
2024-09-04 03:57:11 +02:00
|
|
|
newOutput(1, nodeValue_Output("Atlas", self, VALUE_TYPE.surface, []));
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-01-25 06:49:00 +01:00
|
|
|
input_display_list = [
|
2024-06-02 05:28:43 +02:00
|
|
|
["Shape", false], 0, 5, 1, 4,
|
2024-01-08 08:10:50 +01:00
|
|
|
["Override Color", true, 2], 3,
|
2023-01-25 06:49:00 +01:00
|
|
|
]
|
|
|
|
|
2024-04-30 10:49:12 +02:00
|
|
|
temp_surface = [ noone, noone ];
|
2022-01-14 13:47:15 +01:00
|
|
|
surface_buffer = buffer_create(1 * 1 * 4, buffer_fixed, 2);
|
2023-02-14 05:32:32 +01:00
|
|
|
surface_w = 1;
|
|
|
|
surface_h = 1;
|
2022-01-14 13:47:15 +01:00
|
|
|
|
|
|
|
_prev_type = -1;
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-03-28 06:58:28 +02:00
|
|
|
static onInspector1Update = function() { separateShape(); }
|
2023-03-24 05:55:34 +01:00
|
|
|
|
|
|
|
static update = function() {
|
2023-10-06 11:51:11 +02:00
|
|
|
separateShape();
|
2023-03-24 05:55:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static separateShape = function() {
|
2023-10-02 08:57:44 +02:00
|
|
|
var _inSurf = getInputData(0);
|
|
|
|
var _thres = getInputData(1);
|
|
|
|
var _ovr = getInputData(2);
|
|
|
|
var _ovrclr = getInputData(3);
|
|
|
|
var _ignore = getInputData(4);
|
2024-06-02 05:28:43 +02:00
|
|
|
var _mode = getInputData(5);
|
2022-01-16 14:28:57 +01:00
|
|
|
var t = current_time;
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2022-01-16 05:17:35 +01:00
|
|
|
if(!is_surface(_inSurf)) return;
|
|
|
|
|
2023-09-08 21:37:36 +02:00
|
|
|
var ww = surface_get_width_safe(_inSurf);
|
|
|
|
var hh = surface_get_height_safe(_inSurf);
|
2023-10-04 05:52:20 +02:00
|
|
|
|
2024-04-30 10:49:12 +02:00
|
|
|
for(var i = 0; i < 2; i++) temp_surface[i] = surface_verify(temp_surface[i], ww, hh, surface_rgba32float);
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-10-04 05:52:20 +02:00
|
|
|
#region region indexing
|
|
|
|
surface_set_shader(temp_surface[1], sh_seperate_shape_index);
|
2024-06-02 05:28:43 +02:00
|
|
|
shader_set_i("mode", _mode);
|
2024-04-30 10:49:12 +02:00
|
|
|
shader_set_i("ignore", _ignore);
|
|
|
|
shader_set_f("dimension", ww, hh);
|
|
|
|
|
2023-10-04 05:52:20 +02:00
|
|
|
draw_sprite_stretched(s_fx_pixel, 0, 0, 0, ww, hh);
|
|
|
|
surface_reset_shader();
|
2024-04-30 10:49:12 +02:00
|
|
|
|
2023-10-04 05:52:20 +02:00
|
|
|
shader_set(sh_seperate_shape_ite);
|
2024-06-02 05:28:43 +02:00
|
|
|
shader_set_i("mode", _mode);
|
|
|
|
shader_set_i("ignore", _ignore);
|
2023-10-04 05:52:20 +02:00
|
|
|
shader_set_f("dimension", ww, hh);
|
|
|
|
shader_set_f("threshold", _thres);
|
|
|
|
shader_set_surface("map", _inSurf);
|
|
|
|
shader_reset();
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-10-04 05:52:20 +02:00
|
|
|
var res_index = 0, iteration = ww + hh;
|
|
|
|
for(var i = 0; i <= iteration; i++) {
|
|
|
|
var bg = i % 2;
|
|
|
|
var fg = !bg;
|
2024-04-30 10:49:12 +02:00
|
|
|
|
2023-10-04 05:52:20 +02:00
|
|
|
surface_set_shader(temp_surface[bg], sh_seperate_shape_ite,, BLEND.over);
|
2024-04-30 10:49:12 +02:00
|
|
|
draw_surface_safe(temp_surface[fg]);
|
2023-10-04 05:52:20 +02:00
|
|
|
surface_reset_shader();
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-10-04 05:52:20 +02:00
|
|
|
res_index = bg;
|
|
|
|
}
|
|
|
|
#endregion
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-10-04 05:52:20 +02:00
|
|
|
#region count and match color
|
2024-04-30 10:49:12 +02:00
|
|
|
var i = 0, pxc = ww * hh;
|
|
|
|
var reg = ds_map_create();
|
2023-10-04 05:52:20 +02:00
|
|
|
|
2024-04-30 10:49:12 +02:00
|
|
|
var b = buffer_create(pxc * 16, buffer_fixed, 1);
|
|
|
|
buffer_get_surface(b, temp_surface[res_index], 0);
|
|
|
|
buffer_seek(b, buffer_seek_start, 0);
|
|
|
|
|
|
|
|
repeat(pxc) {
|
|
|
|
var _r = buffer_read(b, buffer_f32);
|
|
|
|
var _g = buffer_read(b, buffer_f32);
|
|
|
|
var _b = buffer_read(b, buffer_f32);
|
|
|
|
var _a = buffer_read(b, buffer_f32);
|
|
|
|
|
|
|
|
if(_r == 0 && _g == 0 && _b == 0 && _a == 0) continue;
|
|
|
|
|
|
|
|
reg[? _g * ww + _r] = [ _r, _g, _b, _a ];
|
|
|
|
}
|
|
|
|
|
|
|
|
var px = ds_map_size(reg);
|
2023-10-04 05:52:20 +02:00
|
|
|
if(px == 0) return;
|
|
|
|
#endregion
|
2023-01-25 06:49:00 +01:00
|
|
|
|
2023-10-04 05:52:20 +02:00
|
|
|
#region extract region
|
|
|
|
var _outSurf, _val;
|
|
|
|
_val = array_create(px);
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-10-04 05:52:20 +02:00
|
|
|
var _atlas = array_create(px);
|
2024-06-02 05:28:43 +02:00
|
|
|
var key = ds_map_keys_to_array(reg);
|
2024-04-30 10:49:12 +02:00
|
|
|
var _ind = 0;
|
2022-01-16 14:28:57 +01:00
|
|
|
|
2023-10-04 05:52:20 +02:00
|
|
|
for(var i = 0; i < px; i++) {
|
2024-06-02 05:28:43 +02:00
|
|
|
var _k = key[i];
|
2024-04-30 10:49:12 +02:00
|
|
|
var ccx = reg[? _k];
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2024-04-30 10:49:12 +02:00
|
|
|
var min_x = round(ccx[0]);
|
|
|
|
var min_y = round(ccx[1]);
|
|
|
|
var max_x = round(ccx[2]);
|
|
|
|
var max_y = round(ccx[3]);
|
2023-10-06 11:51:11 +02:00
|
|
|
|
2024-04-30 10:49:12 +02:00
|
|
|
var _sw = max_x - min_x + 1;
|
|
|
|
var _sh = max_y - min_y + 1;
|
|
|
|
|
|
|
|
if(_sw <= 1 || _sh <= 1) continue;
|
2023-10-04 05:52:20 +02:00
|
|
|
|
2024-04-30 10:49:12 +02:00
|
|
|
_outSurf = surface_create_valid(_sw, _sh);
|
|
|
|
_val[_ind] = _outSurf;
|
2023-10-06 11:51:11 +02:00
|
|
|
|
|
|
|
surface_set_shader(_outSurf, sh_seperate_shape_sep);
|
2023-10-04 05:52:20 +02:00
|
|
|
shader_set_surface("original", _inSurf);
|
2024-04-30 10:49:12 +02:00
|
|
|
shader_set_f("color", ccx);
|
|
|
|
shader_set_i("override", _ovr);
|
|
|
|
shader_set_color("overColor", _ovrclr);
|
|
|
|
|
|
|
|
draw_surface_safe(temp_surface[res_index], -min_x, -min_y);
|
2023-10-04 05:52:20 +02:00
|
|
|
surface_reset_shader();
|
2023-10-06 11:51:11 +02:00
|
|
|
|
2024-04-30 10:49:12 +02:00
|
|
|
_atlas[_ind] = new SurfaceAtlas(_outSurf, min_x, min_y).setOrginalSurface(_inSurf);
|
|
|
|
_ind++;
|
2023-10-04 05:52:20 +02:00
|
|
|
}
|
2023-01-25 06:49:00 +01:00
|
|
|
|
2024-04-30 10:49:12 +02:00
|
|
|
array_resize(_val, _ind);
|
|
|
|
array_resize(_atlas, _ind);
|
|
|
|
|
|
|
|
ds_map_destroy(reg);
|
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
outputs[0].setValue(_val);
|
|
|
|
outputs[1].setValue(_atlas);
|
2023-10-04 05:52:20 +02:00
|
|
|
#endregion
|
2022-01-13 05:24:03 +01:00
|
|
|
}
|
|
|
|
}
|