This is initdir.c in view mode; [Download] [Up]
#include <math.h> #include <stdio.h> #include "ray.h" struct circle *dvl; struct dirlist **neighbor; int *markdir; initdir() {register int o0,o1,d; register double l; struct point c0,c1; register double r0,r1; struct circle cir; register struct objlist *ol; int origins; origins=0; for(o0=0;o0<maxobj;o0++) { if((objects[o0].flags&RAYORIGIN)) origins++; } NRECTS=40; if(NRECTS*sqrt((double)origins)>100) { if(origins) NRECTS=100/sqrt((double)origins); else NRECTS=100; } if(NRECTS<4) NRECTS=4; DIRECTIONS=6*NRECTS*NRECTS; dvl=nalloc(struct circle,DIRECTIONS); neighbor=nalloc(struct dirlist *,DIRECTIONS); markdir=nalloc(int,DIRECTIONS); candidates=nalloc(struct objlist **,maxobj); for(o0=0;o0<maxobj;o0++) { if(!(objects[o0].flags&RAYORIGIN)) continue;; candidates[o0]=nalloc(struct objlist *,DIRECTIONS); } initdvl(); initneighbor(); for(d=0;d<DIRECTIONS;d++) markdir[d]=0; for(o0=0;o0<maxobj;o0++) { if(!(objects[o0].flags&RAYORIGIN)) continue;; for(d=0;d<DIRECTIONS;d++) candidates[o0][d]=(struct objlist *)0; for(o1=lights+1;o1<maxobj;o1++) { if(o0==o1) continue; if(dflag) fprintf(stderr,"object %d to %d\n",o0,o1); c0=objects[o0].center; r0=objects[o0].radius; c1=objects[o1].center; r1=objects[o1].radius; cir.o.x=c1.x-c0.x; cir.o.y=c1.y-c0.y; cir.o.z=c1.z-c0.z; l=sqrt(cir.o.x*cir.o.x+cir.o.y*cir.o.y+cir.o.z*cir.o.z); cir.o.x/=l; cir.o.y/=l; cir.o.z/=l; if(r0+r1>=l) { for(d=0;d<DIRECTIONS;d++) { if(oflag) ol=alloc(struct objlist); else ol=(struct objlist *) alloc(struct objlist2); ol->obj=o1; ol->next=candidates[o0][d]; if(oflag) ol->t=0; candidates[o0][d]=ol; } } else { cir.s=(r0+r1)/l; cir.c=sqrt(1-cir.s*cir.s); d=dindex(cir.o); if(oflag) ttraverse(d,&cir,o1, candidates[o0],l-r0-r1); else traverse(d,&cir,o1,candidates[o0]); tclear(d); } } if(oflag) for(d=0;d<DIRECTIONS;d++) sortlist(candidates[o0][d]); } if(tflag) {int c; c=0; for(d=0;d<DIRECTIONS;d++) for(ol=candidates[0][d];ol;ol=ol->next) c++; fprintf(stderr,"Image complexity %g\n",((double)c)/DIRECTIONS); for(o0=1;o0<lights+1;o0++) { c=0; for(d=0;d<DIRECTIONS;d++) for(ol=candidates[o0][d];ol;ol=ol->next) c++; fprintf(stderr,"Shadow complexity for light %d %g\n", o0,((double)c)/DIRECTIONS); } } } traverse(d,cir,o,ol) register int d; register struct circle *cir; register int o; register struct objlist **ol; {register struct dirlist *dl; register struct objlist *ol2; markdir[d]=1; if(!overlap(&dvl[d],cir)) return; ol2=(struct objlist *)alloc(struct objlist2); ol2->obj=o; ol2->next=ol[d]; ol[d]=ol2; for(dl=neighbor[d];dl;dl=dl->next) if(!markdir[dl->dir]) traverse(dl->dir,cir,o,ol); } ttraverse(d,cir,o,ol,t) register int d; register struct circle *cir; register int o; register struct objlist **ol; register double t; {register struct dirlist *dl; register struct objlist *ol2; markdir[d]=1; if(!overlap(&dvl[d],cir)) return; ol2=alloc(struct objlist); ol2->obj=o; ol2->next=ol[d]; ol2->t=t; ol[d]=ol2; for(dl=neighbor[d];dl;dl=dl->next) if(!markdir[dl->dir]) ttraverse(dl->dir,cir,o,ol,t); } tclear(d) register int d; {register struct dirlist *dl; markdir[d]=0; for(dl=neighbor[d];dl;dl=dl->next) if(markdir[dl->dir]) tclear(dl->dir); } overlap(cir0,cir1) register struct circle *cir0,*cir1; { return cir0->o.x*cir1->o.x+cir0->o.y*cir1->o.y+cir0->o.z*cir1->o.z > cir0->c*cir1->c-cir0->s*cir1->s; } struct circle initdvl2(x,y,z,dx0,dy0,dz0,dx1,dy1,dz1) double x,y,z,dx0,dy0,dz0,dx1,dy1,dz1; {int i; double l,c,minc; struct vector v[4]; struct circle cir; for(i=0;i<4;i++) { v[i].x=x; v[i].y=y; v[i].z=z; } v[1].x+=dx0; v[1].y+=dy0; v[1].z+=dz0; v[2].x+=dx0+dx1; v[2].y+=dy0+dy1; v[2].z+=dz0+dz1; v[3].x+=dx1; v[3].y+=dy1; v[3].z+=dz1; cir.o.x=cir.o.y=cir.o.z=0; for(i=0;i<4;i++) { cir.o.x+=v[i].x/4; cir.o.y+=v[i].y/4; cir.o.z+=v[i].z/4; l=1/sqrt(v[i].x*v[i].x+v[i].y*v[i].y+v[i].z*v[i].z); v[i].x*=l; v[i].y*=l; v[i].z*=l; } l=1/sqrt(cir.o.x*cir.o.x+cir.o.y*cir.o.y+cir.o.z*cir.o.z); cir.o.x*=l; cir.o.y*=l; cir.o.z*=l; minc=1; for(i=0;i<4;i++) { c=cir.o.x*v[i].x+cir.o.y*v[i].y+cir.o.z*v[i].z; if(c<minc) minc=c; } cir.c=minc*0.999999; cir.s=sqrt(1-cir.c*cir.c); return cir; } initdvl() {int i,j,d; double x,y,z,dl; dl=2.0/NRECTS; d=0; x=1; z= -1; for(i=0;i<NRECTS;i++) { y= -1; for(j=0;j<NRECTS;j++) { dvl[d++]=initdvl2(x,y,z,0.0,0.0,dl,0.0,dl,0.0); y+=dl; } z+=dl; } x= -1; z= -1; for(i=0;i<NRECTS;i++) { y= -1; for(j=0;j<NRECTS;j++) { dvl[d++]=initdvl2(x,y,z,0.0,dl,0.0,0.0,0.0,dl); y+=dl; } z+=dl; } y=1; x= -1; for(i=0;i<NRECTS;i++) { z= -1; for(j=0;j<NRECTS;j++) { dvl[d++]=initdvl2(x,y,z,dl,0.0,0.0,0.0,0.0,dl); z+=dl; } x+=dl; } y= -1; x= -1; for(i=0;i<NRECTS;i++) { z= -1; for(j=0;j<NRECTS;j++) { dvl[d++]=initdvl2(x,y,z,0.0,0.0,dl,dl,0.0,0.0); z+=dl; } x+=dl; } z=1; y= -1; for(i=0;i<NRECTS;i++) { x= -1; for(j=0;j<NRECTS;j++) { dvl[d++]=initdvl2(x,y,z,0.0,dl,0.0,dl,0.0,0.0); x+=dl; } y+=dl; } z= -1; y= -1; for(i=0;i<NRECTS;i++) { x= -1; for(j=0;j<NRECTS;j++) { dvl[d++]=initdvl2(x,y,z,dl,0.0,0.0,0.0,dl,0.0); x+=dl; } y+=dl; } } struct dirlist *consdir(m,dl) int m; struct dirlist *dl; {struct dirlist *dl2; dl2=alloc(struct dirlist); dl2->dir=m; dl2->next=dl; return dl2; } initneighbor() {int i; double d; for(i=0;i<DIRECTIONS;i++) neighbor[i]=(struct dirlist *)0; d=2.0/NRECTS; initneighbor2(1.0,-1.0,-1.0,0.0,d,0.0,0.0,0.0,d); initneighbor2(-1.0,-1.0,-1.0,0.0,d,0.0,0.0,0.0,d); initneighbor2(-1.0,1.0,-1.0,d,0.0,0.0,0.0,0.0,d); initneighbor2(-1.0,-1.0,-1.0,d,0.0,0.0,0.0,0.0,d); initneighbor2(-1.0,-1.0,1.0,d,0.0,0.0,0.0,d,0.0); initneighbor2(-1.0,-1.0,-1.0,d,0.0,0.0,0.0,d,0.0); } initneighbor2(x,y,z,dx0,dy0,dz0,dx1,dy1,dz1) double x,y,z,dx0,dy0,dz0,dx1,dy1,dz1; {int i,j,d; double x0,y0,z0,x1,y1,z1; x0=x+dx0/2+dx1/2; y0=y+dy0/2+dy1/2; z0=z+dz0/2+dz1/2; for(i=0;i<NRECTS;i++) { for(j=0;j<NRECTS;j++) { x1=x0+i*dx0+j*dx1; y1=y0+i*dy0+j*dy1; z1=z0+i*dz0+j*dz1; d=dindex2(x1,y1,z1); neighbor[d]=consdir(dindex2(x1+dx0,y1+dy0,z1+dz0), neighbor[d]); neighbor[d]=consdir(dindex2(x1-dx0,y1-dy0,z1-dz0), neighbor[d]); neighbor[d]=consdir(dindex2(x1+dx1,y1+dy1,z1+dz1), neighbor[d]); neighbor[d]=consdir(dindex2(x1-dx1,y1-dy1,z1-dz1), neighbor[d]); } } } dindex2(x,y,z) double x,y,z; {struct vector v; v.x=x; v.y=y; v.z=z; return dindex(v); } print2(v) struct vector *v; { if(v->z==0) { printf("\tz=0\n"); return; } printf("\t%g %g\n",v->x/v->z,v->y/v->z); } sortlist(ol) register struct objlist *ol; {register struct objlist *ol2,*ol3; double t; int obj; if(!ol) return; for(;ol->next;ol=ol->next) { ol3=ol; for(ol2=ol->next;ol2;ol2=ol2->next) if(ol2->t<ol3->t) ol3=ol2; if(ol!=ol3) { t=ol->t; ol->t=ol3->t; ol3->t=t; obj=ol->obj; ol->obj=ol3->obj; ol3->obj=obj; } } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.