From c068f22329d5cc722622a2183bbb22eef2093df7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 24 Aug 2026 11:16:07 +0200 Subject: initial import --- src/libparsec/include/utl_math.h | 438 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 438 insertions(+) create mode 100644 src/libparsec/include/utl_math.h (limited to 'src/libparsec/include/utl_math.h') diff --git a/src/libparsec/include/utl_math.h b/src/libparsec/include/utl_math.h new file mode 100644 index 0000000..9fb5f93 --- /dev/null +++ b/src/libparsec/include/utl_math.h @@ -0,0 +1,438 @@ +/* + * PARSEC HEADER: x_math.h + */ + +#ifndef _X_MATH_H_ +#define _X_MATH_H_ + + +// ---------------------------------------------------------------------------- +// MATHEMATICS SUBSYSTEM - +// ---------------------------------------------------------------------------- + + +// thou shalt choose wise +#define USE_DOTPRODUCT_MACRO + + + +// matrix that can be used as destination (MAT2) +extern pXmatrx DestXmatrx; + +// interpolation info for remote player --------------------------------------- +// +struct playerlerp_s { + + fixed_t curspeed; + bams_t curyaw; + bams_t curpitch; + bams_t curroll; + geomv_t curslidehorz; + geomv_t curslidevert; + + Xmatrx dstposition; + geomv_t transvec_x; // delta vec during + geomv_t transvec_y; // transition + geomv_t transvec_z; + int transition; // time countdown + + Quaternion srcquat; // start of slerp + Quaternion dstquat; // end of slerp + float curalpha; // current slerp alpha + float incalpha; // delta for slerp alpha +}; + +// hermite arclen interpolation data ------------------------------------------ +// +struct Hermite_ArcLen +{ + int num_steps; + float* table_u; + float* table_s; + Vector3* table_Vecs; + float total_arc_len; +}; + +// external functions (MATH) + +void AdjointMtx( const Xmatrx smatrx, Xmatrx dmatrx ); + +void MtxMtxMUL( const Xmatrx matrxb, const Xmatrx matrxa, Xmatrx dmatrx ); +void MtxMtxMULt( const Xmatrx matrxb, const Xmatrx matrxa, Xmatrx dmatrx ); +void MtxVctMUL( const Xmatrx matrx, const Vector3 *svect, Vector3 *dvect ); +void MtxVctMULt( const Xmatrx matrx, const Vector3 *svect, Vector3 *dvect ); +void DirVctMUL( const Xmatrx matrx, geomv_t scalar, Vector3 *dvect ); +void RightVctMUL( const Xmatrx matrx, geomv_t scalar, Vector3 *dvect ); +void UpVctMUL( const Xmatrx matrx, geomv_t scalar, Vector3 *dvect ); +void VctReflect( const Vector3 *ivec, const Vector3 *normal, Vector3 *destvec ); +void CalcMovement( Vector3* move_offset, const Xmatrx frame, fixed_t forward, geomv_t horiz, geomv_t vert, refframe_t refframes ); + +void GetSinCos( dword angle, sincosval_s *resultp ); + +void ObjRotX( Xmatrx matrix, bams_t pitch ); +void ObjRotY( Xmatrx matrix, bams_t yaw ); +void ObjRotZ( Xmatrx matrix, bams_t roll ); +void CamRotX( Xmatrx matrix, bams_t pitch ); +void CamRotY( Xmatrx matrix, bams_t yaw ); +void CamRotZ( Xmatrx matrix, bams_t roll ); + +geomv_t DotProduct( const Vector3 *vect1, const Vector3 *vect2 ); +void CrossProduct( const Vector3 *vect1, const Vector3 *vect2, Vector3 *cproduct ); +void CrossProduct2( const geomv_t *vect1, const geomv_t *vect2, geomv_t *cproduct ); + +void ReOrthoMtx( Xmatrx matrix ); + +void ProcessObject( GenObject *object ); + + +// external functions (MAT2) + +geomv_t VctLen( Vector3 *vec ); +geomv_t VctLenX( Vector3 *vec ); +void NormVct( Vector3 *vec ); +void NormVctX( Vector3 *vec ); +void NormMtx( Xmatrx matrix ); +void ReOrthoNormMtx( Xmatrx matrix ); +void MakeIdMatrx( Xmatrx matrx ); +void MakeNonTranslationMatrx( const Xmatrx matrx, Xmatrx dmatrx ); +void CalcOrthoInverse( const Xmatrx matrx, Xmatrx dmatrx ); +void CalcObjSpaceCamera( const GenObject *objectp, Vector3 *cameravec ); +void TransformVolume( const Xmatrx matrx, Plane3 *vol_in, Plane3 *vol_out, dword cullmask ); +void BackTransformVolume( const Xmatrx matrx, Plane3 *vol_in, Plane3 *vol_out, dword cullmask ); + +int QuaternionIsUnit( const Quaternion *quat ); +int QuaternionIsUnit_f( const Quaternion_f *quat ); +void QuaternionMakeUnit( Quaternion *quat ); +void QuaternionMakeUnit_f( Quaternion_f *quat ); +void QuaternionInvertUnit( Quaternion *quat ); +void QuaternionInvertUnit_f( Quaternion_f *quat ); +void QuaternionInvertGeneral( Quaternion *quat ); +void QuaternionInvertGeneral_f( Quaternion_f *quat ); +void QuaternionFromMatrx( Quaternion *quat, const Xmatrx matrix ); +void QuaternionFromMatrx_f( Quaternion_f *quat, const Xmatrx matrix ); +void MatrxFromQuaternion( Xmatrx matrix, const Quaternion *quat ); +void MatrxFromQuaternion_f( Xmatrx matrix, const Quaternion_f *quat ); +void MatrxFromAngularDisplacement( Xmatrx matrix, bams_t angle, Vertex3 *axis ); +void QuaternionMUL( Quaternion *qd, const Quaternion *qb, const Quaternion *qa ); +void QuaternionMUL_f( Quaternion_f *qd, const Quaternion_f *qb, const Quaternion_f *qa ); +void QuaternionSlerp( Quaternion *qd, const Quaternion *qa, const Quaternion *qb, float alpha ); +void QuaternionSlerp_f( Quaternion_f *qd, const Quaternion_f *qa, const Quaternion_f *qb, float alpha ); +void QuaternionSlerpFrames( Xmatrx slerp_frame, Xmatrx start_frame, Xmatrx end_frame, float t ); +void CalcSlerpedMatrix( Xmatrx matrix, const playerlerp_s *playerlerp ); + +void Hermite_Interpolate( Vector3* dest, float t, const Vector3* start, const Vector3* end, const Vector3* start_tan, const Vector3* end_tan ); +Hermite_ArcLen* Hermite_ArcLen_InitData( int num_steps, const Vector3* start, const Vector3* end, const Vector3* start_tan, const Vector3* end_tan ); +void Hermite_ArcLen_KillData( Hermite_ArcLen* hermite_data ); +void Hermite_ArcLen_Interpolate( const Hermite_ArcLen* hermite_data, float s, Vector3* interp ); + +void DumpMatrix( Xmatrx mat ); + + +// geometric value MUL instruction -------------------------------------------- +// +#define GEOMV_MUL(a,b) ((a)*(b)) + + +// geometric value DIV instruction -------------------------------------------- +// +#define GEOMV_DIV(a,b) ((a)/(b)) + + +// dot product macro/function encapsulation ----------------------------------- +// +#ifdef USE_DOTPRODUCT_MACRO + #define DOT_PRODUCT(u,v) \ + (GEOMV_MUL((u)->X,(v)->X)+GEOMV_MUL((u)->Y,(v)->Y)+GEOMV_MUL((u)->Z,(v)->Z)) +#else + #define DOT_PRODUCT(u,v) DotProduct((u),(v)) +#endif + + +// make vector identity (NULL vector) ----------------------------------------- +// +inline +void MakeIdVector( Vector3& vec ) +{ + vec.X = vec.Y = vec.Z = GEOMV_0; +} + + +// fetch x vector of matrix --------------------------------------------------- +// +inline +void FetchXVector( const Xmatrx matrx, Vector3 *vec ) +{ + ASSERT( matrx != NULL ); + ASSERT( vec != NULL ); + + vec->X = matrx[ 0 ][ 0 ]; + vec->Y = matrx[ 1 ][ 0 ]; + vec->Z = matrx[ 2 ][ 0 ]; +} + + +// fetch y vector of matrix --------------------------------------------------- +// +inline +void FetchYVector( const Xmatrx matrx, Vector3 *vec ) +{ + ASSERT( matrx != NULL ); + ASSERT( vec != NULL ); + + vec->X = matrx[ 0 ][ 1 ]; + vec->Y = matrx[ 1 ][ 1 ]; + vec->Z = matrx[ 2 ][ 1 ]; +} + + +// fetch z vector of matrix --------------------------------------------------- +// +inline +void FetchZVector( const Xmatrx matrx, Vector3 *vec ) +{ + ASSERT( matrx != NULL ); + ASSERT( vec != NULL ); + + vec->X = matrx[ 0 ][ 2 ]; + vec->Y = matrx[ 1 ][ 2 ]; + vec->Z = matrx[ 2 ][ 2 ]; +} + + +// fetch t vector of matrix (translation part) -------------------------------- +// +inline +void FetchTVector( const Xmatrx matrx, Vector3 *vec ) +{ + ASSERT( matrx != NULL ); + ASSERT( vec != NULL ); + + vec->X = matrx[ 0 ][ 3 ]; + vec->Y = matrx[ 1 ][ 3 ]; + vec->Z = matrx[ 2 ][ 3 ]; +} + + +// store x vector of matrix --------------------------------------------------- +// +inline +void StoreXVector( Xmatrx matrx, const Vector3 *vec ) +{ + ASSERT( matrx != NULL ); + ASSERT( vec != NULL ); + + matrx[ 0 ][ 0 ] = vec->X; + matrx[ 1 ][ 0 ] = vec->Y; + matrx[ 2 ][ 0 ] = vec->Z; +} + + +// store y vector of matrix --------------------------------------------------- +// +inline +void StoreYVector( Xmatrx matrx, const Vector3 *vec ) +{ + ASSERT( matrx != NULL ); + ASSERT( vec != NULL ); + + matrx[ 0 ][ 1 ] = vec->X; + matrx[ 1 ][ 1 ] = vec->Y; + matrx[ 2 ][ 1 ] = vec->Z; +} + + +// store z vector of matrix --------------------------------------------------- +// +inline +void StoreZVector( Xmatrx matrx, const Vector3 *vec ) +{ + ASSERT( matrx != NULL ); + ASSERT( vec != NULL ); + + matrx[ 0 ][ 2 ] = vec->X; + matrx[ 1 ][ 2 ] = vec->Y; + matrx[ 2 ][ 2 ] = vec->Z; +} + + +// store t vector of matrix (translation part) -------------------------------- +// +inline +void StoreTVector( Xmatrx matrx, const Vector3 *vec ) +{ + ASSERT( matrx != NULL ); + ASSERT( vec != NULL ); + + matrx[ 0 ][ 3 ] = vec->X; + matrx[ 1 ][ 3 ] = vec->Y; + matrx[ 2 ][ 3 ] = vec->Z; +} + + +// primitive vector arithmetics ----------------------------------------------- +// +#define VECADD(c,a,b) { \ + (c)->X = (a)->X+(b)->X; \ + (c)->Y = (a)->Y+(b)->Y; \ + (c)->Z = (a)->Z+(b)->Z; \ +} + +#define VECADD_UVW(c,a,b) { \ + (c)->X = (a)->X+(b)->X; \ + (c)->Y = (a)->Y+(b)->Y; \ + (c)->Z = (a)->Z+(b)->Z; \ + (c)->W = (a)->W+(b)->W; \ + (c)->U = (a)->U+(b)->U; \ + (c)->V = (a)->V+(b)->V; \ +} + +#define VECADD_RGBA(c,a,b) { \ + (c)->X = (a)->X+(b)->X; \ + (c)->Y = (a)->Y+(b)->Y; \ + (c)->Z = (a)->Z+(b)->Z; \ + (c)->R = (a)->R+(b)->R; \ + (c)->G = (a)->G+(b)->G; \ + (c)->B = (a)->B+(b)->B; \ + (c)->A = (a)->A+(b)->A; \ +} + +#define VECADD_UVW_RGBA(c,a,b) { \ + (c)->X = (a)->X+(b)->X; \ + (c)->Y = (a)->Y+(b)->Y; \ + (c)->Z = (a)->Z+(b)->Z; \ + (c)->W = (a)->W+(b)->W; \ + (c)->U = (a)->U+(b)->U; \ + (c)->V = (a)->V+(b)->V; \ + (c)->R = (a)->R+(b)->R; \ + (c)->G = (a)->G+(b)->G; \ + (c)->B = (a)->B+(b)->B; \ + (c)->A = (a)->A+(b)->A; \ +} + +#define VECSUB(c,a,b) { \ + (c)->X = (a)->X-(b)->X; \ + (c)->Y = (a)->Y-(b)->Y; \ + (c)->Z = (a)->Z-(b)->Z; \ +} + +#define VECSUB_UVW(c,a,b) { \ + (c)->X = (a)->X-(b)->X; \ + (c)->Y = (a)->Y-(b)->Y; \ + (c)->Z = (a)->Z-(b)->Z; \ + (c)->W = (a)->W-(b)->W; \ + (c)->U = (a)->U-(b)->U; \ + (c)->V = (a)->V-(b)->V; \ +} + +#define VECSUB_RGBA(c,a,b) { \ + (c)->X = (a)->X-(b)->X; \ + (c)->Y = (a)->Y-(b)->Y; \ + (c)->Z = (a)->Z-(b)->Z; \ + (c)->R = (a)->R-(b)->R; \ + (c)->G = (a)->G-(b)->G; \ + (c)->B = (a)->B-(b)->B; \ + (c)->A = (a)->A-(b)->A; \ +} + +#define VECSUB_UVW_RGBA(c,a,b) { \ + (c)->X = (a)->X-(b)->X; \ + (c)->Y = (a)->Y-(b)->Y; \ + (c)->Z = (a)->Z-(b)->Z; \ + (c)->W = (a)->W-(b)->W; \ + (c)->U = (a)->U-(b)->U; \ + (c)->V = (a)->V-(b)->V; \ + (c)->R = (a)->R-(b)->R; \ + (c)->G = (a)->G-(b)->G; \ + (c)->B = (a)->B-(b)->B; \ + (c)->A = (a)->A-(b)->A; \ +} + +// multiply vector with scalar ------------------------------------------------ +// +#define VECMULS(c,a,b) { \ + (c)->X = (b) * (a)->X; \ + (c)->Y = (b) * (a)->Y; \ + (c)->Z = (b) * (a)->Z; \ +} + + +// saxpy vector arithmetics --------------------------------------------------- +// + +// y = a*x+y (a is scalar) +#define SAXPY(a,x,y) { \ + (y)->X = GEOMV_MUL((a),(x)->X)+(y)->X; \ + (y)->Y = GEOMV_MUL((a),(x)->Y)+(y)->Y; \ + (y)->Z = GEOMV_MUL((a),(x)->Z)+(y)->Z; \ +} + +// c = a*x+y (a is scalar) +#define CSAXPY(c,a,x,y) { \ + (c)->X = GEOMV_MUL((a),(x)->X)+(y)->X; \ + (c)->Y = GEOMV_MUL((a),(x)->Y)+(y)->Y; \ + (c)->Z = GEOMV_MUL((a),(x)->Z)+(y)->Z; \ +} + +// c = a*x+y (a is scalar) +// also calculates [uvw] +#define CSAXPY_UVW(c,a,x,y) { \ + (c)->X = GEOMV_MUL((a),(x)->X)+(y)->X; \ + (c)->Y = GEOMV_MUL((a),(x)->Y)+(y)->Y; \ + (c)->Z = GEOMV_MUL((a),(x)->Z)+(y)->Z; \ + (c)->W = GEOMV_MUL((a),(x)->W)+(y)->W; \ + (c)->U = GEOMV_MUL((a),(x)->U)+(y)->U; \ + (c)->V = GEOMV_MUL((a),(x)->V)+(y)->V; \ +} + + +// accelerated dot product with plane normal (struct Plane3) ------------------ +// +#define PLANE_DOT(p,x) ( PLANE_AXIAL(p) ? \ + ( PLANE_AXISCOMP(p) * ((geomv_t*)x)[ PLANE_CMPAXIS(p) ] ) : \ + DOT_PRODUCT(PLANE_NORMAL(p),(x)) ) + + +// reject/accept point tests for a cull plane --------------------------------- +// +#define PLANEDIST_REJECTPOINT(p,b) ( \ + GEOMV_MUL( (b)->minmax[ (p)->reacx.reject[ 0 ] ], (p)->plane.X ) + \ + GEOMV_MUL( (b)->minmax[ (p)->reacx.reject[ 1 ] ], (p)->plane.Y ) + \ + GEOMV_MUL( (b)->minmax[ (p)->reacx.reject[ 2 ] ], (p)->plane.Z ) - \ + (p)->plane.D ) + +#define PLANEDIST_ACCEPTPOINT(p,b) ( \ + GEOMV_MUL( (b)->minmax[ (p)->reacx.accept[ 0 ] ], (p)->plane.X ) + \ + GEOMV_MUL( (b)->minmax[ (p)->reacx.accept[ 1 ] ], (p)->plane.Y ) + \ + GEOMV_MUL( (b)->minmax[ (p)->reacx.accept[ 2 ] ], (p)->plane.Z ) - \ + (p)->plane.D ) + + +// project 3-D vertex onto screen --------------------------------------------- +// +#define PROJECT_TO_SCREEN(v,s) { \ + (s).X = GEOMV_TO_COORD( GEOMV_DIV( (v).X, (v).Z ) ) + Screen_XOfs; \ + (s).Y = GEOMV_TO_COORD( GEOMV_DIV( (v).Y, (v).Z ) ) + Screen_YOfs; \ +} + + +// elementary transformations into screen space ------------------------------- +// +#define SCREENSPACE_XOZ(v,z) ( GEOMV_TO_COORD( GEOMV_MUL( (v).X, (z) ) ) + Screen_XOfs ) +#define SCREENSPACE_YOZ(v,z) ( GEOMV_TO_COORD( GEOMV_MUL( (v).Y, (z) ) ) + Screen_YOfs ) +#define SCREENSPACE_OOZ(v) ( GEOMV_DIV( GEOMV_1, (v).Z ) ) + + +// depth value calculation ---------------------------------------------------- +// +#ifdef FRACTIONAL_DEPTH_VALUES + #define DEPTHBUFF_VALUE(z) ( (depth_t) (z) ) + #define DEPTHBUFF_OOZ(z) ( (depth_t) GEOMV_DIV( GEOMV_1, (z) ) ) +#else + #define DEPTHBUFF_VALUE(z) ( (word)GEOMV_TO_FIXED(z) ) + #define DEPTHBUFF_OOZ(z) ( (word)GEOMV_TO_FIXED( GEOMV_DIV(GEOMV_1,(z)) ) ) +#endif + + +#endif // _X_MATH_H_ + + -- cgit v1.2.3