2023-01-17 08:11:55 +01:00
|
|
|
enum NODE_SEP_SHAPE_OUTPUT_TYPE {
|
|
|
|
node,
|
|
|
|
array
|
|
|
|
}
|
|
|
|
|
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";
|
2023-02-14 05:32:32 +01:00
|
|
|
error_update_enabled = true;
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-02-14 05:32:32 +01:00
|
|
|
inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, 0)
|
|
|
|
.rejectArray();
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-02-14 05:32:32 +01:00
|
|
|
inputs[| 1] = nodeValue("Tolerance", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.2)
|
|
|
|
.setDisplay(VALUE_DISPLAY.slider, [0, 1, 0.01])
|
|
|
|
.rejectArray();
|
2023-01-25 06:49:00 +01:00
|
|
|
|
2023-02-14 05:32:32 +01:00
|
|
|
inputs[| 2] = nodeValue("Override color", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true)
|
|
|
|
.rejectArray();
|
2023-01-25 06:49:00 +01:00
|
|
|
|
2023-02-14 05:32:32 +01:00
|
|
|
inputs[| 3] = nodeValue("Color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_white)
|
|
|
|
.rejectArray();
|
2023-01-25 06:49:00 +01:00
|
|
|
|
2023-02-14 05:32:32 +01:00
|
|
|
inputs[| 4] = nodeValue("Ignore blank", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false, "Skip empty and black shape.")
|
|
|
|
.rejectArray();
|
2022-01-17 02:19:01 +01:00
|
|
|
|
2023-02-14 05:32:32 +01:00
|
|
|
outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
|
2023-01-17 08:11:55 +01:00
|
|
|
|
2023-02-14 05:32:32 +01:00
|
|
|
outputs[| 1] = nodeValue("Shape map", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
|
2023-01-17 08:11:55 +01:00
|
|
|
|
2023-02-14 05:32:32 +01:00
|
|
|
outputs[| 2] = nodeValue("Boundary data", self, JUNCTION_CONNECT.output, VALUE_TYPE.integer, []);
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-01-25 06:49:00 +01:00
|
|
|
input_display_list = [
|
|
|
|
["Shape", false], 0, 1, 4,
|
|
|
|
["Render", false], 2, 3,
|
|
|
|
]
|
|
|
|
|
2023-02-23 07:02:19 +01:00
|
|
|
temp_surface = [ surface_create(1, 1), surface_create(1, 1) ];
|
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
|
|
|
|
2023-02-14 05:32:32 +01:00
|
|
|
function get_color_buffer(_x, _y) {
|
|
|
|
buffer_seek(surface_buffer, buffer_seek_start, (surface_w * _y + _x) * 4);
|
2022-01-14 13:47:15 +01:00
|
|
|
var c = buffer_read(surface_buffer, buffer_u32);
|
2022-01-16 14:28:57 +01:00
|
|
|
return c;
|
2022-01-14 13:47:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
_prev_type = -1;
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-02-14 05:32:32 +01:00
|
|
|
static onInspectorUpdate = function() {
|
2022-01-13 05:24:03 +01:00
|
|
|
var _inSurf = inputs[| 0].getValue();
|
2023-01-25 06:49:00 +01:00
|
|
|
var _thres = inputs[| 1].getValue();
|
|
|
|
var _ovr = inputs[| 2].getValue();
|
|
|
|
var _ovrclr = inputs[| 3].getValue();
|
|
|
|
var _ignore = inputs[| 4].getValue();
|
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;
|
|
|
|
|
2022-01-13 05:24:03 +01:00
|
|
|
var ww = surface_get_width(_inSurf);
|
|
|
|
var hh = surface_get_height(_inSurf);
|
2023-02-14 05:32:32 +01:00
|
|
|
surface_w = ww;
|
|
|
|
surface_h = hh;
|
|
|
|
|
2022-01-13 05:24:03 +01:00
|
|
|
for(var i = 0; i < 2; i++) {
|
2023-02-23 07:02:19 +01:00
|
|
|
temp_surface[i] = surface_verify(temp_surface[i], ww, hh);
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-02-23 07:02:19 +01:00
|
|
|
surface_set_target(temp_surface[i]);
|
2022-01-13 05:24:03 +01:00
|
|
|
draw_clear_alpha(0, 0);
|
|
|
|
surface_reset_target();
|
|
|
|
}
|
|
|
|
|
|
|
|
shader_set(sh_seperate_shape_index);
|
2023-01-25 06:49:00 +01:00
|
|
|
shader_set_uniform_i(shader_get_uniform(sh_seperate_shape_index, "ignore"), _ignore);
|
2023-02-23 07:02:19 +01:00
|
|
|
surface_set_target(temp_surface[1]);
|
2023-01-25 06:49:00 +01:00
|
|
|
draw_sprite_stretched(s_fx_pixel, 0, 0, 0, ww, hh);
|
2022-01-13 05:24:03 +01:00
|
|
|
surface_reset_target();
|
|
|
|
shader_reset();
|
|
|
|
|
2023-01-25 06:49:00 +01:00
|
|
|
shader_set(sh_seperate_shape_ite);
|
|
|
|
shader_set_uniform_i(shader_get_uniform(sh_seperate_shape_ite, "ignore"), _ignore);
|
|
|
|
shader_set_uniform_f(shader_get_uniform(sh_seperate_shape_ite, "dimension"), ww, hh);
|
|
|
|
shader_set_uniform_f(shader_get_uniform(sh_seperate_shape_ite, "threshold"), _thres);
|
2023-02-14 05:32:32 +01:00
|
|
|
if(is_surface(_inSurf))
|
|
|
|
texture_set_stage(shader_get_sampler_index(sh_seperate_shape_ite, "map"), surface_get_texture(_inSurf));
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2022-01-16 14:28:57 +01:00
|
|
|
var res_index = 0, iteration = ww + hh;
|
2022-01-13 05:24:03 +01:00
|
|
|
for(var i = 0; i <= iteration; i++) {
|
|
|
|
var bg = i % 2;
|
2023-01-25 06:49:00 +01:00
|
|
|
var fg = !bg;
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-02-23 07:02:19 +01:00
|
|
|
surface_set_target(temp_surface[bg]);
|
2022-01-13 05:24:03 +01:00
|
|
|
draw_clear_alpha(0, 0);
|
2023-02-14 05:32:32 +01:00
|
|
|
BLEND_OVERRIDE;
|
2023-02-23 07:02:19 +01:00
|
|
|
draw_surface_safe(temp_surface[fg], 0, 0);
|
2023-02-14 05:32:32 +01:00
|
|
|
BLEND_NORMAL;
|
2022-01-13 05:24:03 +01:00
|
|
|
surface_reset_target();
|
|
|
|
|
|
|
|
res_index = bg;
|
|
|
|
}
|
|
|
|
|
2023-01-25 06:49:00 +01:00
|
|
|
shader_reset();
|
|
|
|
|
2022-11-03 11:44:49 +01:00
|
|
|
var _pixel_surface = surface_create_valid(PREF_MAP[? "shape_separation_max"], 1);
|
2022-01-13 05:24:03 +01:00
|
|
|
surface_set_target(_pixel_surface);
|
|
|
|
draw_clear_alpha(0, 0);
|
2023-02-14 05:32:32 +01:00
|
|
|
BLEND_OVERRIDE;
|
2022-01-13 05:24:03 +01:00
|
|
|
shader_set(sh_seperate_shape_counter);
|
2023-02-23 07:02:19 +01:00
|
|
|
texture_set_stage(shader_get_sampler_index(sh_seperate_shape_counter, "surface"), surface_get_texture(temp_surface[res_index]));
|
2023-02-14 05:32:32 +01:00
|
|
|
shader_set_uniform_f_array_safe(shader_get_uniform(sh_seperate_shape_counter, "dimension"), [ ww, hh ]);
|
2022-01-19 06:11:17 +01:00
|
|
|
shader_set_uniform_i(shader_get_uniform(sh_seperate_shape_counter, "maxShape"), PREF_MAP[? "shape_separation_max"]);
|
2023-01-25 06:49:00 +01:00
|
|
|
shader_set_uniform_i(shader_get_uniform(sh_seperate_shape_counter, "ignore"), _ignore);
|
2022-01-14 13:47:15 +01:00
|
|
|
draw_sprite_ext(s_fx_pixel, 0, 0, 0, PREF_MAP[? "shape_separation_max"], 1, 0, c_white, 1);
|
2022-01-13 05:24:03 +01:00
|
|
|
shader_reset();
|
2023-02-14 05:32:32 +01:00
|
|
|
BLEND_NORMAL;
|
2022-01-13 05:24:03 +01:00
|
|
|
surface_reset_target();
|
|
|
|
|
|
|
|
var px = surface_getpixel(_pixel_surface, 0, 0);
|
|
|
|
|
2023-01-25 06:49:00 +01:00
|
|
|
if(px == 0) return;
|
|
|
|
|
|
|
|
var _outSurf, _val;
|
|
|
|
_val = array_create(px);
|
|
|
|
outputs[| 0].setValue(_val);
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-01-25 06:49:00 +01:00
|
|
|
var _boundary = array_create(px);
|
2022-01-14 13:47:15 +01:00
|
|
|
|
2023-01-25 06:49:00 +01:00
|
|
|
buffer_delete(surface_buffer);
|
|
|
|
surface_buffer = buffer_create(ww * hh * 4, buffer_fixed, 2);
|
2023-02-23 07:02:19 +01:00
|
|
|
buffer_get_surface(surface_buffer, temp_surface[res_index], 0);
|
2022-01-16 14:28:57 +01:00
|
|
|
|
2023-01-25 06:49:00 +01:00
|
|
|
for(var i = 0; i < px; i++) {
|
|
|
|
_outSurf = surface_create_valid(ww, hh);
|
|
|
|
_val[@ i] = _outSurf;
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-01-25 06:49:00 +01:00
|
|
|
surface_set_target(_outSurf);
|
|
|
|
draw_clear_alpha(0, 0);
|
2023-02-14 05:32:32 +01:00
|
|
|
BLEND_OVERRIDE;
|
2023-01-25 06:49:00 +01:00
|
|
|
shader_set(sh_seperate_shape_sep);
|
|
|
|
var ccx = surface_getpixel_ext(_pixel_surface, 1 + i, 0);
|
|
|
|
var alpha = (ccx >> 24) & 255;
|
|
|
|
var blue = (ccx >> 16) & 255;
|
|
|
|
var green = (ccx >> 8) & 255;
|
|
|
|
var red = ccx & 255;
|
2022-01-14 13:47:15 +01:00
|
|
|
|
2023-01-25 06:49:00 +01:00
|
|
|
var min_x = floor(red / 255 * ww);
|
|
|
|
var min_y = floor(green / 255 * hh);
|
|
|
|
var max_x = ceil(blue / 255 * ww);
|
|
|
|
var max_y = ceil(alpha / 255 * hh);
|
|
|
|
var t = max_y;
|
|
|
|
var b = min_y;
|
|
|
|
var l = max_x;
|
|
|
|
var r = min_x;
|
2022-01-14 13:47:15 +01:00
|
|
|
|
2023-01-25 06:49:00 +01:00
|
|
|
for( var j = min_x; j < max_x; j++ )
|
|
|
|
for( var k = min_y; k < max_y; k++ ) {
|
2023-02-14 05:32:32 +01:00
|
|
|
var _sc = get_color_buffer(j, k);
|
2023-01-25 06:49:00 +01:00
|
|
|
if(_sc != ccx) continue;
|
|
|
|
|
|
|
|
t = min(t, k);
|
|
|
|
b = max(b, k);
|
|
|
|
l = min(l, j);
|
|
|
|
r = max(r, j);
|
|
|
|
}
|
2023-01-17 08:11:55 +01:00
|
|
|
|
2023-01-25 06:49:00 +01:00
|
|
|
_boundary[i] = [l, t, r, b];
|
2022-01-14 13:47:15 +01:00
|
|
|
|
2023-02-14 05:32:32 +01:00
|
|
|
if(is_surface(_inSurf))
|
|
|
|
texture_set_stage(shader_get_sampler_index(sh_seperate_shape_sep, "original"), surface_get_texture(_inSurf));
|
2023-01-25 06:49:00 +01:00
|
|
|
shader_set_uniform_f(shader_get_uniform(sh_seperate_shape_sep, "color"), red, green, blue, alpha);
|
|
|
|
shader_set_uniform_i(shader_get_uniform(sh_seperate_shape_sep, "override"), _ovr);
|
2023-02-14 05:32:32 +01:00
|
|
|
shader_set_uniform_f_array_safe(shader_get_uniform(sh_seperate_shape_sep, "overColor"), colToVec4(_ovrclr));
|
2023-02-23 07:02:19 +01:00
|
|
|
draw_surface_safe(temp_surface[res_index], 0, 0);
|
2023-01-25 06:49:00 +01:00
|
|
|
shader_reset();
|
2023-02-14 05:32:32 +01:00
|
|
|
BLEND_NORMAL;
|
2023-01-25 06:49:00 +01:00
|
|
|
surface_reset_target();
|
2022-01-13 05:24:03 +01:00
|
|
|
}
|
2023-01-25 06:49:00 +01:00
|
|
|
|
2023-02-14 05:32:32 +01:00
|
|
|
outputs[| 2].setValue(_boundary,,, false);
|
2022-01-13 05:24:03 +01:00
|
|
|
}
|
|
|
|
}
|