1#ifndef _TCUVECTORUTIL_HPP 2#define _TCUVECTORUTIL_HPP 3/*------------------------------------------------------------------------- 4 * drawElements Quality Program Tester Core 5 * ---------------------------------------- 6 * 7 * Copyright 2014 The Android Open Source Project 8 * 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 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 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. 20 * 21 *//*! 22 * \file 23 * \brief Vector utility functions. 24 *//*--------------------------------------------------------------------*/ 25 26#include "tcuDefs.hpp" 27#include "tcuVector.hpp" 28#include "deMath.h" 29#include "deInt32.h" 30 31#include <ostream> 32#include <math.h> 33 34namespace tcu 35{ 36 37static const float PI = 3.141592653589793238f; 38 39#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_WIN32 && DE_COMPILER == DE_COMPILER_CLANG) 40inline float abs (float f) { return deFloatAbs(f); } 41#endif 42 43template<typename T> inline T add (T a, T b) { return a + b; } 44template<typename T> inline T sub (T a, T b) { return a - b; } 45template<typename T> inline T mul (T a, T b) { return a * b; } 46template<typename T> inline T div (T a, T b) { return a / b; } 47 48template<typename T> inline T bitwiseNot (T a) { return ~a; } 49template<typename T> inline T bitwiseAnd (T a, T b) { return a & b; } 50template<typename T> inline T bitwiseOr (T a, T b) { return a | b; } 51template<typename T> inline T bitwiseXor (T a, T b) { return a ^ b; } 52 53template<typename T> inline T logicalNot (T a) { return !a; } 54template<typename T> inline T logicalAnd (T a, T b) { return a && b; } 55template<typename T> inline T logicalOr (T a, T b) { return a || b; } 56 57template<typename T> inline T mod (T a, T b) { return a % b; } 58template<> inline float mod (float x, float y) { return x - y * floor(x / y); } 59 60template<typename T> inline T negate (T f) { return -f; } 61template<> inline deUint32 negate<deUint32> (deUint32 f) { return (deUint32)-(int)f; } 62 63inline float radians (float f) { return deFloatRadians(f); } 64inline float degrees (float f) { return deFloatDegrees(f); } 65inline float exp2 (float f) { return deFloatExp2(f); } 66inline float log2 (float f) { return deFloatLog2(f); } 67inline float inverseSqrt (float f) { return deFloatRsq(f); } 68inline float sign (float f) { return (f < 0.0f) ? -1.0f : ((f > 0.0f) ? +1.0f : 0.0f); } 69inline float fract (float f) { return f - deFloatFloor(f); } 70inline float mix (float x, float y, float a) { return x * (1.0f - a) + y * a; } 71inline float step (float edge, float x) { return (x < edge) ? 0.0f : 1.0f; } 72inline float smoothStep (float edge0, float edge1, float x) 73{ 74 if (x <= edge0) return 0.0f; 75 if (x >= edge1) return 1.0f; 76 float t = de::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f); 77 return t * t * (3.0f - 2.0f * t); 78} 79 80inline double mix (double x, double y, double a) { return x * (1.0 - a) + y * a; } 81inline double step (double edge, double x) { return (x < edge) ? 0.0 : 1.0; } 82 83inline float length (float f) { return deFloatAbs(f); } 84inline float distance (float x, float y) { return deFloatAbs(x - y); } 85inline float dot (float x, float y) { return (x * y); } 86 87inline float normalize (float f) { return sign(f); } 88inline float faceForward (float n, float i, float ref) { return ((ref * i) < 0.0f) ? n : -n; } 89inline float reflect (float i, float n) { return i - 2.0f * (n * i) * n; } 90inline float refract (float i, float n, float eta) 91{ 92 float cosAngle = (n * i); 93 float k = 1.0f - eta * eta * (1.0f - cosAngle * cosAngle); 94 if (k < 0.0f) 95 return 0.0f; 96 else 97 return eta * i - (eta * cosAngle + ::sqrt(k)) * n; 98} 99 100inline float asinh (float a) { return deFloatAsinh(a); } 101inline float acosh (float a) { return deFloatAcosh(a); } 102inline float atanh (float a) { return deFloatAtanh(a); } 103 104template<typename T> inline bool lessThan (T a, T b) { return (a < b); } 105template<typename T> inline bool lessThanEqual (T a, T b) { return (a <= b); } 106template<typename T> inline bool greaterThan (T a, T b) { return (a > b); } 107template<typename T> inline bool greaterThanEqual (T a, T b) { return (a >= b); } 108template<typename T> inline bool equal (T a, T b) { return (a == b); } 109template<typename T> inline bool notEqual (T a, T b) { return (a != b); } 110template<typename T> inline bool allEqual (T a, T b) { return (a == b); } 111template<typename T> inline bool anyNotEqual (T a, T b) { return (a != b); } 112 113inline bool boolNot (bool a) { return !a; } 114 115inline int chopToInt (float a) { return deChopFloatToInt32(a); } 116 117inline float trunc (float a) { return (float)chopToInt(a); } 118 119inline float roundToEven (float a) 120{ 121 float q = deFloatFrac(a); 122 float r = a-q; 123 124 if (q > 0.5f) 125 r += 1.0f; 126 else if (q == 0.5 && (((int)r) % 2 != 0)) 127 r += 1.0f; 128 129 return r; 130} 131 132template <typename T, int Size> 133inline T dot (const Vector<T, Size>& a, const Vector<T, Size>& b) 134{ 135 T res = T(); 136 for (int i = 0; i < Size; i++) 137 res += a.m_data[i] * b.m_data[i]; 138 return res; 139} 140 141template <typename T, int Size> 142inline T lengthSquared (const Vector<T, Size>& a) 143{ 144 T sqSum = T(); 145 for (int i = 0; i < Size; i++) 146 sqSum += a.m_data[i] * a.m_data[i]; 147 return sqSum; 148} 149 150template <typename T, int Size> 151inline T length (const Vector<T, Size>& a) 152{ 153 return ::sqrt(lengthSquared(a)); 154} 155 156template <typename T, int Size> 157inline T distance (const Vector<T, Size>& a, const Vector<T, Size>& b) 158{ 159 return length(a - b); 160} 161 162template <typename T, int Size> 163inline Vector<T, Size> cross (const Vector<T, Size>& a, const Vector<T, Size>& b) 164{ 165 DE_STATIC_ASSERT(Size == 3); 166 return Vector<T, Size>( 167 a.y() * b.z() - b.y() * a.z(), 168 a.z() * b.x() - b.z() * a.x(), 169 a.x() * b.y() - b.x() * a.y()); 170} 171 172template <typename T, int Size> 173inline Vector<T, Size> normalize (const Vector<T, Size>& a) 174{ 175 T ooLen = T(1) / length(a); 176 Vector<T, Size> res; 177 for (int i = 0; i < Size; i++) 178 res.m_data[i] = ooLen * a.m_data[i]; 179 return res; 180} 181 182template <typename T, int Size> 183inline Vector<T, Size> faceForward (const Vector<T, Size>& n, const Vector<T, Size>& i, const Vector<T, Size>& ref) 184{ 185 return (dot(ref, i) < T(0)) ? n: -n; 186} 187 188template <typename T, int Size> 189inline Vector<T, Size> reflect (const Vector<T, Size>& i, const Vector<T, Size>& n) 190{ 191 return i - T(2) * dot(n, i) * n; 192} 193 194template <typename T, int Size> 195inline Vector<T, Size> refract (const Vector<T, Size>& i, const Vector<T, Size>& n, T eta) 196{ 197 Vector<T, Size> res; 198 T cosAngle = dot(n, i); 199 T k = T(1) - eta * eta * (T(1) - cosAngle * cosAngle); 200 if (k < T(0)) 201 return Vector<T, Size>(T(0)); 202 else 203 return i * eta - n * T(eta * cosAngle + ::sqrt(k)); 204} 205 206template <int Size> 207Vector<float, Size> mix (const Vector<float, Size>& x, const Vector<float, Size>& y, float a) 208{ 209 Vector<float, Size> res; 210 for (int i = 0; i < Size; i++) 211 res.m_data[i] = deFloatMix(x.m_data[i], y.m_data[i], a); 212 return res; 213} 214 215template <int Size> 216Vector<double, Size> mix (const Vector<double, Size>& x, const Vector<double, Size>& y, double a) 217{ 218 Vector<double, Size> res; 219 for (int i = 0; i < Size; i++) 220 res.m_data[i] = deMix(x.m_data[i], y.m_data[i], a); 221 return res; 222} 223 224// Piece-wise compare operators. 225 226template <typename T, int Size> 227inline Vector<bool, Size> equal (const Vector<T, Size>& a, const Vector<T, Size>& b) 228{ 229 Vector<bool, Size> res; 230 for (int i = 0; i < Size; i++) 231 res.m_data[i] = a.m_data[i] == b.m_data[i]; 232 return res; 233} 234 235template <typename T, int Size> 236inline Vector<bool, Size> notEqual (const Vector<T, Size>& a, const Vector<T, Size>& b) 237{ 238 Vector<bool, Size> res; 239 for (int i = 0; i < Size; i++) 240 res.m_data[i] = a.m_data[i] != b.m_data[i]; 241 return res; 242} 243 244template <typename T, int Size> 245inline Vector<bool, Size> lessThan (const Vector<T, Size>& a, const Vector<T, Size>& b) 246{ 247 Vector<bool, Size> res; 248 for (int i = 0; i < Size; i++) 249 res.m_data[i] = a.m_data[i] < b.m_data[i]; 250 return res; 251} 252 253template <typename T, int Size> 254inline Vector<bool, Size> lessThanEqual (const Vector<T, Size>& a, const Vector<T, Size>& b) 255{ 256 Vector<bool, Size> res; 257 for (int i = 0; i < Size; i++) 258 res.m_data[i] = a.m_data[i] <= b.m_data[i]; 259 return res; 260} 261 262template <typename T, int Size> 263inline Vector<bool, Size> greaterThan (const Vector<T, Size>& a, const Vector<T, Size>& b) 264{ 265 Vector<bool, Size> res; 266 for (int i = 0; i < Size; i++) 267 res.m_data[i] = a.m_data[i] > b.m_data[i]; 268 return res; 269} 270 271template <typename T, int Size> 272inline Vector<bool, Size> greaterThanEqual (const Vector<T, Size>& a, const Vector<T, Size>& b) 273{ 274 Vector<bool, Size> res; 275 for (int i = 0; i < Size; i++) 276 res.m_data[i] = a.m_data[i] >= b.m_data[i]; 277 return res; 278} 279 280// Equality comparison operators. 281 282template <typename T, int Size> 283inline bool allEqual (const Vector<T, Size>& a, const Vector<T, Size>& b) 284{ 285 bool res = true; 286 for (int i = 0; i < Size; i++) 287 res = res && a.m_data[i] == b.m_data[i]; 288 return res; 289} 290 291template <typename T, int Size> 292inline bool anyNotEqual (const Vector<T, Size>& a, const Vector<T, Size>& b) 293{ 294 bool res = false; 295 for (int i = 0; i < Size; i++) 296 res = res || a.m_data[i] != b.m_data[i]; 297 return res; 298} 299 300// Boolean built-ins. 301 302template <int Size> 303inline Vector<bool, Size> boolNot (const Vector<bool, Size>& a) 304{ 305 Vector<bool, Size> res; 306 for (int i = 0; i < Size; i++) 307 res.m_data[i] = !a.m_data[i]; 308 return res; 309} 310 311template <int Size> 312inline bool boolAny (const Vector<bool, Size>& a) 313{ 314 for (int i = 0; i < Size; i++) 315 if (a.m_data[i] == true) 316 return true; 317 return false; 318} 319 320template <int Size> 321inline bool boolAll (const Vector<bool, Size>& a) 322{ 323 for (int i = 0; i < Size; i++) 324 if (a.m_data[i] == false) 325 return false; 326 return true; 327} 328 329template <int Size> 330Vector<int, Size> chopToInt (const Vector<float, Size>& v) 331{ 332 Vector<int, Size> res; 333 for (int i = 0; i < Size; i++) 334 res.m_data[i] = chopToInt(v.m_data[i]); 335 return res; 336} 337 338// Vector construction using selection based on boolean vector. 339 340template <typename T, int Size> 341inline Vector<T, Size> select (T trueVal, T falseVal, const Vector<bool, Size>& cond) 342{ 343 Vector<T, Size> res; 344 for (int i = 0; i < Size; i++) 345 res[i] = cond[i] ? trueVal : falseVal; 346 return res; 347} 348 349// Component-wise selection. 350 351template <typename T, int Size> 352inline Vector<T, Size> select (const Vector<T, Size>& trueVal, const Vector<T, Size>& falseVal, const Vector<bool, Size>& cond) 353{ 354 Vector<T, Size> res; 355 for (int i = 0; i < Size; i++) 356 res[i] = cond[i] ? trueVal[i] : falseVal[i]; 357 return res; 358} 359 360// Absolute difference (abs(a - b)) 361 362template<typename T, int Size> 363static inline Vector<T, Size> absDiff (const Vector<T, Size>& a, const Vector<T, Size>& b) 364{ 365 Vector<T, Size> res; 366 367 for (int ndx = 0; ndx < Size; ndx++) 368 res[ndx] = (a[ndx] > b[ndx]) ? (a[ndx] - b[ndx]) : (b[ndx] - a[ndx]); 369 370 return res; 371} 372 373// Macros for component-wise ops. 374 375#define TCU_DECLARE_VECTOR_UNARY_FUNC(FUNC_NAME, OP_NAME) \ 376template <typename T, int Size> \ 377Vector<T, Size> FUNC_NAME (const Vector<T, Size>& v) \ 378{ \ 379 Vector<T, Size> res; \ 380 for (int i = 0; i < Size; i++) \ 381 res.m_data[i] = OP_NAME(v.m_data[i]); \ 382 return res; \ 383} 384 385#define TCU_DECLARE_VECTOR_BINARY_FUNC(FUNC_NAME, OP_NAME) \ 386template <typename T, int Size> \ 387Vector<T, Size> FUNC_NAME (const Vector<T, Size>& a, const Vector<T, Size>& b) \ 388{ \ 389 Vector<T, Size> res; \ 390 for (int i = 0; i < Size; i++) \ 391 res.m_data[i] = OP_NAME(a.m_data[i], b.m_data[i]); \ 392 return res; \ 393} 394 395#define TCU_DECLARE_VECTOR_TERNARY_FUNC(FUNC_NAME, OP_NAME) \ 396template <typename T, int Size> \ 397Vector<T, Size> FUNC_NAME (const Vector<T, Size>& a, const Vector<T, Size>& b, const Vector<T, Size>& c) \ 398{ \ 399 Vector<T, Size> res; \ 400 for (int i = 0; i < Size; i++) \ 401 res.m_data[i] = OP_NAME(a.m_data[i], b.m_data[i], c.m_data[i]); \ 402 return res; \ 403} 404 405// \todo [2011-07-01 pyry] Add some prefix to vector funcs and remove this hack. 406#if defined(min) 407# undef min 408#endif 409#if defined(max) 410# undef max 411#endif 412 413TCU_DECLARE_VECTOR_UNARY_FUNC(negate, negate) 414TCU_DECLARE_VECTOR_UNARY_FUNC(bitwiseNot, bitwiseNot) 415TCU_DECLARE_VECTOR_BINARY_FUNC(add, add) 416TCU_DECLARE_VECTOR_BINARY_FUNC(sub, sub) 417TCU_DECLARE_VECTOR_BINARY_FUNC(mul, mul) 418TCU_DECLARE_VECTOR_BINARY_FUNC(div, div) 419TCU_DECLARE_VECTOR_BINARY_FUNC(mod, mod) 420TCU_DECLARE_VECTOR_BINARY_FUNC(bitwiseAnd, bitwiseAnd) 421TCU_DECLARE_VECTOR_BINARY_FUNC(bitwiseOr, bitwiseOr) 422TCU_DECLARE_VECTOR_BINARY_FUNC(bitwiseXor, bitwiseXor) 423TCU_DECLARE_VECTOR_UNARY_FUNC(logicalNot, logicalNot) 424TCU_DECLARE_VECTOR_BINARY_FUNC(logicalAnd, logicalAnd) 425TCU_DECLARE_VECTOR_BINARY_FUNC(logicalOr, logicalOr) 426 427TCU_DECLARE_VECTOR_UNARY_FUNC(radians, deFloatRadians) 428TCU_DECLARE_VECTOR_UNARY_FUNC(degrees, deFloatDegrees) 429TCU_DECLARE_VECTOR_UNARY_FUNC(sin, deFloatSin) 430TCU_DECLARE_VECTOR_UNARY_FUNC(cos, deFloatCos) 431TCU_DECLARE_VECTOR_UNARY_FUNC(tan, deFloatTan) 432TCU_DECLARE_VECTOR_UNARY_FUNC(asin, deFloatAsin) 433TCU_DECLARE_VECTOR_UNARY_FUNC(acos, deFloatAcos) 434TCU_DECLARE_VECTOR_UNARY_FUNC(atan, deFloatAtanOver) 435TCU_DECLARE_VECTOR_BINARY_FUNC(atan2, deFloatAtan2) 436TCU_DECLARE_VECTOR_UNARY_FUNC(sinh, deFloatSinh) 437TCU_DECLARE_VECTOR_UNARY_FUNC(cosh, deFloatCosh) 438TCU_DECLARE_VECTOR_UNARY_FUNC(tanh, deFloatTanh) 439TCU_DECLARE_VECTOR_UNARY_FUNC(asinh, deFloatAsinh) 440TCU_DECLARE_VECTOR_UNARY_FUNC(acosh, deFloatAcosh) 441TCU_DECLARE_VECTOR_UNARY_FUNC(atanh, deFloatAtanh) 442 443TCU_DECLARE_VECTOR_BINARY_FUNC(pow, deFloatPow) 444TCU_DECLARE_VECTOR_UNARY_FUNC(exp, deFloatExp) 445TCU_DECLARE_VECTOR_UNARY_FUNC(log, deFloatLog) 446TCU_DECLARE_VECTOR_UNARY_FUNC(exp2, deFloatExp2) 447TCU_DECLARE_VECTOR_UNARY_FUNC(log2, deFloatLog2) 448TCU_DECLARE_VECTOR_UNARY_FUNC(sqrt, deFloatSqrt) 449TCU_DECLARE_VECTOR_UNARY_FUNC(inverseSqrt, deFloatRsq) 450 451TCU_DECLARE_VECTOR_UNARY_FUNC(abs, de::abs) 452TCU_DECLARE_VECTOR_UNARY_FUNC(sign, deFloatSign) 453TCU_DECLARE_VECTOR_UNARY_FUNC(floor, deFloatFloor) 454TCU_DECLARE_VECTOR_UNARY_FUNC(trunc, trunc) 455TCU_DECLARE_VECTOR_UNARY_FUNC(roundToEven, roundToEven) 456TCU_DECLARE_VECTOR_UNARY_FUNC(ceil, deFloatCeil) 457TCU_DECLARE_VECTOR_UNARY_FUNC(fract, deFloatFrac) 458TCU_DECLARE_VECTOR_BINARY_FUNC(min, de::min) 459TCU_DECLARE_VECTOR_BINARY_FUNC(max, de::max) 460TCU_DECLARE_VECTOR_TERNARY_FUNC(clamp, de::clamp) 461TCU_DECLARE_VECTOR_TERNARY_FUNC(mix, deFloatMix) 462TCU_DECLARE_VECTOR_BINARY_FUNC(step, deFloatStep) 463TCU_DECLARE_VECTOR_TERNARY_FUNC(smoothStep, deFloatSmoothStep) 464 465} // tcu 466 467#endif // _TCUVECTORUTIL_HPP 468