home *** CD-ROM | disk | FTP | other *** search
- /////////////////////////////////////////////////////////////////////////////
- // //
- // This structs are used for the matrix maths related with the affine //
- // transformations of objects & camera. In 3d_math you will find the //
- // functions related to inversion & combination of affine transformations //
- // //
- /////////////////////////////////////////////////////////////////////////////
-
- #include <math.h>
-
- float pi=3.141592654;
-
- typedef struct matrix
- {
- float m11,m21,m31,m12,m22,m32,m13,m23,m33;
- }MATRIX;
-
- typedef struct vector
- {
- float v1,v2,v3;
- }VECTOR;
-
- typedef struct vector2d
- {
- float v1,v2;
- }VECTOR2D;
-
- typedef struct affin
- {
- MATRIX aff_mtx;
- VECTOR aff_vtr;
- }AFFIN;
-
- typedef struct implicit_plane
- {
- VECTOR normal;
- float d;
- }IMPLICIT_PLANE;
-
- /////////////////////////////////////////////////////////////////////////////
- // //
- // Various functions used for the matrix maths related with the affine //
- // transformations of objects & camera. In 3d_strc you will find the //
- // prototypes for the matrix, vector & aff_trns structures. //
- // //
- /////////////////////////////////////////////////////////////////////////////
-
- /////////////////////////////////////////////////////////////////////////////
- // This function gets the Determinant of an 3x3 matrix, as is defined in //
- // 3d_strc. It returns a float. //
- /////////////////////////////////////////////////////////////////////////////
-
- float det_mtx(MATRIX source)
- {
- float res;
- res=(source.m11*(source.m22*source.m33-source.m23*source.m32)+
- source.m12*(source.m23*source.m31-source.m21*source.m33)+
- source.m13*(source.m21*source.m32-source.m22*source.m31));
- return(res);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // This function gets the Inverse of an 3x3 matrix. The result is another //
- // 3x3 matrix. This routine may fail if Det(source) is equal to 0, but //
- // this is impossible working with standard 3D rotation matrixes //
- /////////////////////////////////////////////////////////////////////////////
-
- MATRIX inv_mtx(MATRIX source)
- {
- MATRIX res;
- float det;
- det=1/det_mtx(source);
- res.m11=det*(source.m22*source.m33-source.m23*source.m32);
- res.m12=det*(source.m13*source.m32-source.m12*source.m33);
- res.m13=det*(source.m12*source.m23-source.m13*source.m22);
-
- res.m21=det*(source.m23*source.m31-source.m21*source.m33);
- res.m22=det*(source.m11*source.m33-source.m13*source.m31);
- res.m23=det*(source.m13*source.m21-source.m11*source.m23);
-
- res.m31=det*(source.m21*source.m32-source.m22*source.m31);
- res.m32=det*(source.m12*source.m31-source.m11*source.m32);
- res.m33=det*(source.m11*source.m22-source.m12*source.m21);
- return(res);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // This function gets Composition of two 3x3 matrix. The result is another //
- // 3x3 matrix. Warning: matrix composition is not commutative!!! //
- /////////////////////////////////////////////////////////////////////////////
-
- MATRIX mtx_mul_mtx(MATRIX a, MATRIX b)
- {
- MATRIX res;
- res.m11=a.m11*b.m11+a.m21*b.m12+a.m31*b.m13;
- res.m21=a.m11*b.m21+a.m21*b.m22+a.m31*b.m23;
- res.m31=a.m11*b.m31+a.m21*b.m32+a.m31*b.m33;
-
- res.m12=a.m12*b.m11+a.m22*b.m12+a.m32*b.m13;
- res.m22=a.m12*b.m21+a.m22*b.m22+a.m32*b.m23;
- res.m32=a.m12*b.m31+a.m22*b.m32+a.m32*b.m33;
-
- res.m13=a.m13*b.m11+a.m23*b.m12+a.m33*b.m13;
- res.m23=a.m13*b.m21+a.m23*b.m22+a.m33*b.m23;
- res.m33=a.m13*b.m31+a.m23*b.m32+a.m33*b.m33;
- return(res);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // This function gets Composition of an 3x3 matrix with a vector. Returns //
- // another vector. It's impossible to make the composition between one //
- // vector and one matrix. //
- /////////////////////////////////////////////////////////////////////////////
-
- VECTOR mtx_mul_vtr(MATRIX a, VECTOR b)
- {
- VECTOR res;
- res.v1=a.m11*b.v1+a.m21*b.v2+a.m31*b.v3;
- res.v2=a.m12*b.v1+a.m22*b.v2+a.m32*b.v3;
- res.v3=a.m13*b.v1+a.m23*b.v2+a.m33*b.v3;
- return(res);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // This function simply changes the sign of a vector. //
- /////////////////////////////////////////////////////////////////////////////
-
- VECTOR neg_vtr(VECTOR source)
- {
- VECTOR res;
- res.v1=-source.v1;
- res.v2=-source.v2;
- res.v3=-source.v3;
- return(res);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // This function just add 2 vectors. //
- /////////////////////////////////////////////////////////////////////////////
-
- VECTOR vtr_add_vtr(VECTOR a, VECTOR b)
- {
- VECTOR res;
- res.v1=a.v1+b.v1;
- res.v2=a.v2+b.v2;
- res.v3=a.v3+b.v3;
- return(res);
- }
-
- VECTOR vtr_sub_vtr(VECTOR a, VECTOR b)
- {
- VECTOR res;
- res.v1=a.v1-b.v1;
- res.v2=a.v2-b.v2;
- res.v3=a.v3-b.v3;
- return(res);
- }
-
- VECTOR mul_vtr(float a, VECTOR b)
- {
- VECTOR res;
- res.v1=a*b.v1;
- res.v2=a*b.v2;
- res.v3=a*b.v3;
- return(res);
- }
-
-
- VECTOR vtr_cross_mul_vtr(VECTOR a, VECTOR b)
- {
- VECTOR res;
- res.v1=a.v2*b.v3-a.v3*b.v2;
- res.v2=a.v3*b.v1-a.v1*b.v3;
- res.v3=a.v1*b.v2-a.v2*b.v1;
- return(res);
- }
-
- VECTOR vtr_dir_mul_vtr(VECTOR a, VECTOR b)
- {
- VECTOR res;
- res.v1=a.v1*b.v1;
- res.v2=a.v2*b.v2;
- res.v3=a.v3*b.v3;
- return(res);
- }
-
- float vtr_dot_mul_vtr(VECTOR a, VECTOR b)
- {
- float res;
- res=a.v1*b.v1+a.v2*b.v2+a.v3*b.v3;
- return(res);
- }
-
- float vtr_mix_mul(VECTOR a, VECTOR b, VECTOR c)
- {
- return(vtr_dot_mul_vtr(a,vtr_cross_mul_vtr(b,c)));
- }
-
- float mod_vtr(VECTOR a)
- {
- return(sqrt(a.v1*a.v1+a.v2*a.v2+a.v3*a.v3));
- }
-
- float mod_vtr2(VECTOR a)
- {
- return(a.v1*a.v1+a.v2*a.v2+a.v3*a.v3);
- }
-
- VECTOR unit_vtr(VECTOR a)
- {
- float res;
- res=mod_vtr(a);
- if (res!=0)
- {
- res=1/res;
- a.v1*=res;
- a.v2*=res;
- a.v3*=res;
- }
- else
- {
- a.v1=0;
- a.v2=0;
- a.v3=1;
- }
- return (a);
- }
-
- VECTOR divide_vtr(VECTOR a,float b)
- {
- float res;
- if (b!=0)
- {
- res=1/b;
- a.v1*=res;
- a.v2*=res;
- a.v3*=res;
- }
- else
- {
- a.v1=0;
- a.v2=0;
- a.v3=1;
- }
- return (a);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // This function gets the Inverse of an affine transformation. The result //
- // It returns another affine transformation. //
- /////////////////////////////////////////////////////////////////////////////
-
-
-
- AFFIN inv_aff(AFFIN source)
- {
- AFFIN res;
- res.aff_mtx=inv_mtx(source.aff_mtx);
- res.aff_vtr=mtx_mul_vtr(res.aff_mtx,neg_vtr(source.aff_vtr));
- return(res);
- }
-
- MATRIX i_mtx(MATRIX source)
- {
- MATRIX res;
- res.m11=source.m22*source.m33-source.m23*source.m32;
- res.m12=source.m13*source.m32-source.m12*source.m33;
- res.m13=source.m12*source.m23-source.m13*source.m22;
-
- res.m21=source.m23*source.m31-source.m21*source.m33;
- res.m22=source.m11*source.m33-source.m13*source.m31;
- res.m23=source.m13*source.m21-source.m11*source.m23;
-
- res.m31=source.m21*source.m32-source.m22*source.m31;
- res.m32=source.m12*source.m31-source.m11*source.m32;
- res.m33=source.m11*source.m22-source.m12*source.m21;
- return(res);
- }
-
-
- AFFIN i_aff(AFFIN source)
- {
- AFFIN res;
- res.aff_mtx=i_mtx(source.aff_mtx);
- res.aff_vtr=mtx_mul_vtr(res.aff_mtx,neg_vtr(source.aff_vtr));
- return(res);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // This is the affine transformation compositon function. It's RES=(A(B)) //
- /////////////////////////////////////////////////////////////////////////////
-
- AFFIN aff_mul_aff(AFFIN a, AFFIN b)
- {
- AFFIN res;
- res.aff_mtx=mtx_mul_mtx(a.aff_mtx,b.aff_mtx);
- res.aff_vtr=vtr_add_vtr(mtx_mul_vtr(a.aff_mtx,b.aff_vtr),a.aff_vtr);
- return(res);
- }
-
- AFFIN AxA(AFFIN a, AFFIN b)
- {
- AFFIN res;
- res.aff_mtx=mtx_mul_mtx(a.aff_mtx,b.aff_mtx);
- res.aff_vtr=vtr_add_vtr(mtx_mul_vtr(a.aff_mtx,b.aff_vtr),a.aff_vtr);
-
- return(res);
- }
-
- VECTOR AxV(AFFIN a, VECTOR b)
- {
- VECTOR res;
- res=vtr_add_vtr(mtx_mul_vtr(a.aff_mtx,b),a.aff_vtr);
- return(res);
- }
-
- IMPLICIT_PLANE calc_plane(VECTOR a, VECTOR b, VECTOR c)
- {
- IMPLICIT_PLANE res;
- res.normal=unit_vtr(vtr_cross_mul_vtr(vtr_sub_vtr(b,a),vtr_sub_vtr(c,a)));
- res.d=-vtr_dot_mul_vtr(res.normal,c);
- return(res);
- }
-
- VECTOR calc_normal(VECTOR a, VECTOR b, VECTOR c)
- {
- VECTOR res;
- res=unit_vtr(vtr_cross_mul_vtr(vtr_sub_vtr(b,a),vtr_sub_vtr(c,a)));
- return(res);
- }
-
- float dist_to_plane(IMPLICIT_PLANE p, VECTOR v)
- {
- return (vtr_dot_mul_vtr(p.normal,v)+p.d);
- }
-