Pixel cloud, shape separation, particle node improvement,

This commit is contained in:
MakhamDev 2022-01-14 19:47:15 +07:00
parent 3a74d04532
commit 71b248fdfe
15 changed files with 280 additions and 111 deletions

View file

@ -25,56 +25,87 @@ event_inherited();
#region pages #region pages
page_current = 0; page_current = 0;
page[0] = "Global data"; page[0] = "Global data";
page[1] = "Hotkeys"; page[1] = "Node data";
page[2] = "Hotkeys";
pref[0][0] = "Show welcome screen"; pref_global = ds_list_create();
pref[0][1] = "show_splash"; pref_node = ds_list_create();
pref[0][2] = new checkBox(function() {
PREF_MAP[? "show_splash"] = !PREF_MAP[? "show_splash"];
PREF_SAVE();
});
pref[1][0] = "Reset preview on focus"; ds_list_add(pref_global, [
pref[1][1] = "reset_display"; "Show welcome screen",
pref[1][2] = new checkBox(function() { "show_splash",
PREF_MAP[? "reset_display"] = !PREF_MAP[? "reset_display"]; new checkBox(function() {
PREF_SAVE(); PREF_MAP[? "show_splash"] = !PREF_MAP[? "show_splash"];
}); PREF_SAVE();
})
]);
pref[2][0] = "Curve connection line"; ds_list_add(pref_global, [
pref[2][1] = "curve_connection_line"; "Reset preview on focus",
pref[2][2] = new checkBox(function() { "reset_display",
PREF_MAP[? "curve_connection_line"] = !PREF_MAP[? "curve_connection_line"]; new checkBox(function() {
PREF_SAVE(); PREF_MAP[? "reset_display"] = !PREF_MAP[? "reset_display"];
}); PREF_SAVE();
})
]);
pref[3][0] = "Max particles"; ds_list_add(pref_global, [
pref[3][1] = "part_max_amount"; "Curve connection line",
pref[3][2] = new textBox(TEXTBOX_INPUT.number, function(str) { "curve_connection_line",
PREF_MAP[? "part_max_amount"] = real(str); new checkBox(function() {
PREF_SAVE(); PREF_MAP[? "curve_connection_line"] = !PREF_MAP[? "curve_connection_line"];
}); PREF_SAVE();
})
]);
pref[4][0] = "Double click delay"; ds_list_add(pref_global, [
pref[4][1] = "double_click_delay"; "Double click delay",
pref[4][2] = new textBox(TEXTBOX_INPUT.number, function(str) { "double_click_delay",
PREF_MAP[? "double_click_delay"] = real(str); new textBox(TEXTBOX_INPUT.number, function(str) {
PREF_SAVE(); PREF_MAP[? "double_click_delay"] = real(str);
}); PREF_SAVE();
})
]);
pref[5][0] = "Default surface size"; ds_list_add(pref_global, [
pref[5][1] = "default_surface_side"; "Default surface size",
pref[5][2] = new textBox(TEXTBOX_INPUT.number, function(str) { "default_surface_side",
PREF_MAP[? "default_surface_side"] = max(1, round(real(str))); new textBox(TEXTBOX_INPUT.number, function(str) {
PREF_SAVE(); PREF_MAP[? "default_surface_side"] = max(1, round(real(str)));
}); PREF_SAVE();
})
]);
pref[6][0] = "Node snapping (set to 1 for no snap)"; ds_list_add(pref_global, [
pref[6][1] = "node_snapping"; "Node snapping (set to 1 for no snap)",
pref[6][2] = new textBox(TEXTBOX_INPUT.number, function(str) { "node_snapping",
PREF_MAP[? "node_snapping"] = max(1, round(real(str))); new textBox(TEXTBOX_INPUT.number, function(str) {
PREF_SAVE(); PREF_MAP[? "node_snapping"] = max(1, round(real(str)));
}); PREF_SAVE();
})
]);
//NODE
ds_list_add(pref_node, [
"[Particle] Max particles",
"part_max_amount",
new textBox(TEXTBOX_INPUT.number, function(str) {
PREF_MAP[? "part_max_amount"] = real(str);
PREF_SAVE();
})
]);
ds_list_add(pref_node, [
"[Separate shape] Max shapes",
"shape_separation_max",
new textBox(TEXTBOX_INPUT.number, function(str) {
PREF_MAP[? "shape_separation_max"] = real(str);
PREF_SAVE();
})
]);
current_list = pref_global;
sp_pref = new scrollPane(dialog_w - 160 - 32, dialog_h - 64 - 28, function(_y, _m) { sp_pref = new scrollPane(dialog_w - 160 - 32, dialog_h - 64 - 28, function(_y, _m) {
draw_clear_alpha(c_ui_blue_black, 0); draw_clear_alpha(c_ui_blue_black, 0);
@ -84,24 +115,26 @@ event_inherited();
var yy = _y + 8; var yy = _y + 8;
var padd = 6; var padd = 6;
for(var i = 0; i < array_length(pref); i++) { for(var i = 0; i < ds_list_size(current_list); i++) {
var name = pref[i][0]; var _pref = current_list[| i];
var name = _pref[0];
if(search_text == "" || string_pos(string_lower(search_text), string_lower(name)) > 0) { if(search_text == "" || string_pos(string_lower(search_text), string_lower(name)) > 0) {
if(i % 2 == 0) { if(i % 2 == 0) {
draw_sprite_stretched_ext(s_ui_panel_bg, 0, 0, yy - padd, dialog_w - 200, th + padd * 2, c_ui_blue_white, 1); draw_sprite_stretched_ext(s_ui_panel_bg, 0, 0, yy - padd, dialog_w - 200, th + padd * 2, c_ui_blue_white, 1);
} }
draw_set_text(f_p1, fa_left, fa_center, c_white); draw_set_text(f_p1, fa_left, fa_center, c_white);
draw_text(8, yy + 17, pref[i][0]); draw_text(8, yy + 17, _pref[0]);
pref[i][2].active = FOCUS == self; _pref[2].active = FOCUS == self;
pref[i][2].hover = HOVER == self; _pref[2].hover = HOVER == self;
switch(instanceof(pref[i][2])) { switch(instanceof(_pref[2])) {
case "textBox" : case "textBox" :
pref[i][2].draw(x1 - 100, yy, 96, 34, PREF_MAP[? pref[i][1]], _m); _pref[2].draw(x1 - 100, yy, 96, 34, PREF_MAP[? _pref[1]], _m);
break; break;
case "checkBox" : case "checkBox" :
pref[i][2].draw(x1 - 36, yy + 2, PREF_MAP[? pref[i][1]], _m); _pref[2].draw(x1 - 36, yy + 2, PREF_MAP[? _pref[1]], _m);
break; break;
} }

View file

@ -0,0 +1,5 @@
/// @description
event_inherited();
ds_list_destroy(pref_global);
ds_list_destroy(pref_node);

View file

@ -43,9 +43,14 @@ if !ready exit;
draw_sprite_ext(s_search_16, 0, dialog_x + dialog_w - 16 - 200 - 16, dialog_y + 16 + 12, 1, 1, 0, c_ui_blue_grey, 1); draw_sprite_ext(s_search_16, 0, dialog_x + dialog_w - 16 - 200 - 16, dialog_y + 16 + 12, 1, 1, 0, c_ui_blue_grey, 1);
if(page_current == 0) { if(page_current == 0) {
current_list = pref_global;
sp_pref.active = HOVER == self; sp_pref.active = HOVER == self;
sp_pref.draw(dialog_x + 160 + 8, yy); sp_pref.draw(dialog_x + 160 + 8, yy);
} else if(page_current == 1) { } else if(page_current == 1) {
current_list = pref_node;
sp_pref.active = HOVER == self;
sp_pref.draw(dialog_x + 160 + 8, yy);
} else if(page_current == 2) {
if(mouse_check_button_pressed(mb_left)) hk_editing = noone; if(mouse_check_button_pressed(mb_left)) hk_editing = noone;
sp_hotkey.active = HOVER == self; sp_hotkey.active = HOVER == self;

View file

@ -23,6 +23,7 @@
"eventList": [ "eventList": [
{"isDnD":false,"eventNum":0,"eventType":0,"collisionObjectId":null,"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMEvent",}, {"isDnD":false,"eventNum":0,"eventType":0,"collisionObjectId":null,"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMEvent",},
{"isDnD":false,"eventNum":64,"eventType":8,"collisionObjectId":null,"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMEvent",}, {"isDnD":false,"eventNum":64,"eventType":8,"collisionObjectId":null,"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMEvent",},
{"isDnD":false,"eventNum":0,"eventType":1,"collisionObjectId":null,"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMEvent",},
], ],
"properties": [], "properties": [],
"overriddenProperties": [], "overriddenProperties": [],

View file

@ -16,6 +16,8 @@ function __part() constructor {
g = 0; g = 0;
wig = 0; wig = 0;
boundary_data = [];
fx = 0; fx = 0;
fy = 0; fy = 0;
@ -32,6 +34,7 @@ function __part() constructor {
col = -1; col = -1;
alp = 1; alp = 1;
alp_draw = alp;
alp_fade = 0; alp_fade = 0;
life = 0; life = 0;
@ -72,6 +75,7 @@ function __part() constructor {
function setDraw(_col, _alp, _fade) { function setDraw(_col, _alp, _fade) {
col = _col; col = _col;
alp = _alp; alp = _alp;
alp_draw = _alp;
alp_fade = _fade; alp_fade = _fade;
} }
@ -106,7 +110,7 @@ function __part() constructor {
rot = point_direction(xp, yp, x, y); rot = point_direction(xp, yp, x, y);
else else
rot += rot_s; rot += rot_s;
alp = clamp(alp + alp_fade, 0, 1); alp_draw = alp * eval_bezier_cubic(life / life_total, alp_fade[0], alp_fade[1], alp_fade[2], alp_fade[3]);
if(life-- < 0) kill(); if(life-- < 0) kill();
} }
@ -119,18 +123,45 @@ function __part() constructor {
if(!is_surface(ss)) return; if(!is_surface(ss)) return;
var cc = (col == -1)? c_white : gradient_eval(col, 1 - life / life_total); var cc = (col == -1)? c_white : gradient_eval(col, 1 - life / life_total);
var _xx, _yy;
var s_w = surface_get_width(ss) * scx; var s_w = surface_get_width(ss) * scx;
var s_h = surface_get_height(ss) * scy; var s_h = surface_get_height(ss) * scy;
var _pp = point_rotate(-s_w / 2, -s_h / 2, 0, 0, rot);
_pp[0] = x + _pp[0];
_pp[1] = y + _pp[1];
if(boundary_data == -1) {
var _pp = point_rotate(-s_w / 2, -s_h / 2, 0, 0, rot);
_xx = x + _pp[0];
_yy = y + _pp[1];
} else {
var ww = boundary_data[2] + boundary_data[0];
var hh = boundary_data[3] + boundary_data[1];
var cx = (boundary_data[0] + boundary_data[2]) / 2;
var cy = (boundary_data[1] + boundary_data[3]) / 2;
var _pp = point_rotate(-cx, -cy, 0, 0, rot);
_xx = x + cx + _pp[0] * scx;
_yy = y + cy + _pp[1] * scy;
}
if(exact) { if(exact) {
_pp[0] = round(_pp[0]); _xx = round(_xx);
_pp[1] = round(_pp[1]); _yy = round(_yy);
} }
draw_surface_ext_safe(ss, _pp[0], _pp[1], scx, scy, rot, cc, alp); draw_surface_ext_safe(ss, _xx, _yy, scx, scy, rot, cc, alp_draw);
}
function getPivot() {
if(boundary_data == -1)
return [x, y];
var ww = boundary_data[2] + boundary_data[0] * scx;
var hh = boundary_data[3] + boundary_data[1] * scy;
var cx = x + boundary_data[0] + ww / 2;
var cy = y + boundary_data[1] + hh / 2;
return [cx, cy];
} }
} }
@ -192,7 +223,7 @@ function Node_Particle(_x, _y) : Node(_x, _y) constructor {
inputs[| 14] = nodeValue(14, "Alpha", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 1, 1 ]) inputs[| 14] = nodeValue(14, "Alpha", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 1, 1 ])
.setDisplay(VALUE_DISPLAY.range) .setDisplay(VALUE_DISPLAY.range)
.setVisible(false); .setVisible(false);
inputs[| 15] = nodeValue(15, "Alpha over time", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0) inputs[| 15] = nodeValue(15, "Alpha over time", self, JUNCTION_CONNECT.input, VALUE_TYPE.curve, [1, 1, 1, 1])
.setVisible(false); .setVisible(false);
inputs[| 16] = nodeValue(16, "Rotate by direction", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false) inputs[| 16] = nodeValue(16, "Rotate by direction", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false)
@ -234,13 +265,16 @@ function Node_Particle(_x, _y) : Node(_x, _y) constructor {
.setVisible(false, false); .setVisible(false, false);
inputs[| 27] = nodeValue(27, "Scatter", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1) inputs[| 27] = nodeValue(27, "Scatter", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1)
.setDisplay(VALUE_DISPLAY.enum_button, [ "Uniform", "Random" ]) .setDisplay(VALUE_DISPLAY.enum_button, [ "Uniform", "Random", "Data" ])
.setVisible(false); .setVisible(false);
inputs[| 28] = nodeValue(28, "Boundary data", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [])
.setVisible(true, false);
input_display_list = [ input_display_list = [
["Output", true], 1, ["Output", true], 1,
["Sprite", true], 0, 25, ["Sprite", true], 0, 25,
["Spawn", true], 17, 2, 3, 4, 5, 27, 6, ["Spawn", true], 17, 2, 3, 4, 5, 27, 28, 6,
["Movement", true], 7, 20, 8, ["Movement", true], 7, 20, 8,
["Physics", true], 21, 22, ["Physics", true], 21, 22,
["Rotation", true], 16, 9, 10, ["Rotation", true], 16, 9, 10,
@ -307,20 +341,34 @@ function Node_Particle(_x, _y) : Node(_x, _y) constructor {
for(var i = 0; i < PREF_MAP[? "part_max_amount"]; i++) { for(var i = 0; i < PREF_MAP[? "part_max_amount"]; i++) {
if(!parts[| i].active) { if(!parts[| i].active) {
var _spr = _inSurf; var _spr = _inSurf, _index = 0;
if(is_array(_inSurf)) { if(is_array(_inSurf)) {
if(_arr_type == 0) if(_arr_type == 0) {
_spr = _inSurf[irandom(array_length(_inSurf) - 1)]; _index = irandom(array_length(_inSurf) - 1);
else if(_arr_type == 1) _spr = _inSurf[_index];
_spr = _inSurf[safe_mod(spawn_index, array_length(_inSurf))]; } else if(_arr_type == 1) {
else if(_arr_type == 2) _index = safe_mod(spawn_index, array_length(_inSurf));
_spr = _inSurf[_index];
} else if(_arr_type == 2)
_spr = _inSurf; _spr = _inSurf;
} }
var xx, yy; var xx, yy;
var sp = area_get_random_point(_spawn_area, _distrib, _scatter, spawn_index, _spawn_amount); if(_scatter == 2) {
xx = sp[0]; var _b_data = inputs[| 28].getValue();
yy = sp[1]; if(!is_array(_b_data) || array_length(_b_data) <= 0) return;
var _b = _b_data[safe_mod(_index, array_length(_b_data))];
if(!is_array(_b) || array_length(_b) != 4) return;
xx = array_safe_get(_spawn_area, 0) - array_safe_get(_spawn_area, 2);
yy = array_safe_get(_spawn_area, 1) - array_safe_get(_spawn_area, 3);
parts[| i].boundary_data = _b;
} else {
var sp = area_get_random_point(_spawn_area, _distrib, _scatter, spawn_index, _spawn_amount);
xx = sp[0];
yy = sp[1];
}
var _lif = random_range(_life[0], _life[1]); var _lif = random_range(_life[0], _life[1]);
@ -396,9 +444,11 @@ function Node_Particle(_x, _y) : Node(_x, _y) constructor {
function step() { function step() {
var _inSurf = inputs[| 0].getValue(); var _inSurf = inputs[| 0].getValue();
var _scatt = inputs[| 27].getValue();
inputs[| 25].show_in_inspector = false; inputs[| 25].show_in_inspector = false;
inputs[| 26].show_in_inspector = false; inputs[| 26].show_in_inspector = false;
inputs[| 28].show_in_inspector = _scatt == 2;
if(is_array(_inSurf)) { if(is_array(_inSurf)) {
inputs[| 25].show_in_inspector = true; inputs[| 25].show_in_inspector = true;

View file

@ -19,30 +19,40 @@ function Node_Particle_Effector(_x, _y) : Node(_x, _y) constructor {
inputs[| 0] = nodeValue(0, "Particle data", self, JUNCTION_CONNECT.input, VALUE_TYPE.object, -1 ); inputs[| 0] = nodeValue(0, "Particle data", self, JUNCTION_CONNECT.input, VALUE_TYPE.object, -1 );
inputs[| 1] = nodeValue(1, "Output dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, def_surf_size2, VALUE_TAG.dimension_2d ) inputs[| 1] = nodeValue(1, "Output dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, def_surf_size2, VALUE_TAG.dimension_2d )
.setDisplay(VALUE_DISPLAY.vector); .setDisplay(VALUE_DISPLAY.vector)
.setVisible(false, false);
inputs[| 2] = nodeValue(2, "Area", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 16, 16, 4, 4, AREA_SHAPE.rectangle ]) inputs[| 2] = nodeValue(2, "Area", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 16, 16, 4, 4, AREA_SHAPE.rectangle ])
.setDisplay(VALUE_DISPLAY.area); .setDisplay(VALUE_DISPLAY.area)
.setVisible(false);
inputs[| 3] = nodeValue(3, "Falloff", self, JUNCTION_CONNECT.input, VALUE_TYPE.curve, [0, 0, 1, 1] ) inputs[| 3] = nodeValue(3, "Falloff", self, JUNCTION_CONNECT.input, VALUE_TYPE.curve, [0, 0, 1, 1] )
.setDisplay(VALUE_DISPLAY.curve); .setDisplay(VALUE_DISPLAY.curve)
.setVisible(false);
inputs[| 4] = nodeValue(4, "Falloff distance", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 4 ); inputs[| 4] = nodeValue(4, "Falloff distance", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 4 )
.setVisible(false);
inputs[| 5] = nodeValue(5, "Effect type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0 ) inputs[| 5] = nodeValue(5, "Effect type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0 )
.setDisplay(VALUE_DISPLAY.enum_scroll, [ "Wind", "Attract", "Repel", "Vortex", "Turbulence", "Destroy" ] ); .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Wind", "Attract", "Repel", "Vortex", "Turbulence", "Destroy" ] )
.setVisible(false);
inputs[| 6] = nodeValue(6, "Effect Vector", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ -1, 0 ] ) inputs[| 6] = nodeValue(6, "Effect Vector", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ -1, 0 ] )
.setDisplay(VALUE_DISPLAY.vector); .setDisplay(VALUE_DISPLAY.vector)
.setVisible(false);
inputs[| 7] = nodeValue(7, "Strength", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1 ); inputs[| 7] = nodeValue(7, "Strength", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1 )
.setVisible(false);
inputs[| 8] = nodeValue(8, "Rotate particle", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0 ); inputs[| 8] = nodeValue(8, "Rotate particle", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0 )
.setVisible(false);
inputs[| 9] = nodeValue(9, "Scale particle", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0 ] ) inputs[| 9] = nodeValue(9, "Scale particle", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0 ] )
.setDisplay(VALUE_DISPLAY.vector); .setDisplay(VALUE_DISPLAY.vector)
.setVisible(false);
inputs[| 10] = nodeValue(10, "Turbulence scale", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 16 ); inputs[| 10] = nodeValue(10, "Turbulence scale", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 16 )
.setVisible(false);
input_display_list = [ 0, 1, input_display_list = [ 0, 1,
["Area", false], 2, 3, 4, ["Area", false], 2, 3, 4,
@ -83,7 +93,6 @@ function Node_Particle_Effector(_x, _y) : Node(_x, _y) constructor {
function affect(part) { function affect(part) {
if(!part.active) return; if(!part.active) return;
if(array_length(current_data) < ds_list_size(inputs)) return;
var _area = current_data[2]; var _area = current_data[2];
var _fall = current_data[3]; var _fall = current_data[3];
@ -107,18 +116,19 @@ function Node_Particle_Effector(_x, _y) : Node(_x, _y) constructor {
var _area_y1 = _area_y + _area_h; var _area_y1 = _area_y + _area_h;
var str = 0; var str = 0;
var pv = part.getPivot();
if(_area_t == AREA_SHAPE.rectangle) { if(_area_t == AREA_SHAPE.rectangle) {
if(point_in_rectangle(part.x, part.y, _area_x0, _area_y0, _area_x1, _area_y1)) { if(point_in_rectangle(pv[0], pv[1], _area_x0, _area_y0, _area_x1, _area_y1)) {
var _dst = min( distance_to_line(part.x, part.y, _area_x0, _area_y0, _area_x1, _area_y0), var _dst = min( distance_to_line(pv[0], pv[1], _area_x0, _area_y0, _area_x1, _area_y0),
distance_to_line(part.x, part.y, _area_x0, _area_y1, _area_x1, _area_y1), distance_to_line(pv[0], pv[1], _area_x0, _area_y1, _area_x1, _area_y1),
distance_to_line(part.x, part.y, _area_x0, _area_y0, _area_x0, _area_y1), distance_to_line(pv[0], pv[1], _area_x0, _area_y0, _area_x0, _area_y1),
distance_to_line(part.x, part.y, _area_x1, _area_y0, _area_x1, _area_y1)); distance_to_line(pv[0], pv[1], _area_x1, _area_y0, _area_x1, _area_y1));
str = eval_curve_bezier_cubic(_fall, clamp(_dst / _fads, 0., 1.)); str = eval_curve_bezier_cubic(_fall, clamp(_dst / _fads, 0., 1.));
} }
} else if(_area_t == AREA_SHAPE.elipse) { } else if(_area_t == AREA_SHAPE.elipse) {
if(point_in_circle(part.x, part.y, _area_x, _area_y, min(_area_w, _area_h))) { if(point_in_circle(pv[0], pv[1], _area_x, _area_y, min(_area_w, _area_h))) {
var _dst = point_distance(part.x, part.y, _area_x, _area_y); var _dst = point_distance(pv[0], pv[1], _area_x, _area_y);
str = eval_curve_bezier_cubic(_fall, clamp(_dst / _fads, 0., 1.)); str = eval_curve_bezier_cubic(_fall, clamp(_dst / _fads, 0., 1.));
} }
} }
@ -128,32 +138,42 @@ function Node_Particle_Effector(_x, _y) : Node(_x, _y) constructor {
case FORCE_TYPE.Wind : case FORCE_TYPE.Wind :
part.x = part.x + _vect[0] * _sten * str; part.x = part.x + _vect[0] * _sten * str;
part.y = part.y + _vect[1] * _sten * str; part.y = part.y + _vect[1] * _sten * str;
part.rot += _rot * str;
break; break;
case FORCE_TYPE.Attract : case FORCE_TYPE.Attract :
var dirr = point_direction(part.x, part.y, _area_x, _area_y); var dirr = point_direction(pv[0], pv[1], _area_x, _area_y);
part.x = part.x + lengthdir_x(_sten * str, dirr); part.x = part.x + lengthdir_x(_sten * str, dirr);
part.y = part.y + lengthdir_y(_sten * str, dirr); part.y = part.y + lengthdir_y(_sten * str, dirr);
part.rot += _rot * str;
break; break;
case FORCE_TYPE.Repel : case FORCE_TYPE.Repel :
var dirr = point_direction(_area_x, _area_y, part.x, part.y); var dirr = point_direction(_area_x, _area_y, pv[0], pv[1]);
part.x = part.x + lengthdir_x(_sten * str, dirr); part.x = part.x + lengthdir_x(_sten * str, dirr);
part.y = part.y + lengthdir_y(_sten * str, dirr); part.y = part.y + lengthdir_y(_sten * str, dirr);
part.rot += _rot * str;
break; break;
case FORCE_TYPE.Vortex : case FORCE_TYPE.Vortex :
var dirr = point_direction(_area_x, _area_y, part.x, part.y) + 90; var dirr = point_direction(_area_x, _area_y, pv[0], pv[1]) + 90;
part.x = part.x + lengthdir_x(_sten * str, dirr); part.x = part.x + lengthdir_x(_sten * str, dirr);
part.y = part.y + lengthdir_y(_sten * str, dirr); part.y = part.y + lengthdir_y(_sten * str, dirr);
part.rot += _rot * str;
break; break;
case FORCE_TYPE.Turbulence : case FORCE_TYPE.Turbulence :
var t_scale = current_data[10]; var t_scale = current_data[10];
var per = (perlin_noise(part.x / t_scale, part.y / t_scale, 4, part.seed) - 0.5) * 2; var per = (perlin_noise(pv[0] / t_scale, pv[1] / t_scale, 4, part.seed) - 0.5) * 2;
per *= str; per *= str;
part.x = part.x + _vect[0] * per; part.x = part.x + _vect[0] * per;
part.y = part.y + _vect[1] * per; part.y = part.y + _vect[1] * per;
part.rot += _rot * per;
break; break;
case FORCE_TYPE.Destroy : case FORCE_TYPE.Destroy :
if(random(1) < _sten) if(random(1) < _sten)
@ -167,8 +187,6 @@ function Node_Particle_Effector(_x, _y) : Node(_x, _y) constructor {
else part.scx += sign(part.scx) * scx_s; else part.scx += sign(part.scx) * scx_s;
if(scy_s < 0) part.scy = lerp_linear(part.scy, 0, abs(scy_s)); if(scy_s < 0) part.scy = lerp_linear(part.scy, 0, abs(scy_s));
else part.scy += sign(part.scy) * scy_s; else part.scy += sign(part.scy) * scy_s;
part.rot += _rot * str;
} }
} }

View file

@ -5,9 +5,8 @@ function Node_create_Seperate_Shape(_x, _y) {
} }
function Node_Seperate_Shape(_x, _y) : Node(_x, _y) constructor { function Node_Seperate_Shape(_x, _y) : Node(_x, _y) constructor {
name = "Seperate shape"; name = "Separate shape";
auto_update = false; auto_update = false;
max_part = 32;
uniform_it_dim = shader_get_uniform(sh_seperate_shape_ite, "dimension"); uniform_it_dim = shader_get_uniform(sh_seperate_shape_ite, "dimension");
@ -26,6 +25,19 @@ function Node_Seperate_Shape(_x, _y) : Node(_x, _y) constructor {
} }
temp_surf = [ surface_create(1, 1), surface_create(1, 1) ]; temp_surf = [ surface_create(1, 1), surface_create(1, 1) ];
surface_buffer = buffer_create(1 * 1 * 4, buffer_fixed, 2);
function get_color_buffer(_x, _y, w, h) {
buffer_seek(surface_buffer, buffer_seek_start, (w * _y + _x) * 4);
var c = buffer_read(surface_buffer, buffer_u32);
var _r = c & 255;
var _g = (c >> 8) & 255;
var _b = (c >> 16) & 255;
return make_color_rgb(_r, _g, _b);
}
_prev_type = -1;
function update() { function update() {
var _inSurf = inputs[| 0].getValue(); var _inSurf = inputs[| 0].getValue();
@ -70,14 +82,14 @@ function Node_Seperate_Shape(_x, _y) : Node(_x, _y) constructor {
res_index = bg; res_index = bg;
} }
var _pixel_surface = surface_create(max_part, 1); var _pixel_surface = surface_create(PREF_MAP[? "shape_separation_max"], 1);
surface_set_target(_pixel_surface); surface_set_target(_pixel_surface);
draw_clear_alpha(0, 0); draw_clear_alpha(0, 0);
BLEND_ADD BLEND_ADD
shader_set(sh_seperate_shape_counter); shader_set(sh_seperate_shape_counter);
texture_set_stage(shader_get_sampler_index(sh_seperate_shape_counter, "surface"), surface_get_texture(temp_surf[res_index])); texture_set_stage(shader_get_sampler_index(sh_seperate_shape_counter, "surface"), surface_get_texture(temp_surf[res_index]));
shader_set_uniform_f_array(shader_get_uniform(sh_seperate_shape_counter, "dimension"), [ surface_get_width(_inSurf), surface_get_height(_inSurf) ]); shader_set_uniform_f_array(shader_get_uniform(sh_seperate_shape_counter, "dimension"), [ surface_get_width(_inSurf), surface_get_height(_inSurf) ]);
draw_sprite_ext(s_fx_pixel, 0, 0, 0, max_part, 1, 0, c_white, 1); draw_sprite_ext(s_fx_pixel, 0, 0, 0, PREF_MAP[? "shape_separation_max"], 1, 0, c_white, 1);
shader_reset(); shader_reset();
BLEND_NORMAL BLEND_NORMAL
surface_reset_target(); surface_reset_target();
@ -90,14 +102,26 @@ function Node_Seperate_Shape(_x, _y) : Node(_x, _y) constructor {
if(_out_type == 0) { if(_out_type == 0) {
while(ds_list_size(outputs) > px) while(ds_list_size(outputs) > px)
ds_list_delete(outputs, px - 1); ds_list_delete(outputs, px - 1);
} else { } else if(_out_type == 1) {
ds_list_clear(outputs); _val = array_create(px);
outputs[| 0] = nodeValue(0, "Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, array_create(px)); if(_prev_type != _out_type) {
_val = outputs[| 0].getValue(); ds_list_clear(outputs);
outputs[| 0] = nodeValue(0, "Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, _val);
outputs[| 1] = nodeValue(1, "Shape map", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, temp_surf[res_index]);
outputs[| 2] = nodeValue(2, "Boundary data", self, JUNCTION_CONNECT.output, VALUE_TYPE.integer, []);
outputs[| 1] = nodeValue(1, "Shape map", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, temp_surf[res_index]); _prev_type = _out_type;
}
} }
var _boundary = array_create(px);
var _sw = surface_get_width(temp_surf[res_index]);
var _sh = surface_get_height(temp_surf[res_index]);
buffer_delete(surface_buffer);
surface_buffer = buffer_create(_sw * _sh * 4, buffer_fixed, 2);
buffer_get_surface(surface_buffer, temp_surf[res_index], 0);
for(var i = 0; i < px; i++) { for(var i = 0; i < px; i++) {
if(_out_type == 0) { if(_out_type == 0) {
if(i >= ds_list_size(outputs)) { if(i >= ds_list_size(outputs)) {
@ -116,6 +140,30 @@ function Node_Seperate_Shape(_x, _y) : Node(_x, _y) constructor {
BLEND_ADD BLEND_ADD
shader_set(sh_seperate_shape_sep); shader_set(sh_seperate_shape_sep);
var cc = surface_getpixel(_pixel_surface, 1 + i, 0); var cc = surface_getpixel(_pixel_surface, 1 + i, 0);
#region boundary search (brute force)
if(_out_type == 1) {
var t = _sh;
var b = 0;
var l = 0;
var r = _sw;
for( var j = 0; j < surface_get_width(_inSurf); j++ ) {
for( var k = 0; k < surface_get_height(_inSurf); k++ ) {
var _sc = get_color_buffer(j, k, _sw, _sh);
if(_sc == cc) {
t = min(t, k);
b = max(b, k);
l = max(l, j);
r = min(r, j);
}
}
}
_boundary[i] = [l, t, r, b];
}
#endregion
texture_set_stage(shader_get_sampler_index(sh_seperate_shape_sep, "original"), surface_get_texture(_inSurf)); texture_set_stage(shader_get_sampler_index(sh_seperate_shape_sep, "original"), surface_get_texture(_inSurf));
shader_set_uniform_f_array(shader_get_uniform(sh_seperate_shape_sep, "color"), [ color_get_red(cc), color_get_green(cc) ]); shader_set_uniform_f_array(shader_get_uniform(sh_seperate_shape_sep, "color"), [ color_get_red(cc), color_get_green(cc) ]);
draw_surface_safe(temp_surf[res_index], 0, 0); draw_surface_safe(temp_surf[res_index], 0, 0);
@ -123,6 +171,10 @@ function Node_Seperate_Shape(_x, _y) : Node(_x, _y) constructor {
BLEND_NORMAL BLEND_NORMAL
surface_reset_target(); surface_reset_target();
} }
if(_out_type == 1) {
outputs[| 2].setValue(_boundary);
}
} }
} }
} }

View file

@ -985,7 +985,9 @@ function NodeValue(_index, _name, _node, _connect, _type, _value, _tag = VALUE_T
} }
} }
PANEL_MENU.addNotiExtra("Node connect error : Node ID " + string(con_node + APPEND_ID) + " not found."); var txt = "Node connect error : Node ID " + string(con_node + APPEND_ID) + " not found.";
log_warning("LOAD", txt);
PANEL_MENU.addNotiExtra(txt);
return true; return true;
} }
} }

View file

@ -27,6 +27,8 @@
PREF_MAP[? "panel_collection"] = true; PREF_MAP[? "panel_collection"] = true;
PREF_MAP[? "node_snapping"] = 32; PREF_MAP[? "node_snapping"] = 32;
PREF_MAP[? "shape_separation_max"] = 32;
#endregion #endregion
#region hotkeys #region hotkeys

View file

@ -5,11 +5,12 @@ varying vec2 v_vTexcoord;
varying vec4 v_vColour; varying vec4 v_vColour;
#define pi2 1.57079 #define pi2 1.57079
#define pi 3.14159265
void main() { void main() {
vec2 center = v_vTexcoord - vec2(0.5, 0.5); vec2 center = v_vTexcoord - vec2(0.5, 0.5);
float radius = distance(v_vTexcoord, vec2(0.5, 0.5)) / (sqrt(2.) * .5); float radius = distance(v_vTexcoord, vec2(0.5, 0.5)) / (sqrt(2.) * .5);
float angle = (atan(center.y, center.x) / pi2 + 1.) / 2.; float angle = (atan(center.y, center.x) / pi + 1.) / 2.;
vec2 polar = vec2(radius, angle); vec2 polar = vec2(radius, angle);
gl_FragColor = v_vColour * texture2D( gm_BaseTexture, polar ); gl_FragColor = v_vColour * texture2D( gm_BaseTexture, polar );

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

View file

@ -24,9 +24,9 @@
"gridX": 0, "gridX": 0,
"gridY": 0, "gridY": 0,
"frames": [ "frames": [
{"compositeImage":{"FrameId":{"name":"90f3e43f-6cad-4a92-8e7c-8764bdde2faf","path":"sprites/s_node_pixel_cloud/s_node_pixel_cloud.yy",},"LayerId":null,"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMSpriteBitmap",},"images":[ {"compositeImage":{"FrameId":{"name":"50aa9e0a-4597-4759-be8c-aea0dfc294f6","path":"sprites/s_node_pixel_cloud/s_node_pixel_cloud.yy",},"LayerId":null,"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMSpriteBitmap",},"images":[
{"FrameId":{"name":"90f3e43f-6cad-4a92-8e7c-8764bdde2faf","path":"sprites/s_node_pixel_cloud/s_node_pixel_cloud.yy",},"LayerId":{"name":"2d92f87b-0c00-4e67-b5e5-80435b8a9954","path":"sprites/s_node_pixel_cloud/s_node_pixel_cloud.yy",},"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMSpriteBitmap",}, {"FrameId":{"name":"50aa9e0a-4597-4759-be8c-aea0dfc294f6","path":"sprites/s_node_pixel_cloud/s_node_pixel_cloud.yy",},"LayerId":{"name":"510fcb08-c7a7-45d8-a16a-11ddc2105fea","path":"sprites/s_node_pixel_cloud/s_node_pixel_cloud.yy",},"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMSpriteBitmap",},
],"parent":{"name":"s_node_pixel_cloud","path":"sprites/s_node_pixel_cloud/s_node_pixel_cloud.yy",},"resourceVersion":"1.0","name":"90f3e43f-6cad-4a92-8e7c-8764bdde2faf","tags":[],"resourceType":"GMSpriteFrame",}, ],"parent":{"name":"s_node_pixel_cloud","path":"sprites/s_node_pixel_cloud/s_node_pixel_cloud.yy",},"resourceVersion":"1.0","name":"50aa9e0a-4597-4759-be8c-aea0dfc294f6","tags":[],"resourceType":"GMSpriteFrame",},
], ],
"sequence": { "sequence": {
"spriteId": {"name":"s_node_pixel_cloud","path":"sprites/s_node_pixel_cloud/s_node_pixel_cloud.yy",}, "spriteId": {"name":"s_node_pixel_cloud","path":"sprites/s_node_pixel_cloud/s_node_pixel_cloud.yy",},
@ -41,10 +41,10 @@
"moments": {"Keyframes":[],"resourceVersion":"1.0","resourceType":"KeyframeStore<MomentsEventKeyframe>",}, "moments": {"Keyframes":[],"resourceVersion":"1.0","resourceType":"KeyframeStore<MomentsEventKeyframe>",},
"tracks": [ "tracks": [
{"name":"frames","spriteId":null,"keyframes":{"Keyframes":[ {"name":"frames","spriteId":null,"keyframes":{"Keyframes":[
{"id":"10ae1b26-149a-4837-b0ef-ebc91848d562","Key":0.0,"Length":1.0,"Stretch":false,"Disabled":false,"IsCreationKey":false,"Channels":{"0":{"Id":{"name":"90f3e43f-6cad-4a92-8e7c-8764bdde2faf","path":"sprites/s_node_pixel_cloud/s_node_pixel_cloud.yy",},"resourceVersion":"1.0","resourceType":"SpriteFrameKeyframe",},},"resourceVersion":"1.0","resourceType":"Keyframe<SpriteFrameKeyframe>",}, {"id":"f15ff1e5-a53c-4c00-8da2-ec5ef0de1206","Key":0.0,"Length":1.0,"Stretch":false,"Disabled":false,"IsCreationKey":false,"Channels":{"0":{"Id":{"name":"50aa9e0a-4597-4759-be8c-aea0dfc294f6","path":"sprites/s_node_pixel_cloud/s_node_pixel_cloud.yy",},"resourceVersion":"1.0","resourceType":"SpriteFrameKeyframe",},},"resourceVersion":"1.0","resourceType":"Keyframe<SpriteFrameKeyframe>",},
],"resourceVersion":"1.0","resourceType":"KeyframeStore<SpriteFrameKeyframe>",},"trackColour":0,"inheritsTrackColour":true,"builtinName":0,"traits":0,"interpolation":1,"tracks":[],"events":[],"isCreationTrack":false,"resourceVersion":"1.0","tags":[],"resourceType":"GMSpriteFramesTrack","modifiers":[],}, ],"resourceVersion":"1.0","resourceType":"KeyframeStore<SpriteFrameKeyframe>",},"trackColour":0,"inheritsTrackColour":true,"builtinName":0,"traits":0,"interpolation":1,"tracks":[],"events":[],"isCreationTrack":false,"resourceVersion":"1.0","tags":[],"resourceType":"GMSpriteFramesTrack","modifiers":[],},
], ],
"visibleRange": {"x":0.0,"y":0.0,}, "visibleRange": null,
"lockOrigin": false, "lockOrigin": false,
"showBackdrop": true, "showBackdrop": true,
"showBackdropImage": false, "showBackdropImage": false,
@ -65,7 +65,7 @@
"resourceType": "GMSequence", "resourceType": "GMSequence",
}, },
"layers": [ "layers": [
{"visible":true,"isLocked":false,"blendMode":0,"opacity":100.0,"displayName":"default","resourceVersion":"1.0","name":"2d92f87b-0c00-4e67-b5e5-80435b8a9954","tags":[],"resourceType":"GMImageLayer",}, {"visible":true,"isLocked":false,"blendMode":0,"opacity":100.0,"displayName":"default","resourceVersion":"1.0","name":"510fcb08-c7a7-45d8-a16a-11ddc2105fea","tags":[],"resourceType":"GMImageLayer",},
], ],
"nineSlice": null, "nineSlice": null,
"parent": { "parent": {