#ifndef GEOMETRY_H #define GEOMETRY_H /* * 3-D geometry (matrix, vector, quaternion) functions for partiview. * * Stuart Levy, slevy@ncsa.uiuc.edu * National Center for Supercomputing Applications, * University of Illinois 2001. * This file is part of partiview, released under the * Illinois Open Source License; see the file LICENSE.partiview for details. */ #ifdef __cplusplus extern "C" { #endif #ifndef CONST # ifdef __cplusplus # define CONST const # else # define CONST # endif #endif #ifdef unix # include <alloca.h> #endif typedef struct { float x[3]; } Point; typedef struct { float q[4]; } Quat; /* {r,i,j,k} => {0,1,2,3} */ typedef struct { float m[4*4]; } Matrix; #define NewA(type, count) (type *)alloca((count) * sizeof(type)) #ifndef COUNT # define COUNT(array) (sizeof(array) / sizeof((array)[0])) #endif /* * Global Constants */ extern Matrix Tidentity; /* * Global variables */ void arena_init( int nbytes ); void vsub( Point *dst, CONST Point *a, CONST Point *b ); void vadd( Point *dst, CONST Point *a, CONST Point *b ); void vcross( Point *dst, CONST Point *a, CONST Point *b ); float vdot( CONST Point *a, CONST Point *b ); void vscale( Point *dst, float s, CONST Point *src ); void vsadd( Point *dst, CONST Point *a, float sb, CONST Point *b ); void vlerp( Point *dst, float frac, CONST Point *vfrom, CONST Point *vto ); void vcomb( Point *dst, float sa, CONST Point *a, float sb, CONST Point *b ); float vunit( Point *dst, CONST Point *src ); void vproj( Point *along, Point *perp, CONST Point *vec, CONST Point *onto ); float qdot( CONST Quat *q1, CONST Quat *q2 ); void qnorm( Quat *qdst, CONST Quat *qsrc ); void qcomb( Quat *qdst, float sa, CONST Quat *qa, float sb, CONST Quat *qb ); /* Distance between two 3-D points */ float vdist( CONST Point *p1, CONST Point *p2 ); /* Distance between two quaternions */ float iqdist( CONST Point *q1, CONST Point *q2 ); float qdist( CONST Quat *q1, CONST Quat *q2 ); /* Distance between two matrices */ float tdist( CONST Matrix *t1, CONST Matrix *t2 ); /* vector magnitude */ float vlength( CONST Point *v ); /* Transform a 3-D point by a matrix: dst = src*T. */ void vtfmpoint( Point *dst, CONST Point *src, CONST Matrix *T ); /* Transform a vector by a (Euclidean) matrix: dst = src*T */ void vtfmvector( Point *dst, CONST Point *src, CONST Matrix *T ); void vuntfmvector( Point *dst, CONST Point *src, CONST Matrix *T ); /* Get translation part of matrix */ void vgettranslation( Point *dst, CONST Matrix *T ); /* Set translation part of matrix, leave 3x3 submatrix alone */ void vsettranslation( Matrix *T, CONST Point *src ); void vrotxy( Point *dst, CONST Point *src, CONST float cs[2] ); void mcopy( Matrix *dst, CONST Matrix *src ); /* 4x4 matrix multiply */ void mmmul( Matrix *dst, CONST Matrix *a, CONST Matrix *b ); /* Matrix inverse for Euclidean similarities: matrices are * a product of pure translation/rotation/uniform-scaling -- */ void eucinv( Matrix *dst, CONST Matrix *src ); /* matrix conjugation: see its use in Gview.C */ void mconjugate( Matrix *To2wout, CONST Matrix *To2win, CONST Matrix *Tincrf, CONST Matrix *Tf2w, CONST Matrix *Tw2f, CONST Point *pcenw, CONST Point *pcenf ); void grotation( Matrix *Trot, CONST Point *fromaxis, CONST Point *toaxis ); /* matrix to 3-component quaternion (real-part is sqrt(1-iquat.iquat), * and real part (in range 0 .. +1) is also returned as func value. */ float tfm2iquat( Point *iquat, CONST Matrix *src ); /* returns real part */ void tfm2quat( Quat *quat, CONST Matrix *src ); void iquat2tfm( Matrix *dst, CONST Point *iquat ); void quat2tfm( Matrix *dst, CONST Quat *quat ); /* quaternion interpolation */ void iquat_lerp( Point *dquat, float frac, CONST Point *qfrom, CONST Point *qto ); void quat_lerp( Quat *dquat, float frac, CONST Quat *qfrom, CONST Quat *qto ); /* axis/angle rotation -> quaternion */ void rot2quat( Quat *quat, float degrees, CONST Point *axis ); void rot2iquat( Point *iquat, float degrees, CONST Point *axis ); /* construct matrix from axis/angle rotation */ void rot2tfm( Matrix *dst, float degrees, CONST Point *axis ); /* Construct a matrix that's a pure X/Y/Z rotation/scaling/translation */ void mrotation( Matrix *dst, float degrees, char xyzaxis ); void mscaling( Matrix *dst, float sx, float sy, float sz ); void mtranslation( Matrix *dst, float tx, float ty, float tz ); /* cam2world <-> az(Y) el(X) roll(Z) + translation */ float tfm2xyzaer( Point *xyz, float aer[3], CONST Matrix *c2w ); /* => scale */ void xyzaer2tfm( Matrix *c2w, CONST Point *xyz, CONST float aer[3] ); /* perspective frustum */ void mfrustum( Matrix *Tproj, float nl, float nr, float nd, float nu, float cnear, float cfar ); #ifdef __cplusplus } #endif #endif