diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index b615fd4e4..faba4f972 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -1127,6 +1127,7 @@ {"name":"node_sequence_to_anim","order":3,"path":"scripts/node_sequence_to_anim/node_sequence_to_anim.yy",}, {"name":"sh_blend_replace","order":50,"path":"shaders/sh_blend_replace/sh_blend_replace.yy",}, {"name":"node_FLIP_domain","order":1,"path":"scripts/node_FLIP_domain/node_FLIP_domain.yy",}, + {"name":"node_FLIP_update","order":10,"path":"scripts/node_FLIP_update/node_FLIP_update.yy",}, {"name":"node_rigid_render","order":3,"path":"scripts/node_rigid_render/node_rigid_render.yy",}, {"name":"node_image_splice_sheet","order":4,"path":"scripts/node_image_splice_sheet/node_image_splice_sheet.yy",}, {"name":"node_VFX_renderer_output","order":8,"path":"scripts/node_VFX_renderer_output/node_VFX_renderer_output.yy",}, @@ -1181,6 +1182,7 @@ {"name":"node_glow","order":10,"path":"scripts/node_glow/node_glow.yy",}, {"name":"sh_blend_min","order":9,"path":"shaders/sh_blend_min/sh_blend_min.yy",}, {"name":"d3d_gizmo_circle_z","order":4,"path":"scripts/d3d_gizmo_circle_z/d3d_gizmo_circle_z.yy",}, + {"name":"node_mk_flame","order":9,"path":"scripts/node_mk_flame/node_mk_flame.yy",}, {"name":"sh_d3d_background","order":21,"path":"shaders/sh_d3d_background/sh_d3d_background.yy",}, {"name":"s_node_3d_scene","order":14,"path":"sprites/s_node_3d_scene/s_node_3d_scene.yy",}, {"name":"sh_pb_shade_half","order":5,"path":"shaders/sh_pb_shade_half/sh_pb_shade_half.yy",}, @@ -1731,6 +1733,7 @@ {"name":"string_scale","order":4,"path":"scripts/string_scale/string_scale.yy",}, {"name":"node_struct_set","order":3,"path":"scripts/node_struct_set/node_struct_set.yy",}, {"name":"s_node_cache","order":27,"path":"sprites/s_node_cache/s_node_cache.yy",}, + {"name":"s_node_fluidSim_force","order":13,"path":"sprites/s_node_fluidSim_force/s_node_fluidSim_force.yy",}, {"name":"node_repeat","order":8,"path":"scripts/node_repeat/node_repeat.yy",}, {"name":"draw_arc","order":22,"path":"scripts/draw_arc/draw_arc.yy",}, {"name":"sh_fd_advect_velocity_1_glsl","order":7,"path":"shaders/sh_fd_advect_velocity_1_glsl/sh_fd_advect_velocity_1_glsl.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index ed0f3b435..fc3ac2471 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -1434,6 +1434,7 @@ {"id":{"name":"node_sequence_to_anim","path":"scripts/node_sequence_to_anim/node_sequence_to_anim.yy",},}, {"id":{"name":"sh_blend_replace","path":"shaders/sh_blend_replace/sh_blend_replace.yy",},}, {"id":{"name":"node_FLIP_domain","path":"scripts/node_FLIP_domain/node_FLIP_domain.yy",},}, + {"id":{"name":"node_FLIP_update","path":"scripts/node_FLIP_update/node_FLIP_update.yy",},}, {"id":{"name":"node_rigid_render","path":"scripts/node_rigid_render/node_rigid_render.yy",},}, {"id":{"name":"node_image_splice_sheet","path":"scripts/node_image_splice_sheet/node_image_splice_sheet.yy",},}, {"id":{"name":"node_VFX_renderer_output","path":"scripts/node_VFX_renderer_output/node_VFX_renderer_output.yy",},}, @@ -1495,6 +1496,7 @@ {"id":{"name":"node_glow","path":"scripts/node_glow/node_glow.yy",},}, {"id":{"name":"sh_blend_min","path":"shaders/sh_blend_min/sh_blend_min.yy",},}, {"id":{"name":"d3d_gizmo_circle_z","path":"scripts/d3d_gizmo_circle_z/d3d_gizmo_circle_z.yy",},}, + {"id":{"name":"node_mk_flame","path":"scripts/node_mk_flame/node_mk_flame.yy",},}, {"id":{"name":"sh_d3d_background","path":"shaders/sh_d3d_background/sh_d3d_background.yy",},}, {"id":{"name":"s_node_3d_scene","path":"sprites/s_node_3d_scene/s_node_3d_scene.yy",},}, {"id":{"name":"sh_pb_shade_half","path":"shaders/sh_pb_shade_half/sh_pb_shade_half.yy",},}, @@ -2136,6 +2138,7 @@ {"id":{"name":"node_struct_set","path":"scripts/node_struct_set/node_struct_set.yy",},}, {"id":{"name":"s_node_cache","path":"sprites/s_node_cache/s_node_cache.yy",},}, {"id":{"name":"node_logic_operate","path":"scripts/node_logic_operate/node_logic_operate.yy",},}, + {"id":{"name":"s_node_fluidSim_force","path":"sprites/s_node_fluidSim_force/s_node_fluidSim_force.yy",},}, {"id":{"name":"node_repeat","path":"scripts/node_repeat/node_repeat.yy",},}, {"id":{"name":"draw_arc","path":"scripts/draw_arc/draw_arc.yy",},}, {"id":{"name":"sh_fd_advect_velocity_1_glsl","path":"shaders/sh_fd_advect_velocity_1_glsl/sh_fd_advect_velocity_1_glsl.yy",},}, diff --git a/datafiles/data/Theme.zip b/datafiles/data/Theme.zip index c5972f728..f124e233b 100644 Binary files a/datafiles/data/Theme.zip and b/datafiles/data/Theme.zip differ diff --git a/fonts/_f_sdf/_f_sdf.old.png b/fonts/_f_sdf/_f_sdf.old.png index 3f8002148..b1defb063 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 75b2d319a..af7df824d 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 78d52b7a0..87782c2e6 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 898a1f48f..0a09e6d0d 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 cfa4446fe..656ce1ca8 100644 --- a/objects/FLIP_Domain/Create_0.gml +++ b/objects/FLIP_Domain/Create_0.gml @@ -25,10 +25,16 @@ obstracles = []; wallCollide = true; + wallElasticity = 1; + + skip_incompressible = false; + + particleRadius = 0; #endregion function init(width, height, particleSize, density, maxParticles) { #region domain init particlePos = array_create(maxParticles * 2); + particleHist = array_create(maxParticles * 2); particleLife = array_create(maxParticles); obstracles = []; numParticles = 0; @@ -71,31 +77,35 @@ function update() { #region FLIP_setFlipRatio( domain, flipRatio); FLIP_setVelocityDamping( domain, velocityDamping); FLIP_setOverRelaxation( domain, overRelaxation); - FLIP_setWallCollisions( domain, wallCollide); + FLIP_setWallCollisions( domain, wallCollide, wallElasticity); } #endregion function step() { #region FLIP_resetDensity(domain); - FLIP_simulate(domain, dt); - //FLIP_setTimeStep(domain, dt); - //repeat(iteration) { - // FLIP_simulate_integrateParticles(domain); - // FLIP_simulate_pushParticlesApart(domain); - // FLIP_simulate_handleParticleCollisions(domain); - // FLIP_simulate_transferVelocities(domain, 1); - // FLIP_simulate_updateParticleDensity(domain); - // FLIP_simulate_solveIncompressibility(domain); - // FLIP_simulate_transferVelocities(domain, 0); - //} + if(skip_incompressible) { + FLIP_setTimeStep(domain, dt); + repeat(iteration) { + FLIP_simulate_integrateParticles(domain); + FLIP_simulate_pushParticlesApart(domain); + FLIP_simulate_handleParticleCollisions(domain); + //FLIP_simulate_transferVelocities(domain, 1); + //FLIP_simulate_updateParticleDensity(domain); + //FLIP_simulate_solveIncompressibility(domain); + //FLIP_simulate_transferVelocities(domain, 0); + } + } else + FLIP_simulate(domain, dt); FLIP_setParticleBuffer(domain, aPosBuff, aLifeBuff); buffer_seek(particlePosBuff, buffer_seek_start, 0); buffer_seek(particleLifeBuff, buffer_seek_start, 0); - for(var i = 0; i < maxParticles * 2; i++) - particlePos[i] = buffer_read(particlePosBuff, buffer_f64); + for(var i = 0; i < maxParticles * 2; i++) { + particleHist[i] = particlePos[i]; + particlePos[i] = buffer_read(particlePosBuff, buffer_f64); + } for(var i = 0; i < maxParticles; i++) particleLife[i] = buffer_read(particleLifeBuff, buffer_f64); diff --git a/scripts/globals/globals.gml b/scripts/globals/globals.gml index d73791b89..a580d7c19 100644 --- a/scripts/globals/globals.gml +++ b/scripts/globals/globals.gml @@ -24,7 +24,7 @@ globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER, LATEST_VERSION; - LATEST_VERSION = 11500; + LATEST_VERSION = 11600; VERSION = 11620; SAVE_VERSION = 11620; VERSION_STRING = "1.16.2.0"; diff --git a/scripts/nodeValue_drawer/nodeValue_drawer.gml b/scripts/nodeValue_drawer/nodeValue_drawer.gml index 2289b0eff..44d035497 100644 --- a/scripts/nodeValue_drawer/nodeValue_drawer.gml +++ b/scripts/nodeValue_drawer/nodeValue_drawer.gml @@ -128,7 +128,7 @@ function drawWidget(xx, yy, ww, _m, jun, global_var = true, _hover = false, _foc return [ 0, true ]; } #endregion - draw_text_add(lb_x, lb_y - ui(2), _name); + draw_text_add(lb_x, lb_y, _name); #region tooltip if(jun.tooltip != "") { diff --git a/scripts/node_FLIP_domain/node_FLIP_domain.gml b/scripts/node_FLIP_domain/node_FLIP_domain.gml index e67dc0ba7..1ca137c5d 100644 --- a/scripts/node_FLIP_domain/node_FLIP_domain.gml +++ b/scripts/node_FLIP_domain/node_FLIP_domain.gml @@ -11,7 +11,7 @@ function Node_FLIP_Domain(_x, _y, _group = noone) : Node(_x, _y, _group) constru inputs[| 0] = nodeValue("Dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, DEF_SURF) .setDisplay(VALUE_DISPLAY.vector); - inputs[| 1] = nodeValue("Particle Size", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 2); + inputs[| 1] = nodeValue("Particle Size", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1); inputs[| 2] = nodeValue("Particle Density", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 10); @@ -29,7 +29,8 @@ function Node_FLIP_Domain(_x, _y, _group = noone) : Node(_x, _y, _group) constru inputs[| 8] = nodeValue("Time Step", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.05); - inputs[| 9] = nodeValue("Collide wall", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); + inputs[| 9] = nodeValue("Wall type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "None", "Surround", "Ground only" ]); inputs[| 10] = nodeValue("Viscosity", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.) .setDisplay(VALUE_DISPLAY.slider, { range: [ -1, 1, 0.01 ] }); @@ -37,50 +38,62 @@ function Node_FLIP_Domain(_x, _y, _group = noone) : Node(_x, _y, _group) constru inputs[| 11] = nodeValue("Friction", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.) .setDisplay(VALUE_DISPLAY.slider); + inputs[| 12] = nodeValue("Wall Elasticity", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.) + .setDisplay(VALUE_DISPLAY.slider, { range: [ 0, 2, 0.01 ] }); + input_display_list = [ - ["Domain", false], 0, 1, 2, 9, + ["Domain", false], 0, 1, 2, 9, 12, ["Solver", false], 3, 8, ["Physics", false], 6, 7, 10, 11, ] outputs[| 0] = nodeValue("Domain", self, JUNCTION_CONNECT.output, VALUE_TYPE.fdomain, noone); - array_push(attributeEditors, "FLIP Solver"); + #region attributes + 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.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 = 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_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.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(); + })]); + + attributes.skip_incompressible = false; + array_push(attributeEditors, ["Skip incompressible", function() { return attributes.skip_incompressible; }, + new checkBox(function() { + attributes.skip_incompressible = !attributes.skip_incompressible; + triggerRender(); + })]); + #endregion - 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) { @@ -97,6 +110,7 @@ function Node_FLIP_Domain(_x, _y, _group = noone) : Node(_x, _y, _group) constru var _vis = getInputData(10); var _fric = getInputData(11); + var _ela = getInputData(12); var _ovr = attributes.overrelax; @@ -128,6 +142,8 @@ function Node_FLIP_Domain(_x, _y, _group = noone) : Node(_x, _y, _group) constru domain.friction = _fric; domain.wallCollide = _col; + domain.wallElasticity = _ela; + domain.skip_incompressible = attributes.skip_incompressible; domain.update(); diff --git a/scripts/node_FLIP_render/node_FLIP_render.gml b/scripts/node_FLIP_render/node_FLIP_render.gml index d4036acc8..b41aaa08f 100644 --- a/scripts/node_FLIP_render/node_FLIP_render.gml +++ b/scripts/node_FLIP_render/node_FLIP_render.gml @@ -8,34 +8,72 @@ 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("Merge threshold", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.5) + inputs[| 1] = nodeValue("Merge threshold", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.75) .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[| 3] = nodeValue("Particle expansion", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 10); inputs[| 4] = nodeValue("Draw obstracles", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); - input_display_list = [ 0, + inputs[| 5] = nodeValue("Fluid particle", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 6] = nodeValue("Render type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Particle", "Line" ] ); + + inputs[| 7] = nodeValue("Threshold", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); + + inputs[| 8] = nodeValue("Additive", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); + + inputs[| 9] = nodeValue("Alpha", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 1, 1 ]) + .setDisplay(VALUE_DISPLAY.range); + + input_display_list = [ 0, 5, + ["Rendering", false], 6, 3, 4, 9, ["Effect", false], 2, - ["Rendering", false], 3, 1, 4, + ["Post Processing", false], 8, 7, 1, ]; outputs[| 0] = nodeValue("Rendered", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); - temp_surface = [ noone ] + seed = irandom_range(100000, 999999); + temp_surface = [ noone ]; + + array_push(attributeEditors, "FLIP Solver"); + + attributes.update = true; + array_push(attributeEditors, ["Update domain", function() { return attributes.update; }, + new checkBox(function() { + attributes.update = !attributes.update; + triggerRender(); + })]); + + static step = function() { + var _typ = getInputData(6); + var _thr = getInputData(7); + + inputs[| 1].setVisible(_typ == 0 && _thr); + inputs[| 3].setVisible(_typ == 0); + inputs[| 5].setVisible(_typ == 0, _typ == 0); + } static update = function(frame = CURRENT_FRAME) { var domain = getInputData(0); if(!instance_exists(domain)) return; + if(domain.domain == noone) return; - if(IS_PLAYING) domain.step(); + if(attributes.update && IS_PLAYING) domain.step(); var _bln = getInputData(1); var _vap = getInputData(2); var _exp = getInputData(3); var _obs = getInputData(4); + var _spr = getInputData(5); + var _typ = getInputData(6); + var _thr = getInputData(7); + var _add = getInputData(8); + var _alp = getInputData(9); var _outSurf = outputs[| 0].getValue(); var _padd = domain.particleSize; @@ -47,30 +85,83 @@ function Node_FLIP_Render(_x, _y, _group = noone) : Node(_x, _y, _group) constru outputs[| 0].setValue(_outSurf); - var _x, _y, _r, _l; + var _x, _y, _px, _py, _r, _l, _a; var _rad = domain.particleRadius * _exp; var _mx = min(array_length(domain.particlePos) / 2 - 1, domain.numParticles); - surface_set_shader(temp_surface[0], sh_FLIP_draw_droplet); - BLEND_ADD + var _useSpr = is_surface(_spr); + var _sprw, _sprh; + + if(_useSpr) { + _sprw = 0.5 * surface_get_width_safe(_spr); + _sprh = 0.5 * surface_get_height_safe(_spr); + } else if(is_array(_spr) && array_length(_spr)) { + _useSpr = is_surface(_spr[0]); + _sprw = 0.5 * surface_get_width_safe(_spr[0]); + _sprh = 0.5 * surface_get_height_safe(_spr[0]); + } + + random_set_seed(seed); + + surface_set_shader(temp_surface[0], _useSpr? noone : sh_FLIP_draw_droplet); + if(_add) BLEND_ADD + else BLEND_ALPHA_MULP - for( var i = 0; i < _mx; i++ ) { - _x = domain.particlePos[i * 2 + 0]; - _y = domain.particlePos[i * 2 + 1]; - _l = domain.particleLife[i]; + if(_typ == 0) { + for( var i = 0; i < _mx; i++ ) { + _x = domain.particlePos[i * 2 + 0]; + _y = domain.particlePos[i * 2 + 1]; + _l = domain.particleLife[i]; - if(_x == 0 && _y == 0) continue; + if(_x == 0 && _y == 0) continue; - _x -= _padd; - _y -= _padd; - _r = _rad; + _x -= _padd; + _y -= _padd; + _r = 1; + _a = random_range(_alp[0], _alp[1]); - if(_vap) { - _r = (_vap - _l) / _vap * _rad; - if(_r < 0) continue; + if(_vap) { + _r = (_vap - _l) / _vap; + if(_r * _rad < 0.5) continue; + } + + if(_useSpr) { + if(is_array(_spr)) draw_surface_ext(_spr[i % array_length(_spr)], _x - _sprw * _r, _y - _sprh * _r, _r, _r, 0, c_white, _a * _r); + else draw_surface_ext(_spr, _x - _sprw * _r, _y - _sprh * _r, _r, _r, 0, c_white, _a * _r); + } else { + draw_set_alpha(_a * _r); + draw_circle_color(_x, _y, _rad, c_white, c_black, false); + draw_set_alpha(1); + } + } + } else if(_typ == 1) { + for( var i = 0; i < _mx; i++ ) { + _x = domain.particlePos[i * 2 + 0]; + _y = domain.particlePos[i * 2 + 1]; + _px = domain.particleHist[i * 2 + 0]; + _py = domain.particleHist[i * 2 + 1]; + + _l = domain.particleLife[i]; + + if(_x == 0 && _y == 0) continue; + if(_px == 0 && _py == 0) continue; + + if(_vap) { + if(_l >= _vap) continue; + _r = (_vap - _l) / _vap; + + _px = _x + (_px - _x) * _r; + _py = _y + (_py - _y) * _r; + } + + _x -= _padd; + _y -= _padd; + _px -= _padd; + _py -= _padd; + + draw_set_color(c_white); + draw_line(_px, _py, _x, _y); } - - draw_circle_color(_x, _y, _r, c_white, c_black, false); } BLEND_NORMAL @@ -79,10 +170,13 @@ function Node_FLIP_Render(_x, _y, _group = noone) : Node(_x, _y, _group) constru surface_set_target(_outSurf); DRAW_CLEAR - shader_set(sh_FLIP_render_threshold); - shader_set_f("threshold", 1 - _bln); + if(_thr) { + shader_set(sh_FLIP_render_threshold); + shader_set_f("threshold", 1 - _bln); + draw_surface(temp_surface[0], 0, 0); + shader_reset(); + } else draw_surface(temp_surface[0], 0, 0); - shader_reset(); if(_obs) for( var i = 0, n = array_length(domain.obstracles); i < n; i++ ) diff --git a/scripts/node_FLIP_spawner/node_FLIP_spawner.gml b/scripts/node_FLIP_spawner/node_FLIP_spawner.gml index ac56ee367..061827a24 100644 --- a/scripts/node_FLIP_spawner/node_FLIP_spawner.gml +++ b/scripts/node_FLIP_spawner/node_FLIP_spawner.gml @@ -21,14 +21,14 @@ function Node_FLIP_Spawner(_x, _y, _group = noone) : Node(_x, _y, _group) constr inputs[| 4] = nodeValue("Spawn frame", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0 ); - inputs[| 5] = nodeValue("Spawn amount", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 4 ); + inputs[| 5] = nodeValue("Spawn amount", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 8 ); inputs[| 6] = nodeValue("Spawn velocity", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0 ] ) .setDisplay(VALUE_DISPLAY.range); inputs[| 7] = nodeValue("Spawn surface", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone ); - inputs[| 8] = nodeValue("Spawn radius", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 4 ) + inputs[| 8] = nodeValue("Spawn radius", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 2 ) .setDisplay(VALUE_DISPLAY.slider, { range: [1, 16, 0.1] }); inputs[| 9] = nodeValue("Seed", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, irandom_range(100000, 999999) ); @@ -36,14 +36,18 @@ function Node_FLIP_Spawner(_x, _y, _group = noone) : Node(_x, _y, _group) constr inputs[| 10] = nodeValue("Spawn direction", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 45, 135, 0, 0 ] ) .setDisplay(VALUE_DISPLAY.rotation_random); + inputs[| 11] = nodeValue("Inherit velocity", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0 ) + .setDisplay(VALUE_DISPLAY.slider); + input_display_list = [ 0, 9, ["Spawner", false], 1, 7, 8, 2, 3, 4, 5, - ["Physics", false], 10, 6, + ["Physics", false], 10, 6, 11, ] outputs[| 0] = nodeValue("Domain", self, JUNCTION_CONNECT.output, VALUE_TYPE.fdomain, noone ); - spawn_amo = 0; + spawn_amo = 0; + prev_position = [ 0, 0 ]; static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) { #region var _shp = getInputData(1); @@ -80,7 +84,7 @@ function Node_FLIP_Spawner(_x, _y, _group = noone) : Node(_x, _y, _group) constr inputs[| 8].setVisible(_shp == 0); } #endregion - static update = function(frame = CURRENT_FRAME) { + static update = function(frame = CURRENT_FRAME) { #region var domain = getInputData(0); if(!instance_exists(domain)) return; @@ -97,6 +101,7 @@ function Node_FLIP_Spawner(_x, _y, _group = noone) : Node(_x, _y, _group) constr var _vel = getInputData( 6); var _dirr = getInputData(10); + var _ivel = getInputData(11); if(frame == 0) spawn_amo = 0; @@ -110,12 +115,15 @@ function Node_FLIP_Spawner(_x, _y, _group = noone) : Node(_x, _y, _group) constr var _samo = floor(spawn_amo); spawn_amo -= _samo; + var _points = []; + if(_shape == 1) { var _sw = surface_get_width(_surf); var _sh = surface_get_height(_surf); - var _points = get_points_from_dist(_surf, _samo, _seed + ceil(_amo) * frame); - _samo = array_length(_points); + _points = get_points_from_dist(_surf, _samo, _seed + ceil(_amo) * frame); + _points = array_filter(_points, function(a) { return is_array(a); }); + _samo = array_length(_points); if(_samo == 0) return; } @@ -152,8 +160,11 @@ function Node_FLIP_Spawner(_x, _y, _group = noone) : Node(_x, _y, _group) constr var _vdis = random_range(_vel[0], _vel[1]); var _vdir = angle_random_eval(_dirr); - buffer_write(_buffV, buffer_f64, lengthdir_x(_vdis, _vdir)); - buffer_write(_buffV, buffer_f64, lengthdir_y(_vdis, _vdir)); + var _vx = lengthdir_x(_vdis, _vdir) + (frame? (_posit[0] - prev_position[0]) * _ivel : 0); + var _vy = lengthdir_y(_vdis, _vdir) + (frame? (_posit[1] - prev_position[1]) * _ivel : 0); + + buffer_write(_buffV, buffer_f64, _vx); + buffer_write(_buffV, buffer_f64, _vy); ind++; } @@ -162,10 +173,13 @@ function Node_FLIP_Spawner(_x, _y, _group = noone) : Node(_x, _y, _group) constr buffer_delete(_buffP); buffer_delete(_buffV); - } + + prev_position[0] = _posit[0]; + prev_position[1] = _posit[1]; + } #endregion - static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { #region var bbox = drawGetBbox(xx, yy, _s); draw_sprite_fit(s_node_fluidSim_add_fluid, 0, bbox.xc, bbox.yc, bbox.w, bbox.h); - } + } #endregion } \ No newline at end of file diff --git a/scripts/node_FLIP_update/node_FLIP_update.gml b/scripts/node_FLIP_update/node_FLIP_update.gml new file mode 100644 index 000000000..7743a53c7 --- /dev/null +++ b/scripts/node_FLIP_update/node_FLIP_update.gml @@ -0,0 +1,48 @@ +function Node_FLIP_Update(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + name = "Update"; + 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("Update", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); + + inputs[| 2] = nodeValue("Override timestep", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + inputs[| 3] = nodeValue("Timestep", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.01); + + input_display_list = [ 0, 1, + ["Timestep", false], 2, 3, + ]; + + outputs[| 0] = nodeValue("Domain", self, JUNCTION_CONNECT.output, VALUE_TYPE.fdomain, noone); + + static update = function(frame = CURRENT_FRAME) { + var domain = getInputData(0); + var _active = getInputData(1); + + outputs[| 0].setValue(domain); + + if(!instance_exists(domain)) return; + if(domain.domain == noone) return; + + var _timeover = getInputData(2); + var _timestep = getInputData(3); + + if(_timeover) domain.dt = _timestep; + + if(_active && IS_PLAYING) domain.step(); + } + + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { + var bbox = drawGetBbox(xx, yy, _s); + var _active = getInputData(1); + + draw_sprite_fit(_active? s_node_fluidSim_update : s_node_fluidSim_update_paused, 0, bbox.xc, bbox.yc, bbox.w, bbox.h); + } +} \ No newline at end of file diff --git a/scripts/node_FLIP_update/node_FLIP_update.yy b/scripts/node_FLIP_update/node_FLIP_update.yy new file mode 100644 index 000000000..9f438c346 --- /dev/null +++ b/scripts/node_FLIP_update/node_FLIP_update.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "node_FLIP_update", + "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_collection_inline/node_collection_inline.gml b/scripts/node_collection_inline/node_collection_inline.gml index 475195742..f0eb10acf 100644 --- a/scripts/node_collection_inline/node_collection_inline.gml +++ b/scripts/node_collection_inline/node_collection_inline.gml @@ -111,20 +111,22 @@ function Node_Collection_Inline(_x, _y, _group = noone) : Node(_x, _y, _group) c } #region create convex shape - __temp_minP = [ x, y ]; + __temp_minP = _vtrx[0]; __temp_minI = 0; - - for( var i = 0, n = array_length(_vtrx); i < n; i++ ) { - var _v = _vtrx[i]; - if(_v[1] > __temp_minP[1] || (_v[1] == __temp_minP[1] && _v[0] < __temp_minP[0])) { + for( var i = 0, n = array_length(_vtrx); i < n; i++ ) { + var _v = _vtrx[i]; + var _vx = _v[0]; + var _vy = _v[1]; + + if(_vy > __temp_minP[1] || (_vy == __temp_minP[1] && _vx < __temp_minP[0])) { __temp_minP = _v; __temp_minI = i; } } - - _vtrx = array_map( _vtrx, function(a, i) { return [ a[0], a[1], i == __temp_minI? -999 : point_direction(__temp_minP[0], __temp_minP[1], a[0], a[1]) + 360 ] }); - array_sort(_vtrx, function(a0, a1) { return a0[2] == a1[2]? sign(a0[0] - a1[0]) : sign(a0[2] - a1[2]); }); + + _vtrx = array_map( _vtrx, function(a, i) { return [ a[0], a[1], i == __temp_minI? -999 : point_direction(__temp_minP[0], __temp_minP[1], a[0], a[1]) + 360 ] }); + array_sort(_vtrx, function(a0, a1) { return a0[2] == a1[2]? sign(a0[0] - a1[0]) : sign(a0[2] - a1[2]); }); var _linS = 0; for( var i = 1, n = array_length(_vtrx); i < n; i++ ) { @@ -255,6 +257,15 @@ function Node_Collection_Inline(_x, _y, _group = noone) : Node(_x, _y, _group) c draw_set_alpha(1); + //draw_set_color(c_white); + //for( var i = 0, n = array_length(group_vertex); i < n; i++ ) { + // a = group_vertex[i]; + // var _vx = _x + a[0] * _s; + // var _vy = _y + a[1] * _s; + + // draw_circle(_vx, _vy, 3, false); + //} + return _hov; } #endregion diff --git a/scripts/node_feedback_inline/node_feedback_inline.gml b/scripts/node_feedback_inline/node_feedback_inline.gml index 86cfa0113..886c72fe1 100644 --- a/scripts/node_feedback_inline/node_feedback_inline.gml +++ b/scripts/node_feedback_inline/node_feedback_inline.gml @@ -4,6 +4,9 @@ function Node_Feedback_Inline(_x, _y, _group = noone) : Node(_x, _y, _group) con icon = THEME.feedback; icon_24 = THEME.feedback_24; + w = 0; + h = 0; + is_root = false; selectable = false; update_on_frame = true; diff --git a/scripts/node_mk_flame/node_mk_flame.gml b/scripts/node_mk_flame/node_mk_flame.gml new file mode 100644 index 000000000..828b748d6 --- /dev/null +++ b/scripts/node_mk_flame/node_mk_flame.gml @@ -0,0 +1,35 @@ +function Node_MK_Flame(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + name = "MK Flame"; + update_on_frame = true; + + inputs[| 0] = nodeValue("Dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, DEF_SURF) + .setDisplay(VALUE_DISPLAY.vector); + + inputs[| 1] = nodeValue("Direction", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 45) + .setDisplay(VALUE_DISPLAY.rotation); + + input_display_list = [ new Inspector_Sprite(s_MKFX), 0, + ["Shape", false], 1, + ]; + + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + static step = function() { #region + + } #endregion + + static processData = function(_outSurf, _data, _output_index, _array_index) { #region + var _dim = _data[0]; + var _dirr = _data[1]; + + _outSurf = surface_verify(_outSurf, _dim[0], _dim[1]); + + surface_set_target(_outSurf); + DRAW_CLEAR + + + surface_reset_target(); + + return _outSurf; + } #endregion +} \ No newline at end of file diff --git a/scripts/node_mk_flame/node_mk_flame.yy b/scripts/node_mk_flame/node_mk_flame.yy new file mode 100644 index 000000000..698ae0373 --- /dev/null +++ b/scripts/node_mk_flame/node_mk_flame.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "node_mk_flame", + "isCompatibility": false, + "isDnD": false, + "parent": { + "name": "MK effects", + "path": "folders/nodes/data/MK effects.yy", + }, +} \ No newline at end of file diff --git a/scripts/node_registry/node_registry.gml b/scripts/node_registry/node_registry.gml index 97911a96f..b542dc4a7 100644 --- a/scripts/node_registry/node_registry.gml +++ b/scripts/node_registry/node_registry.gml @@ -398,12 +398,12 @@ function __initNodes() { ds_list_add(flipSim, "Domain"); addNodeObject(flipSim, "Domain", s_node_fluidSim_domain, "Node_FLIP_Domain", [1, Node_FLIP_Domain]).hideRecent().setVersion(11620); addNodeObject(flipSim, "Render", s_node_fluidSim_render, "Node_FLIP_Render", [1, Node_FLIP_Render]).hideRecent().setVersion(11620); + addNodeObject(flipSim, "Update", s_node_fluidSim_update, "Node_FLIP_Update", [1, Node_FLIP_Update]).hideRecent().setVersion(11620); 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); + addNodeObject(flipSim, "Apply Force", s_node_fluidSim_force, "Node_FLIP_Apply_Force", [1, Node_FLIP_Apply_Force]).hideRecent().setVersion(11620); #endregion var strandSim = ds_list_create(); #region diff --git a/scripts/node_simple_shape/node_simple_shape.gml b/scripts/node_simple_shape/node_simple_shape.gml index a61d813d8..a017e8e4e 100644 --- a/scripts/node_simple_shape/node_simple_shape.gml +++ b/scripts/node_simple_shape/node_simple_shape.gml @@ -1,13 +1,4 @@ -enum NODE_SHAPE_TYPE { - rectangle, - elipse, - regular, - star, - arc, - teardrop, - cross, - leaf -} +enum NODE_SHAPE_TYPE { rectangle, elipse, regular, star, arc, teardrop, cross, leaf, crescent } function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { name = "Shape"; @@ -18,7 +9,7 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con inputs[| 1] = nodeValue("Background", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); inputs[| 2] = nodeValue("Shape", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) - .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Rectangle", "Ellipse", "Regular polygon", "Star", "Arc", "Teardrop", "Cross", "Leaf" ]); + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Rectangle", "Ellipse", "Regular polygon", "Star", "Arc", "Teardrop", "Cross", "Leaf", "Crescent" ]); onSurfaceSize = function() { return getInputData(0, DEF_SURF); }; inputs[| 3] = nodeValue("Position", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ DEF_SURF_W / 2, DEF_SURF_H / 2, DEF_SURF_W / 2, DEF_SURF_H / 2, AREA_SHAPE.rectangle ]) @@ -55,12 +46,26 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con inputs[| 14] = nodeValue("Shape path", self, JUNCTION_CONNECT.input, VALUE_TYPE.pathnode, noone) .setVisible(true, true); + inputs[| 15] = nodeValue("Positioning Mode", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Area", "Center + Scale", "Full Image" ]) + + inputs[| 16] = nodeValue("Center", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ DEF_SURF_W / 2, DEF_SURF_H / 2 ] ) + .setDisplay(VALUE_DISPLAY.vector) + .setUnitRef(function(index) { return getInputData(0, DEF_SURF); }); + + inputs[| 17] = nodeValue("Half Size", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ DEF_SURF_W / 2, DEF_SURF_H / 2 ] ) + .setDisplay(VALUE_DISPLAY.vector) + .setUnitRef(function(index) { return getInputData(0, DEF_SURF); }); + + inputs[| 18] = nodeValue("Tile", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); input_display_list = [ - ["Output", false], 0, 6, - ["Shape", false], 2, 14, 3, 9, 4, 13, 5, 7, 8, - ["Render", true], 10, 1, 11, 12 + ["Output", false], 0, 6, + ["Transform", false], 15, 3, 16, 17, + ["Shape", false], 14, 2, 9, 4, 13, 5, 7, 8, + ["Render", true], 10, 1, 11, 12, 18 ]; temp_surface = [ noone ]; @@ -70,14 +75,25 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) { #region var _path = getInputData(14); if(_path != noone && struct_has(_path, "getPointRatio")) return; - inputs[| 3].drawOverlay(active, _x, _y, _s, _mx, _my, _snx, _sny); + + var _type = getInputData(15); + + if(_type == 0) { + inputs[| 3].drawOverlay(active, _x, _y, _s, _mx, _my, _snx, _sny); + } else if(_type == 1) { + var _pos = getInputData(16); + var _px = _x + _pos[0] * _s; + var _py = _y + _pos[1] * _s; + + inputs[| 16].drawOverlay(active, _x, _y, _s, _mx, _my, _snx, _sny); + inputs[| 17].drawOverlay(active, _px, _py, _s, _mx, _my, _snx, _sny); + } } #endregion static processData = function(_outSurf, _data, _output_index, _array_index) { #region var _dim = _data[0]; var _bg = _data[1]; var _shape = _data[2]; - var _posit = _data[3]; var _aa = _data[6]; var _corner = _data[9]; var _color = _data[10]; @@ -86,7 +102,36 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con var _bgC = _data[11]; var _bgcol = _bg? colToVec4(_data[11]) : [0, 0, 0, 0]; - inputs[| 3].setVisible(true); + var _posTyp = _data[15]; + var _tile = _data[18]; + + var _center = [ 0, 0 ]; + var _scale = [ 0, 0 ]; + + switch(_posTyp) { + case 0 : + var _area = _data[3]; + + _center = [ _area[0] / _dim[0], _area[1] / _dim[1] ]; + _scale = [ _area[2] / _dim[0], _area[3] / _dim[1] ]; + break; + case 1 : + var _posit = _data[16]; + var _scal = _data[17]; + + _center = [ _posit[0] / _dim[0], _posit[1] / _dim[1] ]; + _scale = [ _scal[0] / _dim[0], _scal[1] / _dim[1] ]; + break; + case 2 : + _center = [ 0.5, 0.5 ]; + _scale = [ 0.5, 0.5 ]; + break; + } + + inputs[| 3].setVisible(_posTyp == 0); + inputs[| 16].setVisible(_posTyp == 1); + inputs[| 17].setVisible(_posTyp == 1); + inputs[| 4].setVisible(true); inputs[| 5].setVisible(true); inputs[| 6].setVisible(_path == noone); @@ -95,6 +140,7 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con inputs[| 9].setVisible(true); inputs[| 11].setVisible(_bg); inputs[| 13].setVisible(true); + inputs[| 15].setVisible(true); _outSurf = surface_verify(_outSurf, _dim[0], _dim[1], attrDepth()); @@ -106,6 +152,7 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con inputs[| 8].setVisible(false); inputs[| 9].setVisible(false); inputs[| 13].setVisible(false); + inputs[| 15].setVisible(false); surface_set_target(_outSurf); if(_bg) draw_clear_alpha(0, 1); @@ -155,10 +202,12 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con inputs[| 8].setVisible(false); inputs[| 9].setVisible(false); inputs[| 13].setVisible(false); + inputs[| 18].setVisible( true); switch(_shape) { #region case NODE_SHAPE_TYPE.rectangle : - inputs[| 9].setVisible(true); + inputs[| 9].setVisible( true); + inputs[| 18].setVisible(false); break; case NODE_SHAPE_TYPE.elipse : break; @@ -223,17 +272,28 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con shader_set_f("inner", _data[ 5]); shader_set_f("outer", _data[13]); break; + case NODE_SHAPE_TYPE.crescent : + inputs[| 5].setVisible(true); + inputs[| 13].setVisible(true); + + inputs[| 5].name = "Shift"; + inputs[| 13].name = "Inner circle"; + + shader_set_f("outer", _data[ 5]); + shader_set_f("inner", _data[13]); + break; } #endregion shader_set_f("dimension", _dim); - shader_set_i("shape", _shape); - shader_set_f("bgColor", _bgcol); - shader_set_i("aa", _aa); - shader_set_i("drawDF", _df); - shader_set_f("corner", _corner); + shader_set_i("shape", _shape); + shader_set_f("bgColor", _bgcol); + shader_set_i("aa", _aa); + shader_set_i("drawDF", _df); + shader_set_i("tile", _tile); + shader_set_f("corner", _corner); - shader_set_f("center", [ _posit[0] / _dim[0], _posit[1] / _dim[1] ]); - shader_set_f("scale", [ _posit[2] / _dim[0], _posit[3] / _dim[1] ]); + shader_set_f("center", _center); + shader_set_f("scale", _scale ); draw_sprite_stretched_ext(s_fx_pixel, 0, 0, 0, _dim[0], _dim[1], _color, 1); surface_reset_shader(); diff --git a/scripts/node_text/node_text.gml b/scripts/node_text/node_text.gml index f5375cef5..615d3f593 100644 --- a/scripts/node_text/node_text.gml +++ b/scripts/node_text/node_text.gml @@ -48,11 +48,24 @@ function Node_Text(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons inputs[| 17] = nodeValue("BG Color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_black); + inputs[| 18] = nodeValue("Wave", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + inputs[| 19] = nodeValue("Wave amplitude", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 4); + + inputs[| 20] = nodeValue("Wave scale", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 30); + + inputs[| 21] = nodeValue("Wave phase", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0) + .setDisplay(VALUE_DISPLAY.rotation); + + inputs[| 22] = nodeValue("Wave shape", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0) + .setDisplay(VALUE_DISPLAY.slider, { range: [ 0, 3, 0.01 ] }); + input_display_list = [ - ["Output", true], 9, 6, 10, + ["Output", true], 9, 6, 10, ["Text", false], 0, 13, 14, 7, 8, - ["Font", false], 1, 2, 15, 3, 11, 12, + ["Font", false], 1, 2, 15, 3, 11, 12, ["Rendering", false], 5, 16, 17, + ["Wave", true, 18], 22, 19, 20, 21, ]; outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); @@ -62,6 +75,7 @@ function Node_Text(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons _font_current = ""; _size_current = 0; _aa_current = false; + seed = irandom_range(10000, 99999); static generateFont = function(_path, _size, _aa) { #region if(PROJECT.animator.is_playing) return; @@ -96,6 +110,26 @@ function Node_Text(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons inputs[| 17].setVisible(_ubg); } #endregion + static waveGet = function(_ind) { #region + var _x = __wave_phase + _ind * __wave_scale; + + var _sine = dsin(_x) * __wave_ampli; + + var _squr = sign(_sine) * __wave_ampli; + _squr = _squr != 0? _squr : __wave_ampli; + + var _taup = abs(_x + 90) % 360; + var _tria = _taup > 180? 360 - _taup : _taup; + _tria = (_tria / 180 * 2 - 1) * __wave_ampli; + + if(__wave_shape < 0) return _sine; + else if(__wave_shape < 1) return lerp(_sine, _tria, frac(__wave_shape)); + else if(__wave_shape < 2) return lerp(_tria, _squr, frac(__wave_shape)); + else if(__wave_shape < 3) return abs(_x) % 360 > 360 * (0.5 - frac(__wave_shape) / 2)? -__wave_ampli : __wave_ampli; + + return random_range_seed(-1, 1, _x + seed) * __wave_ampli; + } #endregion + static processData = function(_outSurf, _data, _output_index, _array_index) { #region var str = _data[0]; var _font = _data[1]; @@ -115,65 +149,89 @@ function Node_Text(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons var _ubg = _data[16]; var _bgc = _data[17]; + var _wave = _data[18]; + var _waveA = _data[19]; + var _waveS = _data[20]; + var _waveP = _data[21]; + var _waveH = _data[22]; + generateFont(_font, _size, _aa); draw_set_font(font); - var _str_lines = string_splice(str, "\n"); - _line_widths = []; + #region cut string + var _str_lines = string_splice(str, "\n"); + _line_widths = []; - var ww = 0, _sw = 0; - var hh = 0, _sh = 0; - - __temp_len = string_length(str); - __temp_lw = 0; - __temp_ww = 0; - __temp_hh = line_get_height(); - __temp_trck = _trck; - __temp_line = _line; + __temp_len = string_length(str); + __temp_lw = 0; + __temp_ww = 0; + __temp_hh = line_get_height(); + __temp_trck = _trck; + __temp_line = _line; - string_foreach(str, function(_chr, _ind) { - if(_chr == "\n") { - var _lw = max(0, __temp_lw - __temp_trck); - array_push(_line_widths, _lw); - __temp_ww = max(__temp_ww, _lw); - __temp_hh += string_height(_chr) + __temp_line; - __temp_lw = 0; - } else - __temp_lw += string_width(_chr) + __temp_trck; - }); - - var _lw = max(0, __temp_lw - __temp_trck); - array_push(_line_widths, _lw); - __temp_ww = max(__temp_ww, _lw); - ww = __temp_ww; - hh = __temp_hh; + string_foreach(str, function(_chr, _ind) { + if(_chr == "\n") { + var _lw = max(0, __temp_lw - __temp_trck); + array_push(_line_widths, _lw); + __temp_ww = max(__temp_ww, _lw); + __temp_hh += string_height(_chr) + __temp_line; + __temp_lw = 0; + } else + __temp_lw += string_width(_chr) + __temp_trck; + }); + #endregion - var _use_path = _path != noone && struct_has(_path, "getPointDistance"); - var _ss = 1; + #region dimension + var ww = 0, _sw = 0; + var hh = 0, _sh = 0; - if(_use_path || _dim_type == 0) { - _sw = _dim[0]; - _sh = _dim[1]; - } else { - _sw = ww; - _sh = hh; - } + var _lw = max(0, __temp_lw - __temp_trck); + array_push(_line_widths, _lw); + __temp_ww = max(__temp_ww, _lw); + ww = __temp_ww; + hh = __temp_hh; - if(_dim_type == 0 && !_use_path && _scaF) - _ss = min(_sw / ww, _sh / hh); + var _use_path = _path != noone && struct_has(_path, "getPointDistance"); + var _ss = 1; - _sw += _padd[PADDING.left] + _padd[PADDING.right]; - _sh += _padd[PADDING.top] + _padd[PADDING.bottom]; - _outSurf = surface_verify(_outSurf, _sw, _sh, attrDepth()); - - var tx = 0, ty = _padd[PADDING.top], _ty = 0; - if(_dim_type == 0) { - switch(_vali) { - case 0 : ty = _padd[PADDING.top]; break; - case 1 : ty = (_sh - hh * _ss) / 2; break; - case 2 : ty = _sh - _padd[PADDING.bottom] - hh * _ss; break; + if(_use_path || _dim_type == 0) { + _sw = _dim[0]; + _sh = _dim[1]; + } else { + _sw = ww; + _sh = hh; } - } + + if(_dim_type == 0 && !_use_path && _scaF) + _ss = min(_sw / ww, _sh / hh); + + if(_wave) _sh += abs(_waveA) * 2; + + _sw += _padd[PADDING.left] + _padd[PADDING.right]; + _sh += _padd[PADDING.top] + _padd[PADDING.bottom]; + _outSurf = surface_verify(_outSurf, _sw, _sh, attrDepth()); + #endregion + + #region position + var tx = 0, ty = _padd[PADDING.top], _ty = 0; + if(_dim_type == 0) { + switch(_vali) { + case 0 : ty = _padd[PADDING.top]; break; + case 1 : ty = (_sh - hh * _ss) / 2; break; + case 2 : ty = _sh - _padd[PADDING.bottom] - hh * _ss; break; + } + } + + if(_wave) ty += abs(_waveA); + #endregion + + #region wave + __wave = _wave; + __wave_ampli = _waveA; + __wave_scale = _waveS; + __wave_phase = -_waveP; + __wave_shape = _waveH; + #endregion surface_set_shader(_outSurf, noone,, BLEND.alpha); if(_ubg) { @@ -215,7 +273,16 @@ function Node_Text(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons var _dx = lengthdir_x(__temp_ty, _line_ang); var _dy = lengthdir_y(__temp_ty, _line_ang); - draw_text_transformed(_pos.x + _dx, _pos.y + _dy, _chr, 1, 1, _nor); + var _tx = _pos.x + _dx; + var _ty = _pos.y + _dy; + + if(__wave) { + var _wd = waveGet(_ind); + _tx += lengthdir_x(_wd, _line_ang + 90); + _ty += lengthdir_y(_wd, _line_ang + 90); + } + + draw_text_transformed(_tx, _ty, _chr, 1, 1, _nor); __temp_tx += string_width(_chr) + __temp_trck; }); @@ -237,7 +304,15 @@ function Node_Text(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons __temp_trck = _trck; string_foreach(_str_line, function(_chr, _ind) { - draw_text_transformed(__temp_tx, __temp_ty, _chr, __temp_ss, __temp_ss, 0); + var _tx = __temp_tx; + var _ty = __temp_ty; + + if(__wave) { + var _wd = waveGet(_ind); + _ty += _wd; + } + + draw_text_transformed(_tx, _ty, _chr, __temp_ss, __temp_ss, 0); __temp_tx += (string_width(_chr) + __temp_trck) * __temp_ss; }); diff --git a/scripts/panel_animation/panel_animation.gml b/scripts/panel_animation/panel_animation.gml index 103d3acd4..3da290ca4 100644 --- a/scripts/panel_animation/panel_animation.gml +++ b/scripts/panel_animation/panel_animation.gml @@ -740,8 +740,8 @@ function Panel_Animation() : PanelContent() constructor { if(!valArray) _oy = [ _oy ]; var oy = array_create(array_length(_oy)); - for( var ki = 0; ki < array_length(oy); ki++ ) - oy[ki] = value_map(oy[ki], _gy_val_min, _gy_val_max, _gy_bottom, _gy_top); + for( var ki = 0; ki < array_length(_oy); ki++ ) + oy[ki] = value_map(_oy[ki], _gy_val_min, _gy_val_max, _gy_bottom, _gy_top); for(var k = 0; k < amo - 1; k++) { #region draw line in between var key = animator.values[| k]; @@ -788,10 +788,10 @@ function Panel_Animation() : PanelContent() constructor { draw_set_color(valArray? COLORS.axis[ki] : (animator.prop.sep_axis? COLORS.axis[animator.index] : COLORS.panel_animation_graph_line)); ny[ki] = value_map(_kv[ki], _gy_val_min, _gy_val_max, _gy_bottom, _gy_top); - + if(array_length(oy) > ki) draw_line(t, oy[ki], t, ny[ki]); oy[ki] = ny[ki]; - + ny[ki] = value_map(_kn[ki], _gy_val_min, _gy_val_max, _gy_bottom, _gy_top); draw_line(t, oy[ki], nx, ny[ki]); oy[ki] = ny[ki]; diff --git a/scripts/panel_graph/panel_graph.gml b/scripts/panel_graph/panel_graph.gml index e3e86b867..37a57835b 100644 --- a/scripts/panel_graph/panel_graph.gml +++ b/scripts/panel_graph/panel_graph.gml @@ -816,7 +816,7 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { var _w = _node.w * graph_s; var _h = _node.h * graph_s; - if(rectangle_inside_rectangle(fx0, fy0, fx1, fy1, _x, _y, _x + _w, _y + _h)) + if(_w && _h && rectangle_inside_rectangle(fx0, fy0, fx1, fy1, _x, _y, _x + _w, _y + _h)) array_push(nodes_selecting, _node); } } else if(DOUBLE_CLICK) { @@ -1165,7 +1165,7 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { var _w = _node.w * graph_s; var _h = _node.h * graph_s; - var _sel = rectangle_in_rectangle(_x, _y, _x + _w, _y + _h, nodes_select_mx, nodes_select_my, mx, my); + var _sel = _w && _h && rectangle_in_rectangle(_x, _y, _x + _w, _y + _h, nodes_select_mx, nodes_select_my, mx, my); if(!array_exists(nodes_selecting, _node) && _sel) array_push(nodes_selecting, _node); diff --git a/scripts/panel_inspector/panel_inspector.gml b/scripts/panel_inspector/panel_inspector.gml index a1bb7c94e..0bf0b94b1 100644 --- a/scripts/panel_inspector/panel_inspector.gml +++ b/scripts/panel_inspector/panel_inspector.gml @@ -480,7 +480,7 @@ function Panel_Inspector() : PanelContent() constructor { } else { if(i >= array_length(_inspecting.input_display_list)) break; var jun_disp = _inspecting.input_display_list[i]; - if(is_instanceof(jun_disp, Inspector_Sprite)) { // others + if(is_instanceof(jun_disp, Inspector_Sprite)) { // SPRITE var _spr = jun_disp.spr; var _sh = sprite_get_height(_spr); @@ -488,30 +488,58 @@ function Panel_Inspector() : PanelContent() constructor { hh += _sh + ui(8); continue; + } if(is_array(jun_disp)) { // LABEL var txt = __txt(jun_disp[0]); var coll = jun_disp[1] && filter_text == ""; var lbh = lineBreak? ui(32) : ui(26); + var togl = array_safe_get(jun_disp, 2, noone); + if(togl != noone) var toging = _inspecting.getInputData(togl); - if(_hover && point_in_rectangle(_m[0], _m[1], 0, yy, con_w, yy + lbh)) { - draw_sprite_stretched_ext(THEME.group_label, 0, 0, yy, con_w, lbh, COLORS.panel_inspector_group_hover, 1); + var lbx = (togl != noone) * ui(36); + var lbw = con_w - lbx; + var ltx = lbx + ui(32); + + if(_hover && point_in_rectangle(_m[0], _m[1], lbx, yy, con_w, yy + lbh)) { + draw_sprite_stretched_ext(THEME.group_label, 0, lbx, yy, lbw, lbh, COLORS.panel_inspector_group_hover, 1); if(mouse_press(mb_left, pFOCUS)) jun_disp[@ 1] = !coll; if(mouse_press(mb_right, pFOCUS)) menuCall("inspector_group_menu",,, group_menu,, _inspecting); } else - draw_sprite_stretched_ext(THEME.group_label, 0, 0, yy, con_w, lbh, COLORS.panel_inspector_group_bg, 1); + draw_sprite_stretched_ext(THEME.group_label, 0, lbx, yy, lbw, lbh, COLORS.panel_inspector_group_bg, 1); - if(filter_text == "") - draw_sprite_ui(THEME.arrow, 0, ui(16), yy + lbh / 2, 1, 1, -90 + coll * 90, COLORS.panel_inspector_group_bg, 1); + if(filter_text == "") + draw_sprite_ui(THEME.arrow, 0, lbx + ui(16), yy + lbh / 2, 1, 1, -90 + coll * 90, COLORS.panel_inspector_group_bg, 1); + var cc, aa = 1; + + if(togl != noone) { + if(_hover && point_in_rectangle(_m[0], _m[1], 0, yy, ui(32), yy + lbh)) { + draw_sprite_stretched_ext(THEME.group_label, 0, 0, yy, ui(32), lbh, COLORS.panel_inspector_group_hover, 1); + + if(mouse_press(mb_left, pFOCUS)) + _inspecting.inputs[| togl].setValue(!toging); + } else + draw_sprite_stretched_ext(THEME.group_label, 0, 0, yy, ui(32), lbh, COLORS.panel_inspector_group_bg, 1); + + cc = toging? COLORS._main_accent : COLORS.panel_inspector_group_bg; + aa = 0.5 + toging * 0.5; + + draw_sprite_ui(THEME.inspector_checkbox, 0, ui(16), yy + lbh / 2, 1, 1, 0, cc, 1); + if(toging) + draw_sprite_ui(THEME.inspector_checkbox, 1, ui(16), yy + lbh / 2, 1, 1, 0, cc, 1); + } + + draw_set_alpha(aa); draw_set_text(lineBreak? f_p0 : f_p1, fa_left, fa_center, COLORS._main_text); - draw_text_add(ui(32), yy + lbh / 2, txt); - + draw_text_add(ltx, yy + lbh / 2, txt); + draw_set_alpha(1); + hh += lbh + ui(lineBreak? 8 : 6); - if(coll) { + if(coll) { // skip var j = i + 1; var _len = array_length(_inspecting.input_display_list); @@ -526,6 +554,7 @@ function Panel_Inspector() : PanelContent() constructor { } continue; + } else if(is_struct(jun_disp) && instanceof(jun_disp) == "Inspector_Custom_Renderer") { jun_disp.register(contentPane); jun_disp.rx = ui(16) + x; diff --git a/shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.fsh b/shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.fsh index 7a3d6f7b1..d4ac6b384 100644 --- a/shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.fsh +++ b/shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.fsh @@ -6,7 +6,7 @@ varying vec4 v_vColour; void main() { float g = v_vColour.g; - g = g * g; + g = pow(g, 5.); - gl_FragColor = vec4(vec3(g), 1.); + gl_FragColor = vec4(vec3(g), v_vColour.a); } diff --git a/shaders/sh_shape/sh_shape.fsh b/shaders/sh_shape/sh_shape.fsh index 6ac2f4e66..288126fa6 100644 --- a/shaders/sh_shape/sh_shape.fsh +++ b/shaders/sh_shape/sh_shape.fsh @@ -1,19 +1,22 @@ +// 2D Signed Distance equations by InigoQuilez + varying vec2 v_vTexcoord; varying vec4 v_vColour; -uniform int shape; -uniform int bg; -uniform int aa; -uniform int sides; -uniform int drawDF; +uniform int shape; +uniform int bg; +uniform int aa; +uniform int sides; +uniform int drawDF; +uniform int tile; -uniform float angle; -uniform float inner; -uniform float outer; -uniform float corner; +uniform float angle; +uniform float inner; +uniform float outer; +uniform float corner; -uniform float stRad; -uniform float edRad; +uniform float stRad; +uniform float edRad; uniform vec2 angle_range; @@ -26,7 +29,7 @@ uniform vec4 bgColor; #define PI 3.14159265359 #define TAU 6.283185307179586 -float sdRegularPolygon(in vec2 p, in float r, in int n, in float ang ) { +float sdRegularPolygon(in vec2 p, in float r, in int n, in float ang ) { #region // these 4 lines can be precomputed for a given shape float an = PI / float(n); vec2 acs = vec2(cos(an), sin(an)); @@ -39,10 +42,10 @@ float sdRegularPolygon(in vec2 p, in float r, in int n, in float ang ) { p -= r * acs; p.y += clamp( -p.y, 0.0, r * acs.y); return length(p) * sign(p.x); -} +} #endregion // signed distance to a n-star polygon with external angle en -float sdStar(in vec2 p, in float r, in int n, in float m, in float ang) { // m=[2,n] +float sdStar(in vec2 p, in float r, in int n, in float m, in float ang) { #region m=[2,n] // these 4 lines can be precomputed for a given shape float an = PI / float(n); float en = PI / m; @@ -57,30 +60,30 @@ float sdStar(in vec2 p, in float r, in int n, in float m, in float ang) { // m=[ p -= r * acs; p += ecs * clamp( -dot(p, ecs), 0.0, r * acs.y / ecs.y); return length(p)*sign(p.x); -} +} #endregion // sca is the sin/cos of the orientation // scb is the sin/cos of the aperture -float sdArc( in vec2 p, in vec2 sca, in vec2 scb, in float ra, in float rb ) { +float sdArc( in vec2 p, in vec2 sca, in vec2 scb, in float ra, in float rb ) { #region p *= mat2(sca.x, sca.y, -sca.y, sca.x); p.x = abs(p.x); float k = (scb.y * p.x > scb.x * p.y) ? dot(p.xy,scb) : length(p); return sqrt( dot(p, p) + ra * ra - 2.0 * ra * k ) - rb; -} +} #endregion -float sdRoundBox( in vec2 p, in vec2 b, in vec4 r ) { +float sdRoundBox( in vec2 p, in vec2 b, in vec4 r ) { #region r.xy = (p.x > 0.0)? r.xy : r.zw; r.x = (p.y > 0.0)? r.x : r.y; vec2 q = abs(p) - b + r.x; return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x; -} +} #endregion -float sdBox( in vec2 p, in vec2 b ) { +float sdBox( in vec2 p, in vec2 b ) { #region vec2 d = abs(p) - b; return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0); -} +} #endregion -float sdTearDrop( vec2 p, float r1, float r2, float h ) { +float sdTearDrop( vec2 p, float r1, float r2, float h ) { #region p.x = abs(p.x); float b = (r1-r2)/h; float a = sqrt(1.0-b*b); @@ -88,49 +91,60 @@ float sdTearDrop( vec2 p, float r1, float r2, float h ) { if( k < 0.0 ) return length(p) - r1; if( k > a*h ) return length(p-vec2(0.0,h)) - r2; return dot(p, vec2(a,b) ) - r1; -} +} #endregion -float sdCross( in vec2 p, in vec2 b, float r ) { +float sdCross( in vec2 p, in vec2 b, float r ) { #region p = abs(p); p = (p.y>p.x) ? p.yx : p.xy; vec2 q = p - b; float k = max(q.y,q.x); vec2 w = (k>0.0) ? q : vec2(b.y-p.x,-k); return sign(k)*length(max(w,0.0)) + r; -} +} #endregion -float sdVesica(vec2 p, float r, float d) { +float sdVesica(vec2 p, float r, float d) { #region p = abs(p); float b = sqrt(r*r-d*d); // can delay this sqrt by rewriting the comparison return ((p.y-b)*d > p.x*b) ? length(p-vec2(0.0,b))*sign(d) : length(p-vec2(-d,0.0))-r; -} +} #endregion + +float sdCrescent(vec2 p, float s, float c) { #region + float o = length(p) - 1.; + float i = length(p - vec2(1. - s * c, 0.)) / s - 1.; + + return max(o, -i); +} #endregion void main() { float color = 0.; - vec2 cen = (v_vTexcoord - center) / scale; - vec2 ratio = dimension / dimension.y; + vec2 coord = (v_vTexcoord - center) / scale; + vec2 ratio = dimension / dimension.y; float d; + if(tile == 1) coord = mod(coord + 1., 2.) - 1.; + if(shape == 0) { d = sdBox( (v_vTexcoord - center) * ratio, (scale * ratio - corner)); d -= corner; } else if(shape == 1) { - d = length(cen) - 1.; + d = length(coord) - 1.; } else if(shape == 2) { - d = sdRegularPolygon( cen, 0.9 - corner, sides, angle ); + d = sdRegularPolygon( coord, 0.9 - corner, sides, angle ); d -= corner; } else if(shape == 3) { - d = sdStar( cen, 0.9 - corner, sides, 2. + inner * (float(sides) - 2.), angle ); + d = sdStar( coord, 0.9 - corner, sides, 2. + inner * (float(sides) - 2.), angle ); d -= corner; } else if(shape == 4) { - d = sdArc( cen, vec2(sin(angle), cos(angle)), angle_range, 0.9 - inner, inner ); + d = sdArc( coord, vec2(sin(angle), cos(angle)), angle_range, 0.9 - inner, inner ); } else if(shape == 5) { - d = sdTearDrop( cen + vec2(0., 0.5), stRad, edRad, 1. ); + d = sdTearDrop( coord + vec2(0., 0.5), stRad, edRad, 1. ); } else if(shape == 6) { - d = sdCross( cen, vec2(1. + corner, outer), corner ); + d = sdCross( coord, vec2(1. + corner, outer), corner ); } else if(shape == 7) { - d = sdVesica( cen, inner, outer ); + d = sdVesica( coord, inner, outer ); + } else if(shape == 8) { + d = sdCrescent( coord, inner, outer ); } //d = d; diff --git a/sprites/s_node_fluidSim_force/f137bb0b-afc7-4c51-81ab-5d039d9345ba.png b/sprites/s_node_fluidSim_force/f137bb0b-afc7-4c51-81ab-5d039d9345ba.png new file mode 100644 index 000000000..e8d71919e Binary files /dev/null and b/sprites/s_node_fluidSim_force/f137bb0b-afc7-4c51-81ab-5d039d9345ba.png differ diff --git a/sprites/s_node_fluidSim_force/layers/f137bb0b-afc7-4c51-81ab-5d039d9345ba/d164cd0a-e3ca-4016-8319-551e7dfc8499.png b/sprites/s_node_fluidSim_force/layers/f137bb0b-afc7-4c51-81ab-5d039d9345ba/d164cd0a-e3ca-4016-8319-551e7dfc8499.png new file mode 100644 index 000000000..e8d71919e Binary files /dev/null and b/sprites/s_node_fluidSim_force/layers/f137bb0b-afc7-4c51-81ab-5d039d9345ba/d164cd0a-e3ca-4016-8319-551e7dfc8499.png differ diff --git a/sprites/s_node_fluidSim_force/s_node_fluidSim_force.yy b/sprites/s_node_fluidSim_force/s_node_fluidSim_force.yy new file mode 100644 index 000000000..06a89aa2f --- /dev/null +++ b/sprites/s_node_fluidSim_force/s_node_fluidSim_force.yy @@ -0,0 +1,74 @@ +{ + "resourceType": "GMSprite", + "resourceVersion": "1.0", + "name": "s_node_fluidSim_force", + "bbox_bottom": 57, + "bbox_left": 6, + "bbox_right": 57, + "bbox_top": 4, + "bboxMode": 0, + "collisionKind": 1, + "collisionTolerance": 0, + "DynamicTexturePage": false, + "edgeFiltering": false, + "For3D": false, + "frames": [ + {"resourceType":"GMSpriteFrame","resourceVersion":"1.1","name":"f137bb0b-afc7-4c51-81ab-5d039d9345ba",}, + ], + "gridX": 0, + "gridY": 0, + "height": 64, + "HTile": false, + "layers": [ + {"resourceType":"GMImageLayer","resourceVersion":"1.0","name":"d164cd0a-e3ca-4016-8319-551e7dfc8499","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_force", + "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":"f137bb0b-afc7-4c51-81ab-5d039d9345ba","path":"sprites/s_node_fluidSim_force/s_node_fluidSim_force.yy",},},},"Disabled":false,"id":"3902d1b6-8dc2-4ea5-8a5f-102d18a89237","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