Flip colider, apply force
|
@ -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",},
|
||||
|
|
|
@ -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",},},
|
||||
|
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
118
scripts/node_FLIP_apply_force/node_FLIP_apply_force.gml
Normal 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);
|
||||
}
|
||||
}
|
11
scripts/node_FLIP_apply_force/node_FLIP_apply_force.yy
Normal 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",
|
||||
},
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
44
scripts/node_FLIP_wall/node_FLIP_wall.gml
Normal 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);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"resourceType": "GMScript",
|
||||
"resourceVersion": "1.0",
|
||||
"name": "_FLIP",
|
||||
"name": "node_FLIP_wall",
|
||||
"isCompatibility": false,
|
||||
"isDnD": false,
|
||||
"parent": {
|
|
@ -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
|
||||
|
|
12
shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.fsh
Normal 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.);
|
||||
}
|
19
shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.vsh
Normal 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;
|
||||
}
|
10
shaders/sh_FLIP_draw_droplet/sh_FLIP_draw_droplet.yy
Normal 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,
|
||||
}
|
After Width: | Height: | Size: 831 B |
After Width: | Height: | Size: 831 B |
74
sprites/s_node_fluidSim_wall/s_node_fluidSim_wall.yy
Normal 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,
|
||||
}
|