#include <acknex.h>
#include <default.c>
#define scale skill1 //INPUT/OUTPUT - scale of the terrain
#define viscosity skill2 //INPUT/OUTPUT - "density" of the fluid. 1=Water, 2=EngineOil, 3=Honey
#define vertex_wide skill3 //OUTPUT - width of HMP in vertices
#define vertex_high skill4 //OUTPUT - height of HMP in vertices
action fluid_action()
{
//validate if a valid entity for fluid simulation (must be a terrain)
if(!ent_status(my,2)||!ent_status(my,3)) return; //this is NOT a terrain.
//create and initialise "workspace" variables & pointers
CONTACT* c;
var x, y, f, tmp, frametime=0;
var size_x=ent_status(my,2)+1, size_y=ent_status(my,3)+1;
//create and initialise "workspace" arrays
var ***data = malloc(sizeof(var)*2);
for(f=0; f<2; f++)
{ data[f] = malloc(sizeof(var)*size_x);
for(x=0; x<size_x; x++)
{ (data[f])[x] = malloc(sizeof(var)*size_y);
for(y=0; y<size_y; y++) ((data[f])[x])[y] = 0;
} }
//setup feedback skills
if(!my.scale)
{
//auto-calculate scale based on VETs idea.
c = ent_getvertex(my,NULL,1);
x=c.v.x; y=c.v.z;
c = ent_getvertex(my,NULL,2+size_y);
x-=c.v.x; y-=c.v.z;
my.scale = (abs(x) + abs(y))/2/2.54; //quants per "square" (2.54qu = scale of 1.0)
}
if(!my.viscosity) my.viscosity = 1; //default to "water" viscosity
my.vertex_wide = size_x;
my.vertex_high = size_y;
//
var sim_fps = 10; //Simulation FPS. AVOID changing if possible, because
// //if changed, it will skew BOTH Scale & Viscosity ranges
//
while(me)
{
my.scale=clamp(my.scale,0.5,50);
frametime += time_frame;
if(frametime>(16/sim_fps*my.scale*2))
{
frametime -= (16/sim_fps*(my.scale*2));
f = !f;
my.viscosity=clamp(my.viscosity,0.9,5);
for(y=1; y<(size_y-1); y++) for(x=1; x<(size_x-1); x++)
{
c = ent_getvertex(my,NULL,(y*size_x)+x+1);
if((c.v.y!=((data[0])[x])[y])&&(c.v.y!=((data[1])[x])[y]))
{ ((data[f])[x])[y] = ((data[!f])[x])[y] = c.v.y;
c = ent_getvertex(my,NULL,((y--)*size_x)+(x--)+1); }
tmp = (((data[!f])[x-1])[y]+((data[!f])[x+1])[y]+((data[!f])[x])[y-1]+((data[!f])[x])[y+1]);
tmp += (((data[!f])[x-1])[y-1]+((data[!f])[x-1])[y+1]+((data[!f])[x+1])[y-1]+((data[!f])[x+1])[y+1])/2;
((data[f])[x])[y] = ((tmp/4*(my.scale))-((data[f])[x])[y])*(0.3*(3/my.viscosity));
((data[f])[x])[y] = c.v.y = integer(((data[f])[x])[y]*10000)/10000; //idle-damping
ent_setvertex(my,c,(y*size_x)+x+1);
}
}
wait(1);
}
//cleanup "workspace" arrays
for(x=0; x<size_x; x++) { free((data[0])[x]); free((data[1])[x]); }
free(data[0]); free(data[1]); free(data);
}
ENTITY* waterent;
void poke()
{
CONTACT* c = ent_getvertex(waterent,NULL,210);
c.v.y += 5;
ent_setvertex(waterent,c,510);
}
function main()
{
video_mode = 10;
// video_screen = 1;
level_load("");
vec_set(camera.x, vector(0,25,25));
vec_set(camera.pan, vector(270,-45,0));
waterent = ent_create("waterent.hmp", nullvector, fluid_action);
on_cuu = poke;
}
//