00001 #define MODULE_TRACE
00002
00003
00004
00005
00006 #include <setjmp.h>
00007 #include "render.h"
00008
00009 #define UC unsigned short
00010 #define US unsigned long
00011
00018 typedef struct traceNODE {
00019 long n,
00020 mi[3],ma[3];
00021 UC *vxi;
00022 UC *oid;
00023 US *fid;
00024 struct traceNODE *octree[8];
00025 long id; struct traceNODE *last; long level;
00026 } node;
00027
00028
00029
00030 #define THRESHOLDF 25 // nominal max number of faces per voxel - use when not subdividing
00031 #define THRESHOLDR 8 // maximum number of recursive levels
00032
00033 extern short R_terminator(void);
00034
00035 static jmp_buf x_buf;
00036 static long threshold_f,threshold_z,threshold_r,
00037 nfaces,kcount,maxfaces,minfaces,
00038 trace_depth_max=7,
00039 level_depth_max;
00040 static node *ROOT;
00041 static long *ObjectXlist=NULL;
00042 static long voxel_xmin,voxel_ymin,voxel_zmin,
00043 voxel_xmax,voxel_ymax,voxel_zmax;
00044
00045 static node *which_voxel(vector p, node *nc);
00046 static node *track_ray(node *nc, vector p, vector d);
00047 static void destroyBST(node *np);
00048 static void countBST(node *np);
00049 static void printBST(node *np);
00050 static int MakeVoxels(node *np, int level);
00051 static void eliminateDuplicatesInBST(node *n);
00052 static BOOL PartitionVoxel(node *, node *, node *, long, long index);
00053 static BOOL SplitVoxel(node *, node *, node *, long, long index);
00054
00055 static double longest_ray;
00056
00057 static void IntersectPlane(long p, long index, ivector vi1, ivector vi2, ivector vo){
00058 long id1[3]={1,2,0},id2[3]={2,0,1};
00059 double mu;
00060 mu=(double)(vi2[index]-vi1[index]);
00061 if(fabs(mu) < 1.0)mu=0.0;
00062 else mu=((double)p-vi1[index])/mu;
00063 vo[index]=p;
00064 vo[id1[index]]=vi1[id1[index]]+(long)(mu*((double)(vi2[id1[index]]-vi1[id1[index]])));
00065 vo[id2[index]]=vi1[id2[index]]+(long)(mu*((double)(vi2[id2[index]]-vi1[id2[index]])));
00066 }
00067
00068 static double c_angle(ivector p1, ivector p2, ivector p3){
00069 vector d1,d2;
00070 VECSUB(p1,p2,d1)
00071 VECSUB(p3,p2,d2)
00072 normalize(d1); normalize(d2);
00073 return DOT(d1,d2);
00074 }
00075
00076 static void SplitFaceAtVoxelPlane(long o, long i, long c,
00077 tvertex *v, tface *f,
00078 tvertex *v0, tvertex *v1, tvertex *v2, tface *fi,
00079 long p, long index,
00080 UC *oid1, US *fid1, UC *oid2, US *fid2,
00081 long *n1, long *n2){
00082 long vp,fp,fa,fb,i1,i2,i3,va,vb,i1i,i2i,i3i;
00083 tvertex *vl,*vr,*vrr;
00084 double uu,vv,ww,uu1,vv1,ww1,uui1,vvi1,wwi1,uui2,vvi2,wwi2,uui3,vvi3,wwi3;
00085 vector norm,normm,norm1,norm2,norm3;
00086 vp=Object[o].NoTraceVertices;
00087 fp=Object[o].NoTraceFaces;
00088 va=vp; vb=vp+1;
00089 fa=fp; fb=fp+1;
00090
00091 if(c == 3 || c == 4 || c == 5 || c == 13 || c == 14 || c == 15){
00092 if (c == 3 || c == 13){vl = v2; vr=v1; i1=0; i2=1; i3=2;}
00093 else if (c == 4 || c == 14){vl = v0; vr=v2; i1=1; i2=2; i3=0;}
00094 else if (c == 5 || c == 15){vl = v1; vr=v0; i1=2; i2=0; i3=1;}
00095
00096 i1i=f[i].V[i1]; i2i=f[i].V[i2]; i3i=f[i].V[i3];
00097 IntersectPlane(p,index,vl->ip,vr->ip, v[va].ip);
00098 f[i].V[0]=i1i; f[i].V[1]=i2i; f[i].V[2]=va;
00099 f[fa].V[0]=i1i; f[fa].V[1]=va; f[fa].V[2]=i3i;
00100 f[fa].o=f[i].o;
00101 f[fa].f=f[i].f;
00102 if(c == 3 || c == 4 || c == 5){
00103 oid1[*n1] = o; fid1[*n1] = fa; *n1 = (*n1) + 1;
00104 oid2[*n2] = o; fid2[*n2] = i; *n2 = (*n2) + 1;
00105 }
00106 else{
00107 oid1[*n1] = o; fid1[*n1] = i; *n1 = (*n1) + 1;
00108 oid2[*n2] = o; fid2[*n2] = fa; *n2 = (*n2) + 1;
00109 }
00110 vp += 1; fp += 1;
00111 }
00112 else {
00113 if (c == 6 || c == 10){vl=v0; vr=v1; vrr=v2; i1=0; i2=1; i3=2;}
00114 else if(c == 7 || c == 11){vl=v1; vr=v2; vrr=v0; i1=1; i2=2; i3=0;}
00115 else if(c == 8 || c == 12){vl=v2; vr=v0; vrr=v1; i1=2; i2=0; i3=1;}
00116 i1i=f[i].V[i1]; i2i=f[i].V[i2]; i3i=f[i].V[i3];
00117 IntersectPlane(p,index,vl->ip,vr->ip, v[va].ip);
00118 IntersectPlane(p,index,vl->ip,vrr->ip, v[vb].ip);
00119 f[i].V[0]=i1i; f[i].V[1]=va; f[i].V[2]=vb;
00120 if(c_angle(v[i3i].ip,v[vb].ip,v[va].ip) >= c_angle(v[vb].ip,v[va].ip,v[i2i].ip)){
00121 f[fa].V[0]=i3i; f[fa].V[1]=vb; f[fa].V[2]=va;
00122 f[fb].V[0]=i2i; f[fb].V[1]=i3i; f[fb].V[2]=va;
00123 }
00124 else{
00125 f[fa].V[0]=i3i; f[fa].V[1]=vb; f[fa].V[2]=i2i;
00126 f[fb].V[0]=i2i; f[fb].V[1]=vb; f[fb].V[2]=va;
00127 }
00128 f[fa].o=f[i].o;
00129 f[fa].f=f[i].f;
00130 f[fb].o=f[i].o;
00131 f[fb].f=f[i].f;
00132 if(c == 6 || c == 7 || c == 8){
00133 oid1[*n1] = o; fid1[*n1] = i; *n1 = (*n1) + 1;
00134 oid2[*n2] = o; fid2[*n2] = fa; *n2 = (*n2) + 1;
00135 oid2[*n2] = o; fid2[*n2] = fb; *n2 = (*n2) + 1;
00136 }
00137 else{
00138 oid1[*n1] = o; fid1[*n1] = fb; *n1 = (*n1) + 1;
00139 oid1[*n1] = o; fid1[*n1] = fa; *n1 = (*n1) + 1;
00140 oid2[*n2] = o; fid2[*n2] = i; *n2 = (*n2) + 1;
00141 }
00142
00143 vp += 2; fp+=2;
00144 }
00145 Object[o].NoTraceVertices = vp;
00146 Object[o].NoTraceFaces = fp;
00147 }
00148
00149 #define IN_PLANE(point,plane) (point == plane)
00150 #define IN_LESS_VOXEL(point,plane) (point < plane)
00151 #define IN_GREATER_VOXEL(point,plane) (point > plane)
00152 #define IN_LESS_EQUAL_VOXEL(point,plane) (point <= plane)
00153 #define IN_GREATER_EQUAL_VOXEL(point,plane) (point >= plane)
00154
00155 static long FaceIntersectVoxelPlane(tvertex *v0, tvertex *v1, tvertex *v2, long p, long index, UC *vxi){
00156 long p0,p1,p2;
00157
00158
00159 p0=(long)(v0->ip[index]);
00160 p1=(long)(v1->ip[index]);
00161 p2=(long)(v2->ip[index]);
00162 if(IN_LESS_EQUAL_VOXEL(p0,p) && IN_LESS_EQUAL_VOXEL(p1,p) && IN_LESS_EQUAL_VOXEL(p2,p)){
00163 *vxi = 1;
00164 return 0;
00165 }
00166 else if(IN_GREATER_EQUAL_VOXEL(p0,p) && IN_GREATER_EQUAL_VOXEL(p1,p) && IN_GREATER_EQUAL_VOXEL(p2,p)){
00167 *vxi = 2;
00168 return 0;
00169 }
00170 else{
00171
00172 if (IN_PLANE(p0,p)){if(IN_LESS_VOXEL(p2,p))*vxi = 3; else *vxi = 13; return 1;}
00173 else if(IN_PLANE(p1,p)){if(IN_LESS_VOXEL(p0,p))*vxi = 4; else *vxi = 14; return 1;}
00174 else if(IN_PLANE(p2,p)){if(IN_LESS_VOXEL(p1,p))*vxi = 5; else *vxi = 15; return 1;}
00175
00176 else if(IN_LESS_VOXEL(p0,p)){
00177 if (IN_LESS_VOXEL(p1,p)){*vxi = 12; return 2;}
00178 else if(IN_LESS_VOXEL(p2,p)){*vxi = 11; return 2;}
00179 else {*vxi = 6; return 2;}
00180 }
00181 else if(IN_LESS_VOXEL(p1,p)){
00182 if (IN_LESS_VOXEL(p2,p)){*vxi = 10; return 2;}
00183 else if(IN_LESS_VOXEL(p0,p)){*vxi = 12; return 2;}
00184 else {*vxi = 7; return 2;}
00185 }
00186 else if(IN_LESS_VOXEL(p2,p)){
00187 if (IN_LESS_VOXEL(p0,p)){*vxi = 11; return 2;}
00188 else if(IN_LESS_VOXEL(p1,p)){*vxi = 10; return 2;}
00189 else {*vxi = 8; return 2;}
00190 }
00191 }
00192
00193 * vxi = 0;
00194 return 0;
00195 }
00196
00197 static BOOL SplitVoxel(node *np, node *na, node *nb, long p, long index){
00198
00199 long i,nnp,nx,n1,n2,o,f,c,sz,xvf,nl,nr,ns,ng;
00200 tface *F;
00201 tvertex *V,*v0,*v1,*v2;
00202 nnp=np->n;
00203
00204
00205 for(i=0;i<3;i++){
00206 na->mi[i]=nb->mi[i]=np->mi[i];
00207 na->ma[i]=nb->ma[i]=np->ma[i];
00208 }
00209 na->ma[index]=p;
00210 nb->mi[index]=p;
00211
00212 for(i=0;i<ObjectCount;i++)ObjectXlist[i]=0;
00213 for(i=0;i<nnp;i++){
00214 o = (long)(*(np->oid+i));
00215 f = (long)(*(np->fid+i));
00216 F=(Object[o].Ftracebase+f);
00217 V=Object[o].Vtracebase;
00218 v0=(V + F->V[0]);
00219 v1=(V + F->V[1]);
00220 v2=(V + F->V[2]);
00221
00222 ObjectXlist[o] += FaceIntersectVoxelPlane(v0,v1,v2,p,index,(np->vxi+i));
00223
00224 }
00225
00226
00227 for(i=0,nx=0;i<ObjectCount;i++)if((xvf=ObjectXlist[i]) > 0){
00228 sz=(Object[i].NoTraceVertices+xvf)*(long)sizeof(tvertex);
00229 if((V=(tvertex *)X__Realloc(Object[i].Vtracebase,sz)) == NULL)goto FAILED;
00230 Object[i].Vtracebase=V;
00231 sz=(Object[i].NoTraceFaces+xvf)*(long)sizeof(tface);
00232 if((F=(tface *)X__Realloc(Object[i].Ftracebase,sz)) == NULL)goto FAILED;
00233 Object[i].Ftracebase=F;
00234 nx += xvf;
00235 }
00236
00237
00238
00239 ng=nnp+nx;
00240
00241 if(ng > 0){
00242 if((na->oid=(UC *)X__Malloc(sizeof(UC)*ng)) == NULL)goto FAILED;
00243 if((na->fid=(US *)X__Malloc(sizeof(US)*ng)) == NULL)goto FAILED;
00244 if((na->vxi=(UC *)X__Malloc(sizeof(UC)*ng)) == NULL)goto FAILED;
00245 if((nb->oid=(UC *)X__Malloc(sizeof(UC)*ng)) == NULL)goto FAILED;
00246 if((nb->fid=(US *)X__Malloc(sizeof(US)*ng)) == NULL)goto FAILED;
00247 if((nb->vxi=(UC *)X__Malloc(sizeof(UC)*ng)) == NULL)goto FAILED;
00248 for(i=0;i<ng;i++){na->oid[i]=999,na->fid[i]=999,na->vxi[i]=999;nb->oid[i]=666,nb->fid[i]=666,nb->vxi[i]=666;}
00249 }
00250
00251 nl=nr=ns=0;
00252 for(i=0,n1=0,n2=0;i<nnp;i++){
00253 c = (long)(*(np->vxi+i));
00254 o = (long)(*(np->oid+i));
00255 f = (long)(*(np->fid+i));
00256 if(c == 1){
00257 *(na->fid+n1)=f;
00258 *(na->oid+n1)=o; n1++;
00259 nl++;
00260 }
00261 else if(c == 2){
00262 *(nb->fid+n2)=f;
00263 *(nb->oid+n2)=o; n2++;
00264 nr++;
00265 }
00266 else{
00267 F=(Object[o].Ftracebase+f);
00268 V=Object[o].Vtracebase;
00269 v0=(V + F->V[0]);
00270 v1=(V + F->V[1]);
00271 v2=(V + F->V[2]);
00272 SplitFaceAtVoxelPlane(o,f,c,V,Object[o].Ftracebase,v0,v1,v2,F,p,index,na->oid,na->fid,nb->oid,nb->fid,&n1,&n2);
00273 ns++;
00274 }
00275 }
00276
00277
00278 if(ng > 0 && n1 == 0){
00279 X__Free(na->oid); na->oid=NULL;
00280 X__Free(na->fid); na->fid=NULL;
00281 X__Free(na->vxi); na->vxi=NULL;
00282 }
00283 else if(n1 > 0){
00284 na->oid=(UC *)X__Realloc(na->oid,sizeof(UC)*n1);
00285 na->vxi=(UC *)X__Realloc(na->vxi,sizeof(UC)*n1);
00286 na->fid=(US *)X__Realloc(na->fid,sizeof(US)*n1);
00287 }
00288 if(ng > 0 && n2 == 0){
00289 X__Free(nb->oid); nb->oid=NULL;
00290 X__Free(nb->fid); nb->fid=NULL;
00291 X__Free(nb->vxi); nb->vxi=NULL;
00292 }
00293 if(n2 > 0){
00294 nb->oid=(UC *)X__Realloc(nb->oid,sizeof(UC)*n2);
00295 nb->vxi=(UC *)X__Realloc(nb->vxi,sizeof(UC)*n2);
00296 nb->fid=(US *)X__Realloc(nb->fid,sizeof(US)*n2);
00297 }
00298
00299 if(np->oid != NULL)X__Free(np->oid); np->oid=NULL;
00300 if(np->fid != NULL)X__Free(np->fid); np->fid=NULL;
00301 if(np->vxi != NULL)X__Free(np->vxi); np->vxi=NULL;
00302 na->n=n1;
00303 nb->n=n2;
00304
00305 np->n=0;
00306 return OK;
00307 FAILED:
00308 return FAIL;
00309 }
00310
00311 static int MakeVoxels(node *np, int level){
00312 static long i,j,k,o,f,n;
00313 static double x,y,z,an;
00314 static tvertex *v,*v0,*v1,*v2;
00315 static tface *F;
00316 static vector p;
00317 static node Nd[6];
00318 RenderYield();
00319 if(R_terminator() == FAIL)longjmp(x_buf,-1);
00320
00321 if(level > threshold_r)return OK;
00322 if(np->n < threshold_f)return OK;
00323 if((np->ma[0]-np->mi[0]) < threshold_z ||
00324 (np->ma[1]-np->mi[1]) < threshold_z ||
00325 (np->ma[2]-np->mi[2]) < threshold_z)return OK;
00326
00327
00328
00329
00330
00331
00332 #if 0
00333 x=(double)(np->mi[0]+np->ma[0])*0.5;
00334 y=(double)(np->mi[1]+np->ma[1])*0.5;
00335 z=(double)(np->mi[2]+np->ma[2])*0.5;
00336 #else
00337 {
00338
00339
00340
00341 long ds,ip,md[3],mxx[3]={BIGP,BIGP,BIGP};
00342 tvertex *vid[3]={NULL,NULL,NULL};
00343 md[0]=(np->mi[0]+np->ma[0])/2;
00344 md[1]=(np->mi[1]+np->ma[1])/2;
00345 md[2]=(np->mi[2]+np->ma[2])/2;
00346 for(i=0;i<np->n;i++){
00347 o = (long)(*(np->oid+i)); f = (long)(*(np->fid+i));
00348 F=(Object[o].Ftracebase+f); v=Object[o].Vtracebase;
00349 for(j=0;j<3;j++){
00350 v0=(v + F->V[j]);
00351 for(k=0;k<3;k++){
00352 ip=v0->ip[k];
00353 if(ip > np->mi[k]+16 && ip < np->ma[k]-16 & (ds=abs(ip - md[k])) < mxx[k]){
00354 mxx[k]=ds; vid[k]=v0;
00355 }
00356 }
00357 }
00358 }
00359 for(k=0;k<3;k++){
00360 if(vid[k] != NULL){
00361 ip=vid[k]->ip[k];
00362 if(ip > np->mi[k]+128 && ip < np->ma[k]-128)mxx[k]=ip; else mxx[k]=md[k];
00363 }
00364 }
00365 x=(double)mxx[0]; y=(double)mxx[1]; z=(double)mxx[2];
00366 }
00367 #endif
00368
00369
00370
00371
00372 if(level > level_depth_max)level_depth_max=level;
00373
00374 for(i=0;i<6;i++){
00375 Nd[i].n=0;
00376 Nd[i].oid=NULL;
00377 Nd[i].fid=NULL;
00378 Nd[i].vxi=NULL;
00379 }
00380
00381 level += 1;
00382 for(i=0;i<8;i++){
00383 if((np->octree[i]=(node *)X__Malloc(sizeof(node))) == NULL)return FAIL;
00384 np->octree[i]->n=0;
00385 np->octree[i]->oid=NULL;
00386 np->octree[i]->fid=NULL;
00387 np->octree[i]->vxi=NULL;
00388 for(j=0;j<8;j++){
00389 np->octree[i]->octree[j]=NULL;
00390 }
00391 kcount++;
00392 np->octree[i]->id=kcount;
00393 np->octree[i]->last=np;
00394 np->octree[i]->level=level;
00395 }
00396 if(trace_partition == 0){
00397
00398 if(!SplitVoxel(np, &Nd[0], &Nd[1],(long)z,2))return FAIL;
00399 if(!SplitVoxel(&Nd[0],&Nd[2],&Nd[3],(long)x,0))return FAIL;
00400 if(!SplitVoxel(&Nd[1],&Nd[4],&Nd[5],(long)x,0))return FAIL;
00401 if(!SplitVoxel(&Nd[2],np->octree[0],np->octree[1],(long)y,1))return FAIL;
00402 if(!SplitVoxel(&Nd[3],np->octree[2],np->octree[3],(long)y,1))return FAIL;
00403 if(!SplitVoxel(&Nd[4],np->octree[4],np->octree[5],(long)y,1))return FAIL;
00404 if(!SplitVoxel(&Nd[5],np->octree[6],np->octree[7],(long)y,1))return FAIL;
00405 } else {
00406 if(!PartitionVoxel(np, &Nd[0], &Nd[1],(long)z,2))return FAIL;
00407 if(!PartitionVoxel(&Nd[0],&Nd[2],&Nd[3],(long)x,0))return FAIL;
00408 if(!PartitionVoxel(&Nd[1],&Nd[4],&Nd[5],(long)x,0))return FAIL;
00409 if(!PartitionVoxel(&Nd[2],np->octree[0],np->octree[1],(long)y,1))return FAIL;
00410 if(!PartitionVoxel(&Nd[3],np->octree[2],np->octree[3],(long)y,1))return FAIL;
00411 if(!PartitionVoxel(&Nd[4],np->octree[4],np->octree[5],(long)y,1))return FAIL;
00412 if(!PartitionVoxel(&Nd[5],np->octree[6],np->octree[7],(long)y,1))return FAIL;
00413 }
00414
00415 MakeVoxels(np->octree[0],level);
00416 MakeVoxels(np->octree[1],level);
00417 MakeVoxels(np->octree[2],level);
00418 MakeVoxels(np->octree[3],level);
00419 MakeVoxels(np->octree[4],level);
00420 MakeVoxels(np->octree[5],level);
00421 MakeVoxels(np->octree[6],level);
00422 MakeVoxels(np->octree[7],level);
00423 return OK;
00424 }
00425
00426 int buildBST(void){
00427 char temp[256];
00428 long i,j,k,l,coord,nv=0;
00429 long divisions;
00430 tvertex *v;
00431 tface *f;
00432 nfaces=0; kcount=0; level_depth_max=0;
00433 voxel_xmin=voxel_ymin=voxel_zmin=BIGP;
00434 voxel_xmax=voxel_ymax=voxel_zmax=BIGN;
00435 Render_Message(31,0,NULL);
00436 ROOT=NULL;
00437 if(ObjectCount > 0)for(i=0;i<ObjectCount;i++){
00438 if(!Object[i].in_use)continue;
00439 Object[i].NoTraceVertices=Object[i].NoVertices;
00440 Object[i].NoTraceFaces=Object[i].NoFaces;
00441 nfaces += Object[i].NoTraceFaces;
00442 nv += Object[i].NoTraceVertices;
00443
00444 if((Object[i].Vtracebase=(tvertex *)X__Malloc(Object[i].NoTraceVertices*sizeof(tvertex))) == NULL)return FAIL;
00445 for(j=0;j<Object[i].NoTraceVertices;j++){
00446 VECCOPY(Object[i].Vbase[j].ip,Object[i].Vtracebase[j].ip)
00447 }
00448 if((Object[i].Ftracebase=(tface *)X__Malloc(Object[i].NoTraceFaces*sizeof(tface))) == NULL)return FAIL;
00449 for(j=0;j<Object[i].NoTraceFaces;j++){
00450 VECCOPY(Object[i].Fbase[j].V,Object[i].Ftracebase[j].V)
00451 Object[i].Ftracebase[j].o=i;
00452 Object[i].Ftracebase[j].f=j;
00453 {
00454 vector v1,v2,n;
00455 VECSUB(Object[i].Vtracebase[Object[i].Ftracebase[j].V[1]].ip,
00456 Object[i].Vtracebase[Object[i].Ftracebase[j].V[0]].ip,v1)
00457 VECSUB(Object[i].Vtracebase[Object[i].Ftracebase[j].V[2]].ip,
00458 Object[i].Vtracebase[Object[i].Ftracebase[j].V[0]].ip,v2)
00459 CROSS(v1,v2,n)
00460 normalize(n);
00461 VECCOPY(n,Object[i].Ftracebase[j].n)
00462 }
00463 }
00464 }
00465 if(nfaces == 0)return 0;
00466 if((ROOT=(node *)X__Malloc(sizeof(node))) == NULL)return FAIL;
00467 ROOT->n=0;
00468 if((ROOT->oid=(UC *)X__Malloc(sizeof(UC ) * nfaces)) == NULL){
00469 destroyBST(ROOT); return FAIL;
00470 }
00471 if((ROOT->fid=(US *)X__Malloc(sizeof(US ) * nfaces)) == NULL){
00472 destroyBST(ROOT); return FAIL;
00473 }
00474 if((ROOT->vxi=(UC *)X__Malloc(sizeof(UC ) * nfaces)) == NULL){
00475 destroyBST(ROOT); return FAIL;
00476 }
00477 ROOT->n=nfaces;
00478 if((ObjectXlist=(long *)X__Malloc(sizeof(long)*ObjectCount)) == NULL)return FAIL;
00479 for(i=0,k=0;i<ObjectCount;i++){
00480 if(!Object[i].in_use)continue;
00481 f=Object[i].Ftracebase;
00482 for(j=0;j<Object[i].NoTraceFaces;j++){
00483 *(ROOT->oid+k)=(UC)i;
00484 *(ROOT->fid+k)=(US)j;
00485 *(ROOT->vxi+k)=(UC)0;
00486 k++;
00487 f++;
00488 }
00489 }
00490 for(i=0;i<8;i++)ROOT->octree[i]=NULL;
00491 ROOT->mi[0]=ROOT->mi[1]=ROOT->mi[2]=BIGP;
00492 ROOT->ma[0]=ROOT->ma[1]=ROOT->ma[2]=BIGN;
00493 ROOT->id=kcount; ROOT->last=NULL;
00494 for(i=0,k=0;i<ObjectCount;i++){
00495 if(!Object[i].in_use)continue;
00496 v = Object[i].Vtracebase;
00497 for(j=0;j<Object[i].NoTraceVertices;j++){
00498 for(l=0;l<3;l++){
00499 if((coord=(long)(v->ip[l])) < ROOT->mi[l])ROOT->mi[l]=coord;
00500 if( coord > ROOT->ma[l])ROOT->ma[l]=coord;
00501 }
00502 k++;
00503 v++;
00504 }
00505 }
00506 if(k == 0)return 0;
00507 for(i=0;i<3;i++){
00508 ROOT->mi[i] -= 2;
00509 ROOT->ma[i] += 2;
00510 }
00511 longest_ray = max((ROOT->ma[1]-ROOT->mi[1]),(ROOT->ma[0]-ROOT->mi[0]));
00512 longest_ray = max(longest_ray,(ROOT->ma[2]-ROOT->mi[2]));
00513 threshold_r=trace_depth;
00514 threshold_f=trace_face_count_target;
00515 divisions = (long)(pow(2.0,(double)threshold_r));
00516 threshold_z=(long)(longest_ray/divisions);
00517 longest_ray *= 1.4142;
00518
00519
00520
00521
00522
00523
00524 if(setjmp(x_buf) != 0 || MakeVoxels(ROOT,0) == FAIL){
00525 destroyBST(ROOT);
00526 X__Free(ObjectXlist);
00527 return FAIL;
00528 }
00529 X__Free(ObjectXlist);
00530 i=nfaces;
00531 nfaces=0;
00532 maxfaces=0;
00533 minfaces=65536*65536;
00534 eliminateDuplicatesInBST(ROOT);
00535 countBST(ROOT);
00536
00537
00538 sprintf(temp,
00539 "Scene: F=%ld V=%ld [Dp=%ld Th=%ld F/v=%ld] Size %ld(%ld) [Vox=%ld Fc=%ld]",
00540 i,nv,level_depth_max,threshold_f,maxfaces,
00541 max(min(voxel_xmax,voxel_ymax),voxel_zmax)/512,
00542 min(min(voxel_xmin,voxel_ymin),voxel_zmin)/512,
00543 kcount,nfaces);
00544 WindowedRenderInfo(temp);
00545
00546
00547
00548
00549
00550
00551 return 0;
00552 }
00553
00554 void freeBST(void){
00555 int i;
00556 if(ROOT != NULL)destroyBST(ROOT);
00557 if(ObjectCount > 0)for(i=0;i<ObjectCount;i++){
00558 if(!Object[i].in_use)continue;
00559 if(Object[i].Vtracebase != NULL)X__Free(Object[i].Vtracebase);
00560 Object[i].Vtracebase=NULL; Object[i].NoTraceVertices=0;
00561 if(Object[i].Ftracebase != NULL)X__Free(Object[i].Ftracebase);
00562 Object[i].Ftracebase=NULL; Object[i].NoTraceFaces=0;
00563 }
00564 }
00565
00566 static void destroyBST(node *np){
00567 if(np->octree[0] != NULL){destroyBST(np->octree[0]); np->octree[0]=NULL;}
00568 if(np->octree[1] != NULL){destroyBST(np->octree[1]); np->octree[1]=NULL;}
00569 if(np->octree[2] != NULL){destroyBST(np->octree[2]); np->octree[2]=NULL;}
00570 if(np->octree[3] != NULL){destroyBST(np->octree[3]); np->octree[3]=NULL;}
00571 if(np->octree[4] != NULL){destroyBST(np->octree[4]); np->octree[4]=NULL;}
00572 if(np->octree[5] != NULL){destroyBST(np->octree[5]); np->octree[5]=NULL;}
00573 if(np->octree[6] != NULL){destroyBST(np->octree[6]); np->octree[6]=NULL;}
00574 if(np->octree[7] != NULL){destroyBST(np->octree[7]); np->octree[7]=NULL;}
00575 if(np->fid != NULL){X__Free(np->fid); np->fid=NULL;}
00576 if(np->oid != NULL){X__Free(np->oid); np->oid=NULL;}
00577 if(np->vxi != NULL){X__Free(np->vxi); np->vxi=NULL;}
00578 X__Free(np); np=NULL;
00579 return;
00580 }
00581
00582 static void countBST(node *np){
00583 char temp[256];
00584 int i;
00585 if(np->ma[0]-np->mi[0] < voxel_xmin)voxel_xmin=np->ma[0]-np->mi[0];
00586 if(np->ma[1]-np->mi[1] < voxel_ymin)voxel_ymin=np->ma[1]-np->mi[1];
00587 if(np->ma[2]-np->mi[2] < voxel_zmin)voxel_zmin=np->ma[2]-np->mi[2];
00588 if(np->ma[0]-np->mi[0] > voxel_xmax)voxel_xmax=np->ma[0]-np->mi[0];
00589 if(np->ma[1]-np->mi[1] > voxel_ymax)voxel_ymax=np->ma[1]-np->mi[1];
00590 if(np->ma[2]-np->mi[2] > voxel_zmax)voxel_zmax=np->ma[2]-np->mi[2];
00591 if(np->octree[0] != NULL)countBST(np->octree[0]);
00592 if(np->octree[1] != NULL)countBST(np->octree[1]);
00593 if(np->octree[2] != NULL)countBST(np->octree[2]);
00594 if(np->octree[3] != NULL)countBST(np->octree[3]);
00595 if(np->octree[4] != NULL)countBST(np->octree[4]);
00596 if(np->octree[5] != NULL)countBST(np->octree[5]);
00597 if(np->octree[6] != NULL)countBST(np->octree[6]);
00598 if(np->octree[7] != NULL)countBST(np->octree[7]);
00599 if(np->fid != NULL){
00600 if(np->n > maxfaces)maxfaces=np->n;
00601 if(np->n < minfaces)minfaces=np->n;
00602 nfaces += np->n;
00603 }
00604 return;
00605 }
00606
00607 static void eliminateDuplicatesInBST(node *n){
00608 if(n->n > 0){
00609 static long i,o,f,ft,pfid,poid,c;
00610 US *next;
00611 pfid=-1,poid=-1; c=0;
00612 if((next=(US *)X__Malloc(sizeof(US)*n->n)) == NULL)return;
00613 for(i=0;i<n->n;i++){
00614 o=n->oid[i];
00615 f=n->fid[i];
00616 ft=(Object[o].Ftracebase + f)->f;
00617 if(!(ft == pfid && o == poid))next[c++]=i;
00618 pfid=ft; poid=o;
00619 }
00620 if(c < n->n)for(i=0;i<c;i++){
00621 n->oid[i]=n->oid[next[i]];
00622 n->fid[i]=n->fid[next[i]];
00623 }
00624 n->n=c;
00625 X__Free(next);
00626 }
00627 if(n->octree[0] != NULL)eliminateDuplicatesInBST(n->octree[0]);
00628 if(n->octree[1] != NULL)eliminateDuplicatesInBST(n->octree[1]);
00629 if(n->octree[2] != NULL)eliminateDuplicatesInBST(n->octree[2]);
00630 if(n->octree[3] != NULL)eliminateDuplicatesInBST(n->octree[3]);
00631 if(n->octree[4] != NULL)eliminateDuplicatesInBST(n->octree[4]);
00632 if(n->octree[5] != NULL)eliminateDuplicatesInBST(n->octree[5]);
00633 if(n->octree[6] != NULL)eliminateDuplicatesInBST(n->octree[6]);
00634 if(n->octree[7] != NULL)eliminateDuplicatesInBST(n->octree[7]);
00635 return;
00636
00637 }
00638
00639 #define TOL 0.00001
00640
00641
00642
00643
00644
00645 static BOOL RayIntersectVoxelSides(node *n, double ddn, vector p1, vector d, vector p2, long i, long j, long k){
00646 double ppn,u,v,mu;
00647 if((p1[i] <= n->mi[i] && p2[i] >= n->mi[i]) ||
00648 (p2[i] <= n->mi[i] && p1[i] >= n->mi[i])){
00649 ppn=n->mi[i]-p1[i]; mu=ppn/ddn;
00650 u=p1[j]+mu*d[j];
00651 v=p1[k]+mu*d[k];
00652 if(u >= n->mi[j] && u <= n->ma[j] && v >= n->mi[k] && v <= n->ma[k])return TRUE;
00653 }
00654 if((p1[i] <= n->ma[i] && p2[i] >= n->ma[i]) ||
00655 (p2[i] <= n->ma[i] && p1[i] >= n->ma[i])){
00656 ppn=n->ma[i]-p1[i]; mu=ppn/ddn;
00657 u=p1[j]+mu*d[j];
00658 v=p1[k]+mu*d[k];
00659 if(u >= n->mi[j] && u <= n->ma[j] && v >= n->mi[k] && v <= n->ma[k])return TRUE;
00660 }
00661 return FALSE;
00662 }
00663
00664 static BOOL RayThroughVoxel(node *n, vector p1, vector d, vector p2){
00665 double ddn,ppn,u,v;
00666 if(p1[0] < n->mi[0] && p2[0] < n->mi[0])return FALSE;
00667 if(p1[1] < n->mi[1] && p2[1] < n->mi[1])return FALSE;
00668 if(p1[2] < n->mi[2] && p2[2] < n->mi[2])return FALSE;
00669 if(p1[0] > n->ma[0] && p2[0] > n->ma[0])return FALSE;
00670 if(p1[1] > n->ma[1] && p2[1] > n->ma[1])return FALSE;
00671 if(p1[2] > n->ma[2] && p2[2] > n->ma[2])return FALSE;
00672 if(p1[0] >= n->mi[0] && p1[0] <= n->ma[0] &&
00673 p1[1] >= n->mi[1] && p1[1] <= n->ma[1] &&
00674 p1[2] >= n->mi[2] && p1[2] <= n->ma[2])return TRUE;
00675 if(p2[0] >= n->mi[0] && p2[0] <= n->ma[0] &&
00676 p2[1] >= n->mi[1] && p2[1] <= n->ma[1] &&
00677 p2[2] >= n->mi[2] && p2[2] <= n->ma[2])return TRUE;
00678 ddn=d[0]; if(fabs(ddn) > TOL)if(RayIntersectVoxelSides(n,ddn,p1,d,p2,0,1,2))return TRUE;
00679 ddn=d[1]; if(fabs(ddn) > TOL)if(RayIntersectVoxelSides(n,ddn,p1,d,p2,1,2,0))return TRUE;
00680 ddn=d[2]; if(fabs(ddn) > TOL)if(RayIntersectVoxelSides(n,ddn,p1,d,p2,2,0,1))return TRUE;
00681 return FALSE;
00682 }
00683
00684 static void FeelerHitsFace(node *np, vector p, vector d, vector pl, double ld,
00685 long obj, long *glassc, BOOL *hit, BOOL *abort){
00686 int i,j,o;
00687 face *f;
00688 long ft;
00689 vertex *v;
00690 matl *mat;
00691 double depth;
00692 unsigned char mattr;
00693 long glass = 0;
00694 node *nx;
00695 if(*abort)return;
00696
00697
00698 if(!RayThroughVoxel(np,p,d,pl))return;
00699
00700 if(np->n > 0){
00701 for(i=0;i<np->n;i++){
00702 o=(int)(*(np->oid + i));
00703 if(!Object[o].cast_shadow)continue;
00704 if(!Object[obj].self_shadow && obj == o)continue;
00705 ft=(Object[o].Ftracebase + (int)(*(np->fid + i)))->f;
00706 f=Object[o].Fbase + (int)(ft);
00707 v=Object[o].Vbase;
00708 if(f->ffmat >= 0 && f->ffmat < Object[o].NoMats){
00709 if(Object[o].Tbase != NULL){
00710 mat=(Object[o].Tbase + f->ffmat);
00711 mattr=mat->transp;
00712 }
00713 else mattr=1;
00714 }
00715 else mattr=1;
00716
00717 if(R_intersect_face(p,d,
00718 (v + f->V[0])->p,(v + f->V[1])->p,(v + f->V[2])->p,
00719 f->n,&depth,32.0) && (depth < ld)){
00720 if(mattr > 1)glassc++;
00721 else{
00722 *abort=TRUE;
00723 *hit=TRUE;
00724 return;
00725 }
00726 }
00727 }
00728 }
00729 if((nx=np->octree[0]) != NULL)FeelerHitsFace(nx,p,d,pl,ld,obj,glassc,hit,abort); else return;
00730 if((nx=np->octree[1]) != NULL)FeelerHitsFace(nx,p,d,pl,ld,obj,glassc,hit,abort);
00731 if((nx=np->octree[2]) != NULL)FeelerHitsFace(nx,p,d,pl,ld,obj,glassc,hit,abort);
00732 if((nx=np->octree[3]) != NULL)FeelerHitsFace(nx,p,d,pl,ld,obj,glassc,hit,abort);
00733 if((nx=np->octree[4]) != NULL)FeelerHitsFace(nx,p,d,pl,ld,obj,glassc,hit,abort);
00734 if((nx=np->octree[5]) != NULL)FeelerHitsFace(nx,p,d,pl,ld,obj,glassc,hit,abort);
00735 if((nx=np->octree[6]) != NULL)FeelerHitsFace(nx,p,d,pl,ld,obj,glassc,hit,abort);
00736 if((nx=np->octree[7]) != NULL)FeelerHitsFace(nx,p,d,pl,ld,obj,glassc,hit,abort);
00737 return;
00738 }
00739
00740 short check_for_shadow(long obj, vector p, vector natp){
00741
00742 int i,j;
00743 vector d,pp;
00744 double ld,alpha;
00745 long glassc=0;
00746 BOOL abort,hit;
00747
00748 for(j=0;j<Nlights;j++)if(Lights[j].type != NOSHADOW &&
00749 Lights[j].type != DUMMYL){
00750 if(Lights[j].type == SPOTLIGHT && Lights[j].shadow_buffer != NULL)continue;
00751 VECSUB(Lights[j].p,p,d)
00752 if(DOT(p,natp)*DOT(d,natp) > 0)continue;
00753 ld=(double)((d[0]*d[0]) + (d[1]*d[1]) + (d[2]*d[2]));
00754 if(ld > 1.e-10){
00755 ld=sqrt(ld);
00756 VECSCALE((1.0/ld),d,d)
00757 if(Lights[j].type == SPOTLIGHT){
00758 if((alpha=DOT(d,Lights[j].d)) < Lights[j].dot2){
00759 continue;
00760 }
00761 }
00762 abort=FALSE;
00763 hit=FALSE;
00764 VECCOPY(p,pp)
00765
00766 FeelerHitsFace(ROOT,pp,d,Lights[j].p,ld,obj,&glassc,&hit,&abort);
00767 if(hit)return -1;
00768 }
00769 }
00770 return glassc;
00771 }
00772
00773 static void GetRayIntersectionFace(node *np, vector p, vector d,
00774 double *ld,
00775 long *closest_o, long *closest_f){
00776
00777
00778 int i,j,o,fi;
00779 face *f;
00780 long ft;
00781 vertex *v;
00782 double depth;
00783 node *nx;
00784 vector pl;
00785 VECSUM(p,(*ld)*d,pl)
00786 if(!RayThroughVoxel(np,p,d,pl))return;
00787 if(np->n > 0){
00788 for(i=0;i<np->n;i++){
00789 o=(int)(*(np->oid + i));
00790 ft=(Object[o].Ftracebase + (int)(*(np->fid + i)))->f;
00791 f=Object[o].Fbase + (fi=(int)(ft));
00792 v=Object[o].Vbase;
00793 if(R_intersect_face(p,d,
00794 (v + f->V[0])->p,(v + f->V[1])->p,(v + f->V[2])->p,
00795 f->n,&depth,32.0)){
00796 if(depth < *ld){
00797 *ld=depth;
00798 *ld=depth - 10.0;
00799 *closest_o = o;
00800 *closest_f = fi;
00801 }
00802 }
00803 }
00804 }
00805 if((nx=np->octree[0]) != NULL)GetRayIntersectionFace(nx,p,d,ld,closest_o,closest_f);
00806 if((nx=np->octree[1]) != NULL)GetRayIntersectionFace(nx,p,d,ld,closest_o,closest_f);
00807 if((nx=np->octree[2]) != NULL)GetRayIntersectionFace(nx,p,d,ld,closest_o,closest_f);
00808 if((nx=np->octree[3]) != NULL)GetRayIntersectionFace(nx,p,d,ld,closest_o,closest_f);
00809 if((nx=np->octree[4]) != NULL)GetRayIntersectionFace(nx,p,d,ld,closest_o,closest_f);
00810 if((nx=np->octree[5]) != NULL)GetRayIntersectionFace(nx,p,d,ld,closest_o,closest_f);
00811 if((nx=np->octree[6]) != NULL)GetRayIntersectionFace(nx,p,d,ld,closest_o,closest_f);
00812 if((nx=np->octree[7]) != NULL)GetRayIntersectionFace(nx,p,d,ld,closest_o,closest_f);
00813 return;
00814 }
00815
00816 BOOL trace_starting_ray(vector d, vector p,
00817 int *ob, int *fc, face **ff){
00818
00819
00820
00821 int o,q;
00822 double depth;
00823 o=-1;
00824 depth=(double)FARAWAY;
00825 GetRayIntersectionFace(ROOT,p,d,&depth,&o,&q);
00826 if(o < 0)return FALSE;
00827 *ff=(Object[o].Fbase + q);
00828 *fc=q;
00829 *ob=o;
00830 VECSCALE(depth,d,p)
00831 return TRUE;
00832 }
00833
00834 short trace_reflection_ray(vector p, vector d,
00835 double depth_max, double *colour,
00836 int at_o, face *at_f,
00837 long trace_reflection_depth,
00838 long trace_refraction_depth,
00839 long refractive_flag){
00840 int o=-1,q;
00841 face *f;
00842 vertex *v;
00843 double depth=longest_ray;
00844 TRY_START_AGAIN:
00845 o=-1;
00846 depth=longest_ray;
00847 VECSUM(p,128.0*d,p)
00848 GetRayIntersectionFace(ROOT,p,d,&depth,&o,&q);
00849 if(o < 0)return 0;
00850 f=(Object[o].Fbase + q);
00851 if(o == at_o && f == at_f){
00852
00853 goto TRY_START_AGAIN;
00854 }
00855 v=Object[o].Vbase;
00856 f=(Object[o].Fbase + q);
00857 depth_max=depth;
00858 if(trace_reflection_depth < trace_depth_max){
00859
00860 trace_reflection_depth++;
00861 GetSurfaceValue(o,f,v,p,d,
00862 colour,(colour+1),(colour+2),
00863 trace_reflection_depth,
00864 trace_refraction_depth,
00865 refractive_flag);
00866 }
00867 return 1;
00868 }
00869
00870 void trace_transmission_ray(vector p, vector d, vector n,
00871 int at_o, face *at_f,
00872 double depth_max, double *colour,
00873 long trace_reflection_depth,
00874 long trace_refraction_depth,
00875 long refractive_flag){
00876
00877
00878
00879
00880
00881 int o,q;
00882 vector pc;
00883 face *f;
00884 vertex *v;
00885 double depth;
00886 TRY_START_AGAIN:
00887 o=-1;
00888 depth=longest_ray;
00889
00890 VECSUM(p,128.0*d,p)
00891 GetRayIntersectionFace(ROOT,p,d,&depth,&o,&q);
00892 if(o < 0)return;
00893 f=(Object[o].Fbase + q);
00894 if(o == at_o && f == at_f){
00895
00896 goto TRY_START_AGAIN;
00897 }
00898 v=Object[o].Vbase;
00899 if(trace_refraction_depth < trace_depth_max){
00900 trace_refraction_depth++;
00901 GetSurfaceValue(o,f,v,p,d,
00902 colour,(colour+1),(colour+2),
00903 trace_reflection_depth,
00904 trace_refraction_depth,
00905 refractive_flag);
00906 }
00907 return;
00908 }
00909
00910
00911 void trace_refraction_ray(vector p, vector d, vector n,
00912 int at_o, face *at_f,
00913 double depth_max, double *colour, int refx,
00914 long trace_reflection_depth,
00915 long trace_refraction_depth,
00916 long refractive_flag){
00917
00918
00919
00920
00921
00922 int o,q;
00923 vector pc,temp,qq;
00924 face *f;
00925 vertex *v;
00926 double depth,ddn;
00927 vector dp,gp;
00928 double pdotn,ddotn,mu,qnorm;
00929 unsigned char red,green,blue;
00930
00931 ddn=DOT(d,n);
00932 if(ddn > 0.0){
00933 ddn = -ddn; n[0] = -n[0]; n[1] = -n[1]; n[2] = -n[2];
00934 }
00935 VECSCALE(ddn,n,temp)
00936 VECSUB(d,temp,temp)
00937 if(refractive_flag == 0){
00938 VECSCALE(1000.0/(double)refx,temp,qq)
00939 }
00940 else{
00941 VECSCALE((double)refx/1000.0,temp,qq)
00942 }
00943 refractive_flag ^= 1;
00944 qnorm=qq[0]*qq[0]+qq[1]*qq[1]+qq[2]*qq[2];
00945 if(qnorm > 1.0){
00946 VECSCALE(sqrt(qnorm-1.0),n,temp)
00947 VECSUM(qq,temp,d)
00948 ddn=d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
00949 ddn=sqrt(ddn);
00950 VECSCALE((1.0/ddn),d,d)
00951 }
00952 else{
00953 VECSCALE(sqrt(1.0-qnorm),n,temp)
00954 VECSUB(qq,temp,d)
00955 ddn=d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
00956 ddn=sqrt(ddn);
00957 VECSCALE((1.0/ddn),d,d)
00958 }
00959
00960 if(R_Nground > 0 && fabs(ddotn=dot(Ground.n,d)) > 1.e-3){
00961 VECSUB(Ground.p,p,dp)
00962 pdotn=DOT(Ground.n,dp);
00963 mu=pdotn/ddotn;
00964 if(mu > 0.0){
00965 vecscale(mu,d,gp);
00966 vecsum(p,gp,gp);
00967 GetGroundLight(gp,&colour[0],&colour[1],&colour[2]);
00968 depth_max = mu;
00969 }
00970 else goto NEXTBLOCK;
00971 }
00972 else{
00973 NEXTBLOCK:
00974 colour[0] = (double)Sky.Zenith[0];
00975 colour[1] = (double)Sky.Zenith[1];
00976 colour[2] = (double)Sky.Zenith[2];
00977
00978 if(Sky.type == SKYMAPPED){
00979 ddotn=d[2];
00980 if(fabs(ddotn) > 1.e-2){
00981 vecsub(Sky.map.p,p,dp);
00982 pdotn=dp[2];
00983 mu=pdotn/ddotn;
00984 vecscale(fabs(mu),d,gp);
00985 vecsum(p,gp,gp);
00986 MapFromProjection(&Sky.map,TILE,EOPAQUE,gp,&colour[0],&colour[1],&colour[2]);
00987 }
00988 }
00989 else if(Sky.type == SKYCUBE){
00990 MapEnvironmentInDirection(d,&colour[0],&colour[1],&colour[2],&Sky.map);
00991 }
00992 }
00993 TRY_START_AGAIN:
00994 o=-1;
00995 depth=longest_ray;
00996
00997 VECSUM(p,128.0*d,p)
00998 GetRayIntersectionFace(ROOT,p,d,&depth,&o,&q);
00999 if(o < 0)return;
01000 f=(Object[o].Fbase + q);
01001 if(o == at_o && f == at_f){
01002
01003 goto TRY_START_AGAIN;
01004 }
01005 v=Object[o].Vbase;
01006 if(trace_refraction_depth < trace_depth_max){
01007 trace_refraction_depth++;
01008 GetSurfaceValue(o,f,v,p,d,
01009 colour,(colour+1),(colour+2),
01010 trace_reflection_depth,
01011 trace_refraction_depth,
01012 refractive_flag);
01013 }
01014 return;
01015 }
01016
01018
01019 #if 0
01020
01021 static void printBST(node *n){
01022 if(debug == NULL)return;
01023 if(n->n > 0){
01024 static int i,o,f,ft;
01025 fprintf(debug,"Voxel id=%5ld (Has %5ld Faces) (At level %5ld) Edges[%8ld][%8ld][%8ld]",n->id,n->n, n->level, n->ma[0]-n->mi[0],n->ma[1]-n->mi[1],n->ma[2]-n->mi[2]);
01026 if(n->last != NULL)fprintf(debug," -> %ld\n",n->last->id);
01027 else fprintf(debug," ROOT \n");
01028 for(i=0;i<n->n;i++){
01029 o=n->oid[i];
01030 f=n->fid[i];
01031 Object[o].Ftracebase[f].x = n->id;
01032 ft=(Object[o].Ftracebase + f)->f;
01033 fprintf(debug, "V%5ld F%3ld - (F)%6ld (O=%d) Maps to face %6ld\n",n->id,i,f,o,ft);
01034 }
01035 }
01036
01037 if(n->octree[0] != NULL)printBST(n->octree[0]);
01038 if(n->octree[1] != NULL)printBST(n->octree[1]);
01039 if(n->octree[2] != NULL)printBST(n->octree[2]);
01040 if(n->octree[3] != NULL)printBST(n->octree[3]);
01041 if(n->octree[4] != NULL)printBST(n->octree[4]);
01042 if(n->octree[5] != NULL)printBST(n->octree[5]);
01043 if(n->octree[6] != NULL)printBST(n->octree[6]);
01044 if(n->octree[7] != NULL)printBST(n->octree[7]);
01045 return;
01046 }
01047
01048 #endif
01049
01051
01052 static BOOL EdgeCrossBoxFaceX(ivector vi1, ivector vi2, long p,
01053 long ymin, long ymax, long zmin, long zmax){
01054 long d1,d2,vo1,vo2,imu;
01055 double mu;
01056 if((imu=vi2[0]-vi1[0]) == 0)return FALSE;
01057 d1=vi1[0]-p; d2=vi2[0]-p;
01058 if((double)d1*(double)d2 >= 0.0)return FALSE;
01059 mu=((double)(p-vi1[0]))/(double)imu;
01060 vo1=vi1[1]+(long)(mu*((double)(vi2[1]-vi1[1])));
01061 vo2=vi1[2]+(long)(mu*((double)(vi2[2]-vi1[2])));
01062 if(ymin <= vo1 && vo1 <= ymax && zmin <= vo2 && vo2 <= zmax)return TRUE;
01063 return FALSE;
01064 }
01065
01066 static BOOL EdgeCrossBoxFaceY(ivector vi1, ivector vi2, long p,
01067 long zmin, long zmax, long xmin, long xmax){
01068 long d1,d2,vo1,vo2,imu;
01069 double mu;
01070 if((imu=vi2[1]-vi1[1]) == 0)return FALSE;
01071 d1=vi1[1]-p; d2=vi2[1]-p;
01072 if((double)d1*(double)d2 >= 0.0)return FALSE;
01073 mu=((double)(p-vi1[1]))/(double)imu;
01074 vo1=vi1[2]+(long)(mu*((double)(vi2[2]-vi1[2])));
01075 vo2=vi1[0]+(long)(mu*((double)(vi2[0]-vi1[0])));
01076 if(zmin <= vo1 && vo1 <= zmax && xmin <= vo2 && vo2 <= xmax)return TRUE;
01077 return FALSE;
01078 }
01079
01080 static BOOL EdgeCrossBoxFaceZ(ivector vi1, ivector vi2, long p,
01081 long xmin, long xmax, long ymin, long ymax){
01082 long d1,d2,vo1,vo2,imu;
01083 double mu;
01084 if((imu=vi2[2]-vi1[2]) == 0)return FALSE;
01085 d1=vi1[2]-p; d2=vi2[2]-p;
01086 if((double)d1*(double)d2 >= 0.0)return FALSE;
01087 mu=((double)(p-vi1[2]))/(double)imu;
01088 vo1=vi1[0]+(long)(mu*((double)(vi2[0]-vi1[0])));
01089 vo2=vi1[1]+(long)(mu*((double)(vi2[1]-vi1[1])));
01090 if(xmin <= vo1 && vo1 <= xmax && ymin <= vo2 && vo2 <= ymax)return TRUE;
01091 return FALSE;
01092 }
01093
01094 static BOOL OnFaceEdge(node *n, long id, ivector ip){
01095 if (id == 0 &&
01096 ip[1]==n->mi[1] && n->mi[0]<=ip[0] && ip[0]<=n->ma[0] && n->mi[2]<=ip[2] && ip[2]<=n->ma[2])return TRUE;
01097 else if (id == 1 &&
01098 ip[1]==n->ma[1] && n->mi[0]<=ip[0] && ip[0]<=n->ma[0] && n->mi[2]<=ip[2] && ip[2]<=n->ma[2])return TRUE;
01099 else if (id == 2 &&
01100 ip[0]==n->mi[0] && n->mi[1]<=ip[1] && ip[1]<=n->ma[1] && n->mi[2]<=ip[2] && ip[2]<=n->ma[2])return TRUE;
01101 else if (id == 3 &&
01102 ip[0]==n->ma[0] && n->mi[1]<=ip[1] && ip[1]<=n->ma[1] && n->mi[2]<=ip[2] && ip[2]<=n->ma[2])return TRUE;
01103 else if (id == 4 &&
01104 ip[2]==n->mi[2] && n->mi[0]<=ip[0] && ip[0]<=n->ma[0] && n->mi[1]<=ip[1] && ip[1]<=n->ma[1])return TRUE;
01105 else if (id == 5 &&
01106 ip[2]==n->ma[2] && n->mi[0]<=ip[0] && ip[0]<=n->ma[0] && n->mi[1]<=ip[1] && ip[1]<=n->ma[1])return TRUE;
01107 return FALSE;
01108 }
01109
01110 static BOOL BoxEdgeCrossFace(ivector p1, ivector p2, long index, long len, vector n,
01111 ivector pf0, ivector pf1, ivector pf2){
01112 vector d,v1,pi,w,u,v;
01113 double mu,a,b,de,uu,vv,wu,wv,uv;
01114 static vector dd[5]={{0.0,0.0,1.0},{0.0,1.0,0.0},{-1.0,0.0,0.0},{0.0,-1.0,0.0},{0.0,0.0,1.0}};
01115 VECCOPY(dd[index],d)
01116 mu=DOT(d,n);
01117 if(fabs(mu) < 0.0001)return FALSE;
01118 VECSUB(pf0,p1,v1)
01119 mu=DOT(n,v1)/mu;
01120 if(mu <= 0.0)return FALSE;
01121 if(mu >= len)return FALSE;
01122 VECSCALE(mu,d,v1)
01123 VECSUM(p1,v1,pi)
01124 VECSUB(pi,pf0,w)
01125 VECSUB(pf1,pf0,u)
01126 VECSUB(pf2,pf0,v)
01127 uv=DOT(u,v);
01128 uu=DOT(u,u);
01129 vv=DOT(v,v);
01130 de=uu*vv-uv*uv;
01131 if(fabs(de) < 32)return FALSE;
01132 wu=DOT(w,u);
01133 wv=DOT(w,v);
01134 a=(wu*vv-wv*uv)/de;
01135 b=(wv*uu-wu*uv)/de;
01136 if( a <= 0.0 || a >= 1.0 || b <= 0.0|| b >= 1.0 || (a+b) >= 1.0)return FALSE;
01137 return TRUE;
01138 }
01139
01140 static BOOL TouchingFaceOutsideBox(node *n, ivector ip1, ivector ip2, ivector ip3){
01141 long ma,i;
01142 for(i=0;i<3;i++){
01143 if(ip1[i] == n->ma[i] && ip2[i] >= n->ma[i] && ip3[i] >= n->ma[i])return TRUE;
01144 if(ip1[i] == n->mi[i] && ip2[i] <= n->mi[i] && ip3[i] <= n->mi[i])return TRUE;
01145 }
01146 return FALSE;
01147 }
01148
01149 static BOOL FaceInVoxel(node *n, tvertex *vBase, tface *f){
01150
01151 long i,j,c,c0,c1,c2,ma,mi;
01152 static long vxi1[12]={0,1,2,3,4,5,6,7,0,1,2,3},
01153 vxi2[12]={1,2,3,0,5,6,7,4,4,5,6,7},
01154 vxdi[12]={0,1,2,3,0,1,2,3,4,4,4,4},
01155 len[12];
01156 tvertex *v;
01157 ivector p1,p2,voxv[8];
01158
01159
01160 for(i=0;i<3;i++){
01161 ma=n->ma[i]; mi=n->mi[i];
01162 c0=(vBase+f->V[0])->ip[i]; c1=(vBase+f->V[1])->ip[i]; c2=(vBase+f->V[2])->ip[i];
01163 if(c0 > ma && c1 > ma && c2 > ma)return FALSE;
01164 if(c0 < mi && c1 < mi && c2 < mi)return FALSE;
01165 }
01166
01167 for(j=0;j<3;j++){
01168 v=(vBase+f->V[j]);
01169 if(v->ip[0] > n->mi[0] && v->ip[0] < n->ma[0] &&
01170 v->ip[1] > n->mi[1] && v->ip[1] < n->ma[1] &&
01171 v->ip[2] > n->mi[2] && v->ip[2] < n->ma[2])return TRUE;
01172 }
01173
01174 for(i=0;i<6;i++){
01175 if(OnFaceEdge(n,i,(vBase+f->V[0])->ip) &&
01176 OnFaceEdge(n,i,(vBase+f->V[1])->ip) &&
01177 OnFaceEdge(n,i,(vBase+f->V[2])->ip)) return TRUE;
01178 }
01179
01180
01181 if(TouchingFaceOutsideBox(n,(vBase+f->V[0])->ip,(vBase+f->V[1])->ip,(vBase+f->V[2])->ip))return FALSE;
01182 if(TouchingFaceOutsideBox(n,(vBase+f->V[1])->ip,(vBase+f->V[2])->ip,(vBase+f->V[0])->ip))return FALSE;
01183 if(TouchingFaceOutsideBox(n,(vBase+f->V[2])->ip,(vBase+f->V[0])->ip,(vBase+f->V[1])->ip))return FALSE;
01184
01185 for(i=0;i<3;i++){
01186 if (i == 0){ VECCOPY((vBase+f->V[0])->ip,p1) VECCOPY((vBase+f->V[1])->ip,p2) }
01187 else if(i == 1){ VECCOPY((vBase+f->V[1])->ip,p1) VECCOPY((vBase+f->V[2])->ip,p2) }
01188 else { VECCOPY((vBase+f->V[2])->ip,p1) VECCOPY((vBase+f->V[0])->ip,p2) }
01189 if(EdgeCrossBoxFaceX(p1,p2,n->mi[0], n->mi[1],n->ma[1],n->mi[2],n->ma[2]))return TRUE;
01190 if(EdgeCrossBoxFaceX(p1,p2,n->ma[0], n->mi[1],n->ma[1],n->mi[2],n->ma[2]))return TRUE;
01191 if(EdgeCrossBoxFaceY(p1,p2,n->mi[1], n->mi[2],n->ma[2],n->mi[0],n->ma[0]))return TRUE;
01192 if(EdgeCrossBoxFaceY(p1,p2,n->ma[1], n->mi[2],n->ma[2],n->mi[0],n->ma[0]))return TRUE;
01193 if(EdgeCrossBoxFaceZ(p1,p2,n->mi[2], n->mi[0],n->ma[0],n->mi[1],n->ma[1]))return TRUE;
01194 if(EdgeCrossBoxFaceZ(p1,p2,n->ma[2], n->mi[0],n->ma[0],n->mi[1],n->ma[1]))return TRUE;
01195 }
01196
01197 voxv[0][0]=n->mi[0]; voxv[0][1]=n->mi[1]; voxv[0][2]=n->mi[2];
01198 voxv[1][0]=n->ma[0]; voxv[1][1]=n->mi[1]; voxv[1][2]=n->mi[2];
01199 voxv[2][0]=n->ma[0]; voxv[2][1]=n->ma[1]; voxv[2][2]=n->mi[2];
01200 voxv[3][0]=n->mi[0]; voxv[3][1]=n->ma[1]; voxv[3][2]=n->mi[2];
01201 voxv[4][0]=n->mi[0]; voxv[4][1]=n->mi[1]; voxv[4][2]=n->ma[2];
01202 voxv[5][0]=n->ma[0]; voxv[5][1]=n->mi[1]; voxv[5][2]=n->ma[2];
01203 voxv[6][0]=n->ma[0]; voxv[6][1]=n->ma[1]; voxv[6][2]=n->ma[2];
01204 voxv[7][0]=n->mi[0]; voxv[7][1]=n->ma[1]; voxv[7][2]=n->ma[2];
01205 len[0]=len[2]=len[4]=len[6]=n->ma[0]-n->mi[0];
01206 len[1]=len[3]=len[5]=len[7]=n->ma[1]-n->mi[1];
01207 len[8]=len[9]=len[10]=len[11]=n->ma[2]-n->mi[2];
01208 for(i=0;i<12;i++){
01209 if(BoxEdgeCrossFace(voxv[vxi1[i]],voxv[vxi2[i]],vxdi[i],len[i],f->n,
01210 (vBase+f->V[0])->ip,(vBase+f->V[1])->ip,(vBase+f->V[2])->ip))return TRUE;
01211 }
01212 return FALSE;
01213 }
01214
01215 static BOOL PartitionVoxel(node *np, node *na, node *nb, long p, long index){
01216
01217 long i,nnp,nx,n1,n2,o,f,c,sz,xvf,nl,nr,ns,ng;
01218 tface *F;
01219 tvertex *V,*v0,*v1,*v2;
01220 nnp=np->n;
01221
01222
01223 for(i=0;i<3;i++){
01224 na->mi[i]=nb->mi[i]=np->mi[i];
01225 na->ma[i]=nb->ma[i]=np->ma[i];
01226 }
01227 na->ma[index]=p;
01228 nb->mi[index]=p;
01229
01230 for(i=0;i<ObjectCount;i++)ObjectXlist[i]=0;
01231 for(i=0;i<nnp;i++){
01232 *(np->vxi+i) = 0;
01233 }
01234
01235 for(i=0,nx=0;i<ObjectCount;i++)if((xvf=ObjectXlist[i]) > 0){
01236 sz=(Object[i].NoTraceVertices+xvf)*(long)sizeof(tvertex);
01237 if((V=(tvertex *)X__Realloc(Object[i].Vtracebase,sz)) == NULL)goto FAILED;
01238 Object[i].Vtracebase=V;
01239 sz=(Object[i].NoTraceFaces+xvf)*(long)sizeof(tface);
01240 if((F=(tface *)X__Realloc(Object[i].Ftracebase,sz)) == NULL)goto FAILED;
01241 Object[i].Ftracebase=F;
01242 nx += xvf;
01243 }
01244
01245
01246
01247 ng=nnp+nx;
01248
01249 if(ng > 0){
01250 if((na->oid=(UC *)X__Malloc(sizeof(UC)*ng)) == NULL)goto FAILED;
01251 if((na->fid=(US *)X__Malloc(sizeof(US)*ng)) == NULL)goto FAILED;
01252 if((na->vxi=(UC *)X__Malloc(sizeof(UC)*ng)) == NULL)goto FAILED;
01253 if((nb->oid=(UC *)X__Malloc(sizeof(UC)*ng)) == NULL)goto FAILED;
01254 if((nb->fid=(US *)X__Malloc(sizeof(US)*ng)) == NULL)goto FAILED;
01255 if((nb->vxi=(UC *)X__Malloc(sizeof(UC)*ng)) == NULL)goto FAILED;
01256 for(i=0;i<ng;i++){na->oid[i]=999,na->fid[i]=999,na->vxi[i]=999;nb->oid[i]=666,nb->fid[i]=666,nb->vxi[i]=666;}
01257 }
01258
01259 nl=nr=ns=0;
01260 for(i=0,n1=0,n2=0;i<nnp;i++){
01261 c = (long)(*(np->vxi+i));
01262 o = (long)(*(np->oid+i));
01263 f = (long)(*(np->fid+i));
01264
01265 F=(Object[o].Ftracebase+f);
01266 V=Object[o].Vtracebase;
01267 if(FaceInVoxel(na,V,F)){
01268 *(na->fid+n1)=f;
01269 *(na->oid+n1)=o; n1++;
01270 nl++;
01271 }
01272 if(FaceInVoxel(nb,V,F)) {
01273 *(nb->fid+n2)=f;
01274 *(nb->oid+n2)=o; n2++;
01275 nr++;
01276 }
01277 }
01278
01279
01280 if(ng > 0 && n1 == 0){
01281 X__Free(na->oid); na->oid=NULL;
01282 X__Free(na->fid); na->fid=NULL;
01283 X__Free(na->vxi); na->vxi=NULL;
01284 }
01285 else if(n1 > 0){
01286 na->oid=(UC *)X__Realloc(na->oid,sizeof(UC)*n1);
01287 na->vxi=(UC *)X__Realloc(na->vxi,sizeof(UC)*n1);
01288 na->fid=(US *)X__Realloc(na->fid,sizeof(US)*n1);
01289 }
01290 if(ng > 0 && n2 == 0){
01291 X__Free(nb->oid); nb->oid=NULL;
01292 X__Free(nb->fid); nb->fid=NULL;
01293 X__Free(nb->vxi); nb->vxi=NULL;
01294 }
01295 if(n2 > 0){
01296 nb->oid=(UC *)X__Realloc(nb->oid,sizeof(UC)*n2);
01297 nb->vxi=(UC *)X__Realloc(nb->vxi,sizeof(UC)*n2);
01298 nb->fid=(US *)X__Realloc(nb->fid,sizeof(US)*n2);
01299 }
01300
01301 if(np->oid != NULL)X__Free(np->oid); np->oid=NULL;
01302 if(np->fid != NULL)X__Free(np->fid); np->fid=NULL;
01303 if(np->vxi != NULL)X__Free(np->vxi); np->vxi=NULL;
01304 na->n=n1;
01305 nb->n=n2;
01306
01307 np->n=0;
01308 return OK;
01309 FAILED:
01310 return FAIL;
01311 }