1 #ifndef _TCUVECTORUTIL_HPP
2 #define _TCUVECTORUTIL_HPP
3 /*-------------------------------------------------------------------------
4 * drawElements Quality Program Tester Core
5 * ----------------------------------------
7 * Copyright 2014 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Vector utility functions.
24 *//*--------------------------------------------------------------------*/
26 #include "tcuDefs.hpp"
27 #include "tcuVector.hpp"
38 static const float PI = 3.141592653589793238f;
40 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_WIN32 && DE_COMPILER == DE_COMPILER_CLANG)
41 inline float abs (float f) { return deFloatAbs(f); }
44 template<typename T> inline T add (T a, T b) { return a + b; }
45 template<typename T> inline T sub (T a, T b) { return a - b; }
46 template<typename T> inline T mul (T a, T b) { return a * b; }
47 template<typename T> inline T div (T a, T b) { return a / b; }
49 template<typename T> inline T bitwiseNot (T a) { return ~a; }
50 template<typename T> inline T bitwiseAnd (T a, T b) { return a & b; }
51 template<typename T> inline T bitwiseOr (T a, T b) { return a | b; }
52 template<typename T> inline T bitwiseXor (T a, T b) { return a ^ b; }
54 template<typename T> inline T logicalNot (T a) { return !a; }
55 template<typename T> inline T logicalAnd (T a, T b) { return a && b; }
56 template<typename T> inline T logicalOr (T a, T b) { return a || b; }
58 template<typename T> inline T mod (T a, T b) { return a % b; }
59 template<> inline float mod (float x, float y) { return x - y * deFloatFloor(x / y); }
61 template<typename T> inline T negate (T f) { return -f; }
62 template<> inline deUint32 negate<deUint32> (deUint32 f) { return (deUint32)-(int)f; }
64 inline float radians (float f) { return deFloatRadians(f); }
65 inline float degrees (float f) { return deFloatDegrees(f); }
66 inline float inverseSqrt (float f) { return deFloatRsq(f); }
67 inline float sign (float f) { return (f < 0.0f) ? -1.0f : ((f > 0.0f) ? +1.0f : 0.0f); }
68 inline float fract (float f) { return f - deFloatFloor(f); }
69 inline float mix (float x, float y, float a) { return x * (1.0f - a) + y * a; }
70 inline float step (float edge, float x) { return (x < edge) ? 0.0f : 1.0f; }
71 inline float smoothStep (float edge0, float edge1, float x)
73 if (x <= edge0) return 0.0f;
74 if (x >= edge1) return 1.0f;
75 float t = de::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
76 return t * t * (3.0f - 2.0f * t);
79 inline double mix (double x, double y, double a) { return x * (1.0 - a) + y * a; }
80 inline double step (double edge, double x) { return (x < edge) ? 0.0 : 1.0; }
82 inline float length (float f) { return deFloatAbs(f); }
83 inline float distance (float x, float y) { return deFloatAbs(x - y); }
84 inline float dot (float x, float y) { return (x * y); }
86 inline float normalize (float f) { return sign(f); }
87 inline float faceForward (float n, float i, float ref) { return ((ref * i) < 0.0f) ? n : -n; }
88 inline float reflect (float i, float n) { return i - 2.0f * (n * i) * n; }
89 inline float refract (float i, float n, float eta)
91 float cosAngle = (n * i);
92 float k = 1.0f - eta * eta * (1.0f - cosAngle * cosAngle);
96 return eta * i - (eta * cosAngle + deFloatSqrt(k)) * n;
99 template<typename T> inline bool lessThan (T a, T b) { return (a < b); }
100 template<typename T> inline bool lessThanEqual (T a, T b) { return (a <= b); }
101 template<typename T> inline bool greaterThan (T a, T b) { return (a > b); }
102 template<typename T> inline bool greaterThanEqual (T a, T b) { return (a >= b); }
103 template<typename T> inline bool equal (T a, T b) { return (a == b); }
104 template<typename T> inline bool notEqual (T a, T b) { return (a != b); }
105 template<typename T> inline bool allEqual (T a, T b) { return (a == b); }
106 template<typename T> inline bool anyNotEqual (T a, T b) { return (a != b); }
108 inline bool boolNot (bool a) { return !a; }
110 inline int chopToInt (float a) { return deChopFloatToInt32(a); }
112 inline float roundToEven (float a)
114 float q = deFloatFrac(a);
119 else if (q == 0.5 && (((int)r) % 2 != 0))
125 template <typename T, int Size>
126 inline T dot (const Vector<T, Size>& a, const Vector<T, Size>& b)
129 for (int i = 0; i < Size; i++)
130 res += a.m_data[i] * b.m_data[i];
134 template <typename T, int Size>
135 inline T lengthSquared (const Vector<T, Size>& a)
138 for (int i = 0; i < Size; i++)
139 sqSum += a.m_data[i] * a.m_data[i];
143 template <typename T, int Size>
144 inline typename de::meta::EnableIf<T, de::meta::TypesSame<T, double>::Value>::Type length (const Vector<T, Size>& a)
146 return ::sqrt(lengthSquared(a));
149 template <typename T, int Size>
150 inline typename de::meta::EnableIf<T, de::meta::TypesSame<T, float>::Value>::Type length (const Vector<T, Size>& a)
152 return deFloatSqrt(lengthSquared(a));
155 template <typename T, int Size>
156 inline T distance (const Vector<T, Size>& a, const Vector<T, Size>& b)
158 return length(a - b);
161 template <typename T, int Size>
162 inline Vector<T, Size> cross (const Vector<T, Size>& a, const Vector<T, Size>& b)
164 DE_STATIC_ASSERT(Size == 3);
165 return Vector<T, Size>(
166 a.y() * b.z() - b.y() * a.z(),
167 a.z() * b.x() - b.z() * a.x(),
168 a.x() * b.y() - b.x() * a.y());
171 template <typename T, int Size>
172 inline Vector<T, Size> normalize (const Vector<T, Size>& a)
174 T ooLen = T(1) / length(a);
176 for (int i = 0; i < Size; i++)
177 res.m_data[i] = ooLen * a.m_data[i];
181 template <typename T, int Size>
182 inline Vector<T, Size> faceForward (const Vector<T, Size>& n, const Vector<T, Size>& i, const Vector<T, Size>& ref)
184 return (dot(ref, i) < T(0)) ? n: -n;
187 template <typename T, int Size>
188 inline Vector<T, Size> reflect (const Vector<T, Size>& i, const Vector<T, Size>& n)
190 return i - T(2) * dot(n, i) * n;
193 template <typename T, int Size>
194 inline Vector<T, Size> refract (const Vector<T, Size>& i, const Vector<T, Size>& n, T eta)
196 T cosAngle = dot(n, i);
197 T k = T(1) - eta * eta * (T(1) - cosAngle * cosAngle);
199 return Vector<T, Size>(T(0));
201 return i * eta - n * T(eta * cosAngle + ::sqrt(k));
205 Vector<float, Size> mix (const Vector<float, Size>& x, const Vector<float, Size>& y, float a)
207 Vector<float, Size> res;
208 for (int i = 0; i < Size; i++)
209 res.m_data[i] = deFloatMix(x.m_data[i], y.m_data[i], a);
214 Vector<double, Size> mix (const Vector<double, Size>& x, const Vector<double, Size>& y, double a)
216 Vector<double, Size> res;
217 for (int i = 0; i < Size; i++)
218 res.m_data[i] = deMix(x.m_data[i], y.m_data[i], a);
222 // Piece-wise compare operators.
224 template <typename T, int Size>
225 inline Vector<bool, Size> equal (const Vector<T, Size>& a, const Vector<T, Size>& b)
227 Vector<bool, Size> res;
228 for (int i = 0; i < Size; i++)
229 res.m_data[i] = a.m_data[i] == b.m_data[i];
233 template <typename T, int Size>
234 inline Vector<bool, Size> notEqual (const Vector<T, Size>& a, const Vector<T, Size>& b)
236 Vector<bool, Size> res;
237 for (int i = 0; i < Size; i++)
238 res.m_data[i] = a.m_data[i] != b.m_data[i];
242 template <typename T, int Size>
243 inline Vector<bool, Size> lessThan (const Vector<T, Size>& a, const Vector<T, Size>& b)
245 Vector<bool, Size> res;
246 for (int i = 0; i < Size; i++)
247 res.m_data[i] = a.m_data[i] < b.m_data[i];
251 template <typename T, int Size>
252 inline Vector<bool, Size> lessThanEqual (const Vector<T, Size>& a, const Vector<T, Size>& b)
254 Vector<bool, Size> res;
255 for (int i = 0; i < Size; i++)
256 res.m_data[i] = a.m_data[i] <= b.m_data[i];
260 template <typename T, int Size>
261 inline Vector<bool, Size> greaterThan (const Vector<T, Size>& a, const Vector<T, Size>& b)
263 Vector<bool, Size> res;
264 for (int i = 0; i < Size; i++)
265 res.m_data[i] = a.m_data[i] > b.m_data[i];
269 template <typename T, int Size>
270 inline Vector<bool, Size> greaterThanEqual (const Vector<T, Size>& a, const Vector<T, Size>& b)
272 Vector<bool, Size> res;
273 for (int i = 0; i < Size; i++)
274 res.m_data[i] = a.m_data[i] >= b.m_data[i];
278 // Equality comparison operators.
280 template <typename T, int Size>
281 inline bool allEqual (const Vector<T, Size>& a, const Vector<T, Size>& b)
284 for (int i = 0; i < Size; i++)
285 res = res && a.m_data[i] == b.m_data[i];
289 template <typename T, int Size>
290 inline bool anyNotEqual (const Vector<T, Size>& a, const Vector<T, Size>& b)
293 for (int i = 0; i < Size; i++)
294 res = res || a.m_data[i] != b.m_data[i];
298 // Boolean built-ins.
301 inline Vector<bool, Size> boolNot (const Vector<bool, Size>& a)
303 Vector<bool, Size> res;
304 for (int i = 0; i < Size; i++)
305 res.m_data[i] = !a.m_data[i];
310 inline bool boolAny (const Vector<bool, Size>& a)
312 for (int i = 0; i < Size; i++)
313 if (a.m_data[i] == true)
319 inline bool boolAll (const Vector<bool, Size>& a)
321 for (int i = 0; i < Size; i++)
322 if (a.m_data[i] == false)
328 Vector<int, Size> chopToInt (const Vector<float, Size>& v)
330 Vector<int, Size> res;
331 for (int i = 0; i < Size; i++)
332 res.m_data[i] = chopToInt(v.m_data[i]);
336 // Vector construction using selection based on boolean vector.
338 template <typename T, int Size>
339 inline Vector<T, Size> select (T trueVal, T falseVal, const Vector<bool, Size>& cond)
342 for (int i = 0; i < Size; i++)
343 res[i] = cond[i] ? trueVal : falseVal;
347 // Component-wise selection.
349 template <typename T, int Size>
350 inline Vector<T, Size> select (const Vector<T, Size>& trueVal, const Vector<T, Size>& falseVal, const Vector<bool, Size>& cond)
353 for (int i = 0; i < Size; i++)
354 res[i] = cond[i] ? trueVal[i] : falseVal[i];
358 // Absolute difference (abs(a - b))
360 template<typename T, int Size>
361 static inline Vector<T, Size> absDiff (const Vector<T, Size>& a, const Vector<T, Size>& b)
365 for (int ndx = 0; ndx < Size; ndx++)
366 res[ndx] = (a[ndx] > b[ndx]) ? (a[ndx] - b[ndx]) : (b[ndx] - a[ndx]);
371 // Macros for component-wise ops.
373 #define TCU_DECLARE_VECTOR_UNARY_FUNC(FUNC_NAME, OP_NAME) \
374 template <typename T, int Size> \
375 Vector<T, Size> FUNC_NAME (const Vector<T, Size>& v) \
377 Vector<T, Size> res; \
378 for (int i = 0; i < Size; i++) \
379 res.m_data[i] = OP_NAME(v.m_data[i]); \
383 #define TCU_DECLARE_VECTOR_BINARY_FUNC(FUNC_NAME, OP_NAME) \
384 template <typename T, int Size> \
385 Vector<T, Size> FUNC_NAME (const Vector<T, Size>& a, const Vector<T, Size>& b) \
387 Vector<T, Size> res; \
388 for (int i = 0; i < Size; i++) \
389 res.m_data[i] = OP_NAME(a.m_data[i], b.m_data[i]); \
393 #define TCU_DECLARE_VECTOR_TERNARY_FUNC(FUNC_NAME, OP_NAME) \
394 template <typename T, int Size> \
395 Vector<T, Size> FUNC_NAME (const Vector<T, Size>& a, const Vector<T, Size>& b, const Vector<T, Size>& c) \
397 Vector<T, Size> res; \
398 for (int i = 0; i < Size; i++) \
399 res.m_data[i] = OP_NAME(a.m_data[i], b.m_data[i], c.m_data[i]); \
403 // \todo [2011-07-01 pyry] Add some prefix to vector funcs and remove this hack.
411 TCU_DECLARE_VECTOR_UNARY_FUNC(negate, negate)
412 TCU_DECLARE_VECTOR_UNARY_FUNC(bitwiseNot, bitwiseNot)
413 TCU_DECLARE_VECTOR_BINARY_FUNC(add, add)
414 TCU_DECLARE_VECTOR_BINARY_FUNC(sub, sub)
415 TCU_DECLARE_VECTOR_BINARY_FUNC(mul, mul)
416 TCU_DECLARE_VECTOR_BINARY_FUNC(div, div)
417 TCU_DECLARE_VECTOR_BINARY_FUNC(mod, mod)
418 TCU_DECLARE_VECTOR_BINARY_FUNC(bitwiseAnd, bitwiseAnd)
419 TCU_DECLARE_VECTOR_BINARY_FUNC(bitwiseOr, bitwiseOr)
420 TCU_DECLARE_VECTOR_BINARY_FUNC(bitwiseXor, bitwiseXor)
421 TCU_DECLARE_VECTOR_UNARY_FUNC(logicalNot, logicalNot)
422 TCU_DECLARE_VECTOR_BINARY_FUNC(logicalAnd, logicalAnd)
423 TCU_DECLARE_VECTOR_BINARY_FUNC(logicalOr, logicalOr)
425 TCU_DECLARE_VECTOR_UNARY_FUNC(radians, deFloatRadians)
426 TCU_DECLARE_VECTOR_UNARY_FUNC(degrees, deFloatDegrees)
427 TCU_DECLARE_VECTOR_UNARY_FUNC(sin, deFloatSin)
428 TCU_DECLARE_VECTOR_UNARY_FUNC(cos, deFloatCos)
429 TCU_DECLARE_VECTOR_UNARY_FUNC(tan, deFloatTan)
430 TCU_DECLARE_VECTOR_UNARY_FUNC(asin, deFloatAsin)
431 TCU_DECLARE_VECTOR_UNARY_FUNC(acos, deFloatAcos)
432 TCU_DECLARE_VECTOR_UNARY_FUNC(atan, deFloatAtanOver)
433 TCU_DECLARE_VECTOR_BINARY_FUNC(atan2, deFloatAtan2)
434 TCU_DECLARE_VECTOR_UNARY_FUNC(sinh, deFloatSinh)
435 TCU_DECLARE_VECTOR_UNARY_FUNC(cosh, deFloatCosh)
436 TCU_DECLARE_VECTOR_UNARY_FUNC(tanh, deFloatTanh)
437 TCU_DECLARE_VECTOR_UNARY_FUNC(asinh, deFloatAsinh)
438 TCU_DECLARE_VECTOR_UNARY_FUNC(acosh, deFloatAcosh)
439 TCU_DECLARE_VECTOR_UNARY_FUNC(atanh, deFloatAtanh)
441 TCU_DECLARE_VECTOR_BINARY_FUNC(pow, deFloatPow)
442 TCU_DECLARE_VECTOR_UNARY_FUNC(exp, deFloatExp)
443 TCU_DECLARE_VECTOR_UNARY_FUNC(log, deFloatLog)
444 TCU_DECLARE_VECTOR_UNARY_FUNC(exp2, deFloatExp2)
445 TCU_DECLARE_VECTOR_UNARY_FUNC(log2, deFloatLog2)
446 TCU_DECLARE_VECTOR_UNARY_FUNC(sqrt, deFloatSqrt)
447 TCU_DECLARE_VECTOR_UNARY_FUNC(inverseSqrt, deFloatRsq)
449 TCU_DECLARE_VECTOR_UNARY_FUNC(abs, de::abs)
450 TCU_DECLARE_VECTOR_UNARY_FUNC(sign, deFloatSign)
451 TCU_DECLARE_VECTOR_UNARY_FUNC(floor, deFloatFloor)
452 TCU_DECLARE_VECTOR_UNARY_FUNC(trunc, deFloatTrunc)
453 TCU_DECLARE_VECTOR_UNARY_FUNC(roundToEven, roundToEven)
454 TCU_DECLARE_VECTOR_UNARY_FUNC(ceil, deFloatCeil)
455 TCU_DECLARE_VECTOR_UNARY_FUNC(fract, deFloatFrac)
456 TCU_DECLARE_VECTOR_BINARY_FUNC(min, de::min)
457 TCU_DECLARE_VECTOR_BINARY_FUNC(max, de::max)
458 TCU_DECLARE_VECTOR_TERNARY_FUNC(clamp, de::clamp)
459 TCU_DECLARE_VECTOR_TERNARY_FUNC(mix, deFloatMix)
460 TCU_DECLARE_VECTOR_BINARY_FUNC(step, deFloatStep)
461 TCU_DECLARE_VECTOR_TERNARY_FUNC(smoothStep, deFloatSmoothStep)
465 #endif // _TCUVECTORUTIL_HPP