Flip colider, apply force

This commit is contained in:
Tanasart 2023-12-31 20:09:49 +07:00
parent f582db702c
commit 812b0808af
26 changed files with 448 additions and 58 deletions

View file

@ -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",},

View file

@ -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",},},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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",
},
}

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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();
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -1,7 +1,7 @@
{
"resourceType": "GMScript",
"resourceVersion": "1.0",
"name": "_FLIP",
"name": "node_FLIP_wall",
"isCompatibility": false,
"isDnD": false,
"parent": {

View file

@ -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

View file

@ -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.);
}

View file

@ -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;
}

View file

@ -0,0 +1,10 @@
{
"resourceType": "GMShader",
"resourceVersion": "1.0",
"name": "sh_FLIP_draw_droplet",
"parent": {
"name": "FLIP",
"path": "folders/shader/FLIP.yy",
},
"type": 1,
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 831 B

View file

@ -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<MessageEventKeyframe>","resourceVersion":"1.0","Keyframes":[],},
"eventStubScript": null,
"eventToFunction": {},
"length": 1.0,
"lockOrigin": false,
"moments": {"resourceType":"KeyframeStore<MomentsEventKeyframe>","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<SpriteFrameKeyframe>","resourceVersion":"1.0","Keyframes":[
{"resourceType":"Keyframe<SpriteFrameKeyframe>","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,
}