1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #pragma once19 20 #include "../MathBuildConfig.h"21 22 #ifdef MATH_ENABLE_STL_SUPPORT23 #include <string>24 #include <vector>25 #endif26 #include "../MathGeoLibFwd.h"27 #include "[float3.h]"28 #include "[SSEMath.h]"29 #include "[assume.h]"30 31 #ifdef MATH_QT_INTEROP32 #include <QVector4D>33 #endif34 #ifdef MATH_OGRE_INTEROP35 #include <OgreVector4.h>36 #endif37 #ifdef MATH_URHO3D_INTEROP38 #include <Urho3D/Math/Vector4.h>39 #endif40 41 [MATH_BEGIN_NAMESPACE]42 43 44 45 46 47 class [ALIGN16] [float4]48 {49 public:50 enum51 {52 53 Size = 454 };55 56 #if defined(MATH_SIMD)57 [NAMELESS_UNION_BEGIN] 58 59 union60 {61 struct62 {63 #endif64 65 66 float [x];67 68 69 float [y];70 71 72 float [z];73 74 75 float [w];76 #if defined(MATH_SIMD)77 };78 simd4f v;79 };80 [NAMELESS_UNION_END]81 #endif82 83 84 85 86 87 [float4]() {}88 89 #ifdef MATH_EXPLICIT_COPYCTORS90 91 92 93 [float4](const [float4] &rhs) { x = rhs.[x]; y = rhs.[y]; z = rhs.[z]; w = rhs.[w]; }94 #endif95 96 97 98 99 100 [float4](float x, float y, float z, float w);101 102 103 104 [float4](const [float3] &xyz, float w);105 106 [float4](float x, float y, const [float2] &zw);107 [float4](float x, const [float2] &yz, float w);108 [float4](float x, const [float3] &yzw);109 [float4](const [float2] &xy, const [float2] &zw);110 111 112 113 [float4](const [float2] &xy, float z, float w);114 115 116 117 explicit [float4](const float *data);118 119 120 121 122 123 124 125 126 127 128 129 130 [FORCE_INLINE] float *[ptr]() { return &x; }131 [FORCE_INLINE] const float *[ptr]() const { return &x; }132 133 134 135 136 137 float &operator [](int index) { return At(index); }138 [CONST_WIN32] float operator [](int index) const { return At(index); }139 140 141 142 143 144 float &At(int index);145 [CONST_WIN32] float At(int index) const;146 147 148 149 150 [float4] [operator +](const [float4] &v) const;151 152 153 154 155 [float4] [operator -]() const;156 157 158 159 160 [float4] [operator -](const [float4] &v) const;161 162 163 164 165 [float4] [operator *](float scalar) const;166 167 168 169 170 [float4] operator /(float scalar) const;171 172 173 [float4] [operator +]() const { return *this; }174 175 176 177 [float4] &[operator +=](const [float4] &v);178 179 180 181 [float4] &[operator -=](const [float4] &v);182 183 184 185 186 [float4] &[operator *=](float scalar);187 188 189 190 [float4] &operator /=(float scalar);191 192 #ifdef MATH_ENABLE_UNCOMMON_OPERATIONS193 194 195 196 197 198 199 [float4] [operator *](const [float4] &vector) const { return this->[Mul](vector); }200 [float4] operator /(const [float4] &vector) const { return this->[Div](vector); }201 [float4] &[operator *=](const [float4] &vector) { *this = this->[Mul](vector); return *this; }202 [float4] &operator /=(const [float4] &vector) { *this = this->[Div](vector); return *this; }203 #endif204 205 206 207 [float4] [Add](const [float4] &v) const { return *this + v; }208 209 210 211 212 213 [float4] [Add](float s) const;214 215 216 217 [float4] [Sub](const [float4] &v) const { return *this - v; }218 219 220 221 222 223 [float4] [Sub](float s) const;224 225 226 227 228 229 [float4] SubLeft(float s) const;230 231 232 233 234 235 [float4] [Mul](const [float4] &v) const;236 237 238 239 240 [float4] [Mul](float s) const { return *this * s; }241 242 243 244 245 246 [float4] [Div](const [float4] &v) const;247 248 249 250 [float4] [Div](float s) const { return *this / s; }251 252 253 254 255 256 [float4] DivLeft(float s) const;257 258 259 [float2] xy() const;260 261 262 [float3] xyz() const;263 264 265 266 267 [float3] &[Float3Part]() { return *reinterpret_cast<[float3]*>(this); }268 const [float3] &[Float3Part]() const { return *reinterpret_cast<const [float3]*>(this); }269 270 271 272 273 274 275 276 277 [float4] Swizzled(int i, int j, int k, int l) const;278 [float3] Swizzled(int i, int j, int k) const;279 [float2] Swizzled(int i, int j) const;280 281 [float4] xxxx() const;282 [float4] xxxw() const;283 [float4] yyyy() const;284 [float4] yyyw() const;285 [float4] zzzz() const;286 [float4] zzzw() const;287 [float4] wwww() const;288 289 290 291 static [float4] FromScalar(float scalar);292 293 294 static [float4] FromScalar(float scalar, float w);295 296 297 298 void SetFromScalar(float scalar);299 300 301 void SetFromScalar(float scalar, float w);302 303 304 305 306 307 308 309 310 311 312 313 void SetFromSphericalCoordinates(float azimuth, float inclination, float radius);314 void [SetFromSphericalCoordinates](const [float3] &spherical) { [SetFromSphericalCoordinates](spherical.[x], spherical.[y], spherical.[z]); }315 static [MUST_USE_RESULT] [float4] FromSphericalCoordinates(float azimuth, float inclination, float radius);316 static [MUST_USE_RESULT] [float4] [FromSphericalCoordinates](const [float3] &spherical) { return [FromSphericalCoordinates](spherical.[x], spherical.[y], spherical.[z]); }317 318 319 320 321 322 323 324 void SetFromSphericalCoordinates(float azimuth, float inclination);325 static [MUST_USE_RESULT] [float4] FromSphericalCoordinates(float azimuth, float inclination);326 327 328 329 330 331 332 [float3] ToSphericalCoordinates() const;333 334 335 336 337 338 339 340 [float2] ToSphericalCoordinatesNormalized() const;341 342 343 344 void Set(float x, float y, float z, float w);345 346 347 348 349 350 351 352 353 354 float LengthSq3() const;355 356 357 358 359 360 float [Length3]() const;361 362 363 364 365 366 367 368 369 float LengthSq4() const;370 inline float [LengthSq]() const { return LengthSq4(); }371 372 373 374 375 float [Length4]() const;376 inline float [Length]() const { return [Length4](); }377 378 379 380 381 382 383 384 385 float Normalize3();386 387 388 389 390 391 392 393 394 float Normalize4();395 inline float [Normalize]() { return Normalize4(); }396 397 398 399 400 401 402 [float4] Normalized3() const;403 404 405 406 407 408 [float4] Normalized4() const;409 inline [float4] [Normalized]() const { return Normalized4(); }410 411 412 413 414 415 416 417 void NormalizeW();418 419 420 421 422 bool IsWZeroOrOne(float [epsilon] = 1[e]-3f) const;423 424 425 426 bool IsZero3(float epsilonSq = 1[e]-6f) const;427 428 429 430 bool IsZero4(float epsilonSq = 1[e]-6f) const;431 bool [IsZero](float epsilonSq = 1[e]-6f) const { return IsZero4(epsilonSq); }432 433 434 435 bool IsNormalized3(float epsilonSq = 1[e]-5f) const;436 437 438 439 440 bool IsNormalized4(float epsilonSq = 1[e]-5f) const;441 bool [IsNormalized](float epsilonSq = 1[e]-5f) const { return IsNormalized4(epsilonSq); }442 443 444 445 446 447 void Scale3(float scalar);448 449 450 451 452 453 float ScaleToLength3(float newLength);454 455 float ScaleToLength(float newLength);456 457 458 459 460 [float4] ScaledToLength3(float newLength) const;461 [float4] ScaledToLength(float newLength) const;462 463 464 bool [IsFinite]() const;465 466 467 bool IsPerpendicular3(const [float4] &other, float epsilonSq = 1[e]-8f) const;468 469 bool IsPerpendicular(const [float4] &other, float epsilonSq = 1[e]-8f) const;470 471 472 473 474 475 476 477 static void Orthogonalize(const [float4] &a, [float4] &b);478 static void Orthogonalize(const [float4] &a, [float4] &b, [float4] &c);479 480 481 482 static [MUST_USE_RESULT] bool AreOrthogonal(const [float4] &a, const [float4] &b, float [epsilon] = 1[e]-3f);483 static [MUST_USE_RESULT] bool AreOrthogonal(const [float4] &a, const [float4] &b, const [float4] &c, float [epsilon] = 1[e]-3f);484 485 486 487 static [MUST_USE_RESULT] bool AreCollinear(const [float4] &p1, const [float4] &p2, const [float4] &p3, float [epsilon] = 1[e]-7f);488 489 490 491 492 493 494 495 static void Orthonormalize([float4] &a, [float4] &b);496 static void Orthonormalize([float4] &a, [float4] &b, [float4] &c);497 498 499 500 501 static [MUST_USE_RESULT] bool AreOrthonormal(const [float4] &a, const [float4] &b, float [epsilon] = 1[e]-3f);502 static [MUST_USE_RESULT] bool AreOrthonormal(const [float4] &a, const [float4] &b, const [float4] &c, float [epsilon] = 1[e]-3f);503 504 #ifdef MATH_ENABLE_STL_SUPPORT505 506 std::string ToString() const;507 508 509 std::string SerializeToString() const;510 511 512 std::string SerializeToCodeString() const;513 #endif514 515 516 static [float4] FromString(const char *str, const char **outEndStr = 0);517 #ifdef MATH_ENABLE_STL_SUPPORT518 static [float4] [FromString](const std::string &str) { return [FromString](str.c_str()); }519 #endif520 521 522 float SumOfElements() const;523 524 525 float ProductOfElements() const;526 527 528 float AverageOfElements() const;529 530 531 532 float MinElement() const;533 534 535 536 int MinElementIndex() const;537 538 539 540 float MaxElement() const;541 542 543 544 int MaxElementIndex() const;545 546 547 548 549 [float4] [Abs]() const;550 551 552 553 554 [float4] Neg3() const;555 556 557 558 559 [float4] Neg4() const;560 561 562 563 564 565 [float4] Recip3() const;566 567 568 569 570 571 [float4] Recip4() const;572 573 574 575 576 577 [float4] RecipFast4() const;578 579 580 581 [float4] [Min](float ceil) const;582 583 584 585 586 [float4] [Min](const [float4] &ceil) const;587 588 589 590 [float4] [Max](float floor) const;591 592 593 594 595 [float4] [Max](const [float4] &floor) const;596 597 598 [float4] [Clamp](float floor, float ceil) const;599 600 601 602 [float4] [Clamp](const [float4] &floor, const [float4] &ceil) const;603 604 605 606 [float4] [Clamp01]() const;607 608 609 610 611 612 613 614 [float4] [Lerp](const [float4] &b, float t) const;615 static [float4] [Lerp](const [float4] &a, const [float4] &b, float t);616 617 618 619 620 621 float Distance3Sq(const [float4] &rhs) const;622 623 624 625 626 627 float [Distance3](const [float4] &rhs) const;628 629 630 631 632 633 float Distance4Sq(const [float4] &rhs) const;634 inline float [DistanceSq](const [float4] &rhs) const { return Distance4Sq(rhs); }635 636 637 638 639 640 float [Distance4](const [float4] &rhs) const;641 inline float [Distance](const [float4] &rhs) const { return [Distance4](rhs); }642 643 644 645 646 float [Dot3](const [float3] &rhs) const;647 float [Dot3](const [float4] &rhs) const;648 649 650 651 float [Dot4](const [float4] &rhs) const;652 653 inline float [Dot](const [float4] &rhs) const { return [Dot4](rhs); }654 655 656 657 [float4] [Cross3](const [float3] &rhs) const;658 [float4] [Cross3](const [float4] &rhs) const;659 660 [float4] [Cross](const [float4] &rhs) const { return [Cross3](rhs); }661 662 663 [float4x4] OuterProduct(const [float4] &rhs) const;664 665 666 [float4] Perpendicular3(const [float3] &hint = [float3](0,1,0), const [float3] &hint2 = [float3](0,0,1)) const;667 [float4] Perpendicular(const [float4] &hint = [float4](0,1,0,0), const [float4] &hint2 = [float4](0,0,1,0)) const;668 669 670 671 672 [float4] AnotherPerpendicular3(const [float3] &hint = [float3](0,1,0), const [float3] &hint2 = [float3](0,0,1)) const;673 [float4] AnotherPerpendicular(const [float4] &hint = [float4](0,1,0,0), const [float4] &hint2 = [float4](0,0,1,0)) const;674 675 676 677 678 679 680 681 void PerpendicularBasis([float4] &outB, [float4] &outC) const;682 683 684 685 [float4] RandomPerpendicular([LCG] &rng) const;686 687 688 689 690 [float4] Reflect3(const [float3] &normal) const;691 [float4] Reflect(const [float4] &normal) const;692 693 [float4] Refract(const [float4] &normal, float negativeSideRefractionIndex, float positiveSideRefractionIndex) const;694 695 696 697 698 699 700 float AngleBetween3(const [float4] &other) const;701 702 703 704 705 706 float AngleBetweenNorm3(const [float4] &normalizedVector) const;707 708 709 710 711 float AngleBetween4(const [float4] &other) const;712 713 714 715 716 float AngleBetweenNorm4(const [float4] &normalizedVector) const;717 718 719 720 721 722 [float4] ProjectTo3(const [float3] &target) const;723 724 [float4] ProjectTo(const [float4] &target) const;725 726 727 728 729 730 731 [float4] ProjectToNorm3(const [float3] &target) const;732 733 [float4] ProjectToNorm(const [float4] &target) const;734 735 736 bool Equals(const [float4] &other, float [epsilon] = 1[e]-3f) const;737 bool Equals(float x, float y, float z, float w, float [epsilon] = 1[e]-3f) const;738 739 740 741 bool BitEquals(const [float4] &other) const;742 743 744 745 746 static [MUST_USE_RESULT] [float4] RandomDir([LCG] &lcg, float length = 1.f);747 748 749 750 static [MUST_USE_RESULT] [float4] RandomSphere([LCG] &lcg, const [float4] ¢er, float radius);751 752 753 754 static [MUST_USE_RESULT] [float4] RandomBox([LCG] &lcg, float xmin, float xmax, float ymin, float ymax, float zmin, float zmax);755 static [MUST_USE_RESULT] [float4] RandomBox([LCG] &lcg, const [float4] &minValues, const [float4] &maxValues);756 757 758 static [MUST_USE_RESULT] [float4] RandomBox([LCG] &lcg, float minElem, float maxElem);759 760 761 762 763 764 static [float4] RandomGeneral([LCG] &lcg, float minElem, float maxElem);765 766 767 768 769 static const [float4] [zero];770 771 772 773 774 static const [float4] [one];775 776 777 778 779 static const [float4] [unitX];780 781 782 783 784 static const [float4] [unitY];785 786 787 788 789 static const [float4] [unitZ];790 791 792 793 794 static const [float4] [unitW];795 796 797 798 799 800 801 802 static const [float4] [nan];803 804 805 806 807 static const [float4] [inf];808 809 #ifdef MATH_OGRE_INTEROP810 [float4](const Ogre::Vector4 &other): x(other.x), y(other.y), z(other.z), w(other.w) {}811 [float4] &operator =(const Ogre::Vector4 &other) { x = other.[x]; y = other.y; z = other.z; w = other.w; return *this; }812 operator Ogre::Vector4() const { return Ogre::Vector4(x, y, z, w); }813 #endif814 #ifdef MATH_QT_INTEROP815 [float4](const QVector4D &other):x(other.x()), y(other.y()), z(other.z()), w(other.w()) {}816 operator QVector4D() const { return QVector4D(x, y, z, w); }817 operator QString() const { return "float4(" + QString::number(x) + "," + QString::number(y) + "," + QString::number(z) + "," + QString::number(w) + ")"; }818 QString toString() const { return (QString)*this; }819 QVector4D ToQVector4D() const { return QVector4D(x, y, z, w); }820 static [float4] FromQVector4D(const QVector4D &v) { return ([float4])v; }821 static [float4] FromString(const QString &str) { return FromString(str.toStdString()); }822 #endif823 #ifdef MATH_BULLET_INTEROP824 825 [float4](const btVector3 &other):x(other.x()), y(other.y()), z(other.z()), w(other.w()) {}826 operator btVector3() const { btVector3 v(x, y, z); v.setW(w); return v; }827 #endif828 #ifdef MATH_URHO3D_INTEROP829 [float4](const Urho3D::Vector4 &other) : x(other.x_), y(other.y_), z(other.z_), w(other.w_) {}830 operator Urho3D::Vector4() const { return Urho3D::Vector4(x, y, z, w); }831 #endif832 833 #ifdef MATH_SIMD834 [float4](simd4f vec):v(vec) {}835 836 837 simd4f Swizzled_SSE(int i, int j, int k, int l) const;838 simd4f LengthSq3_SSE() const;839 simd4f Length3_SSE() const;840 simd4f LengthSq4_SSE() const;841 simd4f Length4_SSE() const;842 simd4f Normalize4_SSE();843 void Normalize3_Fast_SSE();844 void Normalize4_Fast_SSE();845 void NormalizeW_SSE();846 simd4f SumOfElements_SSE() const;847 848 inline [float4] &operator =(simd4f vec) { v = vec; return *this; }849 850 inline operator simd4f() const { return v; }851 #endif852 };853 854 struct [float4_storage]855 {856 float [x],[y],[z],[w];857 [float4_storage](){}858 [float4_storage](const [float4] &rhs)859 {860 *reinterpret_cast<[float4]*>(this) = rhs;861 }862 operator [float4]() const { return *reinterpret_cast<const [float4]*>(this); }863 };864 865 #ifdef MATH_ENABLE_STL_SUPPORT866 867 std::ostream &[operator <<](std::ostream &out, const [float4] &rhs);868 #endif869 870 871 872 [float4] [operator *](float scalar, const [float4] &rhs);873 874 #ifdef MATH_ENABLE_UNCOMMON_OPERATIONS875 inline [float4] operator /(float scalar, const [float4] &rhs) { return [float4::FromScalar](scalar) / rhs; }876 #endif877 878 inline float [Dot3](const [float4] &a, const [float4] &b) { return a.[Dot3](b); }879 inline float [Dot4](const [float4] &a, const [float4] &b) { return a.[Dot4](b); }880 inline float [Dot](const [float4] &a, const [float4] &b) { return a.[Dot](b); }881 inline [float4] [Cross3](const [float4] &a, const [float4] &b) { return a.[Cross3](b); }882 inline [float4] [Cross](const [float4] &a, const [float4] &b) { return a.[Cross](b); }883 inline [float4] [Abs](const [float4] &a) { return a.[Abs](); }884 inline float [Length3](const [float4] &a) { return a.[Length3](); }885 inline float [Length4](const [float4] &a) { return a.[Length4](); }886 inline float [Distance3](const [float4] &a, const [float4] &b) { return a.[Distance3](b); }887 inline float [Distance4](const [float4] &a, const [float4] &b) { return a.[Distance4](b); }888 inline [float4] [Min](const [float4] &a, const [float4] &b) { return a.[Min](b); }889 inline [float4] [Max](const [float4] &a, const [float4] &b) { return a.[Max](b); }890 inline [float4] [Clamp](const [float4] &a, float floor, float ceil) { return a.[Clamp](floor, ceil); }891 inline [float4] [Clamp](const [float4] &a, const [float4] &floor, const [float4] &ceil) { return a.[Clamp](floor, ceil); }892 inline [float4] [Clamp01](const [float4] &a) { return a.[Clamp01](); }893 inline [float4] [Lerp](const [float4] &a, const [float4] &b, float t) { return a.[Lerp](b, t); }894 895 #ifdef MATH_QT_INTEROP896 Q_DECLARE_METATYPE([float4])897 Q_DECLARE_METATYPE([float4]*)898 #endif899 900 [MATH_END_NAMESPACE] Go back to previous page