123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651 |
- /*
- Copyright (C) 2005 Michael Liebscher <johnnycanuck@users.sourceforge.net>
- Copyright (C) 1997-2001 Id Software, Inc.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- /*
- * vector.h: 2D and 3D vector math routines.
- *
- * Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
- *
- * Acknowledgement:
- * Portion of this code was derived from Quake II, and was originally
- * written by Id Software, Inc.
- *
- */
- #include "../wolfiphone.h"
- vec3_t vec3_origin = { 0, 0, 0 };
- vec_t _VectorNormalize( vec3_t v );
- vec_t (*pfVectorNormalize)( vec3_t v ) = _VectorNormalize;
- /*
- -----------------------------------------------------------------------------
- Function: _VectorNormalize -Normalize a 3D vector.
- Parameters: v -[in] 3D vector to normalize.
- Returns: Unit vector value.
- Notes:
- For a given vector, the process of finding a unit vector which is
- parallel to it. This is done by dividing the given vector by its
- magnitude.
- -----------------------------------------------------------------------------
- */
- PUBLIC vec_t _VectorNormalize( vec3_t v )
- {
- float length, ilength;
- length = (float)pfSqrt( v[ 0 ] * v[ 0 ] + v[ 1 ] * v[ 1 ] + v[ 2 ] * v[ 2 ] );
- if( length )
- {
- ilength = 1 / length;
- v[ 0 ] *= ilength;
- v[ 1 ] *= ilength;
- v[ 2 ] *= ilength;
- }
-
- return length;
- }
- /*
- -----------------------------------------------------------------------------
- Function: ProjectPointOnPlane -Project a point onto a plane.
- Parameters: dst -[out] Destination Point on Plane.
- p -[in] Point to project onto the plane.
- normal -[in] A vector to specify the orientation of the plane.
- Returns: Nothing.
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal )
- {
- float d;
- vec3_t n;
- float inv_denom;
- inv_denom = 1.0f / DotProduct( normal, normal );
- d = DotProduct( normal, p ) * inv_denom;
- n[ 0 ] = normal[ 0 ] * inv_denom;
- n[ 1 ] = normal[ 1 ] * inv_denom;
- n[ 2 ] = normal[ 2 ] * inv_denom;
- dst[ 0 ] = p[ 0 ] - d * n[ 0 ];
- dst[ 1 ] = p[ 1 ] - d * n[ 1 ];
- dst[ 2 ] = p[ 2 ] - d * n[ 2 ];
- }
- /*
- -----------------------------------------------------------------------------
- Function: PerpendicularVector -
-
- Parameters:dst -[out] Perpendicular Vector.
- src -[in] Normalized vector.
-
- Returns: Nothing.
-
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC void PerpendicularVector( vec3_t dst, const vec3_t src )
- {
- int pos;
- int i;
- float minelem = 1.0F;
- vec3_t tempvec;
- /* find the smallest magnitude axially aligned vector */
- for( pos = 0, i = 0 ; i < 3 ; ++i )
- {
- if( fabs( src[ i ] ) < minelem )
- {
- pos = i;
- minelem = (float)fabs( src[ i ] );
- }
- }
- tempvec[ 0 ] = tempvec[ 1 ] = tempvec[ 2 ] = 0.0F;
- tempvec[ pos ] = 1.0F;
- /* project the point onto the plane defined by src */
- ProjectPointOnPlane( dst, tempvec, src );
- /* normalize the result */
- pfVectorNormalize( dst );
- }
- /*
- -----------------------------------------------------------------------------
- Function: RotatePointAroundVector -Rotate a point around a vector.
- Parameters: dst -[out] Point after rotation.
- dir -[in] vector.
- point -[in] Point.
- degrees -[in] Degrees of rotation.
- Returns: Nothing.
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees )
- {
- mat3_t m;
- mat3_t im;
- mat3_t zrot;
- mat3_t tmpmat;
- mat3_t rot;
- vec3_t vr, vup, vf;
- float rad;
- vf[0] = dir[0];
- vf[1] = dir[1];
- vf[2] = dir[2];
- PerpendicularVector( vr, dir );
- vectorCrossProduct( vr, vf, vup );
- m[0] = vr[0];
- m[3] = vr[1];
- m[6] = vr[2];
- m[1] = vup[0];
- m[4] = vup[1];
- m[7] = vup[2];
- m[2] = vf[0];
- m[5] = vf[1];
- m[8] = vf[2];
- memcpy( im, m, sizeof( im ) );
- im[1] = m[3];
- im[2] = m[6];
- im[3] = m[1];
- im[5] = m[7];
- im[6] = m[2];
- im[7] = m[5];
- memset( zrot, 0, sizeof( zrot ) );
- zrot[0] = zrot[4] = zrot[8] = 1.0F;
- rad = DEG2RAD( degrees );
- zrot[0] = (float)cos( rad );
- zrot[1] = (float)sin( rad );
- zrot[3] = (float)-sin( rad );
- zrot[4] = (float)cos( rad );
- Matrix3x3Multiply( m, zrot, tmpmat );
- Matrix3x3Multiply( tmpmat, im, rot );
- dst[0] = rot[0] * point[0] + rot[1] * point[1] + rot[2] * point[2];
- dst[1] = rot[3] * point[0] + rot[4] * point[1] + rot[5] * point[2];
- dst[2] = rot[6] * point[0] + rot[7] * point[1] + rot[8] * point[2];
- }
- /*
- -----------------------------------------------------------------------------
- Function:
- Parameters:
- Returns:
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC float RadiusFromBounds( const vec3_t mins, const vec3_t maxs )
- {
- int i;
- vec3_t corner;
- float a, b;
- for( i = 0; i < 3; ++i )
- {
- a = (float)fabs( mins[i] );
- b = (float)fabs( maxs[i] );
- corner[i] = a > b ? a : b;
- }
- return vectorLength( corner );
- }
- /*
- -----------------------------------------------------------------------------
- Function:
- Parameters:
- Returns:
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC void AddPointToBounds( vec3_t v, vec3_t mins, vec3_t maxs )
- {
- if ( v[0] < mins[0] )
- {
- mins[0] = v[0];
- }
- if ( v[0] > maxs[0])
- {
- maxs[0] = v[0];
- }
- if ( v[1] < mins[1] )
- {
- mins[1] = v[1];
- }
- if ( v[1] > maxs[1])
- {
- maxs[1] = v[1];
- }
- if ( v[2] < mins[2] )
- {
- mins[2] = v[2];
- }
- if ( v[2] > maxs[2])
- {
- maxs[2] = v[2];
- }
- }
- /*
- -----------------------------------------------------------------------------
- Function:
- Parameters:
- Returns:
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up )
- {
- float angle;
- static float sr, sp, sy, cr, cp, cy;
- // static to help MS compiler fp bugs
- angle = angles[YAW] * ( M_PI*2 / 360 );
- sy = (float)sin( angle );
- cy = (float)cos( angle );
- angle = angles[PITCH] * ( M_PI*2 / 360 );
- sp = (float)sin( angle );
- cp = (float)cos( angle );
- angle = angles[ROLL] * ( M_PI*2 / 360 );
- sr = (float)sin( angle );
- cr = (float)cos( angle );
- if( forward )
- {
- forward[0] = cp*cy;
- forward[1] = cp*sy;
- forward[2] = -sp;
- }
- if( right )
- {
- right[0] = (-1*sr*sp*cy+-1*cr*-sy);
- right[1] = (-1*sr*sp*sy+-1*cr*cy);
- right[2] = -1*sr*cp;
- }
- if( up )
- {
- up[0] = (cr*sp*cy+-sr*-sy);
- up[1] = (cr*sp*sy+-sr*cy);
- up[2] = cr*cp;
- }
- }
- /*
- -----------------------------------------------------------------------------
- Function: vectorCompare -Compares two vectors for equality.
- Parameters: v1, v2 -[in] 3d vectors to compare.
- Returns: 1 if they are equal, otherwise 0.
- Notes:
- -----------------------------------------------------------------------------
- */
- INLINECALL int vectorCompare( const vec3_t v1, const vec3_t v2 )
- {
- if( v1[ 0 ] != v2[ 0 ] ||
- v1[ 1 ] != v2[ 1 ] ||
- v1[ 2 ] != v2[ 2 ] )
- {
- return 0;
- }
-
- return 1;
- }
- /*
- -----------------------------------------------------------------------------
- Function: vectorLength -Get the length of a vector.
- Parameters: v -[in] 3D vector to get the length of.
- Returns: The length of the vector.
- Notes:
- Since the square of length is a sum of squares, and squares
- (of real numbers) are always positive, length is always positive.
- The only time the length of a 3D vector is zero is when the vector
- is the zero vector.
- -----------------------------------------------------------------------------
- */
- INLINECALL vec_t vectorLength( const vec3_t v )
- {
- return (vec_t)pfSqrt( v[ 0 ] * v[ 0 ] + v[ 1 ] * v[ 1 ] + v[ 2 ] * v[ 2 ] );
- }
- /*
- -----------------------------------------------------------------------------
- Function: CrossProduct -Calulates the cross product of two vectors.
- Parameters: v1, v2 -[in] 3D vectors.
- cross -[out] The vector cross product.
- Returns: Nothing
- Notes:
- The vector cross product takes two vector operands to produce a
- vector result. The result, like all geometric vectors, has two
- properties: length and orientation.
- To find a vector perpendicular to a particular plane, compute the
- cross product of two vectors in that plane. But there are two
- directions perpendicular to the plane. Which one does the cross
- product give you? That is determined by the right hand rule.
- The cross product of two vectors is perpendicular to both; the right
- hand rule picks the one out of two possible perpendicular directions.
- Computing Cross Product from Column Matrices:
- u × v = ( uj vk - uk vj , uk vi - ui vk , ui vj - uj vi )T
- -----------------------------------------------------------------------------
- */
- PUBLIC void vectorCrossProduct( const vec3_t v1, const vec3_t v2, vec3_t cross )
- {
- cross[ 0 ] = v1[ 1 ] * v2[ 2 ] - v1[ 2 ] * v2[ 1 ]; // X
- cross[ 1 ] = v1[ 2 ] * v2[ 0 ] - v1[ 0 ] * v2[ 2 ]; // Y
- cross[ 2 ] = v1[ 0 ] * v2[ 1 ] - v1[ 1 ] * v2[ 0 ]; // Z
- }
- #if defined(__i386__) && defined(_MSC_VER)
- // Taken from an article written by Michael Abrash that originally appeared in
- // Dr. Dobb's Journal.
- PUBLIC void vectorCrossProduct_asm( const vec3_t v1, const vec3_t v2, vec3_t cross )
- {
- __asm
- {
- mov eax, cross
- mov ecx, v2
- mov edx, v1
- ;optimized cross product; 22 cycles
- fld dword ptr [ecx+4] ;starts & ends on cycle 0
- fmul dword ptr [edx+8] ;starts on cycle 1
- fld dword ptr [ecx+8] ;starts & ends on cycle 2
- fmul dword ptr [edx+0] ;starts on cycle 3
- fld dword ptr [ecx+0] ;starts & ends on cycle 4
- fmul dword ptr [edx+4] ;starts on cycle 5
- fld dword ptr [ecx+8] ;starts & ends on cycle 6
- fmul dword ptr [edx+4] ;starts on cycle 7
- fld dword ptr [ecx+0] ;starts & ends on cycle 8
- fmul dword ptr [edx+8] ;starts on cycle 9
- fld dword ptr [ecx+4] ;starts & ends on cycle 10
- fmul dword ptr [edx+0] ;starts on cycle 11
- fxch st(2) ;no cost
- fsubrp st(5),st(0) ;starts on cycle 12
- fsubrp st(3),st(0) ;starts on cycle 13
- fsubrp st(1),st(0) ;starts on cycle 14
- fxch st(2) ;no cost, stalls for cycle 15
- fstp dword ptr [eax+0] ;starts on cycle 16, ends on cycle 17
- fstp dword ptr [eax+4] ;starts on cycle 18, ends on cycle 19
- fstp dword ptr [eax+8] ;starts on cycle 20, ends on cycle 21
- }
- }
- #endif /* __i386__ */
- /*
- -----------------------------------------------------------------------------
- Function: _DotProduct -Calculates the dot product.
-
- Parameters: v1, v2 -[in] 3D vectors to compute dot product.
- Returns: the dot product
- Notes:
- Dot product, which takes two vectors as operands and produces a real
- number as its output. Sometimes the dot product is called the inner
- product or the scalar product.
- The dot product is:
- a · b = a1b1 + a2b2 + a3b3
- -----------------------------------------------------------------------------
- */
- PUBLIC vec_t _vectorDotProduct( const vec3_t v1, const vec3_t v2 )
- {
- return v1[ 0 ] * v2[ 0 ] + v1[ 1 ] * v2[ 1 ] + v1[ 2 ] * v2[ 2 ];
- }
- #if defined(__i386__) && defined(_MSC_VER)
- // Taken from an article written by Michael Abrash that originally appeared in
- // Dr. Dobb's Journal.
- PUBLIC vec_t _vectorDotProduct_asm( const vec3_t v1, const vec3_t v2 )
- {
- float dotret;
- __asm
- {
- mov eax, v2
- mov ecx, v1
-
- ;optimized dot product; 15 cycles
- fld dword ptr [eax+0] ;starts & ends on cycle 0
- fmul dword ptr [ecx+0] ;starts on cycle 1
- fld dword ptr [eax+4] ;starts & ends on cycle 2
- fmul dword ptr [ecx+4] ;starts on cycle 3
- fld dword ptr [eax+8] ;starts & ends on cycle 4
- fmul dword ptr [ecx+8] ;starts on cycle 5
- fxch st(1) ;no cost
- faddp st(2),st(0) ;starts on cycle 6, stalls for cycles 7-8
- faddp st(1),st(0) ;starts on cycle 9, stalls for cycles 10-12
- fstp dword ptr [dotret] ;starts on cycle 13, ends on cycle 14
- }
- return dotret;
- }
- #endif /* __i386__ */
- /*
- -----------------------------------------------------------------------------
- Function: _vectorSubtract -Vector Difference.
- Parameters: veca, vecb -[in] 3D vectors.
- out -[out] The vector difference of vectors A and B.
- Returns: Nothing.
- Notes:
- -----------------------------------------------------------------------------
- */
- INLINECALL void _vectorSubtract( const vec3_t veca, const vec3_t vecb, vec3_t out )
- {
- out[ 0 ] = veca[ 0 ] - vecb[ 0 ];
- out[ 1 ] = veca[ 1 ] - vecb[ 1 ];
- out[ 2 ] = veca[ 2 ] - vecb[ 2 ];
- }
- /*
- -----------------------------------------------------------------------------
- Function: _vectorAdd -Vector addition.
- Parameters: veca, vecb -[in] 3D vectors.
- out -[out] The vector sum of vectors A and B
- Returns: Nothing.
- Notes:
- -----------------------------------------------------------------------------
- */
- INLINECALL void _vectorAdd( const vec3_t veca, const vec3_t vecb, vec3_t out )
- {
- out[ 0 ] = veca[ 0 ] + vecb[ 0 ];
- out[ 1 ] = veca[ 1 ] + vecb[ 1 ];
- out[ 2 ] = veca[ 2 ] + vecb[ 2 ];
- }
- /*
- -----------------------------------------------------------------------------
- Function: _vectorCopy -Copy a vector.
- Parameters: in -[in] Source vector.
- out -[out] Destination vector.
- Returns: Nothing.
- Notes:
- -----------------------------------------------------------------------------
- */
- INLINECALL void _vectorCopy( const vec3_t in, vec3_t out )
- {
- out[ 0 ] = in[ 0 ];
- out[ 1 ] = in[ 1 ];
- out[ 2 ] = in[ 2 ];
- }
- /*
- -----------------------------------------------------------------------------
- Function: _vectorScale -Scale a vector.
- Parameters: in -[in] Source vector.
- scale -[in] Scale vector.
- out -[out] Destination vector.
- Returns: Nothing.
- Notes:
- -----------------------------------------------------------------------------
- */
- INLINECALL void _vectorScale( const vec3_t in, const vec_t scale, vec3_t out )
- {
- out[ 0 ] = in[ 0 ] * scale;
- out[ 1 ] = in[ 1 ] * scale;
- out[ 2 ] = in[ 2 ] * scale;
- }
- /*
- -----------------------------------------------------------------------------
- Function:
- Parameters:
- Returns:
- Notes:
- -----------------------------------------------------------------------------
- */
- INLINECALL void _vectorMA( const vec3_t veca, float scale, const vec3_t vecb, vec3_t vecc )
- {
- vecc[ 0 ] = veca[ 0 ] + scale * vecb[ 0 ];
- vecc[ 1 ] = veca[ 1 ] + scale * vecb[ 1 ];
- vecc[ 2 ] = veca[ 2 ] + scale * vecb[ 2 ];
- }
- /////////////////////////////////////////////////////////////////////
- //
- // 2D Vector routines
- //
- /////////////////////////////////////////////////////////////////////
- /*
- -----------------------------------------------------------------------------
- Function: vector2DCompare -Compares two vectors for equality.
- Parameters: v1, v2 -[in] 2d vectors to compare.
- Returns: 1 if they are equal, otherwise 0.
- Notes:
- -----------------------------------------------------------------------------
- */
- INLINECALL W32 vector2DCompare( const vec2_t v1, const vec2_t v2 )
- {
- if( v1[ 0 ] != v2[ 0 ] || v1[ 1 ] != v2[ 1 ] )
- {
- return 0;
- }
-
- return 1;
- }
- /*
- -----------------------------------------------------------------------------
- Function: vector2DLength -Get the length of a vector.
- Parameters: v -[in] 2D vector to get the length of.
- Returns: The length of the vector.
- Notes:
- -----------------------------------------------------------------------------
- */
- INLINECALL vec_t vector2DLength( const vec2_t v )
- {
- return (vec_t)pfSqrt( v[ 0 ] * v[ 0 ] + v[ 1 ] * v[ 1 ] );
- }
|