math.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. // Licensed under GPLv2
  2. // Refer to the license.txt file included.
  3. // Copyright 2014 Tony Wasserka
  4. // All rights reserved.
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions are met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above copyright
  12. // notice, this list of conditions and the following disclaimer in the
  13. // documentation and/or other materials provided with the distribution.
  14. // * Neither the name of the owner nor the names of its contributors may
  15. // be used to endorse or promote products derived from this software
  16. // without specific prior written permission.
  17. //
  18. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. #pragma once
  30. #include <cmath>
  31. namespace Math {
  32. template<typename T> class Vec2;
  33. template<typename T> class Vec3;
  34. template<typename T> class Vec4;
  35. template<typename T>
  36. class Vec2 {
  37. public:
  38. struct {
  39. T x,y;
  40. };
  41. T* AsArray() { return &x; }
  42. Vec2() = default;
  43. Vec2(const T a[2]) : x(a[0]), y(a[1]) {}
  44. Vec2(const T& _x, const T& _y) : x(_x), y(_y) {}
  45. template<typename T2>
  46. Vec2<T2> Cast() const {
  47. return Vec2<T2>((T2)x, (T2)y);
  48. }
  49. static Vec2 AssignToAll(const T& f)
  50. {
  51. return Vec2<T>(f, f);
  52. }
  53. void Write(T a[2])
  54. {
  55. a[0] = x; a[1] = y;
  56. }
  57. Vec2 operator +(const Vec2& other) const
  58. {
  59. return Vec2(x+other.x, y+other.y);
  60. }
  61. void operator += (const Vec2 &other)
  62. {
  63. x+=other.x; y+=other.y;
  64. }
  65. Vec2 operator -(const Vec2& other) const
  66. {
  67. return Vec2(x-other.x, y-other.y);
  68. }
  69. void operator -= (const Vec2& other)
  70. {
  71. x-=other.x; y-=other.y;
  72. }
  73. Vec2 operator -() const
  74. {
  75. return Vec2(-x,-y);
  76. }
  77. Vec2 operator * (const Vec2& other) const
  78. {
  79. return Vec2(x*other.x, y*other.y);
  80. }
  81. template<typename V>
  82. Vec2 operator * (const V& f) const
  83. {
  84. return Vec2(x*f,y*f);
  85. }
  86. template<typename V>
  87. void operator *= (const V& f)
  88. {
  89. x*=f; y*=f;
  90. }
  91. template<typename V>
  92. Vec2 operator / (const V& f) const
  93. {
  94. return Vec2(x/f,y/f);
  95. }
  96. template<typename V>
  97. void operator /= (const V& f)
  98. {
  99. *this = *this / f;
  100. }
  101. T Length2() const
  102. {
  103. return x*x + y*y;
  104. }
  105. // Only implemented for T=float
  106. float Length() const;
  107. void SetLength(const float l);
  108. Vec2 WithLength(const float l) const;
  109. float Distance2To(Vec2 &other);
  110. Vec2 Normalized() const;
  111. float Normalize(); // returns the previous length, which is often useful
  112. T& operator [] (int i) //allow vector[1] = 3 (vector.y=3)
  113. {
  114. return *((&x) + i);
  115. }
  116. T operator [] (const int i) const
  117. {
  118. return *((&x) + i);
  119. }
  120. void SetZero()
  121. {
  122. x=0; y=0;
  123. }
  124. // Common aliases: UV (texel coordinates), ST (texture coordinates)
  125. T& u() { return x; }
  126. T& v() { return y; }
  127. T& s() { return x; }
  128. T& t() { return y; }
  129. const T& u() const { return x; }
  130. const T& v() const { return y; }
  131. const T& s() const { return x; }
  132. const T& t() const { return y; }
  133. // swizzlers - create a subvector of specific components
  134. Vec2 yx() const { return Vec2(y, x); }
  135. Vec2 vu() const { return Vec2(y, x); }
  136. Vec2 ts() const { return Vec2(y, x); }
  137. // Inserters to add new elements to effectively create larger vectors containing this Vec2
  138. Vec3<T> InsertBeforeX(const T& value) {
  139. return Vec3<T>(value, x, y);
  140. }
  141. Vec3<T> InsertBeforeY(const T& value) {
  142. return Vec3<T>(x, value, y);
  143. }
  144. Vec3<T> Append(const T& value) {
  145. return Vec3<T>(x, y, value);
  146. }
  147. };
  148. template<typename T, typename V>
  149. Vec2<T> operator * (const V& f, const Vec2<T>& vec)
  150. {
  151. return Vec2<T>(f*vec.x,f*vec.y);
  152. }
  153. typedef Vec2<float> Vec2f;
  154. template<typename T>
  155. class Vec3
  156. {
  157. public:
  158. struct
  159. {
  160. T x,y,z;
  161. };
  162. T* AsArray() { return &x; }
  163. Vec3() = default;
  164. Vec3(const T a[3]) : x(a[0]), y(a[1]), z(a[2]) {}
  165. Vec3(const T& _x, const T& _y, const T& _z) : x(_x), y(_y), z(_z) {}
  166. template<typename T2>
  167. Vec3<T2> Cast() const {
  168. return Vec3<T2>((T2)x, (T2)y, (T2)z);
  169. }
  170. // Only implemented for T=int and T=float
  171. static Vec3 FromRGB(unsigned int rgb);
  172. unsigned int ToRGB() const; // alpha bits set to zero
  173. static Vec3 AssignToAll(const T& f)
  174. {
  175. return Vec3<T>(f, f, f);
  176. }
  177. void Write(T a[3])
  178. {
  179. a[0] = x; a[1] = y; a[2] = z;
  180. }
  181. Vec3 operator +(const Vec3 &other) const
  182. {
  183. return Vec3(x+other.x, y+other.y, z+other.z);
  184. }
  185. void operator += (const Vec3 &other)
  186. {
  187. x+=other.x; y+=other.y; z+=other.z;
  188. }
  189. Vec3 operator -(const Vec3 &other) const
  190. {
  191. return Vec3(x-other.x, y-other.y, z-other.z);
  192. }
  193. void operator -= (const Vec3 &other)
  194. {
  195. x-=other.x; y-=other.y; z-=other.z;
  196. }
  197. Vec3 operator -() const
  198. {
  199. return Vec3(-x,-y,-z);
  200. }
  201. Vec3 operator * (const Vec3 &other) const
  202. {
  203. return Vec3(x*other.x, y*other.y, z*other.z);
  204. }
  205. template<typename V>
  206. Vec3 operator * (const V& f) const
  207. {
  208. return Vec3(x*f,y*f,z*f);
  209. }
  210. template<typename V>
  211. void operator *= (const V& f)
  212. {
  213. x*=f; y*=f; z*=f;
  214. }
  215. template<typename V>
  216. Vec3 operator / (const V& f) const
  217. {
  218. return Vec3(x/f,y/f,z/f);
  219. }
  220. template<typename V>
  221. void operator /= (const V& f)
  222. {
  223. *this = *this / f;
  224. }
  225. T Length2() const
  226. {
  227. return x*x + y*y + z*z;
  228. }
  229. // Only implemented for T=float
  230. float Length() const;
  231. void SetLength(const float l);
  232. Vec3 WithLength(const float l) const;
  233. float Distance2To(Vec3 &other);
  234. Vec3 Normalized() const;
  235. float Normalize(); // returns the previous length, which is often useful
  236. T& operator [] (int i) //allow vector[2] = 3 (vector.z=3)
  237. {
  238. return *((&x) + i);
  239. }
  240. T operator [] (const int i) const
  241. {
  242. return *((&x) + i);
  243. }
  244. void SetZero()
  245. {
  246. x=0; y=0; z=0;
  247. }
  248. // Common aliases: UVW (texel coordinates), RGB (colors), STQ (texture coordinates)
  249. T& u() { return x; }
  250. T& v() { return y; }
  251. T& w() { return z; }
  252. T& r() { return x; }
  253. T& g() { return y; }
  254. T& b() { return z; }
  255. T& s() { return x; }
  256. T& t() { return y; }
  257. T& q() { return z; }
  258. const T& u() const { return x; }
  259. const T& v() const { return y; }
  260. const T& w() const { return z; }
  261. const T& r() const { return x; }
  262. const T& g() const { return y; }
  263. const T& b() const { return z; }
  264. const T& s() const { return x; }
  265. const T& t() const { return y; }
  266. const T& q() const { return z; }
  267. // swizzlers - create a subvector of specific components
  268. // e.g. Vec2 uv() { return Vec2(x,y); }
  269. // _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all component names (x<->r) and permutations (xy<->yx)
  270. #define _DEFINE_SWIZZLER2(a, b, name) Vec2<T> name() const { return Vec2<T>(a, b); }
  271. #define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \
  272. _DEFINE_SWIZZLER2(a, b, a##b); \
  273. _DEFINE_SWIZZLER2(a, b, a2##b2); \
  274. _DEFINE_SWIZZLER2(a, b, a3##b3); \
  275. _DEFINE_SWIZZLER2(a, b, a4##b4); \
  276. _DEFINE_SWIZZLER2(b, a, b##a); \
  277. _DEFINE_SWIZZLER2(b, a, b2##a2); \
  278. _DEFINE_SWIZZLER2(b, a, b3##a3); \
  279. _DEFINE_SWIZZLER2(b, a, b4##a4);
  280. DEFINE_SWIZZLER2(x, y, r, g, u, v, s, t);
  281. DEFINE_SWIZZLER2(x, z, r, b, u, w, s, q);
  282. DEFINE_SWIZZLER2(y, z, g, b, v, w, t, q);
  283. #undef DEFINE_SWIZZLER2
  284. #undef _DEFINE_SWIZZLER2
  285. // Inserters to add new elements to effectively create larger vectors containing this Vec2
  286. Vec4<T> InsertBeforeX(const T& value) {
  287. return Vec4<T>(value, x, y, z);
  288. }
  289. Vec4<T> InsertBeforeY(const T& value) {
  290. return Vec4<T>(x, value, y, z);
  291. }
  292. Vec4<T> InsertBeforeZ(const T& value) {
  293. return Vec4<T>(x, y, value, z);
  294. }
  295. Vec4<T> Append(const T& value) {
  296. return Vec4<T>(x, y, z, value);
  297. }
  298. };
  299. template<typename T, typename V>
  300. Vec3<T> operator * (const V& f, const Vec3<T>& vec)
  301. {
  302. return Vec3<T>(f*vec.x,f*vec.y,f*vec.z);
  303. }
  304. typedef Vec3<float> Vec3f;
  305. template<typename T>
  306. class Vec4
  307. {
  308. public:
  309. struct
  310. {
  311. T x,y,z,w;
  312. };
  313. T* AsArray() { return &x; }
  314. Vec4() = default;
  315. Vec4(const T a[4]) : x(a[0]), y(a[1]), z(a[2]), w(a[3]) {}
  316. Vec4(const T& _x, const T& _y, const T& _z, const T& _w) : x(_x), y(_y), z(_z), w(_w) {}
  317. template<typename T2>
  318. Vec4<T2> Cast() const {
  319. return Vec4<T2>((T2)x, (T2)y, (T2)z, (T2)w);
  320. }
  321. // Only implemented for T=int and T=float
  322. static Vec4 FromRGBA(unsigned int rgba);
  323. unsigned int ToRGBA() const;
  324. static Vec4 AssignToAll(const T& f) {
  325. return Vec4<T>(f, f, f, f);
  326. }
  327. void Write(T a[4])
  328. {
  329. a[0] = x; a[1] = y; a[2] = z; a[3] = w;
  330. }
  331. Vec4 operator +(const Vec4& other) const
  332. {
  333. return Vec4(x+other.x, y+other.y, z+other.z, w+other.w);
  334. }
  335. void operator += (const Vec4& other)
  336. {
  337. x+=other.x; y+=other.y; z+=other.z; w+=other.w;
  338. }
  339. Vec4 operator -(const Vec4 &other) const
  340. {
  341. return Vec4(x-other.x, y-other.y, z-other.z, w-other.w);
  342. }
  343. void operator -= (const Vec4 &other)
  344. {
  345. x-=other.x; y-=other.y; z-=other.z; w-=other.w;
  346. }
  347. Vec4 operator -() const
  348. {
  349. return Vec4(-x,-y,-z,-w);
  350. }
  351. Vec4 operator * (const Vec4 &other) const
  352. {
  353. return Vec4(x*other.x, y*other.y, z*other.z, w*other.w);
  354. }
  355. template<typename V>
  356. Vec4 operator * (const V& f) const
  357. {
  358. return Vec4(x*f,y*f,z*f,w*f);
  359. }
  360. template<typename V>
  361. void operator *= (const V& f)
  362. {
  363. x*=f; y*=f; z*=f; w*=f;
  364. }
  365. template<typename V>
  366. Vec4 operator / (const V& f) const
  367. {
  368. return Vec4(x/f,y/f,z/f,w/f);
  369. }
  370. template<typename V>
  371. void operator /= (const V& f)
  372. {
  373. *this = *this / f;
  374. }
  375. T Length2() const
  376. {
  377. return x*x + y*y + z*z + w*w;
  378. }
  379. // Only implemented for T=float
  380. float Length() const;
  381. void SetLength(const float l);
  382. Vec4 WithLength(const float l) const;
  383. float Distance2To(Vec4 &other);
  384. Vec4 Normalized() const;
  385. float Normalize(); // returns the previous length, which is often useful
  386. T& operator [] (int i) //allow vector[2] = 3 (vector.z=3)
  387. {
  388. return *((&x) + i);
  389. }
  390. T operator [] (const int i) const
  391. {
  392. return *((&x) + i);
  393. }
  394. void SetZero()
  395. {
  396. x=0; y=0; z=0;
  397. }
  398. // Common alias: RGBA (colors)
  399. T& r() { return x; }
  400. T& g() { return y; }
  401. T& b() { return z; }
  402. T& a() { return w; }
  403. const T& r() const { return x; }
  404. const T& g() const { return y; }
  405. const T& b() const { return z; }
  406. const T& a() const { return w; }
  407. // swizzlers - create a subvector of specific components
  408. // e.g. Vec2 uv() { return Vec2(x,y); }
  409. // _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all component names (x<->r) and permutations (xy<->yx)
  410. #define _DEFINE_SWIZZLER2(a, b, name) Vec2<T> name() const { return Vec2<T>(a, b); }
  411. #define DEFINE_SWIZZLER2(a, b, a2, b2) \
  412. _DEFINE_SWIZZLER2(a, b, a##b); \
  413. _DEFINE_SWIZZLER2(a, b, a2##b2); \
  414. _DEFINE_SWIZZLER2(b, a, b##a); \
  415. _DEFINE_SWIZZLER2(b, a, b2##a2);
  416. DEFINE_SWIZZLER2(x, y, r, g);
  417. DEFINE_SWIZZLER2(x, z, r, b);
  418. DEFINE_SWIZZLER2(x, w, r, a);
  419. DEFINE_SWIZZLER2(y, z, g, b);
  420. DEFINE_SWIZZLER2(y, w, g, a);
  421. DEFINE_SWIZZLER2(z, w, b, a);
  422. #undef DEFINE_SWIZZLER2
  423. #undef _DEFINE_SWIZZLER2
  424. #define _DEFINE_SWIZZLER3(a, b, c, name) Vec3<T> name() const { return Vec3<T>(a, b, c); }
  425. #define DEFINE_SWIZZLER3(a, b, c, a2, b2, c2) \
  426. _DEFINE_SWIZZLER3(a, b, c, a##b##c); \
  427. _DEFINE_SWIZZLER3(a, c, b, a##c##b); \
  428. _DEFINE_SWIZZLER3(b, a, c, b##a##c); \
  429. _DEFINE_SWIZZLER3(b, c, a, b##c##a); \
  430. _DEFINE_SWIZZLER3(c, a, b, c##a##b); \
  431. _DEFINE_SWIZZLER3(c, b, a, c##b##a); \
  432. _DEFINE_SWIZZLER3(a, b, c, a2##b2##c2); \
  433. _DEFINE_SWIZZLER3(a, c, b, a2##c2##b2); \
  434. _DEFINE_SWIZZLER3(b, a, c, b2##a2##c2); \
  435. _DEFINE_SWIZZLER3(b, c, a, b2##c2##a2); \
  436. _DEFINE_SWIZZLER3(c, a, b, c2##a2##b2); \
  437. _DEFINE_SWIZZLER3(c, b, a, c2##b2##a2);
  438. DEFINE_SWIZZLER3(x, y, z, r, g, b);
  439. DEFINE_SWIZZLER3(x, y, w, r, g, a);
  440. DEFINE_SWIZZLER3(x, z, w, r, b, a);
  441. DEFINE_SWIZZLER3(y, z, w, g, b, a);
  442. #undef DEFINE_SWIZZLER3
  443. #undef _DEFINE_SWIZZLER3
  444. };
  445. template<typename T, typename V>
  446. Vec4<T> operator * (const V& f, const Vec4<T>& vec)
  447. {
  448. return Vec4<T>(f*vec.x,f*vec.y,f*vec.z,f*vec.w);
  449. }
  450. typedef Vec4<float> Vec4f;
  451. template<typename T>
  452. static inline T Dot(const Vec2<T>& a, const Vec2<T>& b)
  453. {
  454. return a.x*b.x + a.y*b.y;
  455. }
  456. template<typename T>
  457. static inline T Dot(const Vec3<T>& a, const Vec3<T>& b)
  458. {
  459. return a.x*b.x + a.y*b.y + a.z*b.z;
  460. }
  461. template<typename T>
  462. static inline T Dot(const Vec4<T>& a, const Vec4<T>& b)
  463. {
  464. return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w;
  465. }
  466. template<typename T>
  467. static inline Vec3<T> Cross(const Vec3<T>& a, const Vec3<T>& b)
  468. {
  469. 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);
  470. }
  471. // linear interpolation via float: 0.0=begin, 1.0=end
  472. template<typename X>
  473. static inline X Lerp(const X& begin, const X& end, const float t)
  474. {
  475. return begin*(1.f-t) + end*t;
  476. }
  477. // linear interpolation via int: 0=begin, base=end
  478. template<typename X, int base>
  479. static inline X LerpInt(const X& begin, const X& end, const int t)
  480. {
  481. return (begin*(base-t) + end*t) / base;
  482. }
  483. // Utility vector factories
  484. template<typename T>
  485. static inline Vec2<T> MakeVec2(const T& x, const T& y)
  486. {
  487. return Vec2<T>{x, y};
  488. }
  489. template<typename T>
  490. static inline Vec3<T> MakeVec3(const T& x, const T& y, const T& z)
  491. {
  492. return Vec3<T>{x, y, z};
  493. }
  494. template<typename T>
  495. static inline Vec4<T> MakeVec4(const T& x, const T& y, const T& z, const T& w)
  496. {
  497. return Vec4<T>{x, y, z, w};
  498. }
  499. } // namespace