00001
00002
00003 #define MODULE_MIRRORS
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "render.h"
00015
00016 static long IntersectMirror(long scanline, double v1x, double v1y,
00017 double v2x, double v2y, double *xi);
00018 static short ShadowMirrorLine(long scanline, double vx[3], double vy[3],
00019 double *leftedge, double *rightedge,
00020 double xmin, double xmax);
00021 static void UpdateShadowZbuffer(float *id,float *id2,
00022 long l, double xl, double xr,
00023 double d, double d2, vector en,
00024 double ec, double SBC);
00025
00026 extern double spec_pow[16][max_spec+1],Rip_Freq;
00027
00028 short mirror_ground=0;
00029
00030
00031 #define US UNSIGNED
00032 #define UC unsigned char
00033
00034 static UC *grf_o;
00035 static US *grf_f;
00036 static float *grf_z;
00037 static long shadow_buffer_size2;
00038
00039 #ifdef _SUNSTYLE
00040 static long IntersectMirror(scanline,v1x,v1y,v2x,v2y,xi)
00041 long scanline; double v1x; double v1y; double v2x; double v2y; double *xi; {
00042 #else
00043 static long IntersectMirror(long scanline, double v1x, double v1y,
00044 double v2x, double v2y, double *xi){
00045 #endif
00046 double ddx,ddy,doff,ddxy;
00047 if((v1y < scanline) && (v2y < scanline))return 0;
00048 if((v1y > scanline) && (v2y > scanline))return 0;
00049 ddy = (v2y) - (v1y);
00050 if(fabs(ddy) < 0.0001)return 0;
00051 ddx = (v2x) - (v1x);
00052 doff=(double)scanline - v1y;
00053 ddxy=ddx*doff/ddy;
00054 *xi=(v1x)+ddxy;
00055 return 1;
00056 }
00057
00058 #ifdef _SUNSTYLE
00059 static short ShadowMirrorLine(scanline,vx,vy,leftedge,rightedge,xmin,xmax)
00060 long scanline; double vx[3]; double vy[3]; double *leftedge;
00061 double *rightedge; double xmin; double xmax; {
00062 #else
00063 static short ShadowMirrorLine(long scanline, double vx[3], double vy[3],
00064 double *leftedge, double *rightedge,
00065 double xmin, double xmax){
00066 #endif
00067 long i1,i2,i3;
00068 double x1,x2,x3;
00069 i1=IntersectMirror(scanline,vx[0],vy[0],vx[1],vy[1],&x1);
00070 i2=IntersectMirror(scanline,vx[1],vy[1],vx[2],vy[2],&x2);
00071 i3=IntersectMirror(scanline,vx[2],vy[2],vx[0],vy[0],&x3);
00072 if((i1 == 1) && (i2 == 1) && (i3 == 1))
00073 {*leftedge = min(min(x1,x2),x3);
00074 *rightedge= max(max(x1,x2),x3);}
00075 else if((i2 == 1) && (i3 == 1))
00076 {*leftedge = min(x2,x3);
00077 *rightedge= max(x2,x3);}
00078 else if((i3 == 1) && (i1 == 1))
00079 {*leftedge = min(x3,x1);
00080 *rightedge= max(x3,x1);}
00081 else if((i1 == 1) && (i2 == 1))
00082 {*leftedge = min(x1,x2);
00083 *rightedge= max(x1,x2);}
00084 else return 0;
00085 if(*leftedge >= xmax)return 0;
00086 else *leftedge = max(0,*leftedge);
00087 if(*rightedge < xmin)return 0;
00088 *rightedge = min(xmax-0.01,*rightedge);
00089 return 1;
00090 }
00091
00092 static void UpdateZbuffer(long l, double xl, double xr, long id, long O,
00093 double d2, vector en, double ec,
00094 long Mxmax, long Mxcentre, double Mscalex){
00095 long i,ixl,ixr;
00096 double depth,bL,bR,aL,aR,dL,dR;
00097 xl += 0.01;
00098 xr -= 0.01;
00099 ixl = (long)xl;
00100 ixr = (long)xr;
00101 if(ixl == ixr){
00102 dL = xl - (double)Mxcentre; dL/=Mscalex;
00103 dR = xr - (double)Mxcentre; dR/=Mscalex;
00104 bL = en[0]*dL + en[2]*d2 + en[1];
00105 if(fabs(bL) < 1.e-30)aL=BIGP;
00106 else aL = ec/bL;
00107 bR = en[0]*dR + en[2]*d2 + en[1];
00108 if(fabs(bR) < 1.e-30)aR=BIGP;
00109 else aR = ec/bR;
00110 depth=min(aL,aR);
00111 if(depth > 1.000 && depth <= *(grf_z+l*(long)Mxmax+ixl)){
00112 *(grf_z+l*(long)Mxmax+ixl) = depth;
00113 *(grf_o+l*(long)Mxmax+ixl) = (UC)O;
00114 *(grf_f+l*(long)Mxmax+ixl) = (US)id;
00115 }
00116 }
00117 else{
00118 dL = xl - (double)Mxcentre; dL/=Mscalex;
00119 bL = en[0]*dL + en[2]*d2 + en[1];
00120 if(fabs(bL) < 1.e-30)aL=BIGP;
00121 else aL = (ec)/bL;
00122 bR = en[0]*DR[ixl] + en[2]*d2 + en[1];
00123 if(fabs(bR) < 1.e-30)aR=BIGP;
00124 else aR = ec/bR;
00125 depth=min(aL,aR);
00126 if(depth > 1.000 && depth <= *(grf_z+l*(long)Mxmax+ixl)){
00127 *(grf_z+l*(long)Mxmax+ixl) = depth;
00128 *(grf_o+l*(long)Mxmax+ixl) = (UC)O;
00129 *(grf_f+l*(long)Mxmax+ixl) = (US)id;
00130 }
00131 bL = en[0]*DL[ixr] + en[2]*d2 + en[1];
00132 if(fabs(bL) < 1.e-30)aL=BIGP;
00133 else aL = ec/bL;
00134 dR = xr - (double)Mxcentre; dR/=Mscalex;
00135 bR = en[0]*dR + en[2]*d2 + en[1];
00136 if(fabs(bR) < 1.e-30)aR=BIGP;
00137 else aR = (ec)/bR;
00138 depth=min(aR,aL);
00139 if(depth > 1.000 && depth <= *(grf_z+l*(long)Mxmax+ixr)){
00140 *(grf_z+l*(long)Mxmax+ixr) = depth;
00141 *(grf_o+l*(long)Mxmax+ixr) = (UC)O;
00142 *(grf_f+l*(long)Mxmax+ixr) = (US)id;
00143 }
00144 if(ixr-ixl > 1)for(i=ixl+1;i<ixr;i++){
00145 bL = en[0]*DL[i] + en[2]*d2 + en[1];
00146 if(fabs(bL) < 1.e-30)aL=BIGP;
00147 else aL = ec/bL;
00148 bR = en[0]*DR[i] + en[2]*d2 + en[1];
00149 if(fabs(bL) < 1.e-30)aL=BIGP;
00150 else aR = ec/bR;
00151 depth=min(aL,aR);
00152 if(depth > 1.00 && depth <= *(grf_z+l*(long)Mxmax+i)){
00153 *(grf_z+l*(long)Mxmax+i) = depth;
00154 *(grf_o+l*(long)Mxmax+i) = (UC)O;
00155 *(grf_f+l*(long)Mxmax+i) = (US)id;
00156 }
00157 }
00158 }
00159 }
00160
00161 void Free_Mirror_On_Ground(void){
00162 if(mirror_ground == 0)return;
00163 X__Free(grf_o);
00164 X__Free(grf_f);
00165 mirror_ground=0;
00166 }
00167
00168 short Mirror_In_Ground(void){
00169 long i,j,l,fbc;
00170 long vi[3],screensize,Mxmax,Mymax,Mxcentre,Mycentre;
00171 face *f;
00172 vertex *v;
00173 vector p,pp[3],en;
00174 double dp,temp4,d2,ec,xx[3],yy[3],xxmin,xxmax,yymin,yymax,Mscalex,Mscaley;
00175 double itr[4][4],tr[4][4],t1[4][4],t2[4][4],t3[4][4],x,y,z,xg,yg,zg;
00176 Mscalex=scalex; Mscaley=scaley;
00177 if(full_mirror){
00178 Mxmax=XMAX; Mymax=YMAX;
00179 }
00180 else{
00181 Mxmax=ResolutionX; Mymax=ResolutionY;
00182 if(anti_alias == LOW) {Mscalex /= 2;}
00183 if(anti_alias == MEDIUM){Mscalex /= 2; Mscaley /= 2;}
00184 if(anti_alias == HIGH) {Mscalex /= 3; Mscaley /= 2;}
00185 if(anti_alias == ULTRA) {Mscalex /= 3; Mscaley /= 3;}
00186 }
00187 Mxcentre=Mxmax/2; Mycentre=Mymax/2;
00188 screensize = Mxmax*Mymax;
00189 if((grf_o = (UC *)X__Malloc(screensize*sizeof(UC))) == NULL){
00190 Render_Message(1,0,NULL); return FAIL;
00191 }
00192 if((grf_f = (US *)X__Malloc(screensize*sizeof(US))) == NULL){
00193 X__Free(grf_o);
00194 Render_Message(1,0,NULL); return FAIL;
00195 }
00196 if((grf_z = (float *)X__Malloc(screensize*sizeof(float))) == NULL){
00197 X__Free(grf_o);
00198 X__Free(grf_f);
00199 Render_Message(1,0,NULL); return FAIL;
00200 }
00201 mirror_ground=1;
00202 for(i=0;i<screensize;i++){
00203 *(grf_o + i) = 255;
00204 *(grf_f + i) = 65535;
00205 *(grf_z + i) = BIGP;
00206 }
00207 R_roty(t1,CamTheta);
00208 R_rotx(t2,CamAlpha);
00209 R_m4by4(t2,t1,t3);
00210 R_rotz(t1,CamPhi);
00211 R_m4by4(t1,t3,t2);
00212 R_tram(t1,ViewPoint[0],ViewPoint[1],ViewPoint[2]);
00213 R_m4by4(t1,t2,itr);
00214 R_tram(t2,-ViewPoint[0],-ViewPoint[1],-ViewPoint[2]);
00215 R_rotz(t3,-CamPhi);
00216 R_m4by4(t3,t2,t1);
00217 R_rotx(t2,-CamAlpha);
00218 R_m4by4(t2,t1,t3);
00219 R_roty(t1,-CamTheta);
00220 R_m4by4(t1,t3,tr);
00221 R_m4by1(itr,Ground.p[0],Ground.p[1],Ground.p[2],&xg,&yg,&zg);
00222 for(i=0;i<Mxmax;i++) {
00223 DL[i]=(double)(i - Mxcentre); DL[i]/=Mscalex;
00224 DR[i]=(double)(i+1-Mxcentre); DR[i]/=Mscalex;
00225 D1[i]=(double)(i - Mxcentre) + 0.5; D1[i]/=Mscalex;
00226 }
00227 for(i=0;i<ObjectCount;i++){
00228 if(!Object[i].in_use)continue;
00229 v=Object[i].Vbase;
00230 f=Object[i].Fbase;
00231 for(j=0;j<Object[i].NoFaces;j++){
00232 vi[0]=(f+j)->V[0];
00233 vi[1]=(f+j)->V[1];
00234 vi[2]=(f+j)->V[2];
00235 fbc=0;
00236 for(l=0;l<3;l++){
00237 R_m4by1(itr,(v+vi[l])->p[0],(v+vi[l])->p[1],(v+vi[l])->p[2],&x,&y,&z);
00238 dp=z-zg;
00239 if(dp < 0.0){fbc++; z = zg;}
00240 else z = zg-dp;
00241 R_m4by1(tr,x,y,z,&p[0],&p[1],&p[2]);
00242 veccopy(p,pp[l]);
00243 if(p[1] >= 1.000){
00244 temp4=(Mscalex*(p[0])/(p[1]));
00245 xx[l]=(double)Mxcentre + temp4;
00246 temp4=(Mscaley*(p[2])/(p[1]));
00247 yy[l]=(double)Mycentre - temp4;
00248 }
00249 else goto FACEBREAK;
00250 }
00251 if(fbc == 3)goto FACEBREAK;
00252 xxmin=min(xx[1],xx[2]); xxmin=min(xx[0],xxmin);
00253 xxmax=max(xx[1],xx[2]); xxmax=max(xx[0],xxmax);
00254 yymin=min(yy[1],yy[2]); yymin=min(yy[0],yymin);
00255 yymax=max(yy[1],yy[2]); yymax=max(yy[0],yymax);
00256 if((yymax > yymin) && (xxmax > xxmin)){
00257 VECSUB(pp[2],pp[0],pp[2])
00258 VECSUB(pp[1],pp[0],pp[1])
00259 cross(pp[1],pp[2],en);
00260 if(normalize(en) == 0){
00261 ec=DOT(pp[0],en);
00262 if(ec > 0.0){
00263 VECSCALE((double)(-1.0),en,en)
00264 ec = -ec;
00265 }
00266 for(l=max(0,(long)yymin);l<=min((long)yymax,Mymax-1);l++){
00267 if(ShadowMirrorLine(l,xx,yy,&xxmin,&xxmax,
00268 0.0,(double)Mxmax)){
00269 d2=(double)(Mycentre-l)/Mscaley;
00270 UpdateZbuffer(l,xxmin,xxmax,j,i,d2,en,ec,Mxmax,Mxcentre,Mscalex);
00271 }
00272 }
00273 }
00274 }
00275 FACEBREAK: continue;
00276 }
00277 }
00278 X__Free(grf_z); grf_z=NULL;
00279 return 1;
00280 }
00281
00282 void Add_Ground_Mirror(long scanline, long col, vector p,
00283 unsigned char *R, unsigned char *G, unsigned char *B){
00284
00285 register long addr;
00286 int obj;
00287 face *f;
00288 vertex *v;
00289 double r1,pdotn,r=0.0,g=0.0,b=0.0;
00290 vector d;
00291
00292 if(full_mirror)addr=XMAX*scanline+col;
00293 else addr=ResolutionX*(scanline/aaYstep)+col/aaXstep;
00294
00295 obj=(int)(*(grf_o + addr));
00296 if( obj < 255){
00297 f = (Object + obj)->Fbase + (long)(*(grf_f + addr));
00298 v = (Object + obj)->Vbase;
00299 pdotn=DOT(p,Ground.n);
00300 VECSCALE(2*pdotn,Ground.n,d)
00301 VECSUB(p,d,d)
00302 GetSurfaceValue(obj,f,v,p,d,&r,&g,&b,0,0,0);
00303 r1=(1.0 - Ground.refl);
00304 *R = (unsigned char)
00305 ((double)*R * r1 + r*Ground.refl);
00306 *G = (unsigned char)
00307 ((double)*G * r1 + g*Ground.refl);
00308 *B = (unsigned char)
00309 ((double)*B * r1 + b*Ground.refl);
00310 }
00311 return;
00312 }
00313
00314 void Free_Lights_Shadows(void){
00315 long i;
00316 for(i=0;i<Nlights;i++){
00317 if(Lights[i].shadow_buffer != NULL){
00318 X__Free(Lights[i].shadow_buffer);
00319 Lights[i].shadow_buffer=NULL;
00320 }
00321 if(Lights[i].object_buffer != NULL){
00322 X__Free(Lights[i].object_buffer);
00323 Lights[i].object_buffer=NULL;
00324 }
00325 if(Lights[i].face_buffer != NULL){
00326 X__Free(Lights[i].face_buffer);
00327 Lights[i].face_buffer=NULL;
00328 }
00329 if(Lights[i].atmospheric_shadow_buffer != NULL){
00330 X__Free(Lights[i].atmospheric_shadow_buffer);
00331 Lights[i].atmospheric_shadow_buffer=NULL;
00332 }
00333 }
00334 }
00335
00336 void SetLightShadow(long id){
00337 double itr[4][4],tr[4][4],t1[4][4],t2[4][4],t3[4][4],d,x,y,z,
00338 xx[3],yy[3],d2,ec,xxmin,xxmax,yymin,yymax;
00339 long i,j,l,vi[3];
00340 face *f;
00341 vertex *v;
00342 vector en,pp[3],dr;
00343 float d2f,*depth2=NULL;
00344 if(shadow_buffer_size == 0)return;
00345 if((Lights[id].shadow_buffer = (float *)X__Malloc((long)shadow_buffer_size*
00346 (long)shadow_buffer_size*(long)sizeof(float))) == NULL){
00347 Render_Message(2,0,NULL);
00348 return;
00349 }
00350 if((depth2 = (float *)X__Malloc((long)shadow_buffer_size*
00351 (long)shadow_buffer_size*(long)sizeof(float))) == NULL){
00352 X__Free(Lights[id].shadow_buffer);
00353 Lights[id].shadow_buffer=NULL;
00354 Render_Message(2,0,NULL);
00355 return;
00356 }
00357 else Render_Message(3,0,NULL);
00358 for(i=0;i< shadow_buffer_size*shadow_buffer_size; i++){
00359 *(Lights[id].shadow_buffer+i) = 1.0e30;
00360 *(depth2+i) = 1.e30;
00361 }
00362 R_roty(t1,CamTheta);
00363 R_rotx(t2,CamAlpha);
00364 R_m4by4(t2,t1,t3);
00365 R_rotz(t1,CamPhi);
00366 R_m4by4(t1,t3,t2);
00367 R_tram(t1,ViewPoint[0],ViewPoint[1],ViewPoint[2]);
00368 R_m4by4(t1,t2,itr);
00369 R_m4by1(itr,Lights[id].p[0],Lights[id].p[1],Lights[id].p[2],&x,&y,&z);
00370 R_tram(t1,-x,-y,-z);
00371 R_rotz(t2,-Lights[id].dPhi*PI/180.0);
00372 R_m4by4(t2,t1,t3);
00373 R_rotx(t1,-Lights[id].dAlpha*PI/180.0);
00374 R_m4by4(t1,t3,t2);
00375 R_roty(t1,0.0);
00376 R_m4by4(t1,t2,tr);
00377 R_m4by4(tr,itr,Lights[id].shadow_transform);
00378 shadow_buffer_size2 = shadow_buffer_size/2.0;
00379
00380 Lights[id].scale=d=(double)shadow_buffer_size2/tan(Lights[id].cone2);
00381 if(R_Nground > 0){
00382 double c,b,mu;
00383 vector gp0,gp1,gp2,gn;
00384 R_m4by1(Lights[id].shadow_transform,
00385 Ground.p[0],Ground.p[1],Ground.p[2],&x,&y,&z);
00386 gp0[0]=x; gp0[1]=y; gp0[2]=z;
00387 R_m4by1(Lights[id].shadow_transform,
00388 Ground.x[0],Ground.x[1],Ground.x[2],&x,&y,&z);
00389 gp1[0]=x; gp1[1]=y; gp1[2]=z;
00390 R_m4by1(Lights[id].shadow_transform,
00391 Ground.y[0],Ground.y[1],Ground.y[2],&x,&y,&z);
00392 gp2[0]=x; gp2[1]=y; gp2[2]=z;
00393 vecsub(gp1,gp0,gp1);
00394 vecsub(gp2,gp0,gp2);
00395 cross(gp1,gp2,gn);
00396 normalize(gn);
00397 c=DOT(gp0,gn);
00398 for(i=0,l=0;i<shadow_buffer_size;i++){
00399 d2=(double)(shadow_buffer_size2-i);
00400 for(j=0;j<shadow_buffer_size;j++){
00401
00402
00403 b=gn[0]*((double)j + 0.5)+gn[1]*d+gn[2]*d2;
00404 if(fabs(b) > 1.e-4){
00405 mu=c/b;
00406 if(mu > 0.0){
00407 *(depth2+l) = mu*d;
00408
00409 }
00410 l++;
00411 }
00412 }
00413 }
00414 }
00415 for(i=0;i<ObjectCount;i++){
00416 if(!Object[i].in_use)continue;
00417 v=Object[i].Vbase;
00418 f=Object[i].Fbase;
00419 if(!Object[i].cast_shadow)continue;
00420 for(j=0;j<Object[i].NoFaces;j++){
00421 vi[0]=(f+j)->V[0]; vi[1]=(f+j)->V[1]; vi[2]=(f+j)->V[2];
00422 for(l=0;l<3;l++){
00423 R_m4by1(Lights[id].shadow_transform,
00424 (v+vi[l])->p[0],(v+vi[l])->p[1],(v+vi[l])->p[2],
00425 &x,&y,&z);
00426 if(y > 0.0){
00427 xx[l]=(double)shadow_buffer_size2 + d*x/y;
00428 yy[l]=(double)shadow_buffer_size2 - d*z/y;
00429 pp[l][0]=x; pp[l][1]=y; pp[l][2]=z;
00430 }
00431 else goto FACEBREAK;
00432 }
00433 xxmin=min(xx[1],xx[2]); xxmin=min(xx[0],xxmin);
00434 xxmax=max(xx[1],xx[2]); xxmax=max(xx[0],xxmax);
00435 yymin=min(yy[1],yy[2]); yymin=min(yy[0],yymin);
00436 yymax=max(yy[1],yy[2]); yymax=max(yy[0],yymax);
00437 if((yymax > yymin) && (xxmax > xxmin)){
00438 VECSUB(pp[2],pp[0],pp[2])
00439 VECSUB(pp[1],pp[0],pp[1])
00440 cross(pp[1],pp[2],en);
00441 if(normalize(en) == 0){
00442 ec=DOT(pp[0],en);
00443 for(l=max(0,(long)yymin);l<=min((long)yymax,shadow_buffer_size-1);l++){
00444 if(ShadowMirrorLine(l,xx,yy,&xxmin,&xxmax,0.0,
00445 (double)shadow_buffer_size)){
00446 d2=(double)(shadow_buffer_size2-l);
00447 UpdateShadowZbuffer(Lights[id].shadow_buffer,depth2,
00448 l,xxmin,xxmax,d,d2,en,ec,
00449 (double)shadow_buffer_size2);
00450 }
00451 }
00452 }
00453 }
00454 FACEBREAK:;
00455 }
00456 }
00457 for(i=0;i< shadow_buffer_size*shadow_buffer_size; i++){
00458 d2f = *(Lights[id].shadow_buffer+i);
00459 if(*(depth2+i) < 1.e25 && d2f < 1.e25){
00460 *(Lights[id].shadow_buffer+i) = ( d2f + *(depth2+i) )*0.5;
00461 }
00462 else{
00463 *(Lights[id].shadow_buffer+i) += 1.e30;
00464 }
00465 *(depth2+i) = d2f;
00466 }
00467
00468 Lights[id].atmospheric_shadow_buffer=depth2;
00469 return;
00470 }
00471
00472 #define SBS shadow_buffer_size
00473
00475
00476
00477 #define TOLL1 10.0
00478 #define TOLL2 0.0
00479
00480 static void UpdateShadowZbuffer(float *id, float *iq,
00481 long l, double xl, double xr,
00482 double d, double d2, vector en, double ec,
00483 double SBC){
00484 long i,ixl,ixr;
00485 double depth,bL,bR,aL,aR,dL,dR;
00486 xl += 0.01;
00487 xr -= 0.01;
00488 ixl = (long)xl;
00489 ixr = (long)xr;
00490 if(ixl == ixr){
00491 dL = xl - SBC;
00492 dR = xr - SBC;
00493 bL = en[0]*dL + en[2]*d2 + en[1]*d ;
00494 if(fabs(bL) < 1.e-30)aL=BIGP;
00495 else aL = ec/bL;
00496 bR = en[0]*dR + en[2]*d2 + en[1]*d ;
00497 if(fabs(bR) < 1.e-30)aR=BIGP;
00498 else aR = ec/bR;
00499 depth=max(aL,aR)*d;
00500 if(fabs(depth - *(id+l*SBS+ixl)) < TOLL1){;}
00501 else if(depth > 0 && depth <= *(id+l*SBS+ixl)){
00502 if(*(id+l*SBS+ixl) <= *(iq+l*SBS+ixl)) *(iq+l*SBS+ixl) = *(id+l*SBS+ixl);
00503 *(id+l*SBS+ixl) = depth;
00504 }
00505 else if(depth > 0 && depth < *(iq+l*SBS+ixl)) *(iq+l*SBS+ixl) = depth;
00506 }
00507 else{
00508 dL = xl - SBC;
00509 bL = en[0]*dL + en[2]*d2 + en[1]*d ;
00510 if(fabs(bL) < 1.e-30)aL=BIGP;
00511 else aL = ec/bL;
00512 bR = en[0]*(double)(ixl+1-SBC) + en[2]*d2 + en[1]*d ;
00513 if(fabs(bR) < 1.e-30)aR=BIGP;
00514 else aR = ec/bR;
00515 depth=max(aL,aR)*d;
00516 if(fabs(depth - *(id+l*SBS+ixl)) < TOLL1){;}
00517 else if(depth > 0 && depth <= *(id+l*SBS+ixl)){
00518 if(*(id+l*SBS+ixl) <= *(iq+l*SBS+ixl)) *(iq+l*SBS+ixl) = *(id+l*SBS+ixl);
00519 *(id+l*SBS+ixl) = depth;
00520 }
00521 else if(depth > 0 && depth < *(iq+l*SBS+ixl)) *(iq+l*SBS+ixl) = depth;
00522 bL = en[0]*(double)(ixr-SBC) + en[2]*d2 + en[1]*d ;
00523 if(fabs(bL) < 1.e-30)aL=BIGP;
00524 else aL = ec/bL;
00525 dR = xr - SBC;
00526 bR = en[0]*dR + en[2]*d2 + en[1]*d ;
00527 if(fabs(bR) < 1.e-30)aR=BIGP;
00528 else aR = ec/bR;
00529 depth=max(aR,aL)*d;
00530 if(fabs(depth - *(id+l*SBS+ixr)) < TOLL1){;}
00531 else if(depth > 0 && depth <= *(id+l*SBS+ixr)){
00532 if(*(id+l*SBS+ixr) <= *(iq+l*SBS+ixr)) *(iq+l*SBS+ixr) = *(id+l*SBS+ixr);
00533 *(id+l*SBS+ixr) = depth;
00534 }
00535 else if(depth > 0 && depth < *(iq+l*SBS+ixr)) *(iq+l*SBS+ixr) = depth;
00536 if(ixr-ixl > 1)for(i=ixl+1;i<ixr;i++){
00537 bL = en[0]*(double)(i-SBC) + en[2]*d2 + en[1]*d ;
00538 if(fabs(bL) < 1.e-30)aL=BIGP;
00539 else aL = ec/bL;
00540 bR = en[0]*(double)(i+1-SBC) + en[2]*d2 + en[1]*d ;
00541 if(fabs(bR) < 1.e-30)aR=BIGP;
00542 else aR = ec/bR;
00543 depth=max(aL,aR)*d;
00544 if(fabs(depth - *(id+l*SBS+i)) < TOLL1){;}
00545 else if(depth > 0 && depth <= *(id+l*SBS+i)){
00546 if(*(id+l*SBS+i) <= *(iq+l*SBS+i)) *(iq+l*SBS+i) = *(id+l*SBS+i);
00547 *(id+l*SBS+i) = depth;
00548 }
00549 else if(depth > 0 && depth < *(iq+l*SBS+i)) *(iq+l*SBS+i) = depth;
00550 }
00551 }
00552 }
00553
00554 #ifdef _SUNSTYLE
00555 void PointInShadow(p,id,intensity)
00556 vector p; long id; double *intensity; {
00557 #else
00558 void PointInShadow(vector p, long id, double *intensity){
00559 #endif
00560 double x,y,z,zz,dx,dy,i0,ix,iy,ii;
00561 long xx,yy,i,j,
00562
00563 edge=2,
00564 edge3,sum;
00565 R_m4by1(Lights[id].shadow_transform,p[0],p[1],p[2],&x,&y,&z);
00566 if(y > 0.0){
00567 i0 = ix = iy = *intensity;
00568 dx=((double)shadow_buffer_size2 + Lights[id].scale*x/y);
00569 dy=((double)shadow_buffer_size2 - Lights[id].scale*z/y);
00570 xx=(long)dx; yy=(long)dy; sum=0; edge3=0;
00571 for(i=xx-edge;i<=xx+edge;i++)for(j=yy-edge;j<=yy+edge;j++){
00572 if(i >= 0 && i < SBS && j >= 0 && j < SBS){
00573 zz = *(Lights[id].shadow_buffer+j*SBS+i);
00574 if(zz < y)sum++; edge3++;
00575 }
00576 }
00577 if(edge3 > 0)i0 = i0 *
00578 (1.0 - (double)sum/(double)edge3*(1.0-shadow_density));
00579 xx++; sum=0; edge3=0;
00580 for(i=xx-edge;i<=xx+edge;i++)for(j=yy-edge;j<=yy+edge;j++){
00581 if(i >= 0 && i < SBS && j >= 0 && j < SBS){
00582 zz = *(Lights[id].shadow_buffer+j*SBS+i);
00583 if(zz < y)sum++; edge3++;
00584 }
00585 }
00586 if(edge3 > 0)ix = ix *
00587 (1.0 - (double)sum/(double)edge3*(1.0-shadow_density));
00588 yy++; xx--; sum=0; edge3=0;
00589 for(i=xx-edge;i<=xx+edge;i++)for(j=yy-edge;j<=yy+edge;j++){
00590 if(i >= 0 && i < SBS && j >= 0 && j < SBS){
00591 zz = *(Lights[id].shadow_buffer+j*SBS+i);
00592 if(zz < y)sum++; edge3++;
00593 }
00594 }
00595 if(edge3 > 0)iy = iy *
00596 (1.0 - (double)sum/(double)edge3*(1.0-shadow_density));
00597 yy--;
00598 dx -= (double)xx;
00599 dy -= (double)yy;
00600 ii = i0 + (ix - i0)*dx + (iy - i0)*dy;
00601 ii = min(ii,*intensity);
00602 *intensity = max(0.0,ii);
00603 }
00604 return;
00605 }
00606
00607 #ifdef TRACER
00608
00609
00610
00611 #define TOL 1.e-6
00612 #define TOLE 1.e-4
00613
00614 int R_intersect_face_old(vector p, vector d,
00615 vector pf0, vector pf1, vector pf2, vector n,
00616 double *depth, double tollerance){
00617
00618
00619
00620 vector v1,pi;
00621 double mu,mu1,det1,det2,det3,ve1,ve2,ve3,vp1,vp2,vp3,p1,p2,p3,a,b,dm,detmax;
00622 int k;
00623 mu1=DOT(d,n);
00624 if(fabs(mu1) < TOL)return 0;
00625 VECSUB(pf0,p,v1)
00626 mu=DOT(n,v1)/mu1;
00627 if(mu < tollerance)return 0;
00628 VECSCALE(mu,d,v1)
00629 VECSUM(p,v1,pi)
00630 ve1=pf1[0]-pf0[0]; ve2=pf1[1]-pf0[1]; ve3=pf1[2]-pf0[2];
00631 vp1=pf2[0]-pf0[0]; vp2=pf2[1]-pf0[1]; vp3=pf2[2]-pf0[2];
00632 p1=pi[0]-pf0[0];
00633 p2=pi[1]-pf0[1];
00634 p3=pi[2]-pf0[2];
00635 det1=ve1*vp2-vp1*ve2;
00636 det2=ve1*vp3-vp1*ve3;
00637 det3=ve2*vp3-vp2*ve3;
00638 k=0; detmax=TOL;
00639 if((dm=fabs(det1)) > detmax){k=1; detmax=dm;}
00640 if((dm=fabs(det2)) > detmax){k=2; detmax=dm;}
00641 if((dm=fabs(det3)) > detmax){k=3; detmax=dm;}
00642 if(k == 0)return 0;
00643 else if(k == 1){
00644 a=( vp2*p1-vp1*p2)/det1;
00645 b=(-ve2*p1+ve1*p2)/det1;
00646 }
00647 else if(k == 2){
00648 a=( vp3*p1-vp1*p3)/det2;
00649 b=(-ve3*p1+ve1*p3)/det2;
00650 }
00651 else if(k == 3){
00652 a=( vp3*p2-vp2*p3)/det3;
00653 b=(-ve3*p2+ve2*p3)/det3;
00654 }
00655 if( a < -TOLE || a > 1.0+TOLE || b < -TOLE || b > 1.0+TOLE || (a+b) > 1.0+TOLE)return 0;
00656 *depth=mu;
00657 return 1;
00658 }
00659
00660 #define TOLF 0.0001
00661 #define TOLP 0.025 // 0.01 = 89.4 degrees.
00662 #define TOLQ 100.0 // much smaller than face
00663 int R_intersect_face(vector p, vector d,
00664 vector pf0, vector pf1, vector pf2, vector n,
00665 double *depth, double tollerance){
00666
00667
00668
00669 vector v1,pi,w,u,v;
00670 double mu,a,b,de,uu,vv,wu,wv,uv;
00671 mu=DOT(d,n);
00672 if(fabs(mu) < TOLP)return 0;
00673 VECSUB(pf0,p,v1)
00674 mu=DOT(n,v1)/mu;
00675 if(mu < tollerance)return 0;
00676 VECSCALE(mu,d,v1)
00677 VECSUM(p,v1,pi)
00678 VECSUB(pi,pf0,w)
00679 VECSUB(pf1,pf0,u)
00680 VECSUB(pf2,pf0,v)
00681 uv=DOT(u,v);
00682 uu=DOT(u,u);
00683 vv=DOT(v,v);
00684 de=uu*vv-uv*uv;
00685 if(fabs(de) < TOLQ)return 0;
00686 wu=DOT(w,u);
00687 wv=DOT(w,v);
00688 a=(wu*vv-wv*uv)/de;
00689 b=(wv*uu-wu*uv)/de;
00690 if( a < -TOLF || a > 1.0+TOLF || b < -TOLF || b > 1.0+TOLF || (a+b) > 1.0+TOLF)return 0;
00691 *depth=mu;
00692 return 1;
00693 }
00694
00695
00696
00697
00698 #endif
00699