diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index c8bdc9a35..b615fd4e4 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -713,6 +713,7 @@ {"name":"node_strand_gravity","order":4,"path":"scripts/node_strand_gravity/node_strand_gravity.yy",}, {"name":"palette_functions","order":3,"path":"scripts/palette_functions/palette_functions.yy",}, {"name":"node_FLIP_apply_velocity","order":7,"path":"scripts/node_FLIP_apply_velocity/node_FLIP_apply_velocity.yy",}, + {"name":"node_FLIP_apply_force","order":8,"path":"scripts/node_FLIP_apply_force/node_FLIP_apply_force.yy",}, {"name":"luaHighlight","order":1,"path":"scripts/luaHighlight/luaHighlight.yy",}, {"name":"d3d_rot3","order":3,"path":"scripts/d3d_rot3/d3d_rot3.yy",}, {"name":"sh_sample_points","order":26,"path":"shaders/sh_sample_points/sh_sample_points.yy",}, @@ -1065,6 +1066,7 @@ {"name":"s_node_strandSim_gravity","order":4,"path":"sprites/s_node_strandSim_gravity/s_node_strandSim_gravity.yy",}, {"name":"node_VFX_effect_turbulence","order":5,"path":"scripts/node_VFX_effect_turbulence/node_VFX_effect_turbulence.yy",}, {"name":"action_loader","order":15,"path":"scripts/action_loader/action_loader.yy",}, + {"name":"s_node_fluidSim_wall","order":12,"path":"sprites/s_node_fluidSim_wall/s_node_fluidSim_wall.yy",}, {"name":"sh_surface_replace_replace","order":1,"path":"shaders/sh_surface_replace_replace/sh_surface_replace_replace.yy",}, {"name":"node_ase_file_read","order":13,"path":"scripts/node_ase_file_read/node_ase_file_read.yy",}, {"name":"s_node_print","order":30,"path":"sprites/s_node_print/s_node_print.yy",}, @@ -1139,6 +1141,7 @@ {"name":"s_node_rigid_variable","order":8,"path":"sprites/s_node_rigid_variable/s_node_rigid_variable.yy",}, {"name":"safe_operation","order":6,"path":"scripts/safe_operation/safe_operation.yy",}, {"name":"s_node_rigid_override","order":9,"path":"sprites/s_node_rigid_override/s_node_rigid_override.yy",}, + {"name":"node_FLIP_wall","order":9,"path":"scripts/node_FLIP_wall/node_FLIP_wall.yy",}, {"name":"s_node_array_get","order":3,"path":"sprites/s_node_array_get/s_node_array_get.yy",}, {"name":"d3d_bbox","order":8,"path":"scripts/d3d_bbox/d3d_bbox.yy",}, {"name":"Obj_FirebaseFirestore_Collection_Query_AscendingDescending","order":1,"path":"objects/Obj_FirebaseFirestore_Collection_Query_AscendingDescending/Obj_FirebaseFirestore_Collection_Query_AscendingDescending.yy",}, @@ -1473,6 +1476,7 @@ {"name":"node_surface_to_color","order":2,"path":"scripts/node_surface_to_color/node_surface_to_color.yy",}, {"name":"sh_shadow_cast_light_sep","order":1,"path":"shaders/sh_shadow_cast_light_sep/sh_shadow_cast_light_sep.yy",}, {"name":"node_audio_loudness","order":1,"path":"scripts/node_audio_loudness/node_audio_loudness.yy",}, + {"name":"sh_FLIP_draw_droplet","order":1,"path":"shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.yy",}, {"name":"node_grid","order":1,"path":"scripts/node_grid/node_grid.yy",}, {"name":"s_node_mk_rain","order":4,"path":"sprites/s_node_mk_rain/s_node_mk_rain.yy",}, {"name":"node_edge_detect","order":8,"path":"scripts/node_edge_detect/node_edge_detect.yy",}, @@ -1722,7 +1726,6 @@ {"name":"s_node_group_output","order":15,"path":"sprites/s_node_group_output/s_node_group_output.yy",}, {"name":"node_path_l_system","order":10,"path":"scripts/node_path_l_system/node_path_l_system.yy",}, {"name":"panel_gradient","order":2,"path":"scripts/panel_gradient/panel_gradient.yy",}, - {"name":"_FLIP","order":2,"path":"scripts/_FLIP/_FLIP.yy",}, {"name":"sh_draw_r16","order":10,"path":"shaders/sh_draw_r16/sh_draw_r16.yy",}, {"name":"sh_channel_S","order":5,"path":"shaders/sh_channel_S/sh_channel_S.yy",}, {"name":"string_scale","order":4,"path":"scripts/string_scale/string_scale.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index 382883ad9..ed0f3b435 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -967,6 +967,7 @@ {"id":{"name":"palette_functions","path":"scripts/palette_functions/palette_functions.yy",},}, {"id":{"name":"sh_alpha_cutoff","path":"shaders/sh_alpha_cutoff/sh_alpha_cutoff.yy",},}, {"id":{"name":"node_FLIP_apply_velocity","path":"scripts/node_FLIP_apply_velocity/node_FLIP_apply_velocity.yy",},}, + {"id":{"name":"node_FLIP_apply_force","path":"scripts/node_FLIP_apply_force/node_FLIP_apply_force.yy",},}, {"id":{"name":"luaHighlight","path":"scripts/luaHighlight/luaHighlight.yy",},}, {"id":{"name":"d3d_rot3","path":"scripts/d3d_rot3/d3d_rot3.yy",},}, {"id":{"name":"sh_sample_points","path":"shaders/sh_sample_points/sh_sample_points.yy",},}, @@ -1366,6 +1367,7 @@ {"id":{"name":"s_node_strandSim_gravity","path":"sprites/s_node_strandSim_gravity/s_node_strandSim_gravity.yy",},}, {"id":{"name":"node_VFX_effect_turbulence","path":"scripts/node_VFX_effect_turbulence/node_VFX_effect_turbulence.yy",},}, {"id":{"name":"action_loader","path":"scripts/action_loader/action_loader.yy",},}, + {"id":{"name":"s_node_fluidSim_wall","path":"sprites/s_node_fluidSim_wall/s_node_fluidSim_wall.yy",},}, {"id":{"name":"sh_surface_replace_replace","path":"shaders/sh_surface_replace_replace/sh_surface_replace_replace.yy",},}, {"id":{"name":"node_ase_file_read","path":"scripts/node_ase_file_read/node_ase_file_read.yy",},}, {"id":{"name":"s_workshop_frame","path":"sprites/s_workshop_frame/s_workshop_frame.yy",},}, @@ -1447,6 +1449,7 @@ {"id":{"name":"s_node_rigid_variable","path":"sprites/s_node_rigid_variable/s_node_rigid_variable.yy",},}, {"id":{"name":"safe_operation","path":"scripts/safe_operation/safe_operation.yy",},}, {"id":{"name":"s_node_rigid_override","path":"sprites/s_node_rigid_override/s_node_rigid_override.yy",},}, + {"id":{"name":"node_FLIP_wall","path":"scripts/node_FLIP_wall/node_FLIP_wall.yy",},}, {"id":{"name":"s_node_array_get","path":"sprites/s_node_array_get/s_node_array_get.yy",},}, {"id":{"name":"d3d_bbox","path":"scripts/d3d_bbox/d3d_bbox.yy",},}, {"id":{"name":"Obj_FirebaseFirestore_Collection_Query_AscendingDescending","path":"objects/Obj_FirebaseFirestore_Collection_Query_AscendingDescending/Obj_FirebaseFirestore_Collection_Query_AscendingDescending.yy",},}, @@ -1836,6 +1839,7 @@ {"id":{"name":"node_surface_to_color","path":"scripts/node_surface_to_color/node_surface_to_color.yy",},}, {"id":{"name":"sh_shadow_cast_light_sep","path":"shaders/sh_shadow_cast_light_sep/sh_shadow_cast_light_sep.yy",},}, {"id":{"name":"node_audio_loudness","path":"scripts/node_audio_loudness/node_audio_loudness.yy",},}, + {"id":{"name":"sh_FLIP_draw_droplet","path":"shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.yy",},}, {"id":{"name":"node_grid","path":"scripts/node_grid/node_grid.yy",},}, {"id":{"name":"s_node_mk_rain","path":"sprites/s_node_mk_rain/s_node_mk_rain.yy",},}, {"id":{"name":"node_edge_detect","path":"scripts/node_edge_detect/node_edge_detect.yy",},}, @@ -2126,7 +2130,6 @@ {"id":{"name":"node_path_l_system","path":"scripts/node_path_l_system/node_path_l_system.yy",},}, {"id":{"name":"panel_gradient","path":"scripts/panel_gradient/panel_gradient.yy",},}, {"id":{"name":"Obj_FirebaseFirestore_Collection_Add","path":"objects/Obj_FirebaseFirestore_Collection_Add/Obj_FirebaseFirestore_Collection_Add.yy",},}, - {"id":{"name":"_FLIP","path":"scripts/_FLIP/_FLIP.yy",},}, {"id":{"name":"sh_draw_r16","path":"shaders/sh_draw_r16/sh_draw_r16.yy",},}, {"id":{"name":"sh_channel_S","path":"shaders/sh_channel_S/sh_channel_S.yy",},}, {"id":{"name":"string_scale","path":"scripts/string_scale/string_scale.yy",},}, diff --git a/fonts/_f_sdf/_f_sdf.old.png b/fonts/_f_sdf/_f_sdf.old.png index ab846849f..3f8002148 100644 Binary files a/fonts/_f_sdf/_f_sdf.old.png and b/fonts/_f_sdf/_f_sdf.old.png differ diff --git a/fonts/_f_sdf/_f_sdf.png b/fonts/_f_sdf/_f_sdf.png index 4d8b0783d..75b2d319a 100644 Binary files a/fonts/_f_sdf/_f_sdf.png and b/fonts/_f_sdf/_f_sdf.png differ diff --git a/fonts/_f_sdf_medium/_f_sdf_medium.old.png b/fonts/_f_sdf_medium/_f_sdf_medium.old.png index 2739fd77d..78d52b7a0 100644 Binary files a/fonts/_f_sdf_medium/_f_sdf_medium.old.png and b/fonts/_f_sdf_medium/_f_sdf_medium.old.png differ diff --git a/fonts/_f_sdf_medium/_f_sdf_medium.png b/fonts/_f_sdf_medium/_f_sdf_medium.png index 8ce603acb..898a1f48f 100644 Binary files a/fonts/_f_sdf_medium/_f_sdf_medium.png and b/fonts/_f_sdf_medium/_f_sdf_medium.png differ diff --git a/objects/FLIP_Domain/Create_0.gml b/objects/FLIP_Domain/Create_0.gml index 87471ac4a..cfa4446fe 100644 --- a/objects/FLIP_Domain/Create_0.gml +++ b/objects/FLIP_Domain/Create_0.gml @@ -16,13 +16,14 @@ dt = 0.1; iteration = 8; - + numPressureIters = 2; + numParticleIters = 2; + g = 1; flipRatio = 0.8; - numPressureIters = 3; - numParticleIters = 3; overRelaxation = 1.5; + obstracles = []; wallCollide = true; #endregion @@ -57,6 +58,9 @@ function init(width, height, particleSize, density, maxParticles) { #region doma domain = FLIP_initDomain(width, height, particleSize, density, maxParticles); particleRadius = FLIP_getParticleRadius(domain); + + cellX = floor(width / particleSize) + 1; + cellY = floor(height / particleSize) + 1; } #endregion function update() { #region @@ -72,10 +76,6 @@ function update() { #region function step() { #region FLIP_resetDensity(domain); - - for( var i = 0, n = array_length(obstracles); i < n; i++ ) - obstracles[i].apply(); - FLIP_simulate(domain, dt); //FLIP_setTimeStep(domain, dt); diff --git a/objects/o_dialog_color_selector/Step_1.gml b/objects/o_dialog_color_selector/Step_1.gml index 158b0d394..177e71d0e 100644 --- a/objects/o_dialog_color_selector/Step_1.gml +++ b/objects/o_dialog_color_selector/Step_1.gml @@ -10,4 +10,16 @@ if !ready exit; instance_destroy(self); } doDrag(); + + if(sFOCUS) { + if(keyboard_check_pressed(vk_enter)) { + onApply(selector.current_color); + instance_destroy(); + } + + if(keyboard_check_pressed(vk_escape)) { + onApply(previous_color); + instance_destroy(); + } + } #endregion \ No newline at end of file diff --git a/objects/o_dialog_gradient/Step_1.gml b/objects/o_dialog_gradient/Step_1.gml index 5b49d546e..352e3fe72 100644 --- a/objects/o_dialog_gradient/Step_1.gml +++ b/objects/o_dialog_gradient/Step_1.gml @@ -9,4 +9,16 @@ if !ready exit; instance_destroy(self); } doDrag(); + + if(sFOCUS) { + if(keyboard_check_pressed(vk_enter)) { + onApply(gradient); + instance_destroy(); + } + + if(keyboard_check_pressed(vk_escape)) { + onApply(previous_gradient); + instance_destroy(); + } + } #endregion \ No newline at end of file diff --git a/objects/o_dialog_palette/Step_1.gml b/objects/o_dialog_palette/Step_1.gml index aecef50c1..a7435c1c8 100644 --- a/objects/o_dialog_palette/Step_1.gml +++ b/objects/o_dialog_palette/Step_1.gml @@ -10,6 +10,18 @@ if !ready exit; } doDrag(); } + + if(sFOCUS) { + if(keyboard_check_pressed(vk_enter)) { + onApply(palette); + instance_destroy(); + } + + if(keyboard_check_pressed(vk_escape)) { + onApply(previous_palette); + instance_destroy(); + } + } #endregion #region resize diff --git a/scripts/_FLIP/_FLIP.gml b/scripts/_FLIP/_FLIP.gml deleted file mode 100644 index 690cc72a0..000000000 --- a/scripts/_FLIP/_FLIP.gml +++ /dev/null @@ -1,19 +0,0 @@ -function FLIP_Obstracle(domain) constructor { - x = 0; - y = 0; - r = 20; - - self.domain = domain; - raw = FLIP_createObstracle(domain); - - static apply = function() { - FLIP_setObstacle_circle(domain, raw, x, y, r, false); - return self; - } - - static draw = function() { - draw_set_color(c_red); - draw_circle(x, y, r, false); - return self; - } -} \ No newline at end of file diff --git a/scripts/node_FLIP_apply_force/node_FLIP_apply_force.gml b/scripts/node_FLIP_apply_force/node_FLIP_apply_force.gml new file mode 100644 index 000000000..ba920f2e0 --- /dev/null +++ b/scripts/node_FLIP_apply_force/node_FLIP_apply_force.gml @@ -0,0 +1,118 @@ +function FLIP_Obstracle() constructor { + x = 0; + y = 0; + + texture = noone; + + static draw = function() { #region + if(!is_surface(texture)) return; + + var _sw = surface_get_width_safe(texture); + var _sh = surface_get_height_safe(texture); + + draw_surface(texture, x - _sw / 2, y - _sh / 2); + } #endregion +} + +function Node_FLIP_Apply_Force(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + name = "Apply Force"; + color = COLORS.node_blend_fluid; + icon = THEME.fluid_sim; + w = 96; + min_h = 96; + + manual_ungroupable = false; + + inputs[| 0] = nodeValue("Domain", self, JUNCTION_CONNECT.input, VALUE_TYPE.fdomain, noone ) + .setVisible(true, true); + + inputs[| 1] = nodeValue("Position", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0 ] ) + .setDisplay(VALUE_DISPLAY.vector); + + inputs[| 2] = nodeValue("Radius", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 4 ) + .setDisplay(VALUE_DISPLAY.slider, { range: [1, 16, 0.1] }); + + inputs[| 3] = nodeValue("Shape", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0 ) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Circle", "Rectangle" ]); + + inputs[| 4] = nodeValue("Size", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 4, 4 ] ) + .setDisplay(VALUE_DISPLAY.vector); + + inputs[| 5] = nodeValue("Texture", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone ) + + input_display_list = [ 0, + ["Collider", false], 3, 2, 4, + ["Obstracle", false], 1, 5, + ] + + outputs[| 0] = nodeValue("Domain", self, JUNCTION_CONNECT.output, VALUE_TYPE.fdomain, noone ); + + obstracle = new FLIP_Obstracle(); + index = 0; + + static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) { #region + var _posit = getInputData(1); + var _rad = getInputData(2); + var _shp = getInputData(3); + var _siz = getInputData(4); + var _tex = getInputData(5); + + var _px = _x + _posit[0] * _s; + var _py = _y + _posit[1] * _s; + + var _r = _rad * _s; + var _w = _siz[0] * _s; + var _h = _siz[1] * _s; + + if(is_surface(_tex)) { + var _sw = surface_get_width_safe(_tex) * _s; + var _sh = surface_get_height_safe(_tex) * _s; + + draw_surface_ext(_tex, _px - _sw / 2, _py - _sh / 2, _s, _s, 0, c_white, 1); + } + + draw_set_color(COLORS._main_accent); + if(_shp == 0) draw_circle(_px, _py, _r, true); + else if(_shp == 1) draw_rectangle(_px - _w, _py - _h, _px + _w, _py + _h, true); + + if(inputs[| 1].drawOverlay(active, _x, _y, _s, _mx, _my, _snx, _sny)) active = false; + + } #endregion + + static step = function() { #region + var _shp = getInputData(3); + + inputs[| 2].setVisible(_shp == 0); + inputs[| 4].setVisible(_shp == 1); + } #endregion + + static update = function(frame = CURRENT_FRAME) { #region + var domain = getInputData(0); + if(!instance_exists(domain)) return; + + outputs[| 0].setValue(domain); + + var _posit = getInputData(1); + var _rad = getInputData(2); + var _shp = getInputData(3); + var _siz = getInputData(4); + var _tex = getInputData(5); + + obstracle.x = _posit[0]; + obstracle.y = _posit[1]; + obstracle.texture = _tex; + + if(frame == 0) { + index = FLIP_createObstracle(domain.domain); + array_push(domain.obstracles, obstracle); + } + + if(_shp == 0) FLIP_setObstracle_circle(domain.domain, index, _posit[0], _posit[1], _rad); + else if(_shp == 1) FLIP_setObstracle_rectangle(domain.domain, index, _posit[0], _posit[1], _siz[0], _siz[1]); + } #endregion + + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { + var bbox = drawGetBbox(xx, yy, _s); + draw_sprite_fit(s_node_fluidSim_add_collider, 0, bbox.xc, bbox.yc, bbox.w, bbox.h); + } +} \ No newline at end of file diff --git a/scripts/node_FLIP_apply_force/node_FLIP_apply_force.yy b/scripts/node_FLIP_apply_force/node_FLIP_apply_force.yy new file mode 100644 index 000000000..dc54d1710 --- /dev/null +++ b/scripts/node_FLIP_apply_force/node_FLIP_apply_force.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "node_FLIP_apply_force", + "isCompatibility": false, + "isDnD": false, + "parent": { + "name": "FLIP", + "path": "folders/nodes/data/simulation/FLIP.yy", + }, +} \ No newline at end of file diff --git a/scripts/node_FLIP_apply_velocity/node_FLIP_apply_velocity.gml b/scripts/node_FLIP_apply_velocity/node_FLIP_apply_velocity.gml index dcd948993..fbfb52a1a 100644 --- a/scripts/node_FLIP_apply_velocity/node_FLIP_apply_velocity.gml +++ b/scripts/node_FLIP_apply_velocity/node_FLIP_apply_velocity.gml @@ -19,8 +19,14 @@ function Node_FLIP_Apply_Velocity(_x, _y, _group = noone) : Node(_x, _y, _group) inputs[| 3] = nodeValue("Velocity", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0 ] ) .setDisplay(VALUE_DISPLAY.vector); + inputs[| 4] = nodeValue("Shape", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0 ) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Circle", "Rectangle" ]); + + inputs[| 5] = nodeValue("Size", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 4, 4 ] ) + .setDisplay(VALUE_DISPLAY.vector); + input_display_list = [ 0, - ["Velocity", false], 1, 2, 3, + ["Velocity", false], 4, 1, 2, 5, 3, ] outputs[| 0] = nodeValue("Domain", self, JUNCTION_CONNECT.output, VALUE_TYPE.fdomain, noone ); @@ -29,17 +35,22 @@ function Node_FLIP_Apply_Velocity(_x, _y, _group = noone) : Node(_x, _y, _group) var _posit = getInputData(1); var _rad = getInputData(2); var _velo = getInputData(3); + var _shp = getInputData(4); + var _siz = getInputData(5); var _px = _x + _posit[0] * _s; var _py = _y + _posit[1] * _s; var _vx = _px + _velo[0] * _s; var _vy = _py + _velo[1] * _s; - - if(inputs[| 2].drawOverlay(active, _px, _py, _s, _mx, _my, _snx, _sny, 0, 1, THEME.anchor_scale_hori)) active = false; - + + var _r = _rad * _s; + var _w = _siz[0] * _s; + var _h = _siz[1] * _s; + draw_set_color(COLORS._main_accent); - draw_circle(_px, _py, _rad * _s, true); + if(_shp == 0) draw_circle(_px, _py, _r, true); + else if(_shp == 1) draw_rectangle(_px - _w, _py - _h, _px + _w, _py + _h, true); draw_set_color(COLORS._main_accent); draw_set_alpha(0.5); @@ -51,7 +62,14 @@ function Node_FLIP_Apply_Velocity(_x, _y, _group = noone) : Node(_x, _y, _group) } #endregion - static update = function(frame = CURRENT_FRAME) { + static step = function() { #region + var _shp = getInputData(4); + + inputs[| 2].setVisible(_shp == 0); + inputs[| 5].setVisible(_shp == 1); + } #endregion + + static update = function(frame = CURRENT_FRAME) { #region var domain = getInputData(0); if(!instance_exists(domain)) return; @@ -60,7 +78,15 @@ function Node_FLIP_Apply_Velocity(_x, _y, _group = noone) : Node(_x, _y, _group) var _posit = getInputData(1); var _rad = getInputData(2); var _velo = getInputData(3); + var _shp = getInputData(4); + var _siz = getInputData(5); - FLIP_applyVelocity_circle(domain.domain, _posit[0], _posit[1], _rad, _velo[0], _velo[1]); + if(_shp == 0) FLIP_applyVelocity_circle(domain.domain, _posit[0], _posit[1], _rad, _velo[0], _velo[1]); + else if(_shp == 1) FLIP_applyVelocity_rectangle(domain.domain, _posit[0] - _siz[0], _posit[1] - _siz[1], _siz[0] * 2, _siz[1] * 2, _velo[0], _velo[1]); + } #endregion + + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { + var bbox = drawGetBbox(xx, yy, _s); + draw_sprite_fit(s_node_fluidSim_apply_velocity, 0, bbox.xc, bbox.yc, bbox.w, bbox.h); } } \ No newline at end of file diff --git a/scripts/node_FLIP_domain/node_FLIP_domain.gml b/scripts/node_FLIP_domain/node_FLIP_domain.gml index 6be8e9355..e67dc0ba7 100644 --- a/scripts/node_FLIP_domain/node_FLIP_domain.gml +++ b/scripts/node_FLIP_domain/node_FLIP_domain.gml @@ -32,21 +32,55 @@ function Node_FLIP_Domain(_x, _y, _group = noone) : Node(_x, _y, _group) constru inputs[| 9] = nodeValue("Collide wall", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); inputs[| 10] = nodeValue("Viscosity", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.) - .setDisplay(VALUE_DISPLAY.slider); + .setDisplay(VALUE_DISPLAY.slider, { range: [ -1, 1, 0.01 ] }); inputs[| 11] = nodeValue("Friction", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.) .setDisplay(VALUE_DISPLAY.slider); input_display_list = [ ["Domain", false], 0, 1, 2, 9, - ["Solver", false], 3, 4, 5, 8, + ["Solver", false], 3, 8, ["Physics", false], 6, 7, 10, 11, ] outputs[| 0] = nodeValue("Domain", self, JUNCTION_CONNECT.output, VALUE_TYPE.fdomain, noone); - attributes.max_particles = 10000; + array_push(attributeEditors, "FLIP Solver"); + attributes.max_particles = 10000; + array_push(attributeEditors, ["Maximum particles", function() { return attributes.max_particles; }, + new textBox(TEXTBOX_INPUT.number, function(val) { + attributes.max_particles = val; + })]); + + attributes.iteration = 8; + array_push(attributeEditors, ["Global iteration", function() { return attributes.iteration; }, + new textBox(TEXTBOX_INPUT.number, function(val) { + attributes.iteration = val; + triggerRender(); + })]); + + attributes.iteration_pressure = 2; + array_push(attributeEditors, ["Pressure iteration", function() { return attributes.iteration_pressure; }, + new textBox(TEXTBOX_INPUT.number, function(val) { + attributes.iteration_pressure = val; + triggerRender(); + })]); + + attributes.iteration_particle = 2; + array_push(attributeEditors, ["Particle iteration", function() { return attributes.iteration_particle; }, + new textBox(TEXTBOX_INPUT.number, function(val) { + attributes.iteration_particle = val; + triggerRender(); + })]); + + attributes.overrelax = 1.5; + array_push(attributeEditors, ["Overrelaxation", function() { return attributes.overrelax; }, + new textBox(TEXTBOX_INPUT.number, function(val) { + attributes.overrelax = val; + triggerRender(); + })]); + domain = instance_create(0, 0, FLIP_Domain); static update = function(frame = CURRENT_FRAME) { @@ -55,8 +89,6 @@ function Node_FLIP_Domain(_x, _y, _group = noone) : Node(_x, _y, _group) constru var _den = getInputData(2); var _flp = getInputData(3); - var _ovr = getInputData(4); - var _itr = getInputData(5); var _dmp = getInputData(6); var _grv = getInputData(7); @@ -66,7 +98,13 @@ function Node_FLIP_Domain(_x, _y, _group = noone) : Node(_x, _y, _group) constru var _vis = getInputData(10); var _fric = getInputData(11); - if(frame == 0 || domain == noone) { + var _ovr = attributes.overrelax; + + var _itr = attributes.iteration; + var _itrP = attributes.iteration_pressure; + var _itrR = attributes.iteration_particle; + + if(frame == 0) { var width = _dim[0] + _siz * 2; var height = _dim[1] + _siz * 2; var particleSize = _siz; @@ -78,12 +116,13 @@ function Node_FLIP_Domain(_x, _y, _group = noone) : Node(_x, _y, _group) constru domain.velocityDamping = _dmp; domain.dt = _dt; + domain.iteration = _itr; + domain.numPressureIters = _itrP; + domain.numParticleIters = _itrR; domain.g = _grv; domain.flipRatio = _flp; - domain.numPressureIters = 3; - domain.numParticleIters = 3; domain.overRelaxation = _ovr; domain.viscosity = _vis; domain.friction = _fric; diff --git a/scripts/node_FLIP_render/node_FLIP_render.gml b/scripts/node_FLIP_render/node_FLIP_render.gml index f7762eeb3..d4036acc8 100644 --- a/scripts/node_FLIP_render/node_FLIP_render.gml +++ b/scripts/node_FLIP_render/node_FLIP_render.gml @@ -8,13 +8,18 @@ function Node_FLIP_Render(_x, _y, _group = noone) : Node(_x, _y, _group) constru inputs[| 0] = nodeValue("Domain", self, JUNCTION_CONNECT.input, VALUE_TYPE.fdomain, noone) .setVisible(true, true); - inputs[| 1] = nodeValue("Blending", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.5) + inputs[| 1] = nodeValue("Merge threshold", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.5) .setDisplay(VALUE_DISPLAY.slider); inputs[| 2] = nodeValue("Vaporize", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0); + inputs[| 3] = nodeValue("Particle expansion", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 8); + + inputs[| 4] = nodeValue("Draw obstracles", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); + input_display_list = [ 0, - ["Rendering", false], 1, 2, + ["Effect", false], 2, + ["Rendering", false], 3, 1, 4, ]; outputs[| 0] = nodeValue("Rendered", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); @@ -29,6 +34,8 @@ function Node_FLIP_Render(_x, _y, _group = noone) : Node(_x, _y, _group) constru var _bln = getInputData(1); var _vap = getInputData(2); + var _exp = getInputData(3); + var _obs = getInputData(4); var _outSurf = outputs[| 0].getValue(); var _padd = domain.particleSize; @@ -41,11 +48,10 @@ function Node_FLIP_Render(_x, _y, _group = noone) : Node(_x, _y, _group) constru outputs[| 0].setValue(_outSurf); var _x, _y, _r, _l; - var _rad = domain.particleRadius; + var _rad = domain.particleRadius * _exp; var _mx = min(array_length(domain.particlePos) / 2 - 1, domain.numParticles); - surface_set_target(temp_surface[0]); - DRAW_CLEAR + surface_set_shader(temp_surface[0], sh_FLIP_draw_droplet); BLEND_ADD for( var i = 0; i < _mx; i++ ) { @@ -57,10 +63,10 @@ function Node_FLIP_Render(_x, _y, _group = noone) : Node(_x, _y, _group) constru _x -= _padd; _y -= _padd; - _r = _rad * 4; + _r = _rad; if(_vap) { - var _r = (_vap - _l) / _vap * _rad * 4; + _r = (_vap - _l) / _vap * _rad; if(_r < 0) continue; } @@ -68,13 +74,20 @@ function Node_FLIP_Render(_x, _y, _group = noone) : Node(_x, _y, _group) constru } BLEND_NORMAL - surface_reset_target(); - - surface_set_shader(_outSurf, sh_FLIP_render_threshold); - shader_set_f("threshold", 1 - _bln); - - draw_surface(temp_surface[0], 0, 0); surface_reset_shader(); + + surface_set_target(_outSurf); + DRAW_CLEAR + + shader_set(sh_FLIP_render_threshold); + shader_set_f("threshold", 1 - _bln); + draw_surface(temp_surface[0], 0, 0); + shader_reset(); + + if(_obs) + for( var i = 0, n = array_length(domain.obstracles); i < n; i++ ) + domain.obstracles[i].draw(); + surface_reset_target(); } } \ No newline at end of file diff --git a/scripts/node_FLIP_spawner/node_FLIP_spawner.gml b/scripts/node_FLIP_spawner/node_FLIP_spawner.gml index 72780391b..ac56ee367 100644 --- a/scripts/node_FLIP_spawner/node_FLIP_spawner.gml +++ b/scripts/node_FLIP_spawner/node_FLIP_spawner.gml @@ -166,7 +166,6 @@ function Node_FLIP_Spawner(_x, _y, _group = noone) : Node(_x, _y, _group) constr static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { var bbox = drawGetBbox(xx, yy, _s); - draw_sprite_fit(s_node_fluidSim_add_fluid, 0, bbox.xc, bbox.yc, bbox.w, bbox.h); } } \ No newline at end of file diff --git a/scripts/node_FLIP_wall/node_FLIP_wall.gml b/scripts/node_FLIP_wall/node_FLIP_wall.gml new file mode 100644 index 000000000..e824f4ea5 --- /dev/null +++ b/scripts/node_FLIP_wall/node_FLIP_wall.gml @@ -0,0 +1,44 @@ +function Node_FLIP_Wall(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + name = "Wall"; + color = COLORS.node_blend_fluid; + icon = THEME.fluid_sim; + w = 96; + min_h = 96; + + manual_ungroupable = false; + + inputs[| 0] = nodeValue("Domain", self, JUNCTION_CONNECT.input, VALUE_TYPE.fdomain, noone ) + .setVisible(true, true); + + inputs[| 1] = nodeValue("Area", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 16, 16, 4, 4, AREA_SHAPE.rectangle ]) + .setDisplay(VALUE_DISPLAY.area); + + input_display_list = [ 0, + ["Collider", false], 1 + ] + + outputs[| 0] = nodeValue("Domain", self, JUNCTION_CONNECT.output, VALUE_TYPE.fdomain, noone ); + + obstracle = new FLIP_Obstracle(); + index = 0; + + static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) { #region + if(inputs[| 1].drawOverlay(active, _x, _y, _s, _mx, _my, _snx, _sny)) active = false; + } #endregion + + static update = function(frame = CURRENT_FRAME) { #region + var domain = getInputData(0); + if(!instance_exists(domain)) return; + + outputs[| 0].setValue(domain); + + var _area = getInputData(1); + + FLIP_setSolid_rectangle(domain.domain, index, _area[0], _area[1], _area[2], _area[3]); + } #endregion + + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { + var bbox = drawGetBbox(xx, yy, _s); + draw_sprite_fit(s_node_fluidSim_wall, 0, bbox.xc, bbox.yc, bbox.w, bbox.h); + } +} \ No newline at end of file diff --git a/scripts/_FLIP/_FLIP.yy b/scripts/node_FLIP_wall/node_FLIP_wall.yy similarity index 87% rename from scripts/_FLIP/_FLIP.yy rename to scripts/node_FLIP_wall/node_FLIP_wall.yy index d00ca1657..de4c6a7db 100644 --- a/scripts/_FLIP/_FLIP.yy +++ b/scripts/node_FLIP_wall/node_FLIP_wall.yy @@ -1,7 +1,7 @@ { "resourceType": "GMScript", "resourceVersion": "1.0", - "name": "_FLIP", + "name": "node_FLIP_wall", "isCompatibility": false, "isDnD": false, "parent": { diff --git a/scripts/node_registry/node_registry.gml b/scripts/node_registry/node_registry.gml index 94cada59a..97911a96f 100644 --- a/scripts/node_registry/node_registry.gml +++ b/scripts/node_registry/node_registry.gml @@ -402,6 +402,8 @@ function __initNodes() { ds_list_add(flipSim, "Fluid"); addNodeObject(flipSim, "Spawner", s_node_fluidSim_add_fluid, "Node_FLIP_Spawner", [1, Node_FLIP_Spawner]).hideRecent().setVersion(11620); addNodeObject(flipSim, "Apply Velocity", s_node_fluidSim_apply_velocity, "Node_FLIP_Apply_Velocity", [1, Node_FLIP_Apply_Velocity]).hideRecent().setVersion(11620); + addNodeObject(flipSim, "Apply Force", s_node_fluidSim_add_collider, "Node_FLIP_Apply_Force", [1, Node_FLIP_Apply_Force]).hideRecent().setVersion(11620); + addNodeObject(flipSim, "Wall", s_node_fluidSim_wall, "Node_FLIP_Wall", [1, Node_FLIP_Wall]).hideRecent().setVersion(11620); #endregion var strandSim = ds_list_create(); #region diff --git a/shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.fsh b/shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.fsh new file mode 100644 index 000000000..7a3d6f7b1 --- /dev/null +++ b/shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.fsh @@ -0,0 +1,12 @@ +// +// Simple passthrough fragment shader +// +//varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +void main() { + float g = v_vColour.g; + g = g * g; + + gl_FragColor = vec4(vec3(g), 1.); +} diff --git a/shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.vsh b/shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.vsh new file mode 100644 index 000000000..15959c8ee --- /dev/null +++ b/shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.vsh @@ -0,0 +1,19 @@ +// +// Simple passthrough vertex shader +// +attribute vec3 in_Position; // (x,y,z) +//attribute vec3 in_Normal; // (x,y,z) unused in this shader. +attribute vec4 in_Colour; // (r,g,b,a) +//attribute vec2 in_TextureCoord; // (u,v) + +//varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +void main() +{ + vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0); + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos; + + v_vColour = in_Colour; + //v_vTexcoord = in_TextureCoord; +} diff --git a/shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.yy b/shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.yy new file mode 100644 index 000000000..65d5d9bbf --- /dev/null +++ b/shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "sh_FLIP_draw_droplet", + "parent": { + "name": "FLIP", + "path": "folders/shader/FLIP.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/sprites/s_node_fluidSim_wall/3e385a06-208f-4558-83b6-103f8d917397.png b/sprites/s_node_fluidSim_wall/3e385a06-208f-4558-83b6-103f8d917397.png new file mode 100644 index 000000000..ddb632760 Binary files /dev/null and b/sprites/s_node_fluidSim_wall/3e385a06-208f-4558-83b6-103f8d917397.png differ diff --git a/sprites/s_node_fluidSim_wall/layers/3e385a06-208f-4558-83b6-103f8d917397/e07e030b-21b3-4d27-a055-45701e82fe35.png b/sprites/s_node_fluidSim_wall/layers/3e385a06-208f-4558-83b6-103f8d917397/e07e030b-21b3-4d27-a055-45701e82fe35.png new file mode 100644 index 000000000..ddb632760 Binary files /dev/null and b/sprites/s_node_fluidSim_wall/layers/3e385a06-208f-4558-83b6-103f8d917397/e07e030b-21b3-4d27-a055-45701e82fe35.png differ diff --git a/sprites/s_node_fluidSim_wall/s_node_fluidSim_wall.yy b/sprites/s_node_fluidSim_wall/s_node_fluidSim_wall.yy new file mode 100644 index 000000000..530a1f084 --- /dev/null +++ b/sprites/s_node_fluidSim_wall/s_node_fluidSim_wall.yy @@ -0,0 +1,74 @@ +{ + "resourceType": "GMSprite", + "resourceVersion": "1.0", + "name": "s_node_fluidSim_wall", + "bbox_bottom": 58, + "bbox_left": 7, + "bbox_right": 56, + "bbox_top": 8, + "bboxMode": 0, + "collisionKind": 1, + "collisionTolerance": 0, + "DynamicTexturePage": false, + "edgeFiltering": false, + "For3D": false, + "frames": [ + {"resourceType":"GMSpriteFrame","resourceVersion":"1.1","name":"3e385a06-208f-4558-83b6-103f8d917397",}, + ], + "gridX": 0, + "gridY": 0, + "height": 64, + "HTile": false, + "layers": [ + {"resourceType":"GMImageLayer","resourceVersion":"1.0","name":"e07e030b-21b3-4d27-a055-45701e82fe35","blendMode":0,"displayName":"default","isLocked":false,"opacity":100.0,"visible":true,}, + ], + "nineSlice": null, + "origin": 4, + "parent": { + "name": "fluidSim", + "path": "folders/nodes/icons/fluidSim.yy", + }, + "preMultiplyAlpha": false, + "sequence": { + "resourceType": "GMSequence", + "resourceVersion": "1.4", + "name": "s_node_fluidSim_wall", + "autoRecord": true, + "backdropHeight": 768, + "backdropImageOpacity": 0.5, + "backdropImagePath": "", + "backdropWidth": 1366, + "backdropXOffset": 0.0, + "backdropYOffset": 0.0, + "events": {"resourceType":"KeyframeStore","resourceVersion":"1.0","Keyframes":[],}, + "eventStubScript": null, + "eventToFunction": {}, + "length": 1.0, + "lockOrigin": false, + "moments": {"resourceType":"KeyframeStore","resourceVersion":"1.0","Keyframes":[],}, + "playback": 1, + "playbackSpeed": 30.0, + "playbackSpeedType": 0, + "showBackdrop": true, + "showBackdropImage": false, + "timeUnits": 1, + "tracks": [ + {"resourceType":"GMSpriteFramesTrack","resourceVersion":"1.0","name":"frames","builtinName":0,"events":[],"inheritsTrackColour":true,"interpolation":1,"isCreationTrack":false,"keyframes":{"resourceType":"KeyframeStore","resourceVersion":"1.0","Keyframes":[ + {"resourceType":"Keyframe","resourceVersion":"1.0","Channels":{"0":{"resourceType":"SpriteFrameKeyframe","resourceVersion":"1.0","Id":{"name":"3e385a06-208f-4558-83b6-103f8d917397","path":"sprites/s_node_fluidSim_wall/s_node_fluidSim_wall.yy",},},},"Disabled":false,"id":"e2978518-3c16-4792-9f39-7d17d87efc2c","IsCreationKey":false,"Key":0.0,"Length":1.0,"Stretch":false,}, + ],},"modifiers":[],"spriteId":null,"trackColour":0,"tracks":[],"traits":0,}, + ], + "visibleRange": null, + "volume": 1.0, + "xorigin": 32, + "yorigin": 32, + }, + "swatchColours": null, + "swfPrecision": 2.525, + "textureGroupId": { + "name": "Default", + "path": "texturegroups/Default", + }, + "type": 0, + "VTile": false, + "width": 64, +} \ No newline at end of file