Fix overlapping particles
This commit is contained in:
parent
882a839205
commit
26dbf70709
@ -848,6 +848,7 @@ unsigned cb_pmap[YRES][XRES];
|
|||||||
|
|
||||||
unsigned photons[YRES][XRES];
|
unsigned photons[YRES][XRES];
|
||||||
|
|
||||||
|
int do_move(int i, int x, int y, float nxf, float nyf);
|
||||||
int try_move(int i, int x, int y, int nx, int ny);
|
int try_move(int i, int x, int y, int nx, int ny);
|
||||||
int eval_move(int pt, int nx, int ny, unsigned *rr);
|
int eval_move(int pt, int nx, int ny, unsigned *rr);
|
||||||
|
|
||||||
|
140
src/powder.c
140
src/powder.c
@ -306,6 +306,35 @@ int try_move(int i, int x, int y, int nx, int ny)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// try to move particle, and if successful update pmap and parts[i].x,y
|
||||||
|
int do_move(int i, int x, int y, float nxf, float nyf)
|
||||||
|
{
|
||||||
|
int nx = (int)(nxf+0.5f), ny = (int)(nyf+0.5f);
|
||||||
|
int result = try_move(i, x, y, nx, ny);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
int t = parts[i].type;
|
||||||
|
parts[i].x = nxf;
|
||||||
|
parts[i].y = nyf;
|
||||||
|
if (ny!=y || nx!=x)
|
||||||
|
{
|
||||||
|
if ((pmap[y][x]>>8)==i) pmap[y][x] = 0;
|
||||||
|
else if ((photons[y][x]>>8)==i) photons[y][x] = 0;
|
||||||
|
if (nx<CELL || nx>=XRES-CELL || ny<CELL || ny>=YRES-CELL)//kill_part if particle is out of bounds
|
||||||
|
{
|
||||||
|
kill_part(i);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (t==PT_PHOT||t==PT_NEUT)
|
||||||
|
photons[ny][nx] = t|(i<<8);
|
||||||
|
else
|
||||||
|
pmap[ny][nx] = t|(i<<8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned direction_to_map(float dx, float dy, int t)
|
static unsigned direction_to_map(float dx, float dy, int t)
|
||||||
{
|
{
|
||||||
// TODO:
|
// TODO:
|
||||||
@ -1845,10 +1874,8 @@ killed:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (try_move(i, x, y, fin_x, fin_y)) {
|
if (!do_move(i, x, y, fin_xf, fin_yf))
|
||||||
parts[i].x = fin_xf;
|
{
|
||||||
parts[i].y = fin_yf;
|
|
||||||
} else {
|
|
||||||
// reflection
|
// reflection
|
||||||
parts[i].flags |= FLAG_STAGNANT;
|
parts[i].flags |= FLAG_STAGNANT;
|
||||||
if (t==PT_NEUT && 100>(rand()%1000))
|
if (t==PT_NEUT && 100>(rand()%1000))
|
||||||
@ -1882,7 +1909,6 @@ killed:
|
|||||||
parts[i].vy -= 2.0f*dp*nry;
|
parts[i].vy -= 2.0f*dp*nry;
|
||||||
fin_x = (int)(parts[i].x + parts[i].vx + 0.5f);
|
fin_x = (int)(parts[i].x + parts[i].vx + 0.5f);
|
||||||
fin_y = (int)(parts[i].y + parts[i].vy + 0.5f);
|
fin_y = (int)(parts[i].y + parts[i].vy + 0.5f);
|
||||||
// cast as int then back to float for compatibility with existing saves
|
|
||||||
if (t==PT_PHOT) {
|
if (t==PT_PHOT) {
|
||||||
s = eval_move(PT_PHOT, fin_x, fin_y, &r);
|
s = eval_move(PT_PHOT, fin_x, fin_y, &r);
|
||||||
if ((((r&0xFF)==PT_GLAS && lt!=PT_GLAS) || ((r&0xFF)!=PT_GLAS && lt==PT_GLAS)) && s) {
|
if ((((r&0xFF)==PT_GLAS && lt!=PT_GLAS) || ((r&0xFF)!=PT_GLAS && lt==PT_GLAS)) && s) {
|
||||||
@ -1890,10 +1916,8 @@ killed:
|
|||||||
goto movedone;
|
goto movedone;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (try_move(i, x, y, fin_x, fin_y)) {
|
// cast coords as int then back to float for compatibility with existing saves
|
||||||
parts[i].x = (float)fin_x;
|
if (!do_move(i, x, y, (float)fin_x, (float)fin_y)) {
|
||||||
parts[i].y = (float)fin_y;
|
|
||||||
} else {
|
|
||||||
kill_part(i);
|
kill_part(i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1911,25 +1935,20 @@ killed:
|
|||||||
else if (ptypes[t].falldown==0)
|
else if (ptypes[t].falldown==0)
|
||||||
{
|
{
|
||||||
// gasses and solids (but not powders)
|
// gasses and solids (but not powders)
|
||||||
if (try_move(i, x, y, fin_x, fin_y)) {
|
if (!do_move(i, x, y, fin_xf, fin_yf))
|
||||||
parts[i].x = fin_xf;
|
{
|
||||||
parts[i].y = fin_yf;
|
// can't move there, so bounce off
|
||||||
} else {
|
|
||||||
// TODO
|
// TODO
|
||||||
if (fin_x>x+ISTP) fin_x=x+ISTP;
|
if (fin_x>x+ISTP) fin_x=x+ISTP;
|
||||||
if (fin_x<x-ISTP) fin_x=x-ISTP;
|
if (fin_x<x-ISTP) fin_x=x-ISTP;
|
||||||
if (fin_y>y+ISTP) fin_y=y+ISTP;
|
if (fin_y>y+ISTP) fin_y=y+ISTP;
|
||||||
if (fin_y<y-ISTP) fin_y=y-ISTP;
|
if (fin_y<y-ISTP) fin_y=y-ISTP;
|
||||||
if (try_move(i, x, y, 2*x-fin_x, fin_y))
|
if (do_move(i, x, y, 0.25f+(float)(2*x-fin_x), 0.25f+fin_y))
|
||||||
{
|
{
|
||||||
parts[i].x = 0.25f+(float)(2*x-fin_x);
|
|
||||||
parts[i].y = 0.25f+fin_y;
|
|
||||||
parts[i].vx *= ptypes[t].collision;
|
parts[i].vx *= ptypes[t].collision;
|
||||||
}
|
}
|
||||||
else if (try_move(i, x, y, fin_x, 2*y-fin_y))
|
else if (do_move(i, x, y, 0.25f+fin_x, 0.25f+(float)(2*y-fin_y)))
|
||||||
{
|
{
|
||||||
parts[i].x = 0.25f+fin_x;
|
|
||||||
parts[i].y = 0.25f+(float)(2*y-fin_y);
|
|
||||||
parts[i].vy *= ptypes[t].collision;
|
parts[i].vy *= ptypes[t].collision;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1942,21 +1961,15 @@ killed:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// liquids and powders
|
// liquids and powders
|
||||||
if (try_move(i, x, y, fin_x, fin_y)) {
|
if (!do_move(i, x, y, fin_xf, fin_yf))
|
||||||
parts[i].x = fin_xf;
|
{
|
||||||
parts[i].y = fin_yf;
|
if (fin_x!=x && do_move(i, x, y, fin_xf, clear_yf))
|
||||||
} else {
|
|
||||||
if (fin_x!=x && try_move(i, x, y, fin_x, clear_y))
|
|
||||||
{
|
{
|
||||||
parts[i].x = fin_xf;
|
|
||||||
parts[i].y = clear_yf;
|
|
||||||
parts[i].vx *= ptypes[t].collision;
|
parts[i].vx *= ptypes[t].collision;
|
||||||
parts[i].vy *= ptypes[t].collision;
|
parts[i].vy *= ptypes[t].collision;
|
||||||
}
|
}
|
||||||
else if (fin_y!=y && try_move(i, x, y, clear_x, fin_y))
|
else if (fin_y!=y && do_move(i, x, y, clear_xf, fin_yf))
|
||||||
{
|
{
|
||||||
parts[i].x = clear_xf;
|
|
||||||
parts[i].y = fin_yf;
|
|
||||||
parts[i].vx *= ptypes[t].collision;
|
parts[i].vx *= ptypes[t].collision;
|
||||||
parts[i].vy *= ptypes[t].collision;
|
parts[i].vy *= ptypes[t].collision;
|
||||||
}
|
}
|
||||||
@ -1978,10 +1991,8 @@ killed:
|
|||||||
dx /= fabsf(dx);
|
dx /= fabsf(dx);
|
||||||
dy /= fabsf(dx);
|
dy /= fabsf(dx);
|
||||||
}
|
}
|
||||||
if (try_move(i, x, y, (int)(clear_xf+dx+0.5f), (int)(clear_yf+dy+0.5f)))
|
if (do_move(i, x, y, clear_xf+dx, clear_yf+dy))
|
||||||
{
|
{
|
||||||
parts[i].x = clear_xf+dx;
|
|
||||||
parts[i].y = clear_yf+dy;
|
|
||||||
parts[i].vx *= ptypes[t].collision;
|
parts[i].vx *= ptypes[t].collision;
|
||||||
parts[i].vy *= ptypes[t].collision;
|
parts[i].vy *= ptypes[t].collision;
|
||||||
goto movedone;
|
goto movedone;
|
||||||
@ -1989,10 +2000,8 @@ killed:
|
|||||||
swappage = dx;
|
swappage = dx;
|
||||||
dx = dy*r;
|
dx = dy*r;
|
||||||
dy = -swappage*r;
|
dy = -swappage*r;
|
||||||
if (try_move(i, x, y, (int)(clear_xf+dx+0.5f), (int)(clear_yf+dy+0.5f)))
|
if (do_move(i, x, y, clear_xf+dx, clear_yf+dy))
|
||||||
{
|
{
|
||||||
parts[i].x = clear_xf+dx;
|
|
||||||
parts[i].y = clear_yf+dy;
|
|
||||||
parts[i].vx *= ptypes[t].collision;
|
parts[i].vx *= ptypes[t].collision;
|
||||||
parts[i].vy *= ptypes[t].collision;
|
parts[i].vy *= ptypes[t].collision;
|
||||||
goto movedone;
|
goto movedone;
|
||||||
@ -2009,22 +2018,16 @@ killed:
|
|||||||
rt = 10;
|
rt = 10;
|
||||||
for (j=clear_x+r; j>=0 && j>=clear_x-rt && j<clear_x+rt && j<XRES; j+=r)
|
for (j=clear_x+r; j>=0 && j>=clear_x-rt && j<clear_x+rt && j<XRES; j+=r)
|
||||||
{
|
{
|
||||||
if (try_move(i, x, y, j, fin_y))
|
if (s=do_move(i, x, y, (float)j, fin_yf))
|
||||||
{
|
{
|
||||||
parts[i].x = clear_xf+(j-clear_x);
|
nx = (int)(parts[i].x+0.5f);
|
||||||
parts[i].y = fin_yf;
|
ny = (int)(parts[i].y+0.5f);
|
||||||
nx = j;
|
|
||||||
ny = fin_y;
|
|
||||||
s = 1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (try_move(i, x, y, j, clear_y))
|
if (fin_y!=clear_y && (s=do_move(i, x, y, (float)j, clear_yf)))
|
||||||
{
|
{
|
||||||
parts[i].x = clear_xf+(j-clear_x);
|
nx = (int)(parts[i].x+0.5f);
|
||||||
parts[i].y = clear_yf;
|
ny = (int)(parts[i].y+0.5f);
|
||||||
nx = j;
|
|
||||||
ny = clear_y;
|
|
||||||
s = 1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((pmap[y][j]&255)!=t || (bmap[y/CELL][j/CELL] && bmap[y/CELL][j/CELL]!=WL_STREAM))
|
if ((pmap[y][j]&255)!=t || (bmap[y/CELL][j/CELL] && bmap[y/CELL][j/CELL]!=WL_STREAM))
|
||||||
@ -2034,39 +2037,25 @@ killed:
|
|||||||
r = 1;
|
r = 1;
|
||||||
else
|
else
|
||||||
r = -1;
|
r = -1;
|
||||||
if (s)
|
if (s==1)
|
||||||
for (j=ny+r; j>=0 && j<YRES && j>=ny-rt && j<ny+rt; j+=r)
|
for (j=ny+r; j>=0 && j<YRES && j>=ny-rt && j<ny+rt; j+=r)
|
||||||
{
|
{
|
||||||
if (try_move(i, nx, ny, nx, j))
|
if (do_move(i, nx, ny, (float)nx, (float)j))
|
||||||
{
|
|
||||||
parts[i].y += j-ny;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
if ((pmap[j][nx]&255)!=t || (bmap[j/CELL][nx/CELL] && bmap[j/CELL][nx/CELL]!=WL_STREAM))
|
if ((pmap[j][nx]&255)!=t || (bmap[j/CELL][nx/CELL] && bmap[j/CELL][nx/CELL]!=WL_STREAM))
|
||||||
{
|
|
||||||
s = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
else if (s==-1) {} // particle is out of bounds
|
||||||
else if ((clear_x!=x||clear_y!=y) && try_move(i, x, y, clear_x, clear_y)) {
|
else if ((clear_x!=x||clear_y!=y) && do_move(i, x, y, clear_xf, clear_yf)) {}
|
||||||
// if interpolation was done and haven't yet moved, try moving to last clear position
|
else parts[i].flags |= FLAG_STAGNANT;
|
||||||
parts[i].x = clear_xf;
|
|
||||||
parts[i].y = clear_yf;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
parts[i].flags |= FLAG_STAGNANT;
|
|
||||||
parts[i].vx *= ptypes[t].collision;
|
parts[i].vx *= ptypes[t].collision;
|
||||||
parts[i].vy *= ptypes[t].collision;
|
parts[i].vy *= ptypes[t].collision;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((clear_x!=x||clear_y!=y) && try_move(i, x, y, clear_x, clear_y)) {
|
|
||||||
// if interpolation was done, try moving to last clear position
|
// if interpolation was done, try moving to last clear position
|
||||||
parts[i].x = clear_xf;
|
if ((clear_x!=x||clear_y!=y) && do_move(i, x, y, clear_xf, clear_yf)) {}
|
||||||
parts[i].y = clear_yf;
|
else parts[i].flags |= FLAG_STAGNANT;
|
||||||
}
|
|
||||||
else
|
|
||||||
parts[i].flags |= FLAG_STAGNANT;
|
|
||||||
parts[i].vx *= ptypes[t].collision;
|
parts[i].vx *= ptypes[t].collision;
|
||||||
parts[i].vy *= ptypes[t].collision;
|
parts[i].vy *= ptypes[t].collision;
|
||||||
}
|
}
|
||||||
@ -2074,23 +2063,8 @@ killed:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
movedone:
|
movedone:
|
||||||
nx = (int)(parts[i].x+0.5f);
|
|
||||||
ny = (int)(parts[i].y+0.5f);
|
|
||||||
if (ny!=y || nx!=x)
|
|
||||||
{
|
|
||||||
if ((pmap[y][x]>>8)==i) pmap[y][x] = 0;
|
|
||||||
else if ((photons[y][x]>>8)==i) photons[y][x] = 0;
|
|
||||||
if (nx<CELL || nx>=XRES-CELL || ny<CELL || ny>=YRES-CELL)//kill_part if particle is out of bounds
|
|
||||||
{
|
|
||||||
kill_part(i);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (t==PT_PHOT||t==PT_NEUT)
|
|
||||||
photons[ny][nx] = t|(i<<8);
|
|
||||||
else
|
|
||||||
pmap[ny][nx] = t|(i<<8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (framerender) {
|
if (framerender) {
|
||||||
framerender = 0;
|
framerender = 0;
|
||||||
sys_pause = 1;
|
sys_pause = 1;
|
||||||
|
Reference in New Issue
Block a user