faster reading of world structure

git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@2655 e016b1c5-ed68-44aa-a2f7-31cac88cffde
This commit is contained in:
Lee Salzman
2008-09-17 01:42:40 +00:00
parent 62baecac96
commit b2811e4893
6 changed files with 44 additions and 43 deletions
+4 -4
View File
@@ -157,9 +157,9 @@ void cursorupdate() // called every frame fr
sqr *s = S(ix,iy);
if(SOLID(s)) continue;
float h1 = sheight(s, s, z);
float h2 = sheight(s, SWS(s,1,0,ssize), z);
float h3 = sheight(s, SWS(s,1,1,ssize), z);
float h4 = sheight(s, SWS(s,0,1,ssize), z);
float h2 = sheight(s, SWS(s,1,0,sfactor), z);
float h3 = sheight(s, SWS(s,1,1,sfactor), z);
float h4 = sheight(s, SWS(s,0,1,sfactor), z);
if(s->tag) linestyle(GRIDW, 0xFF, 0x40, 0x40);
else if(s->type==FHF || s->type==CHF) linestyle(GRIDW, 0x80, 0xFF, 0x80);
else linestyle(GRIDW, 0x80, 0x80, 0x80);
@@ -177,7 +177,7 @@ void cursorupdate() // called every frame fr
float ih = sheight(s, s, z);
linestyle(GRIDS, 0xFF, 0xFF, 0xFF);
block b = { cx, cy, 1, 1 };
box(b, ih, sheight(s, SWS(s,1,0,ssize), z), sheight(s, SWS(s,1,1,ssize), z), sheight(s, SWS(s,0,1,ssize), z));
box(b, ih, sheight(s, SWS(s,1,0,sfactor), z), sheight(s, SWS(s,1,1,sfactor), z), sheight(s, SWS(s,0,1,sfactor), z));
linestyle(GRIDS, 0xFF, 0x00, 0x00);
dot(cx, cy, ih);
ch = (int)ih;
+3 -3
View File
@@ -92,12 +92,12 @@ bool plcollide(physent *d, physent *o, float &headspace, float &hi, float &lo)
bool cornertest(int mip, int x, int y, int dx, int dy, int &bx, int &by, int &bs) // recursively collide with a mipmapped corner cube
{
sqr *w = wmip[mip];
int sz = ssize>>mip;
bool stest = SOLID(SWS(w, x+dx, y, sz)) && SOLID(SWS(w, x, y+dy, sz));
int mfactor = sfactor - mip;
bool stest = SOLID(SWS(w, x+dx, y, mfactor)) && SOLID(SWS(w, x, y+dy, mfactor));
mip++;
x /= 2;
y /= 2;
if(SWS(wmip[mip], x, y, ssize>>mip)->type==CORNER)
if(SWS(wmip[mip], x, y, mfactor-1)->type==CORNER)
{
bx = x<<mip;
by = y<<mip;
+13 -13
View File
@@ -22,8 +22,8 @@ void remip(block &b, int level)
int lighterr = getvar("lighterror")*3;
sqr *w = wmip[level];
sqr *v = wmip[level+1];
int ws = ssize>>level;
int vs = ssize>>(level+1);
int wfactor = sfactor - level;
int vfactor = sfactor - (level+1);
block s = b;
if(s.x&1) { s.x--; s.xs++; }
if(s.y&1) { s.y--; s.ys++; }
@@ -32,11 +32,11 @@ void remip(block &b, int level)
for(int x = s.x; x<s.x+s.xs; x+=2) for(int y = s.y; y<s.y+s.ys; y+=2)
{
sqr *o[4];
o[0] = SWS(w,x,y,ws); // the 4 constituent cubes
o[1] = SWS(w,x+1,y,ws);
o[2] = SWS(w,x+1,y+1,ws);
o[3] = SWS(w,x,y+1,ws);
sqr *r = SWS(v,x/2,y/2,vs); // the target cube in the higher mip level
o[0] = SWS(w,x,y,wfactor); // the 4 constituent cubes
o[1] = SWS(w,x+1,y,wfactor);
o[2] = SWS(w,x+1,y+1,wfactor);
o[3] = SWS(w,x,y+1,wfactor);
sqr *r = SWS(v,x/2,y/2,vfactor); // the target cube in the higher mip level
*r = *o[0];
uchar nums[MAXTYPE];
loopi(MAXTYPE) nums[i] = 0;
@@ -88,11 +88,11 @@ void remip(block &b, int level)
}
if(r->type==CHF || r->type==FHF) // can make a perfect mip out of a hf if slopes lie on one line
{
if(o[0]->vdelta-o[1]->vdelta != o[1]->vdelta-SWS(w,x+2,y,ws)->vdelta
|| o[0]->vdelta-o[2]->vdelta != o[2]->vdelta-SWS(w,x+2,y+2,ws)->vdelta
|| o[0]->vdelta-o[3]->vdelta != o[3]->vdelta-SWS(w,x,y+2,ws)->vdelta
|| o[3]->vdelta-o[2]->vdelta != o[2]->vdelta-SWS(w,x+2,y+1,ws)->vdelta
|| o[1]->vdelta-o[2]->vdelta != o[2]->vdelta-SWS(w,x+1,y+2,ws)->vdelta) goto c;
if(o[0]->vdelta-o[1]->vdelta != o[1]->vdelta-SWS(w,x+2,y,wfactor)->vdelta
|| o[0]->vdelta-o[2]->vdelta != o[2]->vdelta-SWS(w,x+2,y+2,wfactor)->vdelta
|| o[0]->vdelta-o[3]->vdelta != o[3]->vdelta-SWS(w,x,y+2,wfactor)->vdelta
|| o[3]->vdelta-o[2]->vdelta != o[2]->vdelta-SWS(w,x+2,y+1,wfactor)->vdelta
|| o[1]->vdelta-o[2]->vdelta != o[2]->vdelta-SWS(w,x+1,y+2,wfactor)->vdelta) goto c;
}
}
{ loopi(4) if(o[i]->defer) goto c; } // if any of the constituents is not perfect, then this one isn't either
@@ -306,7 +306,7 @@ void empty_world(int factor, bool force) // main empty world creation routine
{
loop(x,ssize/2) loop(y,ssize/2)
{
*S(x+ssize/4, y+ssize/4) = *SWS(oldworld, x, y, ssize/2);
*S(x+ssize/4, y+ssize/4) = *SWS(oldworld, x, y, sfactor-1);
}
loopv(ents)
{
+2 -2
View File
@@ -47,8 +47,8 @@ struct header // map file format header
int reserved[14];
};
#define SWS(w,x,y,s) (&(w)[(y)*(s)+(x)])
#define SW(w,x,y) SWS(w,x,y,ssize)
#define SWS(w,x,y,s) (&(w)[((y)<<(s))+(x)])
#define SW(w,x,y) SWS(w,x,y,sfactor)
#define S(x,y) SW(world,x,y) // convenient lookup of a lowest mip cube
#define SMALLEST_FACTOR 6 // determines number of mips there can be
#define DEFAULT_FACTOR 8
+7 -7
View File
@@ -58,10 +58,10 @@ void voptimize() // reset vdeltas on non-hf cubes
void topt(sqr *s, bool &wf, bool &uf, int &wt, int &ut)
{
sqr *o[4];
o[0] = SWS(s,0,-1,ssize);
o[1] = SWS(s,0,1,ssize);
o[2] = SWS(s,1,0,ssize);
o[3] = SWS(s,-1,0,ssize);
o[0] = SWS(s,0,-1,sfactor);
o[1] = SWS(s,0,1,sfactor);
o[2] = SWS(s,1,0,sfactor);
o[3] = SWS(s,-1,0,sfactor);
wf = true;
uf = true;
if(SOLID(s))
@@ -93,9 +93,9 @@ void toptimize() // FIXME: only does 2x2, make atleast for 4x4 also
s[0] = S(x,y);
int wt = s[0]->wtex, ut = s[0]->utex;
topt(s[0], wf[0], uf[0], wt, ut);
topt(s[1] = SWS(s[0],0,1,ssize), wf[1], uf[1], wt, ut);
topt(s[2] = SWS(s[0],1,1,ssize), wf[2], uf[2], wt, ut);
topt(s[3] = SWS(s[0],1,0,ssize), wf[3], uf[3], wt, ut);
topt(s[1] = SWS(s[0],0,1,sfactor), wf[1], uf[1], wt, ut);
topt(s[2] = SWS(s[0],1,1,sfactor), wf[2], uf[2], wt, ut);
topt(s[3] = SWS(s[0],1,0,sfactor), wf[3], uf[3], wt, ut);
loopi(4)
{
if(wf[i]) s[i]->wtex = wt;
+15 -14
View File
@@ -79,17 +79,17 @@ bool issemi(int mip, int x, int y, int x1, int y1, int x2, int y2)
{
if(!(mip--)) return true;
sqr *w = wmip[mip];
int msize = ssize>>mip;
int mfactor = sfactor - mip;
x *= 2;
y *= 2;
switch(SWS(w, x+x1, y+y1, msize)->type)
switch(SWS(w, x+x1, y+y1, mfactor)->type)
{
case SEMISOLID: if(issemi(mip, x+x1, y+y1, x1, y1, x2, y2)) return true;
case CORNER:
case SOLID: break;
default: return true;
}
switch(SWS(w, x+x2, y+y2, msize)->type)
switch(SWS(w, x+x2, y+y2, mfactor)->type)
{
case SEMISOLID: if(issemi(mip, x+x2, y+y2, x1, y1, x2, y2)) return true;
case CORNER:
@@ -108,7 +108,8 @@ bool render_floor, render_ceil;
void render_seg_new(float vx, float vy, float vh, int mip, int x, int y, int xs, int ys)
{
sqr *w = wmip[mip];
int sz = ssize>>mip;
int mfactor = sfactor - mip;
int sz = 1<<mfactor;
int vxx = ((int)vx+(1<<mip)/2)>>mip;
int vyy = ((int)vy+(1<<mip)/2)>>mip;
int lx = vxx-lodleft; // these mark the rect inside the current rest that we want to render using a lower mip level
@@ -119,15 +120,15 @@ void render_seg_new(float vx, float vy, float vh, int mip, int x, int y, int xs,
float fsize = (float)(1<<mip);
for(int ox = x; ox<xs; ox++) for(int oy = y; oy<ys; oy++) // first collect occlusion information for this block
{
SWS(w,ox,oy,sz)->occluded = isoccluded(camera1->o.x, camera1->o.y, (float)(ox<<mip), (float)(oy<<mip), fsize);
SWS(w,ox,oy,mfactor)->occluded = isoccluded(camera1->o.x, camera1->o.y, (float)(ox<<mip), (float)(oy<<mip), fsize);
}
int pvx = (int)vx>>mip;
int pvy = (int)vy>>mip;
if(pvx>=0 && pvy>=0 && pvx<sz && pvy<sz)
{
//SWS(w,vxx,vyy,sz)->occluded = 0;
SWS(w, pvx, pvy, sz)->occluded = 0; // player cell never occluded
//SWS(w,vxx,vyy,mfactor)->occluded = 0;
SWS(w, pvx, pvy, mfactor)->occluded = 0; // player cell never occluded
}
#define df(x) s->floor-(x->vdelta/4.0f)
@@ -140,17 +141,17 @@ void render_seg_new(float vx, float vy, float vh, int mip, int x, int y, int xs,
// render here.
#define LOOPH {for(int xx = x; xx<xs; xx++) for(int yy = y; yy<ys; yy++) { \
sqr *s = SWS(w,xx,yy,sz); if(s->occluded==1) continue; \
sqr *s = SWS(w,xx,yy,mfactor); if(s->occluded==1) continue; \
if(s->defer && !s->occluded && mip && xx>=lx && xx<rx && yy>=ly && yy<ry)
#define LOOPD sqr *t = SWS(s,1,0,sz); \
sqr *u = SWS(s,1,1,sz); \
sqr *v = SWS(s,0,1,sz);
#define LOOPD sqr *t = SWS(s,1,0,mfactor); \
sqr *u = SWS(s,1,1,mfactor); \
sqr *v = SWS(s,0,1,mfactor);
LOOPH // floors
{
int start = yy;
sqr *next;
while(yy<ys-1 && (next = SWS(w,xx,yy+1,sz))->defer && !next->occluded) yy++; // collect 2xN rect of lower mip
while(yy<ys-1 && (next = SWS(w,xx,yy+1,mfactor))->defer && !next->occluded) yy++; // collect 2xN rect of lower mip
render_seg_new(vx, vy, vh, mip-1, xx*2, start*2, xx*2+2, yy*2+2);
continue;
}
@@ -182,8 +183,8 @@ void render_seg_new(float vx, float vy, float vh, int mip, int x, int y, int xs,
// zSt
// vu
sqr *w = SWS(s,0,-1,sz);
sqr *z = SWS(s,-1,0,sz);
sqr *w = SWS(s,0,-1,mfactor);
sqr *z = SWS(s,-1,0,mfactor);
bool normalwall = true;
if(s->type==CORNER)