• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013 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 
17 
18 #pragma once
19 
20 #include <math.h>
21 #include <stdint.h>
22 #include <sys/types.h>
23 
24 #include <cmath>
25 #include <limits>
26 #include <iostream>
27 
28 #define PURE __attribute__((pure))
29 
30 #if __cplusplus >= 201402L
31 #define CONSTEXPR constexpr
32 #else
33 #define CONSTEXPR
34 #endif
35 
36 namespace android {
37 namespace details {
38 // -------------------------------------------------------------------------------------
39 
40 /*
41  * No user serviceable parts here.
42  *
43  * Don't use this file directly, instead include ui/vec{2|3|4}.h
44  */
45 
46 /*
47  * TVec{Add|Product}Operators implements basic arithmetic and basic compound assignments
48  * operators on a vector of type BASE<T>.
49  *
50  * BASE only needs to implement operator[] and size().
51  * By simply inheriting from TVec{Add|Product}Operators<BASE, T> BASE will automatically
52  * get all the functionality here.
53  */
54 
55 template <template<typename T> class VECTOR, typename T>
56 class TVecAddOperators {
57 public:
58     /* compound assignment from a another vector of the same size but different
59      * element type.
60      */
61     template<typename OTHER>
62     VECTOR<T>& operator +=(const VECTOR<OTHER>& v) {
63         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
64         for (size_t i = 0; i < lhs.size(); i++) {
65             lhs[i] += v[i];
66         }
67         return lhs;
68     }
69     template<typename OTHER>
70     VECTOR<T>& operator -=(const VECTOR<OTHER>& v) {
71         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
72         for (size_t i = 0; i < lhs.size(); i++) {
73             lhs[i] -= v[i];
74         }
75         return lhs;
76     }
77 
78     /* compound assignment from a another vector of the same type.
79      * These operators can be used for implicit conversion and  handle operations
80      * like "vector *= scalar" by letting the compiler implicitly convert a scalar
81      * to a vector (assuming the BASE<T> allows it).
82      */
83     VECTOR<T>& operator +=(const VECTOR<T>& v) {
84         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
85         for (size_t i = 0; i < lhs.size(); i++) {
86             lhs[i] += v[i];
87         }
88         return lhs;
89     }
90     VECTOR<T>& operator -=(const VECTOR<T>& v) {
91         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
92         for (size_t i = 0; i < lhs.size(); i++) {
93             lhs[i] -= v[i];
94         }
95         return lhs;
96     }
97 
98     /*
99      * NOTE: the functions below ARE NOT member methods. They are friend functions
100      * with they definition inlined with their declaration. This makes these
101      * template functions available to the compiler when (and only when) this class
102      * is instantiated, at which point they're only templated on the 2nd parameter
103      * (the first one, BASE<T> being known).
104      */
105 
106     /* The operators below handle operation between vectors of the same size
107      * but of a different element type.
108      */
109     template<typename RT>
110     friend inline constexpr VECTOR<T> PURE operator +(VECTOR<T> lv, const VECTOR<RT>& rv) {
111         // don't pass lv by reference because we need a copy anyways
112         return lv += rv;
113     }
114     template<typename RT>
115     friend inline constexpr VECTOR<T> PURE operator -(VECTOR<T> lv, const VECTOR<RT>& rv) {
116         // don't pass lv by reference because we need a copy anyways
117         return lv -= rv;
118     }
119 
120     /* The operators below (which are not templates once this class is instanced,
121      * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
122      * These handle operations like "vector + scalar" and "scalar + vector" by
123      * letting the compiler implicitly convert a scalar to a vector (assuming
124      * the BASE<T> allows it).
125      */
126     friend inline constexpr VECTOR<T> PURE operator +(VECTOR<T> lv, const VECTOR<T>& rv) {
127         // don't pass lv by reference because we need a copy anyways
128         return lv += rv;
129     }
130     friend inline constexpr VECTOR<T> PURE operator -(VECTOR<T> lv, const VECTOR<T>& rv) {
131         // don't pass lv by reference because we need a copy anyways
132         return lv -= rv;
133     }
134 };
135 
136 template<template<typename T> class VECTOR, typename T>
137 class TVecProductOperators {
138 public:
139     /* compound assignment from a another vector of the same size but different
140      * element type.
141      */
142     template<typename OTHER>
143     VECTOR<T>& operator *=(const VECTOR<OTHER>& v) {
144         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
145         for (size_t i = 0; i < lhs.size(); i++) {
146             lhs[i] *= v[i];
147         }
148         return lhs;
149     }
150     template<typename OTHER>
151     VECTOR<T>& operator /=(const VECTOR<OTHER>& v) {
152         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
153         for (size_t i = 0; i < lhs.size(); i++) {
154             lhs[i] /= v[i];
155         }
156         return lhs;
157     }
158 
159     /* compound assignment from a another vector of the same type.
160      * These operators can be used for implicit conversion and  handle operations
161      * like "vector *= scalar" by letting the compiler implicitly convert a scalar
162      * to a vector (assuming the BASE<T> allows it).
163      */
164     VECTOR<T>& operator *=(const VECTOR<T>& v) {
165         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
166         for (size_t i = 0; i < lhs.size(); i++) {
167             lhs[i] *= v[i];
168         }
169         return lhs;
170     }
171     VECTOR<T>& operator /=(const VECTOR<T>& v) {
172         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
173         for (size_t i = 0; i < lhs.size(); i++) {
174             lhs[i] /= v[i];
175         }
176         return lhs;
177     }
178 
179     /*
180      * NOTE: the functions below ARE NOT member methods. They are friend functions
181      * with they definition inlined with their declaration. This makes these
182      * template functions available to the compiler when (and only when) this class
183      * is instantiated, at which point they're only templated on the 2nd parameter
184      * (the first one, BASE<T> being known).
185      */
186 
187     /* The operators below handle operation between vectors of the same size
188      * but of a different element type.
189      */
190     template<typename RT>
191     friend inline constexpr VECTOR<T> PURE operator *(VECTOR<T> lv, const VECTOR<RT>& rv) {
192         // don't pass lv by reference because we need a copy anyways
193         return lv *= rv;
194     }
195     template<typename RT>
196     friend inline constexpr VECTOR<T> PURE operator /(VECTOR<T> lv, const VECTOR<RT>& rv) {
197         // don't pass lv by reference because we need a copy anyways
198         return lv /= rv;
199     }
200 
201     /* The operators below (which are not templates once this class is instanced,
202      * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
203      * These handle operations like "vector * scalar" and "scalar * vector" by
204      * letting the compiler implicitly convert a scalar to a vector (assuming
205      * the BASE<T> allows it).
206      */
207     friend inline constexpr VECTOR<T> PURE operator *(VECTOR<T> lv, const VECTOR<T>& rv) {
208         // don't pass lv by reference because we need a copy anyways
209         return lv *= rv;
210     }
211     friend inline constexpr VECTOR<T> PURE operator /(VECTOR<T> lv, const VECTOR<T>& rv) {
212         // don't pass lv by reference because we need a copy anyways
213         return lv /= rv;
214     }
215 };
216 
217 /*
218  * TVecUnaryOperators implements unary operators on a vector of type BASE<T>.
219  *
220  * BASE only needs to implement operator[] and size().
221  * By simply inheriting from TVecUnaryOperators<BASE, T> BASE will automatically
222  * get all the functionality here.
223  *
224  * These operators are implemented as friend functions of TVecUnaryOperators<BASE, T>
225  */
226 template<template<typename T> class VECTOR, typename T>
227 class TVecUnaryOperators {
228 public:
229     VECTOR<T>& operator ++() {
230         VECTOR<T>& rhs = static_cast<VECTOR<T>&>(*this);
231         for (size_t i = 0; i < rhs.size(); i++) {
232             ++rhs[i];
233         }
234         return rhs;
235     }
236 
237     VECTOR<T>& operator --() {
238         VECTOR<T>& rhs = static_cast<VECTOR<T>&>(*this);
239         for (size_t i = 0; i < rhs.size(); i++) {
240             --rhs[i];
241         }
242         return rhs;
243     }
244 
245     CONSTEXPR VECTOR<T> operator -() const {
246         VECTOR<T> r(VECTOR<T>::NO_INIT);
247         VECTOR<T> const& rv(static_cast<VECTOR<T> const&>(*this));
248         for (size_t i = 0; i < r.size(); i++) {
249             r[i] = -rv[i];
250         }
251         return r;
252     }
253 };
254 
255 /*
256  * TVecComparisonOperators implements relational/comparison operators
257  * on a vector of type BASE<T>.
258  *
259  * BASE only needs to implement operator[] and size().
260  * By simply inheriting from TVecComparisonOperators<BASE, T> BASE will automatically
261  * get all the functionality here.
262  */
263 template<template<typename T> class VECTOR, typename T>
264 class TVecComparisonOperators {
265 public:
266     /*
267      * NOTE: the functions below ARE NOT member methods. They are friend functions
268      * with they definition inlined with their declaration. This makes these
269      * template functions available to the compiler when (and only when) this class
270      * is instantiated, at which point they're only templated on the 2nd parameter
271      * (the first one, BASE<T> being known).
272      */
273     template<typename RT>
274     friend inline
275     bool PURE operator ==(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
276         for (size_t i = 0; i < lv.size(); i++)
277             if (lv[i] != rv[i])
278                 return false;
279         return true;
280     }
281 
282     template<typename RT>
283     friend inline
284     bool PURE operator !=(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
285         return !operator ==(lv, rv);
286     }
287 
288     template<typename RT>
289     friend inline
290     bool PURE operator >(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
291         for (size_t i = 0; i < lv.size(); i++) {
292             if (lv[i] == rv[i]) {
293                 continue;
294             }
295             return lv[i] > rv[i];
296         }
297         return false;
298     }
299 
300     template<typename RT>
301     friend inline
302     constexpr bool PURE operator <=(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
303         return !(lv > rv);
304     }
305 
306     template<typename RT>
307     friend inline
308     bool PURE operator <(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
309         for (size_t i = 0; i < lv.size(); i++) {
310             if (lv[i] == rv[i]) {
311                 continue;
312             }
313             return lv[i] < rv[i];
314         }
315         return false;
316     }
317 
318     template<typename RT>
319     friend inline
320     constexpr bool PURE operator >=(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
321         return !(lv < rv);
322     }
323 
324     template<typename RT>
325     friend inline
equal(const VECTOR<T> & lv,const VECTOR<RT> & rv)326     CONSTEXPR VECTOR<bool> PURE equal(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
327         VECTOR<bool> r;
328         for (size_t i = 0; i < lv.size(); i++) {
329             r[i] = lv[i] == rv[i];
330         }
331         return r;
332     }
333 
334     template<typename RT>
335     friend inline
notEqual(const VECTOR<T> & lv,const VECTOR<RT> & rv)336     CONSTEXPR VECTOR<bool> PURE notEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
337         VECTOR<bool> r;
338         for (size_t i = 0; i < lv.size(); i++) {
339             r[i] = lv[i] != rv[i];
340         }
341         return r;
342     }
343 
344     template<typename RT>
345     friend inline
lessThan(const VECTOR<T> & lv,const VECTOR<RT> & rv)346     CONSTEXPR VECTOR<bool> PURE lessThan(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
347         VECTOR<bool> r;
348         for (size_t i = 0; i < lv.size(); i++) {
349             r[i] = lv[i] < rv[i];
350         }
351         return r;
352     }
353 
354     template<typename RT>
355     friend inline
lessThanEqual(const VECTOR<T> & lv,const VECTOR<RT> & rv)356     CONSTEXPR VECTOR<bool> PURE lessThanEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
357         VECTOR<bool> r;
358         for (size_t i = 0; i < lv.size(); i++) {
359             r[i] = lv[i] <= rv[i];
360         }
361         return r;
362     }
363 
364     template<typename RT>
365     friend inline
greaterThan(const VECTOR<T> & lv,const VECTOR<RT> & rv)366     CONSTEXPR VECTOR<bool> PURE greaterThan(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
367         VECTOR<bool> r;
368         for (size_t i = 0; i < lv.size(); i++) {
369             r[i] = lv[i] > rv[i];
370         }
371         return r;
372     }
373 
374     template<typename RT>
375     friend inline
greaterThanEqual(const VECTOR<T> & lv,const VECTOR<RT> & rv)376     CONSTEXPR VECTOR<bool> PURE greaterThanEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
377         VECTOR<bool> r;
378         for (size_t i = 0; i < lv.size(); i++) {
379             r[i] = lv[i] >= rv[i];
380         }
381         return r;
382     }
383 };
384 
385 /*
386  * TVecFunctions implements functions on a vector of type BASE<T>.
387  *
388  * BASE only needs to implement operator[] and size().
389  * By simply inheriting from TVecFunctions<BASE, T> BASE will automatically
390  * get all the functionality here.
391  */
392 template<template<typename T> class VECTOR, typename T>
393 class TVecFunctions {
394 public:
395     /*
396      * NOTE: the functions below ARE NOT member methods. They are friend functions
397      * with they definition inlined with their declaration. This makes these
398      * template functions available to the compiler when (and only when) this class
399      * is instantiated, at which point they're only templated on the 2nd parameter
400      * (the first one, BASE<T> being known).
401      */
402     template<typename RT>
dot(const VECTOR<T> & lv,const VECTOR<RT> & rv)403     friend inline CONSTEXPR T PURE dot(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
404         T r(0);
405         for (size_t i = 0; i < lv.size(); i++) {
406             //r = std::fma(lv[i], rv[i], r);
407             r += lv[i] * rv[i];
408         }
409         return r;
410     }
411 
norm(const VECTOR<T> & lv)412     friend inline constexpr T PURE norm(const VECTOR<T>& lv) {
413         return std::sqrt(dot(lv, lv));
414     }
415 
length(const VECTOR<T> & lv)416     friend inline constexpr T PURE length(const VECTOR<T>& lv) {
417         return norm(lv);
418     }
419 
norm2(const VECTOR<T> & lv)420     friend inline constexpr T PURE norm2(const VECTOR<T>& lv) {
421         return dot(lv, lv);
422     }
423 
length2(const VECTOR<T> & lv)424     friend inline constexpr T PURE length2(const VECTOR<T>& lv) {
425         return norm2(lv);
426     }
427 
428     template<typename RT>
distance(const VECTOR<T> & lv,const VECTOR<RT> & rv)429     friend inline constexpr T PURE distance(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
430         return length(rv - lv);
431     }
432 
433     template<typename RT>
distance2(const VECTOR<T> & lv,const VECTOR<RT> & rv)434     friend inline constexpr T PURE distance2(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
435         return length2(rv - lv);
436     }
437 
normalize(const VECTOR<T> & lv)438     friend inline constexpr VECTOR<T> PURE normalize(const VECTOR<T>& lv) {
439         return lv * (T(1) / length(lv));
440     }
441 
rcp(VECTOR<T> v)442     friend inline constexpr VECTOR<T> PURE rcp(VECTOR<T> v) {
443         return T(1) / v;
444     }
445 
abs(VECTOR<T> v)446     friend inline CONSTEXPR VECTOR<T> PURE abs(VECTOR<T> v) {
447         for (size_t i = 0; i < v.size(); i++) {
448             v[i] = std::abs(v[i]);
449         }
450         return v;
451     }
452 
floor(VECTOR<T> v)453     friend inline CONSTEXPR VECTOR<T> PURE floor(VECTOR<T> v) {
454         for (size_t i = 0; i < v.size(); i++) {
455             v[i] = std::floor(v[i]);
456         }
457         return v;
458     }
459 
ceil(VECTOR<T> v)460     friend inline CONSTEXPR VECTOR<T> PURE ceil(VECTOR<T> v) {
461         for (size_t i = 0; i < v.size(); i++) {
462             v[i] = std::ceil(v[i]);
463         }
464         return v;
465     }
466 
round(VECTOR<T> v)467     friend inline CONSTEXPR VECTOR<T> PURE round(VECTOR<T> v) {
468         for (size_t i = 0; i < v.size(); i++) {
469             v[i] = std::round(v[i]);
470         }
471         return v;
472     }
473 
inversesqrt(VECTOR<T> v)474     friend inline CONSTEXPR VECTOR<T> PURE inversesqrt(VECTOR<T> v) {
475         for (size_t i = 0; i < v.size(); i++) {
476             v[i] = T(1) / std::sqrt(v[i]);
477         }
478         return v;
479     }
480 
sqrt(VECTOR<T> v)481     friend inline CONSTEXPR VECTOR<T> PURE sqrt(VECTOR<T> v) {
482         for (size_t i = 0; i < v.size(); i++) {
483             v[i] = std::sqrt(v[i]);
484         }
485         return v;
486     }
487 
pow(VECTOR<T> v,T p)488     friend inline CONSTEXPR VECTOR<T> PURE pow(VECTOR<T> v, T p) {
489         for (size_t i = 0; i < v.size(); i++) {
490             v[i] = std::pow(v[i], p);
491         }
492         return v;
493     }
494 
saturate(const VECTOR<T> & lv)495     friend inline CONSTEXPR VECTOR<T> PURE saturate(const VECTOR<T>& lv) {
496         return clamp(lv, T(0), T(1));
497     }
498 
clamp(VECTOR<T> v,T min,T max)499     friend inline CONSTEXPR VECTOR<T> PURE clamp(VECTOR<T> v, T min, T max) {
500         for (size_t i = 0; i< v.size(); i++) {
501             v[i] = std::min(max, std::max(min, v[i]));
502         }
503         return v;
504     }
505 
fma(const VECTOR<T> & lv,const VECTOR<T> & rv,VECTOR<T> a)506     friend inline CONSTEXPR VECTOR<T> PURE fma(const VECTOR<T>& lv, const VECTOR<T>& rv, VECTOR<T> a) {
507         for (size_t i = 0; i<lv.size(); i++) {
508             //a[i] = std::fma(lv[i], rv[i], a[i]);
509             a[i] += (lv[i] * rv[i]);
510         }
511         return a;
512     }
513 
min(const VECTOR<T> & u,VECTOR<T> v)514     friend inline CONSTEXPR VECTOR<T> PURE min(const VECTOR<T>& u, VECTOR<T> v) {
515         for (size_t i = 0; i < v.size(); i++) {
516             v[i] = std::min(u[i], v[i]);
517         }
518         return v;
519     }
520 
max(const VECTOR<T> & u,VECTOR<T> v)521     friend inline CONSTEXPR VECTOR<T> PURE max(const VECTOR<T>& u, VECTOR<T> v) {
522         for (size_t i = 0; i < v.size(); i++) {
523             v[i] = std::max(u[i], v[i]);
524         }
525         return v;
526     }
527 
max(const VECTOR<T> & v)528     friend inline CONSTEXPR T PURE max(const VECTOR<T>& v) {
529         T r(std::numeric_limits<T>::lowest());
530         for (size_t i = 0; i < v.size(); i++) {
531             r = std::max(r, v[i]);
532         }
533         return r;
534     }
535 
min(const VECTOR<T> & v)536     friend inline CONSTEXPR T PURE min(const VECTOR<T>& v) {
537         T r(std::numeric_limits<T>::max());
538         for (size_t i = 0; i < v.size(); i++) {
539             r = std::min(r, v[i]);
540         }
541         return r;
542     }
543 
apply(VECTOR<T> v,const std::function<T (T)> & f)544     friend inline CONSTEXPR VECTOR<T> PURE apply(VECTOR<T> v, const std::function<T(T)>& f) {
545         for (size_t i = 0; i < v.size(); i++) {
546             v[i] = f(v[i]);
547         }
548         return v;
549     }
550 
any(const VECTOR<T> & v)551     friend inline CONSTEXPR bool PURE any(const VECTOR<T>& v) {
552         for (size_t i = 0; i < v.size(); i++) {
553             if (v[i] != T(0)) return true;
554         }
555         return false;
556     }
557 
all(const VECTOR<T> & v)558     friend inline CONSTEXPR bool PURE all(const VECTOR<T>& v) {
559         bool result = true;
560         for (size_t i = 0; i < v.size(); i++) {
561             result &= (v[i] != T(0));
562         }
563         return result;
564     }
565 
566     template<typename R>
map(VECTOR<T> v,const std::function<R (T)> & f)567     friend inline CONSTEXPR VECTOR<R> PURE map(VECTOR<T> v, const std::function<R(T)>& f) {
568         VECTOR<R> result;
569         for (size_t i = 0; i < v.size(); i++) {
570             result[i] = f(v[i]);
571         }
572         return result;
573     }
574 };
575 
576 /*
577  * TVecDebug implements functions on a vector of type BASE<T>.
578  *
579  * BASE only needs to implement operator[] and size().
580  * By simply inheriting from TVecDebug<BASE, T> BASE will automatically
581  * get all the functionality here.
582  */
583 template<template<typename T> class VECTOR, typename T>
584 class TVecDebug {
585 public:
586     /*
587      * NOTE: the functions below ARE NOT member methods. They are friend functions
588      * with they definition inlined with their declaration. This makes these
589      * template functions available to the compiler when (and only when) this class
590      * is instantiated, at which point they're only templated on the 2nd parameter
591      * (the first one, BASE<T> being known).
592      */
593     friend std::ostream& operator<<(std::ostream& stream, const VECTOR<T>& v) {
594         stream << "< ";
595         for (size_t i = 0; i < v.size() - 1; i++) {
596             stream << T(v[i]) << ", ";
597         }
598         stream << T(v[v.size() - 1]) << " >";
599         return stream;
600     }
601 };
602 
603 #undef CONSTEXPR
604 #undef PURE
605 
606 // -------------------------------------------------------------------------------------
607 }  // namespace details
608 }  // namespace android
609