• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
abs(float f)40 inline float abs			(float f) { return deFloatAbs(f); }
41 #endif
42 
add(T a,T b)43 template<typename T> inline T add			(T a, T b) { return a + b; }
sub(T a,T b)44 template<typename T> inline T sub			(T a, T b) { return a - b; }
mul(T a,T b)45 template<typename T> inline T mul			(T a, T b) { return a * b; }
div(T a,T b)46 template<typename T> inline T div			(T a, T b) { return a / b; }
47 
bitwiseNot(T a)48 template<typename T> inline T bitwiseNot	(T a)		{ return ~a; }
bitwiseAnd(T a,T b)49 template<typename T> inline T bitwiseAnd	(T a, T b)	{ return a & b; }
bitwiseOr(T a,T b)50 template<typename T> inline T bitwiseOr		(T a, T b)	{ return a | b; }
bitwiseXor(T a,T b)51 template<typename T> inline T bitwiseXor	(T a, T b)	{ return a ^ b; }
52 
logicalNot(T a)53 template<typename T> inline T logicalNot	(T a)		{ return !a; }
logicalAnd(T a,T b)54 template<typename T> inline T logicalAnd	(T a, T b)	{ return a && b; }
logicalOr(T a,T b)55 template<typename T> inline T logicalOr		(T a, T b)	{ return a || b; }
56 
mod(T a,T b)57 template<typename T>	inline T		mod		(T a, T b)			{ return a % b; }
mod(float x,float y)58 template<>				inline float	mod		(float x, float y)	{ return x - y * floor(x / y); }
59 
negate(T f)60 template<typename T>	inline	T			negate				(T f)			{ return -f; }
negate(deUint32 f)61 template<>				inline	deUint32	negate<deUint32>	(deUint32 f)	{ return (deUint32)-(int)f;	}
62 
radians(float f)63 inline float radians		(float f) { return deFloatRadians(f); }
degrees(float f)64 inline float degrees		(float f) { return deFloatDegrees(f); }
exp2(float f)65 inline float exp2			(float f) { return deFloatExp2(f); }
log2(float f)66 inline float log2			(float f) { return deFloatLog2(f); }
inverseSqrt(float f)67 inline float inverseSqrt	(float f) { return deFloatRsq(f); }
sign(float f)68 inline float sign			(float f) { return (f < 0.0f) ? -1.0f : ((f > 0.0f) ? +1.0f : 0.0f); }
fract(float f)69 inline float fract			(float f) { return f - deFloatFloor(f); }
mix(float x,float y,float a)70 inline float mix			(float x, float y, float a) { return x * (1.0f - a) + y * a; }
step(float edge,float x)71 inline float step			(float edge, float x) { return (x < edge) ? 0.0f : 1.0f; }
smoothStep(float edge0,float edge1,float x)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 
mix(double x,double y,double a)80 inline double mix			(double x, double y, double a) { return x * (1.0 - a) + y * a; }
step(double edge,double x)81 inline double step			(double edge, double x) { return (x < edge) ? 0.0 : 1.0; }
82 
length(float f)83 inline float length			(float f) { return deFloatAbs(f); }
distance(float x,float y)84 inline float distance		(float x, float y) { return deFloatAbs(x - y); }
dot(float x,float y)85 inline float dot			(float x, float y) { return (x * y); }
86 
normalize(float f)87 inline float normalize		(float f) { return sign(f); }
faceForward(float n,float i,float ref)88 inline float faceForward	(float n, float i, float ref) { return ((ref * i) < 0.0f) ? n : -n; }
reflect(float i,float n)89 inline float reflect		(float i, float n) { return i - 2.0f * (n * i) * n; }
refract(float i,float n,float eta)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 
asinh(float a)100 inline float asinh			(float a) { return deFloatAsinh(a); }
acosh(float a)101 inline float acosh			(float a) { return deFloatAcosh(a); }
atanh(float a)102 inline float atanh			(float a) { return deFloatAtanh(a); }
103 
lessThan(T a,T b)104 template<typename T> inline bool	lessThan			(T a, T b) { return (a < b); }
lessThanEqual(T a,T b)105 template<typename T> inline bool	lessThanEqual		(T a, T b) { return (a <= b); }
greaterThan(T a,T b)106 template<typename T> inline bool	greaterThan			(T a, T b) { return (a > b); }
greaterThanEqual(T a,T b)107 template<typename T> inline bool	greaterThanEqual	(T a, T b) { return (a >= b); }
equal(T a,T b)108 template<typename T> inline bool	equal				(T a, T b) { return (a == b); }
notEqual(T a,T b)109 template<typename T> inline bool	notEqual			(T a, T b) { return (a != b); }
allEqual(T a,T b)110 template<typename T> inline bool	allEqual			(T a, T b) { return (a == b); }
anyNotEqual(T a,T b)111 template<typename T> inline bool	anyNotEqual			(T a, T b) { return (a != b); }
112 
boolNot(bool a)113 inline bool boolNot				(bool a) { return !a; }
114 
chopToInt(float a)115 inline int chopToInt			(float a) { return deChopFloatToInt32(a); }
116 
trunc(float a)117 inline float trunc				(float a) { return (float)chopToInt(a); }
118 
roundToEven(float a)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>
dot(const Vector<T,Size> & a,const Vector<T,Size> & b)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>
lengthSquared(const Vector<T,Size> & a)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>
length(const Vector<T,Size> & a)151 inline T length (const Vector<T, Size>& a)
152 {
153 	return ::sqrt(lengthSquared(a));
154 }
155 
156 template <typename T, int Size>
distance(const Vector<T,Size> & a,const Vector<T,Size> & b)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>
cross(const Vector<T,Size> & a,const Vector<T,Size> & b)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>
normalize(const Vector<T,Size> & a)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>
faceForward(const Vector<T,Size> & n,const Vector<T,Size> & i,const Vector<T,Size> & ref)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>
reflect(const Vector<T,Size> & i,const Vector<T,Size> & n)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>
refract(const Vector<T,Size> & i,const Vector<T,Size> & n,T eta)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>
mix(const Vector<float,Size> & x,const Vector<float,Size> & y,float a)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>
mix(const Vector<double,Size> & x,const Vector<double,Size> & y,double a)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>
equal(const Vector<T,Size> & a,const Vector<T,Size> & b)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>
notEqual(const Vector<T,Size> & a,const Vector<T,Size> & b)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>
lessThan(const Vector<T,Size> & a,const Vector<T,Size> & b)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>
lessThanEqual(const Vector<T,Size> & a,const Vector<T,Size> & b)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>
greaterThan(const Vector<T,Size> & a,const Vector<T,Size> & b)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>
greaterThanEqual(const Vector<T,Size> & a,const Vector<T,Size> & b)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>
allEqual(const Vector<T,Size> & a,const Vector<T,Size> & b)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>
anyNotEqual(const Vector<T,Size> & a,const Vector<T,Size> & b)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>
boolNot(const Vector<bool,Size> & a)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>
boolAny(const Vector<bool,Size> & a)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>
boolAll(const Vector<bool,Size> & a)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>
chopToInt(const Vector<float,Size> & v)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>
select(T trueVal,T falseVal,const Vector<bool,Size> & cond)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>
select(const Vector<T,Size> & trueVal,const Vector<T,Size> & falseVal,const Vector<bool,Size> & cond)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>
absDiff(const Vector<T,Size> & a,const Vector<T,Size> & b)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