1// This code is in the public domain -- castanyo@yahoo.es 2 3#ifndef NV_MATH_VECTOR_INL 4#define NV_MATH_VECTOR_INL 5 6#include "vector.h" 7#include "nvcore/utils.h" // min, max 8#include "nvcore/hash.h" // hash 9 10namespace nv 11{ 12 13 // Helpers to convert vector types. Assume T has x,y members and 2 argument constructor. 14 //template <typename T> T to(Vector2::Arg v) { return T(v.x, v.y); } 15 16 // Helpers to convert vector types. Assume T has x,y,z members and 3 argument constructor. 17 //template <typename T> T to(Vector3::Arg v) { return T(v.x, v.y, v.z); } 18 19 // Helpers to convert vector types. Assume T has x,y,z members and 3 argument constructor. 20 //template <typename T> T to(Vector4::Arg v) { return T(v.x, v.y, v.z, v.w); } 21 22 23 // Vector2 24 inline Vector2::Vector2() {} 25 inline Vector2::Vector2(float f) : x(f), y(f) {} 26 inline Vector2::Vector2(float x, float y) : x(x), y(y) {} 27 inline Vector2::Vector2(Vector2::Arg v) : x(v.x), y(v.y) {} 28 29 inline const Vector2 & Vector2::operator=(Vector2::Arg v) 30 { 31 x = v.x; 32 y = v.y; 33 return *this; 34 } 35 36 inline const float * Vector2::ptr() const 37 { 38 return &x; 39 } 40 41 inline void Vector2::set(float x, float y) 42 { 43 this->x = x; 44 this->y = y; 45 } 46 47 inline Vector2 Vector2::operator-() const 48 { 49 return Vector2(-x, -y); 50 } 51 52 inline void Vector2::operator+=(Vector2::Arg v) 53 { 54 x += v.x; 55 y += v.y; 56 } 57 58 inline void Vector2::operator-=(Vector2::Arg v) 59 { 60 x -= v.x; 61 y -= v.y; 62 } 63 64 inline void Vector2::operator*=(float s) 65 { 66 x *= s; 67 y *= s; 68 } 69 70 inline void Vector2::operator*=(Vector2::Arg v) 71 { 72 x *= v.x; 73 y *= v.y; 74 } 75 76 inline bool operator==(Vector2::Arg a, Vector2::Arg b) 77 { 78 return a.x == b.x && a.y == b.y; 79 } 80 inline bool operator!=(Vector2::Arg a, Vector2::Arg b) 81 { 82 return a.x != b.x || a.y != b.y; 83 } 84 85 86 // Vector3 87 inline Vector3::Vector3() {} 88 inline Vector3::Vector3(float f) : x(f), y(f), z(f) {} 89 inline Vector3::Vector3(float x, float y, float z) : x(x), y(y), z(z) {} 90 inline Vector3::Vector3(Vector2::Arg v, float z) : x(v.x), y(v.y), z(z) {} 91 inline Vector3::Vector3(Vector3::Arg v) : x(v.x), y(v.y), z(v.z) {} 92 93 inline const Vector3 & Vector3::operator=(Vector3::Arg v) 94 { 95 x = v.x; 96 y = v.y; 97 z = v.z; 98 return *this; 99 } 100 101 102 inline Vector2 Vector3::xy() const 103 { 104 return Vector2(x, y); 105 } 106 107 inline const float * Vector3::ptr() const 108 { 109 return &x; 110 } 111 112 inline void Vector3::set(float x, float y, float z) 113 { 114 this->x = x; 115 this->y = y; 116 this->z = z; 117 } 118 119 inline Vector3 Vector3::operator-() const 120 { 121 return Vector3(-x, -y, -z); 122 } 123 124 inline void Vector3::operator+=(Vector3::Arg v) 125 { 126 x += v.x; 127 y += v.y; 128 z += v.z; 129 } 130 131 inline void Vector3::operator-=(Vector3::Arg v) 132 { 133 x -= v.x; 134 y -= v.y; 135 z -= v.z; 136 } 137 138 inline void Vector3::operator*=(float s) 139 { 140 x *= s; 141 y *= s; 142 z *= s; 143 } 144 145 inline void Vector3::operator/=(float s) 146 { 147 float is = 1.0f / s; 148 x *= is; 149 y *= is; 150 z *= is; 151 } 152 153 inline void Vector3::operator*=(Vector3::Arg v) 154 { 155 x *= v.x; 156 y *= v.y; 157 z *= v.z; 158 } 159 160 inline void Vector3::operator/=(Vector3::Arg v) 161 { 162 x /= v.x; 163 y /= v.y; 164 z /= v.z; 165 } 166 167 inline bool operator==(Vector3::Arg a, Vector3::Arg b) 168 { 169 return a.x == b.x && a.y == b.y && a.z == b.z; 170 } 171 inline bool operator!=(Vector3::Arg a, Vector3::Arg b) 172 { 173 return a.x != b.x || a.y != b.y || a.z != b.z; 174 } 175 176 177 // Vector4 178 inline Vector4::Vector4() {} 179 inline Vector4::Vector4(float f) : x(f), y(f), z(f), w(f) {} 180 inline Vector4::Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {} 181 inline Vector4::Vector4(Vector2::Arg v, float z, float w) : x(v.x), y(v.y), z(z), w(w) {} 182 inline Vector4::Vector4(Vector2::Arg v, Vector2::Arg u) : x(v.x), y(v.y), z(u.x), w(u.y) {} 183 inline Vector4::Vector4(Vector3::Arg v, float w) : x(v.x), y(v.y), z(v.z), w(w) {} 184 inline Vector4::Vector4(Vector4::Arg v) : x(v.x), y(v.y), z(v.z), w(v.w) {} 185 186 inline const Vector4 & Vector4::operator=(const Vector4 & v) 187 { 188 x = v.x; 189 y = v.y; 190 z = v.z; 191 w = v.w; 192 return *this; 193 } 194 195 inline Vector2 Vector4::xy() const 196 { 197 return Vector2(x, y); 198 } 199 200 inline Vector2 Vector4::zw() const 201 { 202 return Vector2(z, w); 203 } 204 205 inline Vector3 Vector4::xyz() const 206 { 207 return Vector3(x, y, z); 208 } 209 210 inline const float * Vector4::ptr() const 211 { 212 return &x; 213 } 214 215 inline void Vector4::set(float x, float y, float z, float w) 216 { 217 this->x = x; 218 this->y = y; 219 this->z = z; 220 this->w = w; 221 } 222 223 inline Vector4 Vector4::operator-() const 224 { 225 return Vector4(-x, -y, -z, -w); 226 } 227 228 inline void Vector4::operator+=(Vector4::Arg v) 229 { 230 x += v.x; 231 y += v.y; 232 z += v.z; 233 w += v.w; 234 } 235 236 inline void Vector4::operator-=(Vector4::Arg v) 237 { 238 x -= v.x; 239 y -= v.y; 240 z -= v.z; 241 w -= v.w; 242 } 243 244 inline void Vector4::operator*=(float s) 245 { 246 x *= s; 247 y *= s; 248 z *= s; 249 w *= s; 250 } 251 252 inline void Vector4::operator/=(float s) 253 { 254 x /= s; 255 y /= s; 256 z /= s; 257 w /= s; 258 } 259 260 inline void Vector4::operator*=(Vector4::Arg v) 261 { 262 x *= v.x; 263 y *= v.y; 264 z *= v.z; 265 w *= v.w; 266 } 267 268 inline void Vector4::operator/=(Vector4::Arg v) 269 { 270 x /= v.x; 271 y /= v.y; 272 z /= v.z; 273 w /= v.w; 274 } 275 276 inline bool operator==(Vector4::Arg a, Vector4::Arg b) 277 { 278 return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w; 279 } 280 inline bool operator!=(Vector4::Arg a, Vector4::Arg b) 281 { 282 return a.x != b.x || a.y != b.y || a.z != b.z || a.w != b.w; 283 } 284 285 286 287 // Functions 288 289 290 // Vector2 291 292 inline Vector2 add(Vector2::Arg a, Vector2::Arg b) 293 { 294 return Vector2(a.x + b.x, a.y + b.y); 295 } 296 inline Vector2 operator+(Vector2::Arg a, Vector2::Arg b) 297 { 298 return add(a, b); 299 } 300 301 inline Vector2 sub(Vector2::Arg a, Vector2::Arg b) 302 { 303 return Vector2(a.x - b.x, a.y - b.y); 304 } 305 inline Vector2 operator-(Vector2::Arg a, Vector2::Arg b) 306 { 307 return sub(a, b); 308 } 309 310 inline Vector2 scale(Vector2::Arg v, float s) 311 { 312 return Vector2(v.x * s, v.y * s); 313 } 314 315 inline Vector2 scale(Vector2::Arg v, Vector2::Arg s) 316 { 317 return Vector2(v.x * s.x, v.y * s.y); 318 } 319 320 inline Vector2 operator*(Vector2::Arg v, float s) 321 { 322 return scale(v, s); 323 } 324 325 inline Vector2 operator*(Vector2::Arg v1, Vector2::Arg v2) 326 { 327 return Vector2(v1.x*v2.x, v1.y*v2.y); 328 } 329 330 inline Vector2 operator*(float s, Vector2::Arg v) 331 { 332 return scale(v, s); 333 } 334 335 inline Vector2 operator/(Vector2::Arg v, float s) 336 { 337 return scale(v, 1.0f/s); 338 } 339 340 inline Vector2 lerp(Vector2::Arg v1, Vector2::Arg v2, float t) 341 { 342 const float s = 1.0f - t; 343 return Vector2(v1.x * s + t * v2.x, v1.y * s + t * v2.y); 344 } 345 346 inline float dot(Vector2::Arg a, Vector2::Arg b) 347 { 348 return a.x * b.x + a.y * b.y; 349 } 350 351 inline float lengthSquared(Vector2::Arg v) 352 { 353 return v.x * v.x + v.y * v.y; 354 } 355 356 inline float length(Vector2::Arg v) 357 { 358 return sqrtf(lengthSquared(v)); 359 } 360 361 inline float distance(Vector2::Arg a, Vector2::Arg b) 362 { 363 return length(a - b); 364 } 365 366 inline float inverseLength(Vector2::Arg v) 367 { 368 return 1.0f / sqrtf(lengthSquared(v)); 369 } 370 371 inline bool isNormalized(Vector2::Arg v, float epsilon = NV_NORMAL_EPSILON) 372 { 373 return equal(length(v), 1, epsilon); 374 } 375 376 inline Vector2 normalize(Vector2::Arg v, float epsilon = NV_EPSILON) 377 { 378 float l = length(v); 379 NV_UNUSED(epsilon); 380 nvDebugCheck(!isZero(l, epsilon)); 381 Vector2 n = scale(v, 1.0f / l); 382 nvDebugCheck(isNormalized(n)); 383 return n; 384 } 385 386 inline Vector2 normalizeSafe(Vector2::Arg v, Vector2::Arg fallback, float epsilon = NV_EPSILON) 387 { 388 float l = length(v); 389 if (isZero(l, epsilon)) { 390 return fallback; 391 } 392 return scale(v, 1.0f / l); 393 } 394 395 // Safe, branchless normalization from Andy Firth. All error checking ommitted. 396 // http://altdevblogaday.com/2011/08/21/practical-flt-point-tricks/ 397 inline Vector2 normalizeFast(Vector2::Arg v) 398 { 399 const float very_small_float = 1.0e-037f; 400 float l = very_small_float + length(v); 401 return scale(v, 1.0f / l); 402 } 403 404 inline bool equal(Vector2::Arg v1, Vector2::Arg v2, float epsilon = NV_EPSILON) 405 { 406 return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon); 407 } 408 409 inline Vector2 min(Vector2::Arg a, Vector2::Arg b) 410 { 411 return Vector2(min(a.x, b.x), min(a.y, b.y)); 412 } 413 414 inline Vector2 max(Vector2::Arg a, Vector2::Arg b) 415 { 416 return Vector2(max(a.x, b.x), max(a.y, b.y)); 417 } 418 419 inline Vector2 clamp(Vector2::Arg v, float min, float max) 420 { 421 return Vector2(clamp(v.x, min, max), clamp(v.y, min, max)); 422 } 423 424 inline Vector2 saturate(Vector2::Arg v) 425 { 426 return Vector2(saturate(v.x), saturate(v.y)); 427 } 428 429 inline bool isFinite(Vector2::Arg v) 430 { 431 return isFinite(v.x) && isFinite(v.y); 432 } 433 434 inline Vector2 validate(Vector2::Arg v, Vector2::Arg fallback = Vector2(0.0f)) 435 { 436 if (!isFinite(v)) return fallback; 437 Vector2 vf = v; 438 nv::floatCleanup(vf.component, 2); 439 return vf; 440 } 441 442 // Note, this is the area scaled by 2! 443 inline float triangleArea(Vector2::Arg v0, Vector2::Arg v1) 444 { 445 return (v0.x * v1.y - v0.y * v1.x); // * 0.5f; 446 } 447 inline float triangleArea(Vector2::Arg a, Vector2::Arg b, Vector2::Arg c) 448 { 449 // IC: While it may be appealing to use the following expression: 450 //return (c.x * a.y + a.x * b.y + b.x * c.y - b.x * a.y - c.x * b.y - a.x * c.y); // * 0.5f; 451 452 // That's actually a terrible idea. Small triangles far from the origin can end up producing fairly large floating point 453 // numbers and the results becomes very unstable and dependent on the order of the factors. 454 455 // Instead, it's preferable to substract the vertices first, and multiply the resulting small values together. The result 456 // in this case is always much more accurate (as long as the triangle is small) and less dependent of the location of 457 // the triangle. 458 459 //return ((a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x)); // * 0.5f; 460 return triangleArea(a-c, b-c); 461 } 462 463 464 template <> 465 inline uint hash(const Vector2 & v, uint h) 466 { 467 return sdbmFloatHash(v.component, 2, h); 468 } 469 470 471 472 // Vector3 473 474 inline Vector3 add(Vector3::Arg a, Vector3::Arg b) 475 { 476 return Vector3(a.x + b.x, a.y + b.y, a.z + b.z); 477 } 478 inline Vector3 add(Vector3::Arg a, float b) 479 { 480 return Vector3(a.x + b, a.y + b, a.z + b); 481 } 482 inline Vector3 operator+(Vector3::Arg a, Vector3::Arg b) 483 { 484 return add(a, b); 485 } 486 inline Vector3 operator+(Vector3::Arg a, float b) 487 { 488 return add(a, b); 489 } 490 491 inline Vector3 sub(Vector3::Arg a, Vector3::Arg b) 492 { 493 return Vector3(a.x - b.x, a.y - b.y, a.z - b.z); 494 } 495 inline Vector3 sub(Vector3::Arg a, float b) 496 { 497 return Vector3(a.x - b, a.y - b, a.z - b); 498 } 499 inline Vector3 operator-(Vector3::Arg a, Vector3::Arg b) 500 { 501 return sub(a, b); 502 } 503 inline Vector3 operator-(Vector3::Arg a, float b) 504 { 505 return sub(a, b); 506 } 507 508 inline Vector3 cross(Vector3::Arg a, Vector3::Arg b) 509 { 510 return Vector3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); 511 } 512 513 inline Vector3 scale(Vector3::Arg v, float s) 514 { 515 return Vector3(v.x * s, v.y * s, v.z * s); 516 } 517 518 inline Vector3 scale(Vector3::Arg v, Vector3::Arg s) 519 { 520 return Vector3(v.x * s.x, v.y * s.y, v.z * s.z); 521 } 522 523 inline Vector3 operator*(Vector3::Arg v, float s) 524 { 525 return scale(v, s); 526 } 527 528 inline Vector3 operator*(float s, Vector3::Arg v) 529 { 530 return scale(v, s); 531 } 532 533 inline Vector3 operator*(Vector3::Arg v, Vector3::Arg s) 534 { 535 return scale(v, s); 536 } 537 538 inline Vector3 operator/(Vector3::Arg v, float s) 539 { 540 return scale(v, 1.0f/s); 541 } 542 543 /*inline Vector3 add_scaled(Vector3::Arg a, Vector3::Arg b, float s) 544 { 545 return Vector3(a.x + b.x * s, a.y + b.y * s, a.z + b.z * s); 546 }*/ 547 548 inline Vector3 lerp(Vector3::Arg v1, Vector3::Arg v2, float t) 549 { 550 const float s = 1.0f - t; 551 return Vector3(v1.x * s + t * v2.x, v1.y * s + t * v2.y, v1.z * s + t * v2.z); 552 } 553 554 inline float dot(Vector3::Arg a, Vector3::Arg b) 555 { 556 return a.x * b.x + a.y * b.y + a.z * b.z; 557 } 558 559 inline float lengthSquared(Vector3::Arg v) 560 { 561 return v.x * v.x + v.y * v.y + v.z * v.z; 562 } 563 564 inline float length(Vector3::Arg v) 565 { 566 return sqrtf(lengthSquared(v)); 567 } 568 569 inline float distance(Vector3::Arg a, Vector3::Arg b) 570 { 571 return length(a - b); 572 } 573 574 inline float distanceSquared(Vector3::Arg a, Vector3::Arg b) 575 { 576 return lengthSquared(a - b); 577 } 578 579 inline float inverseLength(Vector3::Arg v) 580 { 581 return 1.0f / sqrtf(lengthSquared(v)); 582 } 583 584 inline bool isNormalized(Vector3::Arg v, float epsilon = NV_NORMAL_EPSILON) 585 { 586 return equal(length(v), 1, epsilon); 587 } 588 589 inline Vector3 normalize(Vector3::Arg v, float epsilon = NV_EPSILON) 590 { 591 float l = length(v); 592 NV_UNUSED(epsilon); 593 nvDebugCheck(!isZero(l, epsilon)); 594 Vector3 n = scale(v, 1.0f / l); 595 nvDebugCheck(isNormalized(n)); 596 return n; 597 } 598 599 inline Vector3 normalizeSafe(Vector3::Arg v, Vector3::Arg fallback, float epsilon = NV_EPSILON) 600 { 601 float l = length(v); 602 if (isZero(l, epsilon)) { 603 return fallback; 604 } 605 return scale(v, 1.0f / l); 606 } 607 608 // Safe, branchless normalization from Andy Firth. All error checking ommitted. 609 // http://altdevblogaday.com/2011/08/21/practical-flt-point-tricks/ 610 inline Vector3 normalizeFast(Vector3::Arg v) 611 { 612 const float very_small_float = 1.0e-037f; 613 float l = very_small_float + length(v); 614 return scale(v, 1.0f / l); 615 } 616 617 inline bool equal(Vector3::Arg v1, Vector3::Arg v2, float epsilon = NV_EPSILON) 618 { 619 return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon) && equal(v1.z, v2.z, epsilon); 620 } 621 622 inline Vector3 min(Vector3::Arg a, Vector3::Arg b) 623 { 624 return Vector3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z)); 625 } 626 627 inline Vector3 max(Vector3::Arg a, Vector3::Arg b) 628 { 629 return Vector3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z)); 630 } 631 632 inline Vector3 clamp(Vector3::Arg v, float min, float max) 633 { 634 return Vector3(clamp(v.x, min, max), clamp(v.y, min, max), clamp(v.z, min, max)); 635 } 636 637 inline Vector3 saturate(Vector3::Arg v) 638 { 639 return Vector3(saturate(v.x), saturate(v.y), saturate(v.z)); 640 } 641 642 inline Vector3 floor(Vector3::Arg v) 643 { 644 return Vector3(floorf(v.x), floorf(v.y), floorf(v.z)); 645 } 646 647 inline Vector3 ceil(Vector3::Arg v) 648 { 649 return Vector3(ceilf(v.x), ceilf(v.y), ceilf(v.z)); 650 } 651 652 inline bool isFinite(Vector3::Arg v) 653 { 654 return isFinite(v.x) && isFinite(v.y) && isFinite(v.z); 655 } 656 657 inline Vector3 validate(Vector3::Arg v, Vector3::Arg fallback = Vector3(0.0f)) 658 { 659 if (!isFinite(v)) return fallback; 660 Vector3 vf = v; 661 nv::floatCleanup(vf.component, 3); 662 return vf; 663 } 664 665 inline Vector3 reflect(Vector3::Arg v, Vector3::Arg n) 666 { 667 return v - (2 * dot(v, n)) * n; 668 } 669 670 template <> 671 inline uint hash(const Vector3 & v, uint h) 672 { 673 return sdbmFloatHash(v.component, 3, h); 674 } 675 676 677 // Vector4 678 679 inline Vector4 add(Vector4::Arg a, Vector4::Arg b) 680 { 681 return Vector4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); 682 } 683 inline Vector4 operator+(Vector4::Arg a, Vector4::Arg b) 684 { 685 return add(a, b); 686 } 687 688 inline Vector4 sub(Vector4::Arg a, Vector4::Arg b) 689 { 690 return Vector4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); 691 } 692 inline Vector4 operator-(Vector4::Arg a, Vector4::Arg b) 693 { 694 return sub(a, b); 695 } 696 697 inline Vector4 scale(Vector4::Arg v, float s) 698 { 699 return Vector4(v.x * s, v.y * s, v.z * s, v.w * s); 700 } 701 702 inline Vector4 scale(Vector4::Arg v, Vector4::Arg s) 703 { 704 return Vector4(v.x * s.x, v.y * s.y, v.z * s.z, v.w * s.w); 705 } 706 707 inline Vector4 operator*(Vector4::Arg v, float s) 708 { 709 return scale(v, s); 710 } 711 712 inline Vector4 operator*(float s, Vector4::Arg v) 713 { 714 return scale(v, s); 715 } 716 717 inline Vector4 operator*(Vector4::Arg v, Vector4::Arg s) 718 { 719 return scale(v, s); 720 } 721 722 inline Vector4 operator/(Vector4::Arg v, float s) 723 { 724 return scale(v, 1.0f/s); 725 } 726 727 /*inline Vector4 add_scaled(Vector4::Arg a, Vector4::Arg b, float s) 728 { 729 return Vector4(a.x + b.x * s, a.y + b.y * s, a.z + b.z * s, a.w + b.w * s); 730 }*/ 731 732 inline Vector4 lerp(Vector4::Arg v1, Vector4::Arg v2, float t) 733 { 734 const float s = 1.0f - t; 735 return Vector4(v1.x * s + t * v2.x, v1.y * s + t * v2.y, v1.z * s + t * v2.z, v1.w * s + t * v2.w); 736 } 737 738 inline float dot(Vector4::Arg a, Vector4::Arg b) 739 { 740 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; 741 } 742 743 inline float lengthSquared(Vector4::Arg v) 744 { 745 return v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w; 746 } 747 748 inline float length(Vector4::Arg v) 749 { 750 return sqrtf(lengthSquared(v)); 751 } 752 753 inline float inverseLength(Vector4::Arg v) 754 { 755 return 1.0f / sqrtf(lengthSquared(v)); 756 } 757 758 inline bool isNormalized(Vector4::Arg v, float epsilon = NV_NORMAL_EPSILON) 759 { 760 return equal(length(v), 1, epsilon); 761 } 762 763 inline Vector4 normalize(Vector4::Arg v, float epsilon = NV_EPSILON) 764 { 765 float l = length(v); 766 NV_UNUSED(epsilon); 767 nvDebugCheck(!isZero(l, epsilon)); 768 Vector4 n = scale(v, 1.0f / l); 769 nvDebugCheck(isNormalized(n)); 770 return n; 771 } 772 773 inline Vector4 normalizeSafe(Vector4::Arg v, Vector4::Arg fallback, float epsilon = NV_EPSILON) 774 { 775 float l = length(v); 776 if (isZero(l, epsilon)) { 777 return fallback; 778 } 779 return scale(v, 1.0f / l); 780 } 781 782 // Safe, branchless normalization from Andy Firth. All error checking ommitted. 783 // http://altdevblogaday.com/2011/08/21/practical-flt-point-tricks/ 784 inline Vector4 normalizeFast(Vector4::Arg v) 785 { 786 const float very_small_float = 1.0e-037f; 787 float l = very_small_float + length(v); 788 return scale(v, 1.0f / l); 789 } 790 791 inline bool equal(Vector4::Arg v1, Vector4::Arg v2, float epsilon = NV_EPSILON) 792 { 793 return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon) && equal(v1.z, v2.z, epsilon) && equal(v1.w, v2.w, epsilon); 794 } 795 796 inline Vector4 min(Vector4::Arg a, Vector4::Arg b) 797 { 798 return Vector4(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w)); 799 } 800 801 inline Vector4 max(Vector4::Arg a, Vector4::Arg b) 802 { 803 return Vector4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w)); 804 } 805 806 inline Vector4 clamp(Vector4::Arg v, float min, float max) 807 { 808 return Vector4(clamp(v.x, min, max), clamp(v.y, min, max), clamp(v.z, min, max), clamp(v.w, min, max)); 809 } 810 811 inline Vector4 saturate(Vector4::Arg v) 812 { 813 return Vector4(saturate(v.x), saturate(v.y), saturate(v.z), saturate(v.w)); 814 } 815 816 inline bool isFinite(Vector4::Arg v) 817 { 818 return isFinite(v.x) && isFinite(v.y) && isFinite(v.z) && isFinite(v.w); 819 } 820 821 inline Vector4 validate(Vector4::Arg v, Vector4::Arg fallback = Vector4(0.0f)) 822 { 823 if (!isFinite(v)) return fallback; 824 Vector4 vf = v; 825 nv::floatCleanup(vf.component, 4); 826 return vf; 827 } 828 829 template <> 830 inline uint hash(const Vector4 & v, uint h) 831 { 832 return sdbmFloatHash(v.component, 4, h); 833 } 834 835 836#if NV_OS_IOS // LLVM is not happy with implicit conversion of immediate constants to float 837 838 //int: 839 840 inline Vector2 scale(Vector2::Arg v, int s) 841 { 842 return Vector2(v.x * s, v.y * s); 843 } 844 845 inline Vector2 operator*(Vector2::Arg v, int s) 846 { 847 return scale(v, s); 848 } 849 850 inline Vector2 operator*(int s, Vector2::Arg v) 851 { 852 return scale(v, s); 853 } 854 855 inline Vector2 operator/(Vector2::Arg v, int s) 856 { 857 return scale(v, 1.0f/s); 858 } 859 860 inline Vector3 scale(Vector3::Arg v, int s) 861 { 862 return Vector3(v.x * s, v.y * s, v.z * s); 863 } 864 865 inline Vector3 operator*(Vector3::Arg v, int s) 866 { 867 return scale(v, s); 868 } 869 870 inline Vector3 operator*(int s, Vector3::Arg v) 871 { 872 return scale(v, s); 873 } 874 875 inline Vector3 operator/(Vector3::Arg v, int s) 876 { 877 return scale(v, 1.0f/s); 878 } 879 880 inline Vector4 scale(Vector4::Arg v, int s) 881 { 882 return Vector4(v.x * s, v.y * s, v.z * s, v.w * s); 883 } 884 885 inline Vector4 operator*(Vector4::Arg v, int s) 886 { 887 return scale(v, s); 888 } 889 890 inline Vector4 operator*(int s, Vector4::Arg v) 891 { 892 return scale(v, s); 893 } 894 895 inline Vector4 operator/(Vector4::Arg v, int s) 896 { 897 return scale(v, 1.0f/s); 898 } 899 900 //double: 901 902 inline Vector3 operator*(Vector3::Arg v, double s) 903 { 904 return scale(v, (float)s); 905 } 906 907 inline Vector3 operator*(double s, Vector3::Arg v) 908 { 909 return scale(v, (float)s); 910 } 911 912 inline Vector3 operator/(Vector3::Arg v, double s) 913 { 914 return scale(v, 1.f/((float)s)); 915 } 916 917#endif //NV_OS_IOS 918 919} // nv namespace 920 921#endif // NV_MATH_VECTOR_INL 922