00001
00002
00003
00004 #define MODULE_GEO
00005
00006 #include "render.h"
00007
00008
00009 static unsigned char *AllocateShadowBuffer(void);
00010 static void ApplyVertexEffect(long effect, vertex *v, long N, double time,
00011 double vmin[], double vmax[], ivector Og);
00012 static void FixUpMapEdge(GLfloat a[]);
00013 static void NewPoint(double plane, vector p1, vector p2, vector p,
00014 vector2, vector2, vector2);
00015
00016
00017
00018 static void NewPoint(double dp, vector v1, vector v2, vector p,
00019 vector2 uv1, vector2 uv2, vector2 uv){
00020 double mu;
00021 mu=(v2[1]-v1[1]);
00022 if(fabs(mu) < 1.0)mu=0.0;
00023 else mu=(dp-v1[1])/mu;
00024 p[1]=dp;
00025 p[0]=v1[0]+mu*(v2[0]-v1[0]);
00026 p[2]=v1[2]+mu*(v2[2]-v1[2]);
00027 uv[0] = uv1[0]+mu*(uv2[0]-uv1[0]);
00028 uv[1] = uv1[1]+mu*(uv2[1]-uv1[1]);
00029 }
00030
00031 static void NewMapPoint(double dp, vector a1, vector a2,
00032 double u1, double u2,
00033 double v1, double v2,
00034 double w1, double w2,
00035 vector r){
00036 double mu;
00037 mu=(a2[1]-a1[1]);
00038 if(fabs(mu) < 1.0)mu=0.0;
00039 else mu=(dp-a1[1])/mu;
00040 r[0] = u1 + mu*(u2 - u1);
00041 r[1] = v1 + mu*(v2 - v1);
00042 r[2] = w1 + mu*(w2 - w1);
00043 }
00044
00045 short ClipObject(long O){
00046 vertex *v;
00047 face *f;
00048 double y1,y2,y3,dp;
00049 long i,i1,i2,i3,xv,xf,sz,vp,fp;
00050 vector2 uv1,uv2,uva,uvb;
00051 vector a,b;
00052
00053
00054
00055
00056 dp=FRONT_CLIPPING_PLANE;
00057 xv=0; xf=0;
00058 v=Object[O].Vbase;
00059 f=Object[O].Fbase;
00060 for(i=0;i<Object[O].NoFaces;i++){
00061 i1= -1;
00062 y1=v[f[i].V[0]].p[1];
00063 y2=v[f[i].V[1]].p[1];
00064 y3=v[f[i].V[2]].p[1];
00065 if (y1 <= dp && y2 <=dp && y3 > dp)i1 = 2;
00066 else if(y1 <= dp && y2 > dp && y3 <= dp)i1 = 1;
00067 else if(y1 <= dp && y2 > dp && y3 > dp)i1 = 0;
00068 else if(y1 > dp && y2 <=dp && y3 <= dp)i1 = 0;
00069 else if(y1 > dp && y2 <=dp && y3 > dp)i1 = 1;
00070 else if(y1 > dp && y2 > dp && y3 <= dp)i1 = 2;
00071 if(i1 >= 0){
00072 xv += 2; xf += 2;
00073 }
00074 }
00075 if(xv == 0)return OK;
00076
00077 #if 0
00078 fprintf(debug,"extra v=%ld face=%ld\n",xv,xf);
00079 for(i=0;i<Object[O].NoFaces;i++){
00080 int j;
00081 fprintf(debug,"Face %ld vertices (%ld %ld %ld)\n",i,(f+i)->V[0],(f+i)->V[1],(f+i)->V[2]);
00082 for(j=0;j<3;j++){
00083 fprintf(debug,"(Vvert %8.1lf %8.1lf %8.1lf) (mapping %lf %lf)\n",
00084 (v+(f+i)->V[j])->p[0],(v+(f+i)->V[j])->p[1],(v+(f+i)->V[j])->p[2],
00085 (f+i)->uu[j],(f+i)->vv[j]);
00086 }
00087 }
00088 #endif
00089
00090 sz=(Object[O].NoVertices+xv)*(long)sizeof(vertex);
00091 if((v=(vertex *)X__Realloc(Object[O].Vbase,sz)) == NULL)goto X__ERROR;
00092 Object[O].Vbase=v;
00093 sz=(Object[O].NoFaces+xf)*(long)sizeof(face);
00094 if((f=(face *)X__Realloc(Object[O].Fbase,sz)) == NULL)goto X__ERROR;
00095 Object[O].Fbase=f;
00096 vp=Object[O].NoVertices;
00097 fp=Object[O].NoFaces;
00098 for(i=0;i<Object[O].NoFaces;i++){
00099 i1= -1; i2= -1; i3= -1;
00100 y1=v[f[i].V[0]].p[1];
00101 y2=v[f[i].V[1]].p[1];
00102 y3=v[f[i].V[2]].p[1];
00103 if (y1 <= dp && y2 <=dp && y3 > dp){i1 = 2; i2=0; i3=1;}
00104 else if(y1 <= dp && y2 > dp && y3 <= dp){i1 = 1; i2=0; i3=2;}
00105 else if(y1 <= dp && y2 > dp && y3 > dp){i1 = 0; i2=1; i3=2;}
00106 else if(y1 > dp && y2 <=dp && y3 <= dp){i1 = 0; i2=1; i3=2;}
00107 else if(y1 > dp && y2 <=dp && y3 > dp){i1 = 1; i2=0; i3=2;}
00108 else if(y1 > dp && y2 > dp && y3 <= dp){i1 = 2; i2=0; i3=1;}
00109 if(i1 >= 0){
00110 v[vp].x=v[vp].y=v[vp+1].x=v[vp+1].y=0.0;
00111
00112
00113 uv1[0]=v[f[i].V[i1]].u; uv1[1]=v[f[i].V[i1]].v;
00114 uv2[0]=v[f[i].V[i2]].u; uv2[1]=v[f[i].V[i2]].v;
00115 NewPoint(dp,v[f[i].V[i1]].p,v[f[i].V[i2]].p,v[vp].p,uv1,uv2,uva);
00116 v[vp].u=uva[0]; v[vp].v=uva[1];
00117
00118 uv1[0]=v[f[i].V[i1]].u; uv1[1]=v[f[i].V[i1]].v;
00119 uv2[0]=v[f[i].V[i3]].u; uv2[1]=v[f[i].V[i3]].v;
00120 NewPoint(dp,v[f[i].V[i1]].p,v[f[i].V[i3]].p,v[vp+1].p,uv1,uv2,uvb);
00121 v[vp+1].u=uvb[0]; v[vp+1].v=uvb[1];
00122
00123 NewMapPoint(dp,v[f[i].V[i1]].p,v[f[i].V[i2]].p,
00124 f[i].uu[i1],f[i].uu[i2],
00125 f[i].vv[i1],f[i].vv[i2],
00126 f[i].ww[i1],f[i].ww[i2],a);
00127 NewMapPoint(dp,v[f[i].V[i1]].p,v[f[i].V[i3]].p,
00128 f[i].uu[i1],f[i].uu[i3],
00129 f[i].vv[i1],f[i].vv[i3],
00130 f[i].ww[i1],f[i].ww[i3],b);
00131
00132
00133
00134
00135
00136 f[fp].V[0]=vp;
00137 f[fp].V[1]=f[i].V[i2];
00138 f[fp].V[2]=f[i].V[i3];
00139 f[fp].uu[0]=a[0]; f[fp].vv[0]=a[1]; f[fp].ww[0]=a[2];
00140 f[fp].uu[1]=f[i].uu[i2]; f[fp].vv[1]=f[i].vv[i2]; f[fp].ww[1]=f[i].ww[i2];
00141 f[fp].uu[2]=f[i].uu[i3]; f[fp].vv[2]=f[i].vv[i3]; f[fp].ww[2]=f[i].ww[i3];
00142
00143 f[fp+1].V[0]=vp;
00144 f[fp+1].V[1]=f[i].V[i3];
00145 f[fp+1].V[2]=vp+1;
00146 f[fp+1].uu[0]=a[0]; f[fp+1].vv[0]=a[1]; f[fp+1].ww[0]=a[2];
00147 f[fp+1].uu[1]=f[i].uu[i3]; f[fp+1].vv[1]=f[i].vv[i3]; f[fp+1].ww[1]=f[i].ww[i3];
00148 f[fp+1].uu[2]=b[0]; f[fp+1].vv[2]=b[1]; f[fp+1].ww[2]=b[2];
00149
00150 f[i].V[i2]=vp;
00151 f[i].V[i3]=vp+1;
00152 f[i].uu[i2]=a[0]; f[i].vv[i2]=a[1]; f[i].ww[i2]=a[2];
00153 f[i].uu[i3]=b[0]; f[i].vv[i3]=b[1]; f[i].ww[i3]=b[2];
00154 f[fp+1].color[0]=f[fp].color[0]=f[i].color[0];
00155 f[fp+1].color[1]=f[fp].color[1]=f[i].color[1];
00156 f[fp+1].color[2]=f[fp].color[2]=f[i].color[2];
00157 f[fp+1].ffmap=f[fp].ffmap=f[i].ffmap;
00158 f[fp+1].ffmat=f[fp].ffmat=f[i].ffmat;
00159 f[fp+1].bFmc=f[fp].bFmc=f[i].bFmc;
00160 f[fp+1].bShiny=f[fp].bShiny=f[i].bShiny;
00161 f[fp+1].bSmooth=f[fp].bSmooth=f[i].bSmooth;
00162 f[fp+1].pn[0][0] = f[fp].pn[0][0] = f[i].pn[0][0];
00163 f[fp+1].pn[0][1] = f[fp].pn[0][1] = f[i].pn[0][1];
00164 f[fp+1].pn[0][2] = f[fp].pn[0][2] = f[i].pn[0][2];
00165 f[fp+1].pn[1][0] = f[fp].pn[1][0] = f[i].pn[1][0];
00166 f[fp+1].pn[1][1] = f[fp].pn[1][1] = f[i].pn[1][1];
00167 f[fp+1].pn[1][2] = f[fp].pn[1][2] = f[i].pn[1][2];
00168 f[fp+1].pn[2][0] = f[fp].pn[2][0] = f[i].pn[2][0];
00169 f[fp+1].pn[2][1] = f[fp].pn[2][1] = f[i].pn[2][1];
00170 f[fp+1].pn[2][2] = f[fp].pn[2][2] = f[i].pn[2][2];
00171 f[fp].c=f[fp+1].c=0.0;
00172 f[fp].n[0]=f[fp].n[1]=f[fp].n[2]=f[fp+1].n[0]
00173 =f[fp+1].n[1]=f[fp+1].n[2]=0.0;
00174 vp += 2; fp += 2;
00175 }
00176 }
00177 Object[O].NoVertices = vp;
00178 Object[O].NoFaces = fp;
00179 #if 0
00180 fprintf(debug,"After v=%ld face=%ld\n",Object[O].NoVertices,Object[O].NoFaces);
00181 for(i=0;i<Object[O].NoFaces;i++){
00182 int j;
00183 fprintf(debug,"Face %ld vertices (%ld %ld %ld)\n",i,(f+i)->V[0],(f+i)->V[1],(f+i)->V[2]);
00184 for(j=0;j<3;j++){
00185 fprintf(debug,"(Vvert %8.1lf %8.1lf %8.1lf) (mapping %lf %lf)\n",
00186 (v+(f+i)->V[j])->p[0],(v+(f+i)->V[j])->p[1],(v+(f+i)->V[j])->p[2],
00187 (f+i)->uu[j],(f+i)->vv[j]);
00188 }
00189 }
00190 #endif
00191 return OK;
00192 X__ERROR:
00193 Render_Message(4,0,NULL);
00194 return FAIL;
00195 }
00196
00197 long IShadow(long scanline, long v1x, long v1y, long v2x, long v2y,
00198 long *xi){
00199 double doff,ddxy;
00200 long dx,dy,off,dxy;
00201 if((v1y < scanline) && (v2y < scanline))return 0;
00202 if((v1y > scanline) && (v2y > scanline))return 0;
00203 dy = (v2y) - (v1y);
00204 if(dy == 0)return 0;
00205 dx = (v2x) - (v1x);
00206 off=scanline - v1y;
00207 doff=off;
00208 ddxy=dx*doff/dy;
00209 dxy=ddxy;
00210 *xi=(v1x)+dxy;
00211 return 1;
00212 }
00213
00214 void ShadowFillLine(long scanline, long vx[3], long vy[3],
00215 long *leftedge, long *rightedge){
00216 long x1,x2,x3,i1,i2,i3;
00217 i1=IShadow(scanline,vx[0],vy[0],vx[1],vy[1],&x1);
00218 i2=IShadow(scanline,vx[1],vy[1],vx[2],vy[2],&x2);
00219 i3=IShadow(scanline,vx[2],vy[2],vx[0],vy[0],&x3);
00220 if((i1 == 1) && (i2 == 1) && (i3 == 1))
00221 {*leftedge = min(min(x1,x2),x3);
00222 *rightedge= max(max(x1,x2),x3);}
00223 else if((i1 == 1) && (i2 == 1))
00224 {*leftedge = min(x1,x2);
00225 *rightedge= max(x1,x2);}
00226 else if((i2 == 1) && (i3 == 1))
00227 {*leftedge = min(x2,x3);
00228 *rightedge= max(x2,x3);}
00229 else if((i3 == 1) && (i1 == 1))
00230 {*leftedge = min(x3,x1);
00231 *rightedge= max(x3,x1);}
00232 else {
00233 Render_Message(5,0,NULL);
00234 return;
00235 }
00236 *leftedge = max(0,min(XMAX-1,*leftedge));
00237 *rightedge = min(XMAX-1,max(0,*rightedge));
00238 return;
00239 }
00240
00241 static unsigned char *AllocateShadowBuffer(void){
00242 long i,screensize;
00243 unsigned char *s,*screen;
00244 screensize = (long)XMAX * (long)YMAX;
00245 if((s = (unsigned char *)X__Malloc(screensize)) == NULL){
00246 Render_Message(14,0,NULL);
00247 return NULL;
00248 }
00249 screen=s; for(i=0;i<screensize;i++)*screen++ = 0;
00250 return s;
00251 }
00252
00253 void ShadowGround(void){
00254 long i,j,k,l,m;
00255 long vi[3];
00256 long xx[3],yy[3],xxmin,xxmax,yymin,yymax;
00257 face *f;
00258 vertex *v;
00259 matl *mat;
00260 unsigned char mattr;
00261 vector p,t1;
00262 double mu,nu,de,temp4;
00263 UCHAR *screen;
00264 if((VGA_screen=AllocateShadowBuffer()) == NULL)return;
00265 screen=VGA_screen;
00266 for(k=0;k<Nlights;k++){
00267 if(Lights[k].type == NORMAL || Lights[k].type == SHADOWS){
00268 for(i=0;i<ObjectCount;i++){
00269 if(!Object[i].in_use)continue;
00270 if(!Object[i].cast_shadow)continue;
00271 v=Object[i].Vbase;
00272 f=Object[i].Fbase;
00273 mat=Object[i].Tbase;
00274 for(j=0;j<Object[i].NoFaces;j++){
00275 if((f+j)->ffmat >= 0 && (f+j)->ffmat < Object[i].NoMats){
00276 if(mat != NULL)mattr=(mat + f->ffmat)->transp;
00277 else mattr=0;
00278 } else mattr=0;
00279 if(mattr > 0)continue;
00280 vi[0]=(f+j)->V[0];
00281 vi[1]=(f+j)->V[1];
00282 vi[2]=(f+j)->V[2];
00283 for(l=0;l<3;l++){
00284 p[0]=(v+vi[l])->p[0];
00285 p[1]=(v+vi[l])->p[1];
00286 p[2]=(v+vi[l])->p[2];
00287 vecsub(Ground.p,Lights[k].p,t1);
00288 nu=dot(Ground.n,t1);
00289 vecsub(p,Lights[k].p,t1);
00290 de=dot(Ground.n,t1);
00291 if(fabs(de) < 1.e-5)goto FACEBREAK;
00292 mu=nu/de;
00293 if(mu < 1.0)goto FACEBREAK;
00294 vecsub(p,Lights[k].p,t1);
00295 vecscale(mu,t1,t1);
00296 vecsum(Lights[k].p,t1,t1);
00297 if(t1[1] > 1.000){
00298 temp4=(long)(scalex*t1[0]/(t1[1]));
00299 xx[l]=Xcentre+temp4;
00300 temp4=(long)(scaley*t1[2]/(t1[1]));
00301 yy[l]=Ycentre-temp4;
00302 }
00303 else goto FACEBREAK;
00304 }
00305 xxmin=min(xx[0],min(xx[1],xx[2]));
00306 xxmax=max(xx[0],max(xx[1],xx[2]));
00307 yymin=min(yy[0],min(yy[1],yy[2]));
00308 yymax=max(yy[0],max(yy[1],yy[2]));
00309 if((yymax > yymin) && (xxmax > xxmin))
00310 for(l=max(0,yymin);l<=min(yymax,YMAX-1);l++){
00311 ShadowFillLine(l,xx,yy,&xxmin,&xxmax);
00312 for(m=xxmin;m<=xxmax;m++) *(screen+l*(long)XMAX+m) = 1;
00313 }
00314 FACEBREAK: continue;
00315 }
00316 }
00317 }
00318 }
00319 return;
00320 }
00321
00322 #define TOL 1.e-4;
00323
00324 double hitpoint(vector n, vector x, vector y, vector pb, vector pf,
00325 double * a, double * b){
00326
00327
00328
00329
00330
00331
00332 int k;
00333 vector v1,p;
00334 double mu,dm,detmax,det1,det2,det3,ve1,ve2,ve3,vp1,vp2,vp3,p1,p2,p3;
00335 VECSUB(pb,pf,v1)
00336 mu=DOT(n,v1);
00337 VECSCALE(mu,n,v1)
00338 VECSUM(pf,v1,p)
00339 ve1=x[0]; ve2=x[1]; ve3=x[2];
00340 vp1=y[0]; vp2=y[1]; vp3=y[2];
00341 p1=p[0]-pb[0];
00342 p2=p[1]-pb[1];
00343 p3=p[2]-pb[2];
00344 det1=ve1*vp2-vp1*ve2;
00345 det2=ve1*vp3-vp1*ve3;
00346 det3=ve2*vp3-vp2*ve3;
00347 k=0; detmax=TOL;
00348 if((dm=fabs(det1)) > detmax){k=1; detmax=dm;}
00349 if((dm=fabs(det2)) > detmax){k=2; detmax=dm;}
00350 if((dm=fabs(det3)) > detmax){k=3; detmax=dm;}
00351 if(k == 1){
00352 *a=( vp2*p1-vp1*p2)/det1;
00353 *b=(-ve2*p1+ve1*p2)/det1;
00354 }
00355 else if(k == 2){
00356 *a=( vp3*p1-vp1*p3)/det2;
00357 *b=(-ve3*p1+ve1*p3)/det2;
00358 }
00359 else if(k == 3){
00360 *a=( vp3*p2-vp2*p3)/det3;
00361 *b=(-ve3*p2+ve2*p3)/det3;
00362 }
00363 else {
00364 *a = *b = 0.0;
00365 }
00366 return mu;
00367 }
00368
00369 BOOL hitpoint2(vector n, vector x, vector y, vector pb, vector pf,
00370 double * a, double * b){
00371
00372
00373
00374
00375
00376
00377
00378
00379 vector c;
00380 double dd,xx,yy,xy,cx,cy;
00381 VECSUB(pb,pf,c)
00382 xx=DOT(x,x);
00383 yy=DOT(y,y);
00384 xy=DOT(x,y);
00385 cy=DOT(c,y);
00386 cx=DOT(c,x);
00387 dd=xx*yy-xy*xy;
00388 if(fabs(dd) < 1.e-10){
00389 *a = *b = 0.0;
00390 return FALSE;
00391 }
00392 dd = 1.0/dd;
00393 *a=(cx*yy-cy*xy)*dd;
00394 *b=(cy*xx-cx*xy)*dd;
00395 return TRUE;
00396 }
00397
00398 #define RTD 0.159154943
00399
00400 #ifdef _SUNSTYLE
00401 double hitcylinder(n,x,y,p0,p,a,b) vector n; vector x; vector y;
00402 vector p0; vector p; double *a; double *b; {
00403 #else
00404 double hitcylinder(vector n, vector x, vector y, vector p0, vector p,
00405 double * a, double * b){
00406 #endif
00407 double psi,theta,ddt;
00408 vector p1,q,p2;
00409 vecsub(p,p0,p1);
00410 psi =dot(p1,y)/dot(y,y);
00411 *b = psi;
00412 p2[0] = psi*y[0]; p2[1] = psi*y[1]; p2[2] = psi*y[2];
00413 q[0] = p1[0] - p2[0]; q[1] = p1[1] - p2[1]; q[2] = p1[2] - p2[2];
00414 normalize(q);
00415 ddt=DOT(q,n);
00416 if (ddt > 1.0)ddt = 1.0;
00417 else if(ddt < -1.0)ddt = -1.0;
00418 theta=acos(ddt)*RTD;
00419 cross(q,n,p1);
00420 if(dot(p1,y) <= 0.0){
00421 if(theta <= 0.25) *a = (0.25 - theta);
00422 else *a = (1.25 - theta);
00423 }
00424 else *a = (0.25 + theta);
00425 return psi;
00426 }
00427
00428 double hitsphere(vector y, vector dx, vector dy, vector p0, vector p,
00429 double * a, double * b){
00430
00431
00432
00433
00434
00435
00436
00437 vector x,z,r;
00438 VECCOPY(dx,x)
00439 normalize(x);
00440 VECSCALE(-1.0,dy,z)
00441 normalize(z);
00442 VECSUB(p,p0,r)
00443 normalize(r);
00444 *b = acos(DOT(r,z))*0.3183;
00445 *a = atan2(DOT(r,y),DOT(r,x))*0.1592;
00446 if(*a < 0.0) *a = 1.0 + *a;
00447 return 0.0;
00448 }
00449
00450 #define UpdateNoGlassBuffer(f,i,d,id,O) { \
00451 Zdepth[i]=d; Zbuffer[i]=id; Zobject[i]=O; \
00452 } \
00453
00454 #if NGLASS == 1
00455 #error BADGLASS1
00456 #define UpdateGlassBuffer(f,i,d,id,O,mattr) { \
00457 if(mattr > 0){ \
00458 if(d < Zglassd[0][i]){ \
00459 Zglassd[0][i]=d; Zglass[0][i]=id; ZglassO[0][i]=O; \
00460 } \
00461 } \
00462 else{ \
00463 if(d <= Zglassd[0][i])Zglass[0][i] = -1; \
00464 Zdepth[i]=d; Zbuffer[i]=id; Zobject[i]=O; \
00465 } \
00466 }
00467 #elif NGLASS == 2
00468 #error BADGLASS2
00469 #define UpdateGlassBuffer(f,i,d,id,O,mattr) { \
00470 if(mattr > 0){ \
00471 if(d < Zglassd[0][i]-600.0){ \
00472 if(O != ZglassO[0][i] || id != Zglass[0][i]){ \
00473 Zglassd[1][i]=Zglassd[0][i]; \
00474 ZglassO[1][i]=ZglassO[0][i]; \
00475 Zglass[1][i]=Zglass[0][i]; \
00476 } \
00477 Zglassd[0][i]=d; Zglass[0][i]=id; ZglassO[0][i]=O; \
00478 } \
00479 else if(d > Zglassd[0][i]+600.0 && \
00480 d < Zglassd[1][i]-600.0){ \
00481 Zglassd[1][i]=d; Zglass[1][i]=id; ZglassO[1][i]=O; \
00482 } \
00483 } \
00484 else{ \
00485 if(d <= Zglassd[0][i]){ \
00486 Zglass[0][i] = -1; Zglassd[0][i]=FARAWAY; \
00487 Zglass[1][i] = -1; Zglassd[1][i]=FARAWAY; \
00488 } \
00489 else if(d < Zglassd[1][i]){ \
00490 Zglass[1][i] = -1; \
00491 Zglassd[1][i]=FARAWAY; \
00492 } \
00493 Zdepth[i]=d; Zbuffer[i]=id; Zobject[i]=O; \
00494 } \
00495 }
00496 #elif NGLASS == 4
00497 #define UpdateGlassBuffer(f,i,d,id,O,mattr) { \
00498 if(mattr > 0){ \
00499 if(d < Zglassd[0][i]-600.0){ \
00500 if(O != ZglassO[0][i] || id != Zglass[0][i]){ \
00501 Zglassd[3][i]=Zglassd[2][i]; \
00502 ZglassO[3][i]=ZglassO[2][i]; \
00503 Zglass[3][i]=Zglass[2][i]; \
00504 Zglassd[2][i]=Zglassd[1][i]; \
00505 ZglassO[2][i]=ZglassO[1][i]; \
00506 Zglass[2][i]=Zglass[1][i]; \
00507 Zglassd[1][i]=Zglassd[0][i]; \
00508 ZglassO[1][i]=ZglassO[0][i]; \
00509 Zglass[1][i]=Zglass[0][i]; \
00510 } \
00511 Zglassd[0][i]=d; Zglass[0][i]=id; ZglassO[0][i]=O; \
00512 } \
00513 else if(d > Zglassd[0][i]+600.0 && \
00514 d < Zglassd[1][i]-600.0){ \
00515 if(O != ZglassO[1][i] || id != Zglass[1][i]){ \
00516 Zglassd[3][i]=Zglassd[2][i]; \
00517 ZglassO[3][i]=ZglassO[2][i]; \
00518 Zglass[3][i]=Zglass[2][i]; \
00519 Zglassd[2][i]=Zglassd[1][i]; \
00520 ZglassO[2][i]=ZglassO[1][i]; \
00521 Zglass[2][i]=Zglass[1][i]; \
00522 } \
00523 Zglassd[1][i]=d; Zglass[1][i]=id; ZglassO[1][i]=O; \
00524 } \
00525 else if(d > Zglassd[1][i]+600.0 && \
00526 d < Zglassd[2][i]-600.0){ \
00527 if(O != ZglassO[2][i] || id != Zglass[2][i]){ \
00528 Zglassd[3][i]=Zglassd[2][i]; \
00529 ZglassO[3][i]=ZglassO[2][i]; \
00530 Zglass[3][i]=Zglass[2][i]; \
00531 } \
00532 Zglassd[2][i]=d; Zglass[2][i]=id; ZglassO[2][i]=O; \
00533 } \
00534 else if(d > Zglassd[2][i]+600.0 && \
00535 d < Zglassd[3][i]-600.0){ \
00536 Zglassd[3][i]=d; Zglass[3][i]=id; ZglassO[3][i]=O; \
00537 } \
00538 } \
00539 else{ \
00540 if(d <= Zglassd[0][i]){ \
00541 Zglass[0][i] = -1; Zglassd[0][i]=FARAWAY; \
00542 Zglass[1][i] = -1; Zglassd[1][i]=FARAWAY; \
00543 Zglass[2][i] = -1; Zglassd[2][i]=FARAWAY; \
00544 Zglass[3][i] = -1; Zglassd[3][i]=FARAWAY; \
00545 } \
00546 else if(d < Zglassd[1][i]){ \
00547 Zglass[1][i] = -1; Zglassd[1][i]=FARAWAY; \
00548 Zglass[2][i] = -1; Zglassd[2][i]=FARAWAY; \
00549 Zglass[3][i] = -1; Zglassd[3][i]=FARAWAY; \
00550 } \
00551 else if(d < Zglassd[2][i]){ \
00552 Zglass[2][i] = -1; Zglassd[2][i]=FARAWAY; \
00553 Zglass[3][i] = -1; Zglassd[3][i]=FARAWAY; \
00554 } \
00555 else if(d < Zglassd[3][i]){ \
00556 Zglass[3][i] = -1; Zglassd[3][i]=FARAWAY; \
00557 } \
00558 Zdepth[i]=d; Zbuffer[i]=id; Zobject[i]=O; \
00559 } \
00560 }
00561 #else
00562 #error BADGLASS0
00563 #endif
00564
00565 void UpdateGlassScanBuffers(double xl, double xr, long id, long O,
00566 face *f, double d2,
00567 long *Zglass[], long *ZglassO[], double *Zglassd[],
00568 long *Zbuffer, long *Zobject,
00569 double *Zdepth, double *Zposn){
00570 long i,ixl,ixr,mapID;
00571 double depth,bL,bR,aL,aR,dL,dR;
00572 unsigned char mattr;
00573 if((mapID=f->ffmap) >= 0 && mapID < Object[O].NoMaps &&
00574 Object[O].Mbase[mapID].tp > 0)mattr=255;
00575 else if(f->ffmat < 0 || f->ffmat >= Object[O].NoMats)mattr=0;
00576 else mattr=(Object[O].Tbase + f->ffmat)->transp;
00577
00578
00579
00580
00581 xl += 0.001;
00582 xr -= 0.001;
00583 ixl = (long)xl;
00584 ixr = (long)xr;
00585 if(ixl == ixr){
00586 dL = xl - (double)Xcentre; dL/=scalex;
00587 dR = xr - (double)Xcentre; dR/=scalex;
00588 bL = f->n[0]*dL + f->n[2]*d2 + f->n[1];
00589 aL = (f->c)/bL;
00590 bR = f->n[0]*dR + f->n[2]*d2 + f->n[1];
00591 aR = (f->c)/bR;
00592 depth=min(aL,aR);
00593 if(depth > 1.000 && depth <= Zdepth[ixl]){
00594 UpdateGlassBuffer(f,ixl,depth,id,O,mattr)
00595 Zposn[ixl]=(xr+xl)/2.0;
00596 }
00597 return;
00598 }
00599 else{
00600 dL = xl - (double)Xcentre; dL/=scalex;
00601 bL = f->n[0]*dL + f->n[2]*d2 + f->n[1];
00602 aL = (f->c)/bL;
00603 bR = f->n[0]*DR[ixl] + f->n[2]*d2 + f->n[1];
00604 aR = (f->c)/bR;
00605 depth=min(aL,aR);
00606 if(depth > 1.000 && depth <= Zdepth[ixl]){
00607 UpdateGlassBuffer(f,ixl,depth,id,O,mattr)
00608 Zposn[ixl]=xl;
00609 }
00610 bL = f->n[0]*DL[ixr] + f->n[2]*d2 + f->n[1];
00611 aL = (f->c)/bL;
00612 dR = xr - (double)Xcentre; dR/=scalex;
00613 bR = f->n[0]*dR + f->n[2]*d2 + f->n[1];
00614 aR = (f->c)/bR;
00615 depth=min(aL,aR);
00616 if(depth > 1.000 && depth <= Zdepth[ixr]){
00617 UpdateGlassBuffer(f,ixr,depth,id,O,mattr)
00618 Zposn[ixr]=xr;
00619 }
00620 }
00621 if(ixr-ixl > 1)for(i=ixl+1;i<ixr;i++)
00622 {
00623 bL = f->n[0]*DL[i] + f->n[2]*d2 + f->n[1];
00624 aL = (f->c)/bL;
00625 bR = f->n[0]*DR[i] + f->n[2]*d2 + f->n[1];
00626 aR = (f->c)/bR;
00627 depth=min(aL,aR);
00628 if(depth > 1.000 && depth <= Zdepth[i]){
00629 UpdateGlassBuffer(f,i,depth,id,O,mattr)
00630 Zposn[i]=(double)i+0.5;
00631 }
00632 }
00633 }
00634
00635 void UpdateNoGlassScanBuffers(double xl, double xr, long id, long O,
00636 face *f, double d2,
00637 long *Zglass[], long *ZglassO[], double *Zglassd[],
00638 long *Zbuffer, long *Zobject,
00639 double *Zdepth, double *Zposn){
00640 long i,ixl,ixr;
00641 double depth,bL,bR,aL,aR,dL,dR;
00642 unsigned char mattr;
00643 if(f->ffmat < 0 || f->ffmat >= Object[O].NoMats)mattr=0;
00644 else mattr=(Object[O].Tbase + f->ffmat)->transp;
00645
00646
00647
00648
00649 xl += 0.001;
00650 xr -= 0.001;
00651 ixl = (long)xl;
00652 ixr = (long)xr;
00653 if(ixl == ixr){
00654 dL = xl - (double)Xcentre; dL/=scalex;
00655 dR = xr - (double)Xcentre; dR/=scalex;
00656 bL = f->n[0]*dL + f->n[2]*d2 + f->n[1];
00657 aL = (f->c)/bL;
00658 bR = f->n[0]*dR + f->n[2]*d2 + f->n[1];
00659 aR = (f->c)/bR;
00660 depth=min(aL,aR);
00661 if(depth > 1.000 && depth <= Zdepth[ixl]){
00662 UpdateNoGlassBuffer(f,ixl,depth,id,O)
00663 Zposn[ixl]=(xr+xl)/2.0;
00664 }
00665 return;
00666 }
00667 else{
00668 dL = xl - (double)Xcentre; dL/=scalex;
00669 bL = f->n[0]*dL + f->n[2]*d2 + f->n[1];
00670 aL = (f->c)/bL;
00671 bR = f->n[0]*DR[ixl] + f->n[2]*d2 + f->n[1];
00672 aR = (f->c)/bR;
00673 depth=min(aL,aR);
00674 if(depth > 1.000 && depth <= Zdepth[ixl]){
00675 UpdateNoGlassBuffer(f,ixl,depth,id,O)
00676 Zposn[ixl]=xl;
00677 }
00678 bL = f->n[0]*DL[ixr] + f->n[2]*d2 + f->n[1];
00679 aL = (f->c)/bL;
00680 dR = xr - (double)Xcentre; dR/=scalex;
00681 bR = f->n[0]*dR + f->n[2]*d2 + f->n[1];
00682 aR = (f->c)/bR;
00683 depth=min(aL,aR);
00684 if(depth > 1.000 && depth <= Zdepth[ixr]){
00685 UpdateNoGlassBuffer(f,ixr,depth,id,O)
00686 Zposn[ixr]=xr;
00687 }
00688 }
00689 if(ixr-ixl > 1)for(i=ixl+1;i<ixr;i++)
00690 {
00691 bL = f->n[0]*DL[i] + f->n[2]*d2 + f->n[1];
00692 aL = (f->c)/bL;
00693 bR = f->n[0]*DR[i] + f->n[2]*d2 + f->n[1];
00694 aR = (f->c)/bR;
00695 depth=min(aL,aR);
00696 if(depth > 1.000 && depth <= Zdepth[i]){
00697 UpdateNoGlassBuffer(f,i,depth,id,O)
00698 Zposn[i]=(double)i+0.5;
00699 }
00700 }
00701 }
00702
00703 long Intersect(long scanline, vertex *v1, vertex *v2,
00704 double *xi){
00705 double ddx,ddy,doff,ddxy;
00706 if((v1->y < (double)scanline) && (v2->y < (double)scanline))return 0;
00707 if((v1->y > (double)scanline) && (v2->y > (double)scanline))return 0;
00708 ddy = (v2->y) - (v1->y);
00709 if(fabs(ddy) < 0.0001)return 0;
00710 ddx = (v2->x) - (v1->x);
00711 doff=(double)scanline - v1->y;
00712 ddxy=ddx*doff/ddy;
00713 *xi=(v1->x)+ddxy;
00714 return 1;
00715 }
00716
00717 long Active(long scanline, vertex *v, face *f,
00718 double *leftedge, double *rightedge){
00719 long v1,v2,v3
00720 ,i1,i2,i3;
00721 double x1,x2,x3;
00722 if(f->top > scanline) return 0;
00723 if(f->bottom < scanline) return 0;
00724 v1=f->V[0];
00725 v2=f->V[1];
00726 v3=f->V[2];
00727 i1=Intersect(scanline,(v+v1),(v+v2),&x1);
00728 i2=Intersect(scanline,(v+v2),(v+v3),&x2);
00729 i3=Intersect(scanline,(v+v3),(v+v1),&x3);
00730 if((i1 == 1) && (i2 == 1) && (i3 == 1))
00731 {*leftedge = min(min(x1,x2),x3);
00732 *rightedge= max(max(x1,x2),x3);}
00733 else if((i2 == 1) && (i3 == 1))
00734 {*leftedge = min(x2,x3);
00735 *rightedge= max(x2,x3);}
00736 else if((i3 == 1) && (i1 == 1))
00737 {*leftedge = min(x3,x1);
00738 *rightedge= max(x3,x1);}
00739 else if((i1 == 1) && (i2 == 1))
00740 {*leftedge = min(x1,x2);
00741 *rightedge= max(x1,x2);}
00742 else return 0;
00743 if(*leftedge >= (double)XMAX-0.002)return 0;
00744 else *leftedge = max(0,*leftedge);
00745 if(*rightedge < (double)XMIN+0.002)return 0;
00746 *rightedge = min((double)XMAX-0.01,*rightedge);
00747 return 1;
00748 }
00749
00750 void SetPerspectiveView(long StereoLeft){
00751 double t1[4][4],t2[4][4],t3[4][4],t4[4][4];
00752 double lenz=50.0;
00753 if(ResolutionX > ResolutionY)
00754 scalex=scaley=(double)ResolutionX/2.0/21.22*lenz;
00755 else
00756 scalex=scaley=(double)ResolutionY/2.0/21.22*lenz;
00757 if(ResolutionX <= 320 && ResolutionY <= 200)
00758 scaley /= 1.2;
00759 if(anti_alias == LOW) {scalex *= 2;}
00760 if(anti_alias == MEDIUM){scalex *= 2; scaley *= 2;}
00761 if(anti_alias == HIGH) {scalex *= 3; scaley *= 2;}
00762 if(anti_alias == ULTRA) {scalex *= 3; scaley *= 3;}
00763 CamTheta *= PI/180.0;
00764 CamPhi *= PI/180.0;
00765 CamAlpha *= PI/180.0;
00766 scalex *= CamSx;
00767 scaley *= CamSy;
00768 R_tram(t1,-ViewPoint[0],-ViewPoint[1],-ViewPoint[2]);
00769 R_rotz(t2,-CamPhi);
00770 R_m4by4(t2,t1,t3);
00771 R_rotx(t1,-CamAlpha);
00772 R_m4by4(t1,t3,t2);
00773 R_roty(t1,-CamTheta);
00774 R_m4by4(t1,t2,ViewTransform);
00775 R_roty(t1,CamTheta);
00776 R_rotx(t2,CamAlpha);
00777 R_m4by4(t2,t1,t3);
00778 R_rotz(t1,CamPhi);
00779 R_m4by4(t1,t3,AntiCamera);
00780 R_rotz(t1,CamPhi);
00781 R_rotx(t2,CamAlpha);
00782
00783 R_roty(t3,CamTheta);
00784 R_m4by4(t2,t3,t4);
00785 R_m4by4(t1,t4,CameraRotate);
00786
00787
00788
00789 if(StereoRenderingON == YES){
00790 double tStereo[4][4],rStereo[4][4];
00791 double r,d;
00792 r=atan2(CamStereoSeparation/2.0,CamParallaxDepth);
00793 d=CamStereoSeparation/2.0*CamRuler;
00794 if(StereoLeft == 1){
00795 R_tram(tStereo,d,0.0,0.0);
00796 R_rotz(rStereo,r);
00797 }
00798 else{
00799 R_tram(tStereo,-d,0.0,0.0);
00800 R_rotz(rStereo,-r);
00801 }
00802 R_m4by4(rStereo,ViewTransform,t1);
00803 R_m4by4(tStereo,t1,ViewTransform);
00804 R_m4by4(rStereo,AntiCamera,t1);
00805 R_c4to4(t1,AntiCamera);
00806 R_m4by4(rStereo,CameraRotate,t1);
00807 R_c4to4(t1,CameraRotate);
00808 }
00809 AntiCameraGL[0][0]= AntiCamera[0][0];
00810 AntiCameraGL[0][1]= AntiCamera[0][2];
00811 AntiCameraGL[0][2]=-AntiCamera[0][1];
00812 AntiCameraGL[1][0]= AntiCamera[2][0];
00813 AntiCameraGL[1][1]= AntiCamera[2][2];
00814 AntiCameraGL[1][2]=-AntiCamera[2][1];
00815 AntiCameraGL[2][0]=-AntiCamera[1][0];
00816 AntiCameraGL[2][1]=-AntiCamera[1][2];
00817 AntiCameraGL[2][2]= AntiCamera[1][1];
00818 return;
00819 }
00820
00821
00822 void ApplyViewingTransformToPoint(vector vin, vector vout){
00823 double x1,y1,z1;
00824 R_m4by1(ViewTransform,vin[0],vin[1],vin[2],&x1,&y1,&z1);
00825 vout[0]=x1; vout[1]=y1; vout[2]=z1;
00826 }
00827
00828 void BendNormal(vector nin, vector dn, vector nout){
00829 double x1,y1,z1,x2,y2,z2;
00830 R_m3by1(AntiCamera,nin[0],nin[1],nin[2],&x1,&y1,&z1);
00831 x2=x1+dn[0]; y2=y1+dn[1]; z2=z1+dn[2];
00832 R_m3by1(ViewTransform,x2,y2,z2,&nout[0],&nout[1],&nout[2]);
00833 }
00834
00835 void MakeObjectTransformation(
00836 double fi, double theta, double alpha,
00837 short im, double ima,
00838 double sx, double sy, double sz,
00839 vector Centre,
00840 vector Position,
00841 double trpos[4][4],
00842 double trset[4][4],
00843 double trinv[4][4]){
00844 double t1[4][4],t2[4][4],t3[4][4],t4[4][4];
00845 fi *= PI/180.0;
00846 theta *= PI/180.0;
00847 alpha *= PI/180.0;
00848 R_tram(t2,-(double)Centre[0],-(double)Centre[1],-(double)Centre[2]);
00849 R_scal(t3,sx,sy,sz);
00850 R_m4by4(t3,t2,t1);
00851 if(im > 0){
00852 if(im == 1)R_rotz(t3,ima*PI/180.0);
00853 if(im == 2)R_rotx(t3,ima*PI/180.0);
00854 if(im == 3)R_roty(t3,ima*PI/180.0);
00855 R_m4by4(t3,t1,t2);
00856 R_roty(t1,theta);
00857 R_m4by4(t1,t2,t3);
00858 }
00859 else{
00860 R_roty(t2,theta);
00861 R_m4by4(t2,t1,t3);
00862 }
00863 R_rotx(t1,alpha);
00864 R_m4by4(t1,t3,t2);
00865 R_rotz(t1,fi);
00866 R_m4by4(t1,t2,t3);
00867 R_tram(t1,Position[0],Position[1],Position[2]);
00868 R_m4by4(t1,t3,trset);
00869 R_m4by4(ViewTransform,trset,trpos);
00870
00871
00872
00873 R_tram(t1,-Position[0],-Position[1],-Position[2]);
00874 R_rotz(t2,-fi);
00875 R_m4by4(t2,t1,t3);
00876 R_rotx(t1,-alpha);
00877 R_m4by4(t1,t3,t2);
00878 if(im > 0){
00879 R_roty(t1,-theta);
00880 if(im == 1)R_rotz(t3,-ima*PI/180.0);
00881 if(im == 2)R_rotx(t3,-ima*PI/180.0);
00882 if(im == 3)R_roty(t3,-ima*PI/180.0);
00883 R_m4by4(t3,t1,t4);
00884 }
00885 else{
00886 R_roty(t4,-theta);
00887 }
00888 R_m4by4(t4,t2,t1);
00889 R_scal(t2,1.0/sx,1.0/sy,1.0/sz);
00890 R_m4by4(t2,t1,t3);
00891 R_tram(t2,(double)Centre[0],(double)Centre[1],(double)Centre[2]);
00892 R_m4by4(t2,t3,t1);
00893 R_m4by4(t1,AntiCamera,trinv);
00894 return;
00895 }
00896
00897 void TransformMappingRectangle(
00898 double trpos[4][4], vector P, vector X, vector Y,
00899 vector p, vector x, vector y, vector n){
00900 R_m4by1(trpos,P[0],P[1],P[2],&p[0],&p[1],&p[2]);
00901 R_m4by1(trpos,X[0],X[1],X[2],&x[0],&x[1],&x[2]);
00902 R_m4by1(trpos,Y[0],Y[1],Y[2],&y[0],&y[1],&y[2]);
00903 vecsub(x,p,x);
00904 vecsub(y,p,y);
00905 cross (x,y,n);
00906 if(normalize(n)){
00907 x[0]=1.0; x[1]=0.0; x[2]=0.0;
00908 y[0]=0.0; y[1]=1.0; y[2]=0.0;
00909 cross(x,y,n);
00910 }
00911 }
00912
00913
00914 void R_rotz(double tr[4][4], double ang){
00915 long i,j;
00916 for(i=0;i<4;i++)
00917 for(j=0;j<4;j++)
00918 {
00919 tr[i][j]=0.0;
00920 if(i == j)tr[i][j]=1.0;
00921 }
00922 tr[0][0] = cos(ang);
00923 tr[0][1] = -sin(ang);
00924 tr[1][0] = sin(ang);
00925 tr[1][1] = cos(ang);
00926 return;
00927 }
00928
00929 #ifdef _SUNSTYLE
00930 void R_rotx(tr,ang) double tr[4][4]; double ang; {
00931 #else
00932 void R_rotx(double tr[4][4], double ang){
00933 #endif
00934 long i,j;
00935 for(i=0;i<4;i++)
00936 for(j=0;j<4;j++)
00937 {
00938 tr[i][j]=0.0;
00939 if(i == j)tr[i][j]=1.0;
00940 }
00941 tr[1][1] = cos(ang);
00942 tr[1][2] = -sin(ang);
00943 tr[2][1] = sin(ang);
00944 tr[2][2] = cos(ang);
00945 return;
00946 }
00947
00948 void R_roty(double tr[4][4], double ang){
00949 long i,j;
00950 for(i=0;i<4;i++)
00951 for(j=0;j<4;j++)
00952 {
00953 tr[i][j]=0.0;
00954 if(i == j)tr[i][j]=1.0;
00955 }
00956 tr[0][0] = cos(ang);
00957 tr[0][2] = -sin(ang);
00958 tr[2][0] = sin(ang);
00959 tr[2][2] = cos(ang);
00960 return;
00961 }
00962
00963 void R_tram(double t[4][4], double dx, double dy, double dz){
00964 long i,j;
00965 for(i=0;i<4;i++)
00966 for(j=0;j<4;j++)
00967 {
00968 t[i][j]=0.0;
00969 if(i == j)t[i][j]=1.0;
00970 }
00971 t[0][3]=dx;
00972 t[1][3]=dy;
00973 t[2][3]=dz;
00974 t[3][3]=1;
00975 return;
00976 }
00977
00978 void R_scal(double t[4][4], double sx, double sy, double sz){
00979 long i,j;
00980 for(i=0;i<4;i++)
00981 for(j=0;j<4;j++)
00982 {
00983 t[i][j]=0.0;
00984 if(i == j)t[i][j]=1.0;
00985 }
00986 t[0][0]=sx;
00987 t[1][1]=sy;
00988 t[2][2]=sz;
00989 t[3][3]=1;
00990 return;
00991 }
00992
00993 void R_m4by4(double t1[4][4], double t2[4][4], double tr[4][4]){
00994 long i,j,k;
00995 for(i=0;i<4;i++)
00996 for(j=0;j<4;j++)
00997 {
00998 tr[i][j]=0.0;
00999 for(k=0;k<4;k++)tr[i][j]=tr[i][j]+t1[i][k]*t2[k][j];
01000 }
01001 return;
01002 }
01003
01004 void R_c4to4(double tin[4][4], double tout[4][4]){
01005 int i,j;
01006 for(i=0;i<4;i++)
01007 for(j=0;j<4;j++)
01008 tout[i][j]=tin[i][j];
01009 return;
01010 }
01011
01012 void R_null_transform(double t[4][4]){
01013 short i,j;
01014 for(i=0;i<4;i++)
01015 for(j=0;j<4;j++)
01016 if(i == j)t[i][j]=1.0;
01017 else t[i][j]=0.0;
01018 }
01019
01020 void R_m4by1(double t4[4][4], double x, double y, double z,
01021 double *xx, double *yy, double *zz){
01022 *xx=t4[0][0]*x+t4[0][1]*y+t4[0][2]*z+t4[0][3];
01023 *yy=t4[1][0]*x+t4[1][1]*y+t4[1][2]*z+t4[1][3];
01024 *zz=t4[2][0]*x+t4[2][1]*y+t4[2][2]*z+t4[2][3];
01025 return;
01026 }
01027
01028 void R_m3by1(double t4[4][4], double x, double y, double z,
01029 double *xx, double *yy, double *zz){
01030 *xx=t4[0][0]*x+t4[0][1]*y+t4[0][2]*z;
01031 *yy=t4[1][0]*x+t4[1][1]*y+t4[1][2]*z;
01032 *zz=t4[2][0]*x+t4[2][1]*y+t4[2][2]*z;
01033 return;
01034 }
01035
01036
01037 #ifdef _SUNSTYLE
01038 void R_reflect(t,p,n) double t[4][4]; vector p; vector n; {
01039 #else
01040 void R_reflect(double t[4][4], vector p, vector n){
01041 #endif
01042
01043
01044 long i,j;
01045 double dxy,phi,theta;
01046 double t1[4][4],t2[4][4],t3[4][4];
01047
01048
01049
01050
01051
01052 dxy=n[0]*n[0]+n[1]*n[1];
01053 R_tram(t1,-p[0],-p[1],-p[2]);
01054 if(fabs(n[2]) > 0.7071){
01055
01056 if(fabs(n[2]) > 0.998){
01057
01058 for(i=0;i<4;i++)for(j=0;j<4;j++){
01059 if(i == j)t2[i][j]=1.0;
01060 else t2[i][j]=0.0;
01061 }
01062 t2[2][2]=-1.0;
01063 R_m4by4(t2,t1,t3);
01064 R_tram(t1,p[0],p[1],p[2]);
01065 R_m4by4(t1,t3,t);
01066 return;
01067 }
01068 dxy=sqrt(dxy);
01069 if (fabs(n[0]) < 1.e-6 && n[1] > 0.0)phi = 1.570796;
01070 else if(fabs(n[0]) < 1.e-6 && n[1] < 0.0)phi = -1.570796;
01071 else phi = atan2(n[1],n[0]);
01072 if(n[2] > 0.0)theta = 1.570796-atan2(n[2],dxy);
01073 else theta = -1.570796-atan2(n[2],dxy);
01074 R_rotz(t2, -phi);
01075 R_m4by4(t2,t1,t3);
01076 R_roty(t2, theta);
01077 R_m4by4(t2,t3,t1);
01078 for(i=0;i<4;i++)for(j=0;j<4;j++){
01079 if(i == j)t2[i][j]=1.0;
01080 else t2[i][j]=0.0;
01081 }
01082 t2[2][2]=-1.0;
01083 R_m4by4(t2,t1,t3);
01084 R_roty(t2,-theta);
01085 R_m4by4(t2,t3,t1);
01086 R_rotz(t2,phi);
01087 R_m4by4(t2,t1,t3);
01088 R_tram(t1,p[0],p[1],p[2]);
01089 R_m4by4(t1,t3,t);
01090 }
01091 else{
01092 dxy=sqrt(dxy);
01093 if (fabs(n[0]) < 1.e-6 && n[1] > 0.0)phi = 1.570796;
01094 else if(fabs(n[0]) < 1.e-6 && n[1] < 0.0)phi = -1.570796;
01095 else phi = atan2(n[1],n[0]);
01096 theta = atan2(n[2],dxy);
01097 R_rotz(t2, -phi);
01098 R_m4by4(t2,t1,t3);
01099 R_roty(t2, -theta);
01100 R_m4by4(t2,t3,t1);
01101 for(i=0;i<4;i++)for(j=0;j<4;j++){
01102 if(i == j)t2[i][j]=1.0;
01103 else t2[i][j]=0.0;
01104 }
01105 t2[0][0]=-1.0;
01106 R_m4by4(t2,t1,t3);
01107 R_roty(t2,theta);
01108 R_m4by4(t2,t3,t1);
01109 R_rotz(t2,phi);
01110 R_m4by4(t2,t1,t3);
01111 R_tram(t1,p[0],p[1],p[2]);
01112 R_m4by4(t1,t3,t);
01113 }
01114 return;
01115 }
01116
01117 void veccopy(vector v1, vector r){
01118 r[0] = v1[0];
01119 r[1] = v1[1];
01120 r[2] = v1[2];
01121 }
01122
01123 void vecsub(vector v1, vector v2, vector r){
01124 r[0] = v1[0] - v2[0];
01125 r[1] = v1[1] - v2[1];
01126 r[2] = v1[2] - v2[2];
01127 }
01128
01129 void vecsum(vector v1,vector v2, vector r){
01130 r[0] = v1[0] + v2[0];
01131 r[1] = v1[1] + v2[1];
01132 r[2] = v1[2] + v2[2];
01133 }
01134
01135 void vecscale(double s, vector v, vector r){
01136 r[0] = s * v[0];
01137 r[1] = s * v[1];
01138 r[2] = s * v[2];
01139 }
01140
01141 short normalize(vector v){
01142 double n,nn;
01143 n= (double)((v[0]*v[0]) + (v[1]*v[1]) + (v[2]*v[2]));
01144 if(n < 1.e-10)return 1;
01145 nn=sqrt(n);
01146 n = 1.0 / nn;
01147 vecscale(n,v,v);
01148 return 0;
01149 }
01150
01151 double R_length(vector v){
01152 double n,nn;
01153 n= (double)((v[0]*v[0]) + (v[1]*v[1]) + (v[2]*v[2]));
01154 nn=sqrt(n);
01155 return (nn);
01156 }
01157
01158 void cross(vector v1,vector v2, vector r){
01159 r[0] = (v1[1]*v2[2]) - (v2[1]*v1[2]);
01160 r[1] = (v1[2]*v2[0]) - (v1[0]*v2[2]);
01161 r[2] = (v1[0]*v2[1]) - (v2[0]*v1[1]);
01162 }
01163
01164 double dot(vector v1, vector v2){
01165 double result;
01166 result = v1[0] * v2[0];
01167 result += v1[1] * v2[1];
01168 result += v1[2] * v2[2];
01169 return result;
01170 }
01171
01172 void AssignMappingCoordinatesToVertices(object *O){
01173 vertex *Vbase=O->Vbase;
01174 face *f,*Fbase=O->Fbase;
01175 imap *m,*Mbase=O->Mbase;
01176 matl *Tbase=O->Tbase;
01177 axis *a;
01178 long nfaces=O->NoFaces;
01179 long nvert=O->NoVertices;
01180 long nmaps=O->NoMaps;
01181 long nmats=O->NoMats;
01182 long i,j,mapid,matid;
01183 double alpha,beta,gamma,alphav[3],betav[3];
01184 if(nmaps > 0)for(i=0,m=Mbase;i<nmaps;i++,m++){
01185
01186 vecsub(m->xin,m->pin,m->x);
01187 vecsub(m->yin,m->pin,m->y);
01188 cross(m->x,m->y,m->n);
01189 if(normalize(m->n)){
01190 m->x[0]=1.0; m->x[1]=0.0; m->x[2]=0.0;
01191 m->y[0]=0.0; m->y[1]=1.0; m->y[2]=0.0;
01192 cross(m->x,m->y,m->n);
01193 }
01194 }
01195 for(i = -1; i<nmats; i++){
01196 if(i == -1)a = &(O->Abase);
01197 else a = &((Tbase+i)->ax);
01198 vecsub(a->buin,a->boin,a->bu);
01199 vecsub(a->bvin,a->boin,a->bv);
01200 cross(a->bu,a->bv,a->bn);
01201 normalize(a->bn);
01202 a->tl=max(1.0,R_length(a->bu));
01203 a->tv=max(1.0,R_length(a->bv));
01204 vecscale(1.0/a->tl,a->bu,a->bu_norm);
01205 vecscale(1.0/a->tv,a->bv,a->bv_norm);
01206 }
01207 for(i=0,f=Fbase;i<nfaces;i++,f++){
01208 if(f->bFmc){;}
01209 else if(f->ffmap >= 0){
01210 mapid=f->ffmap;
01211 if(mapid < nmaps){
01212 if((m=(Mbase+mapid))->map != MAP_BY_VERTEX){
01213 for(j=0;j<3;j++){
01214 if(m->map == CYLINDER){
01215 hitcylinder(m->n,m->x,m->y,m->p,
01216 (Vbase+(f->V[j]))->p,&(alphav[j]),&(betav[j]));
01217 }
01218 else if(m->map == MAP_SPHERICAL){
01219 hitsphere(m->n,m->x,m->y,m->p
01220 ,(Vbase+(f->V[j]))->p,&(alphav[j]),&(betav[j]));
01221 }
01222 else
01223 hitpoint(m->n,m->x,m->y,m->p
01224 ,(Vbase+(f->V[j]))->p,&(alphav[j]),&(betav[j]));
01225 }
01226 if(m->map == CYLINDER || m->map == MAP_SPHERICAL)FixUpMapEdge(alphav);
01227 for(j=0;j<3;j++){
01228 if(m->map == CYLINDER)alphav[j] *= m->angle;
01229 f->uu[j]=alphav[j];
01230 f->vv[j]=betav[j];
01231 f->ww[j]=0.5;
01232
01233 }
01234 }
01235 }
01236 }
01237 else{
01238 for(j=0;j<3;j++){
01239 matid=f->ffmat;
01240 if(matid >= 0 && matid < nmats)a = &((Tbase+matid)->ax);
01241 else a = &(O->Abase);
01242 gamma=hitpoint(a->bn,
01243 a->bu,
01244 a->bv,
01245 a->bo,
01246 (Vbase+(f->V[j]))->p,&alpha,&beta);
01247 gamma /= max(1.0,a->tl);
01248 f->uu[j]=alpha;
01249 f->vv[j]=beta;
01250 f->ww[j]=gamma;
01251 }
01252 }
01253 }
01254
01255 if(nmaps > 0)for(i=0,m=Mbase;i<nmaps;i++,m++){
01256 m->map = MAP_BY_VERTEX;
01257 }
01258 }
01259
01260 #define MAPDELTA 0.33333
01261
01262 static void FixUpMapEdge(GLfloat a[]){
01263 if(a[0] < MAPDELTA){if(a[1] >= 1.0-MAPDELTA)a[1] -= 1.0; if(a[2] >= 1.0-MAPDELTA)a[2] -= 1.0; return;}
01264 if(a[1] < MAPDELTA){if(a[2] >= 1.0-MAPDELTA)a[2] -= 1.0; if(a[0] >= 1.0-MAPDELTA)a[0] -= 1.0; return;}
01265 if(a[2] < MAPDELTA){if(a[0] >= 1.0-MAPDELTA)a[0] -= 1.0; if(a[1] >= 1.0-MAPDELTA)a[1] -= 1.0; return;}
01266 }