home *** CD-ROM | disk | FTP | other *** search
- #ifndef __XFORM_H
- #define __XFORM_H
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- /* if you want to use fixedpoint for your base type, uncomment what
- follows: */
-
- /*#define use_fixed*/
-
- /* if you want to use float for your base type, uncomment what follows: */
-
- #define use_float
-
-
- #ifdef use_fixed
-
- #include <math.h>
-
- #define REAL fixedpoint
-
- #define mul fixed_mul
- #define div fixed_div
- #define add(a,b) ((a)+(b))
- #define sub(a,b) ((a)-(b))
-
- #define floattoreal(x) ((x)*65536.0)
- #define realtofloat(x) ((x)/65536.0)
- #define radiantoreal(x) ((x)*(32768.0/M_PI))
- #define realtoradian(x) ((x)*(M_PI/32768.0))
- #define fixedtoreal(x) (x)
- #define realtofixed(x) (x)
-
- /* Normally, you should define "better" functions for better sqrt,
- sin and cos using fixed point. For example, orthonormalize
- should be optimized for close-to-normal vectors already using
- taylor approx. If you need +/- .0002 precision for square root
- of numbers between .9604 and 1.0404, you can use sqrt(x)=(1+x)/2 */
- #define SQRT(x) floattoreal(sqrt(realtofloat(x)))
- #define SIN(x) floattoreal(sin(realtoradian(x)))
- #define COS(x) floattoreal(cos(realtoradian(x)))
-
- #elif defined use_float
-
- #include <math.h>
-
- #define REAL float
-
- #define mul(a,b) ((a)*(b))
- #define div(a,b) ((a)/(b))
- #define add(a,b) ((a)+(b))
- #define sub(a,b) ((a)-(b))
-
- #define floattoreal(x) (x)
- #define realtofloat(x) (x)
- #define radiantoreal(x) ((x)*(.5/M_PI))
- #define realtoradian(x) ((x)*2*M_PI)
- #define fixedtoreal(x) ((x)/65536.0)
- #define realtofixed(x) ((x)*65536l)
-
- #define SQRT sqrt
- #define SIN(x) sin(realtoradian(x))
- #define COS(x) cos(realtoradian(x))
-
- #else
- #error use_fixed or use_float has to be defined in xforms.h
- #endif
-
-
-
- typedef long fixedpoint;
- /* if you want to use fixedpoint, you have to make sure the functions
- below (add, sub, mul, div) are implemented for your platform */
-
- fixedpoint fixed_mul(fixedpoint a, fixedpoint b);
- fixedpoint fixed_div(fixedpoint a, fixedpoint b);
- fixedpoint fixed_add(fixedpoint a, fixedpoint b);
- fixedpoint fixed_sub(fixedpoint a, fixedpoint b);
-
-
- typedef REAL vector[3];
- typedef vector matrix[3];
-
-
- /* For internal reasons, matrices are indexed as matrix[column][row]
- instead of the usual matrix[row][column], e.g. matrix is an array
- of three _column_ vectors (not rows) */
-
-
- struct affine_struct
- {
- matrix m;
- vector v;
- };
-
-
- typedef struct affine_struct affine;
-
- /* The affine type defines an affine transformation, that is, multiply
- by matrix m then translate by vector v. */
-
-
- void mat_add(matrix r, matrix a, matrix b);
- /* r=a+b */
- void mat_sub(matrix r, matrix a, matrix b);
- /* r=a-b */
- void mat_mul(matrix r, matrix a, matrix b);
- /* r=a*b NOTE: r must be different from a and b, though a and b
- can be the same */
-
- void mat_mul_vec(vector r, matrix a, vector b);
- /* r=a*b NOTE: b has to be different from r */
- void mat_mul_scl(matrix r, matrix a, REAL b);
- /* multiplies matrix a by scalar b and stores in r */
- void vec_mul_scl(vector r, vector a, REAL b);
- /* multiplies vector a by a scalar b and stores in r */
-
- void vec_add(vector r, vector a, vector b);
- /* r=a+b */
- void vec_sub(vector r, vector a, vector b);
- /* r=a-b */
-
-
- REAL vec_dot(vector a, vector b);
- /* return a dot b */
-
- void vec_crs(vector r, vector a, vector b);
- /* r=a cross b, r HAS to be different from a and b */
-
- void vec_normalize(vector a);
- /* normalizes vector a */
-
- void mat_orthonormalize(matrix a);
- /* orthonormalizes matrix a (e.g. line vectors will be of unit length
- and perpendicular) */
-
- void affine_xform(affine *a, vector i, vector j);
- /* transforms vector i into vector j through affine transform a */
-
-
- void initmatrix(matrix m,
- float a00, float a01, float a02,
- float a10, float a11, float a12,
- float a20, float a21, float a22);
- /* stores a00 through a22 in the matrix */
-
- void printmatrix(matrix m);
- /* dumps matrix on screen with printf */
-
- void initvector(vector v,
- float i, float j, float k);
-
- void printvector(vector v);
-
- void copymatrix(matrix dest, matrix src);
- void copyvector(vector dest, vector src);
-
-
- /* angles when parameter is REAL is from 0 to 1 for a complete circle */
- void rotatevectors(vector v1, vector v2,
- vector u1, vector u2,
- REAL theta);
- /* rotates vector v1 and v2 to u1 and u2, which could be references
- to the same memory location */
-
- void rotatebase(matrix m, int axis, REAL theta);
- /* rotates base in matrix m about the given axis by an angle of theta
- Note: you could also make a matrix A of rotation about anything you
- want and then use mat_mul(result,A,m) instead of rotatebase(...).
- This could save you a few muls and stuff.
- axis is either 1, 2 or 3 */
-
-
- REAL determinant(matrix m);
- /* returns the determinant of matrix m. used here mainly for finding
- the matrix inverse */
- int invert(matrix m, matrix r);
- /* inverses matrix m if possible and puts the result in r. returns
- 0 on success, nonzero on error (matrix has no inverse)
- Note that all rotation matrices have an inverse */
- int invert_affine(affine *a, affine *r);
- /* inverses affine transformation a into r, which can NOT point to the
- same object. Return value same as invert function */
- #ifdef __cplusplus
- }
- #endif
-
- #endif
-