FLIP VFX fixes

This commit is contained in:
Tanasart 2024-05-02 14:48:48 +07:00
parent 8289d4c117
commit 9215ef1de9
10 changed files with 93 additions and 70 deletions

2
.gitignore vendored
View file

@ -1,5 +1,5 @@
\#backups
\#configs
\#config
extensions
options

View file

@ -26,7 +26,7 @@
overRelaxation = 1.5;
obstracles = [];
wallCollide = true;
wallCollide = 0b1111;
wallElasticity = 1;
skip_incompressible = false;

View file

@ -17,21 +17,43 @@ enum PARTICLE_RENDER_TYPE {
function __particleObject() constructor {
active = false;
x = 0;
y = 0;
rot = 0;
scx = 1;
scy = 1;
surf = noone;
blend = c_white;
alp = 1;
static kill = function() {}
static step = function() {}
static draw = function() {}
__temp_pt = [ 0, 0 ];
static draw = function(exact, surf_w, surf_h) { #region
if(!surface_exists(surf)) return;
var _sw = surface_get_width(surf) * scx;
var _sh = surface_get_height(surf) * scy;
point_rotate(-_sw / 2, -_sh / 2, 0, 0, rot, __temp_pt);
print($"Drawing {surf} at {x + __temp_pt[0]}, {y + __temp_pt[1]} > {scx}, {scy} > {blend}, {alp}");
draw_surface_ext(surf, x + __temp_pt[0], y + __temp_pt[1], scx, scy, rot, blend, alp);
} #endregion
static clone = function() { #region
var _p = new __particleObject();
struct_override(_p, self);
return _p;
} #endregion
}
function __part(_node) : __particleObject() constructor {
seed = irandom(99999);
node = _node;
active = false;
/////////////////////// Lifespans ///////////////////////
life = 0;
@ -42,8 +64,6 @@ function __part(_node) : __particleObject() constructor {
/////////////////////// Transforms ///////////////////////
prevx = 0;
prevy = 0;
x = 0;
y = 0;
speedx = 0;
speedy = 0;
turning = 0;
@ -60,8 +80,6 @@ function __part(_node) : __particleObject() constructor {
gravX = 0;
gravY = 0;
scx = 1;
scy = 1;
sc_sx = 1;
sc_sy = 1;
sct = noone;
@ -69,7 +87,6 @@ function __part(_node) : __particleObject() constructor {
scx_history = [];
scy_history = [];
rot = 0;
follow = false;
rot_s = 0;
@ -81,7 +98,6 @@ function __part(_node) : __particleObject() constructor {
/////////////////////// Render ///////////////////////
render_type = PARTICLE_RENDER_TYPE.surface;
surf = noone;
arr_type = 0;
drawx = 0;
@ -91,8 +107,6 @@ function __part(_node) : __particleObject() constructor {
drawsy = 0;
col = -1;
blend = c_white;
alp = 1;
alp_draw = alp;
alp_fade = 0;
currColor = c_white;

View file

@ -12,9 +12,9 @@ function Node_FLIP_Spawner(_x, _y, _group = noone) : Node(_x, _y, _group) constr
inputs[| 1] = nodeValue("Spawn Shape", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0 )
.setDisplay(VALUE_DISPLAY.enum_scroll, [ new scrollItem("Circle", s_node_shape_type, 1), new scrollItem("Rectangle", s_node_shape_type, 0), "Surface" ]);
inputs[| 2] = nodeValue("Spawn Position", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0 ] )
inputs[| 2] = nodeValue("Spawn Position", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0.5, 0.25 ] )
.setDisplay(VALUE_DISPLAY.vector)
.setUnitRef(function(index) { return getDimension(); });
.setUnitRef(function(index) { return getDimension(); }, VALUE_UNIT.reference);
inputs[| 3] = nodeValue("Spawn Type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0 )
.setDisplay(VALUE_DISPLAY.enum_button, [ "Stream", "Splash" ]);

View file

@ -23,9 +23,10 @@ function Node_FLIP_to_VFX(_x, _y, _group = noone) : Node(_x, _y, _group) constru
if(!instance_exists(domain)) return;
if(domain.domain == noone) return;
var _x, _y, _px, _py, _r, _l, _a, _v, _sx, _sy;
var _x, _y, _p, _px, _py, _r, _l, _a, _v, _sx, _sy;
var _mx = min(array_length(domain.particlePos) / 2 - 1, domain.numParticles);
var _ind = 0, _p;
var _pa = outputs[| 0].getValue();
var _ind = 0;
for( var i = 0; i < _mx; i++ ) {
_x = domain.particlePos[i * 2 + 0];
@ -33,7 +34,10 @@ function Node_FLIP_to_VFX(_x, _y, _group = noone) : Node(_x, _y, _group) constru
if(_x == 0 && _y == 0) continue;
_p = parts[_ind++];
_p = parts[_ind];
_pa[_ind] = _p;
_ind++;
_p.active = true;
_p.x = _x;
_p.y = _y;
@ -41,12 +45,8 @@ function Node_FLIP_to_VFX(_x, _y, _group = noone) : Node(_x, _y, _group) constru
if(_ind >= attributes.part_amount) break;
}
for( ; _ind < attributes.part_amount; i++ ) {
_p = parts[_ind++];
_p.active = false;
}
outputs[| 0].setValue(parts);
array_resize(_pa, _ind);
outputs[| 0].setValue(_pa);
}
static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) {

View file

@ -10,17 +10,15 @@ function Node_VFX_Override(_x, _y, _group = noone) : Node(_x, _y, _group) constr
inputs[| 0] = nodeValue("Particles", self, JUNCTION_CONNECT.input, VALUE_TYPE.particle, -1 )
.setVisible(true, true);
inputs[| 1] = nodeValue("Positions", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [] )
.setDisplay(VALUE_DISPLAY.vector);
inputs[| 1] = nodeValue("Positions", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, noone );
inputs[| 2] = nodeValue("Rotations", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [] )
.setDisplay(VALUE_DISPLAY.vector);
inputs[| 2] = nodeValue("Rotations", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, noone );
inputs[| 3] = nodeValue("Scales", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0 );
inputs[| 3] = nodeValue("Scales", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, noone );
inputs[| 4] = nodeValue("Blend", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_white );
inputs[| 4] = nodeValue("Blend", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, noone );
inputs[| 5] = nodeValue("Alpha", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0 );
inputs[| 5] = nodeValue("Alpha", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, noone );
inputs[| 6] = nodeValue("Surface", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone )
.setVisible(true, false);
@ -40,12 +38,19 @@ function Node_VFX_Override(_x, _y, _group = noone) : Node(_x, _y, _group) constr
var nParts = array_create(array_length(parts));
var _a_pos = is_array(_pos);
var _a_sca = is_array(_sca);
var _a_rot = is_array(_rot);
var _a_col = is_array(_col);
var _a_alp = is_array(_alp);
var _a_srf = is_array(_srf);
var _a_pos = inputs[| 1].value_from != noone;
var _a_rot = inputs[| 2].value_from != noone;
var _a_sca = inputs[| 3].value_from != noone;
var _a_col = inputs[| 4].value_from != noone;
var _a_alp = inputs[| 5].value_from != noone;
var _a_srf = inputs[| 6].value_from != noone;
if(array_get_depth(_pos) < 2) _pos = [ _pos ];
if(array_get_depth(_sca) < 2) _sca = [ _sca ];
if(!is_array(_rot)) _rot = [ _rot ];
if(!is_array(_col)) _col = [ _col ];
if(!is_array(_alp)) _alp = [ _alp ];
if(!is_array(_srf)) _srf = [ _srf ];
var _l_pos = array_length(_pos);
var _l_sca = array_length(_sca);
@ -57,20 +62,20 @@ function Node_VFX_Override(_x, _y, _group = noone) : Node(_x, _y, _group) constr
for( var i = 0, n = array_length(parts); i < n; i++ ) {
var nPart = parts[i].clone();
if(_a_pos && _l_pos > i && is_array(_pos[i])) {
nPart.x = _pos[i][0];
nPart.y = _pos[i][1];
if(_a_pos) {
nPart.x = _pos[i % _l_pos][0];
nPart.y = _pos[i % _l_pos][1];
}
if(_a_sca && _l_sca > i && is_array(_sca[i])) {
nPart.scx = _sca[i][0];
nPart.scy = _sca[i][1];
if(_a_sca) {
nPart.scx = _sca[i % _l_sca][0];
nPart.scy = _sca[i % _l_sca][1];
}
if(_a_rot && _l_rot > i) nPart.rot = array_safe_get_fast(_rot, i);
if(_a_col && _l_col > i) nPart.blend = array_safe_get_fast(_col, i);
if(_a_alp && _l_alp > i) nPart.alp = array_safe_get_fast(_alp, i);
if(_a_srf && _l_srf > i) nPart.surf = array_safe_get_fast(_srf, i);
if(_a_rot) nPart.rot = array_safe_get_fast(_rot, i % _l_rot);
if(_a_col) nPart.blend = array_safe_get_fast(_col, i % _l_col);
if(_a_alp) nPart.alp = array_safe_get_fast(_alp, i % _l_alp);
if(_a_srf) nPart.surf = array_safe_get_fast(_srf, i % _l_srf);
nParts[i] = nPart;
}

View file

@ -86,15 +86,10 @@ function Node_VFX_Renderer(_x, _y, _group = noone) : Node(_x, _y, _group) constr
} #endregion
static step = function() { #region
var _dim = getInputData(0);
var _typ = getInputData(2);
inputs[| 3].setVisible(_typ == PARTICLE_RENDER_TYPE.line);
//var _outSurf = outputs[| 0].getValue();
// _outSurf = surface_verify(_outSurf, _dim[0], _dim[1], attrDepth());
//outputs[| 0].setValue(_outSurf);
if(previewing && is_instanceof(group, Node_VFX_Group))
group.preview_node = self;
} #endregion
@ -134,13 +129,17 @@ function Node_VFX_Renderer(_x, _y, _group = noone) : Node(_x, _y, _group) constr
if(!is_array(parts) || array_length(parts) == 0) continue;
if(!is_array(parts[0])) parts = [ parts ];
for(var j = 0; j < array_length(parts); j++)
for(var k = 0; k < array_length(parts[j]); k++) {
parts[j][k].render_type = _type;
parts[j][k].line_draw = _llife;
for(var j = 0; j < array_length(parts); j++) {
var part = parts[j];
if(parts[j][k].active || _type)
parts[j][k].draw(_exact, surf_w, surf_h);
for(var k = 0; k < array_length(part); k++) {
var _part = part[k];
_part.render_type = _type;
_part.line_draw = _llife;
if(_part.active || _type) _part.draw(_exact, surf_w, surf_h);
}
}
}

View file

@ -7,9 +7,9 @@ function Node_Blur_Radial(_x, _y, _group = noone) : Node_Processor(_x, _y, _grou
.setDisplay(VALUE_DISPLAY.rotation)
.setMappable(10);
inputs[| 2] = nodeValue("Center", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0 ])
inputs[| 2] = nodeValue("Center", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0.5, 0.5 ])
.setDisplay(VALUE_DISPLAY.vector)
.setUnitRef(function(index) { return getDimension(index); });
.setUnitRef(function(index) { return getDimension(index); }, VALUE_UNIT.reference);
inputs[| 3] = nodeValue("Oversample mode", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0, "How to deal with pixel outside the surface.\n - Empty: Use empty pixel\n - Clamp: Repeat edge pixel\n - Repeat: Repeat texture.")
.setDisplay(VALUE_DISPLAY.enum_scroll, [ "Empty", "Clamp", "Repeat" ]);

View file

@ -64,7 +64,7 @@ function Node_Export(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
inputs[| 2].editWidget.auto_update = true;
format_single = ["Single image", "Image sequence", "Animation"];
format_array = ["Multiple images", "Image sequences", "Animation"];
format_array = ["Multiple images", "Image sequences", "Animations"];
inputs[| 3] = nodeValue("Type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
.setDisplay(VALUE_DISPLAY.enum_scroll, { data: format_single, update_hover: false })
@ -342,6 +342,7 @@ function Node_Export(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
if(rate == 0) rate = 1;
temp_path = string_replace_all(temp_path, "/", "\\");
temp_path = string_trim(temp_path, ["*.png"]);
target_path = string_replace_all(target_path, "/", "\\");
var framerate = 100 / rate;
@ -365,6 +366,7 @@ function Node_Export(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
if(file_exists_empty(target_path)) file_delete(target_path);
temp_path = string_replace_all(temp_path, "/", "\\");
temp_path = string_trim(temp_path, ["*.png"]);
target_path = string_replace_all(target_path, "/", "\\");
var shell_cmd = $"-hide_banner -loglevel quiet -framerate {rate} -i \"{temp_path}%05d.png\" -c:v libx264 -r {rate} -pix_fmt yuv420p -crf {qual} {string_quote(target_path)}";
@ -381,6 +383,7 @@ function Node_Export(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
if(file_exists_empty(target_path)) file_delete(target_path);
temp_path = string_replace_all(temp_path, "/", "\\");
temp_path = string_trim(temp_path, ["*.png"]);
target_path = string_replace_all(target_path, "/", "\\");
var shell_cmd = $"-hide_banner -loglevel quiet -framerate {rate} -i \"{temp_path}%05d.png\" -plays 0 {string_quote(target_path)}";

View file

@ -159,18 +159,20 @@ void main() { #region
}
}
if(!isOutline) {
gl_FragColor = col;
return;
}
if(!isOutline) return;
float _aa = 1.;
if(is_aa == 1) _aa = min(smoothstep(bSiz + bStr + 1., bSiz + bStr, closetDistance), smoothstep(bStr - 1., bStr, closetDistance));
else _aa = min(step(-(bSiz + bStr + 0.5), -closetDistance), step(bStr - 0.5, closetDistance));
if(_aa == 0.) return;
if(is_blend == 0) col = blendColor(baseColor, borderColor, _aa);
else col = blendColor(side == 0? baseColor : closetColor, borderColor, _aa * bld);
else {
col = blendColor(side == 0? baseColor : closetColor, borderColor, _aa * bld);
col.a = _aa;
}
gl_FragColor = col;
} #endregion