Vec4.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. #ifndef ANKI_MATH_VEC4_H
  2. #define ANKI_MATH_VEC4_H
  3. #include "anki/math/CommonIncludes.h"
  4. namespace anki {
  5. /// @addtogroup Math
  6. /// @{
  7. /// Template struct that gives the type of the TVec4 SIMD
  8. template<typename T>
  9. struct TVec4Simd
  10. {
  11. typedef Array<T, 4> Type;
  12. };
  13. #if ANKI_SIMD == ANKI_SIMD_SSE
  14. // Specialize for F32
  15. template<>
  16. struct TVec4Simd<F32>
  17. {
  18. typedef __m128 Type;
  19. };
  20. #elif ANKI_SIMD == ANKI_SIMD_NEON
  21. // Specialize for F32
  22. template<>
  23. struct TVec4Simd<F32>
  24. {
  25. typedef float32x4_t Type;
  26. };
  27. #endif
  28. /// 4D vector. SIMD optimized
  29. template<typename T>
  30. ANKI_ATTRIBUTE_ALIGNED(class, 16) TVec4
  31. {
  32. /// @name Friends
  33. /// @{
  34. template<typename Y>
  35. friend TVec4<Y> operator+(const Y f, const TVec4<Y>& v4);
  36. template<typename Y>
  37. friend TVec4<Y> operator-(const Y f, const TVec4<Y>& v4);
  38. template<typename Y>
  39. friend TVec4<Y> operator*(const Y f, const TVec4<Y>& v4);
  40. template<typename Y>
  41. friend TVec4<Y> operator/(const Y f, const TVec4<Y>& v4);
  42. /// @}
  43. public:
  44. typedef typename TVec4Simd<T>::Type Simd;
  45. /// @name Constructors
  46. /// @{
  47. explicit TVec4()
  48. {}
  49. explicit TVec4(const T x_, const T y_, const T z_, const T w_)
  50. {
  51. x() = x_;
  52. y() = y_;
  53. z() = z_;
  54. w() = w_;
  55. }
  56. explicit TVec4(const T f)
  57. {
  58. arr[0] = arr[1] = arr[2] = arr[3] = f;
  59. }
  60. explicit TVec4(const T arr_[])
  61. {
  62. arr[0] = arr_[0];
  63. arr[1] = arr_[1];
  64. arr[2] = arr_[2];
  65. arr[3] = arr_[3];
  66. }
  67. explicit TVec4(const TVec2<T>& v2, const T z_, const T w_)
  68. {
  69. x() = v2.x();
  70. y() = v2.y();
  71. z() = z_;
  72. w() = w_;
  73. }
  74. explicit TVec4(const TVec2<T>& av2, const TVec2<T>& bv2)
  75. {
  76. x() = av2.x();
  77. y() = av2.y();
  78. z() = bv2.x();
  79. w() = bv2.y();
  80. }
  81. explicit TVec4(const TVec3<T>& v3, const T w_)
  82. {
  83. x() = v3.x();
  84. y() = v3.y();
  85. z() = v3.z();
  86. w() = w_;
  87. }
  88. TVec4(const TVec4& b)
  89. {
  90. x() = b.x();
  91. y() = b.y();
  92. z() = b.z();
  93. w() = b.w();
  94. }
  95. explicit TVec4(const TQuat<T>& q)
  96. {
  97. x() = q.x();
  98. y() = q.y();
  99. z() = q.z();
  100. w() = q.w();
  101. }
  102. explicit TVec4(const Simd& simd_)
  103. {
  104. simd = simd_;
  105. }
  106. /// @}
  107. /// @name Accessors
  108. /// @{
  109. T& x()
  110. {
  111. return vec.x;
  112. }
  113. T x() const
  114. {
  115. return vec.x;
  116. }
  117. T& y()
  118. {
  119. return vec.y;
  120. }
  121. T y() const
  122. {
  123. return vec.y;
  124. }
  125. T& z()
  126. {
  127. return vec.z;
  128. }
  129. T z() const
  130. {
  131. return vec.z;
  132. }
  133. T& w()
  134. {
  135. return vec.w;
  136. }
  137. T w() const
  138. {
  139. return vec.w;
  140. }
  141. T& operator[](const U i)
  142. {
  143. return arr[i];
  144. }
  145. T operator[](const U i) const
  146. {
  147. return arr[i];
  148. }
  149. TVec2<T> xy() const
  150. {
  151. return TVec2<T>(x(), y());
  152. }
  153. TVec3<T> xyz() const
  154. {
  155. return TVec3<T>(x(), y(), z());
  156. }
  157. Simd& getSimd()
  158. {
  159. return simd;
  160. }
  161. const Simd& getSimd() const
  162. {
  163. return simd;
  164. }
  165. /// @}
  166. /// @name Operators with same type
  167. /// @{
  168. TVec4& operator=(const TVec4& b)
  169. {
  170. x() = b.x();
  171. y() = b.y();
  172. z() = b.z();
  173. w() = b.w();
  174. return (*this);
  175. }
  176. TVec4 operator+(const TVec4& b) const
  177. {
  178. return TVec4(x() + b.x(), y() + b.y(), z() + b.z(), w() + b.w());
  179. }
  180. TVec4& operator+=(const TVec4& b)
  181. {
  182. x() += b.x();
  183. y() += b.y();
  184. z() += b.z();
  185. w() += b.w();
  186. return (*this);
  187. }
  188. TVec4 operator-(const TVec4& b) const
  189. {
  190. return TVec4(x() - b.x(), y() - b.y(), z() - b.z(), w() - b.w());
  191. }
  192. TVec4& operator-=(const TVec4& b)
  193. {
  194. x() -= b.x();
  195. y() -= b.y();
  196. z() -= b.z();
  197. w() -= b.w();
  198. return (*this);
  199. }
  200. TVec4 operator*(const TVec4& b) const
  201. {
  202. return TVec4(x() * b.x(), y() * b.y(), z() * b.z(), w() * b.w());
  203. }
  204. TVec4& operator*=(const TVec4& b)
  205. {
  206. x() *= b.x();
  207. y() *= b.y();
  208. z() *= b.z();
  209. w() *= b.w();
  210. return (*this);
  211. }
  212. TVec4 operator/(const TVec4& b) const
  213. {
  214. return TVec4(x() / b.x(), y() / b.y(), z() / b.z(), w() / b.w());
  215. }
  216. TVec4& operator/=(const TVec4& b)
  217. {
  218. x() /= b.x();
  219. y() /= b.y();
  220. z() /= b.z();
  221. w() /= b.w();
  222. return (*this);
  223. }
  224. TVec4 operator-() const
  225. {
  226. return TVec4(-x(), -y(), -z(), -w());
  227. }
  228. Bool operator==(const TVec4& b) const
  229. {
  230. TVec4 sub = (*this) - b;
  231. return isZero<T>(sub.x())
  232. && isZero<T>(sub.y())
  233. && isZero<T>(sub.z())
  234. && isZero<T>(sub.w());
  235. }
  236. Bool operator!=(const TVec4& b) const
  237. {
  238. return !operator==(b);
  239. }
  240. Bool operator<(const TVec4& b) const
  241. {
  242. return x() < b.x() && y() < b.y() && z() < b.z() && w() < b.w();
  243. }
  244. Bool operator<=(const TVec4& b) const
  245. {
  246. return x() <= b.x() && y() <= b.y() && z() <= b.z() && w() <= b.w();
  247. }
  248. Bool operator>(const TVec4& b) const
  249. {
  250. return x() > b.x() && y() > b.y() && z() > b.z() && w() > b.w();
  251. }
  252. Bool operator>=(const TVec4& b) const
  253. {
  254. return x() >= b.x() && y() >= b.y() && z() >= b.z() && w() >= b.w();
  255. }
  256. /// @}
  257. /// @name Operators with T
  258. /// @{
  259. TVec4 operator+(const T f) const
  260. {
  261. return (*this) + TVec4(f);
  262. }
  263. TVec4& operator+=(const T f)
  264. {
  265. (*this) += TVec4(f);
  266. return (*this);
  267. }
  268. TVec4 operator-(const T f) const
  269. {
  270. return (*this) - TVec4(f);
  271. }
  272. TVec4& operator-=(const T f)
  273. {
  274. (*this) -= TVec4(f);
  275. return (*this);
  276. }
  277. TVec4 operator*(const T f) const
  278. {
  279. return (*this) * TVec4(f);
  280. }
  281. TVec4& operator*=(const T f)
  282. {
  283. (*this) *= TVec4(f);
  284. return (*this);
  285. }
  286. TVec4 operator/(const T f) const
  287. {
  288. return (*this) / TVec4(f);
  289. }
  290. TVec4& operator/=(const T f)
  291. {
  292. (*this) /= TVec4(f);
  293. return (*this);
  294. }
  295. /// @}
  296. /// @name Operators with other
  297. /// @{
  298. /// @note 16 muls 12 adds
  299. TVec4 operator*(const TMat4<T>& m4) const
  300. {
  301. return TVec4(
  302. x() * m4(0, 0) + y() * m4(1, 0) + z() * m4(2, 0) + w() * m4(3, 0),
  303. x() * m4(0, 1) + y() * m4(1, 1) + z() * m4(2, 1) + w() * m4(3, 1),
  304. x() * m4(0, 2) + y() * m4(1, 2) + z() * m4(2, 2) + w() * m4(3, 2),
  305. x() * m4(0, 3) + y() * m4(1, 3) + z() * m4(2, 3) + w() * m4(3, 3));
  306. }
  307. /// @}
  308. /// @name Other
  309. /// @{
  310. T getLength() const
  311. {
  312. return sqrt<T>(dot(*this));
  313. }
  314. TVec4 getNormalized() const
  315. {
  316. return (*this) / getLength();
  317. }
  318. void normalize()
  319. {
  320. (*this) /= getLength();
  321. }
  322. T dot(const TVec4& b) const
  323. {
  324. return x() * b.x() + y() * b.y() + z() * b.z() + w() * b.w();
  325. }
  326. /// @}
  327. private:
  328. /// @name Data
  329. /// @{
  330. union
  331. {
  332. struct
  333. {
  334. T x, y, z, w;
  335. } vec;
  336. Array<T, 4> arr;
  337. Simd simd;
  338. };
  339. /// @}
  340. };
  341. #if ANKI_SIMD == ANKI_SIMD_SSE
  342. // Forward declare specializations
  343. template<>
  344. TVec4<F32>::TVec4(F32 f);
  345. template<>
  346. TVec4<F32>::TVec4(const F32 arr_[]);
  347. template<>
  348. TVec4<F32>::TVec4(const F32 x_, const F32 y_, const F32 z_, const F32 w_);
  349. template<>
  350. TVec4<F32>::TVec4(const TVec4<F32>& b);
  351. template<>
  352. TVec4<F32>& TVec4<F32>::operator=(const TVec4<F32>& b);
  353. template<>
  354. TVec4<F32> TVec4<F32>::operator+(const TVec4<F32>& b) const;
  355. template<>
  356. TVec4<F32>& TVec4<F32>::operator+=(const TVec4<F32>& b);
  357. template<>
  358. TVec4<F32> TVec4<F32>::operator-(const TVec4<F32>& b) const;
  359. template<>
  360. TVec4<F32>& TVec4<F32>::operator-=(const TVec4<F32>& b);
  361. template<>
  362. TVec4<F32> TVec4<F32>::operator*(const TVec4<F32>& b) const;
  363. template<>
  364. TVec4<F32>& TVec4<F32>::operator*=(const TVec4<F32>& b);
  365. template<>
  366. TVec4<F32> TVec4<F32>::operator/(const TVec4<F32>& b) const;
  367. template<>
  368. TVec4<F32>& TVec4<F32>::operator/=(const TVec4<F32>& b);
  369. template<>
  370. F32 TVec4<F32>::dot(const TVec4<F32>& b) const;
  371. template<>
  372. TVec4<F32> TVec4<F32>::getNormalized() const;
  373. template<>
  374. void TVec4<F32>::normalize();
  375. #elif ANKI_SIMD == ANKI_SIMD_NEON
  376. template<>
  377. TVec4<F32>::TVec4(F32 f);
  378. template<>
  379. TVec4<F32>::TVec4(const F32 arr_[]);
  380. template<>
  381. TVec4<F32>::TVec4(const TVec4<F32>& b);
  382. template<>
  383. TVec4<F32>& TVec4<F32>::operator=(const TVec4<F32>& b);
  384. template<>
  385. TVec4<F32> TVec4<F32>::operator+(const TVec4<F32>& b) const;
  386. template<>
  387. TVec4<F32>& TVec4<F32>::operator+=(const TVec4<F32>& b);
  388. template<>
  389. TVec4<F32> TVec4<F32>::operator-(const TVec4<F32>& b) const;
  390. template<>
  391. TVec4<F32>& TVec4<F32>::operator-=(const TVec4<F32>& b);
  392. template<>
  393. TVec4<F32> TVec4<F32>::operator*(const TVec4<F32>& b) const;
  394. template<>
  395. TVec4<F32>& TVec4<F32>::operator*=(const TVec4<F32>& b);
  396. template<>
  397. TVec4<F32> operator*(const F32 f) const;
  398. template<>
  399. TVec4<F32>& operator*=(const F32 f);
  400. template<>
  401. F32 TVec4<F32>::dot(const TVec4<F32>& b) const;
  402. template<>
  403. TVec4<F32> TVec4<F32>::getNormalized() const;
  404. template<>
  405. void TVec4<F32>::normalize();
  406. #endif
  407. /// F32 4D vector
  408. typedef TVec4<F32> Vec4;
  409. static_assert(sizeof(Vec4) == sizeof(F32) * 4, "Incorrect size");
  410. /// Half float 4D vector
  411. typedef TVec4<F16> HVec4;
  412. /// 32bit signed integer 4D vector
  413. typedef TVec4<I32> IVec4;
  414. /// 32bit unsigned integer 4D vector
  415. typedef TVec4<U32> UVec4;
  416. /// @}
  417. } // end namespace anki
  418. #include "anki/math/Vec4.inl.h"
  419. #endif