static voxmodel *vox2poly ()
{
int i, j, x, y, z, v, ov, oz = 0, cnt, sc, x0, y0, dx, dy, i0, i1, *bx0, *by0;
void (*daquad)(int, int, int, int, int, int, int, int, int, int);
coltype *pic;
unsigned char *cptr, ch;
gvox = (voxmodel *)malloc(sizeof(voxmodel)); if (!gvox) return(0);
memset(gvox,0,sizeof(voxmodel));
//x is largest dimension, y is 2nd largest dimension
x = xsiz; y = ysiz; z = zsiz;
if ((x < y) && (x < z)) x = z; else if (y < z) y = z;
if (x < y) { z = x; x = y; y = z; }
shcntp = x; i = x*y*sizeof(int);
shcntmal = (int *)malloc(i); if (!shcntmal) { free(gvox); return(0); }
memset(shcntmal,0,i); shcnt = &shcntmal[-shcntp-1];
gmaxx = gmaxy = garea = 0;
if (pow2m1[32] != -1) { for(i=0;i<32;i++) pow2m1[i] = (1<<i)-1; pow2m1[32] = -1; }
for(i=0;i<7;i++) gvox->qfacind[i] = -1;
i = ((max(ysiz,zsiz)+1)<<2);
bx0 = (int *)malloc(i<<1); if (!bx0) { free(gvox); return(0); }
by0 = (int *)(((intptr_t)bx0)+i);
for(cnt=0;cnt<2;cnt++)
{
if (!cnt) daquad = cntquad;
else daquad = addquad;
gvox->qcnt = 0;
memset(by0,-1,(max(ysiz,zsiz)+1)<<2); v = 0;
for(i=-1;i<=1;i+=2)
for(y=0;y<ysiz;y++)
for(x=0;x<=xsiz;x++)
for(z=0;z<=zsiz;z++)
{
ov = v; v = (isolid(x,y,z) && (!isolid(x,y+i,z)));
if ((by0[z] >= 0) && ((by0[z] != oz) || (v >= ov)))
{ daquad(bx0[z],y,by0[z],x,y,by0[z],x,y,z,i>=0); by0[z] = -1; }
if (v > ov) oz = z; else if ((v < ov) && (by0[z] != oz)) { bx0[z] = x; by0[z] = oz; }
}
for(i=-1;i<=1;i+=2)
for(z=0;z<zsiz;z++)
for(x=0;x<=xsiz;x++)
for(y=0;y<=ysiz;y++)
{
ov = v; v = (isolid(x,y,z) && (!isolid(x,y,z-i)));
if ((by0[y] >= 0) && ((by0[y] != oz) || (v >= ov)))
{ daquad(bx0[y],by0[y],z,x,by0[y],z,x,y,z,(i>=0)+2); by0[y] = -1; }
if (v > ov) oz = y; else if ((v < ov) && (by0[y] != oz)) { bx0[y] = x; by0[y] = oz; }
}
for(i=-1;i<=1;i+=2)
for(x=0;x<xsiz;x++)
for(y=0;y<=ysiz;y++)
for(z=0;z<=zsiz;z++)
{
ov = v; v = (isolid(x,y,z) && (!isolid(x-i,y,z)));
if ((by0[z] >= 0) && ((by0[z] != oz) || (v >= ov)))
{ daquad(x,bx0[z],by0[z],x,y,by0[z],x,y,z,(i>=0)+4); by0[z] = -1; }
if (v > ov) oz = z; else if ((v < ov) && (by0[z] != oz)) { bx0[z] = y; by0[z] = oz; }
}
if (!cnt)
{
shp = (spoint2d *)malloc(gvox->qcnt*sizeof(spoint2d));
if (!shp) { free(bx0); free(gvox); return(0); }
sc = 0;
for(y=gmaxy;y;y--)
for(x=gmaxx;x>=y;x--)
{
i = shcnt[y*shcntp+x]; shcnt[y*shcntp+x] = sc; //shcnt changes from counter to head index
for(;i>0;i--) { shp[sc].x = x; shp[sc].y = y; sc++; }
}
for(gvox->mytexx=32;gvox->mytexx<(gmaxx+(VOXBORDWIDTH<<1));gvox->
mytexx<<=1);
for(gvox->mytexy=32;gvox->mytexy<(gmaxy+(VOXBORDWIDTH<<1));gvox->
mytexy<<=1);
while (gvox->mytexx*gvox->mytexy*8 < garea*9) //This should be sufficient to fit most skins...
{
skindidntfit:;
if (gvox->mytexx <= gvox->mytexy) gvox->mytexx <<= 1; else gvox->mytexy <<= 1;
}
mytexo5 = (gvox->mytexx>>5);
i = (((gvox->mytexx*gvox->mytexy+31)>>5)<<2);
zbit = (int *)malloc(i); if (!zbit) { free(bx0); free(gvox); free(shp); return(0); }
memset(zbit,0,i);
v = gvox->mytexx*gvox->mytexy;
for(z=0;z<sc;z++)
{
dx = shp[z].x+(VOXBORDWIDTH<<1); dy = shp[z].y+(VOXBORDWIDTH<<1); i = v;
do
{
#if (VOXUSECHAR != 0)
x0 = (((rand()&32767)*(min(gvox->mytexx,255)-dx))>>15);
y0 = (((rand()&32767)*(min(gvox->mytexy,255)-dy))>>15);
#else
x0 = (((rand()&32767)*(gvox->mytexx+1-dx))>>15);
y0 = (((rand()&32767)*(gvox->mytexy+1-dy))>>15);
#endif
i--;
if (i < 0) //Time-out! Very slow if this happens... but at least it still works :P
{
free(zbit);
//Re-generate shp[].x/y (box sizes) from shcnt (now head indices) for next pass :/
j = 0;
for(y=gmaxy;y;y--)
for(x=gmaxx;x>=y;x--)
{
i = shcnt[y*shcntp+x];
for(;j<i;j++) { shp[j].x = x0; shp[j].y = y0; }
x0 = x; y0 = y;
}
for(;j<sc;j++) { shp[j].x = x0; shp[j].y = y0; }
goto skindidntfit;
}
} while (!isrectfree(x0,y0,dx,dy));
while ((y0) && (isrectfree(x0,y0-1,dx,1))) y0--;
while ((x0) && (isrectfree(x0-1,y0,1,dy))) x0--;
setrect(x0,y0,dx,dy);
shp[z].x = x0; shp[z].y = y0; //Overwrite size with top-left location
}
gvox->quad = (voxrect_t *)malloc(gvox->qcnt*sizeof(voxrect_t));
if (!gvox->quad) { free(zbit); free(shp); free(bx0); free(gvox); return(0); }
gvox->mytex = (int *)malloc(gvox->mytexx*gvox->mytexy*sizeof(int));
if (!gvox->mytex) { free(gvox->quad); free(zbit); free(shp); free(bx0); free(gvox); return(0); }
}
}
free(shp); free(zbit); free(bx0);
return(gvox);
}