glh_linear.h 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536
  1. /*
  2. glh - is a platform-indepenedent C++ OpenGL helper library
  3. Copyright (c) 2000 Cass Everitt
  4. Copyright (c) 2000 NVIDIA Corporation
  5. All rights reserved.
  6. Redistribution and use in source and binary forms, with or
  7. without modification, are permitted provided that the following
  8. conditions are met:
  9. * Redistributions of source code must retain the above
  10. copyright notice, this list of conditions and the following
  11. disclaimer.
  12. * Redistributions in binary form must reproduce the above
  13. copyright notice, this list of conditions and the following
  14. disclaimer in the documentation and/or other materials
  15. provided with the distribution.
  16. * The names of contributors to this software may not be used
  17. to endorse or promote products derived from this software
  18. without specific prior written permission.
  19. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  27. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  29. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30. POSSIBILITY OF SUCH DAMAGE.
  31. Cass Everitt - [email protected]
  32. */
  33. /*
  34. glh_linear.h
  35. */
  36. // Author: Cass W. Everitt
  37. #ifndef GLH_LINEAR_H
  38. #define GLH_LINEAR_H
  39. #include "llpreprocessor.h" // LL_INLINE
  40. #include "stdtypes.h" // F32 etc
  41. #include <memory.h>
  42. #include <math.h>
  43. #include <assert.h>
  44. // Only supports float for now...
  45. #define GLH_REAL_IS_FLOAT
  46. #ifdef GLH_REAL_IS_FLOAT
  47. # define GLH_REAL F32
  48. # define GLH_REAL_NAMESPACE ns_float
  49. #endif
  50. #define GLH_QUATERNION_NORMALIZATION_THRESHOLD 64
  51. #define GLH_RAD_TO_DEG GLH_REAL(57.2957795130823208767981548141052)
  52. #define GLH_DEG_TO_RAD GLH_REAL(0.0174532925199432957692369076848861)
  53. #define GLH_ZERO GLH_REAL(0.0)
  54. #define GLH_ONE GLH_REAL(1.0)
  55. #define GLH_TWO GLH_REAL(2.0)
  56. #define GLH_EPSILON GLH_REAL(10e-6)
  57. #define GLH_PI GLH_REAL(3.1415926535897932384626433832795)
  58. namespace glh
  59. {
  60. template <typename Ta, typename Tb>
  61. LL_INLINE bool equivalent(Ta a, Tb b)
  62. {
  63. return a < b + GLH_EPSILON && a > b - GLH_EPSILON;
  64. }
  65. LL_INLINE GLH_REAL to_degrees(GLH_REAL radians) { return radians * GLH_RAD_TO_DEG; }
  66. LL_INLINE GLH_REAL to_radians(GLH_REAL degrees) { return degrees * GLH_DEG_TO_RAD; }
  67. // forward declarations for friend template functions.
  68. template <int N, class T> class vec;
  69. // forward declarations for friend template functions.
  70. template <int N, class T>
  71. bool operator == (const vec<N,T> & v1, const vec<N,T> & v2);
  72. // forward declarations for friend template functions.
  73. template <int N, class T>
  74. bool operator != (const vec<N,T> & v1, const vec<N,T> & v2);
  75. template <int N, class T>
  76. class vec
  77. {
  78. public:
  79. int size() const { return N; }
  80. vec(const T & t = T())
  81. { for(int i = 0; i < N; i++) v[i] = t; }
  82. vec(const T * tp)
  83. { for(int i = 0; i < N; i++) v[i] = tp[i]; }
  84. const T * get_value() const
  85. { return v; }
  86. T dot(const vec<N,T> & rhs) const
  87. {
  88. T r = 0;
  89. for(int i = 0; i < N; i++) r += v[i]*rhs.v[i];
  90. return r;
  91. }
  92. T length() const
  93. {
  94. T r = 0;
  95. for(int i = 0; i < N; i++) r += v[i]*v[i];
  96. return T(sqrt(r));
  97. }
  98. T square_norm() const
  99. {
  100. T r = 0;
  101. for(int i = 0; i < N; i++) r += v[i]*v[i];
  102. return r;
  103. }
  104. void negate()
  105. { for(int i = 0; i < N; i++) v[i] = -v[i]; }
  106. T normalize()
  107. {
  108. T sum(0);
  109. for(int i = 0; i < N; i++)
  110. sum += v[i]*v[i];
  111. sum = T(sqrt(sum));
  112. if (sum > GLH_EPSILON)
  113. for(int i = 0; i < N; i++)
  114. v[i] /= sum;
  115. return sum;
  116. }
  117. vec<N,T> & set_value(const T * rhs)
  118. { for(int i = 0; i < N; i++) v[i] = rhs[i]; return *this; }
  119. T & operator [] (int i)
  120. { return v[i]; }
  121. const T & operator [] (int i) const
  122. { return v[i]; }
  123. vec<N,T> & operator *= (T d)
  124. { for(int i = 0; i < N; i++) v[i] *= d; return *this;}
  125. vec<N,T> & operator *= (const vec<N,T> & u)
  126. { for(int i = 0; i < N; i++) v[i] *= u[i]; return *this;}
  127. vec<N,T> & operator /= (T d)
  128. { if(d == 0) return *this; for(int i = 0; i < N; i++) v[i] /= d; return *this;}
  129. vec<N,T> & operator += (const vec<N,T> & u)
  130. { for(int i = 0; i < N; i++) v[i] += u.v[i]; return *this;}
  131. vec<N,T> & operator -= (const vec<N,T> & u)
  132. { for(int i = 0; i < N; i++) v[i] -= u.v[i]; return *this;}
  133. vec<N,T> operator - () const
  134. { vec<N,T> rv = v; rv.negate(); return rv; }
  135. vec<N,T> operator + (const vec<N,T> &v) const
  136. { vec<N,T> rt(*this); return rt += v; }
  137. vec<N,T> operator - (const vec<N,T> &v) const
  138. { vec<N,T> rt(*this); return rt -= v; }
  139. vec<N,T> operator * (T d) const
  140. { vec<N,T> rt(*this); return rt *= d; }
  141. friend bool operator == <> (const vec<N,T> &v1, const vec<N,T> &v2);
  142. friend bool operator != <> (const vec<N,T> &v1, const vec<N,T> &v2);
  143. //protected:
  144. T v[N];
  145. };
  146. // vector friend operators
  147. template <int N, class T> LL_INLINE
  148. vec<N,T> operator * (const vec<N,T> & b, T d)
  149. {
  150. vec<N,T> rt(b);
  151. return rt *= d;
  152. }
  153. template <int N, class T> LL_INLINE
  154. vec<N,T> operator * (T d, const vec<N,T> & b)
  155. { return b*d; }
  156. template <int N, class T> LL_INLINE
  157. vec<N,T> operator * (const vec<N,T> & b, const vec<N,T> & d)
  158. {
  159. vec<N,T> rt(b);
  160. return rt *= d;
  161. }
  162. template <int N, class T> LL_INLINE
  163. vec<N,T> operator / (const vec<N,T> & b, T d)
  164. { vec<N,T> rt(b); return rt /= d; }
  165. template <int N, class T> LL_INLINE
  166. vec<N,T> operator + (const vec<N,T> & v1, const vec<N,T> & v2)
  167. { vec<N,T> rt(v1); return rt += v2; }
  168. template <int N, class T> LL_INLINE
  169. vec<N,T> operator - (const vec<N,T> & v1, const vec<N,T> & v2)
  170. { vec<N,T> rt(v1); return rt -= v2; }
  171. template <int N, class T> LL_INLINE
  172. bool operator == (const vec<N,T> & v1, const vec<N,T> & v2)
  173. {
  174. for(int i = 0; i < N; i++)
  175. if(v1.v[i] != v2.v[i]) return false;
  176. return true;
  177. }
  178. template <int N, class T> LL_INLINE
  179. bool operator != (const vec<N,T> & v1, const vec<N,T> & v2)
  180. { return !(v1 == v2); }
  181. typedef vec<3,unsigned char> vec3ub;
  182. typedef vec<4,unsigned char> vec4ub;
  183. namespace GLH_REAL_NAMESPACE
  184. {
  185. typedef GLH_REAL real;
  186. class line;
  187. class plane;
  188. class matrix4;
  189. class quaternion;
  190. typedef quaternion rotation;
  191. class vec2 : public vec<2,real>
  192. {
  193. public:
  194. vec2(const real & t = real()) : vec<2,real>(t)
  195. {}
  196. vec2(const vec<2,real> & t) : vec<2,real>(t)
  197. {}
  198. vec2(const real * tp) : vec<2,real>(tp)
  199. {}
  200. vec2(real x, real y)
  201. { v[0] = x; v[1] = y; }
  202. void get_value(real & x, real & y) const
  203. { x = v[0]; y = v[1]; }
  204. vec2 & set_value(const real & x, const real & y)
  205. { v[0] = x; v[1] = y; return *this; }
  206. };
  207. class vec3 : public vec<3,real>
  208. {
  209. public:
  210. vec3(const real & t = real()) : vec<3,real>(t)
  211. {}
  212. vec3(const vec<3,real> & t) : vec<3,real>(t)
  213. {}
  214. vec3(const real * tp) : vec<3,real>(tp)
  215. {}
  216. vec3(real x, real y, real z)
  217. { v[0] = x; v[1] = y; v[2] = z; }
  218. void get_value(real & x, real & y, real & z) const
  219. { x = v[0]; y = v[1]; z = v[2]; }
  220. vec3 cross(const vec3 &rhs) const
  221. {
  222. vec3 rt;
  223. rt.v[0] = v[1]*rhs.v[2]-v[2]*rhs.v[1];
  224. rt.v[1] = v[2]*rhs.v[0]-v[0]*rhs.v[2];
  225. rt.v[2] = v[0]*rhs.v[1]-v[1]*rhs.v[0];
  226. return rt;
  227. }
  228. vec3 & set_value(const real & x, const real & y, const real & z)
  229. { v[0] = x; v[1] = y; v[2] = z; return *this; }
  230. };
  231. class vec4 : public vec<4,real>
  232. {
  233. public:
  234. vec4(const real & t = real()) : vec<4,real>(t)
  235. {}
  236. vec4(const vec<4,real> & t) : vec<4,real>(t)
  237. {}
  238. vec4(const vec<3,real> & t, real fourth)
  239. { v[0] = t.v[0]; v[1] = t.v[1]; v[2] = t.v[2]; v[3] = fourth; }
  240. vec4(const real * tp) : vec<4,real>(tp)
  241. {}
  242. vec4(real x, real y, real z, real w)
  243. { v[0] = x; v[1] = y; v[2] = z; v[3] = w; }
  244. void get_value(real & x, real & y, real & z, real & w) const
  245. { x = v[0]; y = v[1]; z = v[2]; w = v[3]; }
  246. vec4 & set_value(const real & x, const real & y, const real & z, const real & w)
  247. { v[0] = x; v[1] = y; v[2] = z; v[3] = w; return *this; }
  248. };
  249. LL_INLINE
  250. vec3 homogenize(const vec4 & v)
  251. {
  252. vec3 rt;
  253. assert(v.v[3] != GLH_ZERO);
  254. rt.v[0] = v.v[0]/v.v[3];
  255. rt.v[1] = v.v[1]/v.v[3];
  256. rt.v[2] = v.v[2]/v.v[3];
  257. return rt;
  258. }
  259. class line
  260. {
  261. public:
  262. line()
  263. { set_value(vec3(0,0,0),vec3(0,0,1)); }
  264. line(const vec3 & p0, const vec3 &p1)
  265. { set_value(p0,p1); }
  266. void set_value(const vec3 &p0, const vec3 &p1)
  267. {
  268. position = p0;
  269. direction = p1-p0;
  270. direction.normalize();
  271. }
  272. bool get_closest_points(const line &line2,
  273. vec3 &pointOnThis,
  274. vec3 &pointOnThat)
  275. {
  276. // quick check to see if parallel -- if so, quit.
  277. if(fabs(direction.dot(line2.direction)) == 1.0)
  278. return 0;
  279. line l2 = line2;
  280. // Algorithm: Brian Jean
  281. //
  282. real u;
  283. real v;
  284. vec3 Vr = direction;
  285. vec3 Vs = l2.direction;
  286. real Vr_Dot_Vs = Vr.dot(Vs);
  287. real detA = real(1.0 - (Vr_Dot_Vs * Vr_Dot_Vs));
  288. vec3 C = l2.position - position;
  289. real C_Dot_Vr = C.dot(Vr);
  290. real C_Dot_Vs = C.dot(Vs);
  291. u = (C_Dot_Vr - Vr_Dot_Vs * C_Dot_Vs)/detA;
  292. v = (C_Dot_Vr * Vr_Dot_Vs - C_Dot_Vs)/detA;
  293. pointOnThis = position;
  294. pointOnThis += direction * u;
  295. pointOnThat = l2.position;
  296. pointOnThat += l2.direction * v;
  297. return 1;
  298. }
  299. vec3 get_closest_point(const vec3 &point)
  300. {
  301. vec3 np = point - position;
  302. vec3 rp = direction*direction.dot(np)+position;
  303. return rp;
  304. }
  305. const vec3 & get_position() const {return position;}
  306. const vec3 & get_direction() const {return direction;}
  307. //protected:
  308. vec3 position;
  309. vec3 direction;
  310. };
  311. // matrix
  312. class matrix4
  313. {
  314. public:
  315. matrix4() { make_identity(); }
  316. matrix4(real r)
  317. { set_value(r); }
  318. matrix4(real * m)
  319. { set_value(m); }
  320. matrix4(real a00, real a01, real a02, real a03,
  321. real a10, real a11, real a12, real a13,
  322. real a20, real a21, real a22, real a23,
  323. real a30, real a31, real a32, real a33)
  324. {
  325. element(0,0) = a00;
  326. element(0,1) = a01;
  327. element(0,2) = a02;
  328. element(0,3) = a03;
  329. element(1,0) = a10;
  330. element(1,1) = a11;
  331. element(1,2) = a12;
  332. element(1,3) = a13;
  333. element(2,0) = a20;
  334. element(2,1) = a21;
  335. element(2,2) = a22;
  336. element(2,3) = a23;
  337. element(3,0) = a30;
  338. element(3,1) = a31;
  339. element(3,2) = a32;
  340. element(3,3) = a33;
  341. }
  342. void get_value(real * mp) const
  343. {
  344. int c = 0;
  345. for(int j=0; j < 4; j++)
  346. for(int i=0; i < 4; i++)
  347. mp[c++] = element(i,j);
  348. }
  349. const real * get_value() const
  350. { return m; }
  351. void set_value(real * mp)
  352. {
  353. int c = 0;
  354. for(int j=0; j < 4; j++)
  355. for(int i=0; i < 4; i++)
  356. element(i,j) = mp[c++];
  357. }
  358. void set_value(real r)
  359. {
  360. for(int i=0; i < 4; i++)
  361. for(int j=0; j < 4; j++)
  362. element(i,j) = r;
  363. }
  364. void make_identity()
  365. {
  366. element(0,0) = 1.0;
  367. element(0,1) = 0.0;
  368. element(0,2) = 0.0;
  369. element(0,3) = 0.0;
  370. element(1,0) = 0.0;
  371. element(1,1) = 1.0;
  372. element(1,2) = 0.0;
  373. element(1,3) = 0.0;
  374. element(2,0) = 0.0;
  375. element(2,1) = 0.0;
  376. element(2,2) = 1.0;
  377. element(2,3) = 0.0;
  378. element(3,0) = 0.0;
  379. element(3,1) = 0.0;
  380. element(3,2) = 0.0;
  381. element(3,3) = 1.0;
  382. }
  383. static matrix4 identity()
  384. {
  385. static matrix4 mident (
  386. 1.0, 0.0, 0.0, 0.0,
  387. 0.0, 1.0, 0.0, 0.0,
  388. 0.0, 0.0, 1.0, 0.0,
  389. 0.0, 0.0, 0.0, 1.0 );
  390. return mident;
  391. }
  392. void set_scale(real s)
  393. {
  394. element(0,0) = s;
  395. element(1,1) = s;
  396. element(2,2) = s;
  397. }
  398. void set_scale(const vec3 & s)
  399. {
  400. element(0,0) = s.v[0];
  401. element(1,1) = s.v[1];
  402. element(2,2) = s.v[2];
  403. }
  404. void set_translate(const vec3 & t)
  405. {
  406. element(0,3) = t.v[0];
  407. element(1,3) = t.v[1];
  408. element(2,3) = t.v[2];
  409. }
  410. void set_row(int r, const vec4 & t)
  411. {
  412. element(r,0) = t.v[0];
  413. element(r,1) = t.v[1];
  414. element(r,2) = t.v[2];
  415. element(r,3) = t.v[3];
  416. }
  417. void set_column(int c, const vec4 & t)
  418. {
  419. element(0,c) = t.v[0];
  420. element(1,c) = t.v[1];
  421. element(2,c) = t.v[2];
  422. element(3,c) = t.v[3];
  423. }
  424. void get_row(int r, vec4 & t) const
  425. {
  426. t.v[0] = element(r,0);
  427. t.v[1] = element(r,1);
  428. t.v[2] = element(r,2);
  429. t.v[3] = element(r,3);
  430. }
  431. vec4 get_row(int r) const
  432. {
  433. vec4 v; get_row(r, v);
  434. return v;
  435. }
  436. void get_column(int c, vec4 & t) const
  437. {
  438. t.v[0] = element(0,c);
  439. t.v[1] = element(1,c);
  440. t.v[2] = element(2,c);
  441. t.v[3] = element(3,c);
  442. }
  443. vec4 get_column(int c) const
  444. {
  445. vec4 v; get_column(c, v);
  446. return v;
  447. }
  448. matrix4 inverse() const
  449. {
  450. matrix4 minv;
  451. real r1[8], r2[8], r3[8], r4[8];
  452. real *s[4], *tmprow;
  453. s[0] = &r1[0];
  454. s[1] = &r2[0];
  455. s[2] = &r3[0];
  456. s[3] = &r4[0];
  457. int i,j,p,jj;
  458. for(i=0;i<4;i++)
  459. {
  460. for(j=0;j<4;j++)
  461. {
  462. s[i][j] = element(i,j);
  463. if(i==j) s[i][j+4] = 1.0;
  464. else s[i][j+4] = 0.0;
  465. }
  466. }
  467. real scp[4];
  468. for(i=0;i<4;i++)
  469. {
  470. scp[i] = real(fabs(s[i][0]));
  471. for(j=1;j<4;j++)
  472. {
  473. if(real(fabs(s[i][j])) > scp[i]) scp[i] = real(fabs(s[i][j]));
  474. }
  475. if(scp[i] == 0.0) return minv; // singular matrix!
  476. }
  477. int pivot_to;
  478. real scp_max;
  479. for(i=0;i<4;i++)
  480. {
  481. // select pivot row
  482. pivot_to = i;
  483. scp_max = real(fabs(s[i][i]/scp[i]));
  484. // find out which row should be on top
  485. for(p=i+1;p<4;p++)
  486. {
  487. if(real(fabs(s[p][i]/scp[p])) > scp_max)
  488. {
  489. scp_max = real(fabs(s[p][i]/scp[p])); pivot_to = p;
  490. }
  491. }
  492. // Pivot if necessary
  493. if(pivot_to != i)
  494. {
  495. tmprow = s[i];
  496. s[i] = s[pivot_to];
  497. s[pivot_to] = tmprow;
  498. real tmpscp;
  499. tmpscp = scp[i];
  500. scp[i] = scp[pivot_to];
  501. scp[pivot_to] = tmpscp;
  502. }
  503. real mji;
  504. // perform gaussian elimination
  505. for(j=i+1;j<4;j++)
  506. {
  507. mji = s[j][i]/s[i][i];
  508. s[j][i] = 0.0;
  509. for(jj=i+1;jj<8;jj++)
  510. {
  511. s[j][jj] -= mji*s[i][jj];
  512. }
  513. }
  514. }
  515. if(s[3][3] == 0.0) return minv; // singular matrix!
  516. //
  517. // Now we have an upper triangular matrix.
  518. //
  519. // x x x x | y y y y
  520. // 0 x x x | y y y y
  521. // 0 0 x x | y y y y
  522. // 0 0 0 x | y y y y
  523. //
  524. // we'll back substitute to get the inverse
  525. //
  526. // 1 0 0 0 | z z z z
  527. // 0 1 0 0 | z z z z
  528. // 0 0 1 0 | z z z z
  529. // 0 0 0 1 | z z z z
  530. //
  531. real mij;
  532. for(i=3;i>0;i--)
  533. {
  534. for(j=i-1;j > -1; j--)
  535. {
  536. mij = s[j][i]/s[i][i];
  537. for(jj=j+1;jj<8;jj++)
  538. s[j][jj] -= mij*s[i][jj];
  539. }
  540. }
  541. for(i=0;i<4;i++)
  542. {
  543. for(j=0;j<4;j++)
  544. {
  545. minv(i,j) = s[i][j+4] / s[i][i];
  546. }
  547. }
  548. return minv;
  549. }
  550. matrix4 transpose() const
  551. {
  552. matrix4 mtrans;
  553. for(int i=0;i<4;i++)
  554. for(int j=0;j<4;j++)
  555. mtrans(i,j) = element(j,i);
  556. return mtrans;
  557. }
  558. matrix4 & mult_right(const matrix4 & b)
  559. {
  560. matrix4 mt(*this);
  561. set_value(real(0));
  562. for(int i=0; i < 4; i++)
  563. for(int j=0; j < 4; j++)
  564. for(int c=0; c < 4; c++)
  565. element(i,j) += mt(i,c) * b(c,j);
  566. return *this;
  567. }
  568. matrix4 & mult_left(const matrix4 & b)
  569. {
  570. matrix4 mt(*this);
  571. set_value(real(0));
  572. for(int i=0; i < 4; i++)
  573. for(int j=0; j < 4; j++)
  574. for(int c=0; c < 4; c++)
  575. element(i,j) += b(i,c) * mt(c,j);
  576. return *this;
  577. }
  578. // dst = M * src
  579. void mult_matrix_vec(const vec3 &src, vec3 &dst) const
  580. {
  581. real w = (
  582. src.v[0] * element(3,0) +
  583. src.v[1] * element(3,1) +
  584. src.v[2] * element(3,2) +
  585. element(3,3) );
  586. assert(w != GLH_ZERO);
  587. dst.v[0] = (
  588. src.v[0] * element(0,0) +
  589. src.v[1] * element(0,1) +
  590. src.v[2] * element(0,2) +
  591. element(0,3) ) / w;
  592. dst.v[1] = (
  593. src.v[0] * element(1,0) +
  594. src.v[1] * element(1,1) +
  595. src.v[2] * element(1,2) +
  596. element(1,3) ) / w;
  597. dst.v[2] = (
  598. src.v[0] * element(2,0) +
  599. src.v[1] * element(2,1) +
  600. src.v[2] * element(2,2) +
  601. element(2,3) ) / w;
  602. }
  603. void mult_matrix_vec(vec3 & src_and_dst) const
  604. { mult_matrix_vec(vec3(src_and_dst), src_and_dst); }
  605. // dst = src * M
  606. void mult_vec_matrix(const vec3 &src, vec3 &dst) const
  607. {
  608. real w = (
  609. src.v[0] * element(0,3) +
  610. src.v[1] * element(1,3) +
  611. src.v[2] * element(2,3) +
  612. element(3,3) );
  613. assert(w != GLH_ZERO);
  614. dst.v[0] = (
  615. src.v[0] * element(0,0) +
  616. src.v[1] * element(1,0) +
  617. src.v[2] * element(2,0) +
  618. element(3,0) ) / w;
  619. dst.v[1] = (
  620. src.v[0] * element(0,1) +
  621. src.v[1] * element(1,1) +
  622. src.v[2] * element(2,1) +
  623. element(3,1) ) / w;
  624. dst.v[2] = (
  625. src.v[0] * element(0,2) +
  626. src.v[1] * element(1,2) +
  627. src.v[2] * element(2,2) +
  628. element(3,2) ) / w;
  629. }
  630. void mult_vec_matrix(vec3 & src_and_dst) const
  631. { mult_vec_matrix(vec3(src_and_dst), src_and_dst); }
  632. // dst = M * src
  633. void mult_matrix_vec(const vec4 &src, vec4 &dst) const
  634. {
  635. dst.v[0] = (
  636. src.v[0] * element(0,0) +
  637. src.v[1] * element(0,1) +
  638. src.v[2] * element(0,2) +
  639. src.v[3] * element(0,3));
  640. dst.v[1] = (
  641. src.v[0] * element(1,0) +
  642. src.v[1] * element(1,1) +
  643. src.v[2] * element(1,2) +
  644. src.v[3] * element(1,3));
  645. dst.v[2] = (
  646. src.v[0] * element(2,0) +
  647. src.v[1] * element(2,1) +
  648. src.v[2] * element(2,2) +
  649. src.v[3] * element(2,3));
  650. dst.v[3] = (
  651. src.v[0] * element(3,0) +
  652. src.v[1] * element(3,1) +
  653. src.v[2] * element(3,2) +
  654. src.v[3] * element(3,3));
  655. }
  656. void mult_matrix_vec(vec4 & src_and_dst) const
  657. { mult_matrix_vec(vec4(src_and_dst), src_and_dst); }
  658. // dst = src * M
  659. void mult_vec_matrix(const vec4 &src, vec4 &dst) const
  660. {
  661. dst.v[0] = (
  662. src.v[0] * element(0,0) +
  663. src.v[1] * element(1,0) +
  664. src.v[2] * element(2,0) +
  665. src.v[3] * element(3,0));
  666. dst.v[1] = (
  667. src.v[0] * element(0,1) +
  668. src.v[1] * element(1,1) +
  669. src.v[2] * element(2,1) +
  670. src.v[3] * element(3,1));
  671. dst.v[2] = (
  672. src.v[0] * element(0,2) +
  673. src.v[1] * element(1,2) +
  674. src.v[2] * element(2,2) +
  675. src.v[3] * element(3,2));
  676. dst.v[3] = (
  677. src.v[0] * element(0,3) +
  678. src.v[1] * element(1,3) +
  679. src.v[2] * element(2,3) +
  680. src.v[3] * element(3,3));
  681. }
  682. void mult_vec_matrix(vec4 & src_and_dst) const
  683. { mult_vec_matrix(vec4(src_and_dst), src_and_dst); }
  684. // dst = M * src
  685. void mult_matrix_dir(const vec3 &src, vec3 &dst) const
  686. {
  687. dst.v[0] = (
  688. src.v[0] * element(0,0) +
  689. src.v[1] * element(0,1) +
  690. src.v[2] * element(0,2)) ;
  691. dst.v[1] = (
  692. src.v[0] * element(1,0) +
  693. src.v[1] * element(1,1) +
  694. src.v[2] * element(1,2)) ;
  695. dst.v[2] = (
  696. src.v[0] * element(2,0) +
  697. src.v[1] * element(2,1) +
  698. src.v[2] * element(2,2)) ;
  699. }
  700. void mult_matrix_dir(vec3 & src_and_dst) const
  701. { mult_matrix_dir(vec3(src_and_dst), src_and_dst); }
  702. // dst = src * M
  703. void mult_dir_matrix(const vec3 &src, vec3 &dst) const
  704. {
  705. dst.v[0] = (
  706. src.v[0] * element(0,0) +
  707. src.v[1] * element(1,0) +
  708. src.v[2] * element(2,0)) ;
  709. dst.v[1] = (
  710. src.v[0] * element(0,1) +
  711. src.v[1] * element(1,1) +
  712. src.v[2] * element(2,1)) ;
  713. dst.v[2] = (
  714. src.v[0] * element(0,2) +
  715. src.v[1] * element(1,2) +
  716. src.v[2] * element(2,2)) ;
  717. }
  718. void mult_dir_matrix(vec3 & src_and_dst) const
  719. { mult_dir_matrix(vec3(src_and_dst), src_and_dst); }
  720. real & operator () (int row, int col)
  721. { return element(row,col); }
  722. const real & operator () (int row, int col) const
  723. { return element(row,col); }
  724. real & element (int row, int col)
  725. { return m[row | (col<<2)]; }
  726. const real & element (int row, int col) const
  727. { return m[row | (col<<2)]; }
  728. matrix4 & operator *= (const matrix4 & mat)
  729. {
  730. mult_right(mat);
  731. return *this;
  732. }
  733. matrix4 & operator *= (const real & r)
  734. {
  735. for (int i = 0; i < 4; ++i)
  736. {
  737. element(0,i) *= r;
  738. element(1,i) *= r;
  739. element(2,i) *= r;
  740. element(3,i) *= r;
  741. }
  742. return *this;
  743. }
  744. matrix4 & operator += (const matrix4 & mat)
  745. {
  746. for (int i = 0; i < 4; ++i)
  747. {
  748. element(0,i) += mat.element(0,i);
  749. element(1,i) += mat.element(1,i);
  750. element(2,i) += mat.element(2,i);
  751. element(3,i) += mat.element(3,i);
  752. }
  753. return *this;
  754. }
  755. friend matrix4 operator * (const matrix4 & m1, const matrix4 & m2);
  756. friend bool operator == (const matrix4 & m1, const matrix4 & m2);
  757. friend bool operator != (const matrix4 & m1, const matrix4 & m2);
  758. //protected:
  759. real m[16];
  760. };
  761. LL_INLINE
  762. matrix4 operator * (const matrix4 & m1, const matrix4 & m2)
  763. {
  764. matrix4 product;
  765. product = m1;
  766. product.mult_right(m2);
  767. return product;
  768. }
  769. LL_INLINE
  770. bool operator ==(const matrix4 &m1, const matrix4 &m2)
  771. {
  772. return (
  773. m1(0,0) == m2(0,0) &&
  774. m1(0,1) == m2(0,1) &&
  775. m1(0,2) == m2(0,2) &&
  776. m1(0,3) == m2(0,3) &&
  777. m1(1,0) == m2(1,0) &&
  778. m1(1,1) == m2(1,1) &&
  779. m1(1,2) == m2(1,2) &&
  780. m1(1,3) == m2(1,3) &&
  781. m1(2,0) == m2(2,0) &&
  782. m1(2,1) == m2(2,1) &&
  783. m1(2,2) == m2(2,2) &&
  784. m1(2,3) == m2(2,3) &&
  785. m1(3,0) == m2(3,0) &&
  786. m1(3,1) == m2(3,1) &&
  787. m1(3,2) == m2(3,2) &&
  788. m1(3,3) == m2(3,3));
  789. }
  790. LL_INLINE
  791. bool operator != (const matrix4 & m1, const matrix4 & m2)
  792. { return !(m1 == m2); }
  793. class quaternion
  794. {
  795. public:
  796. quaternion()
  797. {
  798. *this = identity();
  799. }
  800. quaternion(const real v[4])
  801. {
  802. set_value(v);
  803. }
  804. quaternion(real q0, real q1, real q2, real q3)
  805. {
  806. set_value(q0, q1, q2, q3);
  807. }
  808. quaternion(const matrix4 & m)
  809. {
  810. set_value(m);
  811. }
  812. quaternion(const vec3 &axis, real radians)
  813. {
  814. set_value(axis, radians);
  815. }
  816. quaternion(const vec3 &rotateFrom, const vec3 &rotateTo)
  817. {
  818. set_value(rotateFrom, rotateTo);
  819. }
  820. quaternion(const vec3 & from_look, const vec3 & from_up,
  821. const vec3 & to_look, const vec3& to_up)
  822. {
  823. set_value(from_look, from_up, to_look, to_up);
  824. }
  825. const real * get_value() const
  826. {
  827. return &q[0];
  828. }
  829. void get_value(real &q0, real &q1, real &q2, real &q3) const
  830. {
  831. q0 = q[0];
  832. q1 = q[1];
  833. q2 = q[2];
  834. q3 = q[3];
  835. }
  836. quaternion & set_value(real q0, real q1, real q2, real q3)
  837. {
  838. q[0] = q0;
  839. q[1] = q1;
  840. q[2] = q2;
  841. q[3] = q3;
  842. counter = 0;
  843. return *this;
  844. }
  845. void get_value(vec3 &axis, real &radians) const
  846. {
  847. radians = real(acos(q[3]) * GLH_TWO);
  848. if (radians == GLH_ZERO)
  849. axis = vec3(0.0, 0.0, 1.0);
  850. else
  851. {
  852. axis.v[0] = q[0];
  853. axis.v[1] = q[1];
  854. axis.v[2] = q[2];
  855. axis.normalize();
  856. }
  857. }
  858. void get_value(matrix4 & m) const
  859. {
  860. real s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
  861. real norm = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3];
  862. s = (equivalent(norm,GLH_ZERO)) ? GLH_ZERO : (GLH_TWO / norm);
  863. xs = q[0] * s;
  864. ys = q[1] * s;
  865. zs = q[2] * s;
  866. wx = q[3] * xs;
  867. wy = q[3] * ys;
  868. wz = q[3] * zs;
  869. xx = q[0] * xs;
  870. xy = q[0] * ys;
  871. xz = q[0] * zs;
  872. yy = q[1] * ys;
  873. yz = q[1] * zs;
  874. zz = q[2] * zs;
  875. m(0,0) = real(GLH_ONE - (yy + zz));
  876. m(1,0) = real (xy + wz);
  877. m(2,0) = real (xz - wy);
  878. m(0,1) = real (xy - wz);
  879. m(1,1) = real (GLH_ONE - (xx + zz));
  880. m(2,1) = real (yz + wx);
  881. m(0,2) = real (xz + wy);
  882. m(1,2) = real (yz - wx);
  883. m(2,2) = real (GLH_ONE - (xx + yy));
  884. m(3,0) = m(3,1) = m(3,2) = m(0,3) = m(1,3) = m(2,3) = GLH_ZERO;
  885. m(3,3) = GLH_ONE;
  886. }
  887. quaternion & set_value(const real * qp)
  888. {
  889. memcpy(q,qp,sizeof(real) * 4);
  890. counter = 0;
  891. return *this;
  892. }
  893. quaternion & set_value(const matrix4 & m)
  894. {
  895. real tr, s;
  896. int i, j, k;
  897. const int nxt[3] = { 1, 2, 0 };
  898. tr = m(0,0) + m(1,1) + m(2,2);
  899. if (tr > GLH_ZERO)
  900. {
  901. s = real(sqrt(tr + m(3,3)));
  902. q[3] = real (s * 0.5);
  903. s = real(0.5) / s;
  904. q[0] = real ((m(1,2) - m(2,1)) * s);
  905. q[1] = real ((m(2,0) - m(0,2)) * s);
  906. q[2] = real ((m(0,1) - m(1,0)) * s);
  907. }
  908. else
  909. {
  910. i = 0;
  911. if (m(1,1) > m(0,0))
  912. i = 1;
  913. if (m(2,2) > m(i,i))
  914. i = 2;
  915. j = nxt[i];
  916. k = nxt[j];
  917. s = real(sqrt((m(i,j) - (m(j,j) + m(k,k))) + GLH_ONE));
  918. q[i] = real (s * 0.5);
  919. s = real(0.5 / s);
  920. q[3] = real ((m(j,k) - m(k,j)) * s);
  921. q[j] = real ((m(i,j) + m(j,i)) * s);
  922. q[k] = real ((m(i,k) + m(k,i)) * s);
  923. }
  924. counter = 0;
  925. return *this;
  926. }
  927. quaternion & set_value(const vec3 &axis, real theta)
  928. {
  929. real sqnorm = axis.square_norm();
  930. if (sqnorm <= GLH_EPSILON)
  931. {
  932. // axis too small.
  933. x = y = z = 0.0;
  934. w = 1.0;
  935. }
  936. else
  937. {
  938. theta *= real(0.5);
  939. real sin_theta = real(sin(theta));
  940. if (!equivalent(sqnorm,GLH_ONE))
  941. sin_theta /= real(sqrt(sqnorm));
  942. x = sin_theta * axis.v[0];
  943. y = sin_theta * axis.v[1];
  944. z = sin_theta * axis.v[2];
  945. w = real(cos(theta));
  946. }
  947. return *this;
  948. }
  949. quaternion & set_value(const vec3 & rotateFrom, const vec3 & rotateTo)
  950. {
  951. vec3 p1, p2;
  952. real alpha;
  953. p1 = rotateFrom;
  954. p1.normalize();
  955. p2 = rotateTo;
  956. p2.normalize();
  957. alpha = p1.dot(p2);
  958. if(equivalent(alpha,GLH_ONE))
  959. {
  960. *this = identity();
  961. return *this;
  962. }
  963. // ensures that the anti-parallel case leads to a positive dot
  964. if(equivalent(alpha,-GLH_ONE))
  965. {
  966. vec3 v;
  967. if(p1.v[0] != p1.v[1] || p1.v[0] != p1.v[2])
  968. v = vec3(p1.v[1], p1.v[2], p1.v[0]);
  969. else
  970. v = vec3(-p1.v[0], p1.v[1], p1.v[2]);
  971. v -= p1 * p1.dot(v);
  972. v.normalize();
  973. set_value(v, GLH_PI);
  974. return *this;
  975. }
  976. p1 = p1.cross(p2);
  977. p1.normalize();
  978. set_value(p1,real(acos(alpha)));
  979. counter = 0;
  980. return *this;
  981. }
  982. quaternion & set_value(const vec3 & from_look, const vec3 & from_up,
  983. const vec3 & to_look, const vec3 & to_up)
  984. {
  985. quaternion r_look = quaternion(from_look, to_look);
  986. vec3 rotated_from_up(from_up);
  987. r_look.mult_vec(rotated_from_up);
  988. quaternion r_twist = quaternion(rotated_from_up, to_up);
  989. *this = r_twist;
  990. *this *= r_look;
  991. return *this;
  992. }
  993. quaternion & operator *= (const quaternion & qr)
  994. {
  995. quaternion ql(*this);
  996. w = ql.w * qr.w - ql.x * qr.x - ql.y * qr.y - ql.z * qr.z;
  997. x = ql.w * qr.x + ql.x * qr.w + ql.y * qr.z - ql.z * qr.y;
  998. y = ql.w * qr.y + ql.y * qr.w + ql.z * qr.x - ql.x * qr.z;
  999. z = ql.w * qr.z + ql.z * qr.w + ql.x * qr.y - ql.y * qr.x;
  1000. counter += qr.counter;
  1001. counter++;
  1002. counter_normalize();
  1003. return *this;
  1004. }
  1005. void normalize()
  1006. {
  1007. real rnorm = GLH_ONE / real(sqrt(w * w + x * x + y * y + z * z));
  1008. if (equivalent(rnorm, GLH_ZERO))
  1009. return;
  1010. x *= rnorm;
  1011. y *= rnorm;
  1012. z *= rnorm;
  1013. w *= rnorm;
  1014. counter = 0;
  1015. }
  1016. friend bool operator == (const quaternion & q1, const quaternion & q2);
  1017. friend bool operator != (const quaternion & q1, const quaternion & q2);
  1018. friend quaternion operator * (const quaternion & q1, const quaternion & q2);
  1019. bool equals(const quaternion & r, real tolerance) const
  1020. {
  1021. real t;
  1022. t = (
  1023. (q[0]-r.q[0])*(q[0]-r.q[0]) +
  1024. (q[1]-r.q[1])*(q[1]-r.q[1]) +
  1025. (q[2]-r.q[2])*(q[2]-r.q[2]) +
  1026. (q[3]-r.q[3])*(q[3]-r.q[3]));
  1027. if(t > GLH_EPSILON)
  1028. return false;
  1029. return 1;
  1030. }
  1031. quaternion & conjugate()
  1032. {
  1033. q[0] *= -GLH_ONE;
  1034. q[1] *= -GLH_ONE;
  1035. q[2] *= -GLH_ONE;
  1036. return *this;
  1037. }
  1038. quaternion & invert()
  1039. {
  1040. return conjugate();
  1041. }
  1042. quaternion inverse() const
  1043. {
  1044. quaternion r = *this;
  1045. return r.invert();
  1046. }
  1047. //
  1048. // Quaternion multiplication with cartesian vector
  1049. // v' = q*v*q(star)
  1050. //
  1051. void mult_vec(const vec3 &src, vec3 &dst) const
  1052. {
  1053. real v_coef = w * w - x * x - y * y - z * z;
  1054. real u_coef = GLH_TWO * (src.v[0] * x + src.v[1] * y + src.v[2] * z);
  1055. real c_coef = GLH_TWO * w;
  1056. dst.v[0] = v_coef * src.v[0] + u_coef * x + c_coef * (y * src.v[2] - z * src.v[1]);
  1057. dst.v[1] = v_coef * src.v[1] + u_coef * y + c_coef * (z * src.v[0] - x * src.v[2]);
  1058. dst.v[2] = v_coef * src.v[2] + u_coef * z + c_coef * (x * src.v[1] - y * src.v[0]);
  1059. }
  1060. void mult_vec(vec3 & src_and_dst) const
  1061. {
  1062. mult_vec(vec3(src_and_dst), src_and_dst);
  1063. }
  1064. void scale_angle(real scaleFactor)
  1065. {
  1066. vec3 axis;
  1067. real radians;
  1068. get_value(axis, radians);
  1069. radians *= scaleFactor;
  1070. set_value(axis, radians);
  1071. }
  1072. static quaternion slerp(const quaternion & p, const quaternion & q, real alpha)
  1073. {
  1074. quaternion r;
  1075. real cos_omega = p.x * q.x + p.y * q.y + p.z * q.z + p.w * q.w;
  1076. // if B is on opposite hemisphere from A, use -B instead
  1077. int bflip;
  1078. if ((bflip = (cos_omega < GLH_ZERO)))
  1079. cos_omega = -cos_omega;
  1080. // complementary interpolation parameter
  1081. real beta = GLH_ONE - alpha;
  1082. if(cos_omega <= GLH_ONE - GLH_EPSILON)
  1083. return p;
  1084. real omega = real(acos(cos_omega));
  1085. real one_over_sin_omega = GLH_ONE / real(sin(omega));
  1086. beta = real(sin(omega*beta) * one_over_sin_omega);
  1087. alpha = real(sin(omega*alpha) * one_over_sin_omega);
  1088. if (bflip)
  1089. alpha = -alpha;
  1090. r.x = beta * p.q[0]+ alpha * q.q[0];
  1091. r.y = beta * p.q[1]+ alpha * q.q[1];
  1092. r.z = beta * p.q[2]+ alpha * q.q[2];
  1093. r.w = beta * p.q[3]+ alpha * q.q[3];
  1094. return r;
  1095. }
  1096. static quaternion identity()
  1097. {
  1098. static quaternion ident(vec3(0.0, 0.0, 0.0), GLH_ONE);
  1099. return ident;
  1100. }
  1101. real & operator [](int i)
  1102. {
  1103. assert(i < 4);
  1104. return q[i];
  1105. }
  1106. const real & operator [](int i) const
  1107. {
  1108. assert(i < 4);
  1109. return q[i];
  1110. }
  1111. protected:
  1112. void counter_normalize()
  1113. {
  1114. if (counter > GLH_QUATERNION_NORMALIZATION_THRESHOLD)
  1115. normalize();
  1116. }
  1117. union
  1118. {
  1119. struct
  1120. {
  1121. real q[4];
  1122. };
  1123. struct
  1124. {
  1125. real x;
  1126. real y;
  1127. real z;
  1128. real w;
  1129. };
  1130. };
  1131. // renormalization counter
  1132. unsigned char counter;
  1133. };
  1134. LL_INLINE
  1135. bool operator == (const quaternion & q1, const quaternion & q2)
  1136. {
  1137. return (equivalent(q1.x, q2.x) &&
  1138. equivalent(q1.y, q2.y) &&
  1139. equivalent(q1.z, q2.z) &&
  1140. equivalent(q1.w, q2.w));
  1141. }
  1142. LL_INLINE
  1143. bool operator != (const quaternion & q1, const quaternion & q2)
  1144. {
  1145. return ! (q1 == q2);
  1146. }
  1147. LL_INLINE
  1148. quaternion operator * (const quaternion & q1, const quaternion & q2)
  1149. {
  1150. quaternion r(q1);
  1151. r *= q2;
  1152. return r;
  1153. }
  1154. class plane
  1155. {
  1156. public:
  1157. plane()
  1158. {
  1159. planedistance = 0.0;
  1160. planenormal.set_value(0.0, 0.0, 1.0);
  1161. }
  1162. plane(const vec3 &p0, const vec3 &p1, const vec3 &p2)
  1163. {
  1164. vec3 v0 = p1 - p0;
  1165. vec3 v1 = p2 - p0;
  1166. planenormal = v0.cross(v1);
  1167. planenormal.normalize();
  1168. planedistance = p0.dot(planenormal);
  1169. }
  1170. plane(const vec3 &normal, real distance)
  1171. {
  1172. planedistance = distance;
  1173. planenormal = normal;
  1174. planenormal.normalize();
  1175. }
  1176. plane(const vec3 &normal, const vec3 &point)
  1177. {
  1178. planenormal = normal;
  1179. planenormal.normalize();
  1180. planedistance = point.dot(planenormal);
  1181. }
  1182. void offset(real d)
  1183. {
  1184. planedistance += d;
  1185. }
  1186. bool intersect(const line &l, vec3 &intersection) const
  1187. {
  1188. vec3 pos, dir;
  1189. vec3 pn = planenormal;
  1190. real pd = planedistance;
  1191. pos = l.get_position();
  1192. dir = l.get_direction();
  1193. if(dir.dot(pn) == 0.0) return 0;
  1194. pos -= pn*pd;
  1195. // now we're talking about a plane passing through the origin
  1196. if(pos.dot(pn) < 0.0) pn.negate();
  1197. if(dir.dot(pn) > 0.0) dir.negate();
  1198. vec3 ppos = pn * pos.dot(pn);
  1199. pos = (ppos.length()/dir.dot(-pn))*dir;
  1200. intersection = l.get_position();
  1201. intersection += pos;
  1202. return 1;
  1203. }
  1204. void transform(const matrix4 &matrix)
  1205. {
  1206. matrix4 invtr = matrix.inverse();
  1207. invtr = invtr.transpose();
  1208. vec3 pntOnplane = planenormal * planedistance;
  1209. vec3 newPntOnplane;
  1210. vec3 newnormal;
  1211. invtr.mult_dir_matrix(planenormal, newnormal);
  1212. matrix.mult_vec_matrix(pntOnplane, newPntOnplane);
  1213. newnormal.normalize();
  1214. planenormal = newnormal;
  1215. planedistance = newPntOnplane.dot(planenormal);
  1216. }
  1217. bool is_in_half_space(const vec3 &point) const
  1218. {
  1219. if((point.dot(planenormal) - planedistance) < 0.0)
  1220. return 0;
  1221. return 1;
  1222. }
  1223. real distance(const vec3 & point) const
  1224. {
  1225. return planenormal.dot(point - planenormal*planedistance);
  1226. }
  1227. const vec3 &get_normal() const
  1228. {
  1229. return planenormal;
  1230. }
  1231. real get_distance_from_origin() const
  1232. {
  1233. return planedistance;
  1234. }
  1235. friend bool operator == (const plane & p1, const plane & p2);
  1236. friend bool operator != (const plane & p1, const plane & p2);
  1237. //protected:
  1238. vec3 planenormal;
  1239. real planedistance;
  1240. };
  1241. LL_INLINE
  1242. bool operator == (const plane & p1, const plane & p2)
  1243. {
  1244. return ( p1.planedistance == p2.planedistance && p1.planenormal == p2.planenormal);
  1245. }
  1246. LL_INLINE
  1247. bool operator != (const plane & p1, const plane & p2)
  1248. { return ! (p1 == p2); }
  1249. } // "ns_##GLH_REAL"
  1250. // make common typedefs...
  1251. #ifdef GLH_REAL_IS_FLOAT
  1252. typedef GLH_REAL_NAMESPACE::vec2 vec2f;
  1253. typedef GLH_REAL_NAMESPACE::vec3 vec3f;
  1254. typedef GLH_REAL_NAMESPACE::vec4 vec4f;
  1255. typedef GLH_REAL_NAMESPACE::quaternion quaternionf;
  1256. typedef GLH_REAL_NAMESPACE::quaternion rotationf;
  1257. typedef GLH_REAL_NAMESPACE::line linef;
  1258. typedef GLH_REAL_NAMESPACE::plane planef;
  1259. typedef GLH_REAL_NAMESPACE::matrix4 matrix4f;
  1260. #endif
  1261. } // namespace glh
  1262. #endif