www.pudn.com > 3DEDITOR.rar > CLASSLIB.CPP


#include "stdafx.h" 
 
#include  
#include  
 
void PrepRotateMatrix(int m, float Theta, mat4x4& M) 
{ 
  static int m1,m2; 
  static float c,s; 
 
  memset(&M.Mat[0][0],0,sizeof(mat4x4)); 
 
  M.Mat[m-1][m-1]=1.0; 
  M.Mat[3][3]=1.0; 
  m1=(m % 3)+1; 
  m2=(m1 % 3); 
  m1-=1; 
  c=(float)CosD(Theta); 
  s=(float)SinD(Theta); 
  M.Mat[m1][m1]=c; 
  M.Mat[m1][m2]=s; 
  M.Mat[m2][m2]=c; 
  M.Mat[m2][m1]=-s; 
} 
 
 
// ========================================================= 
//                     vector_ members 
// ========================================================= 
 
void vector::LinearComb (vector& v1, vector& v2, float u) 
{ 
    static float uu; 
    uu=(float)1.0-u; 
    x = uu * v1.x + u * v2.x; 
    y = uu * v1.y + u * v2.y; 
    z = uu * v1.z + u * v2.z; 
} 
 
int vector::Normalize(void) 
{ 
     float a=(float)sqrt(x*x+y*y+z*z); 
     if (a==0) 
        return 0; 
     x/=a; y/=a; z/=a; 
     return 1; 
} 
 
void vector::Cross(vector& V1,vector& V2) 
{ 
     x=V1.y*V2.z-V1.z*V2.y; 
     y=V1.z*V2.x-V1.x*V2.z; 
     z=V1.x*V2.y-V1.y*V2.x; 
} 
 
// ========================================================= 
//                     mat4x4_ members 
// ========================================================= 
 
void mat4x4::Null(void) 
{ 
   memset(&Mat,0,sizeof(Mat)); 
} 
 
void mat4x4::Inverse(mat4x4& M) 
{ 
    int a,b; 
    for( a=0;a<4;a++ ) 
     for( b=0;b<4;b++ ) 
          Mat[b][a]=M.Mat[a][b]; 
} 
 
void mat4x4::Rotate(float rx,float ry,float rz) 
{ 
     static mat4x4 M1,M2,M3; 
     PrepRotateMatrix(1,rx,M1); 
     PrepRotateMatrix(2,ry,M2); 
     M3=M1*M2; 
     PrepRotateMatrix(2,rz,M2); 
     M1=M3*M2; 
     *this=(*this)*M1; 
} 
 
void mat4x4::Scale(float sx,float sy,float sz) 
{ 
     static mat4x4 M; 
     memset(&M,0,sizeof(M)); 
     M.Mat[0][0]=sx; 
     M.Mat[1][1]=sy; 
     M.Mat[2][2]=sz; 
     M.Mat[3][3]=1.0; 
     *this=(*this)*M; 
} 
 
void mat4x4::Translate(float tx,float ty,float tz) 
{ 
     Mat[3][0]+=tx; 
     Mat[3][1]+=ty; 
     Mat[3][2]+=tz; 
} 
 
void mat4x4::LoadIdentity(void) 
{ 
     memset(Mat,0,sizeof(Mat)); 
     Mat[0][0]=Mat[1][1]=Mat[2][2]=Mat[3][3]=1.0; 
} 
 
void mat4x4::SetCamera(vector& Vp,vector& Lp,float Twist,float d) 
{ 
     vector N,U,T,Up; 
     mat4x4 M1,M2,M3; 
 
     N=Lp-Vp; 
     N.Normalize(); 
 
     if (N.z>1.0-SMALL || N.z<-1.0+SMALL) 
        Up.Vec(0,1,0); 
     else Up.Vec(0,0,1); 
 
     memset(&M1.Mat[0][0],0,sizeof(M1.Mat)); 
     M1.Mat[3][3]=1.0; 
     M1.Mat[0][2]=N.x; 
     M1.Mat[1][2]=N.y; 
     M1.Mat[2][2]=N.z; 
 
     U=Up-VecDot(N,Up)*N; 
     U.Normalize(); 
     M1.Mat[0][1]=-U.x; 
     M1.Mat[1][1]=-U.y; 
     M1.Mat[2][1]=-U.z; 
 
     T.Cross(N,U); 
     M1.Mat[0][0]=T.x; 
     M1.Mat[1][0]=T.y; 
     M1.Mat[2][0]=T.z; 
 
     M2.LoadIdentity(); 
     M2.Mat[3][0]=-Vp.x; 
     M2.Mat[3][1]=-Vp.y; 
     M2.Mat[3][2]=-Vp.z; 
 
     M3=M2*M1; 
 
     memset(&M2.Mat[0][0],0,sizeof(M2.Mat)); 
     M2.Mat[0][0]=(float)CosD(Twist); 
     M2.Mat[0][1]=(float)SinD(Twist); 
     M2.Mat[1][0]=-M2.Mat[0][1]; 
     M2.Mat[1][1]=M2.Mat[0][0]; 
     M2.Mat[2][2]=1.0;; 
     M2.Mat[3][3]=1.0;; 
 
     M1=M3*M2; 
 
     M2.LoadIdentity(); 
     M2.Mat[2][3]=(float)1.0/d; 
 
     *this=M1*M2; 
} 
 
 
void camera::align_z(vector& z) 
{ 
	if (fabs(z.z)>=0.99f) 
		{ 
		Y.x=-z.y*z.x; 
		Y.y=1-z.y*z.y; 
		Y.z=-z.y*z.z; 
 
		Y.Normalize(); 
		X.Cross(Y,z); 
		} 
	else  
		{ 
		Y.x=-z.z*z.x; 
		Y.y=-z.z*z.y; 
		Y.z=1-z.z*z.z; 
 
		Y.Normalize(); 
		X.Cross(Y,z); 
		} 
 
	Z=z; 
 
	update_mat(); 
} 
 
void camera::update_mat() 
{ 
	memset(&mat,0,sizeof(mat)); 
 
	mat.Mat[0][0]=X.x; 
	mat.Mat[0][1]=X.y; 
	mat.Mat[0][2]=X.z; 
 
	mat.Mat[1][0]=Y.x; 
	mat.Mat[1][1]=Y.y; 
	mat.Mat[1][2]=Y.z; 
 
	mat.Mat[2][0]=Z.x; 
	mat.Mat[2][1]=Z.y; 
	mat.Mat[2][2]=Z.z; 
	 
	mat.Mat[3][3]=1; 
 
	int i,j; 
	for( i=0;i<4;i++ ) 
		for( j=0;j<4;j++ ) 
			mat_t.Mat[i][j]=mat.Mat[j][i]; 
 
} 
 
// ========================================================= 
//                     camera members 
// ========================================================= 
 
void camera::CalcSystemVectors(void) 
{ 
     vector U,N,T; 
 
     N=Lp-Vp; 
     N.Normalize(); 
	 Z=N; 
	 Z.Negate(); 
 
     U=Up-VecDot(N,Up)*N; 
     U.Normalize(); 
	 Y=U; 
 
     T.Cross(N,U); 
	 X=T; 
 
	 update_mat(); 
} 
 
void camera::rotate(vector& rot) 
{ 
	static mat4x4 m; 
 
	glPushMatrix(); 
	glLoadIdentity(); 
 
	glRotatef(rot.x, X.x, X.y, X.z); 
	glRotatef(rot.y, Y.x, Y.y, Y.z); 
	glRotatef(rot.z, Z.x, Z.y, Z.z); 
 
	glGetFloatv(GL_MODELVIEW_MATRIX,(float *)&m); 
	glPopMatrix(); 
 
	X=X*m; 
	Y=Y*m; 
	Z=Z*m; 
	Lp=Lp-Vp; 
	Lp=Lp*m; 
	Lp+=Vp; 
	Up=Up*m; 
 
	update_mat(); 
} 
 
int operator>=(vector& v1,vector &v2) 
{ 
	if (v1.x>=v2.x && v1.y>=v2.y && v1.z>=v2.z) 
		return 1; 
	return 0; 
} 
 
int operator<=(vector& v1,vector &v2) 
{ 
	if (v1.x<=v2.x && v1.y<=v2.y && v1.z<=v2.z) 
		return 1; 
	return 0; 
} 
 
int operator==(vector& v1,vector& v2) 
{ 
	if(fabs(v1.x-v2.x)>0.001) 
		return 0; 
 
	if(fabs(v1.y-v2.y)>0.001) 
		return 0; 
	 
	if(fabs(v1.z-v2.z)>0.001) 
		return 0; 
 
	return 1; 
} 
 
void operator+=(vector& v1,vector& v2) 
{ 
  v1.x+=v2.x; v1.y+=v2.y; v1.z+=v2.z; 
} 
 
void operator-=(vector& v1,vector& v2) 
{ 
  v1.x-=v2.x; v1.y-=v2.y; v1.z-=v2.z; 
} 
 
void operator*=(vector& v1,vector& v2) 
{ 
  v1.x*=v2.x; v1.y*=v2.y; v1.z*=v2.z; 
} 
 
void operator/=(vector& v1,vector& v2) 
{ 
  v1.x/=v2.x; v1.y/=v2.y; v1.z/=v2.z; 
} 
 
void operator*=(vector& v,float f) 
{ 
  v.x*=f; v.y*=f; v.z*=f; 
} 
 
void operator/=(vector& v,float f) 
{ 
  v.x/=f; v.y/=f; v.z/=f; 
} 
 
vector operator-(vector v1,vector& v2) 
{ 
   v1.x-=v2.x; v1.y-=v2.y; v1.z-=v2.z; 
   return v1; 
} 
 
vector operator+(vector v1,vector& v2) 
{ 
   v1.x+=v2.x; v1.y+=v2.y; v1.z+=v2.z; 
   return v1; 
} 
 
vector operator*(vector v1,vector& v2) 
{ 
   v1.x*=v2.x; v1.y*=v2.y; v1.z*=v2.z; 
   return v1; 
} 
 
vector operator/(vector v1,vector& v2) 
{ 
   v1.x/=v2.x; v1.y/=v2.y; v1.z/=v2.z; 
   return v1; 
} 
 
vector operator*(float f,vector v) 
{ 
   v.x*=f; v.y*=f; v.z*=f; 
   return v; 
} 
 
vector operator*(vector v,float f) 
{ 
   v.x*=f; v.y*=f; v.z*=f; 
   return v; 
} 
 
vector operator/(float f,vector v) 
{ 
   v.x/=f; v.y/=f; v.z/=f; 
   return v; 
} 
 
vector operator/(vector v,float f) 
{ 
   v.x/=f; v.y/=f; v.z/=f; 
   return v; 
} 
 
vector operator*(vector& V,mat4x4& M) 
{ 
  vector a; 
  float *f=&a.x; 
  for(int j=0; j<3; j++,f++ ) 
  { 
    *f=0; 
    for(int i=0; i<3; i++) 
      *f+=*(&V.x+i)*M.Mat[i][j]; 
    *f+=M.Mat[i][j]; 
  } 
  return a; 
} 
 
vector operator*(mat4x4& M,vector& V) 
{ 
  vector a; 
  float *f=&a.x; 
  for(int j=0; j<3; j++,f++ ) 
  { 
    *f=0; 
    for(int i=0; i<3; i++) 
      *f+=*(&V.x+i)*M.Mat[i][j]; 
    *f+=M.Mat[i][j]; 
  } 
  return a; 
} 
 
// ========================================================= 
//                     mat4x4 operators 
// ========================================================= 
 
mat4x4 mat4x4::operator*(mat4x4& M) 
{ 
  int i,j,k; 
  float ab; 
  mat4x4 I; 
 
  for(i=0; i<4; i++) 
    for(j=0; j<4; j++) 
    { 
      ab=0; 
      for(k=0; k<4; k++) 
           ab+=Mat[i][k]*M.Mat[k][j]; 
      I.Mat[i][j]=ab; 
    } 
  return I; 
}