vec.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /*
  2. * Copyright (C) 2011 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef ANDROID_VEC_H
  17. #define ANDROID_VEC_H
  18. #include <math.h>
  19. #include <stdint.h>
  20. #include <stddef.h>
  21. #include "traits.h"
  22. // -----------------------------------------------------------------------
  23. #define PURE __attribute__((pure))
  24. namespace android {
  25. // -----------------------------------------------------------------------
  26. // non-inline helpers
  27. template <typename TYPE, size_t SIZE>
  28. class vec;
  29. template <typename TYPE, size_t SIZE>
  30. class vbase;
  31. namespace helpers {
  32. template <typename T> inline T min(T a, T b) { return a<b ? a : b; }
  33. template <typename T> inline T max(T a, T b) { return a>b ? a : b; }
  34. template < template<typename T, size_t S> class VEC,
  35. typename TYPE, size_t SIZE, size_t S>
  36. vec<TYPE, SIZE>& doAssign(
  37. vec<TYPE, SIZE>& lhs, const VEC<TYPE, S>& rhs) {
  38. const size_t minSize = min(SIZE, S);
  39. const size_t maxSize = max(SIZE, S);
  40. for (size_t i=0 ; i<minSize ; i++)
  41. lhs[i] = rhs[i];
  42. for (size_t i=minSize ; i<maxSize ; i++)
  43. lhs[i] = 0;
  44. return lhs;
  45. }
  46. template <
  47. template<typename T, size_t S> class VLHS,
  48. template<typename T, size_t S> class VRHS,
  49. typename TYPE,
  50. size_t SIZE
  51. >
  52. VLHS<TYPE, SIZE> PURE doAdd(
  53. const VLHS<TYPE, SIZE>& lhs,
  54. const VRHS<TYPE, SIZE>& rhs) {
  55. VLHS<TYPE, SIZE> r;
  56. for (size_t i=0 ; i<SIZE ; i++)
  57. r[i] = lhs[i] + rhs[i];
  58. return r;
  59. }
  60. template <
  61. template<typename T, size_t S> class VLHS,
  62. template<typename T, size_t S> class VRHS,
  63. typename TYPE,
  64. size_t SIZE
  65. >
  66. VLHS<TYPE, SIZE> PURE doSub(
  67. const VLHS<TYPE, SIZE>& lhs,
  68. const VRHS<TYPE, SIZE>& rhs) {
  69. VLHS<TYPE, SIZE> r;
  70. for (size_t i=0 ; i<SIZE ; i++)
  71. r[i] = lhs[i] - rhs[i];
  72. return r;
  73. }
  74. template <
  75. template<typename T, size_t S> class VEC,
  76. typename TYPE,
  77. size_t SIZE
  78. >
  79. VEC<TYPE, SIZE> PURE doMulScalar(
  80. const VEC<TYPE, SIZE>& lhs,
  81. typename TypeTraits<TYPE>::ParameterType rhs) {
  82. VEC<TYPE, SIZE> r;
  83. for (size_t i=0 ; i<SIZE ; i++)
  84. r[i] = lhs[i] * rhs;
  85. return r;
  86. }
  87. template <
  88. template<typename T, size_t S> class VEC,
  89. typename TYPE,
  90. size_t SIZE
  91. >
  92. VEC<TYPE, SIZE> PURE doScalarMul(
  93. typename TypeTraits<TYPE>::ParameterType lhs,
  94. const VEC<TYPE, SIZE>& rhs) {
  95. VEC<TYPE, SIZE> r;
  96. for (size_t i=0 ; i<SIZE ; i++)
  97. r[i] = lhs * rhs[i];
  98. return r;
  99. }
  100. }; // namespace helpers
  101. // -----------------------------------------------------------------------
  102. // Below we define the mathematical operators for vectors.
  103. // We use template template arguments so we can generically
  104. // handle the case where the right-hand-size and left-hand-side are
  105. // different vector types (but with same value_type and size).
  106. // This is needed for performance when using ".xy{z}" element access
  107. // on vec<>. Without this, an extra conversion to vec<> would be needed.
  108. //
  109. // example:
  110. // vec4_t a;
  111. // vec3_t b;
  112. // vec3_t c = a.xyz + b;
  113. //
  114. // "a.xyz + b" is a mixed-operation between a vbase<> and a vec<>, requiring
  115. // a conversion of vbase<> to vec<>. The template gunk below avoids this,
  116. // by allowing the addition on these different vector types directly
  117. //
  118. template <
  119. template<typename T, size_t S> class VLHS,
  120. template<typename T, size_t S> class VRHS,
  121. typename TYPE,
  122. size_t SIZE
  123. >
  124. inline VLHS<TYPE, SIZE> PURE operator + (
  125. const VLHS<TYPE, SIZE>& lhs,
  126. const VRHS<TYPE, SIZE>& rhs) {
  127. return helpers::doAdd(lhs, rhs);
  128. }
  129. template <
  130. template<typename T, size_t S> class VLHS,
  131. template<typename T, size_t S> class VRHS,
  132. typename TYPE,
  133. size_t SIZE
  134. >
  135. inline VLHS<TYPE, SIZE> PURE operator - (
  136. const VLHS<TYPE, SIZE>& lhs,
  137. const VRHS<TYPE, SIZE>& rhs) {
  138. return helpers::doSub(lhs, rhs);
  139. }
  140. template <
  141. template<typename T, size_t S> class VEC,
  142. typename TYPE,
  143. size_t SIZE
  144. >
  145. inline VEC<TYPE, SIZE> PURE operator * (
  146. const VEC<TYPE, SIZE>& lhs,
  147. typename TypeTraits<TYPE>::ParameterType rhs) {
  148. return helpers::doMulScalar(lhs, rhs);
  149. }
  150. template <
  151. template<typename T, size_t S> class VEC,
  152. typename TYPE,
  153. size_t SIZE
  154. >
  155. inline VEC<TYPE, SIZE> PURE operator * (
  156. typename TypeTraits<TYPE>::ParameterType lhs,
  157. const VEC<TYPE, SIZE>& rhs) {
  158. return helpers::doScalarMul(lhs, rhs);
  159. }
  160. template <
  161. template<typename T, size_t S> class VLHS,
  162. template<typename T, size_t S> class VRHS,
  163. typename TYPE,
  164. size_t SIZE
  165. >
  166. TYPE PURE dot_product(
  167. const VLHS<TYPE, SIZE>& lhs,
  168. const VRHS<TYPE, SIZE>& rhs) {
  169. TYPE r(0);
  170. for (size_t i=0 ; i<SIZE ; i++)
  171. r += lhs[i] * rhs[i];
  172. return r;
  173. }
  174. template <
  175. template<typename T, size_t S> class V,
  176. typename TYPE,
  177. size_t SIZE
  178. >
  179. TYPE PURE length(const V<TYPE, SIZE>& v) {
  180. return sqrt(dot_product(v, v));
  181. }
  182. template <
  183. template<typename T, size_t S> class V,
  184. typename TYPE,
  185. size_t SIZE
  186. >
  187. TYPE PURE length_squared(const V<TYPE, SIZE>& v) {
  188. return dot_product(v, v);
  189. }
  190. template <
  191. template<typename T, size_t S> class V,
  192. typename TYPE,
  193. size_t SIZE
  194. >
  195. V<TYPE, SIZE> PURE normalize(const V<TYPE, SIZE>& v) {
  196. return v * (1/length(v));
  197. }
  198. template <
  199. template<typename T, size_t S> class VLHS,
  200. template<typename T, size_t S> class VRHS,
  201. typename TYPE
  202. >
  203. VLHS<TYPE, 3> PURE cross_product(
  204. const VLHS<TYPE, 3>& u,
  205. const VRHS<TYPE, 3>& v) {
  206. VLHS<TYPE, 3> r;
  207. r.x = u.y*v.z - u.z*v.y;
  208. r.y = u.z*v.x - u.x*v.z;
  209. r.z = u.x*v.y - u.y*v.x;
  210. return r;
  211. }
  212. template <typename TYPE, size_t SIZE>
  213. vec<TYPE, SIZE> PURE operator - (const vec<TYPE, SIZE>& lhs) {
  214. vec<TYPE, SIZE> r;
  215. for (size_t i=0 ; i<SIZE ; i++)
  216. r[i] = -lhs[i];
  217. return r;
  218. }
  219. // -----------------------------------------------------------------------
  220. // This our basic vector type, it just implements the data storage
  221. // and accessors.
  222. template <typename TYPE, size_t SIZE>
  223. struct vbase {
  224. TYPE v[SIZE];
  225. inline const TYPE& operator[](size_t i) const { return v[i]; }
  226. inline TYPE& operator[](size_t i) { return v[i]; }
  227. };
  228. template<> struct vbase<float, 2> {
  229. union {
  230. float v[2];
  231. struct { float x, y; };
  232. struct { float s, t; };
  233. };
  234. inline const float& operator[](size_t i) const { return v[i]; }
  235. inline float& operator[](size_t i) { return v[i]; }
  236. };
  237. template<> struct vbase<float, 3> {
  238. union {
  239. float v[3];
  240. struct { float x, y, z; };
  241. struct { float s, t, r; };
  242. vbase<float, 2> xy;
  243. vbase<float, 2> st;
  244. };
  245. inline const float& operator[](size_t i) const { return v[i]; }
  246. inline float& operator[](size_t i) { return v[i]; }
  247. };
  248. template<> struct vbase<float, 4> {
  249. union {
  250. float v[4];
  251. struct { float x, y, z, w; };
  252. struct { float s, t, r, q; };
  253. vbase<float, 3> xyz;
  254. vbase<float, 3> str;
  255. vbase<float, 2> xy;
  256. vbase<float, 2> st;
  257. };
  258. inline const float& operator[](size_t i) const { return v[i]; }
  259. inline float& operator[](size_t i) { return v[i]; }
  260. };
  261. // -----------------------------------------------------------------------
  262. template <typename TYPE, size_t SIZE>
  263. class vec : public vbase<TYPE, SIZE>
  264. {
  265. typedef typename TypeTraits<TYPE>::ParameterType pTYPE;
  266. typedef vbase<TYPE, SIZE> base;
  267. public:
  268. // STL-like interface.
  269. typedef TYPE value_type;
  270. typedef TYPE& reference;
  271. typedef TYPE const& const_reference;
  272. typedef size_t size_type;
  273. typedef TYPE* iterator;
  274. typedef TYPE const* const_iterator;
  275. iterator begin() { return base::v; }
  276. iterator end() { return base::v + SIZE; }
  277. const_iterator begin() const { return base::v; }
  278. const_iterator end() const { return base::v + SIZE; }
  279. size_type size() const { return SIZE; }
  280. // -----------------------------------------------------------------------
  281. // default constructors
  282. vec() { }
  283. vec(const vec& rhs) : base(rhs) { }
  284. vec(const base& rhs) : base(rhs) { }
  285. // -----------------------------------------------------------------------
  286. // conversion constructors
  287. vec(pTYPE rhs) {
  288. for (size_t i=0 ; i<SIZE ; i++)
  289. base::operator[](i) = rhs;
  290. }
  291. template < template<typename T, size_t S> class VEC, size_t S>
  292. explicit vec(const VEC<TYPE, S>& rhs) {
  293. helpers::doAssign(*this, rhs);
  294. }
  295. explicit vec(TYPE const* array) {
  296. for (size_t i=0 ; i<SIZE ; i++)
  297. base::operator[](i) = array[i];
  298. }
  299. // -----------------------------------------------------------------------
  300. // Assignment
  301. vec& operator = (const vec& rhs) {
  302. base::operator=(rhs);
  303. return *this;
  304. }
  305. vec& operator = (const base& rhs) {
  306. base::operator=(rhs);
  307. return *this;
  308. }
  309. vec& operator = (pTYPE rhs) {
  310. for (size_t i=0 ; i<SIZE ; i++)
  311. base::operator[](i) = rhs;
  312. return *this;
  313. }
  314. template < template<typename T, size_t S> class VEC, size_t S>
  315. vec& operator = (const VEC<TYPE, S>& rhs) {
  316. return helpers::doAssign(*this, rhs);
  317. }
  318. // -----------------------------------------------------------------------
  319. // operation-assignment
  320. vec& operator += (const vec& rhs);
  321. vec& operator -= (const vec& rhs);
  322. vec& operator *= (pTYPE rhs);
  323. // -----------------------------------------------------------------------
  324. // non-member function declaration and definition
  325. // NOTE: we declare the non-member function as friend inside the class
  326. // so that they are known to the compiler when the class is instantiated.
  327. // This helps the compiler doing template argument deduction when the
  328. // passed types are not identical. Essentially this helps with
  329. // type conversion so that you can multiply a vec<float> by an scalar int
  330. // (for instance).
  331. friend inline vec PURE operator + (const vec& lhs, const vec& rhs) {
  332. return helpers::doAdd(lhs, rhs);
  333. }
  334. friend inline vec PURE operator - (const vec& lhs, const vec& rhs) {
  335. return helpers::doSub(lhs, rhs);
  336. }
  337. friend inline vec PURE operator * (const vec& lhs, pTYPE v) {
  338. return helpers::doMulScalar(lhs, v);
  339. }
  340. friend inline vec PURE operator * (pTYPE v, const vec& rhs) {
  341. return helpers::doScalarMul(v, rhs);
  342. }
  343. friend inline TYPE PURE dot_product(const vec& lhs, const vec& rhs) {
  344. return android::dot_product(lhs, rhs);
  345. }
  346. };
  347. // -----------------------------------------------------------------------
  348. template <typename TYPE, size_t SIZE>
  349. vec<TYPE, SIZE>& vec<TYPE, SIZE>::operator += (const vec<TYPE, SIZE>& rhs) {
  350. vec<TYPE, SIZE>& lhs(*this);
  351. for (size_t i=0 ; i<SIZE ; i++)
  352. lhs[i] += rhs[i];
  353. return lhs;
  354. }
  355. template <typename TYPE, size_t SIZE>
  356. vec<TYPE, SIZE>& vec<TYPE, SIZE>::operator -= (const vec<TYPE, SIZE>& rhs) {
  357. vec<TYPE, SIZE>& lhs(*this);
  358. for (size_t i=0 ; i<SIZE ; i++)
  359. lhs[i] -= rhs[i];
  360. return lhs;
  361. }
  362. template <typename TYPE, size_t SIZE>
  363. vec<TYPE, SIZE>& vec<TYPE, SIZE>::operator *= (vec<TYPE, SIZE>::pTYPE rhs) {
  364. vec<TYPE, SIZE>& lhs(*this);
  365. for (size_t i=0 ; i<SIZE ; i++)
  366. lhs[i] *= rhs;
  367. return lhs;
  368. }
  369. // -----------------------------------------------------------------------
  370. typedef vec<float, 2> vec2_t;
  371. typedef vec<float, 3> vec3_t;
  372. typedef vec<float, 4> vec4_t;
  373. // -----------------------------------------------------------------------
  374. }; // namespace android
  375. #endif /* ANDROID_VEC_H */