vecmath.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. //
  2. //
  3. // Typical 3d vector math code.
  4. // By S Melax 1998-2008
  5. //
  6. //
  7. #ifndef SM_VEC_MATH_H
  8. #define SM_VEC_MATH_H
  9. #include <stdio.h>
  10. #include <math.h>
  11. #include <assert.h>
  12. #include <xmmintrin.h>
  13. #define M_PIf (3.1415926535897932384626433832795f)
  14. inline float DegToRad(float angle_degrees) { return angle_degrees * M_PIf / 180.0f; } // returns Radians.
  15. inline float RadToDeg(float angle_radians) { return angle_radians * 180.0f / M_PIf; } // returns Degrees.
  16. #define OFFSET(Class,Member) (((char*) (&(((Class*)NULL)-> Member )))- ((char*)NULL))
  17. int argmin(const float a[],int n);
  18. int argmax(const float a[],int n);
  19. float squared(float a);
  20. float clamp(float a,const float minval=0.0f, const float maxval=1.0f);
  21. int clamp(int a,const int minval,const int maxval) ;
  22. float Round(float a,float precision);
  23. float Interpolate(const float &f0,const float &f1,float alpha) ;
  24. template <class T>
  25. void Swap(T &a,T &b)
  26. {
  27. T tmp = a;
  28. a=b;
  29. b=tmp;
  30. }
  31. template <class T>
  32. T Max(const T &a,const T &b)
  33. {
  34. return (a>b)?a:b;
  35. }
  36. template <class T>
  37. T Min(const T &a,const T &b)
  38. {
  39. return (a<b)?a:b;
  40. }
  41. //for template normalize functions:
  42. inline float squareroot(float a){return sqrtf(a);}
  43. inline double squareroot(double a){return sqrt(a); }
  44. //----------------------------------
  45. //-------- 2D --------
  46. template<class T>
  47. class vec2
  48. {
  49. public:
  50. T x,y;
  51. inline vec2(){x=0;y=0;}
  52. inline vec2(const T &_x, const T &_y){x=_x;y=_y;}
  53. inline T& operator[](int i) {return ((T*)this)[i];}
  54. inline const T& operator[](int i) const {return ((T*)this)[i];}
  55. };
  56. typedef vec2<int> int2;
  57. typedef vec2<float> float2;
  58. template<class T> inline int operator ==(const vec2<T> &a,const vec2<T> &b) {return (a.x==b.x && a.y==b.y);}
  59. template<class T> inline vec2<T> operator-( const vec2<T>& a, const vec2<T>& b ){return vec2<T>(a.x-b.x,a.y-b.y);}
  60. template<class T> inline vec2<T> operator+( const vec2<T>& a, const vec2<T>& b ){return float2(a.x+b.x,a.y+b.y);}
  61. //--------- 3D ---------
  62. template<class T>
  63. class vec3
  64. {
  65. public:
  66. T x,y,z;
  67. inline vec3(){x=0;y=0;z=0;};
  68. inline vec3(const T &_x,const T &_y,const T &_z){x=_x;y=_y;z=_z;};
  69. inline T& operator[](int i) {return ((T*)this)[i];}
  70. inline const T& operator[](int i) const {return ((T*)this)[i];}
  71. };
  72. typedef vec3<int> int3;
  73. typedef vec3<short> short3;
  74. typedef vec3<float> float3;
  75. // due to ambiguity there is no overloaded operators for v3*v3 use dot,cross,outerprod,cmul
  76. template<class T> inline int operator==(const vec3<T> &a,const vec3<T> &b) {return (a.x==b.x && a.y==b.y && a.z==b.z);}
  77. template<class T> inline int operator!=(const vec3<T> &a,const vec3<T> &b) {return !(a==b);}
  78. template<class T> inline vec3<T> operator+(const vec3<T>& a, const vec3<T>& b ){return vec3<T>(a.x+b.x, a.y+b.y, a.z+b.z);}
  79. template<class T> inline vec3<T> operator-(const vec3<T>& a, const vec3<T>& b ){return vec3<T>(a.x-b.x, a.y-b.y, a.z-b.z);}
  80. template<class T> inline vec3<T> operator-(const vec3<T>& v){return vec3<T>(-v.x,-v.y,-v.z );}
  81. template<class T> inline vec3<T> operator*(const vec3<T>& v, const T &s ){ return vec3<T>( v.x*s, v.y*s, v.z*s );}
  82. template<class T> inline vec3<T> operator*(T s, const vec3<T>& v ){return v*s;}
  83. template<class T> inline vec3<T> operator/(const vec3<T>& v, T s ){return vec3<T>( v.x/s, v.y/s, v.z/s );}
  84. template<class T> inline T dot (const vec3<T>& a, const vec3<T>& b){return a.x*b.x + a.y*b.y + a.z*b.z;}
  85. template<class T> inline vec3<T> cmul (const vec3<T>& a, const vec3<T>& b){return vec3<T>(a.x*b.x, a.y*b.y, a.z*b.z);}
  86. template<class T> inline vec3<T> cross(const vec3<T>& a, const vec3<T>& b){return vec3<T>(a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x);}
  87. template<class T> inline T magnitude( const vec3<T>& v ){return squareroot(dot(v,v));}
  88. template<class T> inline vec3<T> normalize( const vec3<T>& v ){return v/magnitude(v);}
  89. template<class T> inline vec3<T>& operator+=(vec3<T>& a, const vec3<T>& b){a.x+=b.x;a.y+=b.y;a.z+=b.z;return a;}
  90. template<class T> inline vec3<T>& operator-=(vec3<T>& a, const vec3<T>& b){a.x-=b.x;a.y-=b.y;a.z-=b.z;return a;}
  91. template<class T> inline vec3<T>& operator*=(vec3<T>& v, T s){v.x*=s;v.y*=s;v.z*= s;return v;}
  92. template<class T> inline vec3<T>& operator/=(vec3<T>& v, T s){v.x/=s;v.y/=s;v.z/=s;return v;}
  93. float3 safenormalize(const float3 &v);
  94. float3 vabs(const float3 &v);
  95. float3 Interpolate(const float3 &v0,const float3 &v1,float alpha);
  96. float3 Round(const float3& a,float precision);
  97. template<class T> inline vec3<T>VectorMin(const vec3<T> &a,const vec3<T> &b) {return vec3<T>(Min(a.x,b.x),Min(a.y,b.y),Min(a.z,b.z));}
  98. template<class T> inline vec3<T>VectorMax(const vec3<T> &a,const vec3<T> &b) {return vec3<T>(Max(a.x,b.x),Max(a.y,b.y),Max(a.z,b.z));}
  99. int overlap(const float3 &bmina,const float3 &bmaxa,const float3 &bminb,const float3 &bmaxb);
  100. template <class T>
  101. class mat3x3
  102. {
  103. public:
  104. vec3<T> x,y,z; // the 3 rows of the Matrix
  105. inline mat3x3(){}
  106. inline mat3x3(const T &xx,const T &xy,const T &xz,const T &yx,const T &yy,const T &yz,const T &zx,const T &zy,const T &zz):x(xx,xy,xz),y(yx,yy,yz),z(zx,zy,zz){}
  107. inline mat3x3(const vec3<T> &_x,const vec3<T> &_y,const vec3<T> &_z):x(_x),y(_y),z(_z){}
  108. inline vec3<T>& operator[](int i) {return (&x)[i];}
  109. inline const vec3<T>& operator[](int i) const {return (&x)[i];}
  110. inline T& operator()(int r, int c) {return ((&x)[r])[c];}
  111. inline const T& operator()(int r, int c) const {return ((&x)[r])[c];}
  112. };
  113. typedef mat3x3<float> float3x3;
  114. float3x3 Transpose( const float3x3& m );
  115. template<class T> vec3<T> operator*( const vec3<T>& v , const mat3x3<T>& m )
  116. {
  117. return vec3<T>((m.x.x*v.x + m.y.x*v.y + m.z.x*v.z),
  118. (m.x.y*v.x + m.y.y*v.y + m.z.y*v.z),
  119. (m.x.z*v.x + m.y.z*v.y + m.z.z*v.z));
  120. }
  121. float3 operator*( const float3x3& m , const float3& v );
  122. float3x3 operator*( const float3x3& m , const float& s );
  123. float3x3 operator*( const float3x3& ma, const float3x3& mb );
  124. float3x3 operator/( const float3x3& a, const float& s ) ;
  125. float3x3 operator+( const float3x3& a, const float3x3& b );
  126. float3x3 operator-( const float3x3& a, const float3x3& b );
  127. float3x3 &operator+=( float3x3& a, const float3x3& b );
  128. float3x3 &operator-=( float3x3& a, const float3x3& b );
  129. float3x3 &operator*=( float3x3& a, const float& s );
  130. float Determinant(const float3x3& m );
  131. float3x3 Inverse(const float3x3& a); // its just 3x3 so we simply do that cofactor method
  132. float3x3 outerprod(const float3& a,const float3& b);
  133. //-------- 4D Math --------
  134. template<class T>
  135. class vec4
  136. {
  137. public:
  138. T x,y,z,w;
  139. inline vec4(){x=0;y=0;z=0;w=0;};
  140. inline vec4(const T &_x, const T &_y, const T &_z, const T &_w){x=_x;y=_y;z=_z;w=_w;}
  141. inline vec4(const vec3<T> &v,const T &_w){x=v.x;y=v.y;z=v.z;w=_w;}
  142. //operator float *() { return &x;};
  143. T& operator[](int i) {return ((T*)this)[i];}
  144. const T& operator[](int i) const {return ((T*)this)[i];}
  145. inline const vec3<T>& xyz() const { return *((vec3<T>*)this);}
  146. inline vec3<T>& xyz() { return *((vec3<T>*)this);}
  147. };
  148. typedef vec4<float> float4;
  149. typedef vec4<int> int4;
  150. typedef vec4<unsigned char> byte4;
  151. template<class T> inline int operator==(const vec4<T> &a,const vec4<T> &b) {return (a.x==b.x && a.y==b.y && a.z==b.z && a.w==b.w);}
  152. template<class T> inline int operator!=(const vec4<T> &a,const vec4<T> &b) {return !(a==b);}
  153. template<class T> inline vec4<T> operator+(const vec4<T>& a, const vec4<T>& b ){return vec4<T>(a.x+b.x,a.y+b.y,a.z+b.z,a.w+b.w);}
  154. template<class T> inline vec4<T> operator-(const vec4<T>& a, const vec4<T>& b ){return vec4<T>(a.x-b.x,a.y-b.y,a.z-b.z,a.w-b.w);}
  155. template<class T> inline vec4<T> operator-(const vec4<T>& v){return vec4<T>(-v.x,-v.y,-v.z,-v.w);}
  156. template<class T> inline vec4<T> operator*(const vec4<T>& v, const T &s ){ return vec4<T>( v.x*s, v.y*s, v.z*s,v.w*s);}
  157. template<class T> inline vec4<T> operator*(T s, const vec4<T>& v ){return v*s;}
  158. template<class T> inline vec4<T> operator/(const vec4<T>& v, T s ){return vec4<T>( v.x/s, v.y/s, v.z/s,v.w/s );}
  159. template<class T> inline T dot(const vec4<T>& a, const vec4<T>& b ){return a.x*b.x + a.y*b.y + a.z*b.z+a.w*b.w;}
  160. template<class T> inline vec4<T> cmul(const vec4<T> &a, const vec4<T> &b) {return vec4<T>(a.x*b.x, a.y*b.y, a.z*b.z,a.w*b.w);}
  161. template<class T> inline vec4<T>& operator+=(vec4<T>& a, const vec4<T>& b ){a.x+=b.x;a.y+=b.y;a.z+=b.z;a.w+=b.w;return a;}
  162. template<class T> inline vec4<T>& operator-=(vec4<T>& a, const vec4<T>& b ){a.x-=b.x;a.y-=b.y;a.z-=b.z;a.w-=b.w;return a;}
  163. template<class T> inline vec4<T>& operator*=(vec4<T>& v, T s){v.x*=s;v.y*=s;v.z*=s;v.w*=s;return v;}
  164. template<class T> inline vec4<T>& operator/=(vec4<T>& v, T s){v.x/=s;v.y/=s;v.z/=s;v.w/=s;return v;}
  165. template<class T> inline T magnitude( const vec4<T>& v ){return squareroot(dot(v,v));}
  166. template<class T> inline vec4<T> normalize( const vec4<T>& v ){return v/magnitude(v);}
  167. struct D3DXMATRIX;
  168. template<class T>
  169. class mat4x4
  170. {
  171. public:
  172. vec4<T> x,y,z,w; // the 4 rows
  173. inline mat4x4(){}
  174. inline mat4x4(const vec4<T> &_x, const vec4<T> &_y, const vec4<T> &_z, const vec4<T> &_w):x(_x),y(_y),z(_z),w(_w){}
  175. inline mat4x4(const T& m00, const T& m01, const T& m02, const T& m03,
  176. const T& m10, const T& m11, const T& m12, const T& m13,
  177. const T& m20, const T& m21, const T& m22, const T& m23,
  178. const T& m30, const T& m31, const T& m32, const T& m33 )
  179. :x(m00,m01,m02,m03),y(m10,m11,m12,m13),z(m20,m21,m22,m23),w(m30,m31,m32,m33){}
  180. inline vec4<T>& operator[](int i) {assert(i>=0&&i<4);return (&x)[i];}
  181. inline const vec4<T>& operator[](int i) const {assert(i>=0&&i<4);return (&x)[i];}
  182. inline T& operator()(int r, int c) {assert(r>=0&&r<4&&c>=0&&c<4);return ((&x)[r])[c];}
  183. inline const T& operator()(int r, int c) const {assert(r>=0&&r<4&&c>=0&&c<4);return ((&x)[r])[c];}
  184. inline operator T* () {return &x.x;}
  185. inline operator const T* () const {return &x.x;}
  186. operator struct D3DXMATRIX* () { return (struct D3DXMATRIX*) this;}
  187. operator const struct D3DXMATRIX* () const { return (struct D3DXMATRIX*) this;}
  188. };
  189. typedef mat4x4<float> float4x4;
  190. float4x4 operator*( const float4x4& a, const float4x4& b );
  191. float4 operator*( const float4& v, const float4x4& m );
  192. float4x4 Inverse(const float4x4 &m);
  193. float4x4 MatrixRigidInverse(const float4x4 &m);
  194. float4x4 MatrixTranspose(const float4x4 &m);
  195. float4x4 MatrixPerspectiveFov(float fovy, float Aspect, float zn, float zf );
  196. float4x4 MatrixTranslation(const float3 &t);
  197. float4x4 MatrixRotationZ(const float angle_radians);
  198. float4x4 MatrixLookAt(const float3& eye, const float3& at, const float3& up);
  199. int operator==( const float4x4 &a, const float4x4 &b );
  200. //-------- Quaternion ------------
  201. template<class T>
  202. class quaternion : public vec4<T>
  203. {
  204. public:
  205. inline quaternion() { this->x = this->y = this->z = 0.0f; this->w = 1.0f; }
  206. inline quaternion(const T &_x, const T &_y, const T &_z, const T &_w){this->x=_x;this->y=_y;this->z=_z;this->w=_w;}
  207. inline explicit quaternion(const vec4<T> &v):vec4<T>(v){}
  208. T angle() const { return acosf(this->w)*2.0f; }
  209. vec3<T> axis() const { vec3<T> a(this->x,this->y,this->z); if(fabsf(angle())<0.0000001f) return vec3<T>(1,0,0); return a*(1/sinf(angle()/2.0f)); }
  210. inline vec3<T> xdir() const { return vec3<T>( 1-2*(this->y*this->y+this->z*this->z), 2*(this->x*this->y+this->w*this->z),
  211. 2*(this->x*this->z-this->w*this->y) ); }
  212. inline vec3<T> ydir() const { return vec3<T>( 2*(this->x*this->y-this->w*this->z),1-2*(this->x*this->x+this->z*this->z), 2*(this->y*this->z+this->w*this->x) ); }
  213. inline vec3<T> zdir() const { return vec3<T>( 2*(this->x*this->z+this->w*this->y),
  214. 2*(this->y*this->z-this->w*this->x),1-
  215. 2*(this->x*this->x+this->y*this->y) ); }
  216. inline mat3x3<T> getmatrix() const { return mat3x3<T>( xdir(), ydir(), zdir() ); }
  217. //operator float3x3() { return getmatrix(); }
  218. void Normalize();
  219. };
  220. template<class T>
  221. inline quaternion<T> quatfrommat(const mat3x3<T> &m)
  222. {
  223. T magw = m[0 ][ 0] + m[1 ][ 1] + m[2 ][ 2];
  224. T magxy;
  225. T magzw;
  226. vec3<T> pre;
  227. vec3<T> prexy;
  228. vec3<T> prezw;
  229. quaternion<T> postxy;
  230. quaternion<T> postzw;
  231. quaternion<T> post;
  232. int wvsz = (magw > m[2][2] ) ;
  233. magzw = (wvsz) ? magw : m[2][2];
  234. prezw = (wvsz) ? vec3<T>(1.0f,1.0f,1.0f) : vec3<T>(-1.0f,-1.0f,1.0f) ;
  235. postzw = (wvsz) ? quaternion<T>(0.0f,0.0f,0.0f,1.0f): quaternion<T>(0.0f,0.0f,1.0f,0.0f);
  236. int xvsy = (m[0][0]>m[1][1]);
  237. magxy = (xvsy) ? m[0][0] : m[1][1];
  238. prexy = (xvsy) ? vec3<T>(1.0f,-1.0f,-1.0f) : vec3<T>(-1.0f,1.0f,-1.0f) ;
  239. postxy = (xvsy) ? quaternion<T>(1.0f,0.0f,0.0f,0.0f): quaternion<T>(0.0f,1.0f,0.0f,0.0f);
  240. int zwvsxy = (magzw > magxy);
  241. pre = (zwvsxy) ? prezw : prexy ;
  242. post = (zwvsxy) ? postzw : postxy;
  243. T t = pre.x * m[0 ][ 0] + pre.y * m[1 ][ 1] + pre.z * m[2 ][ 2] + 1.0f;
  244. T s = 1/sqrt(t) * 0.5f;
  245. quaternion<T> qp;
  246. qp.x = ( pre.y * m[1][2] - pre.z * m[2][1] ) * s;
  247. qp.y = ( pre.z * m[2][0] - pre.x * m[0][2] ) * s;
  248. qp.z = ( pre.x * m[0][1] - pre.y * m[1][0] ) * s;
  249. qp.w = t * s ;
  250. return qp * post ;
  251. }
  252. typedef quaternion<float> Quaternion;
  253. inline Quaternion QuatFromAxisAngle(const float3 &_v, float angle_radians )
  254. {
  255. float3 v = normalize(_v)*sinf(angle_radians/2.0f);
  256. return Quaternion(v.x,v.y,v.z,cosf(angle_radians/2.0f));
  257. }
  258. template<class T> inline quaternion<T> Conjugate(const quaternion<T> &q){return quaternion<T>(-q.x,-q.y,-q.z,q.w);}
  259. template<class T> inline quaternion<T> Inverse(const quaternion<T> &q){return Conjugate(q);}
  260. template<class T> inline quaternion<T> normalize( const quaternion<T> & a ){return quaternion<T> (normalize((vec4<T>&)a));}
  261. template<class T> inline quaternion<T>& operator*=(quaternion<T>& a, T s ){return (quaternion<T>&)((vec4<T>&)a *=s);}
  262. template<class T> inline quaternion<T> operator*( const quaternion<T>& a, float s ){return quaternion<T>((vec4<T>&)a*s);}
  263. template<class T> inline quaternion<T> operator+( const quaternion<T>& a, const quaternion<T>& b){return quaternion<T>((vec4<T>&)a+(vec4<T>&)b);}
  264. template<class T> inline quaternion<T> operator-( const quaternion<T>& a, const quaternion<T>& b){return quaternion<T>((vec4<T>&)a-(vec4<T>&)b);}
  265. template<class T> inline quaternion<T> operator-( const quaternion<T>& b){return quaternion<T>(-(vec4<T>&)b);}
  266. template<class T> inline quaternion<T> operator*( const quaternion<T>& a, const quaternion<T>& b)
  267. {
  268. return quaternion<T>(
  269. a.w*b.x + a.x*b.w + a.y*b.z - a.z*b.y, //x
  270. a.w*b.y - a.x*b.z + a.y*b.w + a.z*b.x, //y
  271. a.w*b.z + a.x*b.y - a.y*b.x + a.z*b.w, //z
  272. a.w*b.w - a.x*b.x - a.y*b.y - a.z*b.z ); //w
  273. }
  274. float3 rotate( const Quaternion& q, const float3& v );
  275. //float3 operator*( const Quaternion& q, const float3& v );
  276. //float3 operator*( const float3& v, const Quaternion& q );
  277. Quaternion slerp(const Quaternion &a, const Quaternion& b, float t );
  278. Quaternion Interpolate(const Quaternion &q0,const Quaternion &q1,float t);
  279. Quaternion RotationArc(float3 v0, float3 v1 ); // returns quat q where q*v0*q^-1=v1
  280. float4x4 MatrixFromQuatVec(const Quaternion &q, const float3 &v);
  281. inline Quaternion QuatFromMat(const float3 &t, const float3 &b, const float3 &n)
  282. {
  283. return normalize(quatfrommat<float>(float3x3(t,b,n)));
  284. }
  285. //---------------- Pose ------------------
  286. class Pose
  287. {
  288. public:
  289. float3 position;
  290. Quaternion orientation;
  291. Pose(){}
  292. Pose(const float3 &p,const Quaternion &q):position(p),orientation(q){}
  293. Pose &pose(){return *this;}
  294. const Pose &pose() const {return *this;}
  295. };
  296. inline float3 operator*(const Pose &a,const float3 &v)
  297. {
  298. return a.position + rotate(a.orientation,v);
  299. }
  300. inline Pose operator*(const Pose &a,const Pose &b)
  301. {
  302. return Pose(a.position + rotate(a.orientation,b.position),a.orientation*b.orientation);
  303. }
  304. inline Pose Inverse(const Pose &a)
  305. {
  306. Quaternion q = Inverse(a.orientation);
  307. return Pose(rotate(q,-a.position),q);
  308. }
  309. inline Pose slerp(const Pose &p0,const Pose &p1,float t)
  310. {
  311. return Pose(p0.position * (1.0f-t) + p1.position * t,slerp(p0.orientation,p1.orientation,t));
  312. }
  313. inline float4x4 MatrixFromPose(const Pose &pose)
  314. {
  315. return MatrixFromQuatVec(pose.orientation,pose.position);
  316. }
  317. //------ Euler Angle -----
  318. Quaternion YawPitchRoll( float yaw, float pitch, float roll );
  319. float Yaw( const Quaternion& q );
  320. float Pitch( const Quaternion& q );
  321. float Roll( const Quaternion &q );
  322. float Yaw( const float3& v );
  323. float Pitch( const float3& v );
  324. //------- Plane ----------
  325. class Plane : public float4
  326. {
  327. public:
  328. float3& normal(){ return xyz(); }
  329. const float3& normal() const { return xyz(); }
  330. float& dist(){return w;} // distance below origin - the D from plane equasion Ax+By+Cz+D=0
  331. const float& dist() const{return w;} // distance below origin - the D from plane equasion Ax+By+Cz+D=0
  332. Plane(const float3 &n,float d):float4(n,d){}
  333. Plane(){dist()=0;}
  334. explicit Plane(const float4 &v):float4(v){}
  335. };
  336. Plane Transform(const Plane &p, const float3 &translation, const Quaternion &rotation);
  337. inline Plane PlaneFlip(const Plane &p){return Plane(-p.normal(),-p.dist());}
  338. inline int operator==( const Plane &a, const Plane &b ) { return (a.normal()==b.normal() && a.dist()==b.dist()); }
  339. inline int coplanar( const Plane &a, const Plane &b ) { return (a==b || a==PlaneFlip(b)); }
  340. float3 PlaneLineIntersection(const Plane &plane, const float3 &p0, const float3 &p1);
  341. float3 PlaneProject(const Plane &plane, const float3 &point);
  342. float3 PlanesIntersection(const Plane &p0,const Plane &p1, const Plane &p2);
  343. float3 PlanesIntersection(const Plane *planes,int planes_count,const float3 &seed=float3(0,0,0));
  344. int Clip(const Plane &p,const float3 *verts_in,int count,float* verts_out); // verts_out must be preallocated with sufficient size >= count+1 or more if concave
  345. int ClipPolyPoly(const float3 &normal,const float3 *clipper,int clipper_count,const float3 *verts_in, int in_count,float3 *scratch); //scratch must be preallocated
  346. //--------- Utility Functions ------
  347. float3 PlaneLineIntersection(const float3 &normal,const float dist, const float3 &p0, const float3 &p1);
  348. float3 LineProject(const float3 &p0, const float3 &p1, const float3 &a); // projects a onto infinite line p0p1
  349. float LineProjectTime(const float3 &p0, const float3 &p1, const float3 &a);
  350. int BoxInside(const float3 &p,const float3 &bmin, const float3 &bmax) ;
  351. int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const float3 &bmax, float3 *impact);
  352. float DistanceBetweenLines(const float3 &ustart, const float3 &udir, const float3 &vstart, const float3 &vdir, float3 *upoint=NULL, float3 *vpoint=NULL);
  353. float3 TriNormal(const float3 &v0, const float3 &v1, const float3 &v2);
  354. float3 NormalOf(const float3 *vert, const int n);
  355. Quaternion VirtualTrackBall(const float3 &cop, const float3 &cor, const float3 &dir0, const float3 &dir1);
  356. int Clip(const float3 &plane_normal,float plane_dist,const float3 *verts_in,int count,float* verts_out); // verts_out must be preallocated with sufficient size >= count+1 or more if concave
  357. int ClipPolyPoly(const float3 &normal,const float3 *clipper,int clipper_count,const float3 *verts_in, int in_count,float3 *scratch); //scratch must be preallocated
  358. float3 Diagonal(const float3x3 &M);
  359. Quaternion Diagonalizer(const float3x3 &A);
  360. float3 Orth(const float3& v);
  361. int SolveQuadratic(float a,float b,float c,float *ta,float *tb); // if true returns roots ta,tb where ta<=tb
  362. int HitCheckPoly(const float3 *vert,const int n,const float3 &v0, const float3 &v1, float3 *impact=NULL, float3 *normal=NULL);
  363. int HitCheckRaySphere(const float3& sphereposition,float radius, const float3& _v0, const float3& _v1, float3 *impact,float3 *normal);
  364. int HitCheckRayCylinder(const float3 &p0,const float3 &p1,float radius,const float3& _v0,const float3& _v1, float3 *impact,float3 *normal);
  365. int HitCheckSweptSphereTri(const float3 &p0,const float3 &p1,const float3 &p2,float radius, const float3& v0,const float3& _v1, float3 *impact,float3 *normal);
  366. void BoxLimits(const float3 *verts,int verts_count, float3 &bmin_out,float3 &bmax_out);
  367. void BoxLimits(const float4 *verts,int verts_count, float3 &bmin_out,float3 &bmax_out);
  368. template<class T>
  369. inline int maxdir(const T *p,int count,const T &dir)
  370. {
  371. assert(count);
  372. int m=0;
  373. for(int i=1;i<count;i++)
  374. {
  375. if(dot(p[i],dir)>dot(p[m],dir)) m=i;
  376. }
  377. return m;
  378. }
  379. float3 CenterOfMass(const float3 *vertices, const int3 *tris, const int count) ;
  380. float3x3 Inertia(const float3 *vertices, const int3 *tris, const int count, const float3& com=float3(0,0,0)) ;
  381. float Volume(const float3 *vertices, const int3 *tris, const int count) ;
  382. int calchull(float3 *verts,int verts_count, int3 *&tris_out, int &tris_count,int vlimit); // computes convex hull see hull.cpp
  383. #endif // VEC_MATH_H