PageRenderTime 82ms CodeModel.GetById 24ms RepoModel.GetById 2ms app.codeStats 0ms

/extern/prmath/vector3float.hpp

https://github.com/joeld42/luddite
C++ Header | 665 lines | 504 code | 97 blank | 64 comment | 29 complexity | 9f8e7f8edbc0552398544774561bc374 MD5 | raw file
Possible License(s): MIT
  1. /*
  2. Twilight Prophecy SDK
  3. A multi-platform development system for virtual reality and multimedia.
  4. Copyright (C) 1997-2003 Twilight 3D Finland Oy Ltd.
  5. */
  6. /*
  7. Abstract:
  8. Meta Expression Template based specialization of prmath::Vector3<float>
  9. Reference material:
  10. Jim Blinn's Corner: Notation, Notation, Notation ISBN 1-55860-860-5
  11. Tomas Arce: Faster Vector Math Using Templates http://www.flipcode.com/tutorials/tut_fastmath.shtml
  12. */
  13. #ifndef PRMATH_VECTOR3FLOAT_HPP
  14. #define PRMATH_VECTOR3FLOAT_HPP
  15. #ifndef PRMATH_VECTOR3_HPP
  16. #error prmath: "do not include this header yourself!"
  17. #endif
  18. #include "metavector.hpp"
  19. #ifdef PRMATH_METAVECTOR_ENABLE
  20. namespace prmath
  21. {
  22. // expression
  23. template <typename E>
  24. class MetaExpV3F
  25. {
  26. E exp;
  27. public:
  28. metainline MetaExpV3F(const E& e)
  29. : exp(e)
  30. {
  31. }
  32. metainline float operator [] (const int index) const
  33. {
  34. return exp[index];
  35. }
  36. metainline MetaExpV3F operator + () const
  37. {
  38. return *this;
  39. }
  40. metainline const MetaExpV3F< MetaNEG<float,E> > operator - () const
  41. {
  42. return MetaExpV3F< MetaNEG<float,E> >(exp);
  43. }
  44. };
  45. template <>
  46. class MetaExpV3F<float>
  47. {
  48. float exp;
  49. public:
  50. metainline MetaExpV3F(const float& e)
  51. : exp(e)
  52. {
  53. }
  54. metainline float operator [] (const int index) const
  55. {
  56. return exp;
  57. }
  58. };
  59. // vector3<float>
  60. template <>
  61. struct Vector3<float> : BaseVector<float,3>
  62. {
  63. // members
  64. union { float x,r; };
  65. union { float y,g; };
  66. union { float z,b; };
  67. // constructors
  68. metainline Vector3()
  69. {
  70. }
  71. metainline Vector3(float sx, float sy, float sz)
  72. : x(sx), y(sy), z(sz)
  73. {
  74. }
  75. metainline Vector3(const float v[])
  76. : x(v[0]), y(v[1]), z(v[2])
  77. {
  78. }
  79. metainline Vector3(const Vector3& v)
  80. : x(v.x), y(v.y), z(v.z)
  81. {
  82. }
  83. metainline Vector3(float v)
  84. : x(v), y(v), z(v)
  85. {
  86. }
  87. template <typename E>
  88. metainline Vector3(const MetaExpV3F<E>& exp)
  89. {
  90. x = exp[0];
  91. y = exp[1];
  92. z = exp[2];
  93. }
  94. // operators
  95. template <typename E>
  96. metainline Vector3<float>& operator += (const MetaExpV3F<E>& exp)
  97. {
  98. x += exp[0];
  99. y += exp[1];
  100. z += exp[2];
  101. return *this;
  102. }
  103. template <typename E>
  104. metainline Vector3<float>& operator -= (const MetaExpV3F<E>& exp)
  105. {
  106. x -= exp[0];
  107. y -= exp[1];
  108. z -= exp[2];
  109. return *this;
  110. }
  111. template <typename E>
  112. metainline Vector3<float>& operator *= (const MetaExpV3F<E>& exp)
  113. {
  114. x *= exp[0];
  115. y *= exp[1];
  116. z *= exp[2];
  117. return *this;
  118. }
  119. template <typename E>
  120. metainline Vector3<float>& operator = (const MetaExpV3F<E>& exp)
  121. {
  122. x = exp[0];
  123. y = exp[1];
  124. z = exp[2];
  125. return *this;
  126. }
  127. metainline Vector3 operator + () const
  128. {
  129. return *this;
  130. }
  131. metainline Vector3 operator - () const
  132. {
  133. return Vector3(-x,-y,-z);
  134. }
  135. metainline Vector3& operator += (const Vector3& v)
  136. {
  137. x += v.x;
  138. y += v.y;
  139. z += v.z;
  140. return *this;
  141. }
  142. metainline Vector3& operator -= (const Vector3& v)
  143. {
  144. x -= v.x;
  145. y -= v.y;
  146. z -= v.z;
  147. return *this;
  148. }
  149. metainline Vector3& operator *= (const Vector3& v)
  150. {
  151. x *= v.x;
  152. y *= v.y;
  153. z *= v.z;
  154. return *this;
  155. }
  156. metainline Vector3& operator = (const Vector3& v)
  157. {
  158. x = v.x;
  159. y = v.y;
  160. z = v.z;
  161. return *this;
  162. }
  163. metainline Vector3& operator = (float v)
  164. {
  165. x = v;
  166. y = v;
  167. z = v;
  168. return *this;
  169. }
  170. metainline Vector3& operator *= (float s)
  171. {
  172. x *= s;
  173. y *= s;
  174. z *= s;
  175. return *this;
  176. }
  177. metainline Vector3& operator /= (float s)
  178. {
  179. assert( s != 0 );
  180. float is = 1 / s;
  181. x *= is;
  182. y *= is;
  183. z *= is;
  184. return *this;
  185. }
  186. // methods
  187. metainline void Normalize()
  188. {
  189. float s = x*x + y*y + z*z;
  190. if ( s != 0 )
  191. {
  192. s = 1 / static_cast<float>(sqrt(s));
  193. x *= s;
  194. y *= s;
  195. z *= s;
  196. }
  197. }
  198. metainline void SetVector(float sx, float sy, float sz)
  199. {
  200. x = sx;
  201. y = sy;
  202. z = sz;
  203. }
  204. metainline void SetVector(float v)
  205. {
  206. x = v;
  207. y = v;
  208. z = v;
  209. }
  210. };
  211. // meta operators
  212. // exp + exp
  213. template <typename A, typename B>
  214. metainline const MetaExpV3F< MetaADD< float,MetaExpV3F<A>,MetaExpV3F<B> > >
  215. operator + (const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
  216. {
  217. typedef MetaADD< float,MetaExpV3F<A>,MetaExpV3F<B> > exp;
  218. return MetaExpV3F<exp>(exp(a,b));
  219. }
  220. // exp + vec3f
  221. template <typename A>
  222. metainline const MetaExpV3F< MetaADD< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > >
  223. operator + (const MetaExpV3F<A>& a, const Vector3<float>& b)
  224. {
  225. typedef MetaADD< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > exp;
  226. return MetaExpV3F<exp>(exp(a,b));
  227. }
  228. // vec3f + exp
  229. template <typename B>
  230. metainline const MetaExpV3F< MetaADD< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > >
  231. operator + (const Vector3<float>& a, const MetaExpV3F<B>& b)
  232. {
  233. typedef MetaADD< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > exp;
  234. return MetaExpV3F<exp>(exp(a,b));
  235. }
  236. // vec3f + vec3f
  237. metainline const MetaExpV3F< MetaADD< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > >
  238. operator + (const Vector3<float>& a, const Vector3<float>& b)
  239. {
  240. typedef MetaADD< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > exp;
  241. return MetaExpV3F<exp>(exp(a,b));
  242. }
  243. // exp - exp
  244. template <typename A, typename B>
  245. metainline const MetaExpV3F< MetaSUB< float,MetaExpV3F<A>,MetaExpV3F<B> > >
  246. operator - (const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
  247. {
  248. typedef MetaSUB< float,MetaExpV3F<A>,MetaExpV3F<B> > exp;
  249. return MetaExpV3F<exp>(exp(a,b));
  250. }
  251. // exp - vec3f
  252. template <typename A>
  253. metainline const MetaExpV3F< MetaSUB< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > >
  254. operator - (const MetaExpV3F<A>& a, const Vector3<float>& b)
  255. {
  256. typedef MetaSUB< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > exp;
  257. return MetaExpV3F<exp>(exp(a,b));
  258. }
  259. // vec3f - exp
  260. template <typename B>
  261. metainline const MetaExpV3F< MetaSUB< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > >
  262. operator - (const Vector3<float>& a, const MetaExpV3F<B>& b)
  263. {
  264. typedef MetaSUB< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > exp;
  265. return MetaExpV3F<exp>(exp(a,b));
  266. }
  267. // vec3f - vec3f
  268. metainline const MetaExpV3F< MetaSUB< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > >
  269. operator - (const Vector3<float>& a, const Vector3<float>& b)
  270. {
  271. typedef MetaSUB< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > exp;
  272. return MetaExpV3F<exp>(exp(a,b));
  273. }
  274. // exp * exp
  275. template <typename A, typename B>
  276. metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F<A>,MetaExpV3F<B> > >
  277. operator * (const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
  278. {
  279. typedef MetaMUL< float,MetaExpV3F<A>,MetaExpV3F<B> > exp;
  280. return MetaExpV3F<exp>(exp(a,b));
  281. }
  282. // exp * vec3f
  283. template <typename A>
  284. metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > >
  285. operator * (const MetaExpV3F<A>& a, const Vector3<float>& b)
  286. {
  287. typedef MetaMUL< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > exp;
  288. return MetaExpV3F<exp>(exp(a,b));
  289. }
  290. // exp * float
  291. template <typename A>
  292. metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F<A>,MetaExpV3F<float> > >
  293. operator * (const MetaExpV3F<A>& a, const float& b)
  294. {
  295. typedef MetaMUL< float,MetaExpV3F<A>,MetaExpV3F<float> > exp;
  296. return MetaExpV3F<exp>(exp(a,b));
  297. }
  298. // vec3f * exp
  299. template <typename B>
  300. metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > >
  301. operator * (const Vector3<float>& a, const MetaExpV3F<B>& b)
  302. {
  303. typedef MetaMUL< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > exp;
  304. return MetaExpV3F<exp>(exp(a,b));
  305. }
  306. // vec3f * vec3f
  307. metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > >
  308. operator * (const Vector3<float>& a, const Vector3<float>& b)
  309. {
  310. typedef MetaMUL< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > exp;
  311. return MetaExpV3F<exp>(exp(a,b));
  312. }
  313. // vec3f * float
  314. metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<float> > >
  315. operator * (const Vector3<float>& a, const float& b)
  316. {
  317. typedef MetaMUL< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<float> > exp;
  318. return MetaExpV3F<exp>(exp(a,b));
  319. }
  320. // float * exp
  321. template <typename B>
  322. metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F<float>,MetaExpV3F<B> > >
  323. operator * (const float& a, const MetaExpV3F<B>& b)
  324. {
  325. typedef MetaMUL< float,MetaExpV3F<float>,MetaExpV3F<B> > exp;
  326. return MetaExpV3F<exp>(exp(a,b));
  327. }
  328. // float * vec3f
  329. metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F<float>,MetaExpV3F< Vector3<float> > > >
  330. operator * (const float& a, Vector3<float>& b)
  331. {
  332. typedef MetaMUL< float,MetaExpV3F<float>,MetaExpV3F< Vector3<float> > > exp;
  333. return MetaExpV3F<exp>(exp(a,b));
  334. }
  335. // exp / exp
  336. template <typename A, typename B>
  337. metainline const MetaExpV3F< MetaDIV< float,MetaExpV3F<A>,MetaExpV3F<B> > >
  338. operator / (const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
  339. {
  340. typedef MetaDIV< float,MetaExpV3F<A>,MetaExpV3F<B> > exp;
  341. return MetaExpV3F<exp>(exp(a,b));
  342. }
  343. // exp / vec3f
  344. template <typename A>
  345. metainline const MetaExpV3F< MetaDIV< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > >
  346. operator / (const MetaExpV3F<A>& a, const Vector3<float>& b)
  347. {
  348. typedef MetaDIV< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > exp;
  349. return MetaExpV3F<exp>(exp(a,b));
  350. }
  351. // exp / float
  352. template <typename A>
  353. metainline const MetaExpV3F< MetaDIV< float,MetaExpV3F<A>,MetaExpV3F<float> > >
  354. operator / (const MetaExpV3F<A>& a, const float& b)
  355. {
  356. typedef MetaDIV< float,MetaExpV3F<A>,MetaExpV3F<float> > exp;
  357. return MetaExpV3F<exp>(exp(a,b));
  358. }
  359. // vec3f / exp
  360. template <typename B>
  361. metainline const MetaExpV3F< MetaDIV< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > >
  362. operator / (const Vector3<float>& a, const MetaExpV3F<B>& b)
  363. {
  364. typedef MetaDIV< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > exp;
  365. return MetaExpV3F<exp>(exp(a,b));
  366. }
  367. // vec3f / vec3f
  368. metainline const MetaExpV3F< MetaDIV< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > >
  369. operator / (const Vector3<float>& a, const Vector3<float>& b)
  370. {
  371. typedef MetaDIV< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > exp;
  372. return MetaExpV3F<exp>(exp(a,b));
  373. }
  374. // vec3f / float
  375. metainline const MetaExpV3F< MetaDIV< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<float> > >
  376. operator / (const Vector3<float>& a, const float& b)
  377. {
  378. typedef MetaDIV< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<float> > exp;
  379. return MetaExpV3F<exp>(exp(a,b));
  380. }
  381. // exp == exp
  382. template <typename A, typename B>
  383. metainline bool operator == (const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
  384. {
  385. for ( int i=0; i<3; ++i )
  386. {
  387. if ( a[i] != b[i] )
  388. return false;
  389. }
  390. return true;
  391. }
  392. // vec3f == exp
  393. template <typename B>
  394. metainline bool operator == (const Vector3<float>& a, const MetaExpV3F<B>& b)
  395. {
  396. for ( int i=0; i<3; ++i )
  397. {
  398. if ( a[i] != b[i] )
  399. return false;
  400. }
  401. return true;
  402. }
  403. // exp == vec3f
  404. template <typename A>
  405. metainline bool operator == (const MetaExpV3F<A>& a, const Vector3<float>& b)
  406. {
  407. for ( int i=0; i<3; ++i )
  408. {
  409. if ( a[i] != b[i] )
  410. return false;
  411. }
  412. return true;
  413. }
  414. // exp != exp
  415. template <typename A, typename B>
  416. metainline bool operator != (const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
  417. {
  418. for ( int i=0; i<3; ++i )
  419. {
  420. if ( a[i] != b[i] )
  421. return true;
  422. }
  423. return false;
  424. }
  425. // vec3f != exp
  426. template <typename B>
  427. metainline bool operator != (const Vector3<float>& a, const MetaExpV3F<B>& b)
  428. {
  429. for ( int i=0; i<3; ++i )
  430. {
  431. if ( a[i] != b[i] )
  432. return true;
  433. }
  434. return false;
  435. }
  436. // exp != vec3f
  437. template <typename A>
  438. metainline bool operator != (const MetaExpV3F<A>& a, const Vector3<float>& b)
  439. {
  440. for ( int i=0; i<3; ++i )
  441. {
  442. if ( a[i] != b[i] )
  443. return true;
  444. }
  445. return false;
  446. }
  447. // meta functions
  448. // exp x exp
  449. template <typename A, typename B>
  450. metainline const MetaExpV3F< MetaCROSS3< float,MetaExpV3F<A>,MetaExpV3F<B> > >
  451. CrossProduct(const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
  452. {
  453. typedef MetaCROSS3< float,MetaExpV3F<A>,MetaExpV3F<B> > exp;
  454. return MetaExpV3F<exp>(exp(a,b));
  455. }
  456. // exp x vec3f
  457. template <typename A>
  458. metainline const MetaExpV3F< MetaCROSS3< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > >
  459. CrossProduct(const MetaExpV3F<A>& a, const Vector3<float>& b)
  460. {
  461. typedef MetaCROSS3< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > exp;
  462. return MetaExpV3F<exp>(exp(a,b));
  463. }
  464. // vec3f x exp
  465. template <typename B>
  466. metainline const MetaExpV3F< MetaCROSS3< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > >
  467. CrossProduct(const Vector3<float>& a, const MetaExpV3F<B>& b)
  468. {
  469. typedef MetaCROSS3< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > exp;
  470. return MetaExpV3F<exp>(exp(a,b));
  471. }
  472. // vec3f x vec3f
  473. /* metainline const MetaExpV3F< MetaCROSS3< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > >
  474. CrossProduct(const Vector3<float>& a, const Vector3<float>& b)
  475. {
  476. typedef MetaCROSS3< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > exp;
  477. return MetaExpV3F<exp>(exp(a,b));
  478. }*/
  479. metainline Vector3<float>
  480. CrossProduct(const Vector3<float>& a, const Vector3<float>& b)
  481. {
  482. return Vector3<float>(
  483. a.y * b.z - a.z * b.y,
  484. a.z * b.x - a.x * b.z,
  485. a.x * b.y - a.y * b.x);
  486. }
  487. // exp . exp
  488. template <typename A, typename B>
  489. metainline float DotProduct(const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
  490. {
  491. return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
  492. }
  493. // exp . vec3f
  494. template <typename A>
  495. metainline float DotProduct(const MetaExpV3F<A>& a, const Vector3<float>& b)
  496. {
  497. return a[0] * b.x + a[1] * b.y + a[2] * b.z;
  498. }
  499. // vec3f . exp
  500. template <typename B>
  501. metainline float DotProduct(const Vector3<float>& a, const MetaExpV3F<B>& b)
  502. {
  503. return a.x * b[0] + a.y * b[1] + a.z * b[2];
  504. }
  505. // vec3f . vec3f
  506. metainline float DotProduct(const Vector3<float>& a, const Vector3<float>& b)
  507. {
  508. return a.x * b.x + a.y * b.y + a.z * b.z;
  509. }
  510. template <typename E>
  511. metainline float LengthSquared(const MetaExpV3F<E>& exp)
  512. {
  513. return DotProduct(exp,exp);
  514. }
  515. template <typename E>
  516. metainline float Length(const MetaExpV3F<E>& exp)
  517. {
  518. return static_cast<float>(sqrt(LengthSquared(exp)));
  519. }
  520. template <typename E>
  521. metainline Vector3<float> Normalize(const MetaExpV3F<E>& exp)
  522. {
  523. float s = LengthSquared(exp);
  524. if ( s == 0 )
  525. return Vector3<float>(0,0,0);
  526. s = 1 / static_cast<float>(sqrt(s));
  527. return Vector3<float>(exp * s);
  528. }
  529. template <typename A, typename B>
  530. metainline Vector3<float> Reflect(const MetaExpV3F<A>& v, const MetaExpV3F<B>& normal)
  531. {
  532. float s = DotProduct(v,normal) * 2;
  533. return Vector3<float>(v + normal * s);
  534. }
  535. template <typename B>
  536. metainline Vector3<float> Reflect(const Vector3<float>& v, const MetaExpV3F<B>& normal)
  537. {
  538. float s = DotProduct(v,normal) * 2;
  539. return Vector3<float>(v + normal * s);
  540. }
  541. template <typename A>
  542. metainline Vector3<float> Reflect(const MetaExpV3F<A>& v, const Vector3<float>& normal)
  543. {
  544. float s = DotProduct(v,normal) * 2;
  545. return Vector3<float>(v + normal * s);
  546. }
  547. template <typename A, typename B>
  548. metainline Vector3<float> Lerp(const MetaExpV3F<A>& a, const MetaExpV3F<B>& b, float time)
  549. {
  550. return Vector3<float>(a + (b - a) * time);
  551. }
  552. template <typename B>
  553. metainline Vector3<float> Lerp(const Vector3<float>& a, const MetaExpV3F<B>& b, float time)
  554. {
  555. return Vector3<float>(a + (b - a) * time);
  556. }
  557. template <typename A>
  558. metainline Vector3<float> Lerp(const MetaExpV3F<A>& a, const Vector3<float>& b, float time)
  559. {
  560. return Vector3<float>(a + (b - a) * time);
  561. }
  562. } // namespace prmath
  563. #undef metainline
  564. #undef PRMATH_METAVECTOR_ENABLE
  565. #endif
  566. #endif