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
diff --git a/include/ui/TVecHelpers.h b/include/ui/TVecHelpers.h
index de1d9ff..4934338 100644
--- a/include/ui/TVecHelpers.h
+++ b/include/ui/TVecHelpers.h
@@ -321,6 +321,66 @@
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 @@
}
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 @@
}
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 @@
}
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 @@
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 @@
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 fdd2e20..308d2b8 100644
--- a/include/ui/vec2.h
+++ b/include/ui/vec2.h
@@ -118,6 +118,7 @@
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 f76b2ec..e3a6d14 100644
--- a/include/ui/vec3.h
+++ b/include/ui/vec3.h
@@ -124,6 +124,7 @@
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 e13ad96..9346fb3 100644
--- a/include/ui/vec4.h
+++ b/include/ui/vec4.h
@@ -121,6 +121,7 @@
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 586d1a8..7c749a7 100644
--- a/libs/ui/tests/vec_test.cpp
+++ b/libs/ui/tests/vec_test.cpp
@@ -187,6 +187,23 @@
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 @@
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