├── LICENSE ├── README.md ├── all.hpp ├── bool2.hpp ├── bool3.hpp ├── bool4.hpp ├── common.hpp ├── float2.hpp ├── float2x2.hpp ├── float3.hpp ├── float3x3.hpp ├── float4.hpp ├── float4x4.hpp ├── funcs_sse.hpp ├── int2.hpp ├── int3.hpp ├── int4.hpp ├── quat.hpp ├── trig.cpp └── trig.hpp /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hlml 2 | vectorized high-level math library 3 | 4 | i started this piece of software after reading http://www.codersnotes.com/notes/maths-lib-2016/ and you should too. 5 | 6 | it's x64 SSE4.1(ish) compatible (which is suppported by every Intel since 2008 and every AMD since 2012) but no NEON or AltiVec at the moment. 7 | 8 | list of resources that might come handy in case you'd like to add or remove something: 9 | 10 | http://www.codersnotes.com/notes/maths-lib-2016/ 11 | 12 | http://www.reedbeta.com/blog/on-vector-math-libraries/ 13 | 14 | https://github.com/g-truc/glm 15 | 16 | https://github.com/scoopr/vectorial 17 | 18 | https://github.com/erwincoumans/sce_vectormath 19 | 20 | http://gruntthepeon.free.fr/ssemath/ 21 | 22 | https://github.com/to-miz/sse_mathfun_extension/ 23 | 24 | https://db.in.tum.de/~finis/x86%20intrinsics%20cheat%20sheet%20v1.0.pdf 25 | 26 | https://bitbucket.org/eschnett/vecmathlib/wiki/Home 27 | 28 | http://www.gamasutra.com/view/feature/132636/designing_fast_crossplatform_simd_.php 29 | 30 | https://www.gamedev.net/resources/_/technical/general-programming/practical-cross-platform-simd-math-r3068 31 | 32 | http://stackoverflow.com/questions/15723995/simd-math-libraries-for-sse-and-avx 33 | 34 | http://codesuppository.blogspot.com/2015/02/sse2neonh-porting-guide-and-header-file.html 35 | -------------------------------------------------------------------------------- /all.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "bool2.hpp" 4 | #include "bool3.hpp" 5 | #include "bool4.hpp" 6 | #include "int2.hpp" 7 | #include "int3.hpp" 8 | #include "int4.hpp" 9 | #include "float2.hpp" 10 | #include "float3.hpp" 11 | #include "float4.hpp" 12 | #include "float2x2.hpp" 13 | #include "float3x3.hpp" 14 | #include "float4x4.hpp" 15 | #include "quat.hpp" 16 | #include "trig.hpp" -------------------------------------------------------------------------------- /bool2.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.hpp" 4 | 5 | namespace hlml { 6 | struct bool2 { 7 | static constexpr u32 flagsall = 0x88; 8 | 9 | VI128 m = { 0 }; 10 | 11 | HLML_INLINEF bool2() {} 12 | HLML_INLINEF explicit bool2(VI128 v) : m(v) {} 13 | HLML_INLINEF explicit bool2(b8 x, b8 y) : bool2(funcs::Ashiftl(funcs::setXYZW(x, y, consts::snZero, consts::snZero), 31u)) {} 14 | HLML_INLINEF explicit bool2(const b8* p) : bool2(p[0], p[1]) {} 15 | 16 | HLML_INLINEF void store(b8 *p) const { p[0] = x(), p[1] = y(); } 17 | 18 | HLML_INLINEF void setX(b8 x) { m = inserti(m, x << 31u, 0); } 19 | HLML_INLINEF void setY(b8 y) { m = inserti(m, y << 31u, 1); } 20 | 21 | HLML_INLINEF b8 x() const { return 0 != extracti(m, 0); } 22 | HLML_INLINEF b8 y() const { return 0 != extracti(m, 1); } 23 | 24 | HLML_INLINEF bool2 xx() const { return shuffleb2(*this, 0, 0); } 25 | HLML_INLINEF bool2 xy() const { return *this; } 26 | HLML_INLINEF bool2 yx() const { return shuffleb2(*this, 1, 0); } 27 | HLML_INLINEF bool2 yy() const { return shuffleb2(*this, 1, 1); } 28 | }; 29 | HLML_INLINEF bool2 operator! (bool2 a) { a.m = funcs::notAandB(a.m, consts::vsignbits_xy); return a; } 30 | HLML_INLINEF bool2 operator~ (bool2 a) { return !a; } 31 | HLML_INLINEF bool2 operator& (bool2 a, bool2 b) { a.m = funcs::AandB(a.m, b.m); return a; } 32 | HLML_INLINEF bool2 operator| (bool2 a, bool2 b) { a.m = funcs::AorB(a.m, b.m); return a; } 33 | HLML_INLINEF bool2 operator^ (bool2 a, bool2 b) { a.m = funcs::AxorB(a.m, b.m); return a; } 34 | HLML_INLINEF bool2& operator&= (bool2& a, bool2 b) { a = a & b; return a; } 35 | HLML_INLINEF bool2& operator|= (bool2& a, bool2 b) { a = a | b; return a; } 36 | HLML_INLINEF bool2& operator^= (bool2& a, bool2 b) { a = a ^ b; return a; } 37 | HLML_INLINEF u32 mask (bool2 v) { return bool2::flagsall & funcs::movemask(v.m); } 38 | HLML_INLINEF b8 all (bool2 v) { return bool2::flagsall == mask(v); } 39 | HLML_INLINEF b8 any (bool2 v) { return mask(v); } 40 | HLML_INLINEF b8 none (bool2 v) { return !any(v); } 41 | } 42 | -------------------------------------------------------------------------------- /bool3.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "bool2.hpp" 4 | 5 | namespace hlml { 6 | struct bool3 { 7 | static constexpr u32 flagsall = 0x888; 8 | 9 | VI128 m = { 0 }; 10 | 11 | HLML_INLINEF bool3() {} 12 | HLML_INLINEF explicit bool3(VI128 v) : m(v) {} 13 | HLML_INLINEF explicit bool3(b8 x, b8 y, b8 z) : m(funcs::Ashiftl(funcs::setXYZW(x, y, z, consts::snZero), 31u)) {} 14 | HLML_INLINEF explicit bool3(const b8* p) : bool3(p[0], p[1], p[2]) {} 15 | HLML_INLINEF explicit bool3(bool2 v, b8 z) : bool3(v.x(), v.y(), z) {} 16 | 17 | HLML_INLINEF void store(b8 *p) const { p[0] = x(), p[1] = y(), p[2] = z(); } 18 | 19 | HLML_INLINEF void setX(b8 x) { m = inserti(m, x << 31u, 0); } 20 | HLML_INLINEF void setY(b8 y) { m = inserti(m, y << 31u, 1); } 21 | HLML_INLINEF void setZ(b8 y) { m = inserti(m, y << 31u, 2); } 22 | 23 | HLML_INLINEF b8 x() const { return 0 != extracti(m, 0); } 24 | HLML_INLINEF b8 y() const { return 0 != extracti(m, 1); } 25 | HLML_INLINEF b8 z() const { return 0 != extracti(m, 2); } 26 | 27 | HLML_INLINEF bool2 xx() const { return shuffleb2(*this, 0, 0); } 28 | HLML_INLINEF bool2 xy() const { return shuffleb2(*this, 0, 1); } 29 | HLML_INLINEF bool2 xz() const { return shuffleb2(*this, 0, 2); } 30 | HLML_INLINEF bool2 yx() const { return shuffleb2(*this, 1, 0); } 31 | HLML_INLINEF bool2 yy() const { return shuffleb2(*this, 1, 1); } 32 | HLML_INLINEF bool2 yz() const { return shuffleb2(*this, 1, 2); } 33 | 34 | HLML_INLINEF bool3 xxx() const { return shuffleb3(*this, 0, 0, 0); } 35 | HLML_INLINEF bool3 xxy() const { return shuffleb3(*this, 0, 0, 1); } 36 | HLML_INLINEF bool3 xxz() const { return shuffleb3(*this, 0, 0, 2); } 37 | HLML_INLINEF bool3 xyx() const { return shuffleb3(*this, 0, 1, 0); } 38 | HLML_INLINEF bool3 xyy() const { return shuffleb3(*this, 0, 1, 1); } 39 | HLML_INLINEF bool3 xyz() const { return *this; } 40 | HLML_INLINEF bool3 xzx() const { return shuffleb3(*this, 0, 2, 0); } 41 | HLML_INLINEF bool3 xzy() const { return shuffleb3(*this, 0, 2, 1); } 42 | HLML_INLINEF bool3 xzz() const { return shuffleb3(*this, 0, 2, 2); } 43 | 44 | HLML_INLINEF bool3 yxx() const { return shuffleb3(*this, 1, 0, 0); } 45 | HLML_INLINEF bool3 yxy() const { return shuffleb3(*this, 1, 0, 1); } 46 | HLML_INLINEF bool3 yxz() const { return shuffleb3(*this, 1, 0, 2); } 47 | HLML_INLINEF bool3 yyx() const { return shuffleb3(*this, 1, 1, 0); } 48 | HLML_INLINEF bool3 yyy() const { return shuffleb3(*this, 1, 1, 1); } 49 | HLML_INLINEF bool3 yyz() const { return shuffleb3(*this, 1, 1, 2); } 50 | HLML_INLINEF bool3 yzx() const { return shuffleb3(*this, 1, 2, 0); } 51 | HLML_INLINEF bool3 yzy() const { return shuffleb3(*this, 1, 2, 1); } 52 | HLML_INLINEF bool3 yzz() const { return shuffleb3(*this, 1, 2, 2); } 53 | 54 | HLML_INLINEF bool3 zxx() const { return shuffleb3(*this, 2, 0, 0); } 55 | HLML_INLINEF bool3 zxy() const { return shuffleb3(*this, 2, 0, 1); } 56 | HLML_INLINEF bool3 zxz() const { return shuffleb3(*this, 2, 0, 2); } 57 | HLML_INLINEF bool3 zyx() const { return shuffleb3(*this, 2, 1, 0); } 58 | HLML_INLINEF bool3 zyy() const { return shuffleb3(*this, 2, 1, 1); } 59 | HLML_INLINEF bool3 zyz() const { return shuffleb3(*this, 2, 1, 2); } 60 | HLML_INLINEF bool3 zzx() const { return shuffleb3(*this, 2, 2, 0); } 61 | HLML_INLINEF bool3 zzy() const { return shuffleb3(*this, 2, 2, 1); } 62 | HLML_INLINEF bool3 zzz() const { return shuffleb3(*this, 2, 2, 2); } 63 | }; 64 | HLML_INLINEF bool3 operator! (bool3 a) { a.m = funcs::notAandB(a.m, consts::vsignbits_xyz); return a; } 65 | HLML_INLINEF bool3 operator~ (bool3 a) { return !a; } 66 | HLML_INLINEF bool3 operator& (bool3 a, bool3 b) { a.m = funcs::AandB(a.m, b.m); return a; } 67 | HLML_INLINEF bool3 operator| (bool3 a, bool3 b) { a.m = funcs::AorB(a.m, b.m); return a; } 68 | HLML_INLINEF bool3 operator^ (bool3 a, bool3 b) { a.m = funcs::AxorB(a.m, b.m); return a; } 69 | HLML_INLINEF bool3& operator&= (bool3& a, bool3 b) { a = a & b; return a; } 70 | HLML_INLINEF bool3& operator|= (bool3& a, bool3 b) { a = a | b; return a; } 71 | HLML_INLINEF bool3& operator^= (bool3& a, bool3 b) { a = a ^ b; return a; } 72 | HLML_INLINEF u32 mask (bool3 v) { return bool3::flagsall & funcs::movemask(v.m); } 73 | HLML_INLINEF b8 all (bool3 v) { return bool3::flagsall == mask(v); } 74 | HLML_INLINEF b8 any (bool3 v) { return mask(v); } 75 | HLML_INLINEF b8 none (bool3 v) { return !any(v); } 76 | } 77 | -------------------------------------------------------------------------------- /bool4.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "bool3.hpp" 4 | 5 | namespace hlml { 6 | struct bool4 { 7 | static constexpr u32 flagsall = 0x8888; 8 | 9 | VI128 m = { 0 }; 10 | 11 | HLML_INLINEF bool4() {} 12 | HLML_INLINEF explicit bool4(VI128 v) : m(v) {} 13 | HLML_INLINEF explicit bool4(b8 x, b8 y, b8 z, b8 w) : m(funcs::Ashiftl(funcs::setXYZW(x, y, z, w), 31u)) {} 14 | HLML_INLINEF explicit bool4(const b8* p) : bool4(p[0], p[1], p[2], p[3]) {} 15 | HLML_INLINEF explicit bool4(bool3 v, b8 w) : bool4(v.x(), v.y(), v.z(), w) {} 16 | 17 | HLML_INLINEF void store(b8 *p) const { p[0] = x(), p[1] = y(), p[2] = z(), p[3] = w(); } 18 | 19 | HLML_INLINEF void setX(b8 x) { m = inserti(m, x << 31u, 0); } 20 | HLML_INLINEF void setY(b8 y) { m = inserti(m, y << 31u, 1); } 21 | HLML_INLINEF void setZ(b8 y) { m = inserti(m, y << 31u, 2); } 22 | HLML_INLINEF void setW(b8 y) { m = inserti(m, y << 31u, 3); } 23 | 24 | HLML_INLINEF b8 x() const { return 0 != extracti(m, 0); } 25 | HLML_INLINEF b8 y() const { return 0 != extracti(m, 1); } 26 | HLML_INLINEF b8 z() const { return 0 != extracti(m, 2); } 27 | HLML_INLINEF b8 w() const { return 0 != extracti(m, 3); } 28 | 29 | HLML_INLINEF bool2 xx() const { return shuffleb2(*this, 0, 0); } 30 | HLML_INLINEF bool2 xy() const { return shuffleb2(*this, 0, 1); } 31 | HLML_INLINEF bool2 xz() const { return shuffleb2(*this, 0, 2); } 32 | HLML_INLINEF bool2 xw() const { return shuffleb2(*this, 0, 3); } 33 | HLML_INLINEF bool2 yx() const { return shuffleb2(*this, 1, 0); } 34 | HLML_INLINEF bool2 yy() const { return shuffleb2(*this, 1, 1); } 35 | HLML_INLINEF bool2 yz() const { return shuffleb2(*this, 1, 2); } 36 | HLML_INLINEF bool2 yw() const { return shuffleb2(*this, 1, 3); } 37 | HLML_INLINEF bool2 zx() const { return shuffleb2(*this, 2, 0); } 38 | HLML_INLINEF bool2 zy() const { return shuffleb2(*this, 2, 1); } 39 | HLML_INLINEF bool2 zz() const { return shuffleb2(*this, 2, 2); } 40 | HLML_INLINEF bool2 zw() const { return shuffleb2(*this, 2, 3); } 41 | HLML_INLINEF bool2 wx() const { return shuffleb2(*this, 3, 0); } 42 | HLML_INLINEF bool2 wy() const { return shuffleb2(*this, 3, 1); } 43 | HLML_INLINEF bool2 wz() const { return shuffleb2(*this, 3, 2); } 44 | HLML_INLINEF bool2 ww() const { return shuffleb2(*this, 3, 3); } 45 | 46 | HLML_INLINEF bool3 xxx() const { return shuffleb3(*this, 0, 0, 0); } 47 | HLML_INLINEF bool3 xxy() const { return shuffleb3(*this, 0, 0, 1); } 48 | HLML_INLINEF bool3 xxz() const { return shuffleb3(*this, 0, 0, 2); } 49 | HLML_INLINEF bool3 xxw() const { return shuffleb3(*this, 0, 0, 3); } 50 | HLML_INLINEF bool3 xyx() const { return shuffleb3(*this, 0, 1, 0); } 51 | HLML_INLINEF bool3 xyy() const { return shuffleb3(*this, 0, 1, 1); } 52 | HLML_INLINEF bool3 xyz() const { return shuffleb3(*this, 0, 1, 2); } 53 | HLML_INLINEF bool3 xyw() const { return shuffleb3(*this, 0, 1, 3); } 54 | HLML_INLINEF bool3 xzx() const { return shuffleb3(*this, 0, 2, 0); } 55 | HLML_INLINEF bool3 xzy() const { return shuffleb3(*this, 0, 2, 1); } 56 | HLML_INLINEF bool3 xzz() const { return shuffleb3(*this, 0, 2, 2); } 57 | HLML_INLINEF bool3 xzw() const { return shuffleb3(*this, 0, 2, 3); } 58 | HLML_INLINEF bool3 xwx() const { return shuffleb3(*this, 0, 3, 0); } 59 | HLML_INLINEF bool3 xwy() const { return shuffleb3(*this, 0, 3, 1); } 60 | HLML_INLINEF bool3 xwz() const { return shuffleb3(*this, 0, 3, 2); } 61 | HLML_INLINEF bool3 xww() const { return shuffleb3(*this, 0, 3, 3); } 62 | 63 | HLML_INLINEF bool3 yxx() const { return shuffleb3(*this, 1, 0, 0); } 64 | HLML_INLINEF bool3 yxy() const { return shuffleb3(*this, 1, 0, 1); } 65 | HLML_INLINEF bool3 yxz() const { return shuffleb3(*this, 1, 0, 2); } 66 | HLML_INLINEF bool3 yxw() const { return shuffleb3(*this, 1, 0, 3); } 67 | HLML_INLINEF bool3 yyx() const { return shuffleb3(*this, 1, 1, 0); } 68 | HLML_INLINEF bool3 yyy() const { return shuffleb3(*this, 1, 1, 1); } 69 | HLML_INLINEF bool3 yyz() const { return shuffleb3(*this, 1, 1, 2); } 70 | HLML_INLINEF bool3 yyw() const { return shuffleb3(*this, 1, 1, 3); } 71 | HLML_INLINEF bool3 yzx() const { return shuffleb3(*this, 1, 2, 0); } 72 | HLML_INLINEF bool3 yzy() const { return shuffleb3(*this, 1, 2, 1); } 73 | HLML_INLINEF bool3 yzz() const { return shuffleb3(*this, 1, 2, 2); } 74 | HLML_INLINEF bool3 yzw() const { return shuffleb3(*this, 1, 2, 3); } 75 | HLML_INLINEF bool3 ywx() const { return shuffleb3(*this, 1, 3, 0); } 76 | HLML_INLINEF bool3 ywy() const { return shuffleb3(*this, 1, 3, 1); } 77 | HLML_INLINEF bool3 ywz() const { return shuffleb3(*this, 1, 3, 2); } 78 | HLML_INLINEF bool3 yww() const { return shuffleb3(*this, 1, 3, 3); } 79 | 80 | HLML_INLINEF bool3 zxx() const { return shuffleb3(*this, 2, 0, 0); } 81 | HLML_INLINEF bool3 zxy() const { return shuffleb3(*this, 2, 0, 1); } 82 | HLML_INLINEF bool3 zxz() const { return shuffleb3(*this, 2, 0, 2); } 83 | HLML_INLINEF bool3 zxw() const { return shuffleb3(*this, 2, 0, 3); } 84 | HLML_INLINEF bool3 zyx() const { return shuffleb3(*this, 2, 1, 0); } 85 | HLML_INLINEF bool3 zyy() const { return shuffleb3(*this, 2, 1, 1); } 86 | HLML_INLINEF bool3 zyz() const { return shuffleb3(*this, 2, 1, 2); } 87 | HLML_INLINEF bool3 zyw() const { return shuffleb3(*this, 2, 1, 3); } 88 | HLML_INLINEF bool3 zzx() const { return shuffleb3(*this, 2, 2, 0); } 89 | HLML_INLINEF bool3 zzy() const { return shuffleb3(*this, 2, 2, 1); } 90 | HLML_INLINEF bool3 zzz() const { return shuffleb3(*this, 2, 2, 2); } 91 | HLML_INLINEF bool3 zzw() const { return shuffleb3(*this, 2, 2, 3); } 92 | HLML_INLINEF bool3 zwx() const { return shuffleb3(*this, 2, 3, 0); } 93 | HLML_INLINEF bool3 zwy() const { return shuffleb3(*this, 2, 3, 1); } 94 | HLML_INLINEF bool3 zwz() const { return shuffleb3(*this, 2, 3, 2); } 95 | HLML_INLINEF bool3 zww() const { return shuffleb3(*this, 2, 3, 3); } 96 | 97 | HLML_INLINEF bool4 xxxx() const { return shuffleb4(*this, 0, 0, 0, 0); } 98 | HLML_INLINEF bool4 xxxy() const { return shuffleb4(*this, 0, 0, 0, 1); } 99 | HLML_INLINEF bool4 xxxz() const { return shuffleb4(*this, 0, 0, 0, 2); } 100 | HLML_INLINEF bool4 xxxw() const { return shuffleb4(*this, 0, 0, 0, 3); } 101 | HLML_INLINEF bool4 xxyx() const { return shuffleb4(*this, 0, 0, 1, 0); } 102 | HLML_INLINEF bool4 xxyy() const { return shuffleb4(*this, 0, 0, 1, 1); } 103 | HLML_INLINEF bool4 xxyz() const { return shuffleb4(*this, 0, 0, 1, 2); } 104 | HLML_INLINEF bool4 xxyw() const { return shuffleb4(*this, 0, 0, 1, 3); } 105 | HLML_INLINEF bool4 xxzx() const { return shuffleb4(*this, 0, 0, 2, 0); } 106 | HLML_INLINEF bool4 xxzy() const { return shuffleb4(*this, 0, 0, 2, 1); } 107 | HLML_INLINEF bool4 xxzz() const { return shuffleb4(*this, 0, 0, 2, 2); } 108 | HLML_INLINEF bool4 xxzw() const { return shuffleb4(*this, 0, 0, 2, 3); } 109 | HLML_INLINEF bool4 xxwx() const { return shuffleb4(*this, 0, 0, 3, 0); } 110 | HLML_INLINEF bool4 xxwy() const { return shuffleb4(*this, 0, 0, 3, 1); } 111 | HLML_INLINEF bool4 xxwz() const { return shuffleb4(*this, 0, 0, 3, 2); } 112 | HLML_INLINEF bool4 xxww() const { return shuffleb4(*this, 0, 0, 3, 3); } 113 | HLML_INLINEF bool4 xyxx() const { return shuffleb4(*this, 0, 1, 0, 0); } 114 | HLML_INLINEF bool4 xyxy() const { return shuffleb4(*this, 0, 1, 0, 1); } 115 | HLML_INLINEF bool4 xyxz() const { return shuffleb4(*this, 0, 1, 0, 2); } 116 | HLML_INLINEF bool4 xyxw() const { return shuffleb4(*this, 0, 1, 0, 3); } 117 | HLML_INLINEF bool4 xyyx() const { return shuffleb4(*this, 0, 1, 1, 0); } 118 | HLML_INLINEF bool4 xyyy() const { return shuffleb4(*this, 0, 1, 1, 1); } 119 | HLML_INLINEF bool4 xyyz() const { return shuffleb4(*this, 0, 1, 1, 2); } 120 | HLML_INLINEF bool4 xyyw() const { return shuffleb4(*this, 0, 1, 1, 3); } 121 | HLML_INLINEF bool4 xyzx() const { return shuffleb4(*this, 0, 1, 2, 0); } 122 | HLML_INLINEF bool4 xyzy() const { return shuffleb4(*this, 0, 1, 2, 1); } 123 | HLML_INLINEF bool4 xyzz() const { return shuffleb4(*this, 0, 1, 2, 2); } 124 | HLML_INLINEF bool4 xyzw() const { return *this; } 125 | HLML_INLINEF bool4 xywx() const { return shuffleb4(*this, 0, 1, 3, 0); } 126 | HLML_INLINEF bool4 xywy() const { return shuffleb4(*this, 0, 1, 3, 1); } 127 | HLML_INLINEF bool4 xywz() const { return shuffleb4(*this, 0, 1, 3, 2); } 128 | HLML_INLINEF bool4 xyww() const { return shuffleb4(*this, 0, 1, 3, 3); } 129 | HLML_INLINEF bool4 xzxx() const { return shuffleb4(*this, 0, 2, 0, 0); } 130 | HLML_INLINEF bool4 xzxy() const { return shuffleb4(*this, 0, 2, 0, 1); } 131 | HLML_INLINEF bool4 xzxz() const { return shuffleb4(*this, 0, 2, 0, 2); } 132 | HLML_INLINEF bool4 xzxw() const { return shuffleb4(*this, 0, 2, 0, 3); } 133 | HLML_INLINEF bool4 xzyx() const { return shuffleb4(*this, 0, 2, 1, 0); } 134 | HLML_INLINEF bool4 xzyy() const { return shuffleb4(*this, 0, 2, 1, 1); } 135 | HLML_INLINEF bool4 xzyz() const { return shuffleb4(*this, 0, 2, 1, 2); } 136 | HLML_INLINEF bool4 xzyw() const { return shuffleb4(*this, 0, 2, 1, 3); } 137 | HLML_INLINEF bool4 xzzx() const { return shuffleb4(*this, 0, 2, 2, 0); } 138 | HLML_INLINEF bool4 xzzy() const { return shuffleb4(*this, 0, 2, 2, 1); } 139 | HLML_INLINEF bool4 xzzz() const { return shuffleb4(*this, 0, 2, 2, 2); } 140 | HLML_INLINEF bool4 xzzw() const { return shuffleb4(*this, 0, 2, 2, 3); } 141 | HLML_INLINEF bool4 xzwx() const { return shuffleb4(*this, 0, 2, 3, 0); } 142 | HLML_INLINEF bool4 xzwy() const { return shuffleb4(*this, 0, 2, 3, 1); } 143 | HLML_INLINEF bool4 xzwz() const { return shuffleb4(*this, 0, 2, 3, 2); } 144 | HLML_INLINEF bool4 xzww() const { return shuffleb4(*this, 0, 2, 3, 3); } 145 | HLML_INLINEF bool4 xwxx() const { return shuffleb4(*this, 0, 3, 0, 0); } 146 | HLML_INLINEF bool4 xwxy() const { return shuffleb4(*this, 0, 3, 0, 1); } 147 | HLML_INLINEF bool4 xwxz() const { return shuffleb4(*this, 0, 3, 0, 2); } 148 | HLML_INLINEF bool4 xwxw() const { return shuffleb4(*this, 0, 3, 0, 3); } 149 | HLML_INLINEF bool4 xwyx() const { return shuffleb4(*this, 0, 3, 1, 0); } 150 | HLML_INLINEF bool4 xwyy() const { return shuffleb4(*this, 0, 3, 1, 1); } 151 | HLML_INLINEF bool4 xwyz() const { return shuffleb4(*this, 0, 3, 1, 2); } 152 | HLML_INLINEF bool4 xwyw() const { return shuffleb4(*this, 0, 3, 1, 3); } 153 | HLML_INLINEF bool4 xwzx() const { return shuffleb4(*this, 0, 3, 2, 0); } 154 | HLML_INLINEF bool4 xwzy() const { return shuffleb4(*this, 0, 3, 2, 1); } 155 | HLML_INLINEF bool4 xwzz() const { return shuffleb4(*this, 0, 3, 2, 2); } 156 | HLML_INLINEF bool4 xwzw() const { return shuffleb4(*this, 0, 3, 2, 3); } 157 | HLML_INLINEF bool4 xwwx() const { return shuffleb4(*this, 0, 3, 3, 0); } 158 | HLML_INLINEF bool4 xwwy() const { return shuffleb4(*this, 0, 3, 3, 1); } 159 | HLML_INLINEF bool4 xwwz() const { return shuffleb4(*this, 0, 3, 3, 2); } 160 | HLML_INLINEF bool4 xwww() const { return shuffleb4(*this, 0, 3, 3, 3); } 161 | 162 | HLML_INLINEF bool4 yxxx() const { return shuffleb4(*this, 1, 0, 0, 0); } 163 | HLML_INLINEF bool4 yxxy() const { return shuffleb4(*this, 1, 0, 0, 1); } 164 | HLML_INLINEF bool4 yxxz() const { return shuffleb4(*this, 1, 0, 0, 2); } 165 | HLML_INLINEF bool4 yxxw() const { return shuffleb4(*this, 1, 0, 0, 3); } 166 | HLML_INLINEF bool4 yxyx() const { return shuffleb4(*this, 1, 0, 1, 0); } 167 | HLML_INLINEF bool4 yxyy() const { return shuffleb4(*this, 1, 0, 1, 1); } 168 | HLML_INLINEF bool4 yxyz() const { return shuffleb4(*this, 1, 0, 1, 2); } 169 | HLML_INLINEF bool4 yxyw() const { return shuffleb4(*this, 1, 0, 1, 3); } 170 | HLML_INLINEF bool4 yxzx() const { return shuffleb4(*this, 1, 0, 2, 0); } 171 | HLML_INLINEF bool4 yxzy() const { return shuffleb4(*this, 1, 0, 2, 1); } 172 | HLML_INLINEF bool4 yxzz() const { return shuffleb4(*this, 1, 0, 2, 2); } 173 | HLML_INLINEF bool4 yxzw() const { return shuffleb4(*this, 1, 0, 2, 3); } 174 | HLML_INLINEF bool4 yxwx() const { return shuffleb4(*this, 1, 0, 3, 0); } 175 | HLML_INLINEF bool4 yxwy() const { return shuffleb4(*this, 1, 0, 3, 1); } 176 | HLML_INLINEF bool4 yxwz() const { return shuffleb4(*this, 1, 0, 3, 2); } 177 | HLML_INLINEF bool4 yxww() const { return shuffleb4(*this, 1, 0, 3, 3); } 178 | HLML_INLINEF bool4 yyxx() const { return shuffleb4(*this, 1, 1, 0, 0); } 179 | HLML_INLINEF bool4 yyxy() const { return shuffleb4(*this, 1, 1, 0, 1); } 180 | HLML_INLINEF bool4 yyxz() const { return shuffleb4(*this, 1, 1, 0, 2); } 181 | HLML_INLINEF bool4 yyxw() const { return shuffleb4(*this, 1, 1, 0, 3); } 182 | HLML_INLINEF bool4 yyyx() const { return shuffleb4(*this, 1, 1, 1, 0); } 183 | HLML_INLINEF bool4 yyyy() const { return shuffleb4(*this, 1, 1, 1, 1); } 184 | HLML_INLINEF bool4 yyyz() const { return shuffleb4(*this, 1, 1, 1, 2); } 185 | HLML_INLINEF bool4 yyyw() const { return shuffleb4(*this, 1, 1, 1, 3); } 186 | HLML_INLINEF bool4 yyzx() const { return shuffleb4(*this, 1, 1, 2, 0); } 187 | HLML_INLINEF bool4 yyzy() const { return shuffleb4(*this, 1, 1, 2, 1); } 188 | HLML_INLINEF bool4 yyzz() const { return shuffleb4(*this, 1, 1, 2, 2); } 189 | HLML_INLINEF bool4 yyzw() const { return shuffleb4(*this, 1, 1, 2, 3); } 190 | HLML_INLINEF bool4 yywx() const { return shuffleb4(*this, 1, 1, 3, 0); } 191 | HLML_INLINEF bool4 yywy() const { return shuffleb4(*this, 1, 1, 3, 1); } 192 | HLML_INLINEF bool4 yywz() const { return shuffleb4(*this, 1, 1, 3, 2); } 193 | HLML_INLINEF bool4 yyww() const { return shuffleb4(*this, 1, 1, 3, 3); } 194 | HLML_INLINEF bool4 yzxx() const { return shuffleb4(*this, 1, 2, 0, 0); } 195 | HLML_INLINEF bool4 yzxy() const { return shuffleb4(*this, 1, 2, 0, 1); } 196 | HLML_INLINEF bool4 yzxz() const { return shuffleb4(*this, 1, 2, 0, 2); } 197 | HLML_INLINEF bool4 yzxw() const { return shuffleb4(*this, 1, 2, 0, 3); } 198 | HLML_INLINEF bool4 yzyx() const { return shuffleb4(*this, 1, 2, 1, 0); } 199 | HLML_INLINEF bool4 yzyy() const { return shuffleb4(*this, 1, 2, 1, 1); } 200 | HLML_INLINEF bool4 yzyz() const { return shuffleb4(*this, 1, 2, 1, 2); } 201 | HLML_INLINEF bool4 yzyw() const { return shuffleb4(*this, 1, 2, 1, 3); } 202 | HLML_INLINEF bool4 yzzx() const { return shuffleb4(*this, 1, 2, 2, 0); } 203 | HLML_INLINEF bool4 yzzy() const { return shuffleb4(*this, 1, 2, 2, 1); } 204 | HLML_INLINEF bool4 yzzz() const { return shuffleb4(*this, 1, 2, 2, 2); } 205 | HLML_INLINEF bool4 yzzw() const { return shuffleb4(*this, 1, 2, 2, 3); } 206 | HLML_INLINEF bool4 yzwx() const { return shuffleb4(*this, 1, 2, 3, 0); } 207 | HLML_INLINEF bool4 yzwy() const { return shuffleb4(*this, 1, 2, 3, 1); } 208 | HLML_INLINEF bool4 yzwz() const { return shuffleb4(*this, 1, 2, 3, 2); } 209 | HLML_INLINEF bool4 yzww() const { return shuffleb4(*this, 1, 2, 3, 3); } 210 | HLML_INLINEF bool4 ywxx() const { return shuffleb4(*this, 1, 3, 0, 0); } 211 | HLML_INLINEF bool4 ywxy() const { return shuffleb4(*this, 1, 3, 0, 1); } 212 | HLML_INLINEF bool4 ywxz() const { return shuffleb4(*this, 1, 3, 0, 2); } 213 | HLML_INLINEF bool4 ywxw() const { return shuffleb4(*this, 1, 3, 0, 3); } 214 | HLML_INLINEF bool4 ywyx() const { return shuffleb4(*this, 1, 3, 1, 0); } 215 | HLML_INLINEF bool4 ywyy() const { return shuffleb4(*this, 1, 3, 1, 1); } 216 | HLML_INLINEF bool4 ywyz() const { return shuffleb4(*this, 1, 3, 1, 2); } 217 | HLML_INLINEF bool4 ywyw() const { return shuffleb4(*this, 1, 3, 1, 3); } 218 | HLML_INLINEF bool4 ywzx() const { return shuffleb4(*this, 1, 3, 2, 0); } 219 | HLML_INLINEF bool4 ywzy() const { return shuffleb4(*this, 1, 3, 2, 1); } 220 | HLML_INLINEF bool4 ywzz() const { return shuffleb4(*this, 1, 3, 2, 2); } 221 | HLML_INLINEF bool4 ywzw() const { return shuffleb4(*this, 1, 3, 2, 3); } 222 | HLML_INLINEF bool4 ywwx() const { return shuffleb4(*this, 1, 3, 3, 0); } 223 | HLML_INLINEF bool4 ywwy() const { return shuffleb4(*this, 1, 3, 3, 1); } 224 | HLML_INLINEF bool4 ywwz() const { return shuffleb4(*this, 1, 3, 3, 2); } 225 | HLML_INLINEF bool4 ywww() const { return shuffleb4(*this, 1, 3, 3, 3); } 226 | 227 | HLML_INLINEF bool4 zxxx() const { return shuffleb4(*this, 2, 0, 0, 0); } 228 | HLML_INLINEF bool4 zxxy() const { return shuffleb4(*this, 2, 0, 0, 1); } 229 | HLML_INLINEF bool4 zxxz() const { return shuffleb4(*this, 2, 0, 0, 2); } 230 | HLML_INLINEF bool4 zxxw() const { return shuffleb4(*this, 2, 0, 0, 3); } 231 | HLML_INLINEF bool4 zxyx() const { return shuffleb4(*this, 2, 0, 1, 0); } 232 | HLML_INLINEF bool4 zxyy() const { return shuffleb4(*this, 2, 0, 1, 1); } 233 | HLML_INLINEF bool4 zxyz() const { return shuffleb4(*this, 2, 0, 1, 2); } 234 | HLML_INLINEF bool4 zxyw() const { return shuffleb4(*this, 2, 0, 1, 3); } 235 | HLML_INLINEF bool4 zxzx() const { return shuffleb4(*this, 2, 0, 2, 0); } 236 | HLML_INLINEF bool4 zxzy() const { return shuffleb4(*this, 2, 0, 2, 1); } 237 | HLML_INLINEF bool4 zxzz() const { return shuffleb4(*this, 2, 0, 2, 2); } 238 | HLML_INLINEF bool4 zxzw() const { return shuffleb4(*this, 2, 0, 2, 3); } 239 | HLML_INLINEF bool4 zxwx() const { return shuffleb4(*this, 2, 0, 3, 0); } 240 | HLML_INLINEF bool4 zxwy() const { return shuffleb4(*this, 2, 0, 3, 1); } 241 | HLML_INLINEF bool4 zxwz() const { return shuffleb4(*this, 2, 0, 3, 2); } 242 | HLML_INLINEF bool4 zxww() const { return shuffleb4(*this, 2, 0, 3, 3); } 243 | HLML_INLINEF bool4 zyxx() const { return shuffleb4(*this, 2, 1, 0, 0); } 244 | HLML_INLINEF bool4 zyxy() const { return shuffleb4(*this, 2, 1, 0, 1); } 245 | HLML_INLINEF bool4 zyxz() const { return shuffleb4(*this, 2, 1, 0, 2); } 246 | HLML_INLINEF bool4 zyxw() const { return shuffleb4(*this, 2, 1, 0, 3); } 247 | HLML_INLINEF bool4 zyyx() const { return shuffleb4(*this, 2, 1, 1, 0); } 248 | HLML_INLINEF bool4 zyyy() const { return shuffleb4(*this, 2, 1, 1, 1); } 249 | HLML_INLINEF bool4 zyyz() const { return shuffleb4(*this, 2, 1, 1, 2); } 250 | HLML_INLINEF bool4 zyyw() const { return shuffleb4(*this, 2, 1, 1, 3); } 251 | HLML_INLINEF bool4 zyzx() const { return shuffleb4(*this, 2, 1, 2, 0); } 252 | HLML_INLINEF bool4 zyzy() const { return shuffleb4(*this, 2, 1, 2, 1); } 253 | HLML_INLINEF bool4 zyzz() const { return shuffleb4(*this, 2, 1, 2, 2); } 254 | HLML_INLINEF bool4 zyzw() const { return shuffleb4(*this, 2, 1, 2, 3); } 255 | HLML_INLINEF bool4 zywx() const { return shuffleb4(*this, 2, 1, 3, 0); } 256 | HLML_INLINEF bool4 zywy() const { return shuffleb4(*this, 2, 1, 3, 1); } 257 | HLML_INLINEF bool4 zywz() const { return shuffleb4(*this, 2, 1, 3, 2); } 258 | HLML_INLINEF bool4 zyww() const { return shuffleb4(*this, 2, 1, 3, 3); } 259 | HLML_INLINEF bool4 zzxx() const { return shuffleb4(*this, 2, 2, 0, 0); } 260 | HLML_INLINEF bool4 zzxy() const { return shuffleb4(*this, 2, 2, 0, 1); } 261 | HLML_INLINEF bool4 zzxz() const { return shuffleb4(*this, 2, 2, 0, 2); } 262 | HLML_INLINEF bool4 zzxw() const { return shuffleb4(*this, 2, 2, 0, 3); } 263 | HLML_INLINEF bool4 zzyx() const { return shuffleb4(*this, 2, 2, 1, 0); } 264 | HLML_INLINEF bool4 zzyy() const { return shuffleb4(*this, 2, 2, 1, 1); } 265 | HLML_INLINEF bool4 zzyz() const { return shuffleb4(*this, 2, 2, 1, 2); } 266 | HLML_INLINEF bool4 zzyw() const { return shuffleb4(*this, 2, 2, 1, 3); } 267 | HLML_INLINEF bool4 zzzx() const { return shuffleb4(*this, 2, 2, 2, 0); } 268 | HLML_INLINEF bool4 zzzy() const { return shuffleb4(*this, 2, 2, 2, 1); } 269 | HLML_INLINEF bool4 zzzz() const { return shuffleb4(*this, 2, 2, 2, 2); } 270 | HLML_INLINEF bool4 zzzw() const { return shuffleb4(*this, 2, 2, 2, 3); } 271 | HLML_INLINEF bool4 zzwx() const { return shuffleb4(*this, 2, 2, 3, 0); } 272 | HLML_INLINEF bool4 zzwy() const { return shuffleb4(*this, 2, 2, 3, 1); } 273 | HLML_INLINEF bool4 zzwz() const { return shuffleb4(*this, 2, 2, 3, 2); } 274 | HLML_INLINEF bool4 zzww() const { return shuffleb4(*this, 2, 2, 3, 3); } 275 | HLML_INLINEF bool4 zwxx() const { return shuffleb4(*this, 2, 3, 0, 0); } 276 | HLML_INLINEF bool4 zwxy() const { return shuffleb4(*this, 2, 3, 0, 1); } 277 | HLML_INLINEF bool4 zwxz() const { return shuffleb4(*this, 2, 3, 0, 2); } 278 | HLML_INLINEF bool4 zwxw() const { return shuffleb4(*this, 2, 3, 0, 3); } 279 | HLML_INLINEF bool4 zwyx() const { return shuffleb4(*this, 2, 3, 1, 0); } 280 | HLML_INLINEF bool4 zwyy() const { return shuffleb4(*this, 2, 3, 1, 1); } 281 | HLML_INLINEF bool4 zwyz() const { return shuffleb4(*this, 2, 3, 1, 2); } 282 | HLML_INLINEF bool4 zwyw() const { return shuffleb4(*this, 2, 3, 1, 3); } 283 | HLML_INLINEF bool4 zwzx() const { return shuffleb4(*this, 2, 3, 2, 0); } 284 | HLML_INLINEF bool4 zwzy() const { return shuffleb4(*this, 2, 3, 2, 1); } 285 | HLML_INLINEF bool4 zwzz() const { return shuffleb4(*this, 2, 3, 2, 2); } 286 | HLML_INLINEF bool4 zwzw() const { return shuffleb4(*this, 2, 3, 2, 3); } 287 | HLML_INLINEF bool4 zwwx() const { return shuffleb4(*this, 2, 3, 3, 0); } 288 | HLML_INLINEF bool4 zwwy() const { return shuffleb4(*this, 2, 3, 3, 1); } 289 | HLML_INLINEF bool4 zwwz() const { return shuffleb4(*this, 2, 3, 3, 2); } 290 | HLML_INLINEF bool4 zwww() const { return shuffleb4(*this, 2, 3, 3, 3); } 291 | 292 | HLML_INLINEF bool4 wxxx() const { return shuffleb4(*this, 3, 0, 0, 0); } 293 | HLML_INLINEF bool4 wxxy() const { return shuffleb4(*this, 3, 0, 0, 1); } 294 | HLML_INLINEF bool4 wxxz() const { return shuffleb4(*this, 3, 0, 0, 2); } 295 | HLML_INLINEF bool4 wxxw() const { return shuffleb4(*this, 3, 0, 0, 3); } 296 | HLML_INLINEF bool4 wxyx() const { return shuffleb4(*this, 3, 0, 1, 0); } 297 | HLML_INLINEF bool4 wxyy() const { return shuffleb4(*this, 3, 0, 1, 1); } 298 | HLML_INLINEF bool4 wxyz() const { return shuffleb4(*this, 3, 0, 1, 2); } 299 | HLML_INLINEF bool4 wxyw() const { return shuffleb4(*this, 3, 0, 1, 3); } 300 | HLML_INLINEF bool4 wxzx() const { return shuffleb4(*this, 3, 0, 2, 0); } 301 | HLML_INLINEF bool4 wxzy() const { return shuffleb4(*this, 3, 0, 2, 1); } 302 | HLML_INLINEF bool4 wxzz() const { return shuffleb4(*this, 3, 0, 2, 2); } 303 | HLML_INLINEF bool4 wxzw() const { return shuffleb4(*this, 3, 0, 2, 3); } 304 | HLML_INLINEF bool4 wxwx() const { return shuffleb4(*this, 3, 0, 3, 0); } 305 | HLML_INLINEF bool4 wxwy() const { return shuffleb4(*this, 3, 0, 3, 1); } 306 | HLML_INLINEF bool4 wxwz() const { return shuffleb4(*this, 3, 0, 3, 2); } 307 | HLML_INLINEF bool4 wxww() const { return shuffleb4(*this, 3, 0, 3, 3); } 308 | HLML_INLINEF bool4 wyxx() const { return shuffleb4(*this, 3, 1, 0, 0); } 309 | HLML_INLINEF bool4 wyxy() const { return shuffleb4(*this, 3, 1, 0, 1); } 310 | HLML_INLINEF bool4 wyxz() const { return shuffleb4(*this, 3, 1, 0, 2); } 311 | HLML_INLINEF bool4 wyxw() const { return shuffleb4(*this, 3, 1, 0, 3); } 312 | HLML_INLINEF bool4 wyyx() const { return shuffleb4(*this, 3, 1, 1, 0); } 313 | HLML_INLINEF bool4 wyyy() const { return shuffleb4(*this, 3, 1, 1, 1); } 314 | HLML_INLINEF bool4 wyyz() const { return shuffleb4(*this, 3, 1, 1, 2); } 315 | HLML_INLINEF bool4 wyyw() const { return shuffleb4(*this, 3, 1, 1, 3); } 316 | HLML_INLINEF bool4 wyzx() const { return shuffleb4(*this, 3, 1, 2, 0); } 317 | HLML_INLINEF bool4 wyzy() const { return shuffleb4(*this, 3, 1, 2, 1); } 318 | HLML_INLINEF bool4 wyzz() const { return shuffleb4(*this, 3, 1, 2, 2); } 319 | HLML_INLINEF bool4 wyzw() const { return shuffleb4(*this, 3, 1, 2, 3); } 320 | HLML_INLINEF bool4 wywx() const { return shuffleb4(*this, 3, 1, 3, 0); } 321 | HLML_INLINEF bool4 wywy() const { return shuffleb4(*this, 3, 1, 3, 1); } 322 | HLML_INLINEF bool4 wywz() const { return shuffleb4(*this, 3, 1, 3, 2); } 323 | HLML_INLINEF bool4 wyww() const { return shuffleb4(*this, 3, 1, 3, 3); } 324 | HLML_INLINEF bool4 wzxx() const { return shuffleb4(*this, 3, 2, 0, 0); } 325 | HLML_INLINEF bool4 wzxy() const { return shuffleb4(*this, 3, 2, 0, 1); } 326 | HLML_INLINEF bool4 wzxz() const { return shuffleb4(*this, 3, 2, 0, 2); } 327 | HLML_INLINEF bool4 wzxw() const { return shuffleb4(*this, 3, 2, 0, 3); } 328 | HLML_INLINEF bool4 wzyx() const { return shuffleb4(*this, 3, 2, 1, 0); } 329 | HLML_INLINEF bool4 wzyy() const { return shuffleb4(*this, 3, 2, 1, 1); } 330 | HLML_INLINEF bool4 wzyz() const { return shuffleb4(*this, 3, 2, 1, 2); } 331 | HLML_INLINEF bool4 wzyw() const { return shuffleb4(*this, 3, 2, 1, 3); } 332 | HLML_INLINEF bool4 wzzx() const { return shuffleb4(*this, 3, 2, 2, 0); } 333 | HLML_INLINEF bool4 wzzy() const { return shuffleb4(*this, 3, 2, 2, 1); } 334 | HLML_INLINEF bool4 wzzz() const { return shuffleb4(*this, 3, 2, 2, 2); } 335 | HLML_INLINEF bool4 wzzw() const { return shuffleb4(*this, 3, 2, 2, 3); } 336 | HLML_INLINEF bool4 wzwx() const { return shuffleb4(*this, 3, 2, 3, 0); } 337 | HLML_INLINEF bool4 wzwy() const { return shuffleb4(*this, 3, 2, 3, 1); } 338 | HLML_INLINEF bool4 wzwz() const { return shuffleb4(*this, 3, 2, 3, 2); } 339 | HLML_INLINEF bool4 wzww() const { return shuffleb4(*this, 3, 2, 3, 3); } 340 | HLML_INLINEF bool4 wwxx() const { return shuffleb4(*this, 3, 3, 0, 0); } 341 | HLML_INLINEF bool4 wwxy() const { return shuffleb4(*this, 3, 3, 0, 1); } 342 | HLML_INLINEF bool4 wwxz() const { return shuffleb4(*this, 3, 3, 0, 2); } 343 | HLML_INLINEF bool4 wwxw() const { return shuffleb4(*this, 3, 3, 0, 3); } 344 | HLML_INLINEF bool4 wwyx() const { return shuffleb4(*this, 3, 3, 1, 0); } 345 | HLML_INLINEF bool4 wwyy() const { return shuffleb4(*this, 3, 3, 1, 1); } 346 | HLML_INLINEF bool4 wwyz() const { return shuffleb4(*this, 3, 3, 1, 2); } 347 | HLML_INLINEF bool4 wwyw() const { return shuffleb4(*this, 3, 3, 1, 3); } 348 | HLML_INLINEF bool4 wwzx() const { return shuffleb4(*this, 3, 3, 2, 0); } 349 | HLML_INLINEF bool4 wwzy() const { return shuffleb4(*this, 3, 3, 2, 1); } 350 | HLML_INLINEF bool4 wwzz() const { return shuffleb4(*this, 3, 3, 2, 2); } 351 | HLML_INLINEF bool4 wwzw() const { return shuffleb4(*this, 3, 3, 2, 3); } 352 | HLML_INLINEF bool4 wwwx() const { return shuffleb4(*this, 3, 3, 3, 0); } 353 | HLML_INLINEF bool4 wwwy() const { return shuffleb4(*this, 3, 3, 3, 1); } 354 | HLML_INLINEF bool4 wwwz() const { return shuffleb4(*this, 3, 3, 3, 2); } 355 | HLML_INLINEF bool4 wwww() const { return shuffleb4(*this, 3, 3, 3, 3); } 356 | }; 357 | HLML_INLINEF bool4 operator! (bool4 a) { a.m = funcs::notAandB(a.m, consts::vsignbits_xyzw); return a; } 358 | HLML_INLINEF bool4 operator~ (bool4 a) { return !a; } 359 | HLML_INLINEF bool4 operator& (bool4 a, bool4 b) { a.m = funcs::AandB(a.m, b.m); return a; } 360 | HLML_INLINEF bool4 operator| (bool4 a, bool4 b) { a.m = funcs::AorB(a.m, b.m); return a; } 361 | HLML_INLINEF bool4 operator^ (bool4 a, bool4 b) { a.m = funcs::AxorB(a.m, b.m); return a; } 362 | HLML_INLINEF bool4& operator&= (bool4& a, bool4 b) { a = a & b; return a; } 363 | HLML_INLINEF bool4& operator|= (bool4& a, bool4 b) { a = a | b; return a; } 364 | HLML_INLINEF bool4& operator^= (bool4& a, bool4 b) { a = a ^ b; return a; } 365 | HLML_INLINEF u32 mask (bool4 v) { return bool4::flagsall & funcs::movemask(v.m); } 366 | HLML_INLINEF b8 all (bool4 v) { return bool4::flagsall == mask(v); } 367 | HLML_INLINEF b8 any (bool4 v) { return mask(v); } 368 | HLML_INLINEF b8 none (bool4 v) { return !any(v); } 369 | } -------------------------------------------------------------------------------- /common.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #define HLML_VCONST extern const __declspec(selectany) 7 | 8 | namespace hlml { 9 | typedef float f32; 10 | typedef float float1; 11 | typedef bool b8; 12 | typedef ::uint_least8_t u8; 13 | typedef ::int_least8_t i8; 14 | typedef ::uint_least16_t u16; 15 | typedef ::int_least16_t i16; 16 | typedef ::uint_least32_t u32; 17 | typedef ::int_least32_t i32; 18 | typedef ::uint_least64_t u64; 19 | typedef ::int_least64_t i64; 20 | typedef u16 b16; 21 | typedef u32 b32; 22 | typedef __m128 VF128; 23 | typedef __m128i VI128; 24 | static_assert(sizeof(bool) == 1, "sizeof(bool) is not 1 byte"); 25 | }; 26 | 27 | #undef min 28 | #undef max 29 | 30 | #include "funcs_sse.hpp" 31 | 32 | namespace hlml { 33 | namespace consts { 34 | constexpr f32 PI = 3.14159265358979323846f; 35 | constexpr f32 PI_INV = 1.0f / 3.14159265358979323846f; 36 | constexpr f32 DEGS_IN_RAD = 180.0f / PI; 37 | constexpr f32 RADS_IN_DEG = PI / 180.0f; 38 | 39 | struct vconstu { 40 | vconstu(u32 u0, u32 u1, u32 u2, u32 u3) { 41 | u[0] = u0; 42 | u[1] = u1; 43 | u[2] = u2; 44 | u[3] = u3; 45 | } 46 | vconstu(i32 u0, i32 u1, i32 u2, i32 u3) { 47 | i[0] = u0; 48 | i[1] = u1; 49 | i[2] = u2; 50 | i[3] = u3; 51 | } 52 | vconstu(f32 f0, f32 f1, f32 f2, f32 f3) { 53 | f[0] = f0; 54 | f[1] = f1; 55 | f[2] = f2; 56 | f[3] = f3; 57 | } 58 | union { u32 u[4]; i32 i[4]; f32 f[4]; VF128 vf; VI128 vi; }; 59 | HLML_INLINEF operator VF128() const { return vf; } 60 | HLML_INLINEF operator VI128() const { return vi; } 61 | }; 62 | 63 | static constexpr f32 sfZero = 0.0f; 64 | static constexpr f32 sfOne = 1.0f; 65 | static constexpr f32 sfNOne = -1.0f; 66 | 67 | static constexpr u32 snSignBit = 0x80000000; 68 | static constexpr u32 snNSignBit = ~snSignBit; 69 | static constexpr u32 snZero = 0x00000000; 70 | static constexpr u32 snZeroN = ~snZero; 71 | static constexpr i32 snMagicF2I = (150 << 23) | (1 << 22); 72 | 73 | HLML_VCONST vconstu vzeros = { sfZero, sfZero, sfZero, sfZero }; 74 | HLML_VCONST vconstu vones = { sfOne, sfOne, sfOne, sfOne }; 75 | HLML_VCONST vconstu vones2 = { sfOne, sfOne, sfZero, sfZero }; 76 | HLML_VCONST vconstu vones3 = { sfOne, sfOne, sfOne, sfZero }; 77 | HLML_VCONST vconstu vones4 = { sfOne, sfOne, sfOne, sfOne }; 78 | HLML_VCONST vconstu vnones2 = { sfNOne, sfNOne, sfZero, sfZero }; 79 | HLML_VCONST vconstu vnones3 = { sfNOne, sfNOne, sfZero, sfZero }; 80 | HLML_VCONST vconstu vnones4 = { sfNOne, sfNOne, sfNOne, sfZero }; 81 | HLML_VCONST vconstu vpoint = { sfZero, sfZero, sfZero, sfOne }; 82 | HLML_VCONST vconstu vvector = { sfZero, sfZero, sfZero, sfZero }; 83 | HLML_VCONST vconstu vscaleinv = { sfOne, sfOne, sfOne, sfZero }; 84 | HLML_VCONST vconstu vf2ibits = { snMagicF2I, snMagicF2I, snMagicF2I, snMagicF2I }; 85 | HLML_VCONST vconstu vsignbits_xyzw = { snSignBit, snSignBit, snSignBit, snSignBit }; 86 | HLML_VCONST vconstu vsignbitsn = { snNSignBit, snNSignBit, snNSignBit, snNSignBit }; 87 | HLML_VCONST vconstu vsignbits_yz = { snZero, snSignBit, snSignBit, snZero }; 88 | HLML_VCONST vconstu vsignbits_w = { snZero, snZero, snZero, snSignBit }; 89 | HLML_VCONST vconstu vsignbits_xyz = { snSignBit, snSignBit, snSignBit, snZero }; 90 | HLML_VCONST vconstu vsignbits_xy = { snSignBit, snSignBit, snZero, snZero }; 91 | HLML_VCONST vconstu vsignbits_xz = { snSignBit, snZero, snSignBit, snZero }; 92 | HLML_VCONST vconstu vsignbits_yw = { snZero, snSignBit, snZero, snSignBit }; 93 | HLML_VCONST vconstu vnall = { snZeroN, snZeroN, snZeroN, snZeroN }; 94 | HLML_VCONST vconstu vnall3 = { snZeroN, snZeroN, snZeroN, snZero }; 95 | HLML_VCONST vconstu vnall2 = { snZeroN, snZeroN, snZero, snZero }; 96 | } 97 | 98 | HLML_INLINEF f32 DEG2RAD(f32 degs) { return degs * consts::RADS_IN_DEG; } 99 | HLML_INLINEF f32 RAD2DEG(f32 rads) { return rads * consts::DEGS_IN_RAD; } 100 | 101 | struct uiasf { 102 | union { i32 asi32; u32 asu32; f32 asf32; }; 103 | uiasf(i32 val) : asi32(val) {} 104 | uiasf(f32 val) : asf32(val) {} 105 | }; 106 | 107 | template HLML_INLINEF T cmpeq (T a, T b) { a.m = funcs::AcmpeqB(a.m, b.m); return a; } 108 | template HLML_INLINEF T cmpne (T a, T b) { a.m = funcs::AcmpneB(a.m, b.m); return a; } 109 | template HLML_INLINEF T cmpgt (T a, T b) { a.m = funcs::AcmpgtB(a.m, b.m); return a; } 110 | template HLML_INLINEF T cmpge (T a, T b) { a.m = funcs::AcmpgeB(a.m, b.m); return a; } 111 | template HLML_INLINEF T cmplt (T a, T b) { a.m = funcs::AcmpltB(a.m, b.m); return a; } 112 | template HLML_INLINEF T cmple (T a, T b) { a.m = funcs::AcmpleB(a.m, b.m); return a; } 113 | 114 | HLML_INLINEF u32 min(u32 a, u32 b) { return a < b ? a : b; } 115 | HLML_INLINEF u32 max(u32 a, u32 b) { return b < a ? a : b; } 116 | HLML_INLINEF f32 min(f32 a, f32 b) { return a < b ? a : b; } 117 | HLML_INLINEF f32 max(f32 a, f32 b) { return b < a ? a : b; } 118 | HLML_INLINEF f32 abs(f32 v) { 119 | uiasf a = { v }; 120 | a.asu32 &= ~consts::snSignBit; 121 | return a.asf32; 122 | } 123 | HLML_INLINEF f32 clamp(f32 v, f32 a, f32 b) { return min(max(v, a), b); } 124 | HLML_INLINEF f32 saturate(f32 v) { return clamp(v, 0.0, 1.0f); } 125 | 126 | HLML_INLINEF i32 f2i(f32 x) { 127 | const i32 magic = consts::snMagicF2I; 128 | x += *(f32*)&magic; 129 | return *(i32*)&x - magic; 130 | } 131 | HLML_INLINEF u32 ftou(f32 nfloat, u32 bits) { u32 nIntervals = (1u << bits) - 1u; return min((u32)(nfloat * (f32)(nIntervals) + 0.5f), nIntervals); } 132 | HLML_INLINEF f32 utof(u32 quantized, u32 bits) { return (f32)quantized / (f32)((1u << bits) - 1u); } 133 | HLML_INLINEF u32 ftou(f32 value, f32 min, f32 max, u32 bits) { return ftou((value - min) / (max - min), bits); } 134 | HLML_INLINEF f32 utof(u32 quantized, f32 min, f32 max, u32 bits) { return min + (utof(quantized, bits) * (max - min)); } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /float2.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.hpp" 4 | #include "bool2.hpp" 5 | #include "int2.hpp" 6 | 7 | namespace hlml { 8 | struct float2 { 9 | VF128 m = { 0 }; 10 | 11 | HLML_INLINEF float2() {} 12 | HLML_INLINEF float2(f32 x, f32 y) : m(funcs::setXYZW(x, y, consts::sfZero, consts::sfZero)) {} 13 | HLML_INLINEF explicit float2(f32 x) : float2(x, x) {} 14 | HLML_INLINEF explicit float2(const f32 *p) : float2(p[0], p[1]) {} 15 | HLML_INLINEF explicit float2(VF128 v) : m(v) {} 16 | HLML_INLINEF float2 float2i(i32 x, i32 y) { return float2((f32)x, (f32)y); } 17 | 18 | HLML_INLINEF void store(f32 *p) const { p[0] = x(); p[1] = y(); } 19 | 20 | HLML_INLINEF void setX(f32 x) { m = insertf(m, x, 0); } 21 | HLML_INLINEF void setY(f32 y) { m = insertf(m, y, 1); } 22 | 23 | HLML_INLINEF f32 x() const { uiasf res(extractf(m, 0)); return res.asf32; } 24 | HLML_INLINEF f32 y() const { uiasf res(extractf(m, 1)); return res.asf32; } 25 | 26 | HLML_INLINEF float2 xx() const { return shufflef2(*this, 0, 0); } 27 | HLML_INLINEF float2 xy() const { return *this; } 28 | HLML_INLINEF float2 yx() const { return shufflef2(*this, 1, 0); } 29 | HLML_INLINEF float2 yy() const { return shufflef2(*this, 1, 1); } 30 | 31 | HLML_INLINEF f32 r() const { return x(); } 32 | HLML_INLINEF f32 g() const { return y(); } 33 | 34 | HLML_INLINEF float2 rr() const { return xx(); } 35 | HLML_INLINEF float2 rg() const { return xy(); } 36 | HLML_INLINEF float2 gr() const { return yx(); } 37 | HLML_INLINEF float2 gg() const { return yy(); } 38 | }; 39 | //boolean 40 | HLML_INLINEF bool2 operator== (float2 a, float2 b) { a.m = funcs::AcmpeqB(a.m, b.m); return bool2(funcs::fasi(a.m)); } 41 | HLML_INLINEF bool2 operator!= (float2 a, float2 b) { a.m = funcs::AcmpneB(a.m, b.m); return bool2(funcs::fasi(a.m)); } 42 | HLML_INLINEF bool2 operator< (float2 a, float2 b) { a.m = funcs::AcmpltB(a.m, b.m); return bool2(funcs::fasi(a.m)); } 43 | HLML_INLINEF bool2 operator> (float2 a, float2 b) { a.m = funcs::AcmpgtB(a.m, b.m); return bool2(funcs::fasi(a.m)); } 44 | HLML_INLINEF bool2 operator<= (float2 a, float2 b) { a.m = funcs::AcmpleB(a.m, b.m); return bool2(funcs::fasi(a.m)); } 45 | HLML_INLINEF bool2 operator>= (float2 a, float2 b) { a.m = funcs::AcmpgeB(a.m, b.m); return bool2(funcs::fasi(a.m)); } 46 | //logical 47 | HLML_INLINEF float2 operator~ (float2 a) { a.m = funcs::notAandB(a.m, consts::vnall2); return a; } 48 | HLML_INLINEF float2 operator& (float2 a, float2 b) { a.m = funcs::AandB(a.m, b.m); return a; } 49 | HLML_INLINEF float2 operator| (float2 a, float2 b) { a.m = funcs::AorB(a.m, b.m); return a; } 50 | HLML_INLINEF float2 operator^ (float2 a, float2 b) { a.m = funcs::AxorB(a.m, b.m); return a; } 51 | //arithmetic 52 | HLML_INLINEF float2 operator+ (float2 a) { return a; } 53 | HLML_INLINEF float2 operator- (float2 a) { a.m = funcs::AxorB(a.m, consts::vsignbits_xy); return a; } 54 | HLML_INLINEF float2 operator+ (float2 a, float2 b) { a.m = funcs::AaddB(a.m, b.m); return a; } 55 | HLML_INLINEF float2 operator- (float2 a, float2 b) { a.m = funcs::AsubB(a.m, b.m); return a; } 56 | HLML_INLINEF float2 operator* (float2 a, float2 b) { a.m = funcs::AmulB(a.m, b.m); return a; } 57 | HLML_INLINEF float2 operator/ (float2 a, float2 b) { a.m = funcs::AdivB(a.m, b.m); return a; } 58 | HLML_INLINEF float2& operator+= (float2& a, float2 b) { a = a + b; return a; } 59 | HLML_INLINEF float2& operator-= (float2& a, float2 b) { a = a - b; return a; } 60 | HLML_INLINEF float2& operator*= (float2& a, float2 b) { a = a * b; return a; } 61 | HLML_INLINEF float2& operator/= (float2& a, float2 b) { a = a / b; return a; } 62 | HLML_INLINEF float2 operator+ (float2 a, f32 b) { return a + float2(b); } 63 | HLML_INLINEF float2 operator- (float2 a, f32 b) { return a - float2(b); } 64 | HLML_INLINEF float2 operator* (float2 a, f32 b) { return a * float2(b); } 65 | HLML_INLINEF float2 operator/ (float2 a, f32 b) { return a / float2(b); } 66 | HLML_INLINEF float2& operator+= (float2& a, f32 b) { return a += float2(b); } 67 | HLML_INLINEF float2& operator-= (float2& a, f32 b) { return a -= float2(b); } 68 | HLML_INLINEF float2& operator*= (float2& a, f32 b) { return a *= float2(b); } 69 | HLML_INLINEF float2& operator/= (float2& a, f32 b) { return a /= float2(b); } 70 | HLML_INLINEF float2 operator+ (f32 a, float2 b) { return float2(a) + b; } 71 | HLML_INLINEF float2 operator- (f32 a, float2 b) { return float2(a) - b; } 72 | HLML_INLINEF float2 operator* (f32 a, float2 b) { return float2(a) * b; } 73 | HLML_INLINEF float2 operator/ (f32 a, float2 b) { return float2(a) / b; } 74 | //funcs 75 | HLML_INLINEF int2 asint (float2 a) { return int2(funcs::fasi(a.m)); } 76 | HLML_INLINEF int2 toint (float2 a) { return int2(funcs::ftoi(a.m)); } 77 | HLML_INLINEF float2 asflt (int2 a) { return float2(funcs::iasf(a.m)); } 78 | HLML_INLINEF float2 toflt (int2 a) { return float2(funcs::itof(a.m)); } 79 | 80 | HLML_INLINEF float2 abs (float2 v) { v.m = funcs::notAandB(consts::vsignbits_xy, v.m); return v; } 81 | HLML_INLINEF float2 ceil (float2 a) { a.m = funcs::ceil(a.m); return a; } 82 | HLML_INLINEF float2 clamp (float2 v, float2 a, float2 b) { v.m = funcs::AminB(funcs::AmaxB(v.m, a.m), b.m); return v; } 83 | HLML_INLINEF float2 clamp (float2 v, f32 a, f32 b) { return clamp(v, float2(a), float2(b)); } 84 | HLML_INLINEF float2 crossv (float2 a, float2 b) { return (a * b.yx() - a.yx() * b); } 85 | HLML_INLINEF float2 dotv (float2 a, float2 b) { a.m = funcs::AdotBxy(a.m, b.m); return a; } 86 | HLML_INLINEF float2 floor (float2 a) { a.m = funcs::floor(a.m); return a; } 87 | HLML_INLINEF float2 fmod (float2 a, float2 b) { return a - toflt(toint(a / b)) * b; } 88 | HLML_INLINEF float2 frac (float2 a) { a.m = funcs::frac(a.m); return a; } 89 | HLML_INLINEF float2 lerp (float2 a, float2 b, f32 t) { return a + (b - a) * t; } 90 | HLML_INLINEF float2 lerp (float2 a, float2 b, float2 t) { return a + (b - a) * t; } 91 | HLML_INLINEF float2 mad (float2 a, float2 b, float2 c) { a.m = funcs::AmulBaddC(a.m, b.m, c.m); return a; } 92 | HLML_INLINEF float2 maxv (float2 a, float2 b) { a.m = funcs::AmaxB(a.m, b.m); return a; } 93 | HLML_INLINEF float2 minv (float2 a, float2 b) { a.m = funcs::AminB(a.m, b.m); return a; } 94 | HLML_INLINEF float2 rcp (float2 v) { v.m = funcs::axay0000(funcs::rcp(funcs::axay1111(v.m))); return v; } 95 | HLML_INLINEF float2 reflect (float2 v, float2 n) { return v - n * dotv(v, n) * 2.0f; } 96 | HLML_INLINEF float2 round (float2 a) { a.m = funcs::round(a.m); return a; } 97 | HLML_INLINEF float2 rsqrt (float2 v) { v.m = funcs::axay0000(funcs::rsqrt(funcs::axay1111(v.m))); return v; } 98 | HLML_INLINEF float2 saturate (float2 a) { return clamp(a, 0.0f, 1.0f); } 99 | HLML_INLINEF float2 sumv (float2 v) { v.m = funcs::AhaddB(v.m, v.m); return v; } 100 | HLML_INLINEF float2 sqrt (float2 v) { v.m = funcs::sqrt(v.m); return v; } 101 | HLML_INLINEF float2 trunc (float2 a) { a.m = funcs::trunc(a.m); return a; } 102 | 103 | 104 | HLML_INLINEF f32 cross (float2 a, float2 b) { return crossv(a, b).x(); } 105 | HLML_INLINEF f32 hmin (float2 v) { return minv(v, shufflef2(v, 1, 0)).x(); } 106 | HLML_INLINEF f32 hmax (float2 v) { return maxv(v, shufflef2(v, 1, 0)).x(); } 107 | HLML_INLINEF f32 sum (float2 v) { return sumv(v).x(); } 108 | HLML_INLINEF f32 dot (float2 a, float2 b) { return dotv(a, b).x(); } 109 | HLML_INLINEF f32 lengthsq (float2 v) { return dot(v, v); } 110 | HLML_INLINEF f32 length (float2 v) { return sqrt(dotv(v, v)).x(); } 111 | 112 | HLML_INLINEF float2 normalize(float2 v) { 113 | float2 t = dotv(v, v); 114 | float2 d = rsqrt(t); 115 | return v * d; 116 | } 117 | 118 | HLML_INLINEF float2 refract(float2 v, float2 n, f32 idx) { 119 | float2 vn = dotv(v, n); 120 | float2 k = maxv(float2(consts::vzeros), float2(1.0f - idx * idx * (1.0f - vn * vn))); 121 | return v * idx - (vn * idx + sqrt(k)) * n; 122 | } 123 | 124 | HLML_INLINEF float2 sign(float2 v) { 125 | //https://github.com/g-truc/glm/blob/master/glm/simd/common.h#L99 126 | VF128 cmp0 = funcs::AcmpltB(v.m, consts::vzeros); 127 | VF128 cmp1 = funcs::AcmpgtB(v.m, consts::vzeros); 128 | VF128 and0 = funcs::AandB(cmp0, consts::vnones2); 129 | VF128 and1 = funcs::AandB(cmp1, consts::vones2); 130 | v.m = funcs::AorB(and0, and1); 131 | return v; 132 | } 133 | 134 | HLML_INLINEF float2 smoothstep(float2 e0, float2 e1, float2 v) { 135 | float2 zeros(consts::vzeros), ones(consts::vones); 136 | float2 t = clamp((v - e0) / (e1 - e0), zeros, ones); 137 | return (3.0f - 2.0f * t) * t * t; 138 | } 139 | 140 | HLML_INLINEF float2 step(float2 e, float2 v) { 141 | e = sign(v - e); 142 | return maxv(float2(consts::vzeros), e); 143 | } 144 | } -------------------------------------------------------------------------------- /float2x2.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.hpp" 4 | #include "float4.hpp" 5 | 6 | namespace hlml { 7 | struct float2x2 { 8 | float4 m; 9 | 10 | HLML_INLINEF float2x2() : m() {} 11 | HLML_INLINEF explicit float2x2(const f32* p) : m(p) {} 12 | HLML_INLINEF float2x2(f32 x0, f32 y0, f32 x1, f32 y1) : m(x0, y0, x1, y1) {} 13 | HLML_INLINEF float2x2(float2 col0, float2 col1) : m(funcs::axaybxby(col0.m, col1.m)) {} 14 | 15 | HLML_INLINEF static float2x2 identity() { static float2x2 i( { 1.0f, 0.0f, 0.0f, 1.0f } ); return i; } 16 | 17 | HLML_INLINEF float2x2& operator= (float2x2 rhs) { m = rhs.m; return *this; } 18 | HLML_INLINEF float2x2& operator= (f32 s) { m = float4(s); return *this; } 19 | }; 20 | 21 | HLML_INLINEF float2x2 transpose(float2x2 m) { m.m = m.m.xzyw(); return m; } 22 | HLML_INLINEF float2x2 inverse(float2x2 a) { 23 | float4 neg(-a.m); 24 | float4 tmp(funcs::awaxbybz(a.m.m, neg.m)); 25 | float4 adj = tmp.xzwy(); 26 | float4 trans = a.m.xzyw(); 27 | float4 lhs = trans * adj; 28 | float4 rhs = lhs.yxwz(); 29 | float4 dets = lhs + rhs; 30 | a.m = adj / dets; 31 | return a; 32 | } 33 | 34 | HLML_INLINEF b8 operator== (float2x2 lhs, float2x2 rhs) { return all(lhs.m == rhs.m); } 35 | HLML_INLINEF b8 operator!= (float2x2 lhs, float2x2 rhs) { return !(lhs == rhs); } 36 | 37 | HLML_INLINEF float2x2 operator+ (float2x2 m) { return m; } 38 | HLML_INLINEF float2x2 operator+ (float2x2 a, float2x2 b) { a.m += b.m; return a; } 39 | HLML_INLINEF float2x2 operator+ (float2x2 a, f32 s) { a.m += s; return a; } 40 | HLML_INLINEF float2x2 operator+ (f32 s, float2x2 a) { return a + s; } 41 | HLML_INLINEF float2x2& operator+= (float2x2& a, float2x2 b) { a = a + b; return a; } 42 | HLML_INLINEF float2x2& operator+= (float2x2& a, f32 s) { a = a + s; return a; } 43 | HLML_INLINEF float2x2 operator- (float2x2 m) { m.m = -m.m; return m; } 44 | HLML_INLINEF float2x2 operator- (float2x2 a, float2x2 b) { a.m -= b.m; return a; } 45 | HLML_INLINEF float2x2 operator- (float2x2 a, f32 s) { a.m -= s; return a; } 46 | HLML_INLINEF float2x2 operator- (f32 s, float2x2 a) { float2 tmp(s); return float2x2(tmp, tmp) - a; } 47 | HLML_INLINEF float2x2& operator-= (float2x2& a, float2x2 b) { a = a - b; return a; } 48 | HLML_INLINEF float2x2& operator-= (float2x2& a, f32 s) { a = a - s; return a; } 49 | HLML_INLINEF float2x2 operator* (float2x2 a, float2x2 b) { 50 | a.m = a.m.xyxy() * b.m.xxzz() + a.m.zwzw() * b.m.yyww(); 51 | return a; 52 | } 53 | HLML_INLINEF float2x2 operator* (float2x2 a, f32 s) { a.m *= s; return a; } 54 | HLML_INLINEF float2x2 operator* (f32 s, float2x2 a) { return a * s; } 55 | HLML_INLINEF float2 operator* (float2x2 a, float2 v) { a.m *= shufflef4(v,0,1,0,1); return (a.m + a.m.yxwz()).xz(); } 56 | HLML_INLINEF float2 operator* (float2 v, float2x2 a) { 57 | float2 xx(dotv(v, a.m.xy())), yy(dotv(v, a.m.zw())); 58 | float2 xy(funcs::axbxayby(xx.m, yy.m)); 59 | return xy; 60 | } 61 | HLML_INLINEF float2x2& operator*= (float2x2& a, float2x2 b) { a.m = b.m.xyxy() * a.m.xxzz() + b.m.zwzw() * a.m.yyww(); return a; } 62 | HLML_INLINEF float2x2& operator*= (float2x2& a, f32 s) { a = a * s; return a; } 63 | } -------------------------------------------------------------------------------- /float3.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "float2.hpp" 4 | #include "bool3.hpp" 5 | #include "int3.hpp" 6 | 7 | namespace hlml { 8 | struct float4; 9 | 10 | struct float3 { 11 | 12 | VF128 m = { 0 }; 13 | 14 | HLML_INLINEF float3() {} 15 | HLML_INLINEF float3(f32 x, f32 y, f32 z) : m(funcs::setXYZW(x, y, z, consts::sfZero)) {} 16 | HLML_INLINEF float3(float2 v, f32 z) : float3(v.x(), v.y(), z) {} 17 | HLML_INLINEF explicit float3(f32 x) : float3(x, x, x) {} 18 | HLML_INLINEF explicit float3(const f32 *p) : float3(p[0], p[1], p[2]) {} 19 | HLML_INLINEF explicit float3(VF128 v) : m(v) {} 20 | //HLML_INLINEF explicit float3(float4 v) : float3(v.m) {} 21 | HLML_INLINEF float3& operator=(VF128 v) { m = v; return *this; } 22 | HLML_INLINEF float3 float3i(i32 x, i32 y, i32 z) { return float3((f32)x, (f32)y, (f32)z); } 23 | 24 | HLML_INLINEF void store(f32 *p) const { p[0] = x(); p[1] = y(); p[2] = z(); } 25 | 26 | HLML_INLINEF void setX(f32 x) { m = insertf(m, x, 0); } 27 | HLML_INLINEF void setY(f32 y) { m = insertf(m, y, 1); } 28 | HLML_INLINEF void setZ(f32 z) { m = insertf(m, z, 2); } 29 | 30 | HLML_INLINEF f32 x() const { uiasf res(extractf(m, 0)); return res.asf32; } 31 | HLML_INLINEF f32 y() const { uiasf res(extractf(m, 1)); return res.asf32; } 32 | HLML_INLINEF f32 z() const { uiasf res(extractf(m, 2)); return res.asf32; } 33 | 34 | HLML_INLINEF float2 xx() const { return shufflef3tof2(*this, 0, 0); } 35 | HLML_INLINEF float2 xy() const { return shufflef3tof2(*this, 0, 1); } 36 | HLML_INLINEF float2 xz() const { return shufflef3tof2(*this, 0, 2); } 37 | HLML_INLINEF float2 yx() const { return shufflef3tof2(*this, 1, 0); } 38 | HLML_INLINEF float2 yy() const { return shufflef3tof2(*this, 1, 1); } 39 | HLML_INLINEF float2 yz() const { return shufflef3tof2(*this, 1, 2); } 40 | HLML_INLINEF float2 zx() const { return shufflef3tof2(*this, 2, 0); } 41 | HLML_INLINEF float2 zy() const { return shufflef3tof2(*this, 2, 1); } 42 | HLML_INLINEF float2 zz() const { return shufflef3tof2(*this, 2, 2); } 43 | 44 | HLML_INLINEF float3 xxx() const { return shufflef3(*this, 0, 0, 0); } 45 | HLML_INLINEF float3 xxy() const { return shufflef3(*this, 0, 0, 1); } 46 | HLML_INLINEF float3 xxz() const { return shufflef3(*this, 0, 0, 2); } 47 | HLML_INLINEF float3 xyx() const { return shufflef3(*this, 0, 1, 0); } 48 | HLML_INLINEF float3 xyy() const { return shufflef3(*this, 0, 1, 1); } 49 | HLML_INLINEF float3 xyz() const { return *this; } 50 | HLML_INLINEF float3 xzx() const { return shufflef3(*this, 0, 2, 0); } 51 | HLML_INLINEF float3 xzy() const { return shufflef3(*this, 0, 2, 1); } 52 | HLML_INLINEF float3 xzz() const { return shufflef3(*this, 0, 2, 2); } 53 | HLML_INLINEF float3 yxx() const { return shufflef3(*this, 1, 0, 0); } 54 | HLML_INLINEF float3 yxy() const { return shufflef3(*this, 1, 0, 1); } 55 | HLML_INLINEF float3 yxz() const { return shufflef3(*this, 1, 0, 2); } 56 | HLML_INLINEF float3 yyx() const { return shufflef3(*this, 1, 1, 0); } 57 | HLML_INLINEF float3 yyy() const { return shufflef3(*this, 1, 1, 1); } 58 | HLML_INLINEF float3 yyz() const { return shufflef3(*this, 1, 1, 2); } 59 | HLML_INLINEF float3 yzx() const { return shufflef3(*this, 1, 2, 0); } 60 | HLML_INLINEF float3 yzy() const { return shufflef3(*this, 1, 2, 1); } 61 | HLML_INLINEF float3 yzz() const { return shufflef3(*this, 1, 2, 2); } 62 | HLML_INLINEF float3 zxx() const { return shufflef3(*this, 2, 0, 0); } 63 | HLML_INLINEF float3 zxy() const { return shufflef3(*this, 2, 0, 1); } 64 | HLML_INLINEF float3 zxz() const { return shufflef3(*this, 2, 0, 2); } 65 | HLML_INLINEF float3 zyx() const { return shufflef3(*this, 2, 1, 0); } 66 | HLML_INLINEF float3 zyy() const { return shufflef3(*this, 2, 1, 1); } 67 | HLML_INLINEF float3 zyz() const { return shufflef3(*this, 2, 1, 2); } 68 | HLML_INLINEF float3 zzx() const { return shufflef3(*this, 2, 2, 0); } 69 | HLML_INLINEF float3 zzy() const { return shufflef3(*this, 2, 2, 1); } 70 | HLML_INLINEF float3 zzz() const { return shufflef3(*this, 2, 2, 2); } 71 | 72 | HLML_INLINEF f32 r() const { return x(); } 73 | HLML_INLINEF f32 g() const { return y(); } 74 | HLML_INLINEF f32 b() const { return z(); } 75 | 76 | HLML_INLINEF float2 rr() const { return xx(); } 77 | HLML_INLINEF float2 rg() const { return xy(); } 78 | HLML_INLINEF float2 rb() const { return xz(); } 79 | HLML_INLINEF float2 gr() const { return yx(); } 80 | HLML_INLINEF float2 gg() const { return yy(); } 81 | HLML_INLINEF float2 gb() const { return yz(); } 82 | HLML_INLINEF float2 br() const { return zx(); } 83 | HLML_INLINEF float2 bg() const { return zy(); } 84 | HLML_INLINEF float2 bb() const { return zz(); } 85 | 86 | HLML_INLINEF float3 rrr() const { return xxx(); } 87 | HLML_INLINEF float3 rrg() const { return xxy(); } 88 | HLML_INLINEF float3 rrb() const { return xxz(); } 89 | HLML_INLINEF float3 rgr() const { return xyx(); } 90 | HLML_INLINEF float3 rgg() const { return xyy(); } 91 | HLML_INLINEF float3 rgb() const { return xyz(); } 92 | HLML_INLINEF float3 rbr() const { return xzx(); } 93 | HLML_INLINEF float3 rbg() const { return xzy(); } 94 | HLML_INLINEF float3 rbb() const { return xzz(); } 95 | HLML_INLINEF float3 grr() const { return yxx(); } 96 | HLML_INLINEF float3 grg() const { return yxy(); } 97 | HLML_INLINEF float3 grb() const { return yxz(); } 98 | HLML_INLINEF float3 ggr() const { return yyx(); } 99 | HLML_INLINEF float3 ggg() const { return yyy(); } 100 | HLML_INLINEF float3 ggb() const { return yyz(); } 101 | HLML_INLINEF float3 gbr() const { return yzx(); } 102 | HLML_INLINEF float3 gbg() const { return yzy(); } 103 | HLML_INLINEF float3 gbb() const { return yzz(); } 104 | HLML_INLINEF float3 brr() const { return zxx(); } 105 | HLML_INLINEF float3 brg() const { return zxy(); } 106 | HLML_INLINEF float3 brb() const { return zxz(); } 107 | HLML_INLINEF float3 bgr() const { return zyx(); } 108 | HLML_INLINEF float3 bgg() const { return zyy(); } 109 | HLML_INLINEF float3 bgb() const { return zyz(); } 110 | HLML_INLINEF float3 bbr() const { return zzx(); } 111 | HLML_INLINEF float3 bbg() const { return zzy(); } 112 | HLML_INLINEF float3 bbb() const { return zzz(); } 113 | }; 114 | //boolean 115 | HLML_INLINEF bool3 operator== (float3 a, float3 b) { a.m = funcs::AcmpeqB(a.m, b.m); return bool3(funcs::fasi(a.m)); } 116 | HLML_INLINEF bool3 operator!= (float3 a, float3 b) { a.m = funcs::AcmpneB(a.m, b.m); return bool3(funcs::fasi(a.m)); } 117 | HLML_INLINEF bool3 operator< (float3 a, float3 b) { a.m = funcs::AcmpltB(a.m, b.m); return bool3(funcs::fasi(a.m)); } 118 | HLML_INLINEF bool3 operator> (float3 a, float3 b) { a.m = funcs::AcmpgtB(a.m, b.m); return bool3(funcs::fasi(a.m)); } 119 | HLML_INLINEF bool3 operator<= (float3 a, float3 b) { a.m = funcs::AcmpleB(a.m, b.m); return bool3(funcs::fasi(a.m)); } 120 | HLML_INLINEF bool3 operator>= (float3 a, float3 b) { a.m = funcs::AcmpgeB(a.m, b.m); return bool3(funcs::fasi(a.m)); } 121 | //logical 122 | HLML_INLINEF float3 operator~ (float3 a) { a.m = funcs::notAandB(a.m, consts::vnall3); return a; } 123 | HLML_INLINEF float3 operator& (float3 a, float3 b) { a.m = funcs::AandB(a.m, b.m); return a; } 124 | HLML_INLINEF float3 operator| (float3 a, float3 b) { a.m = funcs::AorB(a.m, b.m); return a; } 125 | HLML_INLINEF float3 operator^ (float3 a, float3 b) { a.m = funcs::AxorB(a.m, b.m); return a; } 126 | //arithmetic 127 | HLML_INLINEF float3 operator+ (float3 a) { return a; } 128 | HLML_INLINEF float3 operator- (float3 a) { a.m = funcs::AxorB(a.m, consts::vsignbits_xyz); return a; } 129 | HLML_INLINEF float3 operator+ (float3 a, float3 b) { a.m = funcs::AaddB(a.m, b.m); return a; } 130 | HLML_INLINEF float3 operator- (float3 a, float3 b) { a.m = funcs::AsubB(a.m, b.m); return a; } 131 | HLML_INLINEF float3 operator* (float3 a, float3 b) { a.m = funcs::AmulB(a.m, b.m); return a; } 132 | HLML_INLINEF float3 operator/ (float3 a, float3 b) { a.m = funcs::AdivB(a.m, b.m); return a; } 133 | HLML_INLINEF float3& operator+= (float3& a, float3 b) { a = a + b; return a; } 134 | HLML_INLINEF float3& operator-= (float3& a, float3 b) { a = a - b; return a; } 135 | HLML_INLINEF float3& operator*= (float3& a, float3 b) { a = a * b; return a; } 136 | HLML_INLINEF float3& operator/= (float3& a, float3 b) { a = a / b; return a; } 137 | HLML_INLINEF float3 operator+ (float3 a, f32 b) { return a + float3(b); } 138 | HLML_INLINEF float3 operator- (float3 a, f32 b) { return a - float3(b); } 139 | HLML_INLINEF float3 operator* (float3 a, f32 b) { return a * float3(b); } 140 | HLML_INLINEF float3 operator/ (float3 a, f32 b) { return a / float3(b); } 141 | HLML_INLINEF float3& operator+= (float3& a, f32 b) { return a += float3(b); } 142 | HLML_INLINEF float3& operator-= (float3& a, f32 b) { return a -= float3(b); } 143 | HLML_INLINEF float3& operator*= (float3& a, f32 b) { return a *= float3(b); } 144 | HLML_INLINEF float3& operator/= (float3& a, f32 b) { return a /= float3(b); } 145 | HLML_INLINEF float3 operator+ (f32 a, float3 b) { return float3(a) + b; } 146 | HLML_INLINEF float3 operator- (f32 a, float3 b) { return float3(a) - b; } 147 | HLML_INLINEF float3 operator* (f32 a, float3 b) { return float3(a) * b; } 148 | HLML_INLINEF float3 operator/ (f32 a, float3 b) { return float3(a) / b; } 149 | //funcs 150 | HLML_INLINEF int3 asint (float3 a) { return int3(funcs::fasi(a.m)); } 151 | HLML_INLINEF int3 toint (float3 a) { return int3(funcs::ftoi(a.m)); } 152 | HLML_INLINEF float3 asflt (int3 a) { return float3(funcs::iasf(a.m)); } 153 | HLML_INLINEF float3 toflt (int3 a) { return float3(funcs::itof(a.m)); } 154 | 155 | HLML_INLINEF float3 abs (float3 v) { v.m = funcs::notAandB(consts::vsignbits_xyz, v.m); return v; } 156 | HLML_INLINEF float3 ceil (float3 a) { a.m = funcs::ceil(a.m); return a; } 157 | HLML_INLINEF float3 clamp (float3 v, float3 a, float3 b) { v.m = funcs::AminB(funcs::AmaxB(v.m, a.m), b.m); return v; } 158 | HLML_INLINEF float3 clamp (float3 v, f32 a, f32 b) { return clamp(v, float3(a), float3(b)); } 159 | HLML_INLINEF float3 crossv (float3 a, float3 b) { return (a.yzx() * b - a * b.yzx()).yzx(); } 160 | HLML_INLINEF float3 cross (float3 a, float3 b) { return crossv(a, b); } 161 | HLML_INLINEF float3 dotv (float3 a, float3 b) { a.m = funcs::AdotBxyz(a.m, b.m); return a; } 162 | HLML_INLINEF float3 floor (float3 a) { a.m = funcs::floor(a.m); return a; } 163 | HLML_INLINEF float3 fmod (float3 a, float3 b) { return a - toflt(toint(a / b)) * b; } 164 | HLML_INLINEF float3 frac (float3 a) { a.m = funcs::frac(a.m); return a; } 165 | HLML_INLINEF float3 lerp (float3 a, float3 b, f32 t) { return a + (b - a) * t; } 166 | HLML_INLINEF float3 lerp (float3 a, float3 b, float3 t) { return a + (b - a) * t; } 167 | HLML_INLINEF float3 mad (float3 a, float3 b, float3 c) { a.m = funcs::AmulBaddC(a.m, b.m, c.m); return a; } 168 | HLML_INLINEF float3 maxv (float3 a, float3 b) { a.m = funcs::AmaxB(a.m, b.m); return a; } 169 | HLML_INLINEF float3 minv (float3 a, float3 b) { a.m = funcs::AminB(a.m, b.m); return a; } 170 | HLML_INLINEF float3 rcp (float3 v) { v.m = funcs::axayaz00(funcs::rcp(funcs::axayaz11(v.m))); return v; } 171 | HLML_INLINEF float3 reflect (float3 v, float3 n) { return v - n * dotv(v, n) * 2.0f; } 172 | HLML_INLINEF float3 round (float3 a) { a.m = funcs::round(a.m); return a; } 173 | HLML_INLINEF float3 rsqrt (float3 v) { v.m = funcs::axayaz00(funcs::rsqrt(funcs::axayaz11(v.m))); return v; } 174 | HLML_INLINEF float3 saturate (float3 a) { return clamp(a, 0.0f, 1.0f); } 175 | HLML_INLINEF float3 sumv (float3 v) { return v += v.zxy() + v.yzx(); } 176 | HLML_INLINEF float3 sqrt (float3 v) { v.m = funcs::sqrt(v.m); return v; } 177 | HLML_INLINEF float3 trunc (float3 a) { a.m = funcs::trunc(a.m); return a; } 178 | 179 | 180 | HLML_INLINEF f32 hmin (float3 v) { v = minv(v, shufflef3(v, 1, 0, 2)); return minv(v, shufflef3(v, 2, 0, 1)).x(); } 181 | HLML_INLINEF f32 hmax (float3 v) { v = maxv(v, shufflef3(v, 1, 0, 2)); return maxv(v, shufflef3(v, 2, 0, 1)).x(); } 182 | HLML_INLINEF f32 sum (float3 v) { return sumv(v).x(); } 183 | HLML_INLINEF f32 dot (float3 a, float3 b) { return dotv(a, b).x(); } 184 | HLML_INLINEF f32 lengthsq (float3 v) { return dot(v, v); } 185 | HLML_INLINEF f32 length (float3 v) { return sqrt(dotv(v, v)).x(); } 186 | 187 | HLML_INLINEF float3 normalize(float3 v) { return v * rsqrt(dotv(v, v)); } 188 | 189 | HLML_INLINEF float3 refract(float3 v, float3 n, f32 idx) { 190 | float3 vn = dotv(v, n); 191 | float3 k = maxv(float3(consts::vzeros), float3(1.0f - idx * idx * (1.0f - vn * vn))); 192 | return v * idx - (vn * idx + sqrt(k)) * n; 193 | } 194 | 195 | HLML_INLINEF float3 sign(float3 v) { 196 | //https://github.com/g-truc/glm/blob/master/glm/simd/common.h#L99 197 | VF128 cmp0 = funcs::AcmpltB(v.m, consts::vzeros); 198 | VF128 cmp1 = funcs::AcmpgtB(v.m, consts::vzeros); 199 | VF128 and0 = funcs::AandB(cmp0, consts::vnones3); 200 | VF128 and1 = funcs::AandB(cmp1, consts::vones3); 201 | v.m = funcs::AorB(and0, and1); 202 | return v; 203 | } 204 | 205 | HLML_INLINEF float3 smoothstep(float3 e0, float3 e1, float3 v) { 206 | float3 zeros(consts::vzeros), ones(consts::vones); 207 | float3 t = clamp((v - e0) / (e1 - e0), zeros, ones); 208 | return (3.0f - 2.0f * t) * t * t; 209 | } 210 | 211 | HLML_INLINEF float3 step(float3 e, float3 v) { 212 | e = sign(v - e); 213 | return maxv(float3(consts::vzeros), e); 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /float3x3.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.hpp" 4 | #include "float3.hpp" 5 | 6 | namespace hlml { 7 | struct float3x3 { 8 | float3 c0, c1, c2; 9 | 10 | HLML_INLINEF float3x3() : c0(), c1(), c2() {} 11 | HLML_INLINEF explicit float3x3(const f32* p) : c0(p), c1(p+3), c2(p+6) {} 12 | HLML_INLINEF float3x3(f32 x0, f32 y0, f32 z0, f32 x1, f32 y1, f32 z1, f32 x2, f32 y2, f32 z2) : c0(x0, y0, z0), c1(x1, y1, z1), c2(x2, y2, z2) {} 13 | HLML_INLINEF float3x3(float3 col0, float3 col1, float3 col2) : c0(col0), c1(col1), c2(col2) {} 14 | 15 | HLML_INLINEF static float3x3 identity() { static float3x3 i( { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f } ); return i; } 16 | 17 | HLML_INLINEF float3x3& operator= (float3x3 rhs) { c0 = rhs.c0; c1 = rhs.c1; c2 = rhs.c2; return *this; } 18 | HLML_INLINEF float3x3& operator= (f32 s) { c0 = c1 = c2 = float3(s); return *this; } 19 | }; 20 | 21 | HLML_INLINEF float3x3 transpose(float3x3 m) { 22 | float3 t0 = m.c0, t1 = m.c1, t2 = m.c2, vT(funcs::azbzawbw(t0.m, t1.m)); 23 | t0.m = funcs::axbxayby(t0.m, t1.m); 24 | m.c0.m = funcs::axaybxbw(t0.m, t2.m); 25 | m.c1.m = funcs::azawbybw(t0.m, t2.m); 26 | m.c2.m = funcs::axaybzbw(vT.m, t2.m); 27 | return m; 28 | } 29 | HLML_INLINEF float3x3 inverse(float3x3 m) { 30 | float3 t0 = m.c0, t1 = m.c1, t2 = m.c2; 31 | float3 dets = rcp(dotv(t0, cross(t1, t2))); 32 | dets.m = funcs::axaxazaz(dets.m); 33 | m.c0 = cross(t1, t2) * dets; 34 | m.c1 = cross(t2, t0) * dets; 35 | m.c2 = cross(t0, t1) * dets; 36 | return transpose(m); 37 | } 38 | 39 | HLML_INLINEF b8 operator== (float3x3 lhs, float3x3 rhs) { return all(lhs.c0 == rhs.c0) && all(lhs.c1 == rhs.c1) && all(lhs.c2 == rhs.c2); } 40 | HLML_INLINEF b8 operator!= (float3x3 lhs, float3x3 rhs) { return !(lhs == rhs); } 41 | 42 | HLML_INLINEF float3x3 operator+ (float3x3 m) { return m; } 43 | HLML_INLINEF float3x3 operator+ (float3x3 a, float3x3 b) { a.c0 += b.c0; a.c1 += b.c1; a.c2 += b.c2; return a; } 44 | HLML_INLINEF float3x3 operator+ (float3x3 a, f32 s) { a.c0 += s; a.c1 += s; a.c2 += s; return a; } 45 | HLML_INLINEF float3x3 operator+ (f32 s, float3x3 a) { return a + s; } 46 | HLML_INLINEF float3x3& operator+= (float3x3& a, float3x3 b) { a = a + b; return a; } 47 | HLML_INLINEF float3x3& operator+= (float3x3& a, f32 s) { a = a + s; return a; } 48 | HLML_INLINEF float3x3 operator- (float3x3 m) { m.c0 = -m.c0; m.c1 = -m.c1; m.c2 = -m.c2; return m; } 49 | HLML_INLINEF float3x3 operator- (float3x3 a, float3x3 b) { a.c0 -= b.c0; a.c1 -= b.c1; a.c2 -= b.c2; return a; } 50 | HLML_INLINEF float3x3 operator- (float3x3 a, f32 s) { float3 tmp(s); return a - float3x3(tmp, tmp, tmp); } 51 | HLML_INLINEF float3x3 operator- (f32 s, float3x3 a) { float3 tmp(s); return float3x3(tmp, tmp, tmp) - a; } 52 | HLML_INLINEF float3x3& operator-= (float3x3& a, float3x3 b) { a = a - b; return a; } 53 | HLML_INLINEF float3x3& operator-= (float3x3& a, f32 s) { a = a - s; return a; } 54 | HLML_INLINEF float3x3 operator* (float3x3 a, float3x3 b) { 55 | float3 lc0 = a.c0, lc1 = a.c1, lc2 = a.c2, rc0 = b.c0, rc1 = b.c1, rc2 = b.c2; 56 | a.c0 = lc0 * rc0.xxx() + lc1 * rc0.yyy() + lc2 * rc0.zzz(); 57 | a.c1 = lc0 * rc1.xxx() + lc1 * rc1.yyy() + lc2 * rc1.zzz(); 58 | a.c2 = lc0 * rc2.xxx() + lc1 * rc2.yyy() + lc2 * rc2.zzz(); 59 | return a; 60 | } 61 | HLML_INLINEF float3x3 operator* (float3x3 a, f32 s) { a.c0 *= s; a.c1 *= s; a.c2 *= s; return a; } 62 | HLML_INLINEF float3x3 operator* (f32 s, float3x3 a) { return a * s; } 63 | HLML_INLINEF float3 operator* (float3x3 a, float3 v) { return v.xxx() * a.c0 + v.yyy() * a.c1 + v.zzz() * a.c2; } 64 | HLML_INLINEF float3 operator* (float3 v, float3x3 a) { 65 | float3 xxx(dotv(v, a.c0)), yyy(dotv(v, a.c1)), zzz(dotv(v, a.c2)); 66 | float3 xyxy(funcs::axbxayby(xxx.m, yyy.m)), xyz0(funcs::bzbwazaw(zzz.m, xyxy.m)); 67 | return xyz0; 68 | } 69 | HLML_INLINEF float3x3& operator*= (float3x3& a, float3x3 b) { a = a * b; return a; } 70 | HLML_INLINEF float3x3& operator*= (float3x3& a, f32 s) { a = a * s; return a; } 71 | } -------------------------------------------------------------------------------- /float4.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "float3.hpp" 4 | #include "bool4.hpp" 5 | #include "int4.hpp" 6 | 7 | namespace hlml { 8 | struct float4 { 9 | 10 | VF128 m = { 0 }; 11 | 12 | HLML_INLINEF float4() {} 13 | HLML_INLINEF float4(f32 x, f32 y, f32 z, f32 w) : m(funcs::setXYZW(x, y, z, w)) {} 14 | HLML_INLINEF float4(float2 v, f32 z, f32 w) : float4(v.x(), v.y(), z, w) {} 15 | HLML_INLINEF float4(float3 v, f32 w) : float4(v.x(), v.y(), v.z(), w) {} 16 | HLML_INLINEF explicit float4(f32 x) : float4(x, x, x, x) {} 17 | HLML_INLINEF explicit float4(float2 v) : m(v.m) {} 18 | HLML_INLINEF explicit float4(float2 v, float2 u) : float4(v.x(), v.y(), u.x(), u.y()) {} 19 | HLML_INLINEF explicit float4(float3 v) : m(v.m) {} 20 | HLML_INLINEF explicit float4(const f32 *p) : float4(p[0], p[1], p[2], p[3]) {} 21 | HLML_INLINEF explicit float4(VF128 v) : m(v) {} 22 | HLML_INLINEF float4 float4i(i32 x, i32 y, i32 z, i32 w) { return float4((f32)x, (f32)y, (f32)z, (f32)w); } 23 | 24 | HLML_INLINEF void store(f32 *p) const { p[0] = x(); p[1] = y(); p[2] = z(); p[3] = w(); } 25 | 26 | HLML_INLINEF void setX(f32 x) { m = insertf(m, x, 0); } 27 | HLML_INLINEF void setY(f32 y) { m = insertf(m, y, 1); } 28 | HLML_INLINEF void setZ(f32 z) { m = insertf(m, z, 2); } 29 | HLML_INLINEF void setW(f32 w) { m = insertf(m, w, 3); } 30 | 31 | HLML_INLINEF f32 x() const { uiasf res(extractf(m, 0)); return res.asf32; } 32 | HLML_INLINEF f32 y() const { uiasf res(extractf(m, 1)); return res.asf32; } 33 | HLML_INLINEF f32 z() const { uiasf res(extractf(m, 2)); return res.asf32; } 34 | HLML_INLINEF f32 w() const { uiasf res(extractf(m, 3)); return res.asf32; } 35 | 36 | HLML_INLINEF float2 xx() const { return shufflef4tof2(*this, 0, 0); } 37 | HLML_INLINEF float2 xy() const { return shufflef4tof2(*this, 0, 1); } 38 | HLML_INLINEF float2 xz() const { return shufflef4tof2(*this, 0, 2); } 39 | HLML_INLINEF float2 xw() const { return shufflef4tof2(*this, 0, 3); } 40 | HLML_INLINEF float2 yy() const { return shufflef4tof2(*this, 1, 1); } 41 | HLML_INLINEF float2 yx() const { return shufflef4tof2(*this, 1, 0); } 42 | HLML_INLINEF float2 yz() const { return shufflef4tof2(*this, 1, 2); } 43 | HLML_INLINEF float2 yw() const { return shufflef4tof2(*this, 1, 3); } 44 | HLML_INLINEF float2 zz() const { return shufflef4tof2(*this, 2, 2); } 45 | HLML_INLINEF float2 zx() const { return shufflef4tof2(*this, 2, 0); } 46 | HLML_INLINEF float2 zy() const { return shufflef4tof2(*this, 2, 1); } 47 | HLML_INLINEF float2 zw() const { return shufflef4tof2(*this, 2, 3); } 48 | HLML_INLINEF float2 ww() const { return shufflef4tof2(*this, 3, 3); } 49 | HLML_INLINEF float2 wx() const { return shufflef4tof2(*this, 3, 0); } 50 | HLML_INLINEF float2 wy() const { return shufflef4tof2(*this, 3, 1); } 51 | HLML_INLINEF float2 wz() const { return shufflef4tof2(*this, 3, 2); } 52 | 53 | HLML_INLINEF float3 xxx() const { return shufflef4tof3(*this, 0, 0, 0); } 54 | HLML_INLINEF float3 xxy() const { return shufflef4tof3(*this, 0, 0, 1); } 55 | HLML_INLINEF float3 xxz() const { return shufflef4tof3(*this, 0, 0, 2); } 56 | HLML_INLINEF float3 xxw() const { return shufflef4tof3(*this, 0, 0, 3); } 57 | HLML_INLINEF float3 xyx() const { return shufflef4tof3(*this, 0, 1, 0); } 58 | HLML_INLINEF float3 xyy() const { return shufflef4tof3(*this, 0, 1, 1); } 59 | HLML_INLINEF float3 xyz() const { return shufflef4tof3(*this, 0, 1, 2); } 60 | HLML_INLINEF float3 xyw() const { return shufflef4tof3(*this, 0, 1, 3); } 61 | HLML_INLINEF float3 xzx() const { return shufflef4tof3(*this, 0, 2, 0); } 62 | HLML_INLINEF float3 xzy() const { return shufflef4tof3(*this, 0, 2, 1); } 63 | HLML_INLINEF float3 xzz() const { return shufflef4tof3(*this, 0, 2, 2); } 64 | HLML_INLINEF float3 xzw() const { return shufflef4tof3(*this, 0, 2, 3); } 65 | HLML_INLINEF float3 xwx() const { return shufflef4tof3(*this, 0, 3, 0); } 66 | HLML_INLINEF float3 xwy() const { return shufflef4tof3(*this, 0, 3, 1); } 67 | HLML_INLINEF float3 xwz() const { return shufflef4tof3(*this, 0, 3, 2); } 68 | HLML_INLINEF float3 xww() const { return shufflef4tof3(*this, 0, 3, 3); } 69 | 70 | HLML_INLINEF float3 yxx() const { return shufflef4tof3(*this, 1, 0, 0); } 71 | HLML_INLINEF float3 yxy() const { return shufflef4tof3(*this, 1, 0, 1); } 72 | HLML_INLINEF float3 yxz() const { return shufflef4tof3(*this, 1, 0, 2); } 73 | HLML_INLINEF float3 yxw() const { return shufflef4tof3(*this, 1, 0, 3); } 74 | HLML_INLINEF float3 yyx() const { return shufflef4tof3(*this, 1, 1, 0); } 75 | HLML_INLINEF float3 yyy() const { return shufflef4tof3(*this, 1, 1, 1); } 76 | HLML_INLINEF float3 yyz() const { return shufflef4tof3(*this, 1, 1, 2); } 77 | HLML_INLINEF float3 yyw() const { return shufflef4tof3(*this, 1, 1, 3); } 78 | HLML_INLINEF float3 yzx() const { return shufflef4tof3(*this, 1, 2, 0); } 79 | HLML_INLINEF float3 yzy() const { return shufflef4tof3(*this, 1, 2, 1); } 80 | HLML_INLINEF float3 yzz() const { return shufflef4tof3(*this, 1, 2, 2); } 81 | HLML_INLINEF float3 yzw() const { return shufflef4tof3(*this, 1, 2, 3); } 82 | HLML_INLINEF float3 ywx() const { return shufflef4tof3(*this, 1, 3, 0); } 83 | HLML_INLINEF float3 ywy() const { return shufflef4tof3(*this, 1, 3, 1); } 84 | HLML_INLINEF float3 ywz() const { return shufflef4tof3(*this, 1, 3, 2); } 85 | HLML_INLINEF float3 yww() const { return shufflef4tof3(*this, 1, 3, 3); } 86 | 87 | HLML_INLINEF float3 zxx() const { return shufflef4tof3(*this, 2, 0, 0); } 88 | HLML_INLINEF float3 zxy() const { return shufflef4tof3(*this, 2, 0, 1); } 89 | HLML_INLINEF float3 zxz() const { return shufflef4tof3(*this, 2, 0, 2); } 90 | HLML_INLINEF float3 zxw() const { return shufflef4tof3(*this, 2, 0, 3); } 91 | HLML_INLINEF float3 zyx() const { return shufflef4tof3(*this, 2, 1, 0); } 92 | HLML_INLINEF float3 zyy() const { return shufflef4tof3(*this, 2, 1, 1); } 93 | HLML_INLINEF float3 zyz() const { return shufflef4tof3(*this, 2, 1, 2); } 94 | HLML_INLINEF float3 zyw() const { return shufflef4tof3(*this, 2, 1, 3); } 95 | HLML_INLINEF float3 zzx() const { return shufflef4tof3(*this, 2, 2, 0); } 96 | HLML_INLINEF float3 zzy() const { return shufflef4tof3(*this, 2, 2, 1); } 97 | HLML_INLINEF float3 zzz() const { return shufflef4tof3(*this, 2, 2, 2); } 98 | HLML_INLINEF float3 zzw() const { return shufflef4tof3(*this, 2, 2, 3); } 99 | HLML_INLINEF float3 zwx() const { return shufflef4tof3(*this, 2, 3, 0); } 100 | HLML_INLINEF float3 zwy() const { return shufflef4tof3(*this, 2, 3, 1); } 101 | HLML_INLINEF float3 zwz() const { return shufflef4tof3(*this, 2, 3, 2); } 102 | HLML_INLINEF float3 zww() const { return shufflef4tof3(*this, 2, 3, 3); } 103 | 104 | HLML_INLINEF float3 wxx() const { return shufflef4tof3(*this, 3, 0, 0); } 105 | HLML_INLINEF float3 wxy() const { return shufflef4tof3(*this, 3, 0, 1); } 106 | HLML_INLINEF float3 wxz() const { return shufflef4tof3(*this, 3, 0, 2); } 107 | HLML_INLINEF float3 wxw() const { return shufflef4tof3(*this, 3, 0, 3); } 108 | HLML_INLINEF float3 wyx() const { return shufflef4tof3(*this, 3, 1, 0); } 109 | HLML_INLINEF float3 wyy() const { return shufflef4tof3(*this, 3, 1, 1); } 110 | HLML_INLINEF float3 wyz() const { return shufflef4tof3(*this, 3, 1, 2); } 111 | HLML_INLINEF float3 wyw() const { return shufflef4tof3(*this, 3, 1, 3); } 112 | HLML_INLINEF float3 wzx() const { return shufflef4tof3(*this, 3, 2, 0); } 113 | HLML_INLINEF float3 wzy() const { return shufflef4tof3(*this, 3, 2, 1); } 114 | HLML_INLINEF float3 wzz() const { return shufflef4tof3(*this, 3, 2, 2); } 115 | HLML_INLINEF float3 wzw() const { return shufflef4tof3(*this, 3, 2, 3); } 116 | HLML_INLINEF float3 wwx() const { return shufflef4tof3(*this, 3, 3, 0); } 117 | HLML_INLINEF float3 wwy() const { return shufflef4tof3(*this, 3, 3, 1); } 118 | HLML_INLINEF float3 wwz() const { return shufflef4tof3(*this, 3, 3, 2); } 119 | HLML_INLINEF float3 www() const { return shufflef4tof3(*this, 3, 3, 3); } 120 | 121 | HLML_INLINEF float4 xxxx() const { return shufflef4(*this, 0, 0, 0, 0); } 122 | HLML_INLINEF float4 xxxy() const { return shufflef4(*this, 0, 0, 0, 1); } 123 | HLML_INLINEF float4 xxxz() const { return shufflef4(*this, 0, 0, 0, 2); } 124 | HLML_INLINEF float4 xxxw() const { return shufflef4(*this, 0, 0, 0, 3); } 125 | HLML_INLINEF float4 xxyx() const { return shufflef4(*this, 0, 0, 1, 0); } 126 | HLML_INLINEF float4 xxyy() const { return shufflef4(*this, 0, 0, 1, 1); } 127 | HLML_INLINEF float4 xxyz() const { return shufflef4(*this, 0, 0, 1, 2); } 128 | HLML_INLINEF float4 xxyw() const { return shufflef4(*this, 0, 0, 1, 3); } 129 | HLML_INLINEF float4 xxzx() const { return shufflef4(*this, 0, 0, 2, 0); } 130 | HLML_INLINEF float4 xxzy() const { return shufflef4(*this, 0, 0, 2, 1); } 131 | HLML_INLINEF float4 xxzz() const { return shufflef4(*this, 0, 0, 2, 2); } 132 | HLML_INLINEF float4 xxzw() const { return shufflef4(*this, 0, 0, 2, 3); } 133 | HLML_INLINEF float4 xxwx() const { return shufflef4(*this, 0, 0, 3, 0); } 134 | HLML_INLINEF float4 xxwy() const { return shufflef4(*this, 0, 0, 3, 1); } 135 | HLML_INLINEF float4 xxwz() const { return shufflef4(*this, 0, 0, 3, 2); } 136 | HLML_INLINEF float4 xxww() const { return shufflef4(*this, 0, 0, 3, 3); } 137 | HLML_INLINEF float4 xyxx() const { return shufflef4(*this, 0, 1, 0, 0); } 138 | HLML_INLINEF float4 xyxy() const { return shufflef4(*this, 0, 1, 0, 1); } 139 | HLML_INLINEF float4 xyxz() const { return shufflef4(*this, 0, 1, 0, 2); } 140 | HLML_INLINEF float4 xyxw() const { return shufflef4(*this, 0, 1, 0, 3); } 141 | HLML_INLINEF float4 xyyx() const { return shufflef4(*this, 0, 1, 1, 0); } 142 | HLML_INLINEF float4 xyyy() const { return shufflef4(*this, 0, 1, 1, 1); } 143 | HLML_INLINEF float4 xyyz() const { return shufflef4(*this, 0, 1, 1, 2); } 144 | HLML_INLINEF float4 xyyw() const { return shufflef4(*this, 0, 1, 1, 3); } 145 | HLML_INLINEF float4 xyzx() const { return shufflef4(*this, 0, 1, 2, 0); } 146 | HLML_INLINEF float4 xyzy() const { return shufflef4(*this, 0, 1, 2, 1); } 147 | HLML_INLINEF float4 xyzz() const { return shufflef4(*this, 0, 1, 2, 2); } 148 | HLML_INLINEF float4 xyzw() const { return *this; } 149 | HLML_INLINEF float4 xywx() const { return shufflef4(*this, 0, 1, 3, 0); } 150 | HLML_INLINEF float4 xywy() const { return shufflef4(*this, 0, 1, 3, 1); } 151 | HLML_INLINEF float4 xywz() const { return shufflef4(*this, 0, 1, 3, 2); } 152 | HLML_INLINEF float4 xyww() const { return shufflef4(*this, 0, 1, 3, 3); } 153 | HLML_INLINEF float4 xzxx() const { return shufflef4(*this, 0, 2, 0, 0); } 154 | HLML_INLINEF float4 xzxy() const { return shufflef4(*this, 0, 2, 0, 1); } 155 | HLML_INLINEF float4 xzxz() const { return shufflef4(*this, 0, 2, 0, 2); } 156 | HLML_INLINEF float4 xzxw() const { return shufflef4(*this, 0, 2, 0, 3); } 157 | HLML_INLINEF float4 xzyx() const { return shufflef4(*this, 0, 2, 1, 0); } 158 | HLML_INLINEF float4 xzyy() const { return shufflef4(*this, 0, 2, 1, 1); } 159 | HLML_INLINEF float4 xzyz() const { return shufflef4(*this, 0, 2, 1, 2); } 160 | HLML_INLINEF float4 xzyw() const { return shufflef4(*this, 0, 2, 1, 3); } 161 | HLML_INLINEF float4 xzzx() const { return shufflef4(*this, 0, 2, 2, 0); } 162 | HLML_INLINEF float4 xzzy() const { return shufflef4(*this, 0, 2, 2, 1); } 163 | HLML_INLINEF float4 xzzz() const { return shufflef4(*this, 0, 2, 2, 2); } 164 | HLML_INLINEF float4 xzzw() const { return shufflef4(*this, 0, 2, 2, 3); } 165 | HLML_INLINEF float4 xzwx() const { return shufflef4(*this, 0, 2, 3, 0); } 166 | HLML_INLINEF float4 xzwy() const { return shufflef4(*this, 0, 2, 3, 1); } 167 | HLML_INLINEF float4 xzwz() const { return shufflef4(*this, 0, 2, 3, 2); } 168 | HLML_INLINEF float4 xzww() const { return shufflef4(*this, 0, 2, 3, 3); } 169 | HLML_INLINEF float4 xwxx() const { return shufflef4(*this, 0, 3, 0, 0); } 170 | HLML_INLINEF float4 xwxy() const { return shufflef4(*this, 0, 3, 0, 1); } 171 | HLML_INLINEF float4 xwxz() const { return shufflef4(*this, 0, 3, 0, 2); } 172 | HLML_INLINEF float4 xwxw() const { return shufflef4(*this, 0, 3, 0, 3); } 173 | HLML_INLINEF float4 xwyx() const { return shufflef4(*this, 0, 3, 1, 0); } 174 | HLML_INLINEF float4 xwyy() const { return shufflef4(*this, 0, 3, 1, 1); } 175 | HLML_INLINEF float4 xwyz() const { return shufflef4(*this, 0, 3, 1, 2); } 176 | HLML_INLINEF float4 xwyw() const { return shufflef4(*this, 0, 3, 1, 3); } 177 | HLML_INLINEF float4 xwzx() const { return shufflef4(*this, 0, 3, 2, 0); } 178 | HLML_INLINEF float4 xwzy() const { return shufflef4(*this, 0, 3, 2, 1); } 179 | HLML_INLINEF float4 xwzz() const { return shufflef4(*this, 0, 3, 2, 2); } 180 | HLML_INLINEF float4 xwzw() const { return shufflef4(*this, 0, 3, 2, 3); } 181 | HLML_INLINEF float4 xwwx() const { return shufflef4(*this, 0, 3, 3, 0); } 182 | HLML_INLINEF float4 xwwy() const { return shufflef4(*this, 0, 3, 3, 1); } 183 | HLML_INLINEF float4 xwwz() const { return shufflef4(*this, 0, 3, 3, 2); } 184 | HLML_INLINEF float4 xwww() const { return shufflef4(*this, 0, 3, 3, 3); } 185 | 186 | HLML_INLINEF float4 yxxx() const { return shufflef4(*this, 1, 0, 0, 0); } 187 | HLML_INLINEF float4 yxxy() const { return shufflef4(*this, 1, 0, 0, 1); } 188 | HLML_INLINEF float4 yxxz() const { return shufflef4(*this, 1, 0, 0, 2); } 189 | HLML_INLINEF float4 yxxw() const { return shufflef4(*this, 1, 0, 0, 3); } 190 | HLML_INLINEF float4 yxyx() const { return shufflef4(*this, 1, 0, 1, 0); } 191 | HLML_INLINEF float4 yxyy() const { return shufflef4(*this, 1, 0, 1, 1); } 192 | HLML_INLINEF float4 yxyz() const { return shufflef4(*this, 1, 0, 1, 2); } 193 | HLML_INLINEF float4 yxyw() const { return shufflef4(*this, 1, 0, 1, 3); } 194 | HLML_INLINEF float4 yxzx() const { return shufflef4(*this, 1, 0, 2, 0); } 195 | HLML_INLINEF float4 yxzy() const { return shufflef4(*this, 1, 0, 2, 1); } 196 | HLML_INLINEF float4 yxzz() const { return shufflef4(*this, 1, 0, 2, 2); } 197 | HLML_INLINEF float4 yxzw() const { return shufflef4(*this, 1, 0, 2, 3); } 198 | HLML_INLINEF float4 yxwx() const { return shufflef4(*this, 1, 0, 3, 0); } 199 | HLML_INLINEF float4 yxwy() const { return shufflef4(*this, 1, 0, 3, 1); } 200 | HLML_INLINEF float4 yxwz() const { return shufflef4(*this, 1, 0, 3, 2); } 201 | HLML_INLINEF float4 yxww() const { return shufflef4(*this, 1, 0, 3, 3); } 202 | HLML_INLINEF float4 yyxx() const { return shufflef4(*this, 1, 1, 0, 0); } 203 | HLML_INLINEF float4 yyxy() const { return shufflef4(*this, 1, 1, 0, 1); } 204 | HLML_INLINEF float4 yyxz() const { return shufflef4(*this, 1, 1, 0, 2); } 205 | HLML_INLINEF float4 yyxw() const { return shufflef4(*this, 1, 1, 0, 3); } 206 | HLML_INLINEF float4 yyyx() const { return shufflef4(*this, 1, 1, 1, 0); } 207 | HLML_INLINEF float4 yyyy() const { return shufflef4(*this, 1, 1, 1, 1); } 208 | HLML_INLINEF float4 yyyz() const { return shufflef4(*this, 1, 1, 1, 2); } 209 | HLML_INLINEF float4 yyyw() const { return shufflef4(*this, 1, 1, 1, 3); } 210 | HLML_INLINEF float4 yyzx() const { return shufflef4(*this, 1, 1, 2, 0); } 211 | HLML_INLINEF float4 yyzy() const { return shufflef4(*this, 1, 1, 2, 1); } 212 | HLML_INLINEF float4 yyzz() const { return shufflef4(*this, 1, 1, 2, 2); } 213 | HLML_INLINEF float4 yyzw() const { return shufflef4(*this, 1, 1, 2, 3); } 214 | HLML_INLINEF float4 yywx() const { return shufflef4(*this, 1, 1, 3, 0); } 215 | HLML_INLINEF float4 yywy() const { return shufflef4(*this, 1, 1, 3, 1); } 216 | HLML_INLINEF float4 yywz() const { return shufflef4(*this, 1, 1, 3, 2); } 217 | HLML_INLINEF float4 yyww() const { return shufflef4(*this, 1, 1, 3, 3); } 218 | HLML_INLINEF float4 yzxx() const { return shufflef4(*this, 1, 2, 0, 0); } 219 | HLML_INLINEF float4 yzxy() const { return shufflef4(*this, 1, 2, 0, 1); } 220 | HLML_INLINEF float4 yzxz() const { return shufflef4(*this, 1, 2, 0, 2); } 221 | HLML_INLINEF float4 yzxw() const { return shufflef4(*this, 1, 2, 0, 3); } 222 | HLML_INLINEF float4 yzyx() const { return shufflef4(*this, 1, 2, 1, 0); } 223 | HLML_INLINEF float4 yzyy() const { return shufflef4(*this, 1, 2, 1, 1); } 224 | HLML_INLINEF float4 yzyz() const { return shufflef4(*this, 1, 2, 1, 2); } 225 | HLML_INLINEF float4 yzyw() const { return shufflef4(*this, 1, 2, 1, 3); } 226 | HLML_INLINEF float4 yzzx() const { return shufflef4(*this, 1, 2, 2, 0); } 227 | HLML_INLINEF float4 yzzy() const { return shufflef4(*this, 1, 2, 2, 1); } 228 | HLML_INLINEF float4 yzzz() const { return shufflef4(*this, 1, 2, 2, 2); } 229 | HLML_INLINEF float4 yzzw() const { return shufflef4(*this, 1, 2, 2, 3); } 230 | HLML_INLINEF float4 yzwx() const { return shufflef4(*this, 1, 2, 3, 0); } 231 | HLML_INLINEF float4 yzwy() const { return shufflef4(*this, 1, 2, 3, 1); } 232 | HLML_INLINEF float4 yzwz() const { return shufflef4(*this, 1, 2, 3, 2); } 233 | HLML_INLINEF float4 yzww() const { return shufflef4(*this, 1, 2, 3, 3); } 234 | HLML_INLINEF float4 ywxx() const { return shufflef4(*this, 1, 3, 0, 0); } 235 | HLML_INLINEF float4 ywxy() const { return shufflef4(*this, 1, 3, 0, 1); } 236 | HLML_INLINEF float4 ywxz() const { return shufflef4(*this, 1, 3, 0, 2); } 237 | HLML_INLINEF float4 ywxw() const { return shufflef4(*this, 1, 3, 0, 3); } 238 | HLML_INLINEF float4 ywyx() const { return shufflef4(*this, 1, 3, 1, 0); } 239 | HLML_INLINEF float4 ywyy() const { return shufflef4(*this, 1, 3, 1, 1); } 240 | HLML_INLINEF float4 ywyz() const { return shufflef4(*this, 1, 3, 1, 2); } 241 | HLML_INLINEF float4 ywyw() const { return shufflef4(*this, 1, 3, 1, 3); } 242 | HLML_INLINEF float4 ywzx() const { return shufflef4(*this, 1, 3, 2, 0); } 243 | HLML_INLINEF float4 ywzy() const { return shufflef4(*this, 1, 3, 2, 1); } 244 | HLML_INLINEF float4 ywzz() const { return shufflef4(*this, 1, 3, 2, 2); } 245 | HLML_INLINEF float4 ywzw() const { return shufflef4(*this, 1, 3, 2, 3); } 246 | HLML_INLINEF float4 ywwx() const { return shufflef4(*this, 1, 3, 3, 0); } 247 | HLML_INLINEF float4 ywwy() const { return shufflef4(*this, 1, 3, 3, 1); } 248 | HLML_INLINEF float4 ywwz() const { return shufflef4(*this, 1, 3, 3, 2); } 249 | HLML_INLINEF float4 ywww() const { return shufflef4(*this, 1, 3, 3, 3); } 250 | 251 | HLML_INLINEF float4 zxxx() const { return shufflef4(*this, 2, 0, 0, 0); } 252 | HLML_INLINEF float4 zxxy() const { return shufflef4(*this, 2, 0, 0, 1); } 253 | HLML_INLINEF float4 zxxz() const { return shufflef4(*this, 2, 0, 0, 2); } 254 | HLML_INLINEF float4 zxxw() const { return shufflef4(*this, 2, 0, 0, 3); } 255 | HLML_INLINEF float4 zxyx() const { return shufflef4(*this, 2, 0, 1, 0); } 256 | HLML_INLINEF float4 zxyy() const { return shufflef4(*this, 2, 0, 1, 1); } 257 | HLML_INLINEF float4 zxyz() const { return shufflef4(*this, 2, 0, 1, 2); } 258 | HLML_INLINEF float4 zxyw() const { return shufflef4(*this, 2, 0, 1, 3); } 259 | HLML_INLINEF float4 zxzx() const { return shufflef4(*this, 2, 0, 2, 0); } 260 | HLML_INLINEF float4 zxzy() const { return shufflef4(*this, 2, 0, 2, 1); } 261 | HLML_INLINEF float4 zxzz() const { return shufflef4(*this, 2, 0, 2, 2); } 262 | HLML_INLINEF float4 zxzw() const { return shufflef4(*this, 2, 0, 2, 3); } 263 | HLML_INLINEF float4 zxwx() const { return shufflef4(*this, 2, 0, 3, 0); } 264 | HLML_INLINEF float4 zxwy() const { return shufflef4(*this, 2, 0, 3, 1); } 265 | HLML_INLINEF float4 zxwz() const { return shufflef4(*this, 2, 0, 3, 2); } 266 | HLML_INLINEF float4 zxww() const { return shufflef4(*this, 2, 0, 3, 3); } 267 | HLML_INLINEF float4 zyxx() const { return shufflef4(*this, 2, 1, 0, 0); } 268 | HLML_INLINEF float4 zyxy() const { return shufflef4(*this, 2, 1, 0, 1); } 269 | HLML_INLINEF float4 zyxz() const { return shufflef4(*this, 2, 1, 0, 2); } 270 | HLML_INLINEF float4 zyxw() const { return shufflef4(*this, 2, 1, 0, 3); } 271 | HLML_INLINEF float4 zyyx() const { return shufflef4(*this, 2, 1, 1, 0); } 272 | HLML_INLINEF float4 zyyy() const { return shufflef4(*this, 2, 1, 1, 1); } 273 | HLML_INLINEF float4 zyyz() const { return shufflef4(*this, 2, 1, 1, 2); } 274 | HLML_INLINEF float4 zyyw() const { return shufflef4(*this, 2, 1, 1, 3); } 275 | HLML_INLINEF float4 zyzx() const { return shufflef4(*this, 2, 1, 2, 0); } 276 | HLML_INLINEF float4 zyzy() const { return shufflef4(*this, 2, 1, 2, 1); } 277 | HLML_INLINEF float4 zyzz() const { return shufflef4(*this, 2, 1, 2, 2); } 278 | HLML_INLINEF float4 zyzw() const { return shufflef4(*this, 2, 1, 2, 3); } 279 | HLML_INLINEF float4 zywx() const { return shufflef4(*this, 2, 1, 3, 0); } 280 | HLML_INLINEF float4 zywy() const { return shufflef4(*this, 2, 1, 3, 1); } 281 | HLML_INLINEF float4 zywz() const { return shufflef4(*this, 2, 1, 3, 2); } 282 | HLML_INLINEF float4 zyww() const { return shufflef4(*this, 2, 1, 3, 3); } 283 | HLML_INLINEF float4 zzxx() const { return shufflef4(*this, 2, 2, 0, 0); } 284 | HLML_INLINEF float4 zzxy() const { return shufflef4(*this, 2, 2, 0, 1); } 285 | HLML_INLINEF float4 zzxz() const { return shufflef4(*this, 2, 2, 0, 2); } 286 | HLML_INLINEF float4 zzxw() const { return shufflef4(*this, 2, 2, 0, 3); } 287 | HLML_INLINEF float4 zzyx() const { return shufflef4(*this, 2, 2, 1, 0); } 288 | HLML_INLINEF float4 zzyy() const { return shufflef4(*this, 2, 2, 1, 1); } 289 | HLML_INLINEF float4 zzyz() const { return shufflef4(*this, 2, 2, 1, 2); } 290 | HLML_INLINEF float4 zzyw() const { return shufflef4(*this, 2, 2, 1, 3); } 291 | HLML_INLINEF float4 zzzx() const { return shufflef4(*this, 2, 2, 2, 0); } 292 | HLML_INLINEF float4 zzzy() const { return shufflef4(*this, 2, 2, 2, 1); } 293 | HLML_INLINEF float4 zzzz() const { return shufflef4(*this, 2, 2, 2, 2); } 294 | HLML_INLINEF float4 zzzw() const { return shufflef4(*this, 2, 2, 2, 3); } 295 | HLML_INLINEF float4 zzwx() const { return shufflef4(*this, 2, 2, 3, 0); } 296 | HLML_INLINEF float4 zzwy() const { return shufflef4(*this, 2, 2, 3, 1); } 297 | HLML_INLINEF float4 zzwz() const { return shufflef4(*this, 2, 2, 3, 2); } 298 | HLML_INLINEF float4 zzww() const { return shufflef4(*this, 2, 2, 3, 3); } 299 | HLML_INLINEF float4 zwxx() const { return shufflef4(*this, 2, 3, 0, 0); } 300 | HLML_INLINEF float4 zwxy() const { return shufflef4(*this, 2, 3, 0, 1); } 301 | HLML_INLINEF float4 zwxz() const { return shufflef4(*this, 2, 3, 0, 2); } 302 | HLML_INLINEF float4 zwxw() const { return shufflef4(*this, 2, 3, 0, 3); } 303 | HLML_INLINEF float4 zwyx() const { return shufflef4(*this, 2, 3, 1, 0); } 304 | HLML_INLINEF float4 zwyy() const { return shufflef4(*this, 2, 3, 1, 1); } 305 | HLML_INLINEF float4 zwyz() const { return shufflef4(*this, 2, 3, 1, 2); } 306 | HLML_INLINEF float4 zwyw() const { return shufflef4(*this, 2, 3, 1, 3); } 307 | HLML_INLINEF float4 zwzx() const { return shufflef4(*this, 2, 3, 2, 0); } 308 | HLML_INLINEF float4 zwzy() const { return shufflef4(*this, 2, 3, 2, 1); } 309 | HLML_INLINEF float4 zwzz() const { return shufflef4(*this, 2, 3, 2, 2); } 310 | HLML_INLINEF float4 zwzw() const { return shufflef4(*this, 2, 3, 2, 3); } 311 | HLML_INLINEF float4 zwwx() const { return shufflef4(*this, 2, 3, 3, 0); } 312 | HLML_INLINEF float4 zwwy() const { return shufflef4(*this, 2, 3, 3, 1); } 313 | HLML_INLINEF float4 zwwz() const { return shufflef4(*this, 2, 3, 3, 2); } 314 | HLML_INLINEF float4 zwww() const { return shufflef4(*this, 2, 3, 3, 3); } 315 | 316 | HLML_INLINEF float4 wxxx() const { return shufflef4(*this, 3, 0, 0, 0); } 317 | HLML_INLINEF float4 wxxy() const { return shufflef4(*this, 3, 0, 0, 1); } 318 | HLML_INLINEF float4 wxxz() const { return shufflef4(*this, 3, 0, 0, 2); } 319 | HLML_INLINEF float4 wxxw() const { return shufflef4(*this, 3, 0, 0, 3); } 320 | HLML_INLINEF float4 wxyx() const { return shufflef4(*this, 3, 0, 1, 0); } 321 | HLML_INLINEF float4 wxyy() const { return shufflef4(*this, 3, 0, 1, 1); } 322 | HLML_INLINEF float4 wxyz() const { return shufflef4(*this, 3, 0, 1, 2); } 323 | HLML_INLINEF float4 wxyw() const { return shufflef4(*this, 3, 0, 1, 3); } 324 | HLML_INLINEF float4 wxzx() const { return shufflef4(*this, 3, 0, 2, 0); } 325 | HLML_INLINEF float4 wxzy() const { return shufflef4(*this, 3, 0, 2, 1); } 326 | HLML_INLINEF float4 wxzz() const { return shufflef4(*this, 3, 0, 2, 2); } 327 | HLML_INLINEF float4 wxzw() const { return shufflef4(*this, 3, 0, 2, 3); } 328 | HLML_INLINEF float4 wxwx() const { return shufflef4(*this, 3, 0, 3, 0); } 329 | HLML_INLINEF float4 wxwy() const { return shufflef4(*this, 3, 0, 3, 1); } 330 | HLML_INLINEF float4 wxwz() const { return shufflef4(*this, 3, 0, 3, 2); } 331 | HLML_INLINEF float4 wxww() const { return shufflef4(*this, 3, 0, 3, 3); } 332 | HLML_INLINEF float4 wyxx() const { return shufflef4(*this, 3, 1, 0, 0); } 333 | HLML_INLINEF float4 wyxy() const { return shufflef4(*this, 3, 1, 0, 1); } 334 | HLML_INLINEF float4 wyxz() const { return shufflef4(*this, 3, 1, 0, 2); } 335 | HLML_INLINEF float4 wyxw() const { return shufflef4(*this, 3, 1, 0, 3); } 336 | HLML_INLINEF float4 wyyx() const { return shufflef4(*this, 3, 1, 1, 0); } 337 | HLML_INLINEF float4 wyyy() const { return shufflef4(*this, 3, 1, 1, 1); } 338 | HLML_INLINEF float4 wyyz() const { return shufflef4(*this, 3, 1, 1, 2); } 339 | HLML_INLINEF float4 wyyw() const { return shufflef4(*this, 3, 1, 1, 3); } 340 | HLML_INLINEF float4 wyzx() const { return shufflef4(*this, 3, 1, 2, 0); } 341 | HLML_INLINEF float4 wyzy() const { return shufflef4(*this, 3, 1, 2, 1); } 342 | HLML_INLINEF float4 wyzz() const { return shufflef4(*this, 3, 1, 2, 2); } 343 | HLML_INLINEF float4 wyzw() const { return shufflef4(*this, 3, 1, 2, 3); } 344 | HLML_INLINEF float4 wywx() const { return shufflef4(*this, 3, 1, 3, 0); } 345 | HLML_INLINEF float4 wywy() const { return shufflef4(*this, 3, 1, 3, 1); } 346 | HLML_INLINEF float4 wywz() const { return shufflef4(*this, 3, 1, 3, 2); } 347 | HLML_INLINEF float4 wyww() const { return shufflef4(*this, 3, 1, 3, 3); } 348 | HLML_INLINEF float4 wzxx() const { return shufflef4(*this, 3, 2, 0, 0); } 349 | HLML_INLINEF float4 wzxy() const { return shufflef4(*this, 3, 2, 0, 1); } 350 | HLML_INLINEF float4 wzxz() const { return shufflef4(*this, 3, 2, 0, 2); } 351 | HLML_INLINEF float4 wzxw() const { return shufflef4(*this, 3, 2, 0, 3); } 352 | HLML_INLINEF float4 wzyx() const { return shufflef4(*this, 3, 2, 1, 0); } 353 | HLML_INLINEF float4 wzyy() const { return shufflef4(*this, 3, 2, 1, 1); } 354 | HLML_INLINEF float4 wzyz() const { return shufflef4(*this, 3, 2, 1, 2); } 355 | HLML_INLINEF float4 wzyw() const { return shufflef4(*this, 3, 2, 1, 3); } 356 | HLML_INLINEF float4 wzzx() const { return shufflef4(*this, 3, 2, 2, 0); } 357 | HLML_INLINEF float4 wzzy() const { return shufflef4(*this, 3, 2, 2, 1); } 358 | HLML_INLINEF float4 wzzz() const { return shufflef4(*this, 3, 2, 2, 2); } 359 | HLML_INLINEF float4 wzzw() const { return shufflef4(*this, 3, 2, 2, 3); } 360 | HLML_INLINEF float4 wzwx() const { return shufflef4(*this, 3, 2, 3, 0); } 361 | HLML_INLINEF float4 wzwy() const { return shufflef4(*this, 3, 2, 3, 1); } 362 | HLML_INLINEF float4 wzwz() const { return shufflef4(*this, 3, 2, 3, 2); } 363 | HLML_INLINEF float4 wzww() const { return shufflef4(*this, 3, 2, 3, 3); } 364 | HLML_INLINEF float4 wwxx() const { return shufflef4(*this, 3, 3, 0, 0); } 365 | HLML_INLINEF float4 wwxy() const { return shufflef4(*this, 3, 3, 0, 1); } 366 | HLML_INLINEF float4 wwxz() const { return shufflef4(*this, 3, 3, 0, 2); } 367 | HLML_INLINEF float4 wwxw() const { return shufflef4(*this, 3, 3, 0, 3); } 368 | HLML_INLINEF float4 wwyx() const { return shufflef4(*this, 3, 3, 1, 0); } 369 | HLML_INLINEF float4 wwyy() const { return shufflef4(*this, 3, 3, 1, 1); } 370 | HLML_INLINEF float4 wwyz() const { return shufflef4(*this, 3, 3, 1, 2); } 371 | HLML_INLINEF float4 wwyw() const { return shufflef4(*this, 3, 3, 1, 3); } 372 | HLML_INLINEF float4 wwzx() const { return shufflef4(*this, 3, 3, 2, 0); } 373 | HLML_INLINEF float4 wwzy() const { return shufflef4(*this, 3, 3, 2, 1); } 374 | HLML_INLINEF float4 wwzz() const { return shufflef4(*this, 3, 3, 2, 2); } 375 | HLML_INLINEF float4 wwzw() const { return shufflef4(*this, 3, 3, 2, 3); } 376 | HLML_INLINEF float4 wwwx() const { return shufflef4(*this, 3, 3, 3, 0); } 377 | HLML_INLINEF float4 wwwy() const { return shufflef4(*this, 3, 3, 3, 1); } 378 | HLML_INLINEF float4 wwwz() const { return shufflef4(*this, 3, 3, 3, 2); } 379 | HLML_INLINEF float4 wwww() const { return shufflef4(*this, 3, 3, 3, 3); } 380 | 381 | HLML_INLINEF f32 r() const { return x(); } 382 | HLML_INLINEF f32 g() const { return y(); } 383 | HLML_INLINEF f32 b() const { return z(); } 384 | HLML_INLINEF f32 a() const { return w(); } 385 | 386 | HLML_INLINEF float2 rr() const { return xx(); } 387 | HLML_INLINEF float2 rg() const { return xy(); } 388 | HLML_INLINEF float2 rb() const { return xz(); } 389 | HLML_INLINEF float2 ra() const { return xw(); } 390 | HLML_INLINEF float2 gr() const { return yx(); } 391 | HLML_INLINEF float2 gg() const { return yy(); } 392 | HLML_INLINEF float2 gb() const { return yz(); } 393 | HLML_INLINEF float2 ga() const { return yw(); } 394 | HLML_INLINEF float2 br() const { return zx(); } 395 | HLML_INLINEF float2 bg() const { return zy(); } 396 | HLML_INLINEF float2 bb() const { return zz(); } 397 | HLML_INLINEF float2 ba() const { return zw(); } 398 | HLML_INLINEF float2 ar() const { return wx(); } 399 | HLML_INLINEF float2 ag() const { return wy(); } 400 | HLML_INLINEF float2 ab() const { return wz(); } 401 | HLML_INLINEF float2 aa() const { return ww(); } 402 | 403 | HLML_INLINEF float3 rrr() const { return xxx(); } 404 | HLML_INLINEF float3 rrg() const { return xxy(); } 405 | HLML_INLINEF float3 rrb() const { return xxz(); } 406 | HLML_INLINEF float3 rra() const { return xxw(); } 407 | HLML_INLINEF float3 rgr() const { return xyx(); } 408 | HLML_INLINEF float3 rgg() const { return xyy(); } 409 | HLML_INLINEF float3 rgb() const { return xyz(); } 410 | HLML_INLINEF float3 rga() const { return xyw(); } 411 | HLML_INLINEF float3 rbr() const { return xzx(); } 412 | HLML_INLINEF float3 rbg() const { return xzy(); } 413 | HLML_INLINEF float3 rbb() const { return xzz(); } 414 | HLML_INLINEF float3 rba() const { return xzw(); } 415 | HLML_INLINEF float3 rar() const { return xwx(); } 416 | HLML_INLINEF float3 rag() const { return xwy(); } 417 | HLML_INLINEF float3 rab() const { return xwz(); } 418 | HLML_INLINEF float3 raa() const { return xww(); } 419 | HLML_INLINEF float3 grr() const { return yxx(); } 420 | HLML_INLINEF float3 grg() const { return yxy(); } 421 | HLML_INLINEF float3 grb() const { return yxz(); } 422 | HLML_INLINEF float3 gra() const { return yxw(); } 423 | HLML_INLINEF float3 ggr() const { return yyx(); } 424 | HLML_INLINEF float3 ggg() const { return yyy(); } 425 | HLML_INLINEF float3 ggb() const { return yyz(); } 426 | HLML_INLINEF float3 gga() const { return yyw(); } 427 | HLML_INLINEF float3 gbr() const { return yzx(); } 428 | HLML_INLINEF float3 gbg() const { return yzy(); } 429 | HLML_INLINEF float3 gbb() const { return yzz(); } 430 | HLML_INLINEF float3 gba() const { return yzw(); } 431 | HLML_INLINEF float3 gar() const { return ywx(); } 432 | HLML_INLINEF float3 gag() const { return ywy(); } 433 | HLML_INLINEF float3 gab() const { return ywz(); } 434 | HLML_INLINEF float3 gaa() const { return yww(); } 435 | HLML_INLINEF float3 brr() const { return zxx(); } 436 | HLML_INLINEF float3 brg() const { return zxy(); } 437 | HLML_INLINEF float3 brb() const { return zxz(); } 438 | HLML_INLINEF float3 bra() const { return zxw(); } 439 | HLML_INLINEF float3 bgr() const { return zyx(); } 440 | HLML_INLINEF float3 bgg() const { return zyy(); } 441 | HLML_INLINEF float3 bgb() const { return zyz(); } 442 | HLML_INLINEF float3 bga() const { return zyw(); } 443 | HLML_INLINEF float3 bbr() const { return zzx(); } 444 | HLML_INLINEF float3 bbg() const { return zzy(); } 445 | HLML_INLINEF float3 bbb() const { return zzz(); } 446 | HLML_INLINEF float3 bba() const { return zzw(); } 447 | HLML_INLINEF float3 bar() const { return zwx(); } 448 | HLML_INLINEF float3 bag() const { return zwy(); } 449 | HLML_INLINEF float3 bab() const { return zwz(); } 450 | HLML_INLINEF float3 baa() const { return zww(); } 451 | 452 | HLML_INLINEF float4 rrrr() const { return xxxx(); } 453 | HLML_INLINEF float4 rrrg() const { return xxxy(); } 454 | HLML_INLINEF float4 rrrb() const { return xxxz(); } 455 | HLML_INLINEF float4 rrra() const { return xxxw(); } 456 | HLML_INLINEF float4 rrgr() const { return xxyx(); } 457 | HLML_INLINEF float4 rrgg() const { return xxyy(); } 458 | HLML_INLINEF float4 rrgb() const { return xxyz(); } 459 | HLML_INLINEF float4 rrga() const { return xxyw(); } 460 | HLML_INLINEF float4 rrbr() const { return xxzx(); } 461 | HLML_INLINEF float4 rrbg() const { return xxzy(); } 462 | HLML_INLINEF float4 rrbb() const { return xxzz(); } 463 | HLML_INLINEF float4 rrba() const { return xxzw(); } 464 | HLML_INLINEF float4 rrar() const { return xxwx(); } 465 | HLML_INLINEF float4 rrag() const { return xxwy(); } 466 | HLML_INLINEF float4 rrab() const { return xxwz(); } 467 | HLML_INLINEF float4 rraa() const { return xxww(); } 468 | HLML_INLINEF float4 rgrr() const { return xyxx(); } 469 | HLML_INLINEF float4 rgrg() const { return xyxy(); } 470 | HLML_INLINEF float4 rgrb() const { return xyxz(); } 471 | HLML_INLINEF float4 rgra() const { return xyxy(); } 472 | HLML_INLINEF float4 rggr() const { return xyyx(); } 473 | HLML_INLINEF float4 rggg() const { return xyyy(); } 474 | HLML_INLINEF float4 rggb() const { return xyyz(); } 475 | HLML_INLINEF float4 rgga() const { return xyyw(); } 476 | HLML_INLINEF float4 rgbr() const { return xyzx(); } 477 | HLML_INLINEF float4 rgbg() const { return xyzy(); } 478 | HLML_INLINEF float4 rgbb() const { return xyzz(); } 479 | HLML_INLINEF float4 rgba() const { return xyzw(); } 480 | HLML_INLINEF float4 rgar() const { return xywx(); } 481 | HLML_INLINEF float4 rgag() const { return xywy(); } 482 | HLML_INLINEF float4 rgab() const { return xywz(); } 483 | HLML_INLINEF float4 rgaa() const { return xyww(); } 484 | HLML_INLINEF float4 rbrr() const { return xzxx(); } 485 | HLML_INLINEF float4 rbrg() const { return xzxy(); } 486 | HLML_INLINEF float4 rbrb() const { return xzxz(); } 487 | HLML_INLINEF float4 rbra() const { return xzxw(); } 488 | HLML_INLINEF float4 rbgr() const { return xzyx(); } 489 | HLML_INLINEF float4 rbgg() const { return xzyy(); } 490 | HLML_INLINEF float4 rbgb() const { return xzyz(); } 491 | HLML_INLINEF float4 rbga() const { return xzyw(); } 492 | HLML_INLINEF float4 rbbr() const { return xzzx(); } 493 | HLML_INLINEF float4 rbbg() const { return xzzy(); } 494 | HLML_INLINEF float4 rbbb() const { return xzzz(); } 495 | HLML_INLINEF float4 rbba() const { return xzzw(); } 496 | HLML_INLINEF float4 rbar() const { return xzwx(); } 497 | HLML_INLINEF float4 rbag() const { return xzwy(); } 498 | HLML_INLINEF float4 rbab() const { return xzwz(); } 499 | HLML_INLINEF float4 rbaa() const { return xzww(); } 500 | HLML_INLINEF float4 rarr() const { return xwxx(); } 501 | HLML_INLINEF float4 rarg() const { return xwxy(); } 502 | HLML_INLINEF float4 rarb() const { return xwxz(); } 503 | HLML_INLINEF float4 rara() const { return xwxw(); } 504 | HLML_INLINEF float4 ragr() const { return xwyx(); } 505 | HLML_INLINEF float4 ragg() const { return xwyy(); } 506 | HLML_INLINEF float4 ragb() const { return xwyz(); } 507 | HLML_INLINEF float4 raga() const { return xwyw(); } 508 | HLML_INLINEF float4 rabr() const { return xwzx(); } 509 | HLML_INLINEF float4 rabg() const { return xwzy(); } 510 | HLML_INLINEF float4 rabb() const { return xwzz(); } 511 | HLML_INLINEF float4 raba() const { return xwzw(); } 512 | HLML_INLINEF float4 raar() const { return xwwx(); } 513 | HLML_INLINEF float4 raag() const { return xwwy(); } 514 | HLML_INLINEF float4 raab() const { return xwwz(); } 515 | HLML_INLINEF float4 raaa() const { return xwww(); } 516 | 517 | HLML_INLINEF float4 grrr() const { return yxxx(); } 518 | HLML_INLINEF float4 grrg() const { return yxxy(); } 519 | HLML_INLINEF float4 grrb() const { return yxxz(); } 520 | HLML_INLINEF float4 grra() const { return yxxw(); } 521 | HLML_INLINEF float4 grgr() const { return yxyx(); } 522 | HLML_INLINEF float4 grgg() const { return yxyy(); } 523 | HLML_INLINEF float4 grgb() const { return yxyz(); } 524 | HLML_INLINEF float4 grga() const { return yxyw(); } 525 | HLML_INLINEF float4 grbr() const { return yxzx(); } 526 | HLML_INLINEF float4 grbg() const { return yxzy(); } 527 | HLML_INLINEF float4 grbb() const { return yxzz(); } 528 | HLML_INLINEF float4 grba() const { return yxzw(); } 529 | HLML_INLINEF float4 grar() const { return yxwx(); } 530 | HLML_INLINEF float4 grag() const { return yxwy(); } 531 | HLML_INLINEF float4 grab() const { return yxwz(); } 532 | HLML_INLINEF float4 graa() const { return yxww(); } 533 | HLML_INLINEF float4 ggrr() const { return yyxx(); } 534 | HLML_INLINEF float4 ggrg() const { return yyxy(); } 535 | HLML_INLINEF float4 ggrb() const { return yyxz(); } 536 | HLML_INLINEF float4 ggra() const { return yyxy(); } 537 | HLML_INLINEF float4 gggr() const { return yyyx(); } 538 | HLML_INLINEF float4 gggg() const { return yyyy(); } 539 | HLML_INLINEF float4 gggb() const { return yyyz(); } 540 | HLML_INLINEF float4 ggga() const { return yyyw(); } 541 | HLML_INLINEF float4 ggbr() const { return yyzx(); } 542 | HLML_INLINEF float4 ggbg() const { return yyzy(); } 543 | HLML_INLINEF float4 ggbb() const { return yyzz(); } 544 | HLML_INLINEF float4 ggba() const { return yyzw(); } 545 | HLML_INLINEF float4 ggar() const { return yywx(); } 546 | HLML_INLINEF float4 ggag() const { return yywy(); } 547 | HLML_INLINEF float4 ggab() const { return yywz(); } 548 | HLML_INLINEF float4 ggaa() const { return yyww(); } 549 | HLML_INLINEF float4 gbrr() const { return yzxx(); } 550 | HLML_INLINEF float4 gbrg() const { return yzxy(); } 551 | HLML_INLINEF float4 gbrb() const { return yzxz(); } 552 | HLML_INLINEF float4 gbra() const { return yzxw(); } 553 | HLML_INLINEF float4 gbgr() const { return yzyx(); } 554 | HLML_INLINEF float4 gbgg() const { return yzyy(); } 555 | HLML_INLINEF float4 gbgb() const { return yzyz(); } 556 | HLML_INLINEF float4 gbga() const { return yzyw(); } 557 | HLML_INLINEF float4 gbbr() const { return yzzx(); } 558 | HLML_INLINEF float4 gbbg() const { return yzzy(); } 559 | HLML_INLINEF float4 gbbb() const { return yzzz(); } 560 | HLML_INLINEF float4 gbba() const { return yzzw(); } 561 | HLML_INLINEF float4 gbar() const { return yzwx(); } 562 | HLML_INLINEF float4 gbag() const { return yzwy(); } 563 | HLML_INLINEF float4 gbab() const { return yzwz(); } 564 | HLML_INLINEF float4 gbaa() const { return yzww(); } 565 | HLML_INLINEF float4 garr() const { return ywxx(); } 566 | HLML_INLINEF float4 garg() const { return ywxy(); } 567 | HLML_INLINEF float4 garb() const { return ywxz(); } 568 | HLML_INLINEF float4 gara() const { return ywxw(); } 569 | HLML_INLINEF float4 gagr() const { return ywyx(); } 570 | HLML_INLINEF float4 gagg() const { return ywyy(); } 571 | HLML_INLINEF float4 gagb() const { return ywyz(); } 572 | HLML_INLINEF float4 gaga() const { return ywyw(); } 573 | HLML_INLINEF float4 gabr() const { return ywzx(); } 574 | HLML_INLINEF float4 gabg() const { return ywzy(); } 575 | HLML_INLINEF float4 gabb() const { return ywzz(); } 576 | HLML_INLINEF float4 gaba() const { return ywzw(); } 577 | HLML_INLINEF float4 gaar() const { return ywwx(); } 578 | HLML_INLINEF float4 gaag() const { return ywwy(); } 579 | HLML_INLINEF float4 gaab() const { return ywwz(); } 580 | HLML_INLINEF float4 gaaa() const { return ywww(); } 581 | 582 | HLML_INLINEF float4 brrr() const { return zxxx(); } 583 | HLML_INLINEF float4 brrg() const { return zxxy(); } 584 | HLML_INLINEF float4 brrb() const { return zxxz(); } 585 | HLML_INLINEF float4 brra() const { return zxxw(); } 586 | HLML_INLINEF float4 brgr() const { return zxyx(); } 587 | HLML_INLINEF float4 brgg() const { return zxyy(); } 588 | HLML_INLINEF float4 brgb() const { return zxyz(); } 589 | HLML_INLINEF float4 brga() const { return zxyw(); } 590 | HLML_INLINEF float4 brbr() const { return zxzx(); } 591 | HLML_INLINEF float4 brbg() const { return zxzy(); } 592 | HLML_INLINEF float4 brbb() const { return zxzz(); } 593 | HLML_INLINEF float4 brba() const { return zxzw(); } 594 | HLML_INLINEF float4 brar() const { return zxwx(); } 595 | HLML_INLINEF float4 brag() const { return zxwy(); } 596 | HLML_INLINEF float4 brab() const { return zxwz(); } 597 | HLML_INLINEF float4 braa() const { return zxww(); } 598 | HLML_INLINEF float4 bgrr() const { return zyxx(); } 599 | HLML_INLINEF float4 bgrg() const { return zyxy(); } 600 | HLML_INLINEF float4 bgrb() const { return zyxz(); } 601 | HLML_INLINEF float4 bgra() const { return zyxy(); } 602 | HLML_INLINEF float4 bggr() const { return zyyx(); } 603 | HLML_INLINEF float4 bggg() const { return zyyy(); } 604 | HLML_INLINEF float4 bggb() const { return zyyz(); } 605 | HLML_INLINEF float4 bgga() const { return zyyw(); } 606 | HLML_INLINEF float4 bgbr() const { return zyzx(); } 607 | HLML_INLINEF float4 bgbg() const { return zyzy(); } 608 | HLML_INLINEF float4 bgbb() const { return zyzz(); } 609 | HLML_INLINEF float4 bgba() const { return zyzw(); } 610 | HLML_INLINEF float4 bgar() const { return zywx(); } 611 | HLML_INLINEF float4 bgag() const { return zywy(); } 612 | HLML_INLINEF float4 bgab() const { return zywz(); } 613 | HLML_INLINEF float4 bgaa() const { return zyww(); } 614 | HLML_INLINEF float4 bbrr() const { return zzxx(); } 615 | HLML_INLINEF float4 bbrg() const { return zzxy(); } 616 | HLML_INLINEF float4 bbrb() const { return zzxz(); } 617 | HLML_INLINEF float4 bbra() const { return zzxw(); } 618 | HLML_INLINEF float4 bbgr() const { return zzyx(); } 619 | HLML_INLINEF float4 bbgg() const { return zzyy(); } 620 | HLML_INLINEF float4 bbgb() const { return zzyz(); } 621 | HLML_INLINEF float4 bbga() const { return zzyw(); } 622 | HLML_INLINEF float4 bbbr() const { return zzzx(); } 623 | HLML_INLINEF float4 bbbg() const { return zzzy(); } 624 | HLML_INLINEF float4 bbbb() const { return zzzz(); } 625 | HLML_INLINEF float4 bbba() const { return zzzw(); } 626 | HLML_INLINEF float4 bbar() const { return zzwx(); } 627 | HLML_INLINEF float4 bbag() const { return zzwy(); } 628 | HLML_INLINEF float4 bbab() const { return zzwz(); } 629 | HLML_INLINEF float4 bbaa() const { return zzww(); } 630 | HLML_INLINEF float4 barr() const { return zwxx(); } 631 | HLML_INLINEF float4 barg() const { return zwxy(); } 632 | HLML_INLINEF float4 barb() const { return zwxz(); } 633 | HLML_INLINEF float4 bara() const { return zwxw(); } 634 | HLML_INLINEF float4 bagr() const { return zwyx(); } 635 | HLML_INLINEF float4 bagg() const { return zwyy(); } 636 | HLML_INLINEF float4 bagb() const { return zwyz(); } 637 | HLML_INLINEF float4 baga() const { return zwyw(); } 638 | HLML_INLINEF float4 babr() const { return zwzx(); } 639 | HLML_INLINEF float4 babg() const { return zwzy(); } 640 | HLML_INLINEF float4 babb() const { return zwzz(); } 641 | HLML_INLINEF float4 baba() const { return zwzw(); } 642 | HLML_INLINEF float4 baar() const { return zwwx(); } 643 | HLML_INLINEF float4 baag() const { return zwwy(); } 644 | HLML_INLINEF float4 baab() const { return zwwz(); } 645 | HLML_INLINEF float4 baaa() const { return zwww(); } 646 | 647 | HLML_INLINEF float4 arrr() const { return wxxx(); } 648 | HLML_INLINEF float4 arrg() const { return wxxy(); } 649 | HLML_INLINEF float4 arrb() const { return wxxz(); } 650 | HLML_INLINEF float4 arra() const { return wxxw(); } 651 | HLML_INLINEF float4 argr() const { return wxyx(); } 652 | HLML_INLINEF float4 argg() const { return wxyy(); } 653 | HLML_INLINEF float4 argb() const { return wxyz(); } 654 | HLML_INLINEF float4 arga() const { return wxyw(); } 655 | HLML_INLINEF float4 arbr() const { return wxzx(); } 656 | HLML_INLINEF float4 arbg() const { return wxzy(); } 657 | HLML_INLINEF float4 arbb() const { return wxzz(); } 658 | HLML_INLINEF float4 arba() const { return wxzw(); } 659 | HLML_INLINEF float4 arar() const { return wxwx(); } 660 | HLML_INLINEF float4 arag() const { return wxwy(); } 661 | HLML_INLINEF float4 arab() const { return wxwz(); } 662 | HLML_INLINEF float4 araa() const { return wxww(); } 663 | HLML_INLINEF float4 agrr() const { return wyxx(); } 664 | HLML_INLINEF float4 agrg() const { return wyxy(); } 665 | HLML_INLINEF float4 agrb() const { return wyxz(); } 666 | HLML_INLINEF float4 agra() const { return wyxy(); } 667 | HLML_INLINEF float4 aggr() const { return wyyx(); } 668 | HLML_INLINEF float4 aggg() const { return wyyy(); } 669 | HLML_INLINEF float4 aggb() const { return wyyz(); } 670 | HLML_INLINEF float4 agga() const { return wyyw(); } 671 | HLML_INLINEF float4 agbr() const { return wyzx(); } 672 | HLML_INLINEF float4 agbg() const { return wyzy(); } 673 | HLML_INLINEF float4 agbb() const { return wyzz(); } 674 | HLML_INLINEF float4 agba() const { return wyzw(); } 675 | HLML_INLINEF float4 agar() const { return wywx(); } 676 | HLML_INLINEF float4 agag() const { return wywy(); } 677 | HLML_INLINEF float4 agab() const { return wywz(); } 678 | HLML_INLINEF float4 agaa() const { return wyww(); } 679 | HLML_INLINEF float4 abrr() const { return wzxx(); } 680 | HLML_INLINEF float4 abrg() const { return wzxy(); } 681 | HLML_INLINEF float4 abrb() const { return wzxz(); } 682 | HLML_INLINEF float4 abra() const { return wzxw(); } 683 | HLML_INLINEF float4 abgr() const { return wzyx(); } 684 | HLML_INLINEF float4 abgg() const { return wzyy(); } 685 | HLML_INLINEF float4 abgb() const { return wzyz(); } 686 | HLML_INLINEF float4 abga() const { return wzyw(); } 687 | HLML_INLINEF float4 abbr() const { return wzzx(); } 688 | HLML_INLINEF float4 abbg() const { return wzzy(); } 689 | HLML_INLINEF float4 abbb() const { return wzzz(); } 690 | HLML_INLINEF float4 abba() const { return wzzw(); } 691 | HLML_INLINEF float4 abar() const { return wzwx(); } 692 | HLML_INLINEF float4 abag() const { return wzwy(); } 693 | HLML_INLINEF float4 abab() const { return wzwz(); } 694 | HLML_INLINEF float4 abaa() const { return wzww(); } 695 | HLML_INLINEF float4 aarr() const { return wwxx(); } 696 | HLML_INLINEF float4 aarg() const { return wwxy(); } 697 | HLML_INLINEF float4 aarb() const { return wwxz(); } 698 | HLML_INLINEF float4 aara() const { return wwxw(); } 699 | HLML_INLINEF float4 aagr() const { return wwyx(); } 700 | HLML_INLINEF float4 aagg() const { return wwyy(); } 701 | HLML_INLINEF float4 aagb() const { return wwyz(); } 702 | HLML_INLINEF float4 aaga() const { return wwyw(); } 703 | HLML_INLINEF float4 aabr() const { return wwzx(); } 704 | HLML_INLINEF float4 aabg() const { return wwzy(); } 705 | HLML_INLINEF float4 aabb() const { return wwzz(); } 706 | HLML_INLINEF float4 aaba() const { return wwzw(); } 707 | HLML_INLINEF float4 aaar() const { return wwwx(); } 708 | HLML_INLINEF float4 aaag() const { return wwwy(); } 709 | HLML_INLINEF float4 aaab() const { return wwwz(); } 710 | HLML_INLINEF float4 aaaa() const { return wwww(); } 711 | }; 712 | //boolean 713 | HLML_INLINEF bool4 operator== (float4 a, float4 b) { a.m = funcs::AcmpeqB(a.m, b.m); return bool4(funcs::fasi(a.m)); } 714 | HLML_INLINEF bool4 operator!= (float4 a, float4 b) { a.m = funcs::AcmpneB(a.m, b.m); return bool4(funcs::fasi(a.m)); } 715 | HLML_INLINEF bool4 operator< (float4 a, float4 b) { a.m = funcs::AcmpltB(a.m, b.m); return bool4(funcs::fasi(a.m)); } 716 | HLML_INLINEF bool4 operator> (float4 a, float4 b) { a.m = funcs::AcmpgtB(a.m, b.m); return bool4(funcs::fasi(a.m)); } 717 | HLML_INLINEF bool4 operator<= (float4 a, float4 b) { a.m = funcs::AcmpleB(a.m, b.m); return bool4(funcs::fasi(a.m)); } 718 | HLML_INLINEF bool4 operator>= (float4 a, float4 b) { a.m = funcs::AcmpgeB(a.m, b.m); return bool4(funcs::fasi(a.m)); } 719 | //logical 720 | HLML_INLINEF float4 operator~ (float4 a) { a.m = funcs::notAandB(a.m, consts::vnall); return a; } 721 | HLML_INLINEF float4 operator& (float4 a, float4 b) { a.m = funcs::AandB(a.m, b.m); return a; } 722 | HLML_INLINEF float4 operator| (float4 a, float4 b) { a.m = funcs::AorB(a.m, b.m); return a; } 723 | HLML_INLINEF float4 operator^ (float4 a, float4 b) { a.m = funcs::AxorB(a.m, b.m); return a; } 724 | //arithmetic 725 | HLML_INLINEF float4 operator+ (float4 a) { return a; } 726 | HLML_INLINEF float4 operator- (float4 a) { a.m = funcs::AxorB(a.m, consts::vsignbits_xyz); return a; } 727 | HLML_INLINEF float4 operator+ (float4 a, float4 b) { a.m = funcs::AaddB(a.m, b.m); return a; } 728 | HLML_INLINEF float4 operator- (float4 a, float4 b) { a.m = funcs::AsubB(a.m, b.m); return a; } 729 | HLML_INLINEF float4 operator* (float4 a, float4 b) { a.m = funcs::AmulB(a.m, b.m); return a; } 730 | HLML_INLINEF float4 operator/ (float4 a, float4 b) { a.m = funcs::AdivB(a.m, b.m); return a; } 731 | HLML_INLINEF float4& operator+= (float4& a, float4 b) { a = a + b; return a; } 732 | HLML_INLINEF float4& operator-= (float4& a, float4 b) { a = a - b; return a; } 733 | HLML_INLINEF float4& operator*= (float4& a, float4 b) { a = a * b; return a; } 734 | HLML_INLINEF float4& operator/= (float4& a, float4 b) { a = a / b; return a; } 735 | HLML_INLINEF float4 operator+ (float4 a, f32 b) { return a + float4(b); } 736 | HLML_INLINEF float4 operator- (float4 a, f32 b) { return a - float4(b); } 737 | HLML_INLINEF float4 operator* (float4 a, f32 b) { return a * float4(b); } 738 | HLML_INLINEF float4 operator/ (float4 a, f32 b) { return a / float4(b); } 739 | HLML_INLINEF float4& operator+= (float4& a, f32 b) { return a += float4(b); } 740 | HLML_INLINEF float4& operator-= (float4& a, f32 b) { return a -= float4(b); } 741 | HLML_INLINEF float4& operator*= (float4& a, f32 b) { return a *= float4(b); } 742 | HLML_INLINEF float4& operator/= (float4& a, f32 b) { return a /= float4(b); } 743 | HLML_INLINEF float4 operator+ (f32 a, float4 b) { return float4(a) + b; } 744 | HLML_INLINEF float4 operator- (f32 a, float4 b) { return float4(a) - b; } 745 | HLML_INLINEF float4 operator* (f32 a, float4 b) { return float4(a) * b; } 746 | HLML_INLINEF float4 operator/ (f32 a, float4 b) { return float4(a) / b; } 747 | //funcs 748 | HLML_INLINEF int4 asint (float4 a) { return int4(funcs::fasi(a.m)); } 749 | HLML_INLINEF int4 toint (float4 a) { return int4(funcs::ftoi(a.m)); } 750 | HLML_INLINEF float4 asflt (int4 a) { return float4(funcs::iasf(a.m)); } 751 | HLML_INLINEF float4 toflt (int4 a) { return float4(funcs::itof(a.m)); } 752 | 753 | HLML_INLINEF float4 abs (float4 v) { v.m = funcs::notAandB(consts::vsignbits_xyzw, v.m); return v; } 754 | HLML_INLINEF float4 ceil (float4 a) { a.m = funcs::ceil(a.m); return a; } 755 | HLML_INLINEF float4 clamp (float4 v, float4 a, float4 b) { v.m = funcs::AminB(funcs::AmaxB(v.m, a.m), b.m); return v; } 756 | HLML_INLINEF float4 clamp (float4 v, f32 a, f32 b) { return clamp(v, float4(a), float4(b)); } 757 | HLML_INLINEF float4 dotv (float4 a, float4 b) { a.m = funcs::AdotBxyzw(a.m, b.m); return a; } 758 | HLML_INLINEF float4 floor (float4 a) { a.m = funcs::floor(a.m); return a; } 759 | HLML_INLINEF float4 fmod (float4 a, float4 b) { return a - toflt(toint(a / b)) * b; } 760 | HLML_INLINEF float4 frac (float4 a) { a.m = funcs::frac(a.m); return a; } 761 | HLML_INLINEF float4 lerp (float4 a, float4 b, f32 t) { return a + (b - a) * t; } 762 | HLML_INLINEF float4 lerp (float4 a, float4 b, float4 t) { return a + (b - a) * t; } 763 | HLML_INLINEF float4 mad (float4 a, float4 b, float4 c) { a.m = funcs::AmulBaddC(a.m, b.m, c.m); return a; } 764 | HLML_INLINEF float4 maxv (float4 a, float4 b) { a.m = funcs::AmaxB(a.m, b.m); return a; } 765 | HLML_INLINEF float4 minv (float4 a, float4 b) { a.m = funcs::AminB(a.m, b.m); return a; } 766 | HLML_INLINEF float4 rcp (float4 v) { v.m = funcs::rcp(v.m); return v; } 767 | HLML_INLINEF float4 reflect (float4 v, float4 n) { return v - n * dotv(v, n) * 2.0f; } 768 | HLML_INLINEF float4 round (float4 a) { a.m = funcs::round(a.m); return a; } 769 | HLML_INLINEF float4 rsqrt (float4 v) { v.m = funcs::rsqrt(v.m); return v; } 770 | HLML_INLINEF float4 saturate (float4 a) { return clamp(a, 0.0f, 1.0f); } 771 | HLML_INLINEF float4 sumv (float4 v) { v.m = funcs::AhaddB(v.m, v.zwxy().m); v.m = funcs::AhaddB(v.m, v.m); return v; } 772 | HLML_INLINEF float4 sqrt (float4 v) { v.m = funcs::sqrt(v.m); return v; } 773 | HLML_INLINEF float4 trunc (float4 a) { a.m = funcs::trunc(a.m); return a; } 774 | 775 | 776 | HLML_INLINEF f32 hmin (float4 v) { v = minv(v, shufflef4(v, 1, 0, 3, 2)); return minv(v, shufflef4(v, 3, 2, 1, 0)).x(); } 777 | HLML_INLINEF f32 hmax (float4 v) { v = maxv(v, shufflef4(v, 1, 0, 3, 2)); return maxv(v, shufflef4(v, 3, 2, 1, 0)).x(); } 778 | HLML_INLINEF f32 sum (float4 v) { return sumv(v).x(); } 779 | HLML_INLINEF f32 dot (float4 a, float4 b) { return dotv(a, b).x(); } 780 | HLML_INLINEF f32 lengthsq (float4 v) { return dot(v, v); } 781 | HLML_INLINEF f32 length (float4 v) { return sqrt(dotv(v, v)).x(); } 782 | 783 | HLML_INLINEF float4 normalize(float4 v) { return v * rsqrt(dotv(v, v)); } 784 | 785 | HLML_INLINEF float4 refract(float4 v, float4 n, f32 idx) { 786 | float4 vn = dotv(v, n); 787 | float4 k = maxv(float4(consts::vzeros), float4(1.0f - idx * idx * (1.0f - vn * vn))); 788 | return v * idx - (vn * idx + sqrt(k)) * n; 789 | } 790 | 791 | HLML_INLINEF float4 sign(float4 v) { 792 | //https://github.com/g-truc/glm/blob/master/glm/simd/common.h#L99 793 | VF128 cmp0 = funcs::AcmpltB(v.m, consts::vzeros); 794 | VF128 cmp1 = funcs::AcmpgtB(v.m, consts::vzeros); 795 | VF128 and0 = funcs::AandB(cmp0, consts::vnones4); 796 | VF128 and1 = funcs::AandB(cmp1, consts::vones4); 797 | v.m = funcs::AorB(and0, and1); 798 | return v; 799 | } 800 | 801 | HLML_INLINEF float4 smoothstep(float4 e0, float4 e1, float4 v) { 802 | float4 zeros(consts::vzeros), ones(consts::vones); 803 | float4 t = clamp((v - e0) / (e1 - e0), zeros, ones); 804 | return (3.0f - 2.0f * t) * t * t; 805 | } 806 | 807 | HLML_INLINEF float4 step(float4 e, float4 v) { 808 | e = sign(v - e); 809 | return maxv(float4(consts::vzeros), e); 810 | } 811 | } -------------------------------------------------------------------------------- /float4x4.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.hpp" 4 | #include "float4.hpp" 5 | #include "trig.hpp" 6 | #include "float3x3.hpp" 7 | 8 | namespace hlml { 9 | struct float4x4 { 10 | float4 c0, c1, c2, c3; 11 | 12 | HLML_INLINEF float4x4() : c0(), c1(), c2(), c3() {} 13 | HLML_INLINEF explicit float4x4(const f32* p) : c0(p), c1(p+4), c2(p+8), c3(p+12) {} 14 | HLML_INLINEF explicit float4x4(float3x3 m) : c0(m.c0.m), c1(m.c1.m), c2(m.c2.m), c3(consts::vpoint) {} 15 | HLML_INLINEF float4x4(f32 x0, f32 y0, f32 z0, f32 w0, f32 x1, f32 y1, f32 z1, f32 w1, f32 x2, f32 y2, f32 z2, f32 w2, f32 x3, f32 y3, f32 z3, f32 w3) : c0(x0, y0, z0, w0), c1(x1, y1, z1, w1), c2(x2, y2, z2, w2), c3(x3, y3, z3, w3) {} 16 | HLML_INLINEF float4x4(float4 col0, float4 col1, float4 col2, float4 col3) : c0(col0), c1(col1), c2(col2), c3(col3) {} 17 | 18 | HLML_INLINEF static float4x4 identity() { static float4x4 i( { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } ); return i; } 19 | 20 | HLML_INLINEF float4x4& operator= (float4x4 b) { c0 = b.c0; c1 = b.c1; c2 = b.c2; c3 = b.c3; return *this; } 21 | HLML_INLINEF float4x4& operator= (f32 s) { c0 = c1 = c2 = c3 = float4(s); return *this; } 22 | }; 23 | 24 | HLML_INLINEF float4x4 transpose(float4x4 m) { 25 | float4 t0(funcs::axbxayby(m.c0.m, m.c1.m)); 26 | float4 t2(funcs::azbzawbw(m.c0.m, m.c1.m)); 27 | float4 t1(funcs::axbxayby(m.c2.m, m.c3.m)); 28 | float4 t3(funcs::azbzawbw(m.c2.m, m.c3.m)); 29 | m.c0.m = funcs::axaybxby(t0.m, t1.m); 30 | m.c1.m = funcs::bzbwazaw(t1.m, t0.m); 31 | m.c2.m = funcs::axaybxby(t2.m, t3.m); 32 | m.c3.m = funcs::bzbwazaw(t3.m, t2.m); 33 | return m; 34 | } 35 | 36 | HLML_INLINEF float4x4 inverse(float4x4 m) { 37 | float4 A(funcs::axbxayby(m.c0.m, m.c1.m)), B(funcs::axbxayby(m.c2.m, m.c3.m)), C(funcs::azbzawbw(m.c0.m, m.c1.m)), D(funcs::azbzawbw(m.c2.m, m.c3.m)); 38 | float4 AB = A.wwxx() * B - A.yyzz() * B.zwxy(); 39 | float4 t0 = AB.xyxy() * C.xxzz() + AB.zwzw() * C.yyww(); 40 | float4 t1 = AB.wxwx() * D - AB.zyzy() * D.yxwz(); 41 | float4 DC = D.wwxx() * C - D.yyzz() * C.zwxy(); 42 | float4 t2 = DC.wxwx() * A - DC.zyzy() * A.yxwz(); 43 | float4 t3 = DC.xyxy() * B.xxzz() + DC.zwzw() * B.yyww(); 44 | 45 | float4 dA = A * A.wwyy(); 46 | dA = (dA - dA.zwzw()).xxxx(); 47 | float4 iD = D * dA - t0; 48 | float4 dB = B.wwyy() * B; 49 | dB = (dB - dB.zwzw()).xxxx(); 50 | float4 iB = C * dB - t1; 51 | float4 dC = C.wwyy() * C; 52 | dC = (dC - dC.zwzw()).xxxx(); 53 | float4 iC = B * dC - t2; 54 | float4 dD = D.wwyy() * D; 55 | dD = (dD - dD.zwzw()).xxxx(); 56 | float4 iA = A * dD - t3; 57 | 58 | float4 det = dA * dD + dB * dC - dotv(DC.xzyw(), AB); 59 | det.m = funcs::AxorB(det.m, consts::vsignbits_yz); 60 | float4 idet = rcp(det); 61 | iA *= idet; 62 | iB *= idet; 63 | iC *= idet; 64 | iD *= idet; 65 | 66 | m.c0.m = funcs::awazbwbz(iA.m, iC.m); 67 | m.c1.m = funcs::ayaxbybx(iA.m, iC.m); 68 | m.c2.m = funcs::awazbwbz(iB.m, iD.m); 69 | m.c3.m = funcs::ayaxbybx(iB.m, iD.m); 70 | 71 | return m; 72 | } 73 | 74 | HLML_INLINEF b8 operator== (float4x4 lhs, float4x4 rhs) { return all(lhs.c0 == rhs.c0) && all(lhs.c1 == rhs.c1) && all(lhs.c2 == rhs.c2) && all(lhs.c3 == rhs.c3); } 75 | HLML_INLINEF b8 operator!= (float4x4 lhs, float4x4 rhs) { return !(lhs == rhs); } 76 | 77 | HLML_INLINEF float4x4 operator+ (float4x4 a, float4x4 b) { a.c0 += b.c0; a.c1 += b.c1; a.c2 += b.c2; a.c3 += b.c3; return a; } 78 | HLML_INLINEF float4x4 operator+ (float4x4 a, f32 s) { a.c0 += s; a.c1 += s; a.c2 += s; a.c3 += s; return a; } 79 | HLML_INLINEF float4x4 operator- (float4x4 m) { m.c0 = -m.c0; m.c1 = -m.c1; m.c2 = -m.c2, m.c3 = -m.c3; return m; } 80 | HLML_INLINEF float4x4 operator- (float4x4 a, float4x4 b) { a.c0 -= b.c0; a.c1 -= b.c1; a.c2 -= b.c2; a.c3 -= b.c3; return a; } 81 | HLML_INLINEF float4x4 operator- (float4x4 a, f32 s) { float4 tmp(s); return a - float4x4(tmp, tmp, tmp, tmp); } 82 | HLML_INLINEF float4x4& operator-= (float4x4& a, f32 s) { a = a - s; return a; } 83 | HLML_INLINEF float4x4 operator* (float4x4 a, float4x4 b) { 84 | float4 lc0 = a.c0, lc1 = a.c1, lc2 = a.c2, lc3 = a.c3, rc0 = b.c0, rc1 = b.c1, rc2 = b.c2, rc3 = b.c3; 85 | a.c0 = lc0 * rc0.xxxx() + lc1 * rc0.yyyy() + lc2 * rc0.zzzz() + lc3 * rc0.wwww(); 86 | a.c1 = lc0 * rc1.xxxx() + lc1 * rc1.yyyy() + lc2 * rc1.zzzz() + lc3 * rc1.wwww(); 87 | a.c2 = lc0 * rc2.xxxx() + lc1 * rc2.yyyy() + lc2 * rc2.zzzz() + lc3 * rc2.wwww(); 88 | a.c3 = lc0 * rc3.xxxx() + lc1 * rc3.yyyy() + lc2 * rc3.zzzz() + lc3 * rc3.wwww(); 89 | return a; 90 | } 91 | HLML_INLINEF float4x4 operator* (float4x4 a, f32 s) { a.c0 *= s; a.c1 *= s; a.c2 *= s; a.c3 *= s; return a; } 92 | HLML_INLINEF float4 operator* (float4x4 a, float4 v) { return v.xxxx() * a.c0 + v.yyyy() * a.c1 + v.zzzz() * a.c2 + v.wwww() * a.c3; } 93 | HLML_INLINEF float4x4 operator/ (float4x4 a, f32 s) { a.c0 /= s; a.c1 /= s; a.c2 /= s; a.c3 /= s; return a; } 94 | HLML_INLINEF float4x4& operator*= (float4x4& a, float4x4 b) { a = a * b; return a; } 95 | HLML_INLINEF float4x4& operator*= (float4x4& a, f32 s) { a = a * s; return a; } 96 | HLML_INLINEF float4x4& operator/= (float4x4& a, f32 s) { a = a / s; return a; } 97 | 98 | HLML_INLINEF float4x4 fillortho(f32 x, f32 y, f32 z, f32 w, f32 h, f32 d) { 99 | return float4x4( 100 | x, 0.0f, 0.0f, 0.0f, 101 | 0.0f, -y, 0.0f, 0.0f, 102 | 0.0f, 0.0f, z, 0.0f, 103 | -w, -h, d, 1.0f 104 | ); 105 | } 106 | HLML_INLINEF float4x4 ortho(f32 l, f32 r, f32 b, f32 t, f32 zn, f32 zf) { 107 | f32 invW = 1.0f / (r - l), invH = 1.0f / (t - b), invD = 1.0f / (zf - zn); 108 | return fillortho(2.0f * invW, 2.0f * invH, -invD, (l + r) * invW, (t + b) * invH, zn * invD); 109 | } 110 | HLML_INLINEF float4x4 orthoinverse(f32 l, f32 r, f32 b, f32 t, f32 zn, f32 zf) { 111 | return fillortho((r - l) * 0.5f, (t - b) * 0.5f, -(zf - zn), (r + l) * 0.5f, (t + b) * 0.5f, zn); 112 | } 113 | HLML_INLINEF float4x4 ortho(f32 w, f32 h, f32 zn, f32 zf) { 114 | f32 hw = 0.5f * w, hh = 0.5f * h; 115 | return ortho(-hw, hw, -hh, hh, zn, zf); 116 | } 117 | HLML_INLINEF float4x4 orthoinverse(f32 w, f32 h, f32 zn, f32 zf) { 118 | f32 hw = 0.5f * w, hh = 0.5f * h; 119 | return orthoinverse(-hw, hw, -hh, hh, zn, zf); 120 | } 121 | 122 | HLML_INLINEF float4x4 fillpersp(f32 x, f32 y, f32 z, f32 w, f32 h, f32 d) { 123 | return float4x4( 124 | x, 0.0f, 0.0f, 0.0f, 125 | 0.0f, -y, 0.0f, 0.0f, 126 | w, h, -z, 1.0f, 127 | 0.0f, 0.0f, d, 0.0f 128 | ); 129 | } 130 | 131 | HLML_INLINEF float4x4 fillperspinv(f32 x, f32 y, f32 z, f32 w, f32 h, f32 d) { 132 | return float4x4( 133 | 1.0f / x, 0.0f, 0.0f, 0.0f, 134 | 0.0f, 1.0f / -y, 0.0f, 0.0f, 135 | 0.0f, 0.0f, 0.0f, 1.0f / d, 136 | w, h, 1.0f, z / d 137 | ); 138 | } 139 | 140 | HLML_INLINEF float4x4 perspective(f32 fovDegs, f32 h2w, f32 zn, f32 zf) { 141 | const f32 invD = 1.0f / (zn - zf); 142 | float4 rads(hlml::DEG2RAD(fovDegs) * 0.5f), s, c; 143 | sincos(rads, s, c); 144 | f32 invtan = (c / s).x(); 145 | f32 x = invtan * h2w, y = invtan, z = zf * invD, d = zf * zn * invD; 146 | return fillpersp(x, y, z, 0.0f, 0.0f, d); 147 | } 148 | HLML_INLINEF float4x4 perspective(f32 fovDegs, f32 width, f32 height, f32 zn, f32 zf) { return perspective(fovDegs, height / width, zn, zf); } 149 | HLML_INLINEF float4x4 perspectiveinverse(f32 fovDegs, f32 h2w, f32 zn, f32 zf) { 150 | //const f32 invzn = 1.0f / zn, invzf = 1.0f / zf, invdzn = invzn * 0.5f, invdznzf = invdzn * invzf; 151 | const f32 invD = 1.0f / (zn - zf); 152 | float4 rads(hlml::DEG2RAD(fovDegs) * 0.5f), s, c; 153 | sincos(rads, s, c); 154 | f32 invtan = (c / s).x(); 155 | f32 x = invtan * h2w, y = invtan, z = zf * invD, d = zf * zn * invD; 156 | return fillperspinv(x, y, z, 0.0f, 0.0f, d); 157 | } 158 | HLML_INLINEF float4x4 perspectiveZinv(f32 fovDegs, f32 h2w, f32 zn, f32 epsilon = 2.4e-7f) { 159 | float4 rads(hlml::DEG2RAD(fovDegs) * 0.5f), s, c; 160 | sincos(rads, s, c); 161 | f32 diff = (c / s).x() * zn, dzn = 2.0f * zn; 162 | f32 l = -diff * h2w, r = diff * h2w, b = -h2w, t = h2w; 163 | f32 x = (r - l) * dzn, y = (t - b) * dzn, z = (epsilon - 2.0f) * zn; 164 | return fillpersp(x, y, z, 0.0f, 0.0f, epsilon - 1.0f); 165 | } 166 | HLML_INLINEF float4x4 frustum(f32 l, f32 r, f32 b, f32 t, f32 zn, f32 zf) { 167 | f32 dzn = 2.0f * zn, diffx = 1.0f / (r - l), diffy = 1.0f / (t - b), diffz = 1.0f / (zn - zf); 168 | f32 x = dzn * diffx, y = dzn * diffy, z = zn * zf * diffz; 169 | f32 w = (r + l) * diffx, h = (t + b) * diffy, d = zf * diffz; 170 | return fillpersp(x, y, z, w, h, d); 171 | } 172 | HLML_INLINEF float4x4 frustuminverse(f32 l, f32 r, f32 b, f32 t, f32 zn, f32 zf) { 173 | f32 invdzn = 1.0f / (2.0f * zn), invdznzf = invdzn / zf, diffx = (r - l), diffy = (t - b), diffz = (zn - zf); 174 | f32 x = invdzn * diffx, y = invdzn * diffy, z = diffz * invdznzf; 175 | f32 w = (r + l) * invdzn, h = (t + b) * invdzn, d = (zn + zf) * invdznzf; 176 | return fillperspinv(x, y, z, w, h, d); 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /funcs_sse.hpp: -------------------------------------------------------------------------------- 1 | #define HLML_INLINEF __forceinline 2 | 3 | namespace hlml { 4 | namespace funcs { 5 | #define shuffleb2(V, X, Y) bool2(_mm_shuffle_epi32((V).m, _MM_SHUFFLE(3, 2, Y, X))) 6 | #define shufflei2(V, X, Y) int2(_mm_shuffle_epi32((V).m, _MM_SHUFFLE(3, 2, Y, X))) 7 | #define shufflef2(V, X, Y) float2(_mm_shuffle_ps((V).m, (V).m, _MM_SHUFFLE(3, 2, Y, X))) 8 | #define shuffleb3(V, X, Y, Z) bool3(_mm_shuffle_epi32((V).m, _MM_SHUFFLE(3, Z, Y, X))) 9 | #define shufflei3(V, X, Y, Z) int3(_mm_shuffle_epi32((V).m, _MM_SHUFFLE(3, Z, Y, X))) 10 | #define shufflef3(V, X, Y, Z) float3(_mm_shuffle_ps((V).m, (V).m, _MM_SHUFFLE(3, Z, Y, X))) 11 | #define shuffleb4(V, X, Y, Z, W) bool4(_mm_shuffle_epi32((V).m, _MM_SHUFFLE(W, Z, Y, X))) 12 | #define shufflei4(V, X, Y, Z, W) int4(_mm_shuffle_epi32((V).m, _MM_SHUFFLE(W, Z, Y, X))) 13 | #define shufflef4(V, X, Y, Z, W) float4(_mm_shuffle_ps((V).m, (V).m, _MM_SHUFFLE(W, Z, Y, X))) 14 | 15 | #define inserti(V, X, i) _mm_insert_epi32((V), (X), (i)) 16 | #define insertf(V, X, i) _mm_insert_ps((V), _mm_set_ss((X)), (i) << 4) 17 | #define extracti(V, i) _mm_extract_epi32((V), (i)) 18 | #define extractf(V, i) _mm_extract_ps((V), (i)) 19 | 20 | HLML_INLINEF VF128 axayaz00(VF128 a) { return _mm_blend_ps(a, _mm_setzero_ps(), (1 << 3)); } 21 | HLML_INLINEF VF128 axayaz11(VF128 a) { return _mm_blend_ps(a, _mm_set_ss(1.0f), (1 << 3)); } 22 | HLML_INLINEF VF128 axay0000(VF128 a) { return _mm_blend_ps(a, _mm_setzero_ps(), (1 << 3) | (1 << 2)); } 23 | HLML_INLINEF VF128 axay1111(VF128 a) { return _mm_blend_ps(a, _mm_set_ss(1.0f), (1 << 3) | (1 << 2)); } 24 | #define shufflef4tof3(V, X, Y, Z) float3(funcs::axayaz00(_mm_shuffle_ps((V).m, (V).m, _MM_SHUFFLE(3, Z, Y, X)))) 25 | #define shufflef4tof2(V, X, Y) float2(funcs::axay0000(_mm_shuffle_ps((V).m, (V).m, _MM_SHUFFLE(3, 2, Y, X)))) 26 | #define shufflef3tof2(V, X, Y) float2(funcs::axay0000(_mm_shuffle_ps((V).m, (V).m, _MM_SHUFFLE(3, 2, Y, X)))) 27 | 28 | HLML_INLINEF VF128 axbxayby(VF128 a, VF128 b) { return _mm_unpacklo_ps(a, b); } 29 | HLML_INLINEF VF128 axaybxby(VF128 a, VF128 b) { return _mm_movelh_ps(a, b); } 30 | HLML_INLINEF VF128 azbzawbw(VF128 a, VF128 b) { return _mm_unpackhi_ps(a, b); } 31 | HLML_INLINEF VF128 bzbwazaw(VF128 a, VF128 b) { return _mm_movehl_ps(a, b); } 32 | HLML_INLINEF VF128 bxayazaw(VF128 a, VF128 b) { return _mm_move_ss(a, b); } 33 | HLML_INLINEF VF128 axaxazaz(VF128 a) { return _mm_moveldup_ps(a); } 34 | HLML_INLINEF VF128 ayaxbybx(VF128 a, VF128 b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(0,1,0,1)); } 35 | HLML_INLINEF VF128 awazbwbz(VF128 a, VF128 b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(2,3,2,3)); } 36 | HLML_INLINEF VF128 awaxbybz(VF128 a, VF128 b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(2,1,0,3)); } 37 | HLML_INLINEF VF128 axaybxbw(VF128 a, VF128 b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(3,0,1,0)); } 38 | HLML_INLINEF VF128 azawbybw(VF128 a, VF128 b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(3,1,3,2)); } 39 | HLML_INLINEF VF128 axaybzbw(VF128 a, VF128 b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(3,2,1,0)); } 40 | HLML_INLINEF VF128 axazbxbz(VF128 a, VF128 b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(2,0,2,0)); } 41 | HLML_INLINEF VF128 ayawbybw(VF128 a, VF128 b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(3,1,3,1)); } 42 | HLML_INLINEF VF128 setXYZW(f32 x, f32 y, f32 z, f32 w) { return _mm_set_ps(w, z, y, x); } 43 | HLML_INLINEF VI128 setXYZW(i32 x, i32 y, i32 z, i32 w) { return _mm_set_epi32(w, z, y, x); } 44 | HLML_INLINEF VF128 setXXXX(f32 x) { return _mm_set1_ps(x); } 45 | HLML_INLINEF VI128 setXXXX(i32 x) { return _mm_set1_epi32(x); } 46 | HLML_INLINEF VF128 AaddssB(VF128 a, VF128 b) { return _mm_add_ss(a, b); } 47 | HLML_INLINEF VF128 notAandB(VF128 a, VF128 b) { return _mm_andnot_ps(a, b); } 48 | HLML_INLINEF VI128 notAandB(VI128 a, VI128 b) { return _mm_andnot_si128(a, b); } 49 | HLML_INLINEF VF128 AandB(VF128 a, VF128 b) { return _mm_and_ps(a, b); } 50 | HLML_INLINEF VI128 AandB(VI128 a, VI128 b) { return _mm_and_si128(a, b); } 51 | HLML_INLINEF VF128 AorB(VF128 a, VF128 b) { return _mm_or_ps(a, b); } 52 | HLML_INLINEF VI128 AorB(VI128 a, VI128 b) { return _mm_or_si128(a, b); } 53 | HLML_INLINEF VF128 AxorB(VF128 a, VF128 b) { return _mm_xor_ps(a, b); } 54 | HLML_INLINEF VI128 AxorB(VI128 a, VI128 b) { return _mm_xor_si128(a, b); } 55 | HLML_INLINEF VF128 AaddB(VF128 a, VF128 b) { return _mm_add_ps(a, b); } 56 | HLML_INLINEF VI128 AaddB(VI128 a, VI128 b) { return _mm_add_epi32(a, b); } 57 | HLML_INLINEF VF128 AsubB(VF128 a, VF128 b) { return _mm_sub_ps(a, b); } 58 | HLML_INLINEF VI128 AsubB(VI128 a, VI128 b) { return _mm_sub_epi32(a, b); } 59 | HLML_INLINEF VF128 AmulB(VF128 a, VF128 b) { return _mm_mul_ps(a, b); } 60 | HLML_INLINEF VI128 AmulB(VI128 a, VI128 b) { return _mm_mul_epi32(a, b); } 61 | HLML_INLINEF VF128 AdivB(VF128 a, VF128 b) { return _mm_div_ps(a, b); } 62 | HLML_INLINEF VF128 AdotBxyzw(VF128 a, VF128 b) { return _mm_dp_ps(a, b, 0xFF); } 63 | HLML_INLINEF VF128 AdotBxyz(VF128 a, VF128 b) { return _mm_dp_ps(a, b, (0x11 << 2) | (0x11 << 1) | (0x11 << 0)); } 64 | HLML_INLINEF VF128 AdotBxy(VF128 a, VF128 b) { return _mm_dp_ps(a, b, (0x11 << 1) | (0x11 << 0)); } 65 | HLML_INLINEF VF128 AcmpeqB(VF128 a, VF128 b) { return _mm_cmpeq_ps(a, b); } 66 | HLML_INLINEF VI128 AcmpeqB(VI128 a, VI128 b) { return _mm_cmpeq_epi32(a, b); } 67 | HLML_INLINEF VF128 AcmpneB(VF128 a, VF128 b) { return _mm_cmpneq_ps(a, b); } 68 | HLML_INLINEF VI128 AcmpneqB(VI128 a, VI128 b) { return notAandB(AcmpeqB(a, b), setXXXX(~0)); } 69 | HLML_INLINEF VF128 AcmpltB(VF128 a, VF128 b) { return _mm_cmplt_ps(a, b); } 70 | HLML_INLINEF VI128 AcmpltB(VI128 a, VI128 b) { return _mm_cmplt_epi32(a, b); } 71 | HLML_INLINEF VF128 AcmpgeB(VF128 a, VF128 b) { return _mm_cmpge_ps(a, b); } 72 | HLML_INLINEF VI128 AcmpgeB(VI128 a, VI128 b) { return notAandB(AcmpltB(a, b), setXXXX(~0)); } 73 | HLML_INLINEF VF128 AcmpgtB(VF128 a, VF128 b) { return _mm_cmpgt_ps(a, b); } 74 | HLML_INLINEF VI128 AcmpgtB(VI128 a, VI128 b) { return _mm_cmpgt_epi32(a, b); } 75 | HLML_INLINEF VF128 AcmpleB(VF128 a, VF128 b) { return _mm_cmple_ps(a, b); } 76 | HLML_INLINEF VI128 AcmpleB(VI128 a, VI128 b) { return notAandB(AcmpltB(a, b), setXXXX(~0)); } 77 | HLML_INLINEF VF128 AminB(VF128 a, VF128 b) { return _mm_min_ps(a, b); } 78 | HLML_INLINEF VI128 AminB(VI128 a, VI128 b) { return _mm_min_epi32(a, b); } 79 | HLML_INLINEF VF128 AmaxB(VF128 a, VF128 b) { return _mm_max_ps(a, b); } 80 | HLML_INLINEF VI128 AmaxB(VI128 a, VI128 b) { return _mm_max_epi32(a, b); } 81 | HLML_INLINEF VF128 AhaddB(VF128 a, VF128 b) { return _mm_hadd_ps(a, b); } 82 | HLML_INLINEF VI128 AhaddB(VI128 a, VI128 b) { return _mm_hadd_epi32(a, b); } 83 | HLML_INLINEF VI128 Ashiftl(VI128 a, u8 bits) { return _mm_slli_epi32(a, bits); } 84 | HLML_INLINEF VI128 Ashiftr(VI128 a, u8 bits) { return _mm_srli_epi32(a, bits); } 85 | HLML_INLINEF i32 movemask(VI128 a) { return _mm_movemask_epi8(a); } 86 | 87 | HLML_INLINEF VF128 rcp(VF128 a) { return _mm_rcp_ps(a); } 88 | HLML_INLINEF VF128 sqrt(VF128 a) { return _mm_sqrt_ps(a); } 89 | HLML_INLINEF VF128 rsqrt(VF128 a) { return _mm_rsqrt_ps(a); } 90 | HLML_INLINEF VF128 AmulBaddC(VF128 a, VF128 b, VF128 c) { return _mm_fmadd_ps(a, b, c); } 91 | HLML_INLINEF VF128 floor(VF128 a) { return _mm_floor_ps(a); } 92 | HLML_INLINEF VF128 ceil(VF128 a) { return _mm_ceil_ps(a); } 93 | HLML_INLINEF VF128 trunc(VF128 a) { return _mm_round_ps(a, _MM_FROUND_TRUNC); } 94 | HLML_INLINEF VF128 round(VF128 a) { return _mm_round_ps(a, _MM_FROUND_NINT); } 95 | HLML_INLINEF VF128 frac(VF128 a) { return _mm_frcz_ps(a); } 96 | HLML_INLINEF VI128 ftoi(VF128 a) { return _mm_cvttps_epi32(a); } 97 | HLML_INLINEF VF128 itof(VI128 a) { return _mm_cvtepi32_ps(a); } 98 | HLML_INLINEF VI128 fasi(VF128 a) { return _mm_castps_si128(a); } 99 | HLML_INLINEF VF128 iasf(VI128 a) { return _mm_castsi128_ps(a); } 100 | HLML_INLINEF VI128 ftoi(VI128 a) { return a; } 101 | HLML_INLINEF VF128 itof(VF128 a) { return a; } 102 | HLML_INLINEF VI128 fasi(VI128 a) { return a; } 103 | HLML_INLINEF VF128 iasf(VF128 a) { return a; } 104 | } 105 | } -------------------------------------------------------------------------------- /int2.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.hpp" 4 | #include "bool2.hpp" 5 | 6 | namespace hlml { 7 | struct int2 { 8 | 9 | VI128 m = { 0 }; 10 | 11 | HLML_INLINEF int2() {} 12 | HLML_INLINEF explicit int2(VI128 v) : m(v) {} 13 | HLML_INLINEF int2(i32 x, i32 y) : int2(funcs::setXYZW(x, y, consts::snZero, consts::snZero)) {} 14 | HLML_INLINEF explicit int2(i32 x) : int2(x, x) {} 15 | HLML_INLINEF explicit int2(const i32* p) : int2(p[0], p[1]) {} 16 | 17 | HLML_INLINEF void store(i32* p) const { p[0] = x(), p[1] = y(); } 18 | 19 | HLML_INLINEF void setX(i32 x) { m = inserti(m, x, 0); } 20 | HLML_INLINEF void setY(i32 y) { m = inserti(m, y, 1); } 21 | 22 | HLML_INLINEF i32 x() const { return extracti(m, 0); } 23 | HLML_INLINEF i32 y() const { return extracti(m, 1); } 24 | 25 | HLML_INLINEF int2 xx() const { return shufflei2(*this, 0, 0); } 26 | HLML_INLINEF int2 xy() const { return *this; } 27 | HLML_INLINEF int2 yx() const { return shufflei2(*this, 1, 0); } 28 | HLML_INLINEF int2 yy() const { return shufflei2(*this, 1, 1); } 29 | 30 | HLML_INLINEF i32 r() const { return x(); } 31 | HLML_INLINEF i32 g() const { return y(); } 32 | 33 | HLML_INLINEF int2 rr() const { return xx(); } 34 | HLML_INLINEF int2 rg() const { return xy(); } 35 | HLML_INLINEF int2 gr() const { return yx(); } 36 | HLML_INLINEF int2 gg() const { return yy(); } 37 | }; 38 | //boolean 39 | HLML_INLINEF bool2 operator== (int2 a, int2 b) { return bool2(funcs::AcmpeqB(a.m, b.m)); } 40 | HLML_INLINEF bool2 operator!= (int2 a, int2 b) { return bool2(funcs::AcmpneqB(a.m, b.m)); } 41 | HLML_INLINEF bool2 operator< (int2 a, int2 b) { return bool2(funcs::AcmpltB(a.m, b.m)); } 42 | HLML_INLINEF bool2 operator> (int2 a, int2 b) { return bool2(funcs::AcmpgtB(a.m, b.m)); } 43 | HLML_INLINEF bool2 operator<= (int2 a, int2 b) { return bool2(funcs::AcmpleB(a.m, b.m)); } 44 | HLML_INLINEF bool2 operator>= (int2 a, int2 b) { return bool2(funcs::AcmpgeB(a.m, b.m)); } 45 | //logical 46 | HLML_INLINEF int2 operator~ (int2 a) { a.m = funcs::notAandB(a.m, consts::vnall2); return a; } 47 | HLML_INLINEF int2 operator& (int2 a, int2 b) { a.m = funcs::AandB(a.m, b.m); return a; } 48 | HLML_INLINEF int2 operator| (int2 a, int2 b) { a.m = funcs::AorB(a.m, b.m); return a; } 49 | HLML_INLINEF int2 operator^ (int2 a, int2 b) { a.m = funcs::AxorB(a.m, b.m); return a; } 50 | HLML_INLINEF int2 operator<< (int2 a, u8 bits) { a.m = funcs::Ashiftl(a.m, bits); return a; } 51 | HLML_INLINEF int2 operator>> (int2 a, u8 bits) { a.m = funcs::Ashiftr(a.m, bits); return a; } 52 | HLML_INLINEF int2& operator<<= (int2& a, u8 bits) { a = a << bits; return a; } 53 | HLML_INLINEF int2& operator>>= (int2& a, u8 bits) { a = a >> bits; return a; } 54 | //arithmetic 55 | HLML_INLINEF int2 operator+ (int2 a) { return a; } 56 | HLML_INLINEF int2 operator- (int2 a) { a.m = funcs::AxorB(a.m, consts::vsignbits_xy); return a; } 57 | HLML_INLINEF int2 operator+ (int2 a, int2 b) { a.m = funcs::AaddB(a.m, b.m); return a; } 58 | HLML_INLINEF int2 operator- (int2 a, int2 b) { a.m = funcs::AsubB(a.m, b.m); return a; } 59 | HLML_INLINEF int2 operator* (int2 a, int2 b) { a.m = funcs::AmulB(a.m, b.m); return a; } 60 | HLML_INLINEF int2 operator+ (int2 a, i32 b) { return a + int2(b); } 61 | HLML_INLINEF int2 operator- (int2 a, i32 b) { return a - int2(b); } 62 | HLML_INLINEF int2 operator* (int2 a, i32 b) { return a * int2(b); } 63 | HLML_INLINEF int2 operator+ (i32 b, int2 a) { return a + b; } 64 | HLML_INLINEF int2 operator- (i32 a, int2 b) { return int2(a) - b; } 65 | HLML_INLINEF int2 operator* (i32 b, int2 a) { return a * b; } 66 | HLML_INLINEF int2& operator+= (int2& a, int2 b) { a = a + b; return a; } 67 | HLML_INLINEF int2& operator-= (int2& a, int2 b) { a = a - b; return a; } 68 | HLML_INLINEF int2& operator*= (int2& a, int2 b) { a = a * b; return a; } 69 | HLML_INLINEF int2& operator+= (int2& a, i32 b) { return a += int2(b); } 70 | HLML_INLINEF int2& operator-= (int2& a, i32 b) { return a -= int2(b); } 71 | HLML_INLINEF int2& operator*= (int2& a, i32 b) { return a *= int2(b); } 72 | //other 73 | HLML_INLINEF int2 abs(int2 v) { v.m = funcs::notAandB(consts::vsignbits_xyzw, v.m); return v; } 74 | HLML_INLINEF int2 minv(int2 a, int2 b) { a.m = funcs::AminB(a.m, b.m); return a; } 75 | HLML_INLINEF int2 maxv(int2 a, int2 b) { a.m = funcs::AmaxB(a.m, b.m); return a; } 76 | HLML_INLINEF int2 sumv(int2 v) { v.m = funcs::AhaddB(v.m, v.m); return v; } 77 | HLML_INLINEF i32 sum(int2 v) { return sumv(v).x(); } 78 | HLML_INLINEF i32 hmin(int2 v) { return minv(v, shufflei2(v, 1, 0)).x(); } 79 | HLML_INLINEF i32 hmax(int2 v) { return maxv(v, shufflei2(v, 1, 0)).x(); } 80 | } 81 | -------------------------------------------------------------------------------- /int3.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "int2.hpp" 4 | #include "bool3.hpp" 5 | 6 | namespace hlml { 7 | struct int3 { 8 | VI128 m = { 0 }; 9 | 10 | HLML_INLINEF int3() {} 11 | HLML_INLINEF explicit int3(VI128 v) : m(v) {} 12 | HLML_INLINEF int3(i32 x, i32 y, i32 z) : int3(funcs::setXYZW(x, y, z, consts::snZero)) {} 13 | HLML_INLINEF int3(int2 v, i32 z) : int3(v.x(), v.y(), z) {} 14 | HLML_INLINEF explicit int3(i32 x) : int3(x, x, x) {} 15 | HLML_INLINEF explicit int3(const i32* p) : int3(p[0], p[1], p[2]) {} 16 | 17 | HLML_INLINEF void store(i32 *p) const { p[0] = x(), p[1] = y(), p[2] = z(); } 18 | 19 | HLML_INLINEF void setX(i32 x) { m = inserti(m, x, 0); } 20 | HLML_INLINEF void setY(i32 y) { m = inserti(m, y, 1); } 21 | HLML_INLINEF void setZ(i32 z) { m = inserti(m, z, 2); } 22 | 23 | HLML_INLINEF i32 x() const { return extracti(m, 0); } 24 | HLML_INLINEF i32 y() const { return extracti(m, 1); } 25 | HLML_INLINEF i32 z() const { return extracti(m, 2); } 26 | 27 | HLML_INLINEF int2 xx() const { return shufflei2(*this, 0, 0); } 28 | HLML_INLINEF int2 xy() const { return shufflei2(*this, 0, 1); } 29 | HLML_INLINEF int2 xz() const { return shufflei2(*this, 0, 2); } 30 | HLML_INLINEF int2 yy() const { return shufflei2(*this, 1, 1); } 31 | HLML_INLINEF int2 yx() const { return shufflei2(*this, 1, 0); } 32 | HLML_INLINEF int2 yz() const { return shufflei2(*this, 1, 2); } 33 | HLML_INLINEF int2 zz() const { return shufflei2(*this, 2, 2); } 34 | HLML_INLINEF int2 zx() const { return shufflei2(*this, 2, 0); } 35 | HLML_INLINEF int2 zy() const { return shufflei2(*this, 2, 1); } 36 | 37 | HLML_INLINEF int3 xxx() const { return shufflei3(*this, 0, 0, 0); } 38 | HLML_INLINEF int3 xxy() const { return shufflei3(*this, 0, 0, 1); } 39 | HLML_INLINEF int3 xxz() const { return shufflei3(*this, 0, 0, 2); } 40 | HLML_INLINEF int3 xyx() const { return shufflei3(*this, 0, 1, 0); } 41 | HLML_INLINEF int3 xyy() const { return shufflei3(*this, 0, 1, 1); } 42 | HLML_INLINEF int3 xyz() const { return shufflei3(*this, 0, 1, 2); } 43 | HLML_INLINEF int3 xzx() const { return shufflei3(*this, 0, 2, 0); } 44 | HLML_INLINEF int3 xzy() const { return shufflei3(*this, 0, 2, 1); } 45 | HLML_INLINEF int3 xzz() const { return shufflei3(*this, 0, 2, 2); } 46 | 47 | HLML_INLINEF int3 yxx() const { return shufflei3(*this, 1, 0, 0); } 48 | HLML_INLINEF int3 yxy() const { return shufflei3(*this, 1, 0, 1); } 49 | HLML_INLINEF int3 yxz() const { return shufflei3(*this, 1, 0, 2); } 50 | HLML_INLINEF int3 yyx() const { return shufflei3(*this, 1, 1, 0); } 51 | HLML_INLINEF int3 yyy() const { return shufflei3(*this, 1, 1, 1); } 52 | HLML_INLINEF int3 yyz() const { return shufflei3(*this, 1, 1, 2); } 53 | HLML_INLINEF int3 yzx() const { return shufflei3(*this, 1, 2, 0); } 54 | HLML_INLINEF int3 yzy() const { return shufflei3(*this, 1, 2, 1); } 55 | HLML_INLINEF int3 yzz() const { return shufflei3(*this, 1, 2, 2); } 56 | 57 | HLML_INLINEF int3 zxx() const { return shufflei3(*this, 2, 0, 0); } 58 | HLML_INLINEF int3 zxy() const { return shufflei3(*this, 2, 0, 1); } 59 | HLML_INLINEF int3 zxz() const { return shufflei3(*this, 2, 0, 2); } 60 | HLML_INLINEF int3 zyx() const { return shufflei3(*this, 2, 1, 0); } 61 | HLML_INLINEF int3 zyy() const { return shufflei3(*this, 2, 1, 1); } 62 | HLML_INLINEF int3 zyz() const { return shufflei3(*this, 2, 1, 2); } 63 | HLML_INLINEF int3 zzx() const { return shufflei3(*this, 2, 2, 0); } 64 | HLML_INLINEF int3 zzy() const { return shufflei3(*this, 2, 2, 1); } 65 | HLML_INLINEF int3 zzz() const { return shufflei3(*this, 2, 2, 2); } 66 | 67 | HLML_INLINEF i32 r() const { return x(); } 68 | HLML_INLINEF i32 g() const { return y(); } 69 | HLML_INLINEF i32 b() const { return z(); } 70 | 71 | HLML_INLINEF int2 rr() const { return xx(); } 72 | HLML_INLINEF int2 rg() const { return xy(); } 73 | HLML_INLINEF int2 rb() const { return xz(); } 74 | HLML_INLINEF int2 gr() const { return yx(); } 75 | HLML_INLINEF int2 gg() const { return yy(); } 76 | HLML_INLINEF int2 gb() const { return yz(); } 77 | HLML_INLINEF int2 br() const { return zx(); } 78 | HLML_INLINEF int2 bg() const { return zy(); } 79 | HLML_INLINEF int2 bb() const { return zz(); } 80 | 81 | HLML_INLINEF int3 rrr() const { return xxx(); } 82 | HLML_INLINEF int3 rrg() const { return xxy(); } 83 | HLML_INLINEF int3 rrb() const { return xxz(); } 84 | HLML_INLINEF int3 rgr() const { return xyx(); } 85 | HLML_INLINEF int3 rgg() const { return xyy(); } 86 | HLML_INLINEF int3 rgb() const { return xyz(); } 87 | HLML_INLINEF int3 rbr() const { return xzx(); } 88 | HLML_INLINEF int3 rbg() const { return xzy(); } 89 | HLML_INLINEF int3 rbb() const { return xzz(); } 90 | HLML_INLINEF int3 grr() const { return yxx(); } 91 | HLML_INLINEF int3 grg() const { return yxy(); } 92 | HLML_INLINEF int3 grb() const { return yxz(); } 93 | HLML_INLINEF int3 ggr() const { return yyx(); } 94 | HLML_INLINEF int3 ggg() const { return yyy(); } 95 | HLML_INLINEF int3 ggb() const { return yyz(); } 96 | HLML_INLINEF int3 gbr() const { return yzx(); } 97 | HLML_INLINEF int3 gbg() const { return yzy(); } 98 | HLML_INLINEF int3 gbb() const { return yzz(); } 99 | HLML_INLINEF int3 brr() const { return zxx(); } 100 | HLML_INLINEF int3 brg() const { return zxy(); } 101 | HLML_INLINEF int3 brb() const { return zxz(); } 102 | HLML_INLINEF int3 bgr() const { return zyx(); } 103 | HLML_INLINEF int3 bgg() const { return zyy(); } 104 | HLML_INLINEF int3 bgb() const { return zyz(); } 105 | HLML_INLINEF int3 bbr() const { return zzx(); } 106 | HLML_INLINEF int3 bbg() const { return zzy(); } 107 | HLML_INLINEF int3 bbb() const { return zzz(); } 108 | }; 109 | //boolean 110 | HLML_INLINEF bool3 operator== (int3 a, int3 b) { return bool3(funcs::AcmpeqB(a.m, b.m)); } 111 | HLML_INLINEF bool3 operator!= (int3 a, int3 b) { return bool3(funcs::AcmpneqB(a.m, b.m)); } 112 | HLML_INLINEF bool3 operator< (int3 a, int3 b) { return bool3(funcs::AcmpltB(a.m, b.m)); } 113 | HLML_INLINEF bool3 operator> (int3 a, int3 b) { return bool3(funcs::AcmpgtB(a.m, b.m)); } 114 | HLML_INLINEF bool3 operator<= (int3 a, int3 b) { return bool3(funcs::AcmpleB(a.m, b.m)); } 115 | HLML_INLINEF bool3 operator>= (int3 a, int3 b) { return bool3(funcs::AcmpgeB(a.m, b.m)); } 116 | //logical 117 | HLML_INLINEF int3 operator~ (int3 a) { a.m = funcs::notAandB(a.m, consts::vnall3); return a; } 118 | HLML_INLINEF int3 operator& (int3 a, int3 b) { a.m = funcs::AandB(a.m, b.m); return a; } 119 | HLML_INLINEF int3 operator| (int3 a, int3 b) { a.m = funcs::AorB(a.m, b.m); return a; } 120 | HLML_INLINEF int3 operator^ (int3 a, int3 b) { a.m = funcs::AxorB(a.m, b.m); return a; } 121 | HLML_INLINEF int3 operator<< (int3 a, u8 bits) { a.m = funcs::Ashiftl(a.m, bits); return a; } 122 | HLML_INLINEF int3 operator>> (int3 a, u8 bits) { a.m = funcs::Ashiftr(a.m, bits); return a; } 123 | HLML_INLINEF int3& operator<<= (int3& a, u8 bits) { a = a << bits; return a; } 124 | HLML_INLINEF int3& operator>>= (int3& a, u8 bits) { a = a >> bits; return a; } 125 | //arithmetic 126 | HLML_INLINEF int3 operator+ (int3 a) { return a; } 127 | HLML_INLINEF int3 operator- (int3 a) { a.m = funcs::AxorB(a.m, consts::vsignbits_xyz); return a; } 128 | HLML_INLINEF int3 operator+ (int3 a, int3 b) { a.m = funcs::AaddB(a.m, b.m); return a; } 129 | HLML_INLINEF int3 operator- (int3 a, int3 b) { a.m = funcs::AsubB(a.m, b.m); return a; } 130 | HLML_INLINEF int3 operator* (int3 a, int3 b) { a.m = funcs::AmulB(a.m, b.m); return a; } 131 | HLML_INLINEF int3 operator+ (int3 a, i32 b) { return a + int3(b); } 132 | HLML_INLINEF int3 operator- (int3 a, i32 b) { return a - int3(b); } 133 | HLML_INLINEF int3 operator* (int3 a, i32 b) { return a * int3(b); } 134 | HLML_INLINEF int3 operator+ (i32 b, int3 a) { return a + b; } 135 | HLML_INLINEF int3 operator- (i32 a, int3 b) { return int3(a) - b; } 136 | HLML_INLINEF int3 operator* (i32 b, int3 a) { return a * b; } 137 | HLML_INLINEF int3& operator+= (int3& a, int3 b) { a = a + b; return a; } 138 | HLML_INLINEF int3& operator-= (int3& a, int3 b) { a = a - b; return a; } 139 | HLML_INLINEF int3& operator*= (int3& a, int3 b) { a = a * b; return a; } 140 | HLML_INLINEF int3& operator+= (int3& a, i32 b) { return a += int3(b); } 141 | HLML_INLINEF int3& operator-= (int3& a, i32 b) { return a -= int3(b); } 142 | HLML_INLINEF int3& operator*= (int3& a, i32 b) { return a *= int3(b); } 143 | //other 144 | HLML_INLINEF int3 abs(int3 v) { v.m = funcs::notAandB(consts::vsignbits_xyzw, v.m); return v; } 145 | HLML_INLINEF int3 minv(int3 a, int3 b) { a.m = funcs::AminB(a.m, b.m); return a; } 146 | HLML_INLINEF int3 maxv(int3 a, int3 b) { a.m = funcs::AmaxB(a.m, b.m); return a; } 147 | HLML_INLINEF int3 sumv(int3 v) { return v + v.zxy() + v.yzx(); } 148 | HLML_INLINEF i32 sum(int3 v) { return sumv(v).x(); } 149 | HLML_INLINEF i32 hmin(int3 v) { 150 | v = minv(v, shufflei3(v, 1, 0, 2)); 151 | return minv(v, shufflei3(v, 2, 0, 1)).x(); 152 | } 153 | HLML_INLINEF i32 hmax(int3 v) { 154 | v = maxv(v, shufflei3(v, 1, 0, 2)); 155 | return maxv(v, shufflei3(v, 2, 0, 1)).x(); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /int4.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "int3.hpp" 4 | #include "bool4.hpp" 5 | 6 | namespace hlml { 7 | struct int4 { 8 | 9 | VI128 m = { 0 }; 10 | 11 | HLML_INLINEF int4() {} 12 | HLML_INLINEF explicit int4(VI128 v) : m(v) {} 13 | HLML_INLINEF int4(i32 x, i32 y, i32 z, i32 w) : m(funcs::setXYZW(x, y, z, w)) {} 14 | HLML_INLINEF int4(int2 v, i32 z, i32 w) : int4(v.x(), v.y(), z, w) {} 15 | HLML_INLINEF int4(int3 v, i32 w) : int4(v.x(), v.y(), v.z(), w) {} 16 | HLML_INLINEF explicit int4(i32 x) : int4(x, x, x, x) {} 17 | HLML_INLINEF explicit int4(const i32 *p) : int4(p[0], p[1], p[2], p[3]) {} 18 | 19 | HLML_INLINEF void store(i32 *p) const { p[0] = x(), p[1] = y(), p[2] = z(), p[3] = w(); } 20 | 21 | HLML_INLINEF void setX(i32 x) { m = inserti(m, x, 0); } 22 | HLML_INLINEF void setY(i32 y) { m = inserti(m, y, 1); } 23 | HLML_INLINEF void setZ(i32 z) { m = inserti(m, z, 2); } 24 | HLML_INLINEF void setW(i32 w) { m = inserti(m, w, 3); } 25 | 26 | HLML_INLINEF i32 x() const { return extracti(m, 0); } 27 | HLML_INLINEF i32 y() const { return extracti(m, 1); } 28 | HLML_INLINEF i32 z() const { return extracti(m, 2); } 29 | HLML_INLINEF i32 w() const { return extracti(m, 3); } 30 | 31 | HLML_INLINEF int2 xx() const { return shufflei2(*this, 0, 0); } 32 | HLML_INLINEF int2 xy() const { return shufflei2(*this, 0, 1); } 33 | HLML_INLINEF int2 xz() const { return shufflei2(*this, 0, 2); } 34 | HLML_INLINEF int2 xw() const { return shufflei2(*this, 0, 3); } 35 | HLML_INLINEF int2 yy() const { return shufflei2(*this, 1, 1); } 36 | HLML_INLINEF int2 yx() const { return shufflei2(*this, 1, 0); } 37 | HLML_INLINEF int2 yz() const { return shufflei2(*this, 1, 2); } 38 | HLML_INLINEF int2 yw() const { return shufflei2(*this, 1, 3); } 39 | HLML_INLINEF int2 zz() const { return shufflei2(*this, 2, 2); } 40 | HLML_INLINEF int2 zx() const { return shufflei2(*this, 2, 0); } 41 | HLML_INLINEF int2 zy() const { return shufflei2(*this, 2, 1); } 42 | HLML_INLINEF int2 zw() const { return shufflei2(*this, 2, 3); } 43 | HLML_INLINEF int2 ww() const { return shufflei2(*this, 3, 3); } 44 | HLML_INLINEF int2 wx() const { return shufflei2(*this, 3, 0); } 45 | HLML_INLINEF int2 wy() const { return shufflei2(*this, 3, 1); } 46 | HLML_INLINEF int2 wz() const { return shufflei2(*this, 3, 2); } 47 | 48 | HLML_INLINEF int3 xxx() const { return shufflei3(*this, 0, 0, 0); } 49 | HLML_INLINEF int3 xxy() const { return shufflei3(*this, 0, 0, 1); } 50 | HLML_INLINEF int3 xxz() const { return shufflei3(*this, 0, 0, 2); } 51 | HLML_INLINEF int3 xxw() const { return shufflei3(*this, 0, 0, 3); } 52 | HLML_INLINEF int3 xyx() const { return shufflei3(*this, 0, 1, 0); } 53 | HLML_INLINEF int3 xyy() const { return shufflei3(*this, 0, 1, 1); } 54 | HLML_INLINEF int3 xyz() const { return shufflei3(*this, 0, 1, 2); } 55 | HLML_INLINEF int3 xyw() const { return shufflei3(*this, 0, 1, 3); } 56 | HLML_INLINEF int3 xzx() const { return shufflei3(*this, 0, 2, 0); } 57 | HLML_INLINEF int3 xzy() const { return shufflei3(*this, 0, 2, 1); } 58 | HLML_INLINEF int3 xzz() const { return shufflei3(*this, 0, 2, 2); } 59 | HLML_INLINEF int3 xzw() const { return shufflei3(*this, 0, 2, 3); } 60 | HLML_INLINEF int3 xwx() const { return shufflei3(*this, 0, 3, 0); } 61 | HLML_INLINEF int3 xwy() const { return shufflei3(*this, 0, 3, 1); } 62 | HLML_INLINEF int3 xwz() const { return shufflei3(*this, 0, 3, 2); } 63 | HLML_INLINEF int3 xww() const { return shufflei3(*this, 0, 3, 3); } 64 | 65 | HLML_INLINEF int3 yxx() const { return shufflei3(*this, 1, 0, 0); } 66 | HLML_INLINEF int3 yxy() const { return shufflei3(*this, 1, 0, 1); } 67 | HLML_INLINEF int3 yxz() const { return shufflei3(*this, 1, 0, 2); } 68 | HLML_INLINEF int3 yxw() const { return shufflei3(*this, 1, 0, 3); } 69 | HLML_INLINEF int3 yyx() const { return shufflei3(*this, 1, 1, 0); } 70 | HLML_INLINEF int3 yyy() const { return shufflei3(*this, 1, 1, 1); } 71 | HLML_INLINEF int3 yyz() const { return shufflei3(*this, 1, 1, 2); } 72 | HLML_INLINEF int3 yyw() const { return shufflei3(*this, 1, 1, 3); } 73 | HLML_INLINEF int3 yzx() const { return shufflei3(*this, 1, 2, 0); } 74 | HLML_INLINEF int3 yzy() const { return shufflei3(*this, 1, 2, 1); } 75 | HLML_INLINEF int3 yzz() const { return shufflei3(*this, 1, 2, 2); } 76 | HLML_INLINEF int3 yzw() const { return shufflei3(*this, 1, 2, 3); } 77 | HLML_INLINEF int3 ywx() const { return shufflei3(*this, 1, 3, 0); } 78 | HLML_INLINEF int3 ywy() const { return shufflei3(*this, 1, 3, 1); } 79 | HLML_INLINEF int3 ywz() const { return shufflei3(*this, 1, 3, 2); } 80 | HLML_INLINEF int3 yww() const { return shufflei3(*this, 1, 3, 3); } 81 | 82 | HLML_INLINEF int3 zxx() const { return shufflei3(*this, 2, 0, 0); } 83 | HLML_INLINEF int3 zxy() const { return shufflei3(*this, 2, 0, 1); } 84 | HLML_INLINEF int3 zxz() const { return shufflei3(*this, 2, 0, 2); } 85 | HLML_INLINEF int3 zxw() const { return shufflei3(*this, 2, 0, 3); } 86 | HLML_INLINEF int3 zyx() const { return shufflei3(*this, 2, 1, 0); } 87 | HLML_INLINEF int3 zyy() const { return shufflei3(*this, 2, 1, 1); } 88 | HLML_INLINEF int3 zyz() const { return shufflei3(*this, 2, 1, 2); } 89 | HLML_INLINEF int3 zyw() const { return shufflei3(*this, 2, 1, 3); } 90 | HLML_INLINEF int3 zzx() const { return shufflei3(*this, 2, 2, 0); } 91 | HLML_INLINEF int3 zzy() const { return shufflei3(*this, 2, 2, 1); } 92 | HLML_INLINEF int3 zzz() const { return shufflei3(*this, 2, 2, 2); } 93 | HLML_INLINEF int3 zzw() const { return shufflei3(*this, 2, 2, 3); } 94 | HLML_INLINEF int3 zwx() const { return shufflei3(*this, 2, 3, 0); } 95 | HLML_INLINEF int3 zwy() const { return shufflei3(*this, 2, 3, 1); } 96 | HLML_INLINEF int3 zwz() const { return shufflei3(*this, 2, 3, 2); } 97 | HLML_INLINEF int3 zww() const { return shufflei3(*this, 2, 3, 3); } 98 | 99 | HLML_INLINEF int3 wxx() const { return shufflei3(*this, 3, 0, 0); } 100 | HLML_INLINEF int3 wxy() const { return shufflei3(*this, 3, 0, 1); } 101 | HLML_INLINEF int3 wxz() const { return shufflei3(*this, 3, 0, 2); } 102 | HLML_INLINEF int3 wxw() const { return shufflei3(*this, 3, 0, 3); } 103 | HLML_INLINEF int3 wyx() const { return shufflei3(*this, 3, 1, 0); } 104 | HLML_INLINEF int3 wyy() const { return shufflei3(*this, 3, 1, 1); } 105 | HLML_INLINEF int3 wyz() const { return shufflei3(*this, 3, 1, 2); } 106 | HLML_INLINEF int3 wyw() const { return shufflei3(*this, 3, 1, 3); } 107 | HLML_INLINEF int3 wzx() const { return shufflei3(*this, 3, 2, 0); } 108 | HLML_INLINEF int3 wzy() const { return shufflei3(*this, 3, 2, 1); } 109 | HLML_INLINEF int3 wzz() const { return shufflei3(*this, 3, 2, 2); } 110 | HLML_INLINEF int3 wzw() const { return shufflei3(*this, 3, 2, 3); } 111 | HLML_INLINEF int3 wwx() const { return shufflei3(*this, 3, 3, 0); } 112 | HLML_INLINEF int3 wwy() const { return shufflei3(*this, 3, 3, 1); } 113 | HLML_INLINEF int3 wwz() const { return shufflei3(*this, 3, 3, 2); } 114 | HLML_INLINEF int3 www() const { return shufflei3(*this, 3, 3, 3); } 115 | 116 | HLML_INLINEF int4 xxxx() const { return shufflei4(*this, 0, 0, 0, 0); } 117 | HLML_INLINEF int4 xxxy() const { return shufflei4(*this, 0, 0, 0, 1); } 118 | HLML_INLINEF int4 xxxz() const { return shufflei4(*this, 0, 0, 0, 2); } 119 | HLML_INLINEF int4 xxxw() const { return shufflei4(*this, 0, 0, 0, 3); } 120 | HLML_INLINEF int4 xxyx() const { return shufflei4(*this, 0, 0, 1, 0); } 121 | HLML_INLINEF int4 xxyy() const { return shufflei4(*this, 0, 0, 1, 1); } 122 | HLML_INLINEF int4 xxyz() const { return shufflei4(*this, 0, 0, 1, 2); } 123 | HLML_INLINEF int4 xxyw() const { return shufflei4(*this, 0, 0, 1, 3); } 124 | HLML_INLINEF int4 xxzx() const { return shufflei4(*this, 0, 0, 2, 0); } 125 | HLML_INLINEF int4 xxzy() const { return shufflei4(*this, 0, 0, 2, 1); } 126 | HLML_INLINEF int4 xxzz() const { return shufflei4(*this, 0, 0, 2, 2); } 127 | HLML_INLINEF int4 xxzw() const { return shufflei4(*this, 0, 0, 2, 3); } 128 | HLML_INLINEF int4 xxwx() const { return shufflei4(*this, 0, 0, 3, 0); } 129 | HLML_INLINEF int4 xxwy() const { return shufflei4(*this, 0, 0, 3, 1); } 130 | HLML_INLINEF int4 xxwz() const { return shufflei4(*this, 0, 0, 3, 2); } 131 | HLML_INLINEF int4 xxww() const { return shufflei4(*this, 0, 0, 3, 3); } 132 | HLML_INLINEF int4 xyxx() const { return shufflei4(*this, 0, 1, 0, 0); } 133 | HLML_INLINEF int4 xyxy() const { return shufflei4(*this, 0, 1, 0, 1); } 134 | HLML_INLINEF int4 xyxz() const { return shufflei4(*this, 0, 1, 0, 2); } 135 | HLML_INLINEF int4 xyxw() const { return shufflei4(*this, 0, 1, 0, 3); } 136 | HLML_INLINEF int4 xyyx() const { return shufflei4(*this, 0, 1, 1, 0); } 137 | HLML_INLINEF int4 xyyy() const { return shufflei4(*this, 0, 1, 1, 1); } 138 | HLML_INLINEF int4 xyyz() const { return shufflei4(*this, 0, 1, 1, 2); } 139 | HLML_INLINEF int4 xyyw() const { return shufflei4(*this, 0, 1, 1, 3); } 140 | HLML_INLINEF int4 xyzx() const { return shufflei4(*this, 0, 1, 2, 0); } 141 | HLML_INLINEF int4 xyzy() const { return shufflei4(*this, 0, 1, 2, 1); } 142 | HLML_INLINEF int4 xyzz() const { return shufflei4(*this, 0, 1, 2, 2); } 143 | HLML_INLINEF int4 xyzw() const { return shufflei4(*this, 0, 1, 2, 3); } 144 | HLML_INLINEF int4 xywx() const { return shufflei4(*this, 0, 1, 3, 0); } 145 | HLML_INLINEF int4 xywy() const { return shufflei4(*this, 0, 1, 3, 1); } 146 | HLML_INLINEF int4 xywz() const { return shufflei4(*this, 0, 1, 3, 2); } 147 | HLML_INLINEF int4 xyww() const { return shufflei4(*this, 0, 1, 3, 3); } 148 | HLML_INLINEF int4 xzxx() const { return shufflei4(*this, 0, 2, 0, 0); } 149 | HLML_INLINEF int4 xzxy() const { return shufflei4(*this, 0, 2, 0, 1); } 150 | HLML_INLINEF int4 xzxz() const { return shufflei4(*this, 0, 2, 0, 2); } 151 | HLML_INLINEF int4 xzxw() const { return shufflei4(*this, 0, 2, 0, 3); } 152 | HLML_INLINEF int4 xzyx() const { return shufflei4(*this, 0, 2, 1, 0); } 153 | HLML_INLINEF int4 xzyy() const { return shufflei4(*this, 0, 2, 1, 1); } 154 | HLML_INLINEF int4 xzyz() const { return shufflei4(*this, 0, 2, 1, 2); } 155 | HLML_INLINEF int4 xzyw() const { return shufflei4(*this, 0, 2, 1, 3); } 156 | HLML_INLINEF int4 xzzx() const { return shufflei4(*this, 0, 2, 2, 0); } 157 | HLML_INLINEF int4 xzzy() const { return shufflei4(*this, 0, 2, 2, 1); } 158 | HLML_INLINEF int4 xzzz() const { return shufflei4(*this, 0, 2, 2, 2); } 159 | HLML_INLINEF int4 xzzw() const { return shufflei4(*this, 0, 2, 2, 3); } 160 | HLML_INLINEF int4 xzwx() const { return shufflei4(*this, 0, 2, 3, 0); } 161 | HLML_INLINEF int4 xzwy() const { return shufflei4(*this, 0, 2, 3, 1); } 162 | HLML_INLINEF int4 xzwz() const { return shufflei4(*this, 0, 2, 3, 2); } 163 | HLML_INLINEF int4 xzww() const { return shufflei4(*this, 0, 2, 3, 3); } 164 | HLML_INLINEF int4 xwxx() const { return shufflei4(*this, 0, 3, 0, 0); } 165 | HLML_INLINEF int4 xwxy() const { return shufflei4(*this, 0, 3, 0, 1); } 166 | HLML_INLINEF int4 xwxz() const { return shufflei4(*this, 0, 3, 0, 2); } 167 | HLML_INLINEF int4 xwxw() const { return shufflei4(*this, 0, 3, 0, 3); } 168 | HLML_INLINEF int4 xwyx() const { return shufflei4(*this, 0, 3, 1, 0); } 169 | HLML_INLINEF int4 xwyy() const { return shufflei4(*this, 0, 3, 1, 1); } 170 | HLML_INLINEF int4 xwyz() const { return shufflei4(*this, 0, 3, 1, 2); } 171 | HLML_INLINEF int4 xwyw() const { return shufflei4(*this, 0, 3, 1, 3); } 172 | HLML_INLINEF int4 xwzx() const { return shufflei4(*this, 0, 3, 2, 0); } 173 | HLML_INLINEF int4 xwzy() const { return shufflei4(*this, 0, 3, 2, 1); } 174 | HLML_INLINEF int4 xwzz() const { return shufflei4(*this, 0, 3, 2, 2); } 175 | HLML_INLINEF int4 xwzw() const { return shufflei4(*this, 0, 3, 2, 3); } 176 | HLML_INLINEF int4 xwwx() const { return shufflei4(*this, 0, 3, 3, 0); } 177 | HLML_INLINEF int4 xwwy() const { return shufflei4(*this, 0, 3, 3, 1); } 178 | HLML_INLINEF int4 xwwz() const { return shufflei4(*this, 0, 3, 3, 2); } 179 | HLML_INLINEF int4 xwww() const { return shufflei4(*this, 0, 3, 3, 3); } 180 | 181 | HLML_INLINEF int4 yxxx() const { return shufflei4(*this, 1, 0, 0, 0); } 182 | HLML_INLINEF int4 yxxy() const { return shufflei4(*this, 1, 0, 0, 1); } 183 | HLML_INLINEF int4 yxxz() const { return shufflei4(*this, 1, 0, 0, 2); } 184 | HLML_INLINEF int4 yxxw() const { return shufflei4(*this, 1, 0, 0, 3); } 185 | HLML_INLINEF int4 yxyx() const { return shufflei4(*this, 1, 0, 1, 0); } 186 | HLML_INLINEF int4 yxyy() const { return shufflei4(*this, 1, 0, 1, 1); } 187 | HLML_INLINEF int4 yxyz() const { return shufflei4(*this, 1, 0, 1, 2); } 188 | HLML_INLINEF int4 yxyw() const { return shufflei4(*this, 1, 0, 1, 3); } 189 | HLML_INLINEF int4 yxzx() const { return shufflei4(*this, 1, 0, 2, 0); } 190 | HLML_INLINEF int4 yxzy() const { return shufflei4(*this, 1, 0, 2, 1); } 191 | HLML_INLINEF int4 yxzz() const { return shufflei4(*this, 1, 0, 2, 2); } 192 | HLML_INLINEF int4 yxzw() const { return shufflei4(*this, 1, 0, 2, 3); } 193 | HLML_INLINEF int4 yxwx() const { return shufflei4(*this, 1, 0, 3, 0); } 194 | HLML_INLINEF int4 yxwy() const { return shufflei4(*this, 1, 0, 3, 1); } 195 | HLML_INLINEF int4 yxwz() const { return shufflei4(*this, 1, 0, 3, 2); } 196 | HLML_INLINEF int4 yxww() const { return shufflei4(*this, 1, 0, 3, 3); } 197 | HLML_INLINEF int4 yyxx() const { return shufflei4(*this, 1, 1, 0, 0); } 198 | HLML_INLINEF int4 yyxy() const { return shufflei4(*this, 1, 1, 0, 1); } 199 | HLML_INLINEF int4 yyxz() const { return shufflei4(*this, 1, 1, 0, 2); } 200 | HLML_INLINEF int4 yyxw() const { return shufflei4(*this, 1, 1, 0, 3); } 201 | HLML_INLINEF int4 yyyx() const { return shufflei4(*this, 1, 1, 1, 0); } 202 | HLML_INLINEF int4 yyyy() const { return shufflei4(*this, 1, 1, 1, 1); } 203 | HLML_INLINEF int4 yyyz() const { return shufflei4(*this, 1, 1, 1, 2); } 204 | HLML_INLINEF int4 yyyw() const { return shufflei4(*this, 1, 1, 1, 3); } 205 | HLML_INLINEF int4 yyzx() const { return shufflei4(*this, 1, 1, 2, 0); } 206 | HLML_INLINEF int4 yyzy() const { return shufflei4(*this, 1, 1, 2, 1); } 207 | HLML_INLINEF int4 yyzz() const { return shufflei4(*this, 1, 1, 2, 2); } 208 | HLML_INLINEF int4 yyzw() const { return shufflei4(*this, 1, 1, 2, 3); } 209 | HLML_INLINEF int4 yywx() const { return shufflei4(*this, 1, 1, 3, 0); } 210 | HLML_INLINEF int4 yywy() const { return shufflei4(*this, 1, 1, 3, 1); } 211 | HLML_INLINEF int4 yywz() const { return shufflei4(*this, 1, 1, 3, 2); } 212 | HLML_INLINEF int4 yyww() const { return shufflei4(*this, 1, 1, 3, 3); } 213 | HLML_INLINEF int4 yzxx() const { return shufflei4(*this, 1, 2, 0, 0); } 214 | HLML_INLINEF int4 yzxy() const { return shufflei4(*this, 1, 2, 0, 1); } 215 | HLML_INLINEF int4 yzxz() const { return shufflei4(*this, 1, 2, 0, 2); } 216 | HLML_INLINEF int4 yzxw() const { return shufflei4(*this, 1, 2, 0, 3); } 217 | HLML_INLINEF int4 yzyx() const { return shufflei4(*this, 1, 2, 1, 0); } 218 | HLML_INLINEF int4 yzyy() const { return shufflei4(*this, 1, 2, 1, 1); } 219 | HLML_INLINEF int4 yzyz() const { return shufflei4(*this, 1, 2, 1, 2); } 220 | HLML_INLINEF int4 yzyw() const { return shufflei4(*this, 1, 2, 1, 3); } 221 | HLML_INLINEF int4 yzzx() const { return shufflei4(*this, 1, 2, 2, 0); } 222 | HLML_INLINEF int4 yzzy() const { return shufflei4(*this, 1, 2, 2, 1); } 223 | HLML_INLINEF int4 yzzz() const { return shufflei4(*this, 1, 2, 2, 2); } 224 | HLML_INLINEF int4 yzzw() const { return shufflei4(*this, 1, 2, 2, 3); } 225 | HLML_INLINEF int4 yzwx() const { return shufflei4(*this, 1, 2, 3, 0); } 226 | HLML_INLINEF int4 yzwy() const { return shufflei4(*this, 1, 2, 3, 1); } 227 | HLML_INLINEF int4 yzwz() const { return shufflei4(*this, 1, 2, 3, 2); } 228 | HLML_INLINEF int4 yzww() const { return shufflei4(*this, 1, 2, 3, 3); } 229 | HLML_INLINEF int4 ywxx() const { return shufflei4(*this, 1, 3, 0, 0); } 230 | HLML_INLINEF int4 ywxy() const { return shufflei4(*this, 1, 3, 0, 1); } 231 | HLML_INLINEF int4 ywxz() const { return shufflei4(*this, 1, 3, 0, 2); } 232 | HLML_INLINEF int4 ywxw() const { return shufflei4(*this, 1, 3, 0, 3); } 233 | HLML_INLINEF int4 ywyx() const { return shufflei4(*this, 1, 3, 1, 0); } 234 | HLML_INLINEF int4 ywyy() const { return shufflei4(*this, 1, 3, 1, 1); } 235 | HLML_INLINEF int4 ywyz() const { return shufflei4(*this, 1, 3, 1, 2); } 236 | HLML_INLINEF int4 ywyw() const { return shufflei4(*this, 1, 3, 1, 3); } 237 | HLML_INLINEF int4 ywzx() const { return shufflei4(*this, 1, 3, 2, 0); } 238 | HLML_INLINEF int4 ywzy() const { return shufflei4(*this, 1, 3, 2, 1); } 239 | HLML_INLINEF int4 ywzz() const { return shufflei4(*this, 1, 3, 2, 2); } 240 | HLML_INLINEF int4 ywzw() const { return shufflei4(*this, 1, 3, 2, 3); } 241 | HLML_INLINEF int4 ywwx() const { return shufflei4(*this, 1, 3, 3, 0); } 242 | HLML_INLINEF int4 ywwy() const { return shufflei4(*this, 1, 3, 3, 1); } 243 | HLML_INLINEF int4 ywwz() const { return shufflei4(*this, 1, 3, 3, 2); } 244 | HLML_INLINEF int4 ywww() const { return shufflei4(*this, 1, 3, 3, 3); } 245 | 246 | HLML_INLINEF int4 zxxx() const { return shufflei4(*this, 2, 0, 0, 0); } 247 | HLML_INLINEF int4 zxxy() const { return shufflei4(*this, 2, 0, 0, 1); } 248 | HLML_INLINEF int4 zxxz() const { return shufflei4(*this, 2, 0, 0, 2); } 249 | HLML_INLINEF int4 zxxw() const { return shufflei4(*this, 2, 0, 0, 3); } 250 | HLML_INLINEF int4 zxyx() const { return shufflei4(*this, 2, 0, 1, 0); } 251 | HLML_INLINEF int4 zxyy() const { return shufflei4(*this, 2, 0, 1, 1); } 252 | HLML_INLINEF int4 zxyz() const { return shufflei4(*this, 2, 0, 1, 2); } 253 | HLML_INLINEF int4 zxyw() const { return shufflei4(*this, 2, 0, 1, 3); } 254 | HLML_INLINEF int4 zxzx() const { return shufflei4(*this, 2, 0, 2, 0); } 255 | HLML_INLINEF int4 zxzy() const { return shufflei4(*this, 2, 0, 2, 1); } 256 | HLML_INLINEF int4 zxzz() const { return shufflei4(*this, 2, 0, 2, 2); } 257 | HLML_INLINEF int4 zxzw() const { return shufflei4(*this, 2, 0, 2, 3); } 258 | HLML_INLINEF int4 zxwx() const { return shufflei4(*this, 2, 0, 3, 0); } 259 | HLML_INLINEF int4 zxwy() const { return shufflei4(*this, 2, 0, 3, 1); } 260 | HLML_INLINEF int4 zxwz() const { return shufflei4(*this, 2, 0, 3, 2); } 261 | HLML_INLINEF int4 zxww() const { return shufflei4(*this, 2, 0, 3, 3); } 262 | HLML_INLINEF int4 zyxx() const { return shufflei4(*this, 2, 1, 0, 0); } 263 | HLML_INLINEF int4 zyxy() const { return shufflei4(*this, 2, 1, 0, 1); } 264 | HLML_INLINEF int4 zyxz() const { return shufflei4(*this, 2, 1, 0, 2); } 265 | HLML_INLINEF int4 zyxw() const { return shufflei4(*this, 2, 1, 0, 3); } 266 | HLML_INLINEF int4 zyyx() const { return shufflei4(*this, 2, 1, 1, 0); } 267 | HLML_INLINEF int4 zyyy() const { return shufflei4(*this, 2, 1, 1, 1); } 268 | HLML_INLINEF int4 zyyz() const { return shufflei4(*this, 2, 1, 1, 2); } 269 | HLML_INLINEF int4 zyyw() const { return shufflei4(*this, 2, 1, 1, 3); } 270 | HLML_INLINEF int4 zyzx() const { return shufflei4(*this, 2, 1, 2, 0); } 271 | HLML_INLINEF int4 zyzy() const { return shufflei4(*this, 2, 1, 2, 1); } 272 | HLML_INLINEF int4 zyzz() const { return shufflei4(*this, 2, 1, 2, 2); } 273 | HLML_INLINEF int4 zyzw() const { return shufflei4(*this, 2, 1, 2, 3); } 274 | HLML_INLINEF int4 zywx() const { return shufflei4(*this, 2, 1, 3, 0); } 275 | HLML_INLINEF int4 zywy() const { return shufflei4(*this, 2, 1, 3, 1); } 276 | HLML_INLINEF int4 zywz() const { return shufflei4(*this, 2, 1, 3, 2); } 277 | HLML_INLINEF int4 zyww() const { return shufflei4(*this, 2, 1, 3, 3); } 278 | HLML_INLINEF int4 zzxx() const { return shufflei4(*this, 2, 2, 0, 0); } 279 | HLML_INLINEF int4 zzxy() const { return shufflei4(*this, 2, 2, 0, 1); } 280 | HLML_INLINEF int4 zzxz() const { return shufflei4(*this, 2, 2, 0, 2); } 281 | HLML_INLINEF int4 zzxw() const { return shufflei4(*this, 2, 2, 0, 3); } 282 | HLML_INLINEF int4 zzyx() const { return shufflei4(*this, 2, 2, 1, 0); } 283 | HLML_INLINEF int4 zzyy() const { return shufflei4(*this, 2, 2, 1, 1); } 284 | HLML_INLINEF int4 zzyz() const { return shufflei4(*this, 2, 2, 1, 2); } 285 | HLML_INLINEF int4 zzyw() const { return shufflei4(*this, 2, 2, 1, 3); } 286 | HLML_INLINEF int4 zzzx() const { return shufflei4(*this, 2, 2, 2, 0); } 287 | HLML_INLINEF int4 zzzy() const { return shufflei4(*this, 2, 2, 2, 1); } 288 | HLML_INLINEF int4 zzzz() const { return shufflei4(*this, 2, 2, 2, 2); } 289 | HLML_INLINEF int4 zzzw() const { return shufflei4(*this, 2, 2, 2, 3); } 290 | HLML_INLINEF int4 zzwx() const { return shufflei4(*this, 2, 2, 3, 0); } 291 | HLML_INLINEF int4 zzwy() const { return shufflei4(*this, 2, 2, 3, 1); } 292 | HLML_INLINEF int4 zzwz() const { return shufflei4(*this, 2, 2, 3, 2); } 293 | HLML_INLINEF int4 zzww() const { return shufflei4(*this, 2, 2, 3, 3); } 294 | HLML_INLINEF int4 zwxx() const { return shufflei4(*this, 2, 3, 0, 0); } 295 | HLML_INLINEF int4 zwxy() const { return shufflei4(*this, 2, 3, 0, 1); } 296 | HLML_INLINEF int4 zwxz() const { return shufflei4(*this, 2, 3, 0, 2); } 297 | HLML_INLINEF int4 zwxw() const { return shufflei4(*this, 2, 3, 0, 3); } 298 | HLML_INLINEF int4 zwyx() const { return shufflei4(*this, 2, 3, 1, 0); } 299 | HLML_INLINEF int4 zwyy() const { return shufflei4(*this, 2, 3, 1, 1); } 300 | HLML_INLINEF int4 zwyz() const { return shufflei4(*this, 2, 3, 1, 2); } 301 | HLML_INLINEF int4 zwyw() const { return shufflei4(*this, 2, 3, 1, 3); } 302 | HLML_INLINEF int4 zwzx() const { return shufflei4(*this, 2, 3, 2, 0); } 303 | HLML_INLINEF int4 zwzy() const { return shufflei4(*this, 2, 3, 2, 1); } 304 | HLML_INLINEF int4 zwzz() const { return shufflei4(*this, 2, 3, 2, 2); } 305 | HLML_INLINEF int4 zwzw() const { return shufflei4(*this, 2, 3, 2, 3); } 306 | HLML_INLINEF int4 zwwx() const { return shufflei4(*this, 2, 3, 3, 0); } 307 | HLML_INLINEF int4 zwwy() const { return shufflei4(*this, 2, 3, 3, 1); } 308 | HLML_INLINEF int4 zwwz() const { return shufflei4(*this, 2, 3, 3, 2); } 309 | HLML_INLINEF int4 zwww() const { return shufflei4(*this, 2, 3, 3, 3); } 310 | 311 | HLML_INLINEF int4 wxxx() const { return shufflei4(*this, 3, 0, 0, 0); } 312 | HLML_INLINEF int4 wxxy() const { return shufflei4(*this, 3, 0, 0, 1); } 313 | HLML_INLINEF int4 wxxz() const { return shufflei4(*this, 3, 0, 0, 2); } 314 | HLML_INLINEF int4 wxxw() const { return shufflei4(*this, 3, 0, 0, 3); } 315 | HLML_INLINEF int4 wxyx() const { return shufflei4(*this, 3, 0, 1, 0); } 316 | HLML_INLINEF int4 wxyy() const { return shufflei4(*this, 3, 0, 1, 1); } 317 | HLML_INLINEF int4 wxyz() const { return shufflei4(*this, 3, 0, 1, 2); } 318 | HLML_INLINEF int4 wxyw() const { return shufflei4(*this, 3, 0, 1, 3); } 319 | HLML_INLINEF int4 wxzx() const { return shufflei4(*this, 3, 0, 2, 0); } 320 | HLML_INLINEF int4 wxzy() const { return shufflei4(*this, 3, 0, 2, 1); } 321 | HLML_INLINEF int4 wxzz() const { return shufflei4(*this, 3, 0, 2, 2); } 322 | HLML_INLINEF int4 wxzw() const { return shufflei4(*this, 3, 0, 2, 3); } 323 | HLML_INLINEF int4 wxwx() const { return shufflei4(*this, 3, 0, 3, 0); } 324 | HLML_INLINEF int4 wxwy() const { return shufflei4(*this, 3, 0, 3, 1); } 325 | HLML_INLINEF int4 wxwz() const { return shufflei4(*this, 3, 0, 3, 2); } 326 | HLML_INLINEF int4 wxww() const { return shufflei4(*this, 3, 0, 3, 3); } 327 | HLML_INLINEF int4 wyxx() const { return shufflei4(*this, 3, 1, 0, 0); } 328 | HLML_INLINEF int4 wyxy() const { return shufflei4(*this, 3, 1, 0, 1); } 329 | HLML_INLINEF int4 wyxz() const { return shufflei4(*this, 3, 1, 0, 2); } 330 | HLML_INLINEF int4 wyxw() const { return shufflei4(*this, 3, 1, 0, 3); } 331 | HLML_INLINEF int4 wyyx() const { return shufflei4(*this, 3, 1, 1, 0); } 332 | HLML_INLINEF int4 wyyy() const { return shufflei4(*this, 3, 1, 1, 1); } 333 | HLML_INLINEF int4 wyyz() const { return shufflei4(*this, 3, 1, 1, 2); } 334 | HLML_INLINEF int4 wyyw() const { return shufflei4(*this, 3, 1, 1, 3); } 335 | HLML_INLINEF int4 wyzx() const { return shufflei4(*this, 3, 1, 2, 0); } 336 | HLML_INLINEF int4 wyzy() const { return shufflei4(*this, 3, 1, 2, 1); } 337 | HLML_INLINEF int4 wyzz() const { return shufflei4(*this, 3, 1, 2, 2); } 338 | HLML_INLINEF int4 wyzw() const { return shufflei4(*this, 3, 1, 2, 3); } 339 | HLML_INLINEF int4 wywx() const { return shufflei4(*this, 3, 1, 3, 0); } 340 | HLML_INLINEF int4 wywy() const { return shufflei4(*this, 3, 1, 3, 1); } 341 | HLML_INLINEF int4 wywz() const { return shufflei4(*this, 3, 1, 3, 2); } 342 | HLML_INLINEF int4 wyww() const { return shufflei4(*this, 3, 1, 3, 3); } 343 | HLML_INLINEF int4 wzxx() const { return shufflei4(*this, 3, 2, 0, 0); } 344 | HLML_INLINEF int4 wzxy() const { return shufflei4(*this, 3, 2, 0, 1); } 345 | HLML_INLINEF int4 wzxz() const { return shufflei4(*this, 3, 2, 0, 2); } 346 | HLML_INLINEF int4 wzxw() const { return shufflei4(*this, 3, 2, 0, 3); } 347 | HLML_INLINEF int4 wzyx() const { return shufflei4(*this, 3, 2, 1, 0); } 348 | HLML_INLINEF int4 wzyy() const { return shufflei4(*this, 3, 2, 1, 1); } 349 | HLML_INLINEF int4 wzyz() const { return shufflei4(*this, 3, 2, 1, 2); } 350 | HLML_INLINEF int4 wzyw() const { return shufflei4(*this, 3, 2, 1, 3); } 351 | HLML_INLINEF int4 wzzx() const { return shufflei4(*this, 3, 2, 2, 0); } 352 | HLML_INLINEF int4 wzzy() const { return shufflei4(*this, 3, 2, 2, 1); } 353 | HLML_INLINEF int4 wzzz() const { return shufflei4(*this, 3, 2, 2, 2); } 354 | HLML_INLINEF int4 wzzw() const { return shufflei4(*this, 3, 2, 2, 3); } 355 | HLML_INLINEF int4 wzwx() const { return shufflei4(*this, 3, 2, 3, 0); } 356 | HLML_INLINEF int4 wzwy() const { return shufflei4(*this, 3, 2, 3, 1); } 357 | HLML_INLINEF int4 wzwz() const { return shufflei4(*this, 3, 2, 3, 2); } 358 | HLML_INLINEF int4 wzww() const { return shufflei4(*this, 3, 2, 3, 3); } 359 | HLML_INLINEF int4 wwxx() const { return shufflei4(*this, 3, 3, 0, 0); } 360 | HLML_INLINEF int4 wwxy() const { return shufflei4(*this, 3, 3, 0, 1); } 361 | HLML_INLINEF int4 wwxz() const { return shufflei4(*this, 3, 3, 0, 2); } 362 | HLML_INLINEF int4 wwxw() const { return shufflei4(*this, 3, 3, 0, 3); } 363 | HLML_INLINEF int4 wwyx() const { return shufflei4(*this, 3, 3, 1, 0); } 364 | HLML_INLINEF int4 wwyy() const { return shufflei4(*this, 3, 3, 1, 1); } 365 | HLML_INLINEF int4 wwyz() const { return shufflei4(*this, 3, 3, 1, 2); } 366 | HLML_INLINEF int4 wwyw() const { return shufflei4(*this, 3, 3, 1, 3); } 367 | HLML_INLINEF int4 wwzx() const { return shufflei4(*this, 3, 3, 2, 0); } 368 | HLML_INLINEF int4 wwzy() const { return shufflei4(*this, 3, 3, 2, 1); } 369 | HLML_INLINEF int4 wwzz() const { return shufflei4(*this, 3, 3, 2, 2); } 370 | HLML_INLINEF int4 wwzw() const { return shufflei4(*this, 3, 3, 2, 3); } 371 | HLML_INLINEF int4 wwwx() const { return shufflei4(*this, 3, 3, 3, 0); } 372 | HLML_INLINEF int4 wwwy() const { return shufflei4(*this, 3, 3, 3, 1); } 373 | HLML_INLINEF int4 wwwz() const { return shufflei4(*this, 3, 3, 3, 2); } 374 | HLML_INLINEF int4 wwww() const { return shufflei4(*this, 3, 3, 3, 3); } 375 | 376 | HLML_INLINEF i32 r() const { return x(); } 377 | HLML_INLINEF i32 g() const { return y(); } 378 | HLML_INLINEF i32 b() const { return z(); } 379 | HLML_INLINEF i32 a() const { return w(); } 380 | 381 | HLML_INLINEF int2 rr() const { return xx(); } 382 | HLML_INLINEF int2 rg() const { return xy(); } 383 | HLML_INLINEF int2 rb() const { return xz(); } 384 | HLML_INLINEF int2 ra() const { return xw(); } 385 | HLML_INLINEF int2 gr() const { return yx(); } 386 | HLML_INLINEF int2 gg() const { return yy(); } 387 | HLML_INLINEF int2 gb() const { return yz(); } 388 | HLML_INLINEF int2 ga() const { return yw(); } 389 | HLML_INLINEF int2 br() const { return zx(); } 390 | HLML_INLINEF int2 bg() const { return zy(); } 391 | HLML_INLINEF int2 bb() const { return zz(); } 392 | HLML_INLINEF int2 ba() const { return zw(); } 393 | HLML_INLINEF int2 ar() const { return wx(); } 394 | HLML_INLINEF int2 ag() const { return wy(); } 395 | HLML_INLINEF int2 ab() const { return wz(); } 396 | HLML_INLINEF int2 aa() const { return ww(); } 397 | 398 | HLML_INLINEF int3 rrr() const { return xxx(); } 399 | HLML_INLINEF int3 rrg() const { return xxy(); } 400 | HLML_INLINEF int3 rrb() const { return xxz(); } 401 | HLML_INLINEF int3 rra() const { return xxw(); } 402 | HLML_INLINEF int3 rgr() const { return xyx(); } 403 | HLML_INLINEF int3 rgg() const { return xyy(); } 404 | HLML_INLINEF int3 rgb() const { return xyz(); } 405 | HLML_INLINEF int3 rga() const { return xyw(); } 406 | HLML_INLINEF int3 rbr() const { return xzx(); } 407 | HLML_INLINEF int3 rbg() const { return xzy(); } 408 | HLML_INLINEF int3 rbb() const { return xzz(); } 409 | HLML_INLINEF int3 rba() const { return xzw(); } 410 | HLML_INLINEF int3 rar() const { return xwx(); } 411 | HLML_INLINEF int3 rag() const { return xwy(); } 412 | HLML_INLINEF int3 rab() const { return xwz(); } 413 | HLML_INLINEF int3 raa() const { return xww(); } 414 | HLML_INLINEF int3 grr() const { return yxx(); } 415 | HLML_INLINEF int3 grg() const { return yxy(); } 416 | HLML_INLINEF int3 grb() const { return yxz(); } 417 | HLML_INLINEF int3 gra() const { return yxw(); } 418 | HLML_INLINEF int3 ggr() const { return yyx(); } 419 | HLML_INLINEF int3 ggg() const { return yyy(); } 420 | HLML_INLINEF int3 ggb() const { return yyz(); } 421 | HLML_INLINEF int3 gga() const { return yyw(); } 422 | HLML_INLINEF int3 gbr() const { return yzx(); } 423 | HLML_INLINEF int3 gbg() const { return yzy(); } 424 | HLML_INLINEF int3 gbb() const { return yzz(); } 425 | HLML_INLINEF int3 gba() const { return yzw(); } 426 | HLML_INLINEF int3 gar() const { return ywx(); } 427 | HLML_INLINEF int3 gag() const { return ywy(); } 428 | HLML_INLINEF int3 gab() const { return ywz(); } 429 | HLML_INLINEF int3 gaa() const { return yww(); } 430 | HLML_INLINEF int3 brr() const { return zxx(); } 431 | HLML_INLINEF int3 brg() const { return zxy(); } 432 | HLML_INLINEF int3 brb() const { return zxz(); } 433 | HLML_INLINEF int3 bra() const { return zxw(); } 434 | HLML_INLINEF int3 bgr() const { return zyx(); } 435 | HLML_INLINEF int3 bgg() const { return zyy(); } 436 | HLML_INLINEF int3 bgb() const { return zyz(); } 437 | HLML_INLINEF int3 bga() const { return zyw(); } 438 | HLML_INLINEF int3 bbr() const { return zzx(); } 439 | HLML_INLINEF int3 bbg() const { return zzy(); } 440 | HLML_INLINEF int3 bbb() const { return zzz(); } 441 | HLML_INLINEF int3 bba() const { return zzw(); } 442 | HLML_INLINEF int3 bar() const { return zwx(); } 443 | HLML_INLINEF int3 bag() const { return zwy(); } 444 | HLML_INLINEF int3 bab() const { return zwz(); } 445 | HLML_INLINEF int3 baa() const { return zww(); } 446 | 447 | HLML_INLINEF int4 rrrr() const { return xxxx(); } 448 | HLML_INLINEF int4 rrrg() const { return xxxy(); } 449 | HLML_INLINEF int4 rrrb() const { return xxxz(); } 450 | HLML_INLINEF int4 rrra() const { return xxxw(); } 451 | HLML_INLINEF int4 rrgr() const { return xxyx(); } 452 | HLML_INLINEF int4 rrgg() const { return xxyy(); } 453 | HLML_INLINEF int4 rrgb() const { return xxyz(); } 454 | HLML_INLINEF int4 rrga() const { return xxyw(); } 455 | HLML_INLINEF int4 rrbr() const { return xxzx(); } 456 | HLML_INLINEF int4 rrbg() const { return xxzy(); } 457 | HLML_INLINEF int4 rrbb() const { return xxzz(); } 458 | HLML_INLINEF int4 rrba() const { return xxzw(); } 459 | HLML_INLINEF int4 rrar() const { return xxwx(); } 460 | HLML_INLINEF int4 rrag() const { return xxwy(); } 461 | HLML_INLINEF int4 rrab() const { return xxwz(); } 462 | HLML_INLINEF int4 rraa() const { return xxww(); } 463 | HLML_INLINEF int4 rgrr() const { return xyxx(); } 464 | HLML_INLINEF int4 rgrg() const { return xyxy(); } 465 | HLML_INLINEF int4 rgrb() const { return xyxz(); } 466 | HLML_INLINEF int4 rgra() const { return xyxy(); } 467 | HLML_INLINEF int4 rggr() const { return xyyx(); } 468 | HLML_INLINEF int4 rggg() const { return xyyy(); } 469 | HLML_INLINEF int4 rggb() const { return xyyz(); } 470 | HLML_INLINEF int4 rgga() const { return xyyw(); } 471 | HLML_INLINEF int4 rgbr() const { return xyzx(); } 472 | HLML_INLINEF int4 rgbg() const { return xyzy(); } 473 | HLML_INLINEF int4 rgbb() const { return xyzz(); } 474 | HLML_INLINEF int4 rgba() const { return xyzw(); } 475 | HLML_INLINEF int4 rgar() const { return xywx(); } 476 | HLML_INLINEF int4 rgag() const { return xywy(); } 477 | HLML_INLINEF int4 rgab() const { return xywz(); } 478 | HLML_INLINEF int4 rgaa() const { return xyww(); } 479 | HLML_INLINEF int4 rbrr() const { return xzxx(); } 480 | HLML_INLINEF int4 rbrg() const { return xzxy(); } 481 | HLML_INLINEF int4 rbrb() const { return xzxz(); } 482 | HLML_INLINEF int4 rbra() const { return xzxw(); } 483 | HLML_INLINEF int4 rbgr() const { return xzyx(); } 484 | HLML_INLINEF int4 rbgg() const { return xzyy(); } 485 | HLML_INLINEF int4 rbgb() const { return xzyz(); } 486 | HLML_INLINEF int4 rbga() const { return xzyw(); } 487 | HLML_INLINEF int4 rbbr() const { return xzzx(); } 488 | HLML_INLINEF int4 rbbg() const { return xzzy(); } 489 | HLML_INLINEF int4 rbbb() const { return xzzz(); } 490 | HLML_INLINEF int4 rbba() const { return xzzw(); } 491 | HLML_INLINEF int4 rbar() const { return xzwx(); } 492 | HLML_INLINEF int4 rbag() const { return xzwy(); } 493 | HLML_INLINEF int4 rbab() const { return xzwz(); } 494 | HLML_INLINEF int4 rbaa() const { return xzww(); } 495 | HLML_INLINEF int4 rarr() const { return xwxx(); } 496 | HLML_INLINEF int4 rarg() const { return xwxy(); } 497 | HLML_INLINEF int4 rarb() const { return xwxz(); } 498 | HLML_INLINEF int4 rara() const { return xwxw(); } 499 | HLML_INLINEF int4 ragr() const { return xwyx(); } 500 | HLML_INLINEF int4 ragg() const { return xwyy(); } 501 | HLML_INLINEF int4 ragb() const { return xwyz(); } 502 | HLML_INLINEF int4 raga() const { return xwyw(); } 503 | HLML_INLINEF int4 rabr() const { return xwzx(); } 504 | HLML_INLINEF int4 rabg() const { return xwzy(); } 505 | HLML_INLINEF int4 rabb() const { return xwzz(); } 506 | HLML_INLINEF int4 raba() const { return xwzw(); } 507 | HLML_INLINEF int4 raar() const { return xwwx(); } 508 | HLML_INLINEF int4 raag() const { return xwwy(); } 509 | HLML_INLINEF int4 raab() const { return xwwz(); } 510 | HLML_INLINEF int4 raaa() const { return xwww(); } 511 | 512 | HLML_INLINEF int4 grrr() const { return yxxx(); } 513 | HLML_INLINEF int4 grrg() const { return yxxy(); } 514 | HLML_INLINEF int4 grrb() const { return yxxz(); } 515 | HLML_INLINEF int4 grra() const { return yxxw(); } 516 | HLML_INLINEF int4 grgr() const { return yxyx(); } 517 | HLML_INLINEF int4 grgg() const { return yxyy(); } 518 | HLML_INLINEF int4 grgb() const { return yxyz(); } 519 | HLML_INLINEF int4 grga() const { return yxyw(); } 520 | HLML_INLINEF int4 grbr() const { return yxzx(); } 521 | HLML_INLINEF int4 grbg() const { return yxzy(); } 522 | HLML_INLINEF int4 grbb() const { return yxzz(); } 523 | HLML_INLINEF int4 grba() const { return yxzw(); } 524 | HLML_INLINEF int4 grar() const { return yxwx(); } 525 | HLML_INLINEF int4 grag() const { return yxwy(); } 526 | HLML_INLINEF int4 grab() const { return yxwz(); } 527 | HLML_INLINEF int4 graa() const { return yxww(); } 528 | HLML_INLINEF int4 ggrr() const { return yyxx(); } 529 | HLML_INLINEF int4 ggrg() const { return yyxy(); } 530 | HLML_INLINEF int4 ggrb() const { return yyxz(); } 531 | HLML_INLINEF int4 ggra() const { return yyxy(); } 532 | HLML_INLINEF int4 gggr() const { return yyyx(); } 533 | HLML_INLINEF int4 gggg() const { return yyyy(); } 534 | HLML_INLINEF int4 gggb() const { return yyyz(); } 535 | HLML_INLINEF int4 ggga() const { return yyyw(); } 536 | HLML_INLINEF int4 ggbr() const { return yyzx(); } 537 | HLML_INLINEF int4 ggbg() const { return yyzy(); } 538 | HLML_INLINEF int4 ggbb() const { return yyzz(); } 539 | HLML_INLINEF int4 ggba() const { return yyzw(); } 540 | HLML_INLINEF int4 ggar() const { return yywx(); } 541 | HLML_INLINEF int4 ggag() const { return yywy(); } 542 | HLML_INLINEF int4 ggab() const { return yywz(); } 543 | HLML_INLINEF int4 ggaa() const { return yyww(); } 544 | HLML_INLINEF int4 gbrr() const { return yzxx(); } 545 | HLML_INLINEF int4 gbrg() const { return yzxy(); } 546 | HLML_INLINEF int4 gbrb() const { return yzxz(); } 547 | HLML_INLINEF int4 gbra() const { return yzxw(); } 548 | HLML_INLINEF int4 gbgr() const { return yzyx(); } 549 | HLML_INLINEF int4 gbgg() const { return yzyy(); } 550 | HLML_INLINEF int4 gbgb() const { return yzyz(); } 551 | HLML_INLINEF int4 gbga() const { return yzyw(); } 552 | HLML_INLINEF int4 gbbr() const { return yzzx(); } 553 | HLML_INLINEF int4 gbbg() const { return yzzy(); } 554 | HLML_INLINEF int4 gbbb() const { return yzzz(); } 555 | HLML_INLINEF int4 gbba() const { return yzzw(); } 556 | HLML_INLINEF int4 gbar() const { return yzwx(); } 557 | HLML_INLINEF int4 gbag() const { return yzwy(); } 558 | HLML_INLINEF int4 gbab() const { return yzwz(); } 559 | HLML_INLINEF int4 gbaa() const { return yzww(); } 560 | HLML_INLINEF int4 garr() const { return ywxx(); } 561 | HLML_INLINEF int4 garg() const { return ywxy(); } 562 | HLML_INLINEF int4 garb() const { return ywxz(); } 563 | HLML_INLINEF int4 gara() const { return ywxw(); } 564 | HLML_INLINEF int4 gagr() const { return ywyx(); } 565 | HLML_INLINEF int4 gagg() const { return ywyy(); } 566 | HLML_INLINEF int4 gagb() const { return ywyz(); } 567 | HLML_INLINEF int4 gaga() const { return ywyw(); } 568 | HLML_INLINEF int4 gabr() const { return ywzx(); } 569 | HLML_INLINEF int4 gabg() const { return ywzy(); } 570 | HLML_INLINEF int4 gabb() const { return ywzz(); } 571 | HLML_INLINEF int4 gaba() const { return ywzw(); } 572 | HLML_INLINEF int4 gaar() const { return ywwx(); } 573 | HLML_INLINEF int4 gaag() const { return ywwy(); } 574 | HLML_INLINEF int4 gaab() const { return ywwz(); } 575 | HLML_INLINEF int4 gaaa() const { return ywww(); } 576 | 577 | HLML_INLINEF int4 brrr() const { return zxxx(); } 578 | HLML_INLINEF int4 brrg() const { return zxxy(); } 579 | HLML_INLINEF int4 brrb() const { return zxxz(); } 580 | HLML_INLINEF int4 brra() const { return zxxw(); } 581 | HLML_INLINEF int4 brgr() const { return zxyx(); } 582 | HLML_INLINEF int4 brgg() const { return zxyy(); } 583 | HLML_INLINEF int4 brgb() const { return zxyz(); } 584 | HLML_INLINEF int4 brga() const { return zxyw(); } 585 | HLML_INLINEF int4 brbr() const { return zxzx(); } 586 | HLML_INLINEF int4 brbg() const { return zxzy(); } 587 | HLML_INLINEF int4 brbb() const { return zxzz(); } 588 | HLML_INLINEF int4 brba() const { return zxzw(); } 589 | HLML_INLINEF int4 brar() const { return zxwx(); } 590 | HLML_INLINEF int4 brag() const { return zxwy(); } 591 | HLML_INLINEF int4 brab() const { return zxwz(); } 592 | HLML_INLINEF int4 braa() const { return zxww(); } 593 | HLML_INLINEF int4 bgrr() const { return zyxx(); } 594 | HLML_INLINEF int4 bgrg() const { return zyxy(); } 595 | HLML_INLINEF int4 bgrb() const { return zyxz(); } 596 | HLML_INLINEF int4 bgra() const { return zyxy(); } 597 | HLML_INLINEF int4 bggr() const { return zyyx(); } 598 | HLML_INLINEF int4 bggg() const { return zyyy(); } 599 | HLML_INLINEF int4 bggb() const { return zyyz(); } 600 | HLML_INLINEF int4 bgga() const { return zyyw(); } 601 | HLML_INLINEF int4 bgbr() const { return zyzx(); } 602 | HLML_INLINEF int4 bgbg() const { return zyzy(); } 603 | HLML_INLINEF int4 bgbb() const { return zyzz(); } 604 | HLML_INLINEF int4 bgba() const { return zyzw(); } 605 | HLML_INLINEF int4 bgar() const { return zywx(); } 606 | HLML_INLINEF int4 bgag() const { return zywy(); } 607 | HLML_INLINEF int4 bgab() const { return zywz(); } 608 | HLML_INLINEF int4 bgaa() const { return zyww(); } 609 | HLML_INLINEF int4 bbrr() const { return zzxx(); } 610 | HLML_INLINEF int4 bbrg() const { return zzxy(); } 611 | HLML_INLINEF int4 bbrb() const { return zzxz(); } 612 | HLML_INLINEF int4 bbra() const { return zzxw(); } 613 | HLML_INLINEF int4 bbgr() const { return zzyx(); } 614 | HLML_INLINEF int4 bbgg() const { return zzyy(); } 615 | HLML_INLINEF int4 bbgb() const { return zzyz(); } 616 | HLML_INLINEF int4 bbga() const { return zzyw(); } 617 | HLML_INLINEF int4 bbbr() const { return zzzx(); } 618 | HLML_INLINEF int4 bbbg() const { return zzzy(); } 619 | HLML_INLINEF int4 bbbb() const { return zzzz(); } 620 | HLML_INLINEF int4 bbba() const { return zzzw(); } 621 | HLML_INLINEF int4 bbar() const { return zzwx(); } 622 | HLML_INLINEF int4 bbag() const { return zzwy(); } 623 | HLML_INLINEF int4 bbab() const { return zzwz(); } 624 | HLML_INLINEF int4 bbaa() const { return zzww(); } 625 | HLML_INLINEF int4 barr() const { return zwxx(); } 626 | HLML_INLINEF int4 barg() const { return zwxy(); } 627 | HLML_INLINEF int4 barb() const { return zwxz(); } 628 | HLML_INLINEF int4 bara() const { return zwxw(); } 629 | HLML_INLINEF int4 bagr() const { return zwyx(); } 630 | HLML_INLINEF int4 bagg() const { return zwyy(); } 631 | HLML_INLINEF int4 bagb() const { return zwyz(); } 632 | HLML_INLINEF int4 baga() const { return zwyw(); } 633 | HLML_INLINEF int4 babr() const { return zwzx(); } 634 | HLML_INLINEF int4 babg() const { return zwzy(); } 635 | HLML_INLINEF int4 babb() const { return zwzz(); } 636 | HLML_INLINEF int4 baba() const { return zwzw(); } 637 | HLML_INLINEF int4 baar() const { return zwwx(); } 638 | HLML_INLINEF int4 baag() const { return zwwy(); } 639 | HLML_INLINEF int4 baab() const { return zwwz(); } 640 | HLML_INLINEF int4 baaa() const { return zwww(); } 641 | 642 | HLML_INLINEF int4 arrr() const { return wxxx(); } 643 | HLML_INLINEF int4 arrg() const { return wxxy(); } 644 | HLML_INLINEF int4 arrb() const { return wxxz(); } 645 | HLML_INLINEF int4 arra() const { return wxxw(); } 646 | HLML_INLINEF int4 argr() const { return wxyx(); } 647 | HLML_INLINEF int4 argg() const { return wxyy(); } 648 | HLML_INLINEF int4 argb() const { return wxyz(); } 649 | HLML_INLINEF int4 arga() const { return wxyw(); } 650 | HLML_INLINEF int4 arbr() const { return wxzx(); } 651 | HLML_INLINEF int4 arbg() const { return wxzy(); } 652 | HLML_INLINEF int4 arbb() const { return wxzz(); } 653 | HLML_INLINEF int4 arba() const { return wxzw(); } 654 | HLML_INLINEF int4 arar() const { return wxwx(); } 655 | HLML_INLINEF int4 arag() const { return wxwy(); } 656 | HLML_INLINEF int4 arab() const { return wxwz(); } 657 | HLML_INLINEF int4 araa() const { return wxww(); } 658 | HLML_INLINEF int4 agrr() const { return wyxx(); } 659 | HLML_INLINEF int4 agrg() const { return wyxy(); } 660 | HLML_INLINEF int4 agrb() const { return wyxz(); } 661 | HLML_INLINEF int4 agra() const { return wyxy(); } 662 | HLML_INLINEF int4 aggr() const { return wyyx(); } 663 | HLML_INLINEF int4 aggg() const { return wyyy(); } 664 | HLML_INLINEF int4 aggb() const { return wyyz(); } 665 | HLML_INLINEF int4 agga() const { return wyyw(); } 666 | HLML_INLINEF int4 agbr() const { return wyzx(); } 667 | HLML_INLINEF int4 agbg() const { return wyzy(); } 668 | HLML_INLINEF int4 agbb() const { return wyzz(); } 669 | HLML_INLINEF int4 agba() const { return wyzw(); } 670 | HLML_INLINEF int4 agar() const { return wywx(); } 671 | HLML_INLINEF int4 agag() const { return wywy(); } 672 | HLML_INLINEF int4 agab() const { return wywz(); } 673 | HLML_INLINEF int4 agaa() const { return wyww(); } 674 | HLML_INLINEF int4 abrr() const { return wzxx(); } 675 | HLML_INLINEF int4 abrg() const { return wzxy(); } 676 | HLML_INLINEF int4 abrb() const { return wzxz(); } 677 | HLML_INLINEF int4 abra() const { return wzxw(); } 678 | HLML_INLINEF int4 abgr() const { return wzyx(); } 679 | HLML_INLINEF int4 abgg() const { return wzyy(); } 680 | HLML_INLINEF int4 abgb() const { return wzyz(); } 681 | HLML_INLINEF int4 abga() const { return wzyw(); } 682 | HLML_INLINEF int4 abbr() const { return wzzx(); } 683 | HLML_INLINEF int4 abbg() const { return wzzy(); } 684 | HLML_INLINEF int4 abbb() const { return wzzz(); } 685 | HLML_INLINEF int4 abba() const { return wzzw(); } 686 | HLML_INLINEF int4 abar() const { return wzwx(); } 687 | HLML_INLINEF int4 abag() const { return wzwy(); } 688 | HLML_INLINEF int4 abab() const { return wzwz(); } 689 | HLML_INLINEF int4 abaa() const { return wzww(); } 690 | HLML_INLINEF int4 aarr() const { return wwxx(); } 691 | HLML_INLINEF int4 aarg() const { return wwxy(); } 692 | HLML_INLINEF int4 aarb() const { return wwxz(); } 693 | HLML_INLINEF int4 aara() const { return wwxw(); } 694 | HLML_INLINEF int4 aagr() const { return wwyx(); } 695 | HLML_INLINEF int4 aagg() const { return wwyy(); } 696 | HLML_INLINEF int4 aagb() const { return wwyz(); } 697 | HLML_INLINEF int4 aaga() const { return wwyw(); } 698 | HLML_INLINEF int4 aabr() const { return wwzx(); } 699 | HLML_INLINEF int4 aabg() const { return wwzy(); } 700 | HLML_INLINEF int4 aabb() const { return wwzz(); } 701 | HLML_INLINEF int4 aaba() const { return wwzw(); } 702 | HLML_INLINEF int4 aaar() const { return wwwx(); } 703 | HLML_INLINEF int4 aaag() const { return wwwy(); } 704 | HLML_INLINEF int4 aaab() const { return wwwz(); } 705 | HLML_INLINEF int4 aaaa() const { return wwww(); } 706 | }; 707 | 708 | //boolean 709 | HLML_INLINEF bool4 operator== (int4 a, int4 b) { return bool4(funcs::AcmpeqB(a.m, b.m)); } 710 | HLML_INLINEF bool4 operator!= (int4 a, int4 b) { return bool4(funcs::AcmpneqB(a.m, b.m)); } 711 | HLML_INLINEF bool4 operator< (int4 a, int4 b) { return bool4(funcs::AcmpltB(a.m, b.m)); } 712 | HLML_INLINEF bool4 operator> (int4 a, int4 b) { return bool4(funcs::AcmpgtB(a.m, b.m)); } 713 | HLML_INLINEF bool4 operator<= (int4 a, int4 b) { return bool4(funcs::AcmpleB(a.m, b.m)); } 714 | HLML_INLINEF bool4 operator>= (int4 a, int4 b) { return bool4(funcs::AcmpgeB(a.m, b.m)); } 715 | //logical 716 | HLML_INLINEF int4 operator~ (int4 a) { a.m = funcs::notAandB(a.m, consts::vnall); return a; } 717 | HLML_INLINEF int4 operator& (int4 a, int4 b) { a.m = funcs::AandB(a.m, b.m); return a; } 718 | HLML_INLINEF int4 operator| (int4 a, int4 b) { a.m = funcs::AorB(a.m, b.m); return a; } 719 | HLML_INLINEF int4 operator^ (int4 a, int4 b) { a.m = funcs::AxorB(a.m, b.m); return a; } 720 | HLML_INLINEF int4 operator<< (int4 a, u8 bits) { a.m = funcs::Ashiftl(a.m, bits); return a; } 721 | HLML_INLINEF int4 operator>> (int4 a, u8 bits) { a.m = funcs::Ashiftr(a.m, bits); return a; } 722 | HLML_INLINEF int4& operator<<= (int4& a, u8 bits) { a = a << bits; return a; } 723 | HLML_INLINEF int4& operator>>= (int4& a, u8 bits) { a = a >> bits; return a; } 724 | //arithmetic 725 | HLML_INLINEF int4 operator+ (int4 a) { return a; } 726 | HLML_INLINEF int4 operator- (int4 a) { a.m = funcs::AxorB(a.m, consts::vsignbits_xyzw); return a; } 727 | HLML_INLINEF int4 operator+ (int4 a, int4 b) { a.m = funcs::AaddB(a.m, b.m); return a; } 728 | HLML_INLINEF int4 operator- (int4 a, int4 b) { a.m = funcs::AsubB(a.m, b.m); return a; } 729 | HLML_INLINEF int4 operator* (int4 a, int4 b) { a.m = funcs::AmulB(a.m, b.m); return a; } 730 | HLML_INLINEF int4 operator+ (int4 a, i32 b) { return a + int4(b); } 731 | HLML_INLINEF int4 operator- (int4 a, i32 b) { return a - int4(b); } 732 | HLML_INLINEF int4 operator* (int4 a, i32 b) { return a * int4(b); } 733 | HLML_INLINEF int4 operator+ (i32 b, int4 a) { return a + b; } 734 | HLML_INLINEF int4 operator- (i32 a, int4 b) { return int4(a) - b; } 735 | HLML_INLINEF int4 operator* (i32 b, int4 a) { return a * b; } 736 | HLML_INLINEF int4& operator+= (int4& a, int4 b) { a = a + b; return a; } 737 | HLML_INLINEF int4& operator-= (int4& a, int4 b) { a = a - b; return a; } 738 | HLML_INLINEF int4& operator*= (int4& a, int4 b) { a = a * b; return a; } 739 | HLML_INLINEF int4& operator+= (int4& a, i32 b) { return a += int4(b); } 740 | HLML_INLINEF int4& operator-= (int4& a, i32 b) { return a -= int4(b); } 741 | HLML_INLINEF int4& operator*= (int4& a, i32 b) { return a *= int4(b); } 742 | //other 743 | HLML_INLINEF int4 abs(int4 v) { v.m = funcs::notAandB(consts::vsignbits_xyzw, v.m); return v; } 744 | HLML_INLINEF int4 minv(int4 a, int4 b) { a.m = funcs::AminB(a.m, b.m); return a; } 745 | HLML_INLINEF int4 maxv(int4 a, int4 b) { a.m = funcs::AmaxB(a.m, b.m); return a; } 746 | HLML_INLINEF int4 sumv(int4 v) { 747 | v.m = funcs::AhaddB(v.m, v.zwxy().m); 748 | v.m = funcs::AhaddB(v.m, v.m); 749 | return v; 750 | } 751 | HLML_INLINEF i32 sum(int4 v) { return sumv(v).x(); } 752 | HLML_INLINEF i32 hmin(int4 v) { 753 | v = minv(v, shufflei4(v, 1, 0, 3, 2)); 754 | return minv(v, shufflei4(v, 3, 2, 1, 0)).x(); 755 | } 756 | HLML_INLINEF i32 hmax(int4 v) { 757 | v = maxv(v, shufflei4(v, 1, 0, 3, 2)); 758 | return maxv(v, shufflei4(v, 3, 2, 1, 0)).x(); 759 | } 760 | } -------------------------------------------------------------------------------- /quat.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "float4.hpp" 4 | #include "float3x3.hpp" 5 | #include "trig.hpp" 6 | 7 | namespace hlml { 8 | class quat { 9 | float4 m = { consts::sfOne, consts::sfZero, consts::sfZero, consts::sfZero }; 10 | 11 | public: 12 | quat() = default; 13 | explicit quat(float3 v) : quat(0.0f, v) {} 14 | explicit quat(float4 v) : m(v.wxyz()) {} 15 | explicit quat(f32* v) : m(v) {} 16 | explicit quat(f32 scalar) : m(funcs::bxayazaw(funcs::setXXXX(scalar), consts::vzeros)) {} 17 | quat(f32 w, float3 v) : m(w, v.x(), v.y(), v.z()) {} 18 | quat(f32 w, f32 x, f32 y, f32 z) : m(w, x, y, z) {} 19 | quat(float3 axis, f32 degs) { 20 | //http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm 21 | float4 s, c, xxyz(axis.m); 22 | sincos(float4(hlml::DEG2RAD(degs) * 0.5f), s, c); 23 | m.m = funcs::bxayazaw((s * xxyz.xxyz()).m, c.m); 24 | } 25 | //pitch = X axis, yaw = Y axis, roll = Z axis 26 | quat(f32 pitchdegs, f32 yawdegs, f32 rolldegs) { 27 | float4 angles(hlml::DEG2RAD(pitchdegs), hlml::DEG2RAD(pitchdegs), hlml::DEG2RAD(yawdegs), hlml::DEG2RAD(rolldegs)), sines, coses; 28 | sincos(angles * 0.5f, sines, coses); 29 | float4 cxxyz(funcs::bxayazaw(sines.m, coses.m)), sxxyz(funcs::bxayazaw(coses.m, sines.m));; 30 | float4 left = cxxyz * coses.zzyz() * coses.wwwy(), right = sxxyz * sines.zzyz() * sines.wwwy(); 31 | m = left + (right ^ float4(consts::vsignbits_yw)); 32 | } 33 | explicit quat(float3x3 rot) { 34 | // https://www.fd.cvut.cz/personal/voracsar/geometriepg/pgr020/matrix2quaternions.pdf 35 | // http://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2015/01/matrix-to-quat.pdf 36 | // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm 37 | const float3 m00(rot.c0.xxx()), m11(rot.c1.yyy()), m22(rot.c2.zzz()), zero; 38 | const float4 diag(consts::sfZero, m00.x(), m11.x(), m22.x()) 39 | , left(consts::sfZero, rot.c2.y(), rot.c0.z(), rot.c1.x()) 40 | , right(consts::sfZero, rot.c1.z(), rot.c2.x(), rot.c0.y()); 41 | const float4 s0(consts::vsignbits_xy), s1(consts::vsignbits_xz), s2(consts::vsignbits_yz); 42 | float4 factor(1.0f); 43 | if (all(m22 < zero)) { 44 | if (all(m00 > m11)) { 45 | factor += sumv(diag ^ s0); 46 | float4 v(left - (right ^ s0)); 47 | v.m = funcs::bxayazaw(v.m, factor.m); 48 | m = v.yxwz(); 49 | } else { 50 | factor += sumv(diag ^ s1); 51 | float4 v(left - (right ^ s1)); 52 | v.m = funcs::bxayazaw(v.m, factor.m); 53 | m = v.zwxy(); 54 | } 55 | } else { 56 | if (all(m00 < -m11)) { 57 | factor += sumv(diag ^ s2); 58 | float4 v(left - (right ^ s2)); 59 | v.m = funcs::bxayazaw(v.m, factor.m); 60 | m = v.wzyx(); 61 | } else { 62 | factor += sumv(diag); 63 | float4 v(left - right); 64 | m.m = funcs::bxayazaw(v.m, factor.m); 65 | } 66 | } 67 | m *= rsqrt(factor) * 0.5f; 68 | } 69 | quat(float3 u, float3 v) : quat(dot(u, v), cross(u, v)) { 70 | //http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors 71 | float4 t(length(m)); 72 | m.m = funcs::AaddssB(m.m, t.m); 73 | m = normalize(m); 74 | } 75 | explicit HLML_INLINEF operator float4() const { return m.yzwx(); } 76 | HLML_INLINEF operator float3x3() const { 77 | //http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm 78 | float4 v = float4(*this); 79 | float3 c0l(-2.0f, -2.0f, 2.0f), c0r(-2.0f, 2.0f, 2.0f), c1l(2.0f, -2.0f, 2.0f), c1r(-c0r), c2l(-c0l), c2r(-c1l); 80 | float3 xzy(v.xzy()), wxx(v.wxx()); 81 | float3 col0 = c0l * v.zzy() * v.zww() + c0r * v.yyz() * v.yxx(); 82 | float3 col1 = c1l * xzy * v.yzz() + c1r * wxx * v.zxw(); 83 | float3 col2 = c2l * xzy * v.zyy() + c2r * wxx * v.ywx(); 84 | float3x3 result = float3x3::identity() + float3x3(col0, col1, col2); 85 | return result; 86 | } 87 | HLML_INLINEF f32 x() const { return m.y(); } 88 | HLML_INLINEF f32 y() const { return m.z(); } 89 | HLML_INLINEF f32 z() const { return m.w(); } 90 | HLML_INLINEF f32 w() const { return m.x(); } 91 | HLML_INLINEF f32 real() const { return w(); } 92 | HLML_INLINEF float3 imag() const { return m.yzw(); } 93 | }; 94 | 95 | HLML_INLINEF quat operator+ (quat a) { return a; } 96 | HLML_INLINEF quat operator+ (quat a, quat b) { return quat((float4)a + (float4)b); } 97 | HLML_INLINEF quat operator+ (quat a, f32 s) { return a + quat(s); } 98 | HLML_INLINEF quat operator+ (f32 s, quat a) { return a + s; } 99 | HLML_INLINEF quat& operator+= (quat& a, quat b) { a = a + b; return a; } 100 | HLML_INLINEF quat& operator+= (quat& a, f32 s) { a = a + quat(s); return a; } 101 | HLML_INLINEF quat operator- (quat a) { return quat((float4)a ^ float4(consts::vsignbits_xyz)); } 102 | HLML_INLINEF quat operator- (quat a, quat b) { return quat((float4)a - (float4)b); } 103 | HLML_INLINEF quat operator- (quat a, f32 s) { return a - quat(s); } 104 | HLML_INLINEF quat operator- (f32 s, quat b) { return quat(s) - b; } 105 | HLML_INLINEF quat& operator-= (quat& a, quat b) { a = a - b; return a; } 106 | HLML_INLINEF quat& operator-= (quat& a, f32 s) { a = a - quat(s); return a; } 107 | HLML_INLINEF quat operator* (quat a, quat b) { 108 | float4 ai = (float4)a, bi = (float4)b; 109 | float4 s1 = ai.xyzy() * bi.wwwy() + ai.yzxz() * bi.zxyz(); 110 | s1.m = funcs::AxorB(s1.m, consts::vsignbits_w); 111 | ai = ai.wwww() * bi - ai.zxyx() * bi.yzxx() + s1; 112 | return quat(ai); 113 | } 114 | HLML_INLINEF float3 operator* (quat a, float3 b) { 115 | float4 i((float4)a); 116 | float3 axyz(i.xyz()), www(i.www()), bxyz(b); 117 | float3 t(float3(2.0f) * cross(axyz, b)), wwwt(www * t), axyzt(cross(axyz, t)); 118 | return axyzt + wwwt + b; 119 | } 120 | HLML_INLINEF quat operator* (quat a, f32 s) { return quat((float4)a * s); } 121 | HLML_INLINEF quat operator* (f32 s, quat a) { return a * s; } 122 | HLML_INLINEF quat& operator*= (quat& a, quat b) { a = a * b; return a; } 123 | HLML_INLINEF quat& operator*= (quat& a, f32 s) { a = a * s; } 124 | HLML_INLINEF quat operator/ (quat a, f32 s) { return a * (1.0f / s); } 125 | HLML_INLINEF quat& operator/= (quat& a, f32 s) { a = a / s; return a; } 126 | 127 | HLML_INLINEF bool4 operator== (quat a, quat b) { return (float4)a == (float4)b; } 128 | HLML_INLINEF bool4 operator!= (quat a, quat b) { return (float4)a != (float4)b; } 129 | 130 | HLML_INLINEF quat conjugate(quat a) { return -a; } 131 | HLML_INLINEF quat inverse(quat a) { float4 v((float4)a), qc((float4)conjugate(a)); return quat(qc / dotv(v, v)); } 132 | HLML_INLINEF quat normalize(quat a) { return quat(normalize((float4)a)); } 133 | 134 | HLML_INLINEF float3 operator* (float3 b, quat a) { return inverse(a) * b; } 135 | } 136 | -------------------------------------------------------------------------------- /trig.cpp: -------------------------------------------------------------------------------- 1 | #include "trig.hpp" 2 | 3 | namespace hlml { 4 | namespace consts { 5 | // i got these here http://gruntthepeon.free.fr/ssemath/ 6 | // and here https://github.com/to-miz/sse_mathfun_extension/blob/master/sse_mathfun_extension.h 7 | static constexpr f32 sfOneNeg = -sfOne; 8 | static constexpr f32 sfHalf = 0.5f; 9 | static constexpr u32 snOne = 1u; 10 | static constexpr u32 snOneN = ~snOne; 11 | static constexpr u32 snTwo = 2u; 12 | static constexpr u32 snFour = 4u; 13 | static constexpr u32 sn127 = 0x7F; 14 | 15 | static constexpr u32 snNormPos = 0x00800000; 16 | static constexpr u32 snMaskMantis = 0x7f800000; 17 | static constexpr u32 snMaskMantisN = ~snMaskMantis; 18 | 19 | HLML_VCONST vconstu vnormpos = { snNormPos, snNormPos, snNormPos, snNormPos }; 20 | HLML_VCONST vconstu vmskmnts = { snMaskMantis, snMaskMantis, snMaskMantis, snMaskMantis }; 21 | HLML_VCONST vconstu vmskmntsn = { snMaskMantisN, snMaskMantisN, snMaskMantisN, snMaskMantisN }; 22 | 23 | HLML_VCONST vconstu vnzeros = { snZero, snZero, snZero, snZero }; 24 | HLML_VCONST vconstu vnones = { snOne, snOne, snOne, snOne }; 25 | HLML_VCONST vconstu vnonesn = { snOneN, snOneN, snOneN, snOneN }; 26 | HLML_VCONST vconstu vntwos = { snTwo, snTwo, snTwo, snTwo }; 27 | HLML_VCONST vconstu vnfours = { snFour, snFour, snFour, snFour }; 28 | HLML_VCONST vconstu vn127s = { sn127, sn127, sn127, sn127 }; 29 | 30 | HLML_VCONST vconstu vonesneg = { sfOneNeg, sfOneNeg, sfOneNeg, sfOneNeg }; 31 | HLML_VCONST vconstu vhalves = { sfHalf, sfHalf, sfHalf, sfHalf }; 32 | HLML_VCONST vconstu vsqrthf = { 0.707106781186547524f, 0.707106781186547524f, 0.707106781186547524f, 0.707106781186547524f }; 33 | HLML_VCONST vconstu vlogp0 = { 7.0376836292E-2f, 7.0376836292E-2f, 7.0376836292E-2f, 7.0376836292E-2f }; 34 | HLML_VCONST vconstu vlogp1 = { -1.1514610310E-1f, -1.1514610310E-1f, -1.1514610310E-1f, -1.1514610310E-1f }; 35 | HLML_VCONST vconstu vlogp2 = { 1.1676998740E-1f, 1.1676998740E-1f, 1.1676998740E-1f, 1.1676998740E-1f }; 36 | HLML_VCONST vconstu vlogp3 = { -1.2420140846E-1f, -1.2420140846E-1f, -1.2420140846E-1f, -1.2420140846E-1f }; 37 | HLML_VCONST vconstu vlogp4 = { +1.4249322787E-1f, +1.4249322787E-1f, +1.4249322787E-1f, +1.4249322787E-1f }; 38 | HLML_VCONST vconstu vlogp5 = { -1.6668057665E-1f, -1.6668057665E-1f, -1.6668057665E-1f, -1.6668057665E-1f }; 39 | HLML_VCONST vconstu vlogp6 = { +2.0000714765E-1f, +2.0000714765E-1f, +2.0000714765E-1f, +2.0000714765E-1f }; 40 | HLML_VCONST vconstu vlogp7 = { -2.4999993993E-1f, -2.4999993993E-1f, -2.4999993993E-1f, -2.4999993993E-1f }; 41 | HLML_VCONST vconstu vlogp8 = { +3.3333331174E-1f, +3.3333331174E-1f, +3.3333331174E-1f, +3.3333331174E-1f }; 42 | HLML_VCONST vconstu vlogq1 = { -2.12194440e-4f, -2.12194440e-4f, -2.12194440e-4f, -2.12194440e-4f }; 43 | HLML_VCONST vconstu vlogq2 = { 0.693359375f, 0.693359375f, 0.693359375f, 0.693359375f }; 44 | HLML_VCONST vconstu vexphi = { 88.3762626647949f, 88.3762626647949f, 88.3762626647949f, 88.3762626647949f }; 45 | HLML_VCONST vconstu vexplo = { -88.3762626647949f, -88.3762626647949f, -88.3762626647949f, -88.3762626647949f }; 46 | HLML_VCONST vconstu vlogef = { 1.44269504088896341f, 1.44269504088896341f, 1.44269504088896341f, 1.44269504088896341f }; 47 | HLML_VCONST vconstu vexpc1 = { 0.693359375f, 0.693359375f, 0.693359375f, 0.693359375f }; 48 | HLML_VCONST vconstu vexpc2 = { -2.12194440e-4f, -2.12194440e-4f, -2.12194440e-4f, -2.12194440e-4f }; 49 | HLML_VCONST vconstu vexpp0 = { 1.9875691500E-4f, 1.9875691500E-4f, 1.9875691500E-4f, 1.9875691500E-4f }; 50 | HLML_VCONST vconstu vexpp1 = { 1.3981999507E-3f, 1.3981999507E-3f, 1.3981999507E-3f, 1.3981999507E-3f }; 51 | HLML_VCONST vconstu vexpp2 = { 8.3334519073E-3f, 8.3334519073E-3f, 8.3334519073E-3f, 8.3334519073E-3f }; 52 | HLML_VCONST vconstu vexpp3 = { 4.1665795894E-2f, 4.1665795894E-2f, 4.1665795894E-2f, 4.1665795894E-2f }; 53 | HLML_VCONST vconstu vexpp4 = { 1.6666665459E-1f, 1.6666665459E-1f, 1.6666665459E-1f, 1.6666665459E-1f }; 54 | HLML_VCONST vconstu vexpp5 = { 5.0000001201E-1f, 5.0000001201E-1f, 5.0000001201E-1f, 5.0000001201E-1f }; 55 | HLML_VCONST vconstu vnegdp1 = { -0.78515625f, -0.78515625f, -0.78515625f, -0.78515625f }; 56 | HLML_VCONST vconstu vnegdp2 = { -2.4187564849853515625e-4f, -2.4187564849853515625e-4f, -2.4187564849853515625e-4f, -2.4187564849853515625e-4f }; 57 | HLML_VCONST vconstu vnegdp3 = { -3.77489497744594108e-8f, -3.77489497744594108e-8f, -3.77489497744594108e-8f, -3.77489497744594108e-8f }; 58 | HLML_VCONST vconstu vsincp0 = { -1.9515295891E-4f, -1.9515295891E-4f, -1.9515295891E-4f, -1.9515295891E-4f }; 59 | HLML_VCONST vconstu vsincp1 = { 8.3321608736E-3f, 8.3321608736E-3f, 8.3321608736E-3f, 8.3321608736E-3f }; 60 | HLML_VCONST vconstu vsincp2 = { -1.6666654611E-1f, -1.6666654611E-1f, -1.6666654611E-1f, -1.6666654611E-1f }; 61 | HLML_VCONST vconstu vcoscp0 = { 2.443315711809948E-005f, 2.443315711809948E-005f, 2.443315711809948E-005f, 2.443315711809948E-005f }; 62 | HLML_VCONST vconstu vcoscp1 = { -1.388731625493765E-003f, -1.388731625493765E-003f, -1.388731625493765E-003f, -1.388731625493765E-003f }; 63 | HLML_VCONST vconstu vcoscp2 = { 4.166664568298827E-002f, 4.166664568298827E-002f, 4.166664568298827E-002f, 4.166664568298827E-002f }; 64 | HLML_VCONST vconstu vtancp0 = { 9.38540185543E-3f, 9.38540185543E-3f, 9.38540185543E-3f, 9.38540185543E-3f }; 65 | HLML_VCONST vconstu vtancp1 = { 3.11992232697E-3f, 3.11992232697E-3f, 3.11992232697E-3f, 3.11992232697E-3f }; 66 | HLML_VCONST vconstu vtancp2 = { 2.44301354525E-2f, 2.44301354525E-2f, 2.44301354525E-2f, 2.44301354525E-2f }; 67 | HLML_VCONST vconstu vtancp3 = { 5.34112807005E-2f, 5.34112807005E-2f, 5.34112807005E-2f, 5.34112807005E-2f }; 68 | HLML_VCONST vconstu vtancp4 = { 1.33387994085E-1f, 1.33387994085E-1f, 1.33387994085E-1f, 1.33387994085E-1f }; 69 | HLML_VCONST vconstu vtancp5 = { 3.33331568548E-1f, 3.33331568548E-1f, 3.33331568548E-1f, 3.33331568548E-1f }; 70 | HLML_VCONST vconstu vtaneps = { 1.0e-4f, 1.0e-4f, 1.0e-4f, 1.0e-4f }; 71 | HLML_VCONST vconstu vfopi = { 1.27323954473516f, 1.27323954473516f, 1.27323954473516f, 1.27323954473516f };// 4 / M_PI 72 | HLML_VCONST vconstu vpif = { 3.141592653589793238f, 3.141592653589793238f, 3.141592653589793238f, 3.141592653589793238f }; 73 | HLML_VCONST vconstu vpih = { 1.5707963267948966192f, 1.5707963267948966192f, 1.5707963267948966192f, 1.5707963267948966192f}; 74 | HLML_VCONST vconstu vpiq = { 0.7853981633974483096f, 0.7853981633974483096f, 0.7853981633974483096f, 0.7853981633974483096f}; 75 | HLML_VCONST vconstu vatanhi = { 2.414213562373095f, 2.414213562373095f, 2.414213562373095f, 2.414213562373095f }; 76 | HLML_VCONST vconstu vatanlo = { 0.4142135623730950f, 0.4142135623730950f, 0.4142135623730950f, 0.4142135623730950f }; 77 | HLML_VCONST vconstu vatanp0 = { 8.05374449538e-2f, 8.05374449538e-2f, 8.05374449538e-2f, 8.05374449538e-2f }; 78 | HLML_VCONST vconstu vatanp1 = { 1.38776856032E-1f, 1.38776856032E-1f, 1.38776856032E-1f, 1.38776856032E-1f }; 79 | HLML_VCONST vconstu vatanp2 = { 1.99777106478E-1f, 1.99777106478E-1f, 1.99777106478E-1f, 1.99777106478E-1f }; 80 | HLML_VCONST vconstu vatanp3 = { 3.33329491539E-1f, 3.33329491539E-1f, 3.33329491539E-1f, 3.33329491539E-1f }; 81 | } 82 | float4 log(float4 x) { 83 | const float4 ones(consts::vones), zeros(consts::vzeros), halves(consts::vhalves), npos(consts::vnormpos), sqrthf(consts::vsqrthf), mantisn(consts::vmskmntsn), lp1(consts::vlogp1), lp2(consts::vlogp2), lp3(consts::vlogp3), lp4(consts::vlogp4), lp5(consts::vlogp5), lp6(consts::vlogp6), lp7(consts::vlogp7), lp8(consts::vlogp8), lq1(consts::vlogq1), lq2(consts::vlogq2); 84 | const int4 v127(consts::vn127s); 85 | 86 | float4 maskinv = cmple(x, zeros); 87 | x = maxv(x, npos); 88 | int4 emm0((asint(x) >> 23) - v127); 89 | x = (x & mantisn) | halves; 90 | float4 mask = cmplt(x, sqrthf), e = toflt(emm0) - (ones & mask) + ones; 91 | x = x - ones + (x & mask); 92 | float4 z(x * x), y(consts::vlogp0); 93 | y = y * x + lp1; 94 | y = y * x + lp2; 95 | y = y * x + lp3; 96 | y = y * x + lp4; 97 | y = y * x + lp5; 98 | y = y * x + lp6; 99 | y = y * x + lp7; 100 | y = y * x + lp8; 101 | y = y * z * x + e * lq1 + e * lq2 - z * halves; 102 | return (x + y) | maskinv; 103 | } 104 | 105 | float4 exp(float4 x) { 106 | const float4 one(consts::vones), ehi(consts::vexphi), elo(consts::vexplo), elf(consts::vlogef), halves(consts::vhalves), exc1(consts::vexpc1), exc2(consts::vexpc2), exp1(consts::vexpp1), exp2(consts::vexpp2), exp3(consts::vexpp3), exp4(consts::vexpp4), exp5(consts::vexpp5); 107 | const int4 n127(consts::vn127s); 108 | float4 xex = maxv(elo, minv(x, ehi)), fx = xex * elf + halves; //express exp(x) as exp(g + n*log(2)) 109 | float4 nfx(toflt(toint(fx))); //how to perform a floorf with SSE: just below 110 | fx = toflt(toint(fx)) - (cmpgt(nfx, fx) & one); //if greater, substract 1 111 | xex = xex - fx * exc1 - fx * exc2; 112 | 113 | float4 z(xex * xex), poly(consts::vexpp0); 114 | poly = poly * xex + exp1; 115 | poly = poly * xex + exp2; 116 | poly = poly * xex + exp3; 117 | poly = poly * xex + exp4; 118 | poly = poly * xex + exp5; 119 | poly = poly * z + xex + one; 120 | 121 | return poly * asflt((toint(fx) + n127) << 23);// build 2^n 122 | } 123 | 124 | void sincos(float4 x, float4& s, float4& c) { 125 | const int4 ones(consts::vnones), nones(consts::vnonesn), zeros(consts::vnzeros), twos(consts::vntwos), fours(consts::vnfours); 126 | const float4 cp1(consts::vcoscp1), cp2(consts::vcoscp2), sp1(consts::vsincp1), sp2(consts::vsincp2), halves(consts::vhalves), fones(consts::vones), ndp1(consts::vnegdp1), ndp2(consts::vnegdp2), ndp3(consts::vnegdp3), fpi(consts::vfopi); 127 | 128 | float4 ax(abs(x)), y(ax * fpi); 129 | int4 emm2 = nones & (toint(y) + ones); 130 | y = toflt(emm2); 131 | float4 dps = ((ax + y * ndp1) + y * ndp2) + y * ndp3, z(dps * dps), polyc(consts::vcoscp0), polys(consts::vsincp0); 132 | polyc = polyc * z + cp1; 133 | polys = polys * z + sp1; 134 | polyc = polyc * z + cp2; 135 | polys = polys * z + sp2; 136 | polyc = polyc * z * z - halves * z + fones; 137 | polys = polys * z * dps + dps; 138 | 139 | float4 polymsk = asflt(cmpeq((emm2 & twos), zeros)), polymskn(~polymsk); 140 | float4 ysin = (polymsk & polys) + (polymskn & polyc); 141 | float4 ycos = polyc + polys - ysin; 142 | float4 signs_cos = asflt((~(emm2 - twos) & fours) << 29); 143 | float4 signs_sin = (x & float4(consts::vsignbits_xyzw)) ^ asflt((emm2 & fours) << 29); 144 | s = ysin ^ signs_sin; 145 | c = ycos ^ signs_cos; 146 | } 147 | 148 | float4 tan(float4 x) { 149 | const float4 signs(consts::vsignbits_xyzw), ones(consts::vones), signsres(x & signs), fopi(consts::vfopi), tanp1(consts::vtancp1), tanp2(consts::vtancp2), tanp3(consts::vtancp3), tanp4(consts::vtancp4), tanp5(consts::vtancp5); 150 | const int4 iones(consts::vnones), ionesn(consts::vnonesn), twos(consts::vntwos), nzeros(consts::vnzeros); 151 | 152 | float4 ax(abs(x)); 153 | /* store the integer part of y in mm0 */ 154 | int4 emm2 = (toint(ax * fopi) + iones) & ionesn; 155 | float4 y = toflt(emm2); 156 | emm2 = cmpeq(emm2 & twos, nzeros); 157 | const float4 polymsk(asflt(emm2)), polymskn(~polymsk); 158 | 159 | float4 z = ((ax + y * float4(consts::vnegdp1)) + y * float4(consts::vnegdp2)) + y * float4(consts::vnegdp3), zz(z * z), poly(consts::vtancp0); 160 | poly = poly * zz + tanp1; 161 | poly = poly * zz + tanp2; 162 | poly = poly * zz + tanp3; 163 | poly = poly * zz + tanp4; 164 | poly = poly * zz + tanp5; 165 | poly = poly * zz * z + z; 166 | 167 | float4 polyinv = ones / poly; 168 | poly = (poly & polymsk) | (-polyinv & polymskn); 169 | return poly ^ signsres; 170 | } 171 | 172 | float4 atan(float4 x) { 173 | const float4 signsn(consts::vsignbitsn), signs(consts::vsignbits_xyzw), ones(consts::vones), atanhi(consts::vatanhi), atanlo(consts::vatanlo), pih(consts::vpih), piq(consts::vpiq), atanp0(consts::vatanp0), atanp1(consts::vatanp1), atanp2(consts::vatanp2), atanp3(consts::vatanp3); 174 | float4 ax = abs(x), r = ax - ones, r0 = rcp(ax + ones), r1 = -rcp(ax); 175 | float4 cmp0 = cmpgt(ax, atanhi), cmp1 = cmpgt(ax, atanlo), cmp2 = ~cmp0 & cmp1, cmp = cmp0 | cmp1; 176 | float4 x2 = (cmp2 & (r * r0)) | (cmp0 & r1); 177 | ax = (cmp & x2) | (~cmp & ax); 178 | 179 | float4 zz = ax * ax, acc = atanp0; 180 | acc = acc * zz - atanp1; 181 | acc = acc * zz + atanp2; 182 | acc = acc * zz - atanp3; 183 | acc = acc * zz * ax + ax + ((cmp0 & pih) | (cmp2 & piq)); 184 | return acc ^ (x & signs); 185 | } 186 | 187 | float4 atan2(float4 x, float4 y) { 188 | const float4 zeros(consts::vzeros), signs(consts::vsignbits_xyzw), pi(consts::vpif), pih(consts::vpih); 189 | float4 xeq = cmpeq(x, zeros), xgt = cmpgt(x, zeros), xle = cmple(x, zeros), xlt = cmplt(x, zeros), yeq = cmpeq(y, zeros), ylt = cmplt(y, zeros); 190 | float4 zero_mask = (xeq & yeq) | (xgt & yeq), pio2_mask = ~yeq & xeq; 191 | float4 pio2_result = (pih ^ (ylt & signs)) & pio2_mask; 192 | float4 atan_result = atan(y / x) + (xlt & (pi ^ (xlt & ylt & signs))); 193 | 194 | return (~zero_mask & pio2_result) | (~pio2_mask & atan_result) | (pi & xle & yeq); 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /trig.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "float4.hpp" 4 | 5 | namespace hlml { 6 | float4 log(float4 x); 7 | float4 exp(float4 x); 8 | void sincos(float4 x, float4& s, float4& c); 9 | float4 tan(float4 x); 10 | float4 atan(float4 x); 11 | float4 atan2(float4 x, float4 y); 12 | } --------------------------------------------------------------------------------