- improved filling in faces in octree, resulting in less nodes and

branches. Especially larger faces give result. Rendering times go down
  with an average of 10%. My reference testfile went down from 30.4 to
  27.9 seconds.
This commit is contained in:
Ton Roosendaal
2003-12-24 19:05:38 +00:00
parent e9a6c2d996
commit da0e131b16

View File

@@ -104,7 +104,7 @@ static Octree g_oc; /* can be scene pointer or so later... */
/* just for statistics */
static int raycount, branchcount, nodecount;
static int accepted, rejected;
static int accepted, rejected, coherent_ray;
/* **************** ocval method ******************* */
@@ -217,6 +217,45 @@ static Node *addnode(void)
return g_oc.adrnode[nodecount>>12]+(nodecount & 4095);
}
static int face_in_node(VlakRen *vlr, short x, short y, short z, float rtf[][3])
{
static float nor[3], d;
float fx, fy, fz;
// init static vars
if(vlr) {
CalcNormFloat(rtf[0], rtf[1], rtf[2], nor);
d= -nor[0]*rtf[0][0] - nor[1]*rtf[0][1] - nor[2]*rtf[0][2];
return 0;
}
fx= x;
fy= y;
fz= z;
if((x+0)*nor[0] + (y+0)*nor[1] + (z+0)*nor[2] + d > 0.0) {
if((x+1)*nor[0] + (y+0)*nor[1] + (z+0)*nor[2] + d < 0.0) return 1;
if((x+0)*nor[0] + (y+1)*nor[1] + (z+0)*nor[2] + d < 0.0) return 1;
if((x+1)*nor[0] + (y+1)*nor[1] + (z+0)*nor[2] + d < 0.0) return 1;
if((x+0)*nor[0] + (y+0)*nor[1] + (z+1)*nor[2] + d < 0.0) return 1;
if((x+1)*nor[0] + (y+0)*nor[1] + (z+1)*nor[2] + d < 0.0) return 1;
if((x+0)*nor[0] + (y+1)*nor[1] + (z+1)*nor[2] + d < 0.0) return 1;
if((x+1)*nor[0] + (y+1)*nor[1] + (z+1)*nor[2] + d < 0.0) return 1;
}
else {
if((x+1)*nor[0] + (y+0)*nor[1] + (z+0)*nor[2] + d > 0.0) return 1;
if((x+0)*nor[0] + (y+1)*nor[1] + (z+0)*nor[2] + d > 0.0) return 1;
if((x+1)*nor[0] + (y+1)*nor[1] + (z+0)*nor[2] + d > 0.0) return 1;
if((x+0)*nor[0] + (y+0)*nor[1] + (z+1)*nor[2] + d > 0.0) return 1;
if((x+1)*nor[0] + (y+0)*nor[1] + (z+1)*nor[2] + d > 0.0) return 1;
if((x+0)*nor[0] + (y+1)*nor[1] + (z+1)*nor[2] + d > 0.0) return 1;
if((x+1)*nor[0] + (y+1)*nor[1] + (z+1)*nor[2] + d > 0.0) return 1;
}
return 0;
}
static void ocwrite(VlakRen *vlr, short x, short y, short z, float rtf[][3])
{
@@ -224,6 +263,8 @@ static void ocwrite(VlakRen *vlr, short x, short y, short z, float rtf[][3])
Node *no;
short a, oc0, oc1, oc2, oc3, oc4, oc5;
if(face_in_node(NULL, x,y,z, rtf)==0) return;
x<<=2;
y<<=1;
oc0= ((x & 128)+(y & 64)+(z & 32))>>5;
@@ -382,7 +423,8 @@ void freeoctree(void)
}
printf("branches %d nodes %d\n", branchcount, nodecount);
printf("raycount %d \n", raycount);
printf("raycount %d \n", raycount);
// printf("ray coherent %d \n", coherent_ray);
// printf("accepted %d rejected %d\n", accepted, rejected);
branchcount= 0;
@@ -409,7 +451,8 @@ void makeoctree()
raycount=0;
accepted= 0;
rejected= 0;
coherent_ray= 0;
g_oc.vlr_last= NULL;
INIT_MINMAX(g_oc.min, g_oc.max);
@@ -515,8 +558,8 @@ void makeoctree()
filltriangle(0,2,ocvlak,ocmin);
filltriangle(1,2,ocvlak+2*OCRES*OCRES,ocmin);
/* this is approximation here... should calculate for real
if a node intersects plane */
/* init static vars here */
face_in_node(vlr, 0,0,0, rtf);
for(x=ocmin[0];x<=ocmax[0];x++) {
a= OCRES*x;
@@ -932,7 +975,7 @@ static int d3dda(Isect *is)
float labdao,labdax,ldx,labday,ldy,labdaz,ldz, ddalabda;
float vec1[3], vec2[3];
int dx,dy,dz;
int xo,yo,zo,c1=0;
int xo,yo,zo,c1=0; //, testcoh=0;
int ocx1,ocx2,ocy1, ocy2,ocz1,ocz2;
/* clip with octree */
@@ -1076,10 +1119,13 @@ static int d3dda(Isect *is)
/* this loop has been constructed to make sure the first and last node of ray
are always included, even when ddalabda==1.0 or larger */
while(TRUE) {
no= ocread(xo, yo, zo);
if(no) {
//if(xo==ocx1 && yo==ocy1 && zo==ocz1);
//else testcoh= 1;
/* calculate ray intersection with octree node */
VECCOPY(vec1, vec2);
@@ -1142,6 +1188,7 @@ static int d3dda(Isect *is)
/* to make sure the last node is always checked */
if(labdao>=1.0) break;
}
//if(testcoh==0) coherent_ray++;
}
/* reached end, no intersections found */