Home | History | Annotate | Download | only in common
      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 
     34 namespace tcu
     35 {
     36 
     37 static 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)
     40 inline float abs			(float f) { return deFloatAbs(f); }
     41 #endif
     42 
     43 template<typename T> inline T add			(T a, T b) { return a + b; }
     44 template<typename T> inline T sub			(T a, T b) { return a - b; }
     45 template<typename T> inline T mul			(T a, T b) { return a * b; }
     46 template<typename T> inline T div			(T a, T b) { return a / b; }
     47 
     48 template<typename T> inline T bitwiseNot	(T a)		{ return ~a; }
     49 template<typename T> inline T bitwiseAnd	(T a, T b)	{ return a & b; }
     50 template<typename T> inline T bitwiseOr		(T a, T b)	{ return a | b; }
     51 template<typename T> inline T bitwiseXor	(T a, T b)	{ return a ^ b; }
     52 
     53 template<typename T> inline T logicalNot	(T a)		{ return !a; }
     54 template<typename T> inline T logicalAnd	(T a, T b)	{ return a && b; }
     55 template<typename T> inline T logicalOr		(T a, T b)	{ return a || b; }
     56 
     57 template<typename T>	inline T		mod		(T a, T b)			{ return a % b; }
     58 template<>				inline float	mod		(float x, float y)	{ return x - y * floor(x / y); }
     59 
     60 template<typename T>	inline	T			negate				(T f)			{ return -f; }
     61 template<>				inline	deUint32	negate<deUint32>	(deUint32 f)	{ return (deUint32)-(int)f;	}
     62 
     63 inline float radians		(float f) { return deFloatRadians(f); }
     64 inline float degrees		(float f) { return deFloatDegrees(f); }
     65 inline float exp2			(float f) { return deFloatExp2(f); }
     66 inline float log2			(float f) { return deFloatLog2(f); }
     67 inline float inverseSqrt	(float f) { return deFloatRsq(f); }
     68 inline float sign			(float f) { return (f < 0.0f) ? -1.0f : ((f > 0.0f) ? +1.0f : 0.0f); }
     69 inline float fract			(float f) { return f - deFloatFloor(f); }
     70 inline float mix			(float x, float y, float a) { return x * (1.0f - a) + y * a; }
     71 inline float step			(float edge, float x) { return (x < edge) ? 0.0f : 1.0f; }
     72 inline 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 
     80 inline double mix			(double x, double y, double a) { return x * (1.0 - a) + y * a; }
     81 inline double step			(double edge, double x) { return (x < edge) ? 0.0 : 1.0; }
     82 
     83 inline float length			(float f) { return deFloatAbs(f); }
     84 inline float distance		(float x, float y) { return deFloatAbs(x - y); }
     85 inline float dot			(float x, float y) { return (x * y); }
     86 
     87 inline float normalize		(float f) { return sign(f); }
     88 inline float faceForward	(float n, float i, float ref) { return ((ref * i) < 0.0f) ? n : -n; }
     89 inline float reflect		(float i, float n) { return i - 2.0f * (n * i) * n; }
     90 inline 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 
    100 inline float asinh			(float a) { return deFloatAsinh(a); }
    101 inline float acosh			(float a) { return deFloatAcosh(a); }
    102 inline float atanh			(float a) { return deFloatAtanh(a); }
    103 
    104 template<typename T> inline bool	lessThan			(T a, T b) { return (a < b); }
    105 template<typename T> inline bool	lessThanEqual		(T a, T b) { return (a <= b); }
    106 template<typename T> inline bool	greaterThan			(T a, T b) { return (a > b); }
    107 template<typename T> inline bool	greaterThanEqual	(T a, T b) { return (a >= b); }
    108 template<typename T> inline bool	equal				(T a, T b) { return (a == b); }
    109 template<typename T> inline bool	notEqual			(T a, T b) { return (a != b); }
    110 template<typename T> inline bool	allEqual			(T a, T b) { return (a == b); }
    111 template<typename T> inline bool	anyNotEqual			(T a, T b) { return (a != b); }
    112 
    113 inline bool boolNot				(bool a) { return !a; }
    114 
    115 inline int chopToInt			(float a) { return deChopFloatToInt32(a); }
    116 
    117 inline float trunc				(float a) { return (float)chopToInt(a); }
    118 
    119 inline 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 
    132 template <typename T, int Size>
    133 inline 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 
    141 template <typename T, int Size>
    142 inline 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 
    150 template <typename T, int Size>
    151 inline T length (const Vector<T, Size>& a)
    152 {
    153 	return ::sqrt(lengthSquared(a));
    154 }
    155 
    156 template <typename T, int Size>
    157 inline T distance (const Vector<T, Size>& a, const Vector<T, Size>& b)
    158 {
    159 	return length(a - b);
    160 }
    161 
    162 template <typename T, int Size>
    163 inline 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 
    172 template <typename T, int Size>
    173 inline 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 
    182 template <typename T, int Size>
    183 inline 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 
    188 template <typename T, int Size>
    189 inline 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 
    194 template <typename T, int Size>
    195 inline 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 
    206 template <int Size>
    207 Vector<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 
    215 template <int Size>
    216 Vector<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 
    226 template <typename T, int Size>
    227 inline 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 
    235 template <typename T, int Size>
    236 inline 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 
    244 template <typename T, int Size>
    245 inline 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 
    253 template <typename T, int Size>
    254 inline 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 
    262 template <typename T, int Size>
    263 inline 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 
    271 template <typename T, int Size>
    272 inline 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 
    282 template <typename T, int Size>
    283 inline 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 
    291 template <typename T, int Size>
    292 inline 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 
    302 template <int Size>
    303 inline 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 
    311 template <int Size>
    312 inline 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 
    320 template <int Size>
    321 inline 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 
    329 template <int Size>
    330 Vector<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 
    340 template <typename T, int Size>
    341 inline 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 
    351 template <typename T, int Size>
    352 inline 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 
    362 template<typename T, int Size>
    363 static 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)	\
    376 template <typename T, int Size>								\
    377 Vector<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)						\
    386 template <typename T, int Size>													\
    387 Vector<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)													\
    396 template <typename T, int Size>																				\
    397 Vector<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 
    413 TCU_DECLARE_VECTOR_UNARY_FUNC(negate, negate)
    414 TCU_DECLARE_VECTOR_UNARY_FUNC(bitwiseNot, bitwiseNot)
    415 TCU_DECLARE_VECTOR_BINARY_FUNC(add, add)
    416 TCU_DECLARE_VECTOR_BINARY_FUNC(sub, sub)
    417 TCU_DECLARE_VECTOR_BINARY_FUNC(mul, mul)
    418 TCU_DECLARE_VECTOR_BINARY_FUNC(div, div)
    419 TCU_DECLARE_VECTOR_BINARY_FUNC(mod, mod)
    420 TCU_DECLARE_VECTOR_BINARY_FUNC(bitwiseAnd, bitwiseAnd)
    421 TCU_DECLARE_VECTOR_BINARY_FUNC(bitwiseOr, bitwiseOr)
    422 TCU_DECLARE_VECTOR_BINARY_FUNC(bitwiseXor, bitwiseXor)
    423 TCU_DECLARE_VECTOR_UNARY_FUNC(logicalNot, logicalNot)
    424 TCU_DECLARE_VECTOR_BINARY_FUNC(logicalAnd, logicalAnd)
    425 TCU_DECLARE_VECTOR_BINARY_FUNC(logicalOr, logicalOr)
    426 
    427 TCU_DECLARE_VECTOR_UNARY_FUNC(radians, deFloatRadians)
    428 TCU_DECLARE_VECTOR_UNARY_FUNC(degrees, deFloatDegrees)
    429 TCU_DECLARE_VECTOR_UNARY_FUNC(sin, deFloatSin)
    430 TCU_DECLARE_VECTOR_UNARY_FUNC(cos, deFloatCos)
    431 TCU_DECLARE_VECTOR_UNARY_FUNC(tan, deFloatTan)
    432 TCU_DECLARE_VECTOR_UNARY_FUNC(asin, deFloatAsin)
    433 TCU_DECLARE_VECTOR_UNARY_FUNC(acos, deFloatAcos)
    434 TCU_DECLARE_VECTOR_UNARY_FUNC(atan, deFloatAtanOver)
    435 TCU_DECLARE_VECTOR_BINARY_FUNC(atan2, deFloatAtan2)
    436 TCU_DECLARE_VECTOR_UNARY_FUNC(sinh, deFloatSinh)
    437 TCU_DECLARE_VECTOR_UNARY_FUNC(cosh, deFloatCosh)
    438 TCU_DECLARE_VECTOR_UNARY_FUNC(tanh, deFloatTanh)
    439 TCU_DECLARE_VECTOR_UNARY_FUNC(asinh, deFloatAsinh)
    440 TCU_DECLARE_VECTOR_UNARY_FUNC(acosh, deFloatAcosh)
    441 TCU_DECLARE_VECTOR_UNARY_FUNC(atanh, deFloatAtanh)
    442 
    443 TCU_DECLARE_VECTOR_BINARY_FUNC(pow, deFloatPow)
    444 TCU_DECLARE_VECTOR_UNARY_FUNC(exp, deFloatExp)
    445 TCU_DECLARE_VECTOR_UNARY_FUNC(log, deFloatLog)
    446 TCU_DECLARE_VECTOR_UNARY_FUNC(exp2, deFloatExp2)
    447 TCU_DECLARE_VECTOR_UNARY_FUNC(log2, deFloatLog2)
    448 TCU_DECLARE_VECTOR_UNARY_FUNC(sqrt, deFloatSqrt)
    449 TCU_DECLARE_VECTOR_UNARY_FUNC(inverseSqrt, deFloatRsq)
    450 
    451 TCU_DECLARE_VECTOR_UNARY_FUNC(abs, de::abs)
    452 TCU_DECLARE_VECTOR_UNARY_FUNC(sign, deFloatSign)
    453 TCU_DECLARE_VECTOR_UNARY_FUNC(floor, deFloatFloor)
    454 TCU_DECLARE_VECTOR_UNARY_FUNC(trunc, trunc)
    455 TCU_DECLARE_VECTOR_UNARY_FUNC(roundToEven, roundToEven)
    456 TCU_DECLARE_VECTOR_UNARY_FUNC(ceil, deFloatCeil)
    457 TCU_DECLARE_VECTOR_UNARY_FUNC(fract, deFloatFrac)
    458 TCU_DECLARE_VECTOR_BINARY_FUNC(min, de::min)
    459 TCU_DECLARE_VECTOR_BINARY_FUNC(max, de::max)
    460 TCU_DECLARE_VECTOR_TERNARY_FUNC(clamp, de::clamp)
    461 TCU_DECLARE_VECTOR_TERNARY_FUNC(mix, deFloatMix)
    462 TCU_DECLARE_VECTOR_BINARY_FUNC(step, deFloatStep)
    463 TCU_DECLARE_VECTOR_TERNARY_FUNC(smoothStep, deFloatSmoothStep)
    464 
    465 } // tcu
    466 
    467 #endif // _TCUVECTORUTIL_HPP
    468