1 /* 2 * Copyright 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 18 #pragma once 19 20 #include <math.h> 21 #include <stdint.h> 22 #include <sys/types.h> 23 24 #include <cmath> 25 #include <limits> 26 #include <iostream> 27 28 #define PURE __attribute__((pure)) 29 30 #if __cplusplus >= 201402L 31 #define CONSTEXPR constexpr 32 #else 33 #define CONSTEXPR 34 #endif 35 36 namespace android { 37 namespace details { 38 // ------------------------------------------------------------------------------------- 39 40 /* 41 * No user serviceable parts here. 42 * 43 * Don't use this file directly, instead include ui/vec{2|3|4}.h 44 */ 45 46 /* 47 * TVec{Add|Product}Operators implements basic arithmetic and basic compound assignments 48 * operators on a vector of type BASE<T>. 49 * 50 * BASE only needs to implement operator[] and size(). 51 * By simply inheriting from TVec{Add|Product}Operators<BASE, T> BASE will automatically 52 * get all the functionality here. 53 */ 54 55 template <template<typename T> class VECTOR, typename T> 56 class TVecAddOperators { 57 public: 58 /* compound assignment from a another vector of the same size but different 59 * element type. 60 */ 61 template<typename OTHER> 62 VECTOR<T>& operator +=(const VECTOR<OTHER>& v) { 63 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 64 for (size_t i = 0; i < lhs.size(); i++) { 65 lhs[i] += v[i]; 66 } 67 return lhs; 68 } 69 template<typename OTHER> 70 VECTOR<T>& operator -=(const VECTOR<OTHER>& v) { 71 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 72 for (size_t i = 0; i < lhs.size(); i++) { 73 lhs[i] -= v[i]; 74 } 75 return lhs; 76 } 77 78 /* compound assignment from a another vector of the same type. 79 * These operators can be used for implicit conversion and handle operations 80 * like "vector *= scalar" by letting the compiler implicitly convert a scalar 81 * to a vector (assuming the BASE<T> allows it). 82 */ 83 VECTOR<T>& operator +=(const VECTOR<T>& v) { 84 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 85 for (size_t i = 0; i < lhs.size(); i++) { 86 lhs[i] += v[i]; 87 } 88 return lhs; 89 } 90 VECTOR<T>& operator -=(const VECTOR<T>& v) { 91 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 92 for (size_t i = 0; i < lhs.size(); i++) { 93 lhs[i] -= v[i]; 94 } 95 return lhs; 96 } 97 98 /* 99 * NOTE: the functions below ARE NOT member methods. They are friend functions 100 * with they definition inlined with their declaration. This makes these 101 * template functions available to the compiler when (and only when) this class 102 * is instantiated, at which point they're only templated on the 2nd parameter 103 * (the first one, BASE<T> being known). 104 */ 105 106 /* The operators below handle operation between vectors of the same size 107 * but of a different element type. 108 */ 109 template<typename RT> 110 friend inline constexpr VECTOR<T> PURE operator +(VECTOR<T> lv, const VECTOR<RT>& rv) { 111 // don't pass lv by reference because we need a copy anyways 112 return lv += rv; 113 } 114 template<typename RT> 115 friend inline constexpr VECTOR<T> PURE operator -(VECTOR<T> lv, const VECTOR<RT>& rv) { 116 // don't pass lv by reference because we need a copy anyways 117 return lv -= rv; 118 } 119 120 /* The operators below (which are not templates once this class is instanced, 121 * i.e.: BASE<T> is known) can be used for implicit conversion on both sides. 122 * These handle operations like "vector + scalar" and "scalar + vector" by 123 * letting the compiler implicitly convert a scalar to a vector (assuming 124 * the BASE<T> allows it). 125 */ 126 friend inline constexpr VECTOR<T> PURE operator +(VECTOR<T> lv, const VECTOR<T>& rv) { 127 // don't pass lv by reference because we need a copy anyways 128 return lv += rv; 129 } 130 friend inline constexpr VECTOR<T> PURE operator -(VECTOR<T> lv, const VECTOR<T>& rv) { 131 // don't pass lv by reference because we need a copy anyways 132 return lv -= rv; 133 } 134 }; 135 136 template<template<typename T> class VECTOR, typename T> 137 class TVecProductOperators { 138 public: 139 /* compound assignment from a another vector of the same size but different 140 * element type. 141 */ 142 template<typename OTHER> 143 VECTOR<T>& operator *=(const VECTOR<OTHER>& v) { 144 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 145 for (size_t i = 0; i < lhs.size(); i++) { 146 lhs[i] *= v[i]; 147 } 148 return lhs; 149 } 150 template<typename OTHER> 151 VECTOR<T>& operator /=(const VECTOR<OTHER>& v) { 152 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 153 for (size_t i = 0; i < lhs.size(); i++) { 154 lhs[i] /= v[i]; 155 } 156 return lhs; 157 } 158 159 /* compound assignment from a another vector of the same type. 160 * These operators can be used for implicit conversion and handle operations 161 * like "vector *= scalar" by letting the compiler implicitly convert a scalar 162 * to a vector (assuming the BASE<T> allows it). 163 */ 164 VECTOR<T>& operator *=(const VECTOR<T>& v) { 165 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 166 for (size_t i = 0; i < lhs.size(); i++) { 167 lhs[i] *= v[i]; 168 } 169 return lhs; 170 } 171 VECTOR<T>& operator /=(const VECTOR<T>& v) { 172 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 173 for (size_t i = 0; i < lhs.size(); i++) { 174 lhs[i] /= v[i]; 175 } 176 return lhs; 177 } 178 179 /* 180 * NOTE: the functions below ARE NOT member methods. They are friend functions 181 * with they definition inlined with their declaration. This makes these 182 * template functions available to the compiler when (and only when) this class 183 * is instantiated, at which point they're only templated on the 2nd parameter 184 * (the first one, BASE<T> being known). 185 */ 186 187 /* The operators below handle operation between vectors of the same size 188 * but of a different element type. 189 */ 190 template<typename RT> 191 friend inline constexpr VECTOR<T> PURE operator *(VECTOR<T> lv, const VECTOR<RT>& rv) { 192 // don't pass lv by reference because we need a copy anyways 193 return lv *= rv; 194 } 195 template<typename RT> 196 friend inline constexpr VECTOR<T> PURE operator /(VECTOR<T> lv, const VECTOR<RT>& rv) { 197 // don't pass lv by reference because we need a copy anyways 198 return lv /= rv; 199 } 200 201 /* The operators below (which are not templates once this class is instanced, 202 * i.e.: BASE<T> is known) can be used for implicit conversion on both sides. 203 * These handle operations like "vector * scalar" and "scalar * vector" by 204 * letting the compiler implicitly convert a scalar to a vector (assuming 205 * the BASE<T> allows it). 206 */ 207 friend inline constexpr VECTOR<T> PURE operator *(VECTOR<T> lv, const VECTOR<T>& rv) { 208 // don't pass lv by reference because we need a copy anyways 209 return lv *= rv; 210 } 211 friend inline constexpr VECTOR<T> PURE operator /(VECTOR<T> lv, const VECTOR<T>& rv) { 212 // don't pass lv by reference because we need a copy anyways 213 return lv /= rv; 214 } 215 }; 216 217 /* 218 * TVecUnaryOperators implements unary operators on a vector of type BASE<T>. 219 * 220 * BASE only needs to implement operator[] and size(). 221 * By simply inheriting from TVecUnaryOperators<BASE, T> BASE will automatically 222 * get all the functionality here. 223 * 224 * These operators are implemented as friend functions of TVecUnaryOperators<BASE, T> 225 */ 226 template<template<typename T> class VECTOR, typename T> 227 class TVecUnaryOperators { 228 public: 229 VECTOR<T>& operator ++() { 230 VECTOR<T>& rhs = static_cast<VECTOR<T>&>(*this); 231 for (size_t i = 0; i < rhs.size(); i++) { 232 ++rhs[i]; 233 } 234 return rhs; 235 } 236 237 VECTOR<T>& operator --() { 238 VECTOR<T>& rhs = static_cast<VECTOR<T>&>(*this); 239 for (size_t i = 0; i < rhs.size(); i++) { 240 --rhs[i]; 241 } 242 return rhs; 243 } 244 245 CONSTEXPR VECTOR<T> operator -() const { 246 VECTOR<T> r(VECTOR<T>::NO_INIT); 247 VECTOR<T> const& rv(static_cast<VECTOR<T> const&>(*this)); 248 for (size_t i = 0; i < r.size(); i++) { 249 r[i] = -rv[i]; 250 } 251 return r; 252 } 253 }; 254 255 /* 256 * TVecComparisonOperators implements relational/comparison operators 257 * on a vector of type BASE<T>. 258 * 259 * BASE only needs to implement operator[] and size(). 260 * By simply inheriting from TVecComparisonOperators<BASE, T> BASE will automatically 261 * get all the functionality here. 262 */ 263 template<template<typename T> class VECTOR, typename T> 264 class TVecComparisonOperators { 265 public: 266 /* 267 * NOTE: the functions below ARE NOT member methods. They are friend functions 268 * with they definition inlined with their declaration. This makes these 269 * template functions available to the compiler when (and only when) this class 270 * is instantiated, at which point they're only templated on the 2nd parameter 271 * (the first one, BASE<T> being known). 272 */ 273 template<typename RT> 274 friend inline 275 bool PURE operator ==(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 276 for (size_t i = 0; i < lv.size(); i++) 277 if (lv[i] != rv[i]) 278 return false; 279 return true; 280 } 281 282 template<typename RT> 283 friend inline 284 bool PURE operator !=(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 285 return !operator ==(lv, rv); 286 } 287 288 template<typename RT> 289 friend inline 290 bool PURE operator >(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 291 for (size_t i = 0; i < lv.size(); i++) { 292 if (lv[i] == rv[i]) { 293 continue; 294 } 295 return lv[i] > rv[i]; 296 } 297 return false; 298 } 299 300 template<typename RT> 301 friend inline 302 constexpr bool PURE operator <=(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 303 return !(lv > rv); 304 } 305 306 template<typename RT> 307 friend inline 308 bool PURE operator <(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 309 for (size_t i = 0; i < lv.size(); i++) { 310 if (lv[i] == rv[i]) { 311 continue; 312 } 313 return lv[i] < rv[i]; 314 } 315 return false; 316 } 317 318 template<typename RT> 319 friend inline 320 constexpr bool PURE operator >=(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 321 return !(lv < rv); 322 } 323 324 template<typename RT> 325 friend inline equal(const VECTOR<T> & lv,const VECTOR<RT> & rv)326 CONSTEXPR VECTOR<bool> PURE equal(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 327 VECTOR<bool> r; 328 for (size_t i = 0; i < lv.size(); i++) { 329 r[i] = lv[i] == rv[i]; 330 } 331 return r; 332 } 333 334 template<typename RT> 335 friend inline notEqual(const VECTOR<T> & lv,const VECTOR<RT> & rv)336 CONSTEXPR VECTOR<bool> PURE notEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 337 VECTOR<bool> r; 338 for (size_t i = 0; i < lv.size(); i++) { 339 r[i] = lv[i] != rv[i]; 340 } 341 return r; 342 } 343 344 template<typename RT> 345 friend inline lessThan(const VECTOR<T> & lv,const VECTOR<RT> & rv)346 CONSTEXPR VECTOR<bool> PURE lessThan(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 347 VECTOR<bool> r; 348 for (size_t i = 0; i < lv.size(); i++) { 349 r[i] = lv[i] < rv[i]; 350 } 351 return r; 352 } 353 354 template<typename RT> 355 friend inline lessThanEqual(const VECTOR<T> & lv,const VECTOR<RT> & rv)356 CONSTEXPR VECTOR<bool> PURE lessThanEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 357 VECTOR<bool> r; 358 for (size_t i = 0; i < lv.size(); i++) { 359 r[i] = lv[i] <= rv[i]; 360 } 361 return r; 362 } 363 364 template<typename RT> 365 friend inline greaterThan(const VECTOR<T> & lv,const VECTOR<RT> & rv)366 CONSTEXPR VECTOR<bool> PURE greaterThan(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 367 VECTOR<bool> r; 368 for (size_t i = 0; i < lv.size(); i++) { 369 r[i] = lv[i] > rv[i]; 370 } 371 return r; 372 } 373 374 template<typename RT> 375 friend inline greaterThanEqual(const VECTOR<T> & lv,const VECTOR<RT> & rv)376 CONSTEXPR VECTOR<bool> PURE greaterThanEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 377 VECTOR<bool> r; 378 for (size_t i = 0; i < lv.size(); i++) { 379 r[i] = lv[i] >= rv[i]; 380 } 381 return r; 382 } 383 }; 384 385 /* 386 * TVecFunctions implements functions on a vector of type BASE<T>. 387 * 388 * BASE only needs to implement operator[] and size(). 389 * By simply inheriting from TVecFunctions<BASE, T> BASE will automatically 390 * get all the functionality here. 391 */ 392 template<template<typename T> class VECTOR, typename T> 393 class TVecFunctions { 394 public: 395 /* 396 * NOTE: the functions below ARE NOT member methods. They are friend functions 397 * with they definition inlined with their declaration. This makes these 398 * template functions available to the compiler when (and only when) this class 399 * is instantiated, at which point they're only templated on the 2nd parameter 400 * (the first one, BASE<T> being known). 401 */ 402 template<typename RT> dot(const VECTOR<T> & lv,const VECTOR<RT> & rv)403 friend inline CONSTEXPR T PURE dot(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 404 T r(0); 405 for (size_t i = 0; i < lv.size(); i++) { 406 //r = std::fma(lv[i], rv[i], r); 407 r += lv[i] * rv[i]; 408 } 409 return r; 410 } 411 norm(const VECTOR<T> & lv)412 friend inline constexpr T PURE norm(const VECTOR<T>& lv) { 413 return std::sqrt(dot(lv, lv)); 414 } 415 length(const VECTOR<T> & lv)416 friend inline constexpr T PURE length(const VECTOR<T>& lv) { 417 return norm(lv); 418 } 419 norm2(const VECTOR<T> & lv)420 friend inline constexpr T PURE norm2(const VECTOR<T>& lv) { 421 return dot(lv, lv); 422 } 423 length2(const VECTOR<T> & lv)424 friend inline constexpr T PURE length2(const VECTOR<T>& lv) { 425 return norm2(lv); 426 } 427 428 template<typename RT> distance(const VECTOR<T> & lv,const VECTOR<RT> & rv)429 friend inline constexpr T PURE distance(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 430 return length(rv - lv); 431 } 432 433 template<typename RT> distance2(const VECTOR<T> & lv,const VECTOR<RT> & rv)434 friend inline constexpr T PURE distance2(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 435 return length2(rv - lv); 436 } 437 normalize(const VECTOR<T> & lv)438 friend inline constexpr VECTOR<T> PURE normalize(const VECTOR<T>& lv) { 439 return lv * (T(1) / length(lv)); 440 } 441 rcp(VECTOR<T> v)442 friend inline constexpr VECTOR<T> PURE rcp(VECTOR<T> v) { 443 return T(1) / v; 444 } 445 abs(VECTOR<T> v)446 friend inline CONSTEXPR VECTOR<T> PURE abs(VECTOR<T> v) { 447 for (size_t i = 0; i < v.size(); i++) { 448 v[i] = std::abs(v[i]); 449 } 450 return v; 451 } 452 floor(VECTOR<T> v)453 friend inline CONSTEXPR VECTOR<T> PURE floor(VECTOR<T> v) { 454 for (size_t i = 0; i < v.size(); i++) { 455 v[i] = std::floor(v[i]); 456 } 457 return v; 458 } 459 ceil(VECTOR<T> v)460 friend inline CONSTEXPR VECTOR<T> PURE ceil(VECTOR<T> v) { 461 for (size_t i = 0; i < v.size(); i++) { 462 v[i] = std::ceil(v[i]); 463 } 464 return v; 465 } 466 round(VECTOR<T> v)467 friend inline CONSTEXPR VECTOR<T> PURE round(VECTOR<T> v) { 468 for (size_t i = 0; i < v.size(); i++) { 469 v[i] = std::round(v[i]); 470 } 471 return v; 472 } 473 inversesqrt(VECTOR<T> v)474 friend inline CONSTEXPR VECTOR<T> PURE inversesqrt(VECTOR<T> v) { 475 for (size_t i = 0; i < v.size(); i++) { 476 v[i] = T(1) / std::sqrt(v[i]); 477 } 478 return v; 479 } 480 sqrt(VECTOR<T> v)481 friend inline CONSTEXPR VECTOR<T> PURE sqrt(VECTOR<T> v) { 482 for (size_t i = 0; i < v.size(); i++) { 483 v[i] = std::sqrt(v[i]); 484 } 485 return v; 486 } 487 pow(VECTOR<T> v,T p)488 friend inline CONSTEXPR VECTOR<T> PURE pow(VECTOR<T> v, T p) { 489 for (size_t i = 0; i < v.size(); i++) { 490 v[i] = std::pow(v[i], p); 491 } 492 return v; 493 } 494 saturate(const VECTOR<T> & lv)495 friend inline CONSTEXPR VECTOR<T> PURE saturate(const VECTOR<T>& lv) { 496 return clamp(lv, T(0), T(1)); 497 } 498 clamp(VECTOR<T> v,T min,T max)499 friend inline CONSTEXPR VECTOR<T> PURE clamp(VECTOR<T> v, T min, T max) { 500 for (size_t i = 0; i< v.size(); i++) { 501 v[i] = std::min(max, std::max(min, v[i])); 502 } 503 return v; 504 } 505 fma(const VECTOR<T> & lv,const VECTOR<T> & rv,VECTOR<T> a)506 friend inline CONSTEXPR VECTOR<T> PURE fma(const VECTOR<T>& lv, const VECTOR<T>& rv, VECTOR<T> a) { 507 for (size_t i = 0; i<lv.size(); i++) { 508 //a[i] = std::fma(lv[i], rv[i], a[i]); 509 a[i] += (lv[i] * rv[i]); 510 } 511 return a; 512 } 513 min(const VECTOR<T> & u,VECTOR<T> v)514 friend inline CONSTEXPR VECTOR<T> PURE min(const VECTOR<T>& u, VECTOR<T> v) { 515 for (size_t i = 0; i < v.size(); i++) { 516 v[i] = std::min(u[i], v[i]); 517 } 518 return v; 519 } 520 max(const VECTOR<T> & u,VECTOR<T> v)521 friend inline CONSTEXPR VECTOR<T> PURE max(const VECTOR<T>& u, VECTOR<T> v) { 522 for (size_t i = 0; i < v.size(); i++) { 523 v[i] = std::max(u[i], v[i]); 524 } 525 return v; 526 } 527 max(const VECTOR<T> & v)528 friend inline CONSTEXPR T PURE max(const VECTOR<T>& v) { 529 T r(std::numeric_limits<T>::lowest()); 530 for (size_t i = 0; i < v.size(); i++) { 531 r = std::max(r, v[i]); 532 } 533 return r; 534 } 535 min(const VECTOR<T> & v)536 friend inline CONSTEXPR T PURE min(const VECTOR<T>& v) { 537 T r(std::numeric_limits<T>::max()); 538 for (size_t i = 0; i < v.size(); i++) { 539 r = std::min(r, v[i]); 540 } 541 return r; 542 } 543 apply(VECTOR<T> v,const std::function<T (T)> & f)544 friend inline CONSTEXPR VECTOR<T> PURE apply(VECTOR<T> v, const std::function<T(T)>& f) { 545 for (size_t i = 0; i < v.size(); i++) { 546 v[i] = f(v[i]); 547 } 548 return v; 549 } 550 any(const VECTOR<T> & v)551 friend inline CONSTEXPR bool PURE any(const VECTOR<T>& v) { 552 for (size_t i = 0; i < v.size(); i++) { 553 if (v[i] != T(0)) return true; 554 } 555 return false; 556 } 557 all(const VECTOR<T> & v)558 friend inline CONSTEXPR bool PURE all(const VECTOR<T>& v) { 559 bool result = true; 560 for (size_t i = 0; i < v.size(); i++) { 561 result &= (v[i] != T(0)); 562 } 563 return result; 564 } 565 566 template<typename R> map(VECTOR<T> v,const std::function<R (T)> & f)567 friend inline CONSTEXPR VECTOR<R> PURE map(VECTOR<T> v, const std::function<R(T)>& f) { 568 VECTOR<R> result; 569 for (size_t i = 0; i < v.size(); i++) { 570 result[i] = f(v[i]); 571 } 572 return result; 573 } 574 }; 575 576 /* 577 * TVecDebug implements functions on a vector of type BASE<T>. 578 * 579 * BASE only needs to implement operator[] and size(). 580 * By simply inheriting from TVecDebug<BASE, T> BASE will automatically 581 * get all the functionality here. 582 */ 583 template<template<typename T> class VECTOR, typename T> 584 class TVecDebug { 585 public: 586 /* 587 * NOTE: the functions below ARE NOT member methods. They are friend functions 588 * with they definition inlined with their declaration. This makes these 589 * template functions available to the compiler when (and only when) this class 590 * is instantiated, at which point they're only templated on the 2nd parameter 591 * (the first one, BASE<T> being known). 592 */ 593 friend std::ostream& operator<<(std::ostream& stream, const VECTOR<T>& v) { 594 stream << "< "; 595 for (size_t i = 0; i < v.size() - 1; i++) { 596 stream << T(v[i]) << ", "; 597 } 598 stream << T(v[v.size() - 1]) << " >"; 599 return stream; 600 } 601 }; 602 603 #undef CONSTEXPR 604 #undef PURE 605 606 // ------------------------------------------------------------------------------------- 607 } // namespace details 608 } // namespace android 609