]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - libs/splines/math_vector.h
various: reindent classes
[xonotic/netradiant.git] / libs / splines / math_vector.h
index 6e1f765ac460ec1fb07e28d567d53fd1ddcb7298..3e6372e5db44335c231af4a403258b02e69ccfec 100644 (file)
-/*\r
-Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
-For a list of contributors, see the accompanying CONTRIBUTORS file.\r
-\r
-This file is part of GtkRadiant.\r
-\r
-GtkRadiant is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-GtkRadiant is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with GtkRadiant; if not, write to the Free Software\r
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
-*/\r
-\r
-#ifndef __MATH_VECTOR_H__\r
-#define __MATH_VECTOR_H__\r
-\r
-#ifdef _WIN32\r
-#pragma warning(disable : 4244)\r
-#endif\r
-\r
-#include <math.h>\r
-#include <assert.h>\r
-\r
-//#define DotProduct(a,b)                      ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2])\r
-//#define VectorSubtract(a,b,c)        ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2])\r
-//#define VectorAdd(a,b,c)             ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2])\r
-//#define VectorCopy(a,b)                      ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2])\r
-//#define VectorCopy(a,b)                      ((b).x=(a).x,(b).y=(a).y,(b).z=(a).z])\r
-\r
-//#define      VectorScale(v, s, o)    ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s))\r
-#define        __VectorMA(v, s, b, o)  ((o)[0]=(v)[0]+(b)[0]*(s),(o)[1]=(v)[1]+(b)[1]*(s),(o)[2]=(v)[2]+(b)[2]*(s))\r
-//#define CrossProduct(a,b,c)          ((c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1],(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2],(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0])\r
-\r
-#define DotProduct4(x,y)               ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]+(x)[3]*(y)[3])\r
-#define VectorSubtract4(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2],(c)[3]=(a)[3]-(b)[3])\r
-#define VectorAdd4(a,b,c)              ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2],(c)[3]=(a)[3]+(b)[3])\r
-#define VectorCopy4(a,b)               ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])\r
-#define        VectorScale4(v, s, o)   ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s),(o)[3]=(v)[3]*(s))\r
-#define        VectorMA4(v, s, b, o)   ((o)[0]=(v)[0]+(b)[0]*(s),(o)[1]=(v)[1]+(b)[1]*(s),(o)[2]=(v)[2]+(b)[2]*(s),(o)[3]=(v)[3]+(b)[3]*(s))\r
-\r
-\r
-//#define VectorClear(a)                       ((a)[0]=(a)[1]=(a)[2]=0)\r
-#define VectorNegate(a,b)              ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2])\r
-//#define VectorSet(v, x, y, z)        ((v)[0]=(x), (v)[1]=(y), (v)[2]=(z))\r
-#define Vector4Copy(a,b)               ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])\r
-\r
-#define        SnapVector(v) {v[0]=(int)v[0];v[1]=(int)v[1];v[2]=(int)v[2];}\r
-\r
-\r
-//#include "util_heap.h"\r
-\r
-#ifndef EQUAL_EPSILON\r
-#define EQUAL_EPSILON  0.001\r
-#endif\r
-\r
-float Q_fabs( float f );\r
-\r
-#ifndef ID_INLINE\r
-#ifdef _WIN32\r
-#define ID_INLINE __inline \r
-#else\r
-#define ID_INLINE inline\r
-#endif\r
-#endif\r
-\r
-// if this is defined, vec3 will take four elements, which may allow\r
-// easier SIMD optimizations\r
-//#define      FAT_VEC3\r
-//#ifdef __ppc__\r
-//#pragma align(16)\r
-//#endif\r
-\r
-class angles_t;\r
-#ifdef __ppc__\r
-// Vanilla PPC code, but since PPC has a reciprocal square root estimate instruction, \r
-// runs *much* faster than calling sqrt(). We'll use two Newton-Raphson \r
-// refinement steps to get bunch more precision in the 1/sqrt() value for very little cost. \r
-// We'll then multiply 1/sqrt times the original value to get the sqrt. \r
-// This is about 12.4 times faster than sqrt() and according to my testing (not exhaustive) \r
-// it returns fairly accurate results (error below 1.0e-5 up to 100000.0 in 0.1 increments). \r
-\r
-static inline float idSqrt(float x) {\r
-    const float half = 0.5;\r
-    const float one = 1.0;\r
-    float B, y0, y1;\r
-\r
-    // This'll NaN if it hits frsqrte. Handle both +0.0 and -0.0\r
-    if (fabs(x) == 0.0)\r
-        return x;\r
-    B = x;\r
-    \r
-#ifdef __GNUC__\r
-    asm("frsqrte %0,%1" : "=f" (y0) : "f" (B));\r
-#else\r
-    y0 = __frsqrte(B);\r
-#endif\r
-    /* First refinement step */\r
-    \r
-    y1 = y0 + half*y0*(one - B*y0*y0);\r
-    \r
-    /* Second refinement step -- copy the output of the last step to the input of this step */\r
-    \r
-    y0 = y1;\r
-    y1 = y0 + half*y0*(one - B*y0*y0);\r
-    \r
-    /* Get sqrt(x) from x * 1/sqrt(x) */\r
-    return x * y1;\r
-}\r
-#else\r
-static inline double idSqrt(double x) {\r
-    return sqrt(x);\r
-}\r
-#endif\r
-\r
-\r
-//class idVec3  : public idHeap<idVec3> {\r
-class idVec3 {\r
-public:        \r
-#ifndef        FAT_VEC3\r
-           float x,y,z;\r
-#else\r
-           float x,y,z,dist;\r
-#endif\r
-\r
-#ifndef        FAT_VEC3\r
-                                       idVec3() {};\r
-#else\r
-                                       idVec3() {dist = 0.0f;};\r
-#endif\r
-                                       idVec3( const float x, const float y, const float z );\r
-\r
-                                       operator float *();\r
-\r
-       float                   operator[]( const int index ) const;\r
-       float                   &operator[]( const int index );\r
-\r
-       void                    set( const float x, const float y, const float z );\r
-\r
-       idVec3                  operator-() const;\r
-\r
-       idVec3                  &operator=( const idVec3 &a );\r
-\r
-       float                   operator*( const idVec3 &a ) const;\r
-       idVec3                  operator*( const float a ) const;\r
-       friend idVec3   operator*( float a, idVec3 b );\r
-\r
-       idVec3                  operator+( const idVec3 &a ) const;\r
-       idVec3                  operator-( const idVec3 &a ) const;\r
-       \r
-       idVec3                  &operator+=( const idVec3 &a );\r
-       idVec3                  &operator-=( const idVec3 &a );\r
-       idVec3                  &operator*=( const float a );\r
-\r
-       int                             operator==(     const idVec3 &a ) const;\r
-       int                             operator!=(     const idVec3 &a ) const;\r
-\r
-       idVec3                  Cross( const idVec3 &a ) const;\r
-       idVec3                  &Cross( const idVec3 &a, const idVec3 &b );\r
-\r
-       float                   Length( void ) const;\r
-       float                   Normalize( void );\r
-\r
-       void                    Zero( void );\r
-       void                    Snap( void );\r
-       void                    SnapTowards( const idVec3 &to );\r
-\r
-       float                   toYaw( void );\r
-       float                   toPitch( void );\r
-       angles_t                toAngles( void );\r
-       friend idVec3   LerpVector( const idVec3 &w1, const idVec3 &w2, const float t );\r
-\r
-       char                    *string( void );\r
-};\r
-\r
-extern idVec3 vec_zero;\r
-\r
-ID_INLINE idVec3::idVec3( const float x, const float y, const float z ) {\r
-       this->x = x;\r
-       this->y = y;\r
-       this->z = z;\r
-#ifdef FAT_VEC3\r
-       this->dist = 0.0f;\r
-#endif\r
-}\r
-\r
-ID_INLINE float idVec3::operator[]( const int index ) const {\r
-       return ( &x )[ index ];\r
-}\r
-\r
-ID_INLINE float &idVec3::operator[]( const int index ) {\r
-       return ( &x )[ index ];\r
-}\r
-\r
-ID_INLINE idVec3::operator float *( void ) {\r
-       return &x;\r
-}\r
-\r
-ID_INLINE idVec3 idVec3::operator-() const {\r
-       return idVec3( -x, -y, -z );\r
-}\r
-       \r
-ID_INLINE idVec3 &idVec3::operator=( const idVec3 &a ) { \r
-       x = a.x;\r
-       y = a.y;\r
-       z = a.z;\r
-       \r
-       return *this;\r
-}\r
-\r
-ID_INLINE void idVec3::set( const float x, const float y, const float z ) {\r
-       this->x = x;\r
-       this->y = y;\r
-       this->z = z;\r
-}\r
-\r
-ID_INLINE idVec3 idVec3::operator-( const idVec3 &a ) const {\r
-       return idVec3( x - a.x, y - a.y, z - a.z );\r
-}\r
-\r
-ID_INLINE float idVec3::operator*( const idVec3 &a ) const {\r
-       return x * a.x + y * a.y + z * a.z;\r
-}\r
-\r
-ID_INLINE idVec3 idVec3::operator*( const float a ) const {\r
-       return idVec3( x * a, y * a, z * a );\r
-}\r
-\r
-ID_INLINE idVec3 operator*( const float a, const idVec3 b ) {\r
-       return idVec3( b.x * a, b.y * a, b.z * a );\r
-}\r
-\r
-ID_INLINE idVec3 idVec3::operator+( const idVec3 &a ) const {\r
-       return idVec3( x + a.x, y + a.y, z + a.z );\r
-}\r
-\r
-ID_INLINE idVec3 &idVec3::operator+=( const idVec3 &a ) {\r
-       x += a.x;\r
-       y += a.y;\r
-       z += a.z;\r
-\r
-       return *this;\r
-}\r
-\r
-ID_INLINE idVec3 &idVec3::operator-=( const idVec3 &a ) {\r
-       x -= a.x;\r
-       y -= a.y;\r
-       z -= a.z;\r
-\r
-       return *this;\r
-}\r
-\r
-ID_INLINE idVec3 &idVec3::operator*=( const float a ) {\r
-       x *= a;\r
-       y *= a;\r
-       z *= a;\r
-\r
-       return *this;\r
-}\r
-\r
-ID_INLINE int idVec3::operator==( const idVec3 &a ) const {\r
-       if ( Q_fabs( x - a.x ) > EQUAL_EPSILON ) {\r
-               return false;\r
-       }\r
-                       \r
-       if ( Q_fabs( y - a.y ) > EQUAL_EPSILON ) {\r
-               return false;\r
-       }\r
-\r
-       if ( Q_fabs( z - a.z ) > EQUAL_EPSILON ) {\r
-               return false;\r
-       }\r
-\r
-       return true;\r
-}\r
-\r
-ID_INLINE int idVec3::operator!=( const idVec3 &a ) const {\r
-       if ( Q_fabs( x - a.x ) > EQUAL_EPSILON ) {\r
-               return true;\r
-       }\r
-                       \r
-       if ( Q_fabs( y - a.y ) > EQUAL_EPSILON ) {\r
-               return true;\r
-       }\r
-\r
-       if ( Q_fabs( z - a.z ) > EQUAL_EPSILON ) {\r
-               return true;\r
-       }\r
-\r
-       return false;\r
-}\r
-\r
-ID_INLINE idVec3 idVec3::Cross( const idVec3 &a ) const {\r
-       return idVec3( y * a.z - z * a.y, z * a.x - x * a.z, x * a.y - y * a.x );\r
-}\r
-\r
-ID_INLINE idVec3 &idVec3::Cross( const idVec3 &a, const idVec3 &b ) {\r
-       x = a.y * b.z - a.z * b.y;\r
-       y = a.z * b.x - a.x * b.z;\r
-       z = a.x * b.y - a.y * b.x;\r
-\r
-       return *this;\r
-}\r
-\r
-ID_INLINE float idVec3::Length( void ) const {\r
-       float length;\r
-       \r
-       length = x * x + y * y + z * z;\r
-       return ( float )idSqrt( length );\r
-}\r
-\r
-ID_INLINE float idVec3::Normalize( void ) {\r
-       float length;\r
-       float ilength;\r
-\r
-       length = this->Length();\r
-       if ( length ) {\r
-               ilength = 1.0f / length;\r
-               x *= ilength;\r
-               y *= ilength;\r
-               z *= ilength;\r
-       }\r
-               \r
-       return length;\r
-}\r
-\r
-ID_INLINE void idVec3::Zero( void ) {\r
-       x = 0.0f;\r
-       y = 0.0f;\r
-       z = 0.0f;\r
-}\r
-\r
-ID_INLINE void idVec3::Snap( void ) {\r
-       x = float( int( x ) );\r
-       y = float( int( y ) );\r
-       z = float( int( z ) );\r
-}\r
-\r
-/*\r
-======================\r
-SnapTowards\r
-\r
-Round a vector to integers for more efficient network\r
-transmission, but make sure that it rounds towards a given point\r
-rather than blindly truncating.  This prevents it from truncating \r
-into a wall.\r
-======================\r
-*/\r
-ID_INLINE void idVec3::SnapTowards( const idVec3 &to ) {\r
-       if ( to.x <= x ) {\r
-               x = float( int( x ) );\r
-       } else {\r
-               x = float( int( x ) + 1 );\r
-       }\r
-\r
-       if ( to.y <= y ) {\r
-               y = float( int( y ) );\r
-       } else {\r
-               y = float( int( y ) + 1 );\r
-       }\r
-\r
-       if ( to.z <= z ) {\r
-               z = float( int( z ) );\r
-       } else {\r
-               z = float( int( z ) + 1 );\r
-       }\r
-}\r
-\r
-//===============================================================\r
-\r
-class Bounds {\r
-public:\r
-       idVec3  b[2];\r
-\r
-                       Bounds();\r
-                       Bounds( const idVec3 &mins, const idVec3 &maxs );\r
-\r
-       void    Clear();\r
-       void    Zero();\r
-       float   Radius();               // radius from origin, not from center\r
-       idVec3  Center();\r
-       void    AddPoint( const idVec3 &v );\r
-       void    AddBounds( const Bounds &bb );\r
-       bool    IsCleared();\r
-       bool    ContainsPoint( const idVec3 &p );\r
-       bool    IntersectsBounds( const Bounds &b2 );   // touching is NOT intersecting\r
-};\r
-\r
-extern Bounds  boundsZero;\r
-\r
-ID_INLINE Bounds::Bounds(){\r
-}\r
-\r
-ID_INLINE bool Bounds::IsCleared() {\r
-       return b[0][0] > b[1][0];\r
-}\r
-\r
-ID_INLINE bool Bounds::ContainsPoint( const idVec3 &p ) {\r
-       if ( p[0] < b[0][0] || p[1] < b[0][1] || p[2] < b[0][2]\r
-               || p[0] > b[1][0] || p[1] > b[1][1] || p[2] > b[1][2] ) {\r
-               return false;\r
-       }\r
-       return true;\r
-}\r
-\r
-ID_INLINE bool Bounds::IntersectsBounds( const Bounds &b2 ) {\r
-       if ( b2.b[1][0] < b[0][0] || b2.b[1][1] < b[0][1] || b2.b[1][2] < b[0][2]\r
-               || b2.b[0][0] > b[1][0] || b2.b[0][1] > b[1][1] || b2.b[0][2] > b[1][2] ) {\r
-               return false;\r
-       }\r
-       return true;\r
-}\r
-\r
-ID_INLINE Bounds::Bounds( const idVec3 &mins, const idVec3 &maxs ) {\r
-       b[0] = mins;\r
-       b[1] = maxs;\r
-}\r
-\r
-ID_INLINE idVec3 Bounds::Center() {\r
-       return idVec3( ( b[1][0] + b[0][0] ) * 0.5f, ( b[1][1] + b[0][1] ) * 0.5f, ( b[1][2] + b[0][2] ) * 0.5f );\r
-}\r
-\r
-ID_INLINE void Bounds::Clear() {\r
-       b[0][0] = b[0][1] = b[0][2] = 99999;\r
-       b[1][0] = b[1][1] = b[1][2] = -99999;\r
-}\r
-\r
-ID_INLINE void Bounds::Zero() {\r
-       b[0][0] = b[0][1] = b[0][2] =\r
-       b[1][0] = b[1][1] = b[1][2] = 0;\r
-}\r
-\r
-ID_INLINE void Bounds::AddPoint( const idVec3 &v ) {\r
-       if ( v[0] < b[0][0]) {\r
-               b[0][0] = v[0];\r
-       }\r
-       if ( v[0] > b[1][0]) {\r
-               b[1][0] = v[0];\r
-       }\r
-       if ( v[1] < b[0][1] ) {\r
-               b[0][1] = v[1];\r
-       }\r
-       if ( v[1] > b[1][1]) {\r
-               b[1][1] = v[1];\r
-       }\r
-       if ( v[2] < b[0][2] ) {\r
-               b[0][2] = v[2];\r
-       }\r
-       if ( v[2] > b[1][2]) {\r
-               b[1][2] = v[2];\r
-       }\r
-}\r
-\r
-\r
-ID_INLINE void Bounds::AddBounds( const Bounds &bb ) {\r
-       if ( bb.b[0][0] < b[0][0]) {\r
-               b[0][0] = bb.b[0][0];\r
-       }\r
-       if ( bb.b[0][1] < b[0][1]) {\r
-               b[0][1] = bb.b[0][1];\r
-       }\r
-       if ( bb.b[0][2] < b[0][2]) {\r
-               b[0][2] = bb.b[0][2];\r
-       }\r
-\r
-       if ( bb.b[1][0] > b[1][0]) {\r
-               b[1][0] = bb.b[1][0];\r
-       }\r
-       if ( bb.b[1][1] > b[1][1]) {\r
-               b[1][1] = bb.b[1][1];\r
-       }\r
-       if ( bb.b[1][2] > b[1][2]) {\r
-               b[1][2] = bb.b[1][2];\r
-       }\r
-}\r
-\r
-ID_INLINE float Bounds::Radius( ) {\r
-       int             i;\r
-       float   total;\r
-       float   a, aa;\r
-\r
-       total = 0;\r
-       for (i=0 ; i<3 ; i++) {\r
-               a = (float)fabs( b[0][i] );\r
-               aa = (float)fabs( b[1][i] );\r
-               if ( aa > a ) {\r
-                       a = aa;\r
-               }\r
-               total += a * a;\r
-       }\r
-\r
-       return (float)idSqrt( total );\r
-}\r
-\r
-//===============================================================\r
-\r
-\r
-class idVec2 {\r
-public:\r
-       float                   x;\r
-       float                   y;\r
-\r
-                                       operator float *();\r
-       float                   operator[]( int index ) const;\r
-       float                   &operator[]( int index );\r
-};\r
-\r
-ID_INLINE float idVec2::operator[]( int index ) const {\r
-       return ( &x )[ index ];\r
-}\r
-\r
-ID_INLINE float& idVec2::operator[]( int index ) {\r
-       return ( &x )[ index ];\r
-}\r
-\r
-ID_INLINE idVec2::operator float *( void ) {\r
-       return &x;\r
-}\r
-\r
-class idVec4 : public idVec3 {\r
-public:\r
-#ifndef        FAT_VEC3\r
-       float                   dist;\r
-#endif\r
-       idVec4();\r
-       ~idVec4() {};\r
-       \r
-       idVec4( float x, float y, float z, float dist );\r
-       float                   operator[]( int index ) const;\r
-       float                   &operator[]( int index );\r
-};\r
-\r
-ID_INLINE idVec4::idVec4() {}\r
-ID_INLINE idVec4::idVec4( float x, float y, float z, float dist ) {\r
-       this->x = x;\r
-       this->y = y;\r
-       this->z = z;\r
-       this->dist = dist;\r
-}\r
-\r
-ID_INLINE float idVec4::operator[]( int index ) const {\r
-       return ( &x )[ index ];\r
-}\r
-\r
-ID_INLINE float& idVec4::operator[]( int index ) {\r
-       return ( &x )[ index ];\r
-}\r
-\r
-\r
-class idVec5_t : public idVec3 {\r
-public:\r
-       float                   s;\r
-       float                   t;\r
-       float                   operator[]( int index ) const;\r
-       float                   &operator[]( int index );\r
-};\r
-\r
-\r
-ID_INLINE float idVec5_t::operator[]( int index ) const {\r
-       return ( &x )[ index ];\r
-}\r
-\r
-ID_INLINE float& idVec5_t::operator[]( int index ) {\r
-       return ( &x )[ index ];\r
-}\r
-\r
-#endif /* !__MATH_VECTOR_H__ */\r
+/*
+   Copyright (C) 1999-2006 Id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __MATH_VECTOR_H__
+#define __MATH_VECTOR_H__
+
+#include "globaldefs.h"
+
+#if GDEF_COMPILER_MSVC
+#pragma warning(disable : 4244)
+#endif
+
+#include <math.h>
+#include <assert.h>
+
+//#define DotProduct(a,b)                      ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2])
+//#define VectorSubtract(a,b,c)        ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2])
+//#define VectorAdd(a,b,c)             ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2])
+//#define VectorCopy(a,b)                      ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2])
+//#define VectorCopy(a,b)                      ((b).x=(a).x,(b).y=(a).y,(b).z=(a).z])
+
+//#define      VectorScale(v, s, o)    ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s))
+#define __VectorMA( v, s, b, o )  ( ( o )[0] = ( v )[0] + ( b )[0] * ( s ),( o )[1] = ( v )[1] + ( b )[1] * ( s ),( o )[2] = ( v )[2] + ( b )[2] * ( s ) )
+//#define CrossProduct(a,b,c)          ((c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1],(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2],(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0])
+
+#define DotProduct4( x,y )        ( ( x )[0] * ( y )[0] + ( x )[1] * ( y )[1] + ( x )[2] * ( y )[2] + ( x )[3] * ( y )[3] )
+#define VectorSubtract4( a,b,c )  ( ( c )[0] = ( a )[0] - ( b )[0],( c )[1] = ( a )[1] - ( b )[1],( c )[2] = ( a )[2] - ( b )[2],( c )[3] = ( a )[3] - ( b )[3] )
+#define VectorAdd4( a,b,c )       ( ( c )[0] = ( a )[0] + ( b )[0],( c )[1] = ( a )[1] + ( b )[1],( c )[2] = ( a )[2] + ( b )[2],( c )[3] = ( a )[3] + ( b )[3] )
+#define VectorCopy4( a,b )        ( ( b )[0] = ( a )[0],( b )[1] = ( a )[1],( b )[2] = ( a )[2],( b )[3] = ( a )[3] )
+#define VectorScale4( v, s, o )   ( ( o )[0] = ( v )[0] * ( s ),( o )[1] = ( v )[1] * ( s ),( o )[2] = ( v )[2] * ( s ),( o )[3] = ( v )[3] * ( s ) )
+#define VectorMA4( v, s, b, o )   ( ( o )[0] = ( v )[0] + ( b )[0] * ( s ),( o )[1] = ( v )[1] + ( b )[1] * ( s ),( o )[2] = ( v )[2] + ( b )[2] * ( s ),( o )[3] = ( v )[3] + ( b )[3] * ( s ) )
+
+
+//#define VectorClear(a)                       ((a)[0]=(a)[1]=(a)[2]=0)
+#define VectorNegate( a,b )       ( ( b )[0] = -( a )[0],( b )[1] = -( a )[1],( b )[2] = -( a )[2] )
+//#define VectorSet(v, x, y, z)        ((v)[0]=(x), (v)[1]=(y), (v)[2]=(z))
+#define Vector4Copy( a,b )        ( ( b )[0] = ( a )[0],( b )[1] = ( a )[1],( b )[2] = ( a )[2],( b )[3] = ( a )[3] )
+
+#define SnapVector( v ) {v[0] = (int)v[0]; v[1] = (int)v[1]; v[2] = (int)v[2]; }
+
+
+//#include "util_heap.h"
+
+#ifndef EQUAL_EPSILON
+#define EQUAL_EPSILON   0.001
+#endif
+
+float Q_fabs( float f );
+
+#ifndef ID_INLINE
+#define ID_INLINE GDEF_ATTRIBUTE_INLINE
+#endif
+
+// if this is defined, vec3 will take four elements, which may allow
+// easier SIMD optimizations
+//#define      FAT_VEC3
+//#ifdef __ppc__
+//#pragma align(16)
+//#endif
+
+class angles_t;
+#ifdef __ppc__
+// Vanilla PPC code, but since PPC has a reciprocal square root estimate instruction,
+// runs *much* faster than calling sqrt(). We'll use two Newton-Raphson
+// refinement steps to get bunch more precision in the 1/sqrt() value for very little cost.
+// We'll then multiply 1/sqrt times the original value to get the sqrt.
+// This is about 12.4 times faster than sqrt() and according to my testing (not exhaustive)
+// it returns fairly accurate results (error below 1.0e-5 up to 100000.0 in 0.1 increments).
+
+static inline float idSqrt( float x ) {
+       const float half = 0.5;
+       const float one = 1.0;
+       float B, y0, y1;
+
+       // This'll NaN if it hits frsqrte. Handle both +0.0 and -0.0
+       if ( fabs( x ) == 0.0 ) {
+               return x;
+       }
+       B = x;
+
+#if GDEF_COMPILER_GNU
+       asm ( "frsqrte %0,%1" : "=f" ( y0 ) : "f" ( B ) );
+#else
+       y0 = __frsqrte( B );
+#endif
+       /* First refinement step */
+
+       y1 = y0 + half * y0 * ( one - B * y0 * y0 );
+
+       /* Second refinement step -- copy the output of the last step to the input of this step */
+
+       y0 = y1;
+       y1 = y0 + half * y0 * ( one - B * y0 * y0 );
+
+       /* Get sqrt(x) from x * 1/sqrt(x) */
+       return x * y1;
+}
+#else
+static inline double idSqrt( double x ) {
+       return sqrt( x );
+}
+#endif
+
+
+//class idVec3  : public idHeap<idVec3> {
+class idVec3 {
+public:
+#ifndef FAT_VEC3
+       float x,y,z;
+#else
+       float x,y,z,dist;
+#endif
+
+#ifndef FAT_VEC3
+       idVec3() {};
+#else
+       idVec3() {dist = 0.0f; };
+#endif
+       idVec3( const float x, const float y, const float z );
+
+       operator float *();
+
+       float operator[]( const int index ) const;
+       float &operator[]( const int index );
+
+       void set( const float x, const float y, const float z );
+
+       idVec3 operator-() const;
+
+       idVec3 &operator=( const idVec3 &a );
+
+       float operator*( const idVec3 &a ) const;
+       idVec3 operator*( const float a ) const;
+       friend idVec3 operator*( float a, idVec3 b );
+
+       idVec3 operator+( const idVec3 &a ) const;
+       idVec3 operator-( const idVec3 &a ) const;
+
+       idVec3 &operator+=( const idVec3 &a );
+       idVec3 &operator-=( const idVec3 &a );
+       idVec3 &operator*=( const float a );
+
+       int operator==( const idVec3 &a ) const;
+       int operator!=( const idVec3 &a ) const;
+
+       idVec3          Cross( const idVec3 &a ) const;
+       idVec3          &Cross( const idVec3 &a, const idVec3 &b );
+
+       float           Length( void ) const;
+       float           Normalize( void );
+
+       void            Zero( void );
+       void            Snap( void );
+       void            SnapTowards( const idVec3 &to );
+
+       float           toYaw( void );
+       float           toPitch( void );
+       angles_t        toAngles( void );
+       friend idVec3   LerpVector( const idVec3 &w1, const idVec3 &w2, const float t );
+
+       char            *string( void );
+};
+
+extern idVec3 vec_zero;
+
+ID_INLINE idVec3::idVec3( const float x, const float y, const float z ) {
+       this->x = x;
+       this->y = y;
+       this->z = z;
+#ifdef  FAT_VEC3
+       this->dist = 0.0f;
+#endif
+}
+
+ID_INLINE float idVec3::operator[]( const int index ) const {
+       return ( &x )[ index ];
+}
+
+ID_INLINE float &idVec3::operator[]( const int index ) {
+       return ( &x )[ index ];
+}
+
+ID_INLINE idVec3::operator float *( void ) {
+       return &x;
+}
+
+ID_INLINE idVec3 idVec3::operator-() const {
+       return idVec3( -x, -y, -z );
+}
+
+ID_INLINE idVec3 &idVec3::operator=( const idVec3 &a ) {
+       x = a.x;
+       y = a.y;
+       z = a.z;
+
+       return *this;
+}
+
+ID_INLINE void idVec3::set( const float x, const float y, const float z ) {
+       this->x = x;
+       this->y = y;
+       this->z = z;
+}
+
+ID_INLINE idVec3 idVec3::operator-( const idVec3 &a ) const {
+       return idVec3( x - a.x, y - a.y, z - a.z );
+}
+
+ID_INLINE float idVec3::operator*( const idVec3 &a ) const {
+       return x * a.x + y * a.y + z * a.z;
+}
+
+ID_INLINE idVec3 idVec3::operator*( const float a ) const {
+       return idVec3( x * a, y * a, z * a );
+}
+
+ID_INLINE idVec3 operator*( const float a, const idVec3 b ) {
+       return idVec3( b.x * a, b.y * a, b.z * a );
+}
+
+ID_INLINE idVec3 idVec3::operator+( const idVec3 &a ) const {
+       return idVec3( x + a.x, y + a.y, z + a.z );
+}
+
+ID_INLINE idVec3 &idVec3::operator+=( const idVec3 &a ) {
+       x += a.x;
+       y += a.y;
+       z += a.z;
+
+       return *this;
+}
+
+ID_INLINE idVec3 &idVec3::operator-=( const idVec3 &a ) {
+       x -= a.x;
+       y -= a.y;
+       z -= a.z;
+
+       return *this;
+}
+
+ID_INLINE idVec3 &idVec3::operator*=( const float a ) {
+       x *= a;
+       y *= a;
+       z *= a;
+
+       return *this;
+}
+
+ID_INLINE int idVec3::operator==( const idVec3 &a ) const {
+       if ( Q_fabs( x - a.x ) > EQUAL_EPSILON ) {
+               return false;
+       }
+
+       if ( Q_fabs( y - a.y ) > EQUAL_EPSILON ) {
+               return false;
+       }
+
+       if ( Q_fabs( z - a.z ) > EQUAL_EPSILON ) {
+               return false;
+       }
+
+       return true;
+}
+
+ID_INLINE int idVec3::operator!=( const idVec3 &a ) const {
+       if ( Q_fabs( x - a.x ) > EQUAL_EPSILON ) {
+               return true;
+       }
+
+       if ( Q_fabs( y - a.y ) > EQUAL_EPSILON ) {
+               return true;
+       }
+
+       if ( Q_fabs( z - a.z ) > EQUAL_EPSILON ) {
+               return true;
+       }
+
+       return false;
+}
+
+ID_INLINE idVec3 idVec3::Cross( const idVec3 &a ) const {
+       return idVec3( y * a.z - z * a.y, z * a.x - x * a.z, x * a.y - y * a.x );
+}
+
+ID_INLINE idVec3 &idVec3::Cross( const idVec3 &a, const idVec3 &b ) {
+       x = a.y * b.z - a.z * b.y;
+       y = a.z * b.x - a.x * b.z;
+       z = a.x * b.y - a.y * b.x;
+
+       return *this;
+}
+
+ID_INLINE float idVec3::Length( void ) const {
+       float length;
+
+       length = x * x + y * y + z * z;
+       return ( float )idSqrt( length );
+}
+
+ID_INLINE float idVec3::Normalize( void ) {
+       float length;
+       float ilength;
+
+       length = this->Length();
+       if ( length ) {
+               ilength = 1.0f / length;
+               x *= ilength;
+               y *= ilength;
+               z *= ilength;
+       }
+
+       return length;
+}
+
+ID_INLINE void idVec3::Zero( void ) {
+       x = 0.0f;
+       y = 0.0f;
+       z = 0.0f;
+}
+
+ID_INLINE void idVec3::Snap( void ) {
+       x = float( int( x ) );
+       y = float( int( y ) );
+       z = float( int( z ) );
+}
+
+/*
+   ======================
+   SnapTowards
+
+   Round a vector to integers for more efficient network
+   transmission, but make sure that it rounds towards a given point
+   rather than blindly truncating.  This prevents it from truncating
+   into a wall.
+   ======================
+ */
+ID_INLINE void idVec3::SnapTowards( const idVec3 &to ) {
+       if ( to.x <= x ) {
+               x = float( int( x ) );
+       }
+       else {
+               x = float( int( x ) + 1 );
+       }
+
+       if ( to.y <= y ) {
+               y = float( int( y ) );
+       }
+       else {
+               y = float( int( y ) + 1 );
+       }
+
+       if ( to.z <= z ) {
+               z = float( int( z ) );
+       }
+       else {
+               z = float( int( z ) + 1 );
+       }
+}
+
+//===============================================================
+
+class Bounds {
+public:
+idVec3 b[2];
+
+Bounds();
+Bounds( const idVec3 &mins, const idVec3 &maxs );
+
+void    Clear();
+void    Zero();
+float   Radius();           // radius from origin, not from center
+idVec3  Center();
+void    AddPoint( const idVec3 &v );
+void    AddBounds( const Bounds &bb );
+bool    IsCleared();
+bool    ContainsPoint( const idVec3 &p );
+bool    IntersectsBounds( const Bounds &b2 );       // touching is NOT intersecting
+};
+
+extern Bounds boundsZero;
+
+ID_INLINE Bounds::Bounds(){
+}
+
+ID_INLINE bool Bounds::IsCleared() {
+       return b[0][0] > b[1][0];
+}
+
+ID_INLINE bool Bounds::ContainsPoint( const idVec3 &p ) {
+       if ( p[0] < b[0][0] || p[1] < b[0][1] || p[2] < b[0][2]
+                || p[0] > b[1][0] || p[1] > b[1][1] || p[2] > b[1][2] ) {
+               return false;
+       }
+       return true;
+}
+
+ID_INLINE bool Bounds::IntersectsBounds( const Bounds &b2 ) {
+       if ( b2.b[1][0] < b[0][0] || b2.b[1][1] < b[0][1] || b2.b[1][2] < b[0][2]
+                || b2.b[0][0] > b[1][0] || b2.b[0][1] > b[1][1] || b2.b[0][2] > b[1][2] ) {
+               return false;
+       }
+       return true;
+}
+
+ID_INLINE Bounds::Bounds( const idVec3 &mins, const idVec3 &maxs ) {
+       b[0] = mins;
+       b[1] = maxs;
+}
+
+ID_INLINE idVec3 Bounds::Center() {
+       return idVec3( ( b[1][0] + b[0][0] ) * 0.5f, ( b[1][1] + b[0][1] ) * 0.5f, ( b[1][2] + b[0][2] ) * 0.5f );
+}
+
+ID_INLINE void Bounds::Clear() {
+       b[0][0] = b[0][1] = b[0][2] = 99999;
+       b[1][0] = b[1][1] = b[1][2] = -99999;
+}
+
+ID_INLINE void Bounds::Zero() {
+       b[0][0] = b[0][1] = b[0][2] =
+                                                       b[1][0] = b[1][1] = b[1][2] = 0;
+}
+
+ID_INLINE void Bounds::AddPoint( const idVec3 &v ) {
+       if ( v[0] < b[0][0] ) {
+               b[0][0] = v[0];
+       }
+       if ( v[0] > b[1][0] ) {
+               b[1][0] = v[0];
+       }
+       if ( v[1] < b[0][1] ) {
+               b[0][1] = v[1];
+       }
+       if ( v[1] > b[1][1] ) {
+               b[1][1] = v[1];
+       }
+       if ( v[2] < b[0][2] ) {
+               b[0][2] = v[2];
+       }
+       if ( v[2] > b[1][2] ) {
+               b[1][2] = v[2];
+       }
+}
+
+
+ID_INLINE void Bounds::AddBounds( const Bounds &bb ) {
+       if ( bb.b[0][0] < b[0][0] ) {
+               b[0][0] = bb.b[0][0];
+       }
+       if ( bb.b[0][1] < b[0][1] ) {
+               b[0][1] = bb.b[0][1];
+       }
+       if ( bb.b[0][2] < b[0][2] ) {
+               b[0][2] = bb.b[0][2];
+       }
+
+       if ( bb.b[1][0] > b[1][0] ) {
+               b[1][0] = bb.b[1][0];
+       }
+       if ( bb.b[1][1] > b[1][1] ) {
+               b[1][1] = bb.b[1][1];
+       }
+       if ( bb.b[1][2] > b[1][2] ) {
+               b[1][2] = bb.b[1][2];
+       }
+}
+
+ID_INLINE float Bounds::Radius() {
+       int i;
+       float total;
+       float a, aa;
+
+       total = 0;
+       for ( i = 0 ; i < 3 ; i++ ) {
+               a = (float)fabs( b[0][i] );
+               aa = (float)fabs( b[1][i] );
+               if ( aa > a ) {
+                       a = aa;
+               }
+               total += a * a;
+       }
+
+       return (float)idSqrt( total );
+}
+
+//===============================================================
+
+
+class idVec2 {
+public:
+float x;
+float y;
+
+operator float *();
+float operator[]( int index ) const;
+float           &operator[]( int index );
+};
+
+ID_INLINE float idVec2::operator[]( int index ) const {
+       return ( &x )[ index ];
+}
+
+ID_INLINE float& idVec2::operator[]( int index ) {
+       return ( &x )[ index ];
+}
+
+ID_INLINE idVec2::operator float *( void ) {
+       return &x;
+}
+
+class idVec4 : public idVec3 {
+public:
+#ifndef FAT_VEC3
+float dist;
+#endif
+idVec4();
+~idVec4() {};
+
+idVec4( float x, float y, float z, float dist );
+float operator[]( int index ) const;
+float           &operator[]( int index );
+};
+
+ID_INLINE idVec4::idVec4() {}
+ID_INLINE idVec4::idVec4( float x, float y, float z, float dist ) {
+       this->x = x;
+       this->y = y;
+       this->z = z;
+       this->dist = dist;
+}
+
+ID_INLINE float idVec4::operator[]( int index ) const {
+       return ( &x )[ index ];
+}
+
+ID_INLINE float& idVec4::operator[]( int index ) {
+       return ( &x )[ index ];
+}
+
+
+class idVec5_t : public idVec3 {
+public:
+float s;
+float t;
+float operator[]( int index ) const;
+float           &operator[]( int index );
+};
+
+
+ID_INLINE float idVec5_t::operator[]( int index ) const {
+       return ( &x )[ index ];
+}
+
+ID_INLINE float& idVec5_t::operator[]( int index ) {
+       return ( &x )[ index ];
+}
+
+#endif /* !__MATH_VECTOR_H__ */