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