From da0e131b1665b283fc53606dff43c21d7b7a2902 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 24 Dec 2003 19:05:38 +0000 Subject: - 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. --- source/blender/render/intern/source/ray.c | 59 +++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 6 deletions(-) (limited to 'source') diff --git a/source/blender/render/intern/source/ray.c b/source/blender/render/intern/source/ray.c index c60b679465c..5b5ea18487e 100644 --- a/source/blender/render/intern/source/ray.c +++ b/source/blender/render/intern/source/ray.c @@ -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 */ -- cgit v1.2.3