Skip to content

Commit

Permalink
Comments for some of the liquid movement code
Browse files Browse the repository at this point in the history
  • Loading branch information
jacksonmj committed Apr 26, 2014
1 parent 097e496 commit 4dae152
Showing 1 changed file with 23 additions and 5 deletions.
28 changes: 23 additions & 5 deletions src/simulation/Simulation.cpp
Expand Up @@ -4443,7 +4443,7 @@ void Simulation::update_particles_i(int start, int inc)
else
{
s = 1;
r = (rand()%2)*2-1;
r = (rand()%2)*2-1;// position search direction (left/right first)
if ((clear_x!=x || clear_y!=y || nt || surround_space) &&
(fabsf(parts[i].vx)>0.01f || fabsf(parts[i].vy)>0.01f))
{
Expand Down Expand Up @@ -4531,12 +4531,15 @@ void Simulation::update_particles_i(int start, int inc)
rt = 30;//slight less water lag, although it changes how it moves a lot
else
rt = 10;
// clear_xf, clear_yf is the last known position that the particle should almost certainly be able to move to
nxf = clear_xf;
nyf = clear_yf;
nx = (int)(parts[i].x+0.5f);
ny = (int)(parts[i].y+0.5f);
nx = clear_y;
ny = clear_x;
// Look for spaces to move horizontally (perpendicular to gravity direction), keep going until a space is found or the number of positions examined = rt
for (j=0;j<rt;j++)
{
// Calculate overall gravity direction
switch (gravityMode)
{
default:
Expand All @@ -4555,15 +4558,21 @@ void Simulation::update_particles_i(int start, int inc)
}
pGravX += gravx[(ny/CELL)*(XRES/CELL)+(nx/CELL)];
pGravY += gravy[(ny/CELL)*(XRES/CELL)+(nx/CELL)];
// Scale gravity vector so that the largest component is 1 pixel
if (fabsf(pGravY)>fabsf(pGravX))
mv = fabsf(pGravY);
else
mv = fabsf(pGravX);
if (mv<0.0001f) break;
pGravX /= mv;
pGravY /= mv;
// Move 1 pixel perpendicularly to gravity
// r is +1/-1, to try moving left or right at random
if (j)
{
// Not quite the gravity direction
// Gravity direction + last change in gravity direction
// This makes liquid movement a bit less frothy, particularly for balls of liquid in radial gravity. With radial gravity, instead of just moving along a tangent, the attempted movement will follow the curvature a bit better.
nxf += r*(pGravY*2.0f-prev_pGravY);
nyf += -r*(pGravX*2.0f-prev_pGravX);
}
Expand All @@ -4574,6 +4583,7 @@ void Simulation::update_particles_i(int start, int inc)
}
prev_pGravX = pGravX;
prev_pGravY = pGravY;
// Check whether movement is allowed
nx = (int)(nxf+0.5f);
ny = (int)(nyf+0.5f);
if (nx<0 || ny<0 || nx>=XRES || ny >=YRES)
Expand All @@ -4583,20 +4593,25 @@ void Simulation::update_particles_i(int start, int inc)
s = do_move(i, x, y, nxf, nyf);
if (s)
{
// Movement was successful
nx = (int)(parts[i].x+0.5f);
ny = (int)(parts[i].y+0.5f);
break;
}
// A particle of a different type, or a wall, was found. Stop trying to move any further horizontally unless the wall should be completely invisible to particles.
if (bmap[ny/CELL][nx/CELL]!=WL_STREAM)
break;
}
}
if (s==1)
{
// The particle managed to move horizontally, now try to move vertically (parallel to gravity direction)
// Keep going until the particle is blocked (by something that isn't the same element) or the number of positions examined = rt
clear_x = nx;
clear_y = ny;
for (j=0;j<rt;j++)
{
// Calculate overall gravity direction
switch (gravityMode)
{
default:
Expand All @@ -4615,29 +4630,32 @@ void Simulation::update_particles_i(int start, int inc)
}
pGravX += gravx[(ny/CELL)*(XRES/CELL)+(nx/CELL)];
pGravY += gravy[(ny/CELL)*(XRES/CELL)+(nx/CELL)];
// Scale gravity vector so that the largest component is 1 pixel
if (fabsf(pGravY)>fabsf(pGravX))
mv = fabsf(pGravY);
else
mv = fabsf(pGravX);
if (mv<0.0001f) break;
pGravX /= mv;
pGravY /= mv;
// Move 1 pixel in the direction of gravity
nxf += pGravX;
nyf += pGravY;
nx = (int)(nxf+0.5f);
ny = (int)(nyf+0.5f);
if (nx<0 || ny<0 || nx>=XRES || ny>=YRES)
break;
// If the space is anything except the same element (a wall, empty space, or occupied by a particle of a different element), try to move into it
if ((pmap[ny][nx]&0xFF)!=t || bmap[ny/CELL][nx/CELL])
{
s = do_move(i, clear_x, clear_y, nxf, nyf);
if (s || bmap[ny/CELL][nx/CELL]!=WL_STREAM)
break;
break; // found the edge of the liquid and movement into it succeeded, so stop moving down
}
}
}
else if (s==-1) {} // particle is out of bounds
else if ((clear_x!=x||clear_y!=y) && do_move(i, x, y, clear_xf, clear_yf)) {}
else if ((clear_x!=x||clear_y!=y) && do_move(i, x, y, clear_xf, clear_yf)) {} // try moving to the last clear position
else parts[i].flags |= FLAG_STAGNANT;
parts[i].vx *= elements[t].Collision;
parts[i].vy *= elements[t].Collision;
Expand Down

0 comments on commit 4dae152

Please sign in to comment.