home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * *
- * sol.c *
- * *
- ******************************************************************************/
-
- #include <stdlib.h>
- #include <math.h>
- #include "GrpLib.h"
- #include "extern.h"
-
- /*****************************************************************************/
-
- void ProdVectorielNI(vec4 a,double b[],double c[])
- {
- double n,d[4];
-
- d[0] = -(b[1]*c[2] - b[2]*c[1]);
- d[1] = -(b[2]*c[0] - b[0]*c[2]);
- d[2] = -(b[0]*c[1] - b[1]*c[0]);
-
- n = sqrt(d[0]*d[0] + d[1]*d[1] + d[2]*d[2]);
- a[0] = (int)(16384*d[0]/n);
- a[1] = (int)(16384*d[1]/n);
- a[2] = (int)(16384*d[2]/n);
- }
-
- /*****************************************************************************/
-
- void TransformPt(vec3 q,mat33 m,vec3 t,vec3 p)
- {
- q[0] = ((m[0][0]*p[0] + m[1][0]*p[1] + m[2][0]*p[2])>>14) + t[0];
- q[1] = ((m[0][1]*p[0] + m[1][1]*p[1] + m[2][1]*p[2])>>14) + t[1];
- q[2] = ((m[0][2]*p[0] + m[1][2]*p[1] + m[2][2]*p[2])>>14) + t[2];
- }
-
- /*****************************************************************************/
-
- void trace(vec4 pts[],int i,int k,int i2,int k2,int tgx,
- char *sprite,int pgx,int pgz)
- {
- GrpReg[ 0] = pts[2*(i+ (k )*tgx)+1][0];
- GrpReg[ 1] = pts[2*(i+ (k )*tgx)+1][1];
- GrpReg[ 2] = pts[2*(i+i2+(k+k2)*tgx)+1][0];
- GrpReg[ 3] = pts[2*(i+i2+(k+k2)*tgx)+1][1];
- GrpReg[ 4] = pts[2*(i+1 +(k+1 )*tgx)+1][0];
- GrpReg[ 5] = pts[2*(i+1 +(k+1 )*tgx)+1][1];
- GrpReg[ 6] = i *pgx;
- GrpReg[ 7] = k *pgz;
- GrpReg[ 8] = (i+i2)*pgx;
- GrpReg[ 9] = (k+k2)*pgz;
- GrpReg[10] = (i+1) *pgx;
- GrpReg[11] = (k+1) *pgz;
- GrpReg[12] = (int)sprite;
- CallGrp(GrpReg,GrpStack,Spr2DPoly3);
- }
-
- /*****************************************************************************/
-
- void InitSol(Sol *sold,char *spr,int *alt,int scalex,int scalez)
- {
- int tgx,tgz,pgx,pgz;
- int nbpts,nbnms,i,k;
- vec4 *normals,*points;
- int *altd;
- double b[4],c[4];
-
- sold->sprite = spr;
- sold->altitudes = alt;
-
- tgx = (sold->tgx = alt[ 7]);
- tgz = (sold->tgz = alt[ 8]);
- pgx = (sold->pgx = alt[ 9]);
- pgz = (sold->pgz = alt[10]);
- sold->scalex = scalex;
- sold->scalez = scalez;
- altd = alt + (alt[6]>>2);
-
- nbpts = tgx*tgz;
- points = ( sold->points = malloc( (nbpts+1) * sizeof(vec4)) );
- sold->pscreen = malloc(2 * (nbpts+1) * sizeof(vec4));
- points[nbpts][3] = -1;
- sold->pscreen[2*nbpts][3] = -1;
-
- for(k=0 ; k<tgz ; k++)
- for(i=0 ; i<tgx ; i++) {
- int alt1;
- alt1 = altd[i+k*tgx];
- if (i==0 ) { alt1=0; }
- if (i==tgx-1) { alt1=0; }
- if (k==0 ) { alt1=0; }
- if (k==tgz-1) { alt1=0; }
- points[i+k*tgx][0] = scalex*i*pgx;
- points[i+k*tgx][1] = alt1;
- points[i+k*tgx][2] = scalez*k*pgz;
- points[i+k*tgx][3] = 0;
- }
-
- nbnms = 2*(tgx-1)*(tgz-1);
- normals = ( sold->normals = malloc((nbnms+1) * sizeof(vec4)) );
- sold->nscreen = malloc((nbnms+1) * sizeof(vec4));
- normals[nbnms][3] = -1;
-
- for(k=0 ; k<tgz-1 ; k++)
- for(i=0 ; i<tgx-1 ; i++) {
- int alt1,alt2,alt3,alt4;
- alt1 = altd[(i )+(k )*tgx];
- alt2 = altd[(i+1)+(k )*tgx];
- alt3 = altd[(i )+(k+1)*tgx];
- alt4 = altd[(i+1)+(k+1)*tgx];
- if (i==0 ) { alt1=0; alt3=0; }
- if (i==tgx-2) { alt2=0; alt4=0;}
- if (k==0 ) { alt1=0; alt2=0;}
- if (k==tgz-2) { alt3=0; alt4=0;}
- b[0] = scalex*pgx;
- b[1] = alt2 - alt1;
- b[2] = 0;
- c[0] = 0;
- c[1] = alt4 - alt2;
- c[2] = scalez*pgz;
- ProdVectorielNI(normals[2*(i+k*(tgx-1)) ],b,c);
- b[0] = scalex*pgx;
- b[1] = alt4 - alt3;
- b[2] = 0;
- c[0] = 0;
- c[1] = alt3 - alt1;
- c[2] = scalez*pgz;
- ProdVectorielNI(normals[2*(i+k*(tgx-1))+1],b,c);
- }
- }
-
- /*****************************************************************************/
-
- void PlotSol(Envi *envi,Object *obs,Object *sol,Sol *sold)
- {
- vec4 Obj4Rep[4];
- mat33 inv;
- vec3 transl,p;
- int vu;
-
- vec4 pex[5],pexs[10];
- int zneg=0,code,codeand=0;
-
- vec4 *pscreen,*nscreen;
-
- int tgx,tgz,pgx,pgz;
- char *sp;
- int x,z,nx,nz;
- int i,k;
-
- tgx = sold->tgx;
- tgz = sold->tgz;
- pgx = sold->pgx;
- pgz = sold->pgz;
- sp = sold->sprite;
-
- InvMat(inv,obs->Rep);
- MkVec3(transl,sol->Org[0] - obs->Org[0],
- sol->Org[1] - obs->Org[1],
- sol->Org[2] - obs->Org[2]);
-
- GrpReg[0] = (int)inv;
- GrpReg[1] = (int)Obj4Rep;
- GrpReg[2] = (int)sol->Rep;
- GrpReg[3] = (int)transl;
- CallGrp(GrpReg,GrpStack,RepToRepIn4Rep); /*Obj4Rep=inv*(transl o SolRep)*/
-
- /* verifie si le sol est dans la piramide de vision */
-
- pex[0][0] = sold->points[ 0][0];
- pex[0][1] = sold->points[ 0][1];
- pex[0][2] = sold->points[ 0][2];
- pex[0][3] = 0;
- pex[1][0] = sold->points[ tgx-1][0];
- pex[1][1] = sold->points[ tgx-1][1];
- pex[1][2] = sold->points[ tgx-1][2];
- pex[1][3] = 0;
- pex[2][0] = sold->points[(tgz-1)*tgx ][0];
- pex[2][1] = sold->points[(tgz-1)*tgx ][1];
- pex[2][2] = sold->points[(tgz-1)*tgx ][2];
- pex[2][3] = 0;
- pex[3][0] = sold->points[(tgz-1)*tgx+tgx-1][0];
- pex[3][1] = sold->points[(tgz-1)*tgx+tgx-1][1];
- pex[3][2] = sold->points[(tgz-1)*tgx+tgx-1][2];
- pex[3][3] = 0;
- pex[4][3] = -1;
-
- pexs[8][3] = -1;
-
- GrpReg[ 0] = Obj4Rep[0][0];
- GrpReg[ 1] = Obj4Rep[0][1];
- GrpReg[ 2] = Obj4Rep[0][2];
- GrpReg[ 3] = Obj4Rep[1][0];
- GrpReg[ 4] = Obj4Rep[1][1];
- GrpReg[ 5] = Obj4Rep[1][2];
- GrpReg[ 6] = Obj4Rep[2][0];
- GrpReg[ 7] = Obj4Rep[2][1];
- GrpReg[ 8] = Obj4Rep[2][2];
- GrpReg[ 9] = Obj4Rep[3][0];
- GrpReg[10] = Obj4Rep[3][1];
- GrpReg[11] = Obj4Rep[3][2];
- GrpReg[12] = (int)pex;
- GrpReg[13] = (int)pexs;
- Call2Grp(GrpReg,PtsTrans);
- GrpReg[13] = (int)pexs;
- Call2Grp(GrpReg,PtsProj);
-
- for (i=0 ; i<4 ; i++)
- if (pex[i][2] > 0) {
- zneg |= (0x01 << i);
- code = 0;
- if ( pexs[2*i+1][0] > 319) code |= 0x08;
- if ( pexs[2*i+1][0] < 0) code |= 0x04;
- if ( pexs[2*i+1][1] > 255) code |= 0x02;
- if ( pexs[2*i+1][1] < 0) code |= 0x01;
- codeand &= code;
- }
- if (((codeand != 0) && (zneg == 0x0F)) || (zneg == 0)) return;
-
- /* transforme points et normales, puis projette points */
-
- nscreen = sold->nscreen;
- pscreen = sold->pscreen;
-
- GrpReg[ 0] = Obj4Rep[0][0];
- GrpReg[ 1] = Obj4Rep[0][1];
- GrpReg[ 2] = Obj4Rep[0][2];
- GrpReg[ 3] = Obj4Rep[1][0];
- GrpReg[ 4] = Obj4Rep[1][1];
- GrpReg[ 5] = Obj4Rep[1][2];
- GrpReg[ 6] = Obj4Rep[2][0];
- GrpReg[ 7] = Obj4Rep[2][1];
- GrpReg[ 8] = Obj4Rep[2][2];
- GrpReg[12] = (int)(sold->normals);
- GrpReg[13] = (int)nscreen;
- Call2Grp(GrpReg,NormTrans);
-
- GrpReg[ 0] = Obj4Rep[0][0];
- GrpReg[ 1] = Obj4Rep[0][1];
- GrpReg[ 2] = Obj4Rep[0][2];
- GrpReg[ 3] = Obj4Rep[1][0];
- GrpReg[ 4] = Obj4Rep[1][1];
- GrpReg[ 5] = Obj4Rep[1][2];
- GrpReg[ 6] = Obj4Rep[2][0];
- GrpReg[ 7] = Obj4Rep[2][1];
- GrpReg[ 8] = Obj4Rep[2][2];
- GrpReg[ 9] = Obj4Rep[3][0];
- GrpReg[10] = Obj4Rep[3][1];
- GrpReg[11] = Obj4Rep[3][2];
- GrpReg[12] = (int)(sold->points);
- GrpReg[13] = (int)pscreen;
- Call2Grp(GrpReg,PtsTrans);
-
- for(k=0 ; k<tgz-1 ; k++) {
- register int ln,lp;
- ln = k*(tgx-1);
- lp = k* tgx;
- for(i=0 ; i<tgx-1 ; i++) {
- vu = nscreen[2*(i+ln) ][0] * pscreen[2*(i+lp)][0];
- vu += nscreen[2*(i+ln) ][1] * pscreen[2*(i+lp)][1];
- vu += nscreen[2*(i+ln) ][2] * pscreen[2*(i+lp)][2];
- nscreen[2*(i+ln) ][3] = -vu;
- if ((pscreen[2*(i +(k )*tgx)][2] < 0) ||
- (pscreen[2*(i+1+(k )*tgx)][2] < 0) ||
- (pscreen[2*(i+1+(k+1)*tgx)][2] < 0) )
- vu = 1;
- nscreen[2*(i+ln) ][3] = -vu;
- vu = nscreen[2*(i+ln)+1][0] * pscreen[2*(i+lp)][0];
- vu += nscreen[2*(i+ln)+1][1] * pscreen[2*(i+lp)][1];
- vu += nscreen[2*(i+ln)+1][2] * pscreen[2*(i+lp)][2];
- if ((pscreen[2*(i +(k )*tgx)][2] < 0) ||
- (pscreen[2*(i +(k+1)*tgx)][2] < 0) ||
- (pscreen[2*(i+1+(k+1)*tgx)][2] < 0) )
- vu = 1;
- nscreen[2*(i+ln)+1][3] = -vu;
- }
- }
-
- GrpReg[13] = (int)pscreen;
- Call2Grp(GrpReg,PtsProj);
-
- /* trace le sol en 4 fois */
-
- InvMat(inv,sol->Rep);
- MkVec3(transl,- sol->Org[0],
- - sol->Org[1],
- - sol->Org[2]);
- TransformPt(p,inv,transl,obs->Org);
-
- x = p[0];
- z = p[2];
-
- x = x/(pgx*sold->scalex);
- z = z/(pgz*sold->scalez);
-
- if ((x>0 ) && (z>0 )) {
- if (x>tgx-2) nx = tgx-2; else nx = x;
- if (z>tgz-2) nz = tgz-2; else nz = z;
- for (k=0 ; k<=nz ; k++) {
- register int ln;
- ln = k*(tgx-1);
- for (i=0 ; i<=nx ; i++) {
- if (nscreen[2*(i+ln)+1][3] > 0) trace(pscreen,i,k,0,1,tgx,sp,pgx,pgz);
- if (nscreen[2*(i+ln) ][3] > 0) trace(pscreen,i,k,1,0,tgx,sp,pgx,pgz);
- }
- }
- }
-
- if ((x<tgx) && (z>0 )) {
- if (x<0 ) nx = 0 ; else nx = x;
- if (z>tgz-2) nz = tgz-2; else nz = z;
- for (k=0 ; k<=nz ; k++) {
- register int ln;
- ln = k*(tgx-1);
- for (i=tgx-2 ; i>=nx ; i--) {
- if (nscreen[2*(i+ln) ][3] > 0) trace(pscreen,i,k,1,0,tgx,sp,pgx,pgz);
- if (nscreen[2*(i+ln)+1][3] > 0) trace(pscreen,i,k,0,1,tgx,sp,pgx,pgz);
- }
- }
- }
-
- if ((x>0 ) && (z<tgz)) {
- if (x>tgx-2) nx = tgx-2; else nx = x;
- if (z<0 ) nz = 0 ; else nz = z;
- for (k=tgz-2 ; k>=nz ; k--) {
- register int ln;
- ln = k*(tgx-1);
- for (i=0 ; i<=nx ; i++) {
- if (nscreen[2*(i+ln)+1][3] > 0) trace(pscreen,i,k,0,1,tgx,sp,pgx,pgz);
- if (nscreen[2*(i+ln) ][3] > 0) trace(pscreen,i,k,1,0,tgx,sp,pgx,pgz);
- }
- }
- }
-
- if ((x<tgx) && (z<tgz)) {
- if (x<0 ) nx = 0 ; else nx = x;
- if (z<0 ) nz = 0 ; else nz = z;
- for (k=tgz-2 ; k>=nz ; k--) {
- register int ln;
- ln = k*(tgx-1);
- for (i=tgx-2 ; i>=nx ; i--) {
- if (nscreen[2*(i+ln) ][3] > 0) trace(pscreen,i,k,1,0,tgx,sp,pgx,pgz);
- if (nscreen[2*(i+ln)+1][3] > 0) trace(pscreen,i,k,0,1,tgx,sp,pgx,pgz);
- }
- }
- }
- }
-
- /*****************************************************************************/
-
- int CollisionSol(Object *obs,Object *sol,Sol *sold)
- {
- mat33 inv;
- vec3 transl,p;
-
- vec4 *points;
- int tgx,tgz;
- int i,k;
- double x,z,lx,lz;
- double y;
-
- tgx = sold->tgx;
- tgz = sold->tgz;
- lx = sold->pgx * sold->scalex;
- lz = sold->pgz * sold->scalez;
- points = sold->points;
-
- InvMat(inv,sol->Rep);
- MkVec3(transl,- sol->Org[0],
- - sol->Org[1],
- - sol->Org[2]);
- TransformPt(p,inv,transl,obs->Org);
-
- i = (int)(p[0] / lx);
- k = (int)(p[2] / lz);
- x = p[0] % (int)lx;
- z = p[2] % (int)lz;
- /*
- SetTxtCurPos(15,0);
- printf("%d %d %d %d %d",i,k,x,z,p[1]);
- */
- if ((i>=0) && (i<=tgx-2) && (k>=0) && (k<=tgz-2)) {
- if (x>z) {
- y = points[i +(k )*tgx][1];
- y += (points[i+1+(k )*tgx][1] - points[i +(k )*tgx][1]) * x / lx;
- y += (points[i+1+(k+1)*tgx][1] - points[i+1+(k )*tgx][1]) * z / lz;
- if (y>p[1]-150) return(y+1); else return(0);
- }
- else {
- y = points[i +(k )*tgx][1];
- y += (points[i+1+(k+1)*tgx][1] - points[i +(k+1)*tgx][1]) * x / lx;
- y += (points[i +(k+1)*tgx][1] - points[i +(k )*tgx][1]) * z / lz;
- if (y>p[1]-150) return(y+1); else return(0);
- }
- }
- return(0);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-