mirror of
https://github.com/Ttanasart-pt/Pixel-Composer.git
synced 2024-12-27 15:36:16 +01:00
348 lines
No EOL
12 KiB
Text
348 lines
No EOL
12 KiB
Text
enum FD_TARGET_TYPE {
|
|
REPLACE_MATERIAL,
|
|
ADD_MATERIAL,
|
|
REPLACE_VELOCITY,
|
|
ADD_VELOCITY,
|
|
}
|
|
|
|
enum FD_BOUNDARY_TYPE {
|
|
empty,
|
|
wall,
|
|
wrap
|
|
}
|
|
|
|
function smokeSim_Domain(_width, _height) constructor {
|
|
sf_world = noone;
|
|
sf_world_update = true;
|
|
|
|
material_surface_was_created = false;
|
|
|
|
acceleration_type = 0;
|
|
acceleration_a = 0;
|
|
acceleration_b = 0;
|
|
acceleration_x = 0;
|
|
acceleration_y = 0;
|
|
|
|
time_step = 1;
|
|
|
|
initial_value_pressure = 0.5;
|
|
material_dissipation_type = 0;
|
|
material_dissipation_value = 1;
|
|
|
|
velocity_dissipation_type = 1;
|
|
velocity_dissipation_value = 0;
|
|
velocity_maccormack_weight = 0.5;
|
|
material_maccormack_weight = 0;
|
|
|
|
pressure_type = -3;
|
|
pressure_relax = 0;
|
|
|
|
texture_repeat = false;
|
|
texture_wall = false;
|
|
|
|
sf_world = 0;
|
|
sf_pressure = 0; sf_pressure_t = 0;
|
|
sf_velocity = 0; sf_velocity_t = 0;
|
|
sf_material = 0; sf_material_t = 0;
|
|
|
|
max_force = 10;
|
|
|
|
static setSize = function(_width, _height) {
|
|
width = _width;
|
|
height = _height;
|
|
tx_width = 1 / width;
|
|
tx_height = 1 / height;
|
|
verify();
|
|
|
|
return self;
|
|
}
|
|
|
|
static resetSize = function(_width, _height) {
|
|
free();
|
|
setSize(_width, _height);
|
|
|
|
return self;
|
|
}
|
|
|
|
static verify = function() {
|
|
var _f = surface_rgba32float;
|
|
if(!surface_valid(sf_pressure, width, height, _f)) { sf_pressure = surface_verify(sf_pressure, width, height, _f); surface_clear(sf_pressure); }
|
|
if(!surface_valid(sf_pressure_t, width, height, _f)) { sf_pressure_t = surface_verify(sf_pressure_t, width, height, _f); surface_clear(sf_pressure_t); }
|
|
|
|
if(!surface_valid(sf_velocity, width, height, _f)) { sf_velocity = surface_verify(sf_velocity, width, height, _f); surface_clear(sf_velocity); }
|
|
if(!surface_valid(sf_velocity_t, width, height, _f)) { sf_velocity_t = surface_verify(sf_velocity_t, width, height, _f); surface_clear(sf_velocity_t); }
|
|
|
|
if(!surface_valid(sf_material, width, height, _f)) { sf_material = surface_verify(sf_material, width, height, _f); surface_clear(sf_material); }
|
|
if(!surface_valid(sf_material_t, width, height, _f)) { sf_material_t = surface_verify(sf_material_t, width, height, _f); surface_clear(sf_material_t); }
|
|
|
|
sf_world = surface_verify(sf_world, width, height, _f);
|
|
if (sf_world_update) {
|
|
surface_set_target(sf_world);
|
|
draw_clear_alpha(0, 0);
|
|
surface_reset_target();
|
|
sf_world_update = false;
|
|
}
|
|
}
|
|
|
|
static setAcceleration = function(xacc, yacc, a = 0, b = 0) {
|
|
acceleration_x = xacc;
|
|
acceleration_y = yacc;
|
|
|
|
acceleration_a = a;
|
|
acceleration_b = b;
|
|
|
|
acceleration_type = 1;
|
|
if ((xacc == 0 && yacc == 0) || (acceleration_a == 0 && acceleration_b == 0))
|
|
acceleration_type = 0;
|
|
|
|
return self;
|
|
}
|
|
|
|
static setMaterial = function(type, value) {
|
|
material_dissipation_type = type;
|
|
material_dissipation_value = value;
|
|
|
|
return self;
|
|
}
|
|
|
|
static setVelocity = function(type, value) {
|
|
velocity_dissipation_type = type;
|
|
velocity_dissipation_value = value;
|
|
|
|
return self;
|
|
}
|
|
|
|
static setMaccormack = function(vel, mat) {
|
|
velocity_maccormack_weight = vel;
|
|
material_maccormack_weight = mat;
|
|
|
|
return self;
|
|
}
|
|
|
|
static setPressure = function(iteration) {
|
|
pressure_type = iteration;
|
|
pressure_relax = 0;
|
|
|
|
if (iteration >= 0) return;
|
|
|
|
var i = 0, j = 0;
|
|
|
|
switch (iteration) {
|
|
case -1:
|
|
for (j = 0; j < 1; ++j) pressure_relax[i++] = j == 0? 32.6 : -1;
|
|
for (j = 0; j < 15; ++j) pressure_relax[i++] = j == 0? 0.8630 : -1;
|
|
break;
|
|
|
|
case -2:
|
|
for (j = 0; j < 1; ++j) pressure_relax[i++] = j == 0? 81.22 : -1;
|
|
for (j = 0; j < 30; ++j) pressure_relax[i++] = j == 0? 0.9178 : -1;
|
|
break;
|
|
|
|
case -3:
|
|
for (j = 0; j < 1; ++j) pressure_relax[i++] = j == 0? 190.2 : -1;
|
|
for (j = 0; j < 63; ++j) pressure_relax[i++] = j == 0? 0.9532 : -1;
|
|
break;
|
|
|
|
case -4:
|
|
for (j = 0; j < 1; ++j) pressure_relax[i++] = j == 0? 425.8 : -1;
|
|
for (j = 0; j < 130; ++j) pressure_relax[i++] = j == 0? 0.9742 : -1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static setBoundary = function(boundary) {
|
|
switch(boundary) {
|
|
case FD_BOUNDARY_TYPE.empty :
|
|
texture_repeat = false;
|
|
texture_wall = false;
|
|
break;
|
|
|
|
case FD_BOUNDARY_TYPE.wall :
|
|
texture_repeat = false;
|
|
texture_wall = true;
|
|
break;
|
|
|
|
case FD_BOUNDARY_TYPE.wrap :
|
|
texture_repeat = true;
|
|
texture_wall = false;
|
|
break;
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
static addMaterial = function(surface, _x, _y, xscale, yscale, color, alpha) {
|
|
setTarget(FD_TARGET_TYPE.ADD_MATERIAL);
|
|
draw_surface_ext_safe(surface, _x, _y, xscale, yscale, 0, color, alpha);
|
|
resetTarget();
|
|
}
|
|
|
|
static addVelocity = function(surface, _x = 0, _y = 0, xscale = 1, yscale = 1, xvelo = 1, yvelo = 1) {
|
|
setTarget(FD_TARGET_TYPE.ADD_VELOCITY);
|
|
shader_set(sh_fd_add_velocity);
|
|
shader_set_f("velo", xvelo, yvelo);
|
|
draw_surface_ext_safe(surface, _x, _y, xscale, yscale);
|
|
shader_reset();
|
|
resetTarget();
|
|
}
|
|
|
|
static update = function() {
|
|
updateVelocity();
|
|
updateMaterial();
|
|
}
|
|
|
|
static updateVelocity = function() {
|
|
var temporary = noone;
|
|
|
|
gpu_set_texrepeat(texture_repeat);
|
|
gpu_set_texfilter(true);
|
|
gpu_set_blendenable(false);
|
|
verify();
|
|
|
|
surface_set_target(sf_velocity_t);
|
|
shader_set(sh_fd_advect_velocity);
|
|
shader_set_surface("texture_world", sf_world);
|
|
shader_set_surface("texture_material", sf_material);
|
|
shader_set_f("max_force", max_force);
|
|
shader_set_i("mode", acceleration_type);
|
|
shader_set_i("repeat", texture_repeat);
|
|
shader_set_i("wall", texture_wall);
|
|
shader_set_f("precalculated", time_step * tx_width, time_step * tx_height, tx_width, tx_height);
|
|
shader_set_f("precalculated_1", velocity_dissipation_type, velocity_dissipation_value, velocity_maccormack_weight * 0.5);
|
|
shader_set_f("acceleration", acceleration_x, acceleration_y, acceleration_a, acceleration_b);
|
|
shader_set_f("texel_size", tx_width, tx_height);
|
|
|
|
draw_surface_safe(sf_velocity);
|
|
shader_reset();
|
|
surface_reset_target();
|
|
|
|
temporary = sf_velocity;
|
|
sf_velocity = sf_velocity_t;
|
|
sf_velocity_t = temporary;
|
|
|
|
// Calculates divergence of velocity.
|
|
surface_set_target(sf_pressure);
|
|
shader_set(sh_fd_velocity_divergence);
|
|
shader_set_f("max_force", max_force);
|
|
shader_set_i("repeat", texture_repeat);
|
|
shader_set_i("wall", texture_wall);
|
|
shader_set_f("initial_value_pressure", initial_value_pressure);
|
|
shader_set_f("texel_size", tx_width, tx_height);
|
|
draw_surface_safe(sf_velocity);
|
|
shader_reset();
|
|
surface_reset_target();
|
|
|
|
shader_set(sh_fd_pressure_srj);
|
|
shader_set_f("texel_size", tx_width, tx_height);
|
|
shader_set_f("max_force", max_force);
|
|
shader_set_i("repeat", texture_repeat);
|
|
shader_set_i("wall", texture_wall);
|
|
|
|
var length = array_length(pressure_relax);
|
|
for (var i = 0; i < length; ++i) {
|
|
if (pressure_relax[i] != -1) shader_set_f("precalculated", 1 - pressure_relax[i], 0.25 * pressure_relax[i]);
|
|
surface_set_target(sf_pressure_t);
|
|
draw_surface_safe(sf_pressure);
|
|
surface_reset_target();
|
|
|
|
temporary = sf_pressure;
|
|
sf_pressure = sf_pressure_t;
|
|
sf_pressure_t = temporary;
|
|
}
|
|
shader_reset();
|
|
|
|
// Calculates the gradient of pressure and subtracts it from the velocity.
|
|
surface_set_target(sf_velocity_t);
|
|
shader_set(sh_fd_subtract_pressure_gradient);
|
|
shader_set_surface("texture_pressure", sf_pressure);
|
|
shader_set_f("texel_size", tx_width, tx_height);
|
|
shader_set_f("max_force", max_force);
|
|
shader_set_i("repeat", texture_repeat);
|
|
shader_set_i("wall", texture_wall);
|
|
draw_surface_safe(sf_velocity);
|
|
shader_reset();
|
|
surface_reset_target();
|
|
|
|
temporary = sf_velocity;
|
|
sf_velocity = sf_velocity_t;
|
|
sf_velocity_t = temporary;
|
|
|
|
gpu_set_blendenable(true);
|
|
}
|
|
|
|
static updateMaterial = function() {
|
|
var temporary = noone;
|
|
|
|
gpu_set_texrepeat(texture_repeat);
|
|
gpu_set_texfilter(true);
|
|
gpu_set_blendenable(false);
|
|
verify();
|
|
|
|
var _scale = .5;
|
|
|
|
surface_set_target(sf_material_t);
|
|
shader_set(sh_fd_advect_material);
|
|
shader_set_surface("texture_velocity", sf_velocity);
|
|
shader_set_surface("texture_world", sf_world);
|
|
shader_set_i("repeat", texture_repeat);
|
|
shader_set_i("wall", texture_wall);
|
|
shader_set_f("max_force", max_force);
|
|
shader_set_f("texel_size", tx_width, tx_height);
|
|
shader_set_f("precalculated", time_step * tx_width, time_step * tx_height);
|
|
shader_set_f("precalculated_1", tx_width * _scale, tx_height * _scale, -tx_width * _scale, -tx_height * _scale);
|
|
shader_set_f("precalculated_2", material_dissipation_type, material_dissipation_value, material_maccormack_weight * 0.5);
|
|
draw_surface_safe(sf_material);
|
|
shader_reset();
|
|
surface_reset_target();
|
|
|
|
temporary = sf_material;
|
|
sf_material = sf_material_t;
|
|
sf_material_t = temporary;
|
|
|
|
gpu_set_blendenable(true);
|
|
}
|
|
|
|
target_type = noone;
|
|
static setTarget = function(type) {
|
|
target_type = type;
|
|
verify();
|
|
|
|
switch (type) {
|
|
case FD_TARGET_TYPE.REPLACE_MATERIAL:
|
|
surface_set_target(sf_material);
|
|
break;
|
|
|
|
case FD_TARGET_TYPE.ADD_MATERIAL:
|
|
surface_set_target(sf_material);
|
|
gpu_set_blendmode_ext(bm_one, bm_one);
|
|
break;
|
|
|
|
case FD_TARGET_TYPE.REPLACE_VELOCITY:
|
|
surface_set_target(sf_velocity);
|
|
break;
|
|
|
|
case FD_TARGET_TYPE.ADD_VELOCITY:
|
|
surface_set_target(sf_velocity);
|
|
gpu_set_blendmode_ext(bm_one, bm_one);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static resetTarget = function() {
|
|
surface_reset_target();
|
|
BLEND_NORMAL
|
|
}
|
|
|
|
static free = function() {
|
|
surface_free_safe(sf_world);
|
|
surface_free_safe(sf_pressure);
|
|
surface_free_safe(sf_pressure_t);
|
|
surface_free_safe(sf_velocity);
|
|
surface_free_safe(sf_velocity_t);
|
|
surface_free_safe(sf_material);
|
|
surface_free_safe(sf_material_t);
|
|
}
|
|
|
|
setSize(_width, _height);
|
|
setPressure(-3);
|
|
} |