diff options
author | 2017-01-27 20:04:01 -0800 | |
---|---|---|
committer | 2017-01-27 20:04:01 -0800 | |
commit | 11ecb63414d2fea2f4217db8bb06a998bcf8b425 (patch) | |
tree | b556bf0351dafe49a0e45dfaaf493b1612845f2a | |
parent | 2a03c32a4e9089e941335cb496a21509ab5ba5ec (diff) |
Add various vector functions
- map()
- Bool vectors
- any(), all(), comparison functions
Example:
all(lessThan(abs(v1 - v0), epsilon))
Bug: 32984164
Test: vec_test
Change-Id: I7d030387f5a280a499ea480015b69138cef38459
-rw-r--r-- | include/ui/TVecHelpers.h | 112 | ||||
-rw-r--r-- | include/ui/vec2.h | 1 | ||||
-rw-r--r-- | include/ui/vec3.h | 1 | ||||
-rw-r--r-- | include/ui/vec4.h | 1 | ||||
-rw-r--r-- | libs/ui/tests/vec_test.cpp | 32 |
5 files changed, 133 insertions, 14 deletions
diff --git a/include/ui/TVecHelpers.h b/include/ui/TVecHelpers.h index de1d9ffcc9..493433822e 100644 --- a/include/ui/TVecHelpers.h +++ b/include/ui/TVecHelpers.h @@ -321,6 +321,66 @@ public: constexpr bool PURE operator >=(const VECTOR<T>& lv, const VECTOR<RT>& rv) { return !(lv < rv); } + + template<typename RT> + friend inline + constexpr VECTOR<bool> PURE equal(const VECTOR<T>& lv, const VECTOR<RT>& rv) { + VECTOR<bool> r; + for (size_t i = 0; i < lv.size(); i++) { + r[i] = lv[i] == rv[i]; + } + return r; + } + + template<typename RT> + friend inline + constexpr VECTOR<bool> PURE notEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) { + VECTOR<bool> r; + for (size_t i = 0; i < lv.size(); i++) { + r[i] = lv[i] != rv[i]; + } + return r; + } + + template<typename RT> + friend inline + constexpr VECTOR<bool> PURE lessThan(const VECTOR<T>& lv, const VECTOR<RT>& rv) { + VECTOR<bool> r; + for (size_t i = 0; i < lv.size(); i++) { + r[i] = lv[i] < rv[i]; + } + return r; + } + + template<typename RT> + friend inline + constexpr VECTOR<bool> PURE lessThanEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) { + VECTOR<bool> r; + for (size_t i = 0; i < lv.size(); i++) { + r[i] = lv[i] <= rv[i]; + } + return r; + } + + template<typename RT> + friend inline + constexpr VECTOR<bool> PURE greaterThan(const VECTOR<T>& lv, const VECTOR<RT>& rv) { + VECTOR<bool> r; + for (size_t i = 0; i < lv.size(); i++) { + r[i] = lv[i] > rv[i]; + } + return r; + } + + template<typename RT> + friend inline + constexpr VECTOR<bool> PURE greaterThanEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) { + VECTOR<bool> r; + for (size_t i = 0; i < lv.size(); i++) { + r[i] = lv[i] >= rv[i]; + } + return r; + } }; /* @@ -385,49 +445,49 @@ public: } friend inline CONSTEXPR VECTOR<T> PURE abs(VECTOR<T> v) { - for (size_t i=0 ; i<v.size() ; i++) { + for (size_t i = 0; i < v.size(); i++) { v[i] = std::abs(v[i]); } return v; } friend inline CONSTEXPR VECTOR<T> PURE floor(VECTOR<T> v) { - for (size_t i=0 ; i<v.size() ; i++) { + for (size_t i = 0; i < v.size(); i++) { v[i] = std::floor(v[i]); } return v; } friend inline CONSTEXPR VECTOR<T> PURE ceil(VECTOR<T> v) { - for (size_t i=0 ; i<v.size() ; i++) { + for (size_t i = 0; i < v.size(); i++) { v[i] = std::ceil(v[i]); } return v; } friend inline CONSTEXPR VECTOR<T> PURE round(VECTOR<T> v) { - for (size_t i=0 ; i<v.size() ; i++) { + for (size_t i = 0; i < v.size(); i++) { v[i] = std::round(v[i]); } return v; } friend inline CONSTEXPR VECTOR<T> PURE inversesqrt(VECTOR<T> v) { - for (size_t i=0 ; i<v.size() ; i++) { + for (size_t i = 0; i < v.size(); i++) { v[i] = T(1) / std::sqrt(v[i]); } return v; } friend inline CONSTEXPR VECTOR<T> PURE sqrt(VECTOR<T> v) { - for (size_t i=0 ; i<v.size() ; i++) { + for (size_t i = 0; i < v.size(); i++) { v[i] = std::sqrt(v[i]); } return v; } friend inline CONSTEXPR VECTOR<T> PURE pow(VECTOR<T> v, T p) { - for (size_t i=0 ; i<v.size() ; i++) { + for (size_t i = 0; i < v.size(); i++) { v[i] = std::pow(v[i], p); } return v; @@ -438,14 +498,14 @@ public: } friend inline CONSTEXPR VECTOR<T> PURE clamp(VECTOR<T> v, T min, T max) { - for (size_t i=0 ; i< v.size() ; i++) { + for (size_t i = 0; i< v.size(); i++) { v[i] = std::min(max, std::max(min, v[i])); } return v; } friend inline CONSTEXPR VECTOR<T> PURE fma(const VECTOR<T>& lv, const VECTOR<T>& rv, VECTOR<T> a) { - for (size_t i=0 ; i<lv.size() ; i++) { + for (size_t i = 0; i<lv.size(); i++) { //a[i] = std::fma(lv[i], rv[i], a[i]); a[i] += (lv[i] * rv[i]); } @@ -453,14 +513,14 @@ public: } friend inline CONSTEXPR VECTOR<T> PURE min(const VECTOR<T>& u, VECTOR<T> v) { - for (size_t i=0 ; i<v.size() ; i++) { + for (size_t i = 0; i < v.size(); i++) { v[i] = std::min(u[i], v[i]); } return v; } friend inline CONSTEXPR VECTOR<T> PURE max(const VECTOR<T>& u, VECTOR<T> v) { - for (size_t i=0 ; i<v.size() ; i++) { + for (size_t i = 0; i < v.size(); i++) { v[i] = std::max(u[i], v[i]); } return v; @@ -468,7 +528,7 @@ public: friend inline CONSTEXPR T PURE max(const VECTOR<T>& v) { T r(std::numeric_limits<T>::lowest()); - for (size_t i=0 ; i<v.size() ; i++) { + for (size_t i = 0; i < v.size(); i++) { r = std::max(r, v[i]); } return r; @@ -476,18 +536,42 @@ public: friend inline CONSTEXPR T PURE min(const VECTOR<T>& v) { T r(std::numeric_limits<T>::max()); - for (size_t i=0 ; i<v.size() ; i++) { + for (size_t i = 0; i < v.size(); i++) { r = std::min(r, v[i]); } return r; } friend inline CONSTEXPR VECTOR<T> PURE apply(VECTOR<T> v, const std::function<T(T)>& f) { - for (size_t i=0 ; i<v.size() ; i++) { + for (size_t i = 0; i < v.size(); i++) { v[i] = f(v[i]); } return v; } + + friend inline CONSTEXPR bool PURE any(const VECTOR<T>& v) { + for (size_t i = 0; i < v.size(); i++) { + if (v[i] != T(0)) return true; + } + return false; + } + + friend inline CONSTEXPR bool PURE all(const VECTOR<T>& v) { + bool result = true; + for (size_t i = 0; i < v.size(); i++) { + result &= (v[i] != T(0)); + } + return result; + } + + template<typename R> + friend inline CONSTEXPR VECTOR<R> PURE map(VECTOR<T> v, const std::function<R(T)>& f) { + VECTOR<R> result; + for (size_t i = 0; i < v.size(); i++) { + result[i] = f(v[i]); + } + return result; + } }; /* diff --git a/include/ui/vec2.h b/include/ui/vec2.h index fdd2e202fa..308d2b802a 100644 --- a/include/ui/vec2.h +++ b/include/ui/vec2.h @@ -118,6 +118,7 @@ typedef details::TVec2<int16_t> short2; typedef details::TVec2<uint16_t> ushort2; typedef details::TVec2<int8_t> byte2; typedef details::TVec2<uint8_t> ubyte2; +typedef details::TVec2<bool> bool2; // ---------------------------------------------------------------------------------------- } // namespace android diff --git a/include/ui/vec3.h b/include/ui/vec3.h index f76b2ec0dd..e3a6d14807 100644 --- a/include/ui/vec3.h +++ b/include/ui/vec3.h @@ -124,6 +124,7 @@ typedef details::TVec3<int16_t> short3; typedef details::TVec3<uint16_t> ushort3; typedef details::TVec3<int8_t> byte3; typedef details::TVec3<uint8_t> ubyte3; +typedef details::TVec3<bool> bool3; // ---------------------------------------------------------------------------------------- } // namespace android diff --git a/include/ui/vec4.h b/include/ui/vec4.h index e13ad96913..9346fb378b 100644 --- a/include/ui/vec4.h +++ b/include/ui/vec4.h @@ -121,6 +121,7 @@ typedef details::TVec4<int16_t> short4; typedef details::TVec4<uint16_t> ushort4; typedef details::TVec4<int8_t> byte4; typedef details::TVec4<uint8_t> ubyte4; +typedef details::TVec4<bool> bool4; // ---------------------------------------------------------------------------------------- } // namespace android diff --git a/libs/ui/tests/vec_test.cpp b/libs/ui/tests/vec_test.cpp index 586d1a8456..7c749a7b1e 100644 --- a/libs/ui/tests/vec_test.cpp +++ b/libs/ui/tests/vec_test.cpp @@ -187,6 +187,23 @@ TEST_F(VecTest, ComparisonOps) { EXPECT_FALSE(v0 == v1); } +TEST_F(VecTest, ComparisonFunctions) { + vec4 v0(1, 2, 3, 4); + vec4 v1(10, 20, 30, 40); + + EXPECT_TRUE(all(equal(v0, v0))); + EXPECT_TRUE(all(notEqual(v0, v1))); + EXPECT_FALSE(any(notEqual(v0, v0))); + EXPECT_FALSE(any(equal(v0, v1))); + + EXPECT_FALSE(all(lessThan(v0, v0))); + EXPECT_TRUE(all(lessThanEqual(v0, v0))); + EXPECT_FALSE(all(greaterThan(v0, v0))); + EXPECT_TRUE(all(greaterThanEqual(v0, v0))); + EXPECT_TRUE(all(lessThan(v0, v1))); + EXPECT_TRUE(all(greaterThan(v1, v0))); +} + TEST_F(VecTest, ArithmeticOps) { vec4 v0(1, 2, 3, 4); vec4 v1(10, 20, 30, 40); @@ -233,6 +250,21 @@ TEST_F(VecTest, ArithmeticFunc) { float3 vf(east); EXPECT_EQ(length(vf), 1); + + EXPECT_TRUE(any(vec3(0, 0, 1))); + EXPECT_FALSE(any(vec3(0, 0, 0))); + + EXPECT_TRUE(all(vec3(1, 1, 1))); + EXPECT_FALSE(all(vec3(0, 0, 1))); + + EXPECT_TRUE(any(bool3(false, false, true))); + EXPECT_FALSE(any(bool3(false))); + + EXPECT_TRUE(all(bool3(true))); + EXPECT_FALSE(all(bool3(false, false, true))); + + std::function<bool(float)> p = [](auto v) -> bool { return v > 0.0f; }; + EXPECT_TRUE(all(map(vec3(1, 2, 3), p))); } }; // namespace android |