00001
00002
00003 #define MODULE_MATERIAL
00004
00005
00006
00007
00008
00009
00010
00011 #include "render.h"
00012
00013 extern short mirror_ground;
00014 extern double Rip_Freq;
00015
00016 #define FLOOR(x) ((x) >= 0.0 ? floor(x) : (0.0 - floor(0.0 - (x)) - 1.0))
00017
00018 static void Transform_to_Moziac(double, double ,double *, double *);
00019 static void AttenuateGlassSurface(long , long , long ,
00020 UCHAR *, UCHAR *, UCHAR *,
00021 long *[], long *[], double *[], double *);
00022 static void AttenuateGlass(long, long,
00023 UCHAR *, UCHAR *, UCHAR *Blue,
00024 long *[], long *[], double *[], double *);
00025 static void PutBackPlanes(long i, long scanline, double d2,
00026 UCHAR *Red, UCHAR *Green, UCHAR *Blue,
00027 double *Zground, long *Zobject, double *Zdepth,
00028 UCHAR *ZobjChar, long Wsky, double Rsky);
00029 static void GetBackdropValue(long row, long col, vector p, vector d,
00030 double *colour);
00031
00032 double spec_pow[16][max_spec+1],spec_gro[max_spec+1];
00033
00034 static double spec_val[16]={
00035 10.0, 15.0, 20.0, 25.0, 27.0, 30.0, 32.0, 35.0,
00036 40.0, 45.0, 50.0, 55.0, 60.0, 70.0, 80.0, 99.0};
00037
00038 void init_spec(void){
00039 long i,j;
00040 double d;
00041 for(j=0;j<16;j++){
00042 spec_pow[j][max_spec] = 1.0;
00043 for(i=0;i<max_spec;i++){
00044 d = pow(((double)i/(double)max_spec),spec_val[j]);
00045 spec_pow[j][i]=d;
00046 }
00047 }
00048 for(i=0;i<max_spec;i++)spec_gro[i] = pow((1.0/max_spec*(double)i),200.0);
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 void BumpByCoordinates(imap *Map, short type, long obj, face *f, vector p, vector n){
00062 long i,j,ialpha,ibeta,k,kl,kr,kt,kb,pixel,ix,iy;
00063 double alpha0,beta0,alpha,beta,a,b,red[3],cc0,cl0,cr0,ct0,cb0,
00064 ve1,ve2,ve3,vp1,vp2,vp3,p1,p2,p3,
00065 detmax,dm,det1,det2,det3,
00066 t1x,t2x,t1y,t2y;
00067 vertex *V,*v0,*v1,*v2;
00068 static double dalpha_bump[3]={0.0,0.01,0.0},
00069 dbeta_bump[3]={0.0,0.0,0.01};
00070 vector vv1,vv2;
00071 unsigned char *pP,*pR;
00072 if(Map->bp < 0)return;
00073 j=Map->xmaxbump;
00074 if((V=Object[obj].Vbase) == NULL)return;
00075 v0=(V+(f->V[0]));
00076 v1=(V+(f->V[1]));
00077 v2=(V+(f->V[2]));
00078 ve1=v1->p[0] - v0->p[0]; ve2=v1->p[1] - v0->p[1]; ve3=v1->p[2] - v0->p[2];
00079 vp1=v2->p[0] - v0->p[0]; vp2=v2->p[1] - v0->p[1]; vp3=v2->p[2] - v0->p[2];
00080 p1=p[0]-v0->p[0];
00081 p2=p[1]-v0->p[1];
00082 p3=p[2]-v0->p[2];
00083 det1=ve1*vp2-vp1*ve2;
00084 det2=ve1*vp3-vp1*ve3;
00085 det3=ve2*vp3-vp2*ve3;
00086 k=0; detmax=1.e-3;
00087 if((dm=fabs(det1)) > detmax){k=1; detmax=dm;}
00088 if((dm=fabs(det2)) > detmax){k=2; detmax=dm;}
00089 if((dm=fabs(det3)) > detmax){k=3; detmax=dm;}
00090 if(k == 0)return;
00091 else if(k == 1){
00092 a=( vp2*p1-vp1*p2)/det1;
00093 b=(-ve2*p1+ve1*p2)/det1;
00094 }
00095 else if(k == 2){
00096 a=( vp3*p1-vp1*p3)/det2;
00097 b=(-ve3*p1+ve1*p3)/det2;
00098 }
00099 else if(k == 3){
00100 a=( vp3*p2-vp2*p3)/det3;
00101 b=(-ve3*p2+ve2*p3)/det3;
00102 }
00103
00104 t1x=f->uu[1] - f->uu[0]; t2x=f->uu[2] - f->uu[0];
00105 t1y=f->vv[1] - f->vv[0]; t2y=f->vv[2] - f->vv[0];
00106 alpha0 = f->uu[0] + a*t1x + b*t2x;
00107 beta0 = f->vv[0] + a*t1y + b*t2y;
00108
00109 for(i=0;i<3;i++){
00110 alpha = alpha0+dalpha_bump[i];
00111 beta = beta0+dbeta_bump[i];
00112 if(type == TILE){
00113 if(Map->moziac)Transform_to_Moziac(alpha,beta,&a,&b);
00114 else{
00115 a=(alpha-floor(alpha));
00116 b=(beta-floor(beta));
00117 }
00118 alpha=a*Map->xmaxbump;
00119 beta=b*Map->ymaxbump;
00120 }
00121 else{
00122 alpha=Map->xmaxbump*alpha;
00123 beta =Map->ymaxbump*beta;
00124 }
00125 ialpha = (long)alpha; alpha -= (double)ialpha;
00126 ibeta = (long)beta; beta -= (double)ibeta;
00127 if(ialpha < 0 || ialpha >= Map->xmaxbump)return;
00128 if(ibeta < 0 || ibeta >= Map->ymaxbump)return;
00129 k =ibeta*j+ialpha;
00130 if(type == TILE){
00131 if(Map->moziac){
00132 if(ialpha < 1)kl=1; else kl=k-1;
00133 if(ialpha > j-2)kr=k-1; else kr=k+1;
00134 if(ibeta < 1)kb=k+j; else kb=k-j;
00135 if(ibeta > Map->ymaxbump-2)kt=k-j; else kt=k+j;
00136 }
00137 else{
00138 if(ialpha < 1)kl=k+j-1; else kl=k-1;
00139 if(ialpha > j-2)kr=ibeta*j; else kr=k+1;
00140 if(ibeta < 1)kb=(Map->ymaxbump-1)*j+ialpha; else kb=k-j;
00141 if(ibeta > Map->ymaxbump-2)kt=ialpha; else kt=k+j;
00142 }
00143 }
00144 else{
00145 if(ialpha < 1)kl=k; else kl=k-1;
00146 if(ialpha > j-2)kr=k; else kr=k+1;
00147 if(ibeta < 1)kb=k; else kb=k-j;
00148 if(ibeta > Map->ymaxbump-2)kt=k; else kt=k+j;
00149 }
00150
00151 pR=Map->p24Gbump;
00152 cc0 = (double)pR[k];
00153 cl0 = (double)pR[kl];
00154 cr0 = (double)pR[kr];
00155 ct0 = (double)pR[kt];
00156 cb0 = (double)pR[kb];
00157 if(alpha > 0.5){
00158 alpha = alpha-0.5;
00159 if(beta > 0.5){
00160 beta = beta-0.5;
00161 red[i] = (cr0-cc0)*alpha+(ct0-cc0)*beta+cc0;
00162 }
00163 else{
00164 beta = 0.5-beta;
00165 red[i] = (cr0-cc0)*alpha+(cb0-cc0)*beta+cc0;
00166 }
00167 }
00168 else{
00169 alpha = 0.5-alpha;
00170 if(beta > 0.5){
00171 beta = beta-0.5;
00172 red[i] = (cl0-cc0)*alpha+(ct0-cc0)*beta+cc0;
00173 }
00174 else{
00175 beta = 0.5-beta;
00176 red[i] = (cl0-cc0)*alpha+(cb0-cc0)*beta+cc0;
00177 }
00178 }
00179 }
00180 vecscale((red[1]-red[0])*Map->bumpx,Map->x,vv1);
00181 vecscale((red[2]-red[0])*Map->bumpy,Map->y,vv2);
00182 vecsum(n,vv1,n);
00183 vecsum(n,vv2,n);
00184 normalize(n);
00185 return;
00186 }
00187
00188 void BoxMapIntersect(vector d, long *id, double *alpha, double *beta){
00189
00190 double a,b,t=0.1;
00191 long i = -1;
00192 normalize(d);
00193 if(d[1] > t){
00194 a = d[0]/d[1]; b = d[2]/d[1];
00195 if(-1.0 <= a && a <= 1.0 && -1.0 <= b && b <= 1.0){i=0; goto HIT;}
00196 }
00197 if(d[0] > t){
00198 a = d[1]/d[0]; b = d[2]/d[0]; a = -a;
00199 if(-1.0 <= a && a <= 1.0 && -1.0 <= b && b <= 1.0){i=1; goto HIT;}
00200 }
00201 if(d[1] < -t){
00202 a = -d[0]/d[1]; b = -d[2]/d[1]; a = -a;
00203 if(-1.0 <= a && a <= 1.0 && -1.0 <= b && b <= 1.0){i=2; goto HIT;}
00204 }
00205 if(d[0] < -t){
00206 a = -d[1]/d[0]; b = -d[2]/d[0];
00207 if(-1.0 <= a && a <= 1.0 && -1.0 <= b && b <= 1.0){i=3; goto HIT;}
00208 }
00209 if(d[2] > t){
00210 a = d[0]/d[2]; b = d[1]/d[2]; b= -b;
00211 if(-1.0 <= a && a <= 1.0 && -1.0 <= b && b <= 1.0){i=4; goto HIT;}
00212 }
00213 if(d[2] < -t){
00214 a = -d[0]/d[2]; b = -d[1]/d[2];
00215 if(-1.0 <= a && a <= 1.0 && -1.0 <= b && b <= 1.0){i=5; goto HIT;}
00216 }
00217 HIT:
00218 *id = i;
00219 *alpha = 0.5*(a+1);
00220 *beta = 1.0 - 0.5*(b+1);
00221 return;
00222 }
00223
00224 void MapMirror(double *R,double *G, double *B, imap *Map, vector p, vector n){
00225
00226
00227
00228 #define FOURDIV2PI 0.318309886
00229 #define TWODIVPI 0.318309886
00230
00231 long j,pixel,k,ibeta,ialpha,kl,kr,kt,kb;
00232 double pdotn,alpha,beta,d12;
00233 double cc0,cc1,cc2,cl0,cl1,cl2,cr0,cr1,cr2,ct0,ct1,ct2,cb0,cb1,cb2;
00234 unsigned char *pP,*pR,*pG,*pB;
00235 vector d,dd;
00236 if(Map->rp < 0)return;
00237 pdotn=dot(p,n);
00238 vecscale(2*pdotn,n,d);
00239 vecsub(p,d,dd);
00240 R_m4by1(AntiCamera,dd[0],dd[1],dd[2],&d[0],&d[1],&d[2]);
00241
00242 BoxMapIntersect(d,&j,&alpha,&beta); if(j < 0)return;
00243
00244 alpha *= (double)Map->xmaxrefl;
00245 beta *= (double)Map->ymaxrefl;
00246 ialpha = (long)alpha; alpha -= (double)ialpha;
00247 ibeta=(long)beta; beta -= (double)ibeta;
00248 if(ialpha < 0 || ialpha >= Map->xmaxrefl)return;
00249 if(ibeta < 0 || ibeta >= Map->ymaxrefl)return;
00250 j=Map->xmaxrefl;
00251 k =ibeta*j+ialpha;
00252
00253 if(ialpha < 1)kl=1; else kl=k-1;
00254 if(ialpha > j-2)kr=k-1; else kr=k+1;
00255 if(ibeta < 1)kb=k+j; else kb=k-j;
00256 if(ibeta > Map->ymaxrefl-2)kt=k-j; else kt=k+j;
00257
00258 pR=Map->p24Rrefl; pG=Map->p24Grefl; pB=Map->p24Brefl;
00259 cc0 = (double)pR[k]; cc1 = (double)pG[k]; cc2 = (double)pB[k];
00260 cl0 = (double)pR[kl]; cl1 = (double)pG[kl]; cl2 = (double)pB[kl];
00261 cr0 = (double)pR[kr]; cr1 = (double)pG[kr]; cr2 = (double)pB[kr];
00262 ct0 = (double)pR[kt]; ct1 = (double)pG[kt]; ct2 = (double)pB[kt];
00263 cb0 = (double)pR[kb]; cb1 = (double)pG[kb]; cb2 = (double)pB[kb];
00264 if(alpha > 0.5){
00265 alpha = alpha-0.5;
00266 if(beta > 0.5){
00267 beta = beta-0.5;
00268 *R = (cr0-cc0)*alpha+(ct0-cc0)*beta+cc0;
00269 *G = (cr1-cc1)*alpha+(ct1-cc1)*beta+cc1;
00270 *B = (cr2-cc2)*alpha+(ct2-cc2)*beta+cc2;
00271 }
00272 else{
00273 beta = 0.5-beta;
00274 *R = (cr0-cc0)*alpha+(cb0-cc0)*beta+cc0;
00275 *G = (cr1-cc1)*alpha+(cb1-cc1)*beta+cc1;
00276 *B = (cr2-cc2)*alpha+(cb2-cc2)*beta+cc2;
00277 }
00278 }
00279 else{
00280 alpha = 0.5-alpha;
00281 if(beta > 0.5){
00282 beta = beta-0.5;
00283 *R = (cl0-cc0)*alpha+(ct0-cc0)*beta+cc0;
00284 *G = (cl1-cc1)*alpha+(ct1-cc1)*beta+cc1;
00285 *B = (cl2-cc2)*alpha+(ct2-cc2)*beta+cc2;
00286 }
00287 else{
00288 beta = 0.5-beta;
00289 *R = (cl0-cc0)*alpha+(cb0-cc0)*beta+cc0;
00290 *G = (cl1-cc1)*alpha+(cb1-cc1)*beta+cc1;
00291 *B = (cl2-cc2)*alpha+(cb2-cc2)*beta+cc2;
00292 }
00293 }
00294 }
00295
00296 void MapEnvironment(long col, long row, UCHAR *r, UCHAR *g, UCHAR *b, imap *Map){
00297 long j,pixel,k,ibeta,ialpha,kl,kr,kt,kb,w,kmin,kmax;
00298 double alpha,beta,R,G,B;
00299 double cc0,cc1,cc2,cl0,cl1,cl2,cr0,cr1,cr2,ct0,ct1,ct2,cb0,cb1,cb2;
00300 unsigned char *pP,*pR,*pG,*pB;
00301 vector d,dd;
00302 if(Map->pp < 0)return;
00303 d[0]=((double)col-(double)Xcentre)/scalex;
00304 d[1]=1.0;
00305 d[2]=((double)Ycentre-(double)row)/scaley;
00306 R_m3by1(CameraRotate,d[0],d[1],d[2],&dd[0],&dd[1],&dd[2]);
00307 BoxMapIntersect(dd,&j,&alpha,&beta); if(j < 0){
00308 *r = 0; *g=255; *b=0;
00309 return;
00310 }
00311 w=Map->xmax/6;
00312 alpha = ((double)j+alpha)*(double)w;
00313 beta *= (double)Map->ymax;
00314 ialpha = (long)alpha; alpha -= (double)ialpha;
00315 ibeta=(long)beta; beta -= (double)ibeta;
00316 if(ialpha < 0)ialpha=0;
00317 if(ialpha >= Map->xmax)ialpha=Map->xmax-1;
00318 if(ibeta < 0)ibeta=0;
00319 if(ibeta >= Map->ymax)ibeta=Map->ymax-1;
00320 k = ibeta*Map->xmax+ialpha;
00321 kmin = j*w + 1;
00322 kmax = (j+1)*w - 2;
00323 if(ialpha < kmin)kl=k; else kl=k-1;
00324 if(ialpha > kmax) kr=k; else kr=k+1;
00325 if(ibeta < 1)kb=k; else kb=k-Map->xmax;
00326 if(ibeta > Map->ymax-2)kt=k; else kt=k+Map->xmax;
00327 pR=Map->p24R; pG=Map->p24G; pB=Map->p24B;
00328
00329 cc0 = (double)pR[k]; cc1 = (double)pG[k]; cc2 = (double)pB[k];
00330 cl0 = (double)pR[kl]; cl1 = (double)pG[kl]; cl2 = (double)pB[kl];
00331 cr0 = (double)pR[kr]; cr1 = (double)pG[kr]; cr2 = (double)pB[kr];
00332 ct0 = (double)pR[kt]; ct1 = (double)pG[kt]; ct2 = (double)pB[kt];
00333 cb0 = (double)pR[kb]; cb1 = (double)pG[kb]; cb2 = (double)pB[kb];
00334 if(alpha > 0.5){
00335 alpha = alpha-0.5;
00336 if(beta > 0.5){
00337 beta = beta-0.5;
00338 R = (cr0-cc0)*alpha+(ct0-cc0)*beta+cc0;
00339 G = (cr1-cc1)*alpha+(ct1-cc1)*beta+cc1;
00340 B = (cr2-cc2)*alpha+(ct2-cc2)*beta+cc2;
00341 }
00342 else{
00343 beta = 0.5-beta;
00344 R = (cr0-cc0)*alpha+(cb0-cc0)*beta+cc0;
00345 G = (cr1-cc1)*alpha+(cb1-cc1)*beta+cc1;
00346 B = (cr2-cc2)*alpha+(cb2-cc2)*beta+cc2;
00347 }
00348 }
00349 else{
00350 alpha = 0.5-alpha;
00351 if(beta > 0.5){
00352 beta = beta-0.5;
00353 R = (cl0-cc0)*alpha+(ct0-cc0)*beta+cc0;
00354 G = (cl1-cc1)*alpha+(ct1-cc1)*beta+cc1;
00355 B = (cl2-cc2)*alpha+(ct2-cc2)*beta+cc2;
00356 }
00357 else{
00358 beta = 0.5-beta;
00359 R = (cl0-cc0)*alpha+(cb0-cc0)*beta+cc0;
00360 G = (cl1-cc1)*alpha+(cb1-cc1)*beta+cc1;
00361 B = (cl2-cc2)*alpha+(cb2-cc2)*beta+cc2;
00362 }
00363 }
00364 *r = (unsigned char)R;
00365 *g = (unsigned char)G;
00366 *b = (unsigned char)B;
00367 return;
00368 }
00369
00370 void MapEnvironmentInDirection(vector dd, double *r, double *g, double *b, imap *Map){
00371
00372 long j,pixel,k,ibeta,ialpha,kl,kr,kt,kb,w,kmin,kmax;
00373 double alpha,beta,R,G,B;
00374 double cc0,cc1,cc2,cl0,cl1,cl2,cr0,cr1,cr2,ct0,ct1,ct2,cb0,cb1,cb2;
00375 unsigned char *pP,*pR,*pG,*pB;
00376 vector d;
00377 R_m4by1(AntiCamera,dd[0],dd[1],dd[2],&d[0],&d[1],&d[2]);
00378 if(Map->pp < 0)return;
00379 BoxMapIntersect(d,&j,&alpha,&beta); if(j < 0){
00380 *r = 0; *g=255; *b=0;
00381 return;
00382 }
00383 w=Map->xmax/6;
00384 alpha = ((double)j+alpha)*(double)w;
00385 beta *= (double)Map->ymax;
00386 ialpha = (long)alpha; alpha -= (double)ialpha;
00387 ibeta=(long)beta; beta -= (double)ibeta;
00388 if(ialpha < 0)ialpha=0;
00389 if(ialpha >= Map->xmax)ialpha=Map->xmax-1;
00390 if(ibeta < 0)ibeta=0;
00391 if(ibeta >= Map->ymax)ibeta=Map->ymax-1;
00392 k = ibeta*Map->xmax+ialpha;
00393 kmin = j*w + 1;
00394 kmax = (j+1)*w - 2;
00395 if(ialpha < kmin)kl=k; else kl=k-1;
00396 if(ialpha > kmax) kr=k; else kr=k+1;
00397 if(ibeta < 1)kb=k; else kb=k-Map->xmax;
00398 if(ibeta > Map->ymax-2)kt=k; else kt=k+Map->xmax;
00399 pR=Map->p24R; pG=Map->p24G; pB=Map->p24B;
00400
00401 cc0 = (double)pR[k]; cc1 = (double)pG[k]; cc2 = (double)pB[k];
00402 cl0 = (double)pR[kl]; cl1 = (double)pG[kl]; cl2 = (double)pB[kl];
00403 cr0 = (double)pR[kr]; cr1 = (double)pG[kr]; cr2 = (double)pB[kr];
00404 ct0 = (double)pR[kt]; ct1 = (double)pG[kt]; ct2 = (double)pB[kt];
00405 cb0 = (double)pR[kb]; cb1 = (double)pG[kb]; cb2 = (double)pB[kb];
00406 if(alpha > 0.5){
00407 alpha = alpha-0.5;
00408 if(beta > 0.5){
00409 beta = beta-0.5;
00410 R = (cr0-cc0)*alpha+(ct0-cc0)*beta+cc0;
00411 G = (cr1-cc1)*alpha+(ct1-cc1)*beta+cc1;
00412 B = (cr2-cc2)*alpha+(ct2-cc2)*beta+cc2;
00413 }
00414 else{
00415 beta = 0.5-beta;
00416 R = (cr0-cc0)*alpha+(cb0-cc0)*beta+cc0;
00417 G = (cr1-cc1)*alpha+(cb1-cc1)*beta+cc1;
00418 B = (cr2-cc2)*alpha+(cb2-cc2)*beta+cc2;
00419 }
00420 }
00421 else{
00422 alpha = 0.5-alpha;
00423 if(beta > 0.5){
00424 beta = beta-0.5;
00425 R = (cl0-cc0)*alpha+(ct0-cc0)*beta+cc0;
00426 G = (cl1-cc1)*alpha+(ct1-cc1)*beta+cc1;
00427 B = (cl2-cc2)*alpha+(ct2-cc2)*beta+cc2;
00428 }
00429 else{
00430 beta = 0.5-beta;
00431 R = (cl0-cc0)*alpha+(cb0-cc0)*beta+cc0;
00432 G = (cl1-cc1)*alpha+(cb1-cc1)*beta+cc1;
00433 B = (cl2-cc2)*alpha+(cb2-cc2)*beta+cc2;
00434 }
00435 }
00436 *r = R;
00437 *g = G;
00438 *b = B;
00439 return;
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449 static void Transform_to_Moziac(double alpha, double beta,
00450 double *a, double *b){
00451 long brkindx,brkindy;
00452 *a=FLOOR(alpha); *b=FLOOR(beta);
00453 brkindx=((long)(*a) & 1L);
00454 brkindy=((long)(*b) & 1L);
00455 *a=(alpha - *a); *b=(beta - *b);
00456 if(brkindx){
00457 if(brkindy){ *a = 1.0 - *a; *b = 1.0 - *b; }
00458 else { *a = 1.0 - *a; }
00459 }
00460 else if(brkindy){ *b = 1.0 - *b; }
00461 return;
00462 }
00463
00464
00465 long MapFromProjection(imap *Map, short type, short clear,
00466 vector p , double *red
00467 , double *green
00468 , double *blue){
00469
00470 long ialpha,ibeta,i,j,k,kl,kr,kt,kb,pixel;
00471 double alpha,beta,a,b,cc0,cc1,cc2,cl0,cl1,cl2,
00472 cr0,cr1,cr2,ct0,ct1,ct2,cb0,cb1,cb2;
00473 unsigned char *pP,*pR,*pG,*pB;
00474
00475 if(Map->pp < 0)return 0;
00476 j=Map->xmax;
00477 if(Map->map == CYLINDER){
00478 hitcylinder(Map->n,Map->x,Map->y,Map->p
00479 ,p,&alpha,&beta);
00480 alpha *= Map->angle;
00481 }
00482 else if(Map->map == MAP_SPHERICAL){
00483 hitsphere(Map->n,Map->x,Map->y,Map->p
00484 ,p,&alpha,&beta);
00485 }
00486 else
00487 hitpoint(Map->n,Map->x,Map->y,Map->p
00488 ,p,&alpha,&beta);
00489 if(type == TILE){
00490 if(Map->moziac)Transform_to_Moziac(alpha,beta,&a,&b);
00491 else{
00492 a=(alpha-floor(alpha));
00493 b=(beta-floor(beta));
00494 }
00495 alpha=a*Map->xmax;
00496 beta=b*Map->ymax;
00497 }
00498 else{
00499 alpha=Map->xmax*alpha;
00500 beta =Map->ymax*beta;
00501 }
00502 ialpha = (long)alpha; alpha -= (double)ialpha;
00503 ibeta = (long)beta; beta -= (double)ibeta;
00504 if(ialpha < 0 || ialpha >= Map->xmax)return 0;
00505 if(ibeta < 0 || ibeta >= Map->ymax)return 0;
00506 k =ibeta*j+ialpha;
00507 if(type == TILE){
00508 if(Map->moziac){
00509 if(ialpha < 1)kl=1; else kl=k-1;
00510 if(ialpha > j-2)kr=k-1; else kr=k+1;
00511 if(ibeta < 1)kb=k+j; else kb=k-j;
00512 if(ibeta > Map->ymax-2)kt=k-j; else kt=k+j;
00513 }
00514 else{
00515 if(ialpha < 1)kl=k+j-1; else kl=k-1;
00516 if(ialpha > j-2)kr=ibeta*j; else kr=k+1;
00517 if(ibeta < 1)kb=(Map->ymax-1)*j+ialpha; else kb=k-j;
00518 if(ibeta > Map->ymax-2)kt=ialpha; else kt=k+j;
00519 }
00520 }
00521 else{
00522 if(ialpha < 1)kl=k; else kl=k-1;
00523 if(ialpha > j-2)kr=k; else kr=k+1;
00524 if(ibeta < 1)kb=k; else kb=k-j;
00525 if(ibeta > Map->ymax-2)kt=k; else kt=k+j;
00526 }
00527 pR=Map->p24R; pG=Map->p24G; pB=Map->p24B;
00528 if(clear == TRANSP){
00529 if(pR[k] == Map->kc[0] && pG[k] == Map->kc[1] && pB[k] == Map->kc[2])
00530 return 0;
00531 }
00532 cc0 = (double)pR[k]; cc1 = (double)pG[k]; cc2 = (double)pB[k];
00533 cl0 = (double)pR[kl]; cl1 = (double)pG[kl]; cl2 = (double)pB[kl];
00534 cr0 = (double)pR[kr]; cr1 = (double)pG[kr]; cr2 = (double)pB[kr];
00535 ct0 = (double)pR[kt]; ct1 = (double)pG[kt]; ct2 = (double)pB[kt];
00536 cb0 = (double)pR[kb]; cb1 = (double)pG[kb]; cb2 = (double)pB[kb];
00537 if(alpha > 0.5){
00538 alpha = alpha-0.5;
00539 if(beta > 0.5){
00540 beta = beta-0.5;
00541 *red = (cr0-cc0)*alpha+(ct0-cc0)*beta+cc0;
00542 *green = (cr1-cc1)*alpha+(ct1-cc1)*beta+cc1;
00543 *blue = (cr2-cc2)*alpha+(ct2-cc2)*beta+cc2;
00544 }
00545 else{
00546 beta = 0.5-beta;
00547 *red = (cr0-cc0)*alpha+(cb0-cc0)*beta+cc0;
00548 *green = (cr1-cc1)*alpha+(cb1-cc1)*beta+cc1;
00549 *blue = (cr2-cc2)*alpha+(cb2-cc2)*beta+cc2;
00550 }
00551 }
00552 else{
00553 alpha = 0.5-alpha;
00554 if(beta > 0.5){
00555 beta = beta-0.5;
00556 *red = (cl0-cc0)*alpha+(ct0-cc0)*beta+cc0;
00557 *green = (cl1-cc1)*alpha+(ct1-cc1)*beta+cc1;
00558 *blue = (cl2-cc2)*alpha+(ct2-cc2)*beta+cc2;
00559 }
00560 else{
00561 beta = 0.5-beta;
00562 *red = (cl0-cc0)*alpha+(cb0-cc0)*beta+cc0;
00563 *green = (cl1-cc1)*alpha+(cb1-cc1)*beta+cc1;
00564 *blue = (cl2-cc2)*alpha+(cb2-cc2)*beta+cc2;
00565 }
00566 }
00567 return 1;
00568 }
00569
00570 long MapByCoordinates(imap *Map,
00571 long obj, face *f,
00572 short type, short clear,
00573 vector p,
00574 double *red,
00575 double *green,
00576 double *blue){
00577
00578 long ialpha,ibeta,i,j,k,kl,kr,kt,kb,pixel;
00579 double alpha,beta,a,b,cc0,cc1,cc2,cl0,cl1,cl2,
00580 cr0,cr1,cr2,ct0,ct1,ct2,cb0,cb1,cb2,
00581 ve1,ve2,ve3,vp1,vp2,vp3,p1,p2,p3,
00582 detmax,dm,det1,det2,det3,
00583 t1x,t2x,t1y,t2y;
00584 unsigned char *pP,*pR,*pG,*pB;
00585 vertex *V,*v0,*v1,*v2;
00586
00587 if(Map->pp < 0)return 0;
00588 j=Map->xmax;
00589 if((V=Object[obj].Vbase) == NULL)return 0;
00590 v0=(V+(f->V[0]));
00591 v1=(V+(f->V[1]));
00592 v2=(V+(f->V[2]));
00593 ve1=v1->p[0] - v0->p[0]; ve2=v1->p[1] - v0->p[1]; ve3=v1->p[2] - v0->p[2];
00594 vp1=v2->p[0] - v0->p[0]; vp2=v2->p[1] - v0->p[1]; vp3=v2->p[2] - v0->p[2];
00595 p1=p[0]-v0->p[0];
00596 p2=p[1]-v0->p[1];
00597 p3=p[2]-v0->p[2];
00598 det1=ve1*vp2-vp1*ve2;
00599 det2=ve1*vp3-vp1*ve3;
00600 det3=ve2*vp3-vp2*ve3;
00601 k=0; detmax=1.e-3;
00602 if((dm=fabs(det1)) > detmax){k=1; detmax=dm;}
00603 if((dm=fabs(det2)) > detmax){k=2; detmax=dm;}
00604 if((dm=fabs(det3)) > detmax){k=3; detmax=dm;}
00605 if(k == 0)return 0;
00606 else if(k == 1){
00607 a=( vp2*p1-vp1*p2)/det1;
00608 b=(-ve2*p1+ve1*p2)/det1;
00609 }
00610 else if(k == 2){
00611 a=( vp3*p1-vp1*p3)/det2;
00612 b=(-ve3*p1+ve1*p3)/det2;
00613 }
00614 else if(k == 3){
00615 a=( vp3*p2-vp2*p3)/det3;
00616 b=(-ve3*p2+ve2*p3)/det3;
00617 }
00618
00619 t1x=f->uu[1] - f->uu[0]; t2x=f->uu[2] - f->uu[0];
00620 t1y=f->vv[1] - f->vv[0]; t2y=f->vv[2] - f->vv[0];
00621 alpha = f->uu[0] + a*t1x + b*t2x;
00622 beta = f->vv[0] + a*t1y + b*t2y;
00623 if(type == TILE){
00624 if(Map->moziac)Transform_to_Moziac(alpha,beta,&a,&b);
00625 else{
00626 a=(alpha-floor(alpha));
00627 b=(beta-floor(beta));
00628 }
00629 alpha=a*Map->xmax;
00630 beta=b*Map->ymax;
00631 }
00632 else{
00633 alpha=Map->xmax*alpha;
00634 beta =Map->ymax*beta;
00635 }
00636 ialpha = (long)alpha; alpha -= (double)ialpha;
00637 ibeta = (long)beta; beta -= (double)ibeta;
00638 if(ialpha < 0 || ialpha >= Map->xmax)return 0;
00639 if(ibeta < 0 || ibeta >= Map->ymax)return 0;
00640 k =ibeta*j+ialpha;
00641
00642 if(type == TILE){
00643 if(Map->moziac){
00644 if(ialpha < 1)kl=1; else kl=k-1;
00645 if(ialpha > j-2)kr=k-1; else kr=k+1;
00646 if(ibeta < 1)kb=k+j; else kb=k-j;
00647 if(ibeta > Map->ymax-2)kt=k-j; else kt=k+j;
00648 }
00649 else{
00650 if(ialpha < 1)kl=k+j-1; else kl=k-1;
00651 if(ialpha > j-2)kr=ibeta*j; else kr=k+1;
00652 if(ibeta < 1)kb=(Map->ymax-1)*j+ialpha; else kb=k-j;
00653 if(ibeta > Map->ymax-2)kt=ialpha; else kt=k+j;
00654 }
00655 }
00656 else{
00657 if(ialpha < 1)kl=k; else kl=k-1;
00658 if(ialpha > j-2)kr=k; else kr=k+1;
00659 if(ibeta < 1)kb=k; else kb=k-j;
00660 if(ibeta > Map->ymax-2)kt=k; else kt=k+j;
00661 }
00662
00663 pR=Map->p24R; pG=Map->p24G; pB=Map->p24B;
00664 if(clear == TRANSP){
00665 if(pR[k] == Map->kc[0] && pG[k] == Map->kc[1] && pB[k] == Map->kc[2])
00666 return 0;
00667 }
00668 cc0 = (double)pR[k]; cc1 = (double)pG[k]; cc2 = (double)pB[k];
00669 cl0 = (double)pR[kl]; cl1 = (double)pG[kl]; cl2 = (double)pB[kl];
00670 cr0 = (double)pR[kr]; cr1 = (double)pG[kr]; cr2 = (double)pB[kr];
00671 ct0 = (double)pR[kt]; ct1 = (double)pG[kt]; ct2 = (double)pB[kt];
00672 cb0 = (double)pR[kb]; cb1 = (double)pG[kb]; cb2 = (double)pB[kb];
00673 if(alpha > 0.5){
00674 alpha = alpha-0.5;
00675 if(beta > 0.5){
00676 beta = beta-0.5;
00677 *red = (cr0-cc0)*alpha+(ct0-cc0)*beta+cc0;
00678 *green = (cr1-cc1)*alpha+(ct1-cc1)*beta+cc1;
00679 *blue = (cr2-cc2)*alpha+(ct2-cc2)*beta+cc2;
00680 }
00681 else{
00682 beta = 0.5-beta;
00683 *red = (cr0-cc0)*alpha+(cb0-cc0)*beta+cc0;
00684 *green = (cr1-cc1)*alpha+(cb1-cc1)*beta+cc1;
00685 *blue = (cr2-cc2)*alpha+(cb2-cc2)*beta+cc2;
00686 }
00687 }
00688 else{
00689 alpha = 0.5-alpha;
00690 if(beta > 0.5){
00691 beta = beta-0.5;
00692 *red = (cl0-cc0)*alpha+(ct0-cc0)*beta+cc0;
00693 *green = (cl1-cc1)*alpha+(ct1-cc1)*beta+cc1;
00694 *blue = (cl2-cc2)*alpha+(ct2-cc2)*beta+cc2;
00695 }
00696 else{
00697 beta = 0.5-beta;
00698 *red = (cl0-cc0)*alpha+(cb0-cc0)*beta+cc0;
00699 *green = (cl1-cc1)*alpha+(cb1-cc1)*beta+cc1;
00700 *blue = (cl2-cc2)*alpha+(cb2-cc2)*beta+cc2;
00701 }
00702 }
00703 return 1;
00704 }
00705
00706 long MapTransByCoordinates(imap *Map, short type, long obj, face *f,
00707 vector p , double *trans){
00708 long ialpha,ibeta,i,j,k,kl,kr,kt,kb,pixel;
00709 double red,green,blue;
00710 double alpha,beta,a,b,cc0,cc1,cc2,cl0,cl1,cl2,
00711 cr0,cr1,cr2,ct0,ct1,ct2,cb0,cb1,cb2,
00712 ve1,ve2,ve3,vp1,vp2,vp3,p1,p2,p3,
00713 detmax,dm,det1,det2,det3,
00714 t1x,t2x,t1y,t2y;
00715 unsigned char *pP,*pR,*pG,*pB;
00716 vertex *V,*v0,*v1,*v2;
00717
00718 j=Map->xmaxtran;
00719 if((V=Object[obj].Vbase) == NULL)return 0;
00720 v0=(V+(f->V[0]));
00721 v1=(V+(f->V[1]));
00722 v2=(V+(f->V[2]));
00723 ve1=v1->p[0] - v0->p[0]; ve2=v1->p[1] - v0->p[1]; ve3=v1->p[2] - v0->p[2];
00724 vp1=v2->p[0] - v0->p[0]; vp2=v2->p[1] - v0->p[1]; vp3=v2->p[2] - v0->p[2];
00725 p1=p[0]-v0->p[0];
00726 p2=p[1]-v0->p[1];
00727 p3=p[2]-v0->p[2];
00728 det1=ve1*vp2-vp1*ve2;
00729 det2=ve1*vp3-vp1*ve3;
00730 det3=ve2*vp3-vp2*ve3;
00731 k=0; detmax=1.e-3;
00732 if((dm=fabs(det1)) > detmax){k=1; detmax=dm;}
00733 if((dm=fabs(det2)) > detmax){k=2; detmax=dm;}
00734 if((dm=fabs(det3)) > detmax){k=3; detmax=dm;}
00735 if(k == 0)return 0;
00736 else if(k == 1){
00737 a=( vp2*p1-vp1*p2)/det1;
00738 b=(-ve2*p1+ve1*p2)/det1;
00739 }
00740 else if(k == 2){
00741 a=( vp3*p1-vp1*p3)/det2;
00742 b=(-ve3*p1+ve1*p3)/det2;
00743 }
00744 else if(k == 3){
00745 a=( vp3*p2-vp2*p3)/det3;
00746 b=(-ve3*p2+ve2*p3)/det3;
00747 }
00748
00749 t1x=f->uu[1] - f->uu[0]; t2x=f->uu[2] - f->uu[0];
00750 t1y=f->vv[1] - f->vv[0]; t2y=f->vv[2] - f->vv[0];
00751 alpha = f->uu[0] + a*t1x + b*t2x;
00752 beta = f->vv[0] + a*t1y + b*t2y;
00753
00754 if(type == TILE){
00755 if(Map->moziac)Transform_to_Moziac(alpha,beta,&a,&b);
00756 else{
00757 a=(alpha-floor(alpha));
00758 b=(beta-floor(beta));
00759 }
00760 alpha=a*Map->xmaxtran;
00761 beta=b*Map->ymaxtran;
00762 }
00763 else{
00764 alpha=Map->xmaxtran*alpha;
00765 beta =Map->ymaxtran*beta;
00766 }
00767 ialpha = (long)alpha; alpha -= (double)ialpha;
00768 ibeta = (long)beta; beta -= (double)ibeta;
00769
00770 if(ialpha < 0 || ialpha >= Map->xmaxtran)return 0;
00771 if(ibeta < 0 || ibeta >= Map->ymaxtran)return 0;
00772 k =ibeta*j+ialpha;
00773 if(type == TILE){
00774 if(Map->moziac){
00775 if(ialpha < 1)kl=1; else kl=k-1;
00776 if(ialpha > j-2)kr=k-1; else kr=k+1;
00777 if(ibeta < 1)kb=k+j; else kb=k-j;
00778 if(ibeta > Map->ymaxtran-2)kt=k-j; else kt=k+j;
00779 }
00780 else{
00781 if(ialpha < 1)kl=k+j-1; else kl=k-1;
00782 if(ialpha > j-2)kr=ibeta*j; else kr=k+1;
00783 if(ibeta < 1)kb=(Map->ymaxtran-1)*j+ialpha; else kb=k-j;
00784 if(ibeta > Map->ymaxtran-2)kt=ialpha; else kt=k+j;
00785 }
00786 }
00787 else{
00788 if(ialpha < 1)kl=k; else kl=k-1;
00789 if(ialpha > j-2)kr=k; else kr=k+1;
00790 if(ibeta < 1)kb=k; else kb=k-j;
00791 if(ibeta > Map->ymaxtran-2)kt=k; else kt=k+j;
00792 }
00793 pR=Map->p24Rtran; pG=Map->p24Gtran; pB=Map->p24Btran;
00794 cc0 = (double)pR[k]; cc1 = (double)pG[k]; cc2 = (double)pB[k];
00795 cl0 = (double)pR[kl]; cl1 = (double)pG[kl]; cl2 = (double)pB[kl];
00796 cr0 = (double)pR[kr]; cr1 = (double)pG[kr]; cr2 = (double)pB[kr];
00797 ct0 = (double)pR[kt]; ct1 = (double)pG[kt]; ct2 = (double)pB[kt];
00798 cb0 = (double)pR[kb]; cb1 = (double)pG[kb]; cb2 = (double)pB[kb];
00799 if(alpha > 0.5){
00800 alpha = alpha-0.5;
00801 if(beta > 0.5){
00802 beta = beta-0.5;
00803 red = (cr0-cc0)*alpha+(ct0-cc0)*beta+cc0;
00804 green = (cr1-cc1)*alpha+(ct1-cc1)*beta+cc1;
00805 blue = (cr2-cc2)*alpha+(ct2-cc2)*beta+cc2;
00806 }
00807 else{
00808 beta = 0.5-beta;
00809 red = (cr0-cc0)*alpha+(cb0-cc0)*beta+cc0;
00810 green = (cr1-cc1)*alpha+(cb1-cc1)*beta+cc1;
00811 blue = (cr2-cc2)*alpha+(cb2-cc2)*beta+cc2;
00812 }
00813 }
00814 else{
00815 alpha = 0.5-alpha;
00816 if(beta > 0.5){
00817 beta = beta-0.5;
00818 red = (cl0-cc0)*alpha+(ct0-cc0)*beta+cc0;
00819 green = (cl1-cc1)*alpha+(ct1-cc1)*beta+cc1;
00820 blue = (cl2-cc2)*alpha+(ct2-cc2)*beta+cc2;
00821 }
00822 else{
00823 beta = 0.5-beta;
00824 red = (cl0-cc0)*alpha+(cb0-cc0)*beta+cc0;
00825 green = (cl1-cc1)*alpha+(cb1-cc1)*beta+cc1;
00826 blue = (cl2-cc2)*alpha+(cb2-cc2)*beta+cc2;
00827 }
00828 }
00829 *trans = (1.0- 1.3071895e-3*(red+green+blue));
00830 return 1;
00831 }
00832
00833 long MapTextureByCoordinates(long obj,face *f, vector p,
00834 double *alpha, double *beta, double *gamma){
00835
00836 long k;
00837 double a,b,
00838 ve1,ve2,ve3,vp1,vp2,vp3,p1,p2,p3,
00839 detmax,dm,det1,det2,det3,
00840 t1x,t2x,t1y,t2y,t1w,t2w;
00841 unsigned char *pP,*pR,*pG,*pB;
00842 vertex *V,*v0,*v1,*v2;
00843
00844 if((V=Object[obj].Vbase) == NULL)return 0;
00845 v0=(V+(f->V[0]));
00846 v1=(V+(f->V[1]));
00847 v2=(V+(f->V[2]));
00848 ve1=v1->p[0] - v0->p[0]; ve2=v1->p[1] - v0->p[1]; ve3=v1->p[2] - v0->p[2];
00849 vp1=v2->p[0] - v0->p[0]; vp2=v2->p[1] - v0->p[1]; vp3=v2->p[2] - v0->p[2];
00850 p1=p[0]-v0->p[0];
00851 p2=p[1]-v0->p[1];
00852 p3=p[2]-v0->p[2];
00853 det1=ve1*vp2-vp1*ve2;
00854 det2=ve1*vp3-vp1*ve3;
00855 det3=ve2*vp3-vp2*ve3;
00856 k=0; detmax=1.e-3;
00857 if((dm=fabs(det1)) > detmax){k=1; detmax=dm;}
00858 if((dm=fabs(det2)) > detmax){k=2; detmax=dm;}
00859 if((dm=fabs(det3)) > detmax){k=3; detmax=dm;}
00860 if(k == 0)return 0;
00861 else if(k == 1){
00862 a=( vp2*p1-vp1*p2)/det1;
00863 b=(-ve2*p1+ve1*p2)/det1;
00864 }
00865 else if(k == 2){
00866 a=( vp3*p1-vp1*p3)/det2;
00867 b=(-ve3*p1+ve1*p3)/det2;
00868 }
00869 else if(k == 3){
00870 a=( vp3*p2-vp2*p3)/det3;
00871 b=(-ve3*p2+ve2*p3)/det3;
00872 }
00873
00874 t1x=f->uu[1] - f->uu[0]; t2x=f->uu[2] - f->uu[0];
00875 t1y=f->vv[1] - f->vv[0]; t2y=f->vv[2] - f->vv[0];
00876 t1w=f->ww[1] - f->ww[0]; t2w=f->ww[2] - f->ww[0];
00877 *alpha = f->uu[0] + a*t1x + b*t2x;
00878 *beta = f->vv[0] + a*t1y + b*t2y;
00879 *gamma = f->ww[0] + a*t1w + b*t2w;
00880
00881 return 1;
00882 }
00883
00885
00892 long ShadedScanline(
00893 long scanline ,double d2,
00894 UCHAR *Red, UCHAR *Green, UCHAR *Blue,
00895 double *Zground, long Wsky, double Rsky,
00896 long *Zglass[], long *ZglassO[], double *Zglassd[],
00897 long *Zbuffer, long *Zobject,
00898 double *Zdepth, double *Zposn){
00899 face *f;
00900 vertex *v;
00901 imap *Map;
00902 matl *Mat;
00903 BOOL bSmooth;
00904 long i,j,k,f1,obj;
00905 double det,alpha,beta;
00906 vector n,nn,dn,v0,v1,v2;
00907 UCHAR *ZobjChar;
00908 if(VGA_screen == NULL)ZobjChar=DummyShadow;
00909 else ZobjChar = &VGA_screen[scanline*XMAX];
00910 i=XMIN;
00911 LOOP:
00912 f1=Zbuffer[i];
00913 if(f1 >= 0){
00914 obj=Zobject[i];
00915 v=Object[obj].Vbase;
00916 f=Object[obj].Fbase + f1;
00917 if(f->ffmap >= 0){
00918 if((long)f->ffmap >= Object[obj].NoMaps)Map=NULL;
00919 else Map=(Object[obj].Mbase+(long)f->ffmap);
00920 }
00921 else Map=NULL;
00922
00923 if(f->ffmat < 0 || f->ffmat >= Object[obj].NoMats)Mat=NULL;
00924 else Mat=(Object[obj].Tbase+(long)f->ffmat);
00925
00926 if(Mat != NULL)bSmooth=Mat->bSmooth;
00927 else bSmooth=f->bSmooth;
00928 if(!bSmooth){
00929 VECCOPY(f->n,n)
00930 }
00931 else{
00932 det=(
00933 (v[f->V[2]].y - v[f->V[0]].y) * (v[f->V[1]].x - v[f->V[0]].x)
00934 -(v[f->V[2]].x - v[f->V[0]].x) * (v[f->V[1]].y - v[f->V[0]].y)
00935 );
00936 if(det == 0){
00937 VECCOPY(f->n,n)
00938 }
00939 else{
00940 VECCOPY(f->pn[0],v0)
00941 VECCOPY(f->pn[1],v1)
00942 VECCOPY(f->pn[2],v2)
00943 det=1.0/det;
00944 alpha= (double)(
00945 (v[f->V[2]].y - v[f->V[0]].y) * (Zposn[i] - v[f->V[0]].x)
00946 -(v[f->V[2]].x - v[f->V[0]].x) * ((double)scanline - v[f->V[0]].y)
00947 )*det;
00948 beta= (double)(
00949 ((double)scanline - v[f->V[0]].y) * (v[f->V[1]].x - v[f->V[0]].x)
00950 -(Zposn[i] - v[f->V[0]].x) * (v[f->V[1]].y - v[f->V[0]].y)
00951 )*det;
00952 n[0]=v0[0] + alpha*(v1[0] - v0[0])
00953 + beta*(v2[0] - v0[0]);
00954 n[1]=v0[1] + alpha*(v1[1] - v0[1])
00955 + beta*(v2[1] - v0[1]);
00956 n[2]=v0[2] + alpha*(v1[2] - v0[2])
00957 + beta*(v2[2] - v0[2]);
00958 normalize(n);
00959 }
00960 }
00961 GetRowPixelValue(scanline,i,Map,Mat,f,obj,n,Red,Green,Blue,
00962 Zdepth,ZobjChar);
00963 if(Zglass[0][i] > -1)AttenuateGlass(scanline,i,Red,Green,Blue,
00964 Zglass,ZglassO,Zglassd,Zposn);
00965 j=i+1;
00966 if(j < XMAX){
00967 while((Zbuffer[j] == f1) && (Zobject[j] == Zobject[i]))
00968 {j++; if(j == XMAX)break; }
00969 if(j > i+1){
00970 if(j > i+2){
00971 if((det==0) || !(bSmooth)){
00972 dn[0]=0; dn[1]=0; dn[2]=0;
00973 }
00974 else{
00975 dn[0]=( (v[f->V[1]].y - v[f->V[2]].y) * v0[0]
00976 + (v[f->V[2]].y - v[f->V[0]].y) * v1[0]
00977 + (v[f->V[0]].y - v[f->V[1]].y) * v2[0]
00978 )*det;
00979 dn[1]=( (v[f->V[1]].y - v[f->V[2]].y) * v0[1]
00980 + (v[f->V[2]].y - v[f->V[0]].y) * v1[1]
00981 + (v[f->V[0]].y - v[f->V[1]].y) * v2[1]
00982 )*det;
00983 dn[2]=( (v[f->V[1]].y - v[f->V[2]].y) * v0[2]
00984 + (v[f->V[2]].y - v[f->V[0]].y) * v1[2]
00985 + (v[f->V[0]].y - v[f->V[1]].y) * v2[2]
00986 )*det;
00987 }
00988 for(k=i+1; k<j-1; k++){
00989 VECSUM(n,dn,n)
00990 VECCOPY(n,nn)
00991 normalize(nn);
00992 GetRowPixelValue(scanline,k,Map,Mat,f,obj,nn,Red,Green,Blue,
00993 Zdepth,ZobjChar);
00994 if(Zglass[0][k] > -1)AttenuateGlass(scanline,k,Red,Green,Blue,
00995 Zglass,ZglassO,Zglassd,Zposn);
00996 }
00997 }
00998
00999 if((det==0) || !(bSmooth))VECCOPY(f->n,n)
01000 else{
01001 alpha = (double)(
01002 (v[f->V[2]].y - v[f->V[0]].y) * (Zposn[j-1] - v[f->V[0]].x)
01003 -(v[f->V[2]].x - v[f->V[0]].x) * ((double)scanline - v[f->V[0]].y)
01004 )*det;
01005 beta = (double)(
01006 ((double)scanline - v[f->V[0]].y) * (v[f->V[1]].x - v[f->V[0]].x)
01007 -(Zposn[j-1] - v[f->V[0]].x) * (v[f->V[1]].y - v[f->V[0]].y)
01008 )*det;
01009 n[0]=v0[0] + alpha*(v1[0] - v0[0])
01010 + beta*(v2[0] - v0[0]);
01011 n[1]=v0[1] + alpha*(v1[1] - v0[1])
01012 + beta*(v2[1] - v0[1]);
01013 n[2]=v0[2] + alpha*(v1[2] - v0[2])
01014 + beta*(v2[2] - v0[2]);
01015 normalize(n);
01016 }
01017 GetRowPixelValue(scanline,j-1,Map,Mat,f,obj,n,Red,Green,Blue,
01018 Zdepth,ZobjChar);
01019 if(Zglass[0][j-1] > -1)AttenuateGlass(scanline,j-1,Red,Green,Blue,
01020 Zglass,ZglassO,Zglassd,Zposn);
01021 }
01022 }
01023 i=j;
01024 }
01025 else{
01026 PutBackPlanes(i,scanline,d2,Red,Green,Blue,
01027 Zground,Zobject,Zdepth,
01028 ZobjChar,Wsky,Rsky);
01029 if(Zglass[0][i] > -1)AttenuateGlass(scanline,i,Red,Green,Blue,
01030 Zglass,ZglassO,Zglassd,Zposn);
01031 i++;
01032 }
01033 if(i < XMAX)goto LOOP;
01034 return 0;
01035 }
01036
01044 long FastAntiAliasShadedScanline(
01045 long scanline ,long aaline, double d2,
01046 UCHAR *Red, UCHAR *Green, UCHAR *Blue,
01047 double *Zground, long Wsky, double Rsky,
01048 long *Xbuffer, long *Xobject,
01049 long *Zglass[], long *ZglassO[], double *Zglassd[],
01050 long *Zbuffer, long *Zobject,
01051 double *Zdepth, double *Zposn){
01052 face *f;
01053 vertex *v;
01054 imap *Map;
01055 matl *Mat;
01056 BOOL bSmooth;
01057 long i,j,k,l,f1,obj,AlreadyCalculated;
01058 double det,alpha,beta;
01059 vector n,v0,v1,v2;
01060 UCHAR *ZobjChar;
01061 if(VGA_screen == NULL)ZobjChar=DummyShadow;
01062 else ZobjChar = &VGA_screen[scanline*XMAX];
01063 i=0; l=i-1;
01064 for(k=0;k<XMAX;k+=aaXstep){
01065 for(j=0;j<aaXstep;j++){
01066 f1=Zbuffer[i]; obj=Zobject[i];
01067 if(f1 == Xbuffer[i] && obj == Xobject[i])AlreadyCalculated=1;
01068 else if(j == 0)AlreadyCalculated=0;
01069 else if(f1 == Zbuffer[i-1] && obj == Zobject[i-1]){
01070 AlreadyCalculated=1;
01071 Red[i] = Red[l]; Green[i]=Green[l]; Blue[i]=Blue[l];
01072 }
01073 else AlreadyCalculated=0;
01074 if(!AlreadyCalculated){
01075 if(f1 >= 0){
01076 v=Object[obj].Vbase;
01077 f=Object[obj].Fbase + f1;
01078 if(f->ffmap >= 0){
01079 if((long)f->ffmap >= Object[obj].NoMaps)Map=NULL;
01080 else Map=(Object[obj].Mbase+(long)f->ffmap);
01081 }
01082 else Map=NULL;
01083 if(f->ffmat < 0 || f->ffmat >= Object[obj].NoMats)Mat=NULL;
01084 else Mat=(Object[obj].Tbase+(long)f->ffmat);
01085 if(Mat != NULL)bSmooth=Mat->bSmooth;
01086 else bSmooth=f->bSmooth;
01087 if(!bSmooth)VECCOPY(f->n,n)
01088 else{
01089 det=(
01090 (v[f->V[2]].y - v[f->V[0]].y) * (v[f->V[1]].x - v[f->V[0]].x)
01091 -(v[f->V[2]].x - v[f->V[0]].x) * (v[f->V[1]].y - v[f->V[0]].y)
01092 );
01093 if(det == 0){ VECCOPY(f->n,n) }
01094 else{
01095 VECCOPY(f->pn[0],v0)
01096 VECCOPY(f->pn[1],v1)
01097 VECCOPY(f->pn[2],v2)
01098 det=1.0/det;
01099 alpha= (double)(
01100 (v[f->V[2]].y - v[f->V[0]].y) *
01101 (Zposn[i] - v[f->V[0]].x)
01102 -(v[f->V[2]].x - v[f->V[0]].x) *
01103 ((double)scanline - v[f->V[0]].y)
01104 )*det;
01105 beta= (double)(
01106 ((double)scanline - v[f->V[0]].y) *
01107 (v[f->V[1]].x - v[f->V[0]].x)
01108 -(Zposn[i] - v[f->V[0]].x) *
01109 (v[f->V[1]].y - v[f->V[0]].y)
01110 )*det;
01111 n[0]=v0[0] + alpha*(v1[0] - v0[0]) + beta*(v2[0] - v0[0]);
01112 n[1]=v0[1] + alpha*(v1[1] - v0[1]) + beta*(v2[1] - v0[1]);
01113 n[2]=v0[2] + alpha*(v1[2] - v0[2]) + beta*(v2[2] - v0[2]);
01114 normalize(n);
01115 }
01116 }
01117 GetRowPixelValue(scanline,i,Map,Mat,f,obj,n,Red,Green,Blue,
01118 Zdepth,ZobjChar);
01119 if(Zglass[0][i] > -1)AttenuateGlass(scanline,i,Red,Green,Blue,
01120 Zglass,ZglassO,Zglassd,Zposn);
01121 }
01122 else{
01123 PutBackPlanes(i,scanline,d2,Red,Green,Blue,
01124 Zground,Zobject,Zdepth,ZobjChar,Wsky,Rsky);
01125 if(Zglass[0][i] > -1)AttenuateGlass(scanline,i,Red,Green,Blue,
01126 Zglass,ZglassO,Zglassd,Zposn);
01127 }
01128 }
01129 i++; l++;
01130 }
01131 }
01132 return 0;
01133 }
01134
01135
01136
01137
01138
01139 void GetSkyLocation(void){
01140 double b;
01141 long i;
01142 for(i=XMIN;i<XMAX;i++){
01143 if(Sky.type == SKYMAPPED){
01144 b= (CamPhi+atan2(D1[i],1.000))/PI*180.0 * 4.0 ;
01145 while(b < -180.0)b = b + 360.0;
01146 while(b >= 180.0)b = b - 360.0;
01147 ZskyBuffer[XMAX-1-i]=(short)((b+180.0)*skyXscale);
01148 }
01149 else{
01150 ZskyBuffer[XMAX-1-i]=0;
01151 }
01152 }
01153 }
01154
01155 long PutBackIntersection(long scanline, double d2,
01156 UCHAR *Alfa, double *Zground,
01157 long *Zglass[], long *ZglassO[], double *Zglassd[],
01158 long *Zbuffer, long *Zobject,
01159 double *Zdepth, double *Zposn, double *Rsky){
01160 long i,j,Wsky;
01161 double b,c,mu;
01162 if(Sky.type == SKYGRADED){
01163
01164 *Rsky=fabs((double)(Ycentre-scanline))/(double)Ycentre;
01165 }
01166 else if(Sky.type == SKYMAPPED){
01167 Wsky=0;
01168 b=90.0 - (CamAlpha+atan2(d2,1.000))/PI*180.0 * 2;
01169 while(b < 0.0)b += 90.0;
01170 while(b > 180.0)b -= 90.0;
01171 if(b > 0){
01172 if(b > 90)Wsky=(short)((180-b)*skyYscale);
01173 else Wsky=(short)(b*skyYscale);
01174 Wsky = min(Wsky,skyBmax);
01175 }
01176 }
01177 for(i=XMIN;i<XMAX;i++){
01178 Zbuffer[i] = -1;
01179 Zdepth [i] = FARAWAY;
01180 Zposn [i] = (double)i+0.5;
01181 for(j=0;j<NGLASS;j++){
01182 Zglassd[j][i] = FARAWAY;
01183 ZglassO[j][i] = -1;
01184 Zglass [j][i] = -1;
01185 }
01186 Zobject[i] = -2;
01187 Alfa [i] = 0;
01188 if(R_Nground > 0){
01189 b=Ground.n[0]*D1[i]+Ground.n[1]+Ground.n[2]*d2;
01190
01191
01192
01193
01194
01195 if(fabs(b) > 1.e-4){
01196 c=dot(Ground.n,Ground.p);
01197 mu=c/b;
01198 if(mu > 0.0){
01199 Zdepth[i] = mu;
01200 Zground[i]= mu;
01201 Zobject[i]= -1;
01202 }
01203 }
01204 }
01205 }
01206 return Wsky;
01207 }
01208
01209 void GetGroundLight(vector p0, double *R, double *G ,double *B){
01210
01211 long j,brkindx;
01212 double c,cc,alpha,beta,Iab,IsR,IsG,IsB,Bump_Scale,IdR,IdG,IdB,xRGB[3]={0.0,0.0,0.0};
01213 vector p1,p2,ripple,gn,gnn,bv;
01214 double red,green,blue,map;
01215 IdR=IdG=IdB=0.0;
01216 if(Ground.texture > 0 && (Ground.texture < 4 || Ground.texture > 9)){
01217 switch(Ground.texture){
01218 case 1:
01219 calcripple(p0,Ground.p,wave_phase,Ground.lengthy,1.0,
01220 Ground.height,ripple);
01221 Bump_Scale = - dot(p0,Ground.n)/R_length(p0);
01222 vecscale(Bump_Scale,ripple,ripple);
01223 vecsum(ripple,Ground.n,gn);
01224 normalize(gn);
01225 IsR=IsG=IsB=0.0;
01226 break;
01227 case 2:
01228
01229
01230
01231 IsR=IsG=IsB=0.0;
01232 break;
01233 case 3:
01234 Ocean(p0,Ground.n,gn);
01235 IsR=IsG=IsB=0.0;
01236 break;
01237 case 10:
01238 hitpoint(Ground.n,Ground.dx,Ground.dy,Ground.p,p0,&alpha,&beta);
01239 Dnoise2(gn,alpha*10.0,beta*10.0,0.0);
01240 Bump_Scale = dot(p0,Ground.n)/R_length(p0);
01241 Bump_Scale = min(0.5, Bump_Scale*2.0)*Ground.height*0.5;
01242 vecscale(Bump_Scale,gn,gn);
01243 vecsum(Ground.n,gn,gn);
01244 normalize(gn);
01245 break;
01246 case 16: {
01247 }
01248 break;
01249 default:
01250 veccopy(Ground.n,gn);
01251 break;
01252 }
01253 }
01254 else {
01255 veccopy(Ground.n,gn);
01256 }
01257
01258 for(j=0;j<Nlights;j++)if(Lights[j].type != SHADOWS &&
01259 Lights[j].type != DUMMYL){
01260 vecsub(Lights[j].p,p0,p1);
01261 cc=R_length(p1);
01262 vecscale(1.0/cc,p1,p2);
01263 Iab = Ground.ambient_light+(1.0-Ground.ambient_light)*fabs(DOT(p2,gn));
01264 if(Lights[j].dc){
01265 cc = DepthCueLight(j,cc);
01266 Iab *= cc;
01267 }
01268 if(Lights[j].type == SPOTLIGHT){
01269 if((alpha=DOT(p2,Lights[j].d)) < Lights[j].dot2)
01270 Iab=Ground.ambient_light;
01271 else if(alpha < Lights[j].dot1){
01272 Iab=Ground.ambient_light+(Iab-Ground.ambient_light)*
01273 (alpha-Lights[j].dot2)*Lights[j].falloff;
01274 }
01275 if(Iab > Ground.ambient_light && Lights[j].shadow_buffer != NULL)
01276 PointInShadow(p0,j,&Iab);
01277 }
01278 IdR += Iab*Lights[j].Ire;
01279 IdG += Iab*Lights[j].Igr;
01280 IdB += Iab*Lights[j].Ibl;
01281 if(Ground.shiny){
01282 vecsub(p1,p0,bv);
01283 normalize(bv);
01284 c=fabs(dot(bv,gn));
01285 if(c > 0.0){
01286 Iab = spec_gro[min(max_spec,(long)(c*max_spec))];
01287 if(Lights[j].dc)Iab *= cc;
01288 IsR += Iab*Lights[j].Ire;
01289 IsG += Iab*Lights[j].Igr;
01290 IsB += Iab*Lights[j].Ibl;
01291 }
01292 }
01293 }
01294 switch(Ground.texture){
01295 case 1:
01296 case 2:
01297 case 3:
01298 *R = min( ((double)Ground.color[0]*IdR + IsR*255), 255);
01299 *G = min( ((double)Ground.color[1]*IdG + IsG*255), 255);
01300 *B = min( ((double)Ground.color[2]*IdB + IsB*255), 255);
01301 break;
01302 case 4:
01303 hitpoint2(Ground.n,Ground.dx,Ground.dy,Ground.p,p0,&alpha,&beta);
01304 brkindx = (long)FLOOR(alpha) + (long)FLOOR(beta);
01305 if(brkindx & 1){
01306 *R = (double)Ground.acolor[0]*IdR;
01307 *G = (double)Ground.acolor[1]*IdG;
01308 *B = (double)Ground.acolor[2]*IdB;
01309 }
01310 else{
01311 *R = (double)Ground.color[0]*IdR;
01312 *G = (double)Ground.color[1]*IdG;
01313 *B = (double)Ground.color[2]*IdB;
01314 }
01315 break;
01316 case 5:
01317 hitpoint(Ground.n,Ground.dx,Ground.dy,Ground.p,p0,&alpha,&beta);
01318 alpha=(alpha-floor(alpha));
01319 beta=(beta-floor(beta));
01320 if(beta < 0.1 || alpha < 0.1){
01321 *R = (double)Ground.acolor[0]*IdR;
01322 *G = (double)Ground.acolor[1]*IdG;
01323 *B = (double)Ground.acolor[2]*IdB;
01324 }
01325 else{
01326 *R = (double)Ground.color[0]*IdR;
01327 *G = (double)Ground.color[1]*IdG;
01328 *B = (double)Ground.color[2]*IdB;
01329 }
01330 break;
01331 case 6:
01332 hitpoint(Ground.n,Ground.dx,Ground.dy,Ground.p,p0,&alpha,&beta);
01333 alpha=(alpha-floor(alpha));
01334 beta=(beta-floor(beta));
01335 if(alpha < 0.1){
01336 *R = (double)Ground.acolor[0]*IdR;
01337 *G = (double)Ground.acolor[1]*IdG;
01338 *B = (double)Ground.acolor[2]*IdB;
01339 }
01340 else{
01341 *R = (double)Ground.color[0]*IdR;
01342 *G = (double)Ground.color[1]*IdG;
01343 *B = (double)Ground.color[2]*IdB;
01344 }
01345 break;
01346 case 7:
01347 hitpoint(Ground.n,Ground.dx,Ground.dyy,Ground.p,p0,&alpha,&beta);
01348 alpha=(alpha-floor(alpha))-0.5;
01349 beta=(beta-floor(beta))-0.5;
01350 if(beta*beta+alpha*alpha < Ground.range){
01351 *R = (double)Ground.acolor[0]*IdR;
01352 *G = (double)Ground.acolor[1]*IdG;
01353 *B = (double)Ground.acolor[2]*IdB;
01354 }
01355 else{
01356 *R = (double)Ground.color[0]*IdR;
01357 *G = (double)Ground.color[1]*IdG;
01358 *B = (double)Ground.color[2]*IdB;
01359 }
01360 break;
01361 case 8:
01362 hitpoint(Ground.n,Ground.dx,Ground.dyy,Ground.p,p0,&alpha,&beta);
01363 alpha=fabs((alpha-floor(alpha))-0.5);
01364 beta=fabs((beta-floor(beta))-0.5);
01365 if((beta < 0.3 && alpha < 0.1) || (alpha < 0.3 && beta < 0.1)){
01366 *R = (double)Ground.acolor[0]*IdR;
01367 *G = (double)Ground.acolor[1]*IdG;
01368 *B = (double)Ground.acolor[2]*IdB;
01369 }
01370 else{
01371 *R = (double)Ground.color[0]*IdR;
01372 *G = (double)Ground.color[1]*IdG;
01373 *B = (double)Ground.color[2]*IdB;
01374 }
01375 break;
01376 case 9:
01377 hitpoint(Ground.n,Ground.dx,Ground.dy,Ground.p,p0,&alpha,&beta);
01378 alpha=(alpha-floor(alpha));
01379 beta=(beta-floor(beta));
01380 if((beta > 0.95 || (beta > 0.45 && beta < 0.5)) ||
01381 (beta < 0.5 && ( (alpha > 0.45 && alpha < 0.5) || alpha > 0.95) ) ||
01382 (beta > 0.5 && ((alpha > 0.25 && alpha < 0.3) ||
01383 (alpha > 0.7 && alpha < 0.75)))
01384 ){
01385 *R = (double)Ground.acolor[0]*IdR;
01386 *G = (double)Ground.acolor[1]*IdG;
01387 *B = (double)Ground.acolor[2]*IdB;
01388 }
01389 else{
01390 *R = (double)Ground.color[0]*IdR;
01391 *G = (double)Ground.color[1]*IdG;
01392 *B = (double)Ground.color[2]*IdB;
01393 }
01394 break;
01395 case 10:
01396 *R = (double)Ground.color[0]*IdR;
01397 *G = (double)Ground.color[1]*IdG;
01398 *B = (double)Ground.color[2]*IdB;
01399 break;
01400 case 16:
01401 *R = xRGB[0]*IdR; *G = xRGB[1]*IdG; *B = xRGB[2]*IdB;
01402 break;
01403 default:
01404 map=0;
01405
01406 if(Ground.mapped){
01407 map=MapFromProjection(&Ground.map,Ground.maptype,0,
01408 p0,&red,&green,&blue);
01409 }
01410 if(map == 1){
01411 *R = (red*IdR);
01412 *G = (green*IdG);
01413 *B = (blue*IdB);
01414 }
01415 else{
01416 *R = (double)Ground.color[0]*IdR;
01417 *G = (double)Ground.color[1]*IdG;
01418 *B = (double)Ground.color[2]*IdB;
01419 }
01420 break;
01421 }
01422 }
01423
01424
01425
01426 double DepthCueLight(long j, double cc){
01427 double d;
01428 return 1.0/(Lights[j].dc_c + cc*(Lights[j].dc_l + cc*Lights[j].dc_q));
01429 }
01430
01431 void GetPixelLighting(matl *Mat, vector p, vector n, double pdotn, double ddotn,
01432 long obj, face *f,
01433 double *IdR, double *IdG, double *IdB,
01434 double *IsR, double *IsG, double *IsB){
01435 long j,matsp;
01436 double cc,alpha,c,ldotn,falloff,Iab,amblight;
01437 vector bv,pl,pr;
01438 BOOL bShiny;
01439 for(j=0;j<Nlights;j++)if(Lights[j].type != SHADOWS &&
01440 Lights[j].type != DUMMYL){
01441 VECSUB(Lights[j].p,p,pl)
01442 cc=R_length(pl);
01443 VECSCALE(1.0/cc,pl,pr)
01444
01445
01446 ldotn=DOT(pr,n);
01447 if((ldotn > 1.e-6)){
01448 amblight=Object[obj].ambient_light;
01449
01450 c = ldotn;
01451 if(Lights[j].type == SPOTLIGHT){
01452
01453
01454
01455
01456
01457 if((alpha=DOT(pr,Lights[j].d)) < Lights[j].dot2)falloff=0;
01458 else if(alpha < Lights[j].dot1){
01459 falloff=(alpha-Lights[j].dot2)*Lights[j].falloff;
01460 }
01461 else falloff=1.0;
01462 c *= falloff;
01463 if(c > 0.0 && Lights[j].shadow_buffer != NULL &&
01464 Object[obj].show_shadow)PointInShadow(p,j,&c);
01465 }
01466 Iab = amblight+(1.0-amblight)*c;
01467 }
01468 else{
01469 Iab=Object[obj].ambient_light;
01470 falloff=1.0;
01471 }
01472 if(Lights[j].dc){
01473 cc = DepthCueLight(j,cc);
01474 Iab *= cc;
01475 }
01476 *IdR += Iab*Lights[j].Ire;
01477 *IdG += Iab*Lights[j].Igr;
01478 *IdB += Iab*Lights[j].Ibl;
01479
01480 if(Mat != NULL){bShiny=Mat->bShiny; matsp=Mat->gloss;}
01481 else {bShiny=f->bShiny;; matsp=8;}
01482 if(bShiny){
01483 VECSUB(pl,p,bv)
01484 normalize(bv);
01485 c=DOT(bv,n);
01486 if(c > 0.0)Iab = spec_pow[matsp][min(max_spec,(long)(c*max_spec))];
01487 else Iab = 0;
01488 if(Lights[j].type == SPOTLIGHT)Iab *= falloff;
01489 if(Lights[j].dc)Iab *= cc;
01490 *IsR += Iab*Lights[j].Ire;
01491 *IsG += Iab*Lights[j].Igr;
01492 *IsB += Iab*Lights[j].Ibl;
01493 }
01494 }
01495 }
01496
01497 static void PutBackPlanes(long i, long scanline, double d2,
01498 UCHAR *Red, UCHAR *Green, UCHAR *Blue,
01499 double *Zground, long *Zobject, double *Zdepth,
01500 UCHAR *ZobjChar, long Wsky, double Rsky){
01501 vector p0;
01502 double red,green,blue;
01503 long ix;
01504 if(Zobject[i] == -1){
01505 p0[0]=(((double)i-(double)Xcentre)/scalex*Zground[i]);
01506 p0[1]=min(FARAWAY,Zdepth[i]);
01507 p0[2]=(((double)Ycentre-(double)scanline)/scaley*Zground[i]);
01508 GetGroundLight(p0,&red,&green,&blue);
01509 Red [i] = (unsigned char)min(255.0,red);
01510 Green[i] = (unsigned char)min(255.0,green);
01511 Blue [i] = (unsigned char)min(255.0,blue);
01512 if((ZobjChar[i] & 1) == 1){
01513 Red[i] *= shadow_density;
01514 Green[i] *= shadow_density;
01515 Blue[i] *= shadow_density;
01516 }
01517 if(mirror_ground == 1){
01518 Add_Ground_Mirror(scanline,i,p0,&Red[i],&Green[i],&Blue[i]);
01519 }
01520 }
01521 else if(Nsky > 0){
01522
01523 if(Sky.type == SKYGRADED){
01524 Red [i]=(unsigned char)(
01525 ((double)Sky.Zenith[0]-(double)Sky.Horizon[0])*Rsky
01526 + (double)Sky.Horizon[0]);
01527 Green[i]=(unsigned char)(
01528 ((double)Sky.Zenith[1]-(double)Sky.Horizon[1])*Rsky
01529 + (double)Sky.Horizon[1]);
01530 Blue [i]=(unsigned char)(
01531 ((double)Sky.Zenith[2]-(double)Sky.Horizon[2])*Rsky
01532 + (double)Sky.Horizon[2]);
01533 }
01534 else if(Sky.type <= SKYCOLOUR || !Sky.mapped){
01535 Red [i]=Sky.Zenith[0];
01536 Green[i]=Sky.Zenith[1];
01537 Blue [i]=Sky.Zenith[2];
01538 }
01539 else if(Sky.type == SKYMAPPED){
01540 ix=Wsky*Sky.map.xmax+ZskyBuffer[i];
01541 Red[i] = Sky.map.p24R[ix];
01542 Green[i] = Sky.map.p24G[ix];
01543 Blue[i] = Sky.map.p24B[ix];
01544 }
01545 else if(Sky.type == BACKDROP){
01546 ix=((scanline*Sky.map.ymax)/YMAX)*Sky.map.xmax
01547 +(i*Sky.map.xmax)/XMAX;
01548 Red[i] = Sky.map.p24R[ix];
01549 Green[i] = Sky.map.p24G[ix];
01550 Blue[i] = Sky.map.p24B[ix];
01551 }
01552 else if(Sky.type == SKYCUBE){
01553 MapEnvironment(i,scanline,&Red[i],&Green[i],&Blue[i], &(Sky.map));
01554 }
01555 }
01556 else{ Red[i]=0; Green[i]=0; Blue[i]=0; }
01557 }
01558
01559 static void GetBackdropValue(long row, long col, vector p, vector d,
01560 double *colour){
01561
01562 vector dp,gp;
01563 double pdotn,ddotn,mu,d2,Rsky;
01564 long ix;
01565 if(R_Nground > 0 && fabs(ddotn=dot(Ground.n,d)) > 1.e-3){
01566 VECSUB(Ground.p,p,dp)
01567 pdotn=DOT(Ground.n,dp);
01568 mu=pdotn/ddotn;
01569 if(mu > 0.0){
01570 vecscale(mu,d,gp);
01571 vecsum(p,gp,gp);
01572 GetGroundLight(gp,&colour[0],&colour[1],&colour[2]);
01573 }
01574 else goto NEXTBLOCK;
01575 }
01576 else{
01577 NEXTBLOCK:
01578 if(Sky.type == SKYGRADED){
01579 d2=(double)(Ycentre-row);
01580 d2/=scaley;
01581
01582 Rsky=fabs((double)(Ycentre-row))/(double)Ycentre;
01583 colour[0]=((double)Sky.Zenith[0]-(double)Sky.Horizon[0])*Rsky
01584 +(double)Sky.Horizon[0];
01585 colour[1]=((double)Sky.Zenith[1]-(double)Sky.Horizon[1])*Rsky
01586 +(double)Sky.Horizon[1];
01587 colour[2]=((double)Sky.Zenith[2]-(double)Sky.Horizon[2])*Rsky
01588 +(double)Sky.Horizon[2];
01589 }
01590 else if(Sky.type == SKYMAPPED && Sky.mapped){
01591 ddotn=d[2];
01592 if(fabs(ddotn) > 1.e-2){
01593 vecsub(Sky.map.p,p,dp);
01594 pdotn=dp[2];
01595 mu=pdotn/ddotn;
01596 vecscale(fabs(mu),d,gp);
01597 vecsum(p,gp,gp);
01598 MapFromProjection(&Sky.map,TILE,EOPAQUE,gp,&colour[0],&colour[1],&colour[2]);
01599 }
01600 }
01601 else if(Sky.type == BACKDROP && Sky.mapped){
01602 ix=((row*Sky.map.ymax)/YMAX)*Sky.map.xmax
01603 +(col*Sky.map.xmax)/XMAX;
01604 colour[0] = Sky.map.p24R[ix];
01605 colour[1] = Sky.map.p24G[ix];
01606 colour[2] = Sky.map.p24B[ix];
01607 }
01608 else if(Sky.type == SKYCUBE && Sky.mapped){
01609 unsigned char R,G,B;
01610 MapEnvironment(col,row,&R,&G,&B, &(Sky.map));
01611 colour[0]=(double)R; colour[1]=(double)G; colour[2]=(double)B;
01612 }
01613 else{
01614 colour[0] = (double)Sky.Zenith[0];
01615 colour[1] = (double)Sky.Zenith[1];
01616 colour[2] = (double)Sky.Zenith[2];
01617 }
01618 }
01619 return;
01620 }
01621
01622 void GetMirrorValues(double *color, vector p, vector din, vector n,
01623 int at_o, face *at_f,
01624 long trace_reflection_depth,
01625 long trace_refraction_depth,
01626 long trace_refractive_flag){
01627
01628
01629 vector d,dp,gp,di;
01630 double pdotn,ddotn,mu,ld;
01631 ddotn = dot(din,n);
01632 vecscale(2*ddotn,n,d);
01633 vecsub(din,d,d);
01634 if(R_Nground > 0){
01635 ddotn=dot(Ground.n,d);
01636 if(fabs(ddotn) > 1.e-2){
01637 vecsub(Ground.p,p,dp);
01638 pdotn=dot(Ground.n,dp);
01639 mu=pdotn/ddotn;
01640 if(mu > 0.0){
01641 vecscale(mu,d,di);
01642 vecsum(p,di,gp);
01643 GetGroundLight(gp,&color[0],&color[1],&color[2]);
01644 if(trace_reflections == 1){
01645 ld = (double)((di[0]*di[0]) + (di[1]*di[1]) + (di[2]*di[2]));
01646 if(fabs(ld) > 1.e-10){
01647 ld=sqrt(ld);
01648 VECSCALE((1.0/ld),di,di)
01649 trace_reflection_ray(p,di,ld,color,
01650 at_o,at_f,
01651 trace_reflection_depth,
01652 trace_refraction_depth,
01653 trace_refractive_flag);
01654 }
01655 }
01656 return;
01657 }
01658 }
01659 }
01660 color[0] = (double)Sky.Zenith[0];
01661 color[1] = (double)Sky.Zenith[1];
01662 color[2] = (double)Sky.Zenith[2];
01663 if(Sky.type == SKYMAPPED){
01664 ddotn=d[2];
01665 if(fabs(ddotn) > 1.e-2){
01666 vecsub(Sky.map.p,p,dp);
01667 pdotn=dp[2];
01668 mu=pdotn/ddotn;
01669 vecscale(fabs(mu),d,gp);
01670 vecsum(p,gp,gp);
01671
01672 MapFromProjection(&Sky.map,TILE,EOPAQUE,gp,&color[0],&color[1],&color[2]);
01673 }
01674 }
01675 else if(Sky.type == SKYCUBE){
01676 MapEnvironmentInDirection(d,&color[0],&color[1],&color[2],&Sky.map);
01677 }
01678 if(trace_reflections == 1){
01679 ld= (double)((d[0]*d[0]) + (d[1]*d[1]) + (d[2]*d[2]));
01680 if(fabs(ld) > 1.e-10){
01681 ld=sqrt(ld);
01682 VECSCALE((1.0/ld),d,di)
01683 trace_reflection_ray(p,di,
01684 (double)BIGP,color,
01685 at_o,at_f,
01686 trace_reflection_depth,
01687 trace_refraction_depth,
01688 trace_refractive_flag);
01689 }
01690 }
01691 return;
01692 }
01693
01694 static void AttenuateGlass(long row, long col,
01695 UCHAR *Red, UCHAR *Green, UCHAR *Blue,
01696 long *Zglass[], long *ZglassO[], double *Zglassd[],
01697 double *Zposn){
01698 long i;
01699 for(i=NGLASS-1;i>=0;i--){
01700 if(Zglass[i][col] >= 0)AttenuateGlassSurface(i,row,col,Red,Green,Blue,
01701 Zglass,ZglassO,Zglassd,
01702 Zposn);
01703 }
01704 }
01705
01706 static void AttenuateGlassSurface(long id, long row, long col,
01707 UCHAR *Red, UCHAR *Green, UCHAR *Blue,
01708 long *Zglass[], long *ZglassO[], double *Zglassd[],
01709 double *Zposn){
01710 double tr,tr1,srf=0.0,srf1=1.0;
01711 double Iab,IdR,IdG,IdB,IsR,IsG,IsB,c,cc,det,alpha,beta,bend,bend1,falloff;
01712 double pdotn,ldotn;
01713 double colorb0=0,colorb1=0,colorb2=0,colorr0=0,colorr1=0,colorr2=0,
01714 colors[3],colorm[3];
01715 vector n,p,pr,pl,bv;
01716 long j,obj;
01717 short clear,type;
01718 face *f;
01719 vertex *v;
01720 imap *Map;
01721 matl *Mat;
01722 BOOL bSmooth,xtext=FALSE;
01723 unsigned char mattr,matre;
01724 obj=ZglassO[id][col];
01725 f=Object[obj].Fbase+Zglass[id][col];
01726 v=Object[obj].Vbase;
01727 if(f->ffmap >= 0){
01728 if((long)f->ffmap >= Object[obj].NoMaps)Map=NULL;
01729 else Map=(Object[obj].Mbase+(long)f->ffmap);
01730 }
01731 else Map=NULL;
01732 if(f->ffmat < 0 || f->ffmat >= Object[obj].NoMats)Mat=NULL;
01733 else Mat=(Object[obj].Tbase+(long)f->ffmat);
01734
01735 if(Mat != NULL)bSmooth=Mat->bSmooth;
01736 else bSmooth=f->bSmooth;
01737 if(!bSmooth)VECCOPY(f->n,n)
01738 else{
01739 det=(
01740 (v[f->V[2]].y - v[f->V[0]].y) * (v[f->V[1]].x - v[f->V[0]].x)
01741 -(v[f->V[2]].x - v[f->V[0]].x) * (v[f->V[1]].y - v[f->V[0]].y)
01742 );
01743 if(det == 0){
01744 VECCOPY(f->n,n)
01745 }
01746 else{
01747 det=1.0/det;
01748 alpha= (double)(
01749 (v[f->V[2]].y - v[f->V[0]].y) * (Zposn[col] - v[f->V[0]].x)
01750 -(v[f->V[2]].x - v[f->V[0]].x) * ((double)row - v[f->V[0]].y)
01751 )*det;
01752 beta= (double)(
01753 ((double)row - v[f->V[0]].y) * (v[f->V[1]].x - v[f->V[0]].x)
01754 -(Zposn[col] - v[f->V[0]].x) * (v[f->V[1]].y - v[f->V[0]].y)
01755 )*det;
01756 n[0]=f->pn[0][0] + alpha*(f->pn[1][0] - f->pn[0][0])
01757 + beta*(f->pn[2][0] - f->pn[0][0]);
01758 n[1]=f->pn[0][1] + alpha*(f->pn[1][1] - f->pn[0][1])
01759 + beta*(f->pn[2][1] - f->pn[0][1]);
01760 n[2]=f->pn[0][2] + alpha*(f->pn[1][2] - f->pn[0][2])
01761 + beta*(f->pn[2][2] - f->pn[0][2]);
01762 normalize(n);
01763 }
01764 }
01765
01766 p[0]=(((double)col-(double)Xcentre)/scalex*Zglassd[id][col]);
01767 p[1]=Zglassd[id][col];
01768 p[2]=(((double)Ycentre-(double)row)/scaley*Zglassd[id][col]);
01769 if((pdotn=DOT(p,f->n)) > 0){n[0] = -n[0]; n[1] = -n[1]; n[2] = -n[2];}
01770 IdR=IdG=IdB=0.0; IsR=IsG=IsB=0.0;
01771 if(Map != NULL && Map->bp >= 0){
01772 if(Map->bTiled)type=TILE;
01773 else type=SINGLE;
01774 if(Map->map == MAP_BY_VERTEX)
01775 BumpByCoordinates(Map,type,obj,f,p,n);
01776 else{;}
01777 }
01778 if(Mat != NULL){
01779 VECCOPY((double)Mat->color,colors)
01780 tr=((double)(Mat->transp))*3.92e-3;
01781 if(Mat->bInternalShader)xtext=FALSE; else xtext=TRUE;
01782 }
01783 else{
01784 VECCOPY((double)f->color,colors)
01785 tr=((double)(8))*3.92e-3;
01786 xtext=FALSE;
01787 }
01788 if(xtext){
01789 double alpha_channel=0.0;
01790 int s;
01791 double beta,gamma;
01792 MapTextureByCoordinates(obj,f,p,&alpha,&beta,&gamma);
01793 for(s=0;s<4;s++){
01794 if(Mat->shaderID[s] >= 0)
01795 RenderExternalTexture(Mat->shaderID[s],
01796 p,n,
01797 alpha,beta,gamma,
01798 (double)(Mat->params[0])*SHSCALE,
01799 &alpha_channel,
01800 &tr,
01801 Mat->texco,
01802 obj,f,
01803 colors);
01804 }
01805 }
01806 if(Mat != NULL && Mat->bGlassEdge){
01807 if((bend=DOT(p,n)) < 0)bend = -bend;
01808 bend1=sqrt(bend/R_length(p));
01809 tr1 = 1.0-tr;
01810 tr *= bend1;
01811 }
01812 else{
01813 tr1 = 1.0-tr;
01814 }
01815 GetPixelLighting(Mat,p,n,pdotn,0.0,obj,f,
01816 &IdR,&IdG,&IdB,&IsR,&IsG,&IsB);
01817 if(Map != NULL){
01818 if(Map->rp >= 0){
01819 MapMirror(&colorr0,&colorr1,&colorr2,Map,p,n);
01820 srf=Map->rd; srf1=(1.0-srf);
01821 }
01822 if(Map->pp < 0)goto MISSBRUSH;
01823 if(Map->bDecal)clear = TRANSP;
01824 else clear = EOPAQUE;
01825 if(Map->map == MAP_BY_VERTEX){
01826 if(Map->bTiled)type = TILE;
01827 else type = SINGLE;
01828 if(MapByCoordinates(Map,obj,f,type,clear,p,&colorb0,&colorb1,&colorb2)
01829 == 0)goto MISSBRUSH1;
01830 }
01831 else{;}
01832 if(!(Map->bShaded)){
01833 IdR=IdG=IdB=1.0; IsR=IsG=IsB=0.0;
01834 }
01835 tr1=Map->pd; tr=(1.0-tr1);
01836 *(colors ) = colorb0;
01837 *(colors+1) = colorb1;
01838 *(colors+2) = colorb2;
01839 MISSBRUSH:
01840 if(Map->tp >= 0){
01841 if(Map->bTiled)type = TILE;
01842 else type = SINGLE;
01843 if(Map->map == MAP_BY_VERTEX){
01844 if(MapTransByCoordinates(Map,type,obj,f,p,&tr) != 0)tr1=(1.0-tr);
01845 }
01846 else{;}
01847 }
01848 MISSBRUSH1:
01849 IdR=(double)Red[col]*tr + (colors[0]*IdR+IsR*255)*tr1;
01850 IdG=(double)Green[col]*tr + (colors[1]*IdG+IsG*255)*tr1;
01851 IdB=(double)Blue[col]*tr + (colors[2]*IdB+IsB*255)*tr1;
01852 IdR=IdR*srf1 + colorr0*srf;
01853 IdG=IdG*srf1 + colorr1*srf;
01854 IdB=IdB*srf1 + colorr2*srf;
01855 }
01856 else{
01857 IdR=(double)Red[col]*tr + colors[0]*tr1*IdR+IsR*255;
01858 IdG=(double)Green[col]*tr + colors[1]*tr1*IdG+IsG*255;
01859 IdB=(double)Blue[col]*tr + colors[2]*tr1*IdB+IsB*255;
01860 if(Mat != NULL)matre=Mat->refl; else matre=0;
01861 if(matre > 0){
01862 GetMirrorValues(colorm,p,p,n,0,NULL,0,0,0);
01863 srf = (double)(matre)/255.0; srf1=(1.0-srf);
01864 IdR=IdR*srf1 + colorm[0]*srf;
01865 IdG=IdG*srf1 + colorm[1]*srf;
01866 IdB=IdB*srf1 + colorm[2]*srf;
01867 }
01868 }
01869 Red[col] =(unsigned char)min(255.0,IdR);
01870 Green[col]=(unsigned char)min(255.0,IdG);
01871 Blue[col] =(unsigned char)min(255.0,IdB);
01872 }
01873
01884 void GetPixelValue(vector p, vector dinput,
01885 vector n, double pdotn,
01886 imap *Map, matl *Mat, face *f, long obj,
01887 long row, long col, BOOL first_trace,
01888 long trace_relection_depth, long trace_refraction_depth, long refractive_flag,
01889 double *Red, double *Green, double *Blue){
01890 BOOL xtext,fullsat=FALSE;
01891 vector pr,bv,pl,d;
01892 long j,flag_mirror=0,t,flag_trans=0,refx=1000;
01893 short type,textID,clear;
01894 double alpha,beta,gamma;
01895 double colors[3],colorr[3],colorm[3],colort[3];
01896 double Iab,IdR,IdG,IdB,IsR,IsG,IsB,c,cc,
01897 ldotn,amblight,falloff;
01898 double sf,sf1,tr,tr1,rf,rf1;
01899 unsigned char mattr,matre;
01900
01901 IdR=IdG=IdB=0.0; IsR=IsG=IsB=0.0;
01902 colorr[0]=colorr[1]=colorr[2]=0.0;
01903 colorm[0]=colorm[1]=colorm[2]=0.0;
01904 colort[0]=colort[1]=colort[2]=0.0;
01905
01906 if(Mat != NULL){
01907 VECCOPY((double)Mat->color,colors)
01908 if(Mat->bInternalShader){textID=Mat->internalShaderID; xtext=FALSE;}
01909 else {textID=0; xtext=TRUE;}
01910 tr=((double)(Mat->transp))*3.92e-3;
01911 refx=Mat->refractive_index;
01912 }
01913 else{
01914 VECCOPY((double)f->color,colors)
01915 textID=0;
01916 xtext=FALSE;
01917 tr=0;
01918 refx=1000;
01919 }
01920 sf=1.0;
01921
01922 if(Map != NULL && Map->bp >= 0){
01923 if(Map->bTiled)type=TILE;
01924 else type=SINGLE;
01925 if(Map->map == MAP_BY_VERTEX)
01926 BumpByCoordinates(Map,type,obj,f,p,n);
01927 else{;}
01928 }
01929 if(textID > 0 || xtext){
01930 MapTextureByCoordinates(obj,f,p,&alpha,&beta,&gamma);
01931 if(xtext){
01932 double alpha_channel=0.0;
01933 int s;
01934 for(s=0; s<4;s++){
01935 if(Mat->shaderID[s] >= 0)
01936 fullsat=RenderExternalTexture(Mat->shaderID[s],
01937 p,n,
01938 alpha,beta,gamma,
01939 (double)(Mat->params[0])*SHSCALE,
01940 &alpha_channel,
01941 &tr,
01942 Mat->texco,
01943 obj,f,
01944 colors);
01945 }
01946 }
01947 else fullsat=GetInternalTexture(Mat,alpha,beta,gamma,textID,p,n,obj,f,colors,
01948 colort,&flag_trans,tr,&tr1,
01949 trace_relection_depth,trace_refraction_depth,
01950 refractive_flag);
01951 }
01952 GetPixelLighting(Mat,p,n,pdotn,0.0,obj,f,
01953 &IdR,&IdG,&IdB,&IsR,&IsG,&IsB);
01954 colorm[0]=colorm[1]=colorm[2]=0.0;
01955 if(Map != NULL){
01956 if(Map->rp >= 0){
01957 MapMirror(&colorr[0],&colorr[1],&colorr[2],Map,p,n);
01958 flag_mirror=1; rf=Map->rd;
01959 }
01960 if(Map->tp >= 0){
01961 if(Map->bTiled)type = TILE;
01962 else type = SINGLE;
01963 if(MapTransByCoordinates(Map,type,obj,f,p,&tr) != 0)tr1=(1.0-tr);
01964 if(trace_refractions && tr > 0.0){
01965 c=(double)((dinput[0]*dinput[0]) + (dinput[1]*dinput[1]) + (dinput[2]*dinput[2]));
01966 c=sqrt(c);
01967 VECSCALE((1.0/c),dinput,d)
01968 if(first_trace && refx == 1000){
01969 GetBackdropValue(row,col,p,d,colort);
01970 }
01971 else {
01972 colort[0]=*Red; colort[1]=*Green; colort[2]=*Blue;
01973 }
01974 if(refx == 1000)trace_transmission_ray(p,d,n,obj,f,(double)BIGP,colort,
01975 trace_relection_depth,trace_refraction_depth,refractive_flag);
01976 else trace_refraction_ray(p,d,n,obj,f,(double)BIGP,colort,refx,
01977 trace_relection_depth,trace_refraction_depth,refractive_flag);
01978 flag_trans=1;
01979 }
01980 }
01981 if(Map->pp < 0)goto ALGOTEXT;
01982 if(Map->bDecal)clear = TRANSP;
01983 else clear = EOPAQUE;
01984 if(Map->map == MAP_BY_VERTEX){
01985 if(Map->bTiled)type = TILE;
01986 else type = SINGLE;
01987 if(MapByCoordinates(Map,obj,f,type,clear,p,
01988 &colorm[0],&colorm[1],&colorm[2])
01989 == 0)goto ALGOTEXT;
01990 flag_trans=2;
01991 }
01992 if(Map->bShaded){
01993 colorm[0] = colorm[0]*IdR+IsR*255;
01994 colorm[1] = colorm[1]*IdG+IsG*255;
01995 colorm[2] = colorm[2]*IdB+IsB*255;
01996 }
01997 sf=(1.0-Map->pd);
01998 if(Map->pp == 100){
01999 colors[0]=colors[1]=colors[2]=0.0;
02000 goto SKIPALGO;
02001 }
02002 }
02003
02004 ALGOTEXT:
02005 if(fullsat){IdR=IdG=IdB=1.0; IsR=IsG=IsB=0.0;}
02006
02007 SKIPALGO:
02008
02009 sf1=1.0-sf;
02010 colors[0] = colors[0]*IdR*sf + colorm[0]*sf1;
02011 colors[1] = colors[1]*IdG*sf + colorm[1]*sf1;
02012 colors[2] = colors[2]*IdB*sf + colorm[2]*sf1;
02013
02014 if(trace_shadows && Object[obj].show_shadow &&
02015 (j=check_for_shadow(obj,p,f->n)) != 0){
02016 IsR = IsG = IsB = 0.0;
02017 if(j < 0){
02018 colors[0] *= shadow_density;
02019 colors[1] *= shadow_density;
02020 colors[2] *= shadow_density;
02021 }
02022 else{
02023 colors[0] *= glass_shadow_density;
02024 colors[1] *= glass_shadow_density;
02025 colors[2] *= glass_shadow_density;
02026 }
02027 }
02028 if(Mat != NULL)mattr=Mat->transp;
02029 else mattr=0;
02030 if(trace_refractions && mattr > 0 && flag_trans == 0){
02031 double bend,bend1;
02032 BOOL glass_edge;
02033 if(Mat != NULL)glass_edge=Mat->bGlassEdge;
02034 else glass_edge=FALSE;
02035 if(glass_edge){
02036 if((bend=DOT(p,n)) < 0)bend = -bend;
02037 bend1=sqrt(bend/R_length(p));
02038 tr1 = 1.0-tr;
02039 tr *= bend1;
02040 }
02041 else{
02042 tr1 = 1.0-tr;
02043 }
02044 c=(double)((dinput[0]*dinput[0]) + (dinput[1]*dinput[1]) + (dinput[2]*dinput[2]));
02045 c=sqrt(c);
02046 VECSCALE((1.0/c),dinput,d)
02047 if(refx == 1000){
02048 GetBackdropValue(row,col,p,d,colort);
02049 trace_transmission_ray(p,d,n,obj,f,(double)BIGP,colort,
02050 trace_relection_depth,trace_refraction_depth,refractive_flag);
02051 }
02052 else trace_refraction_ray(p,d,n,obj,f,(double)BIGP,colort,refx,
02053 trace_relection_depth,trace_refraction_depth,refractive_flag);
02054 flag_trans=1;
02055 }
02056 if(flag_trans == 1){
02057 colors[0] = colort[0]*tr + colors[0]*tr1;
02058 colors[1] = colort[1]*tr + colors[1]*tr1;
02059 colors[2] = colort[2]*tr + colors[2]*tr1;
02060 }
02061 colors[0] += IsR*255;
02062 colors[1] += IsG*255;
02063 colors[2] += IsB*255;
02064
02065 if(Mat != NULL)matre=Mat->refl;
02066 else matre=0;
02067 if(matre > 0 && ! flag_mirror){
02068 GetMirrorValues(colorr,p,dinput,n,obj,f,
02069 trace_relection_depth,trace_refraction_depth,refractive_flag);
02070 rf = (double)(matre)/255.0;
02071 flag_mirror=1;
02072 }
02073
02074 if(flag_mirror){
02075 rf1=1.0-rf;
02076 *Red = (unsigned char)min(255,colorr[0]*rf+colors[0]*rf1);
02077 *Green= (unsigned char)min(255,colorr[1]*rf+colors[1]*rf1);
02078 *Blue = (unsigned char)min(255,colorr[2]*rf+colors[2]*rf1);
02079 }
02080 else{
02081 *Red = (unsigned char)min(255,colors[0]);
02082 *Green= (unsigned char)min(255,colors[1]);
02083 *Blue = (unsigned char)min(255,colors[2]);
02084 }
02085 }
02086
02087
02106 void GetRowPixelValue(long row, long col, imap *Map, matl *Mat,
02107 face *f, long obj, vector nn,
02108 UCHAR *Red, UCHAR *Green, UCHAR *Blue,
02109 double *Zdepth,UCHAR *ZobjChar){
02110 double r,g,b,pdotn;
02111 vector p,n;
02112
02113 p[0]=(((double)col-(double)Xcentre)/scalex*Zdepth[col]);
02114 p[1]=Zdepth[col];
02115 p[2]=(((double)Ycentre-(double)row)/scaley*Zdepth[col]);
02116 if((pdotn=DOT(p,f->n)) < 0)VECCOPY(nn,n)
02117 else {n[0] = -nn[0]; n[1] = -nn[1]; n[2] = -nn[2];}
02118 if(trace_refractions){
02119 double maptr,mattr;
02120 if(Map != NULL)maptr=Map->tp;
02121 else maptr=0;
02122 if(Mat != NULL)mattr=Mat->transp;
02123 else mattr=0;
02124 if(mattr > 0.0 || maptr > 0.0){
02125 int fc;
02126 vector d;
02127 d[0]=(((double)col-(double)Xcentre+0.5)/scalex);
02128 d[1]=1.0;
02129 d[2]=(((double)Ycentre-(double)row)/scaley);
02130 normalize(d);
02131 p[0]=p[1]=p[2]=0.0;
02132 if(!trace_starting_ray(d,p,&obj,&fc,&f))return;
02133 p[0]=p[1]=p[2]=0.0;
02134 GetSurfaceValue(obj,f,Object[obj].Vbase,p,d,&r,&g,&b,0,0,0);
02135 goto ENDP;
02136 }
02137 }
02138 GetPixelValue(p,p,n,pdotn,Map,Mat,f,obj,row,col,TRUE,0,0,0,&r,&g,&b);
02139 ENDP:
02140 Red[col] = (unsigned char)min(255,r);
02141 Green[col]= (unsigned char)min(255,g);
02142 Blue[col] = (unsigned char)min(255,b);
02143 }
02144
02145 void GetSurfaceValue(int obj, face *f, vertex *v,
02146 vector p, vector dr, double *r, double *g, double *b,
02147 long trace_reflection_depth, long trace_refraction_depth,
02148 long refractive_flag){
02149
02150
02151
02152 imap *Map;
02153 matl *Mat;
02154 vector d,n,pr,pl,dp,bv,dl,nn;
02155 double ddotn,mu,pdotn,alpha,beta;
02156 BOOL bSmooth;
02157 ddotn=DOT(f->n,dr);
02158 if(fabs(ddotn) > 1.e-3){
02159 VECSUB(v[f->V[0]].p,p,dp)
02160 pdotn=DOT(f->n,dp);
02161 mu=pdotn/ddotn;
02162 VECSCALE(mu,dr,dp)
02163 VECSUM(p,dp,d)
02164 if(f->ffmat < 0 || f->ffmat >= Object[obj].NoMats)Mat=NULL;
02165 else Mat=(Object[obj].Tbase+(long)f->ffmat);
02166 if(Mat != NULL)bSmooth=Mat->bSmooth;
02167 else bSmooth=f->bSmooth;
02168 if(!bSmooth)veccopy(f->n,n);
02169 else{
02170 VECSUB(v[f->V[1]].p,v[f->V[0]].p,pr)
02171 VECSUB(v[f->V[2]].p,v[f->V[0]].p,pl)
02172 hitpoint(f->n,pr,pl,v[f->V[0]].p,d,&alpha,&beta);
02173 VECSUB(f->pn[1],f->pn[0],pr)
02174 VECSUB(f->pn[2],f->pn[0],pl)
02175 VECSCALE(alpha,pr,pr)
02176 VECSCALE(beta,pl,pl)
02177 VECSUM(f->pn[0],pr,n)
02178 VECSUM(n,pl,n)
02179 normalize(n);
02180 }
02181 if(f->ffmap >= 0){
02182 if((long)f->ffmap >= Object[obj].NoMaps)Map=NULL;
02183 else Map=(Object[obj].Mbase+(long)f->ffmap);
02184 }
02185 else Map=NULL;
02186
02187 if(DOT(dp,n) < 0.0)VECCOPY(n,nn)
02188 else {nn[0] = -n[0]; nn[1] = -n[1]; nn[2] = -n[2];}
02189
02190 GetPixelValue(d,dr,nn,-1.0,Map,Mat,f,obj,
02191 0,0,FALSE,
02192 trace_reflection_depth,trace_refraction_depth,refractive_flag,
02193 r,g,b);
02194 }
02195 }