home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ARM Club 3
/
TheARMClub_PDCD3.iso
/
hensa
/
graphics
/
a150_1
/
!Demo4
/
c
/
sol
< prev
next >
Wrap
Text File
|
1992-02-10
|
12KB
|
410 lines
/******************************************************************************
* *
* 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);
}