HLSLToCPP.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2026 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. JPH_NAMESPACE_BEGIN
  6. /// Emulates HLSL vector types and operations in C++.
  7. /// Note doesn't emulate things like barriers and group shared memory.
  8. namespace HLSLToCPP {
  9. using std::sqrt;
  10. using std::min;
  11. using std::max;
  12. using std::round;
  13. //////////////////////////////////////////////////////////////////////////////////////////
  14. // float2
  15. //////////////////////////////////////////////////////////////////////////////////////////
  16. struct float2
  17. {
  18. // Constructors
  19. inline float2() = default;
  20. constexpr float2(float inX, float inY) : x(inX), y(inY) { }
  21. explicit constexpr float2(float inS) : x(inS), y(inS) { }
  22. // Operators
  23. constexpr float2 & operator += (const float2 &inRHS) { x += inRHS.x; y += inRHS.y; return *this; }
  24. constexpr float2 & operator -= (const float2 &inRHS) { x -= inRHS.x; y -= inRHS.y; return *this; }
  25. constexpr float2 & operator *= (float inRHS) { x *= inRHS; y *= inRHS; return *this; }
  26. constexpr float2 & operator /= (float inRHS) { x /= inRHS; y /= inRHS; return *this; }
  27. constexpr float2 & operator *= (const float2 &inRHS) { x *= inRHS.x; y *= inRHS.y; return *this; }
  28. constexpr float2 & operator /= (const float2 &inRHS) { x /= inRHS.x; y /= inRHS.y; return *this; }
  29. // Equality
  30. constexpr bool operator == (const float2 &inRHS) const { return x == inRHS.x && y == inRHS.y; }
  31. constexpr bool operator != (const float2 &inRHS) const { return !(*this == inRHS); }
  32. // Component access
  33. const float & operator [] (uint inIndex) const { return (&x)[inIndex]; }
  34. float & operator [] (uint inIndex) { return (&x)[inIndex]; }
  35. // Swizzling (note return value is const to prevent assignment to swizzled results)
  36. const float2 swizzle_xy() const { return float2(x, y); }
  37. const float2 swizzle_yx() const { return float2(y, x); }
  38. float x, y;
  39. };
  40. // Operators
  41. constexpr float2 operator - (const float2 &inA) { return float2(-inA.x, -inA.y); }
  42. constexpr float2 operator + (const float2 &inA, const float2 &inB) { return float2(inA.x + inB.x, inA.y + inB.y); }
  43. constexpr float2 operator - (const float2 &inA, const float2 &inB) { return float2(inA.x - inB.x, inA.y - inB.y); }
  44. constexpr float2 operator * (const float2 &inA, const float2 &inB) { return float2(inA.x * inB.x, inA.y * inB.y); }
  45. constexpr float2 operator / (const float2 &inA, const float2 &inB) { return float2(inA.x / inB.x, inA.y / inB.y); }
  46. constexpr float2 operator * (const float2 &inA, float inS) { return float2(inA.x * inS, inA.y * inS); }
  47. constexpr float2 operator * (float inS, const float2 &inA) { return inA * inS; }
  48. constexpr float2 operator / (const float2 &inA, float inS) { return float2(inA.x / inS, inA.y / inS); }
  49. // Dot product
  50. constexpr float dot(const float2 &inA, const float2 &inB) { return inA.x * inB.x + inA.y * inB.y; }
  51. // Min value
  52. constexpr float2 min(const float2 &inA, const float2 &inB) { return float2(min(inA.x, inB.x), min(inA.y, inB.y)); }
  53. // Max value
  54. constexpr float2 max(const float2 &inA, const float2 &inB) { return float2(max(inA.x, inB.x), max(inA.y, inB.y)); }
  55. // Length
  56. inline float length(const float2 &inV) { return sqrt(dot(inV, inV)); }
  57. // Normalization
  58. inline float2 normalize(const float2 &inV) { return inV / length(inV); }
  59. // Rounding to int
  60. inline float2 round(const float2 &inV) { return float2(round(inV.x), round(inV.y)); }
  61. //////////////////////////////////////////////////////////////////////////////////////////
  62. // float3
  63. //////////////////////////////////////////////////////////////////////////////////////////
  64. struct uint3;
  65. struct float3
  66. {
  67. // Constructors
  68. inline float3() = default;
  69. constexpr float3(const float2 &inV, float inZ) : x(inV.x), y(inV.y), z(inZ) { }
  70. constexpr float3(float inX, float inY, float inZ) : x(inX), y(inY), z(inZ) { }
  71. explicit constexpr float3(float inS) : x(inS), y(inS), z(inS) { }
  72. explicit constexpr float3(const uint3 &inV);
  73. // Operators
  74. constexpr float3 & operator += (const float3 &inRHS) { x += inRHS.x; y += inRHS.y; z += inRHS.z; return *this; }
  75. constexpr float3 & operator -= (const float3 &inRHS) { x -= inRHS.x; y -= inRHS.y; z -= inRHS.z; return *this; }
  76. constexpr float3 & operator *= (float inRHS) { x *= inRHS; y *= inRHS; z *= inRHS; return *this; }
  77. constexpr float3 & operator /= (float inRHS) { x /= inRHS; y /= inRHS; z /= inRHS; return *this; }
  78. constexpr float3 & operator *= (const float3 &inRHS) { x *= inRHS.x; y *= inRHS.y; z *= inRHS.z; return *this; }
  79. constexpr float3 & operator /= (const float3 &inRHS) { x /= inRHS.x; y /= inRHS.y; z /= inRHS.z; return *this; }
  80. // Equality
  81. constexpr bool operator == (const float3 &inRHS) const { return x == inRHS.x && y == inRHS.y && z == inRHS.z; }
  82. constexpr bool operator != (const float3 &inRHS) const { return !(*this == inRHS); }
  83. // Component access
  84. const float & operator [] (uint inIndex) const { return (&x)[inIndex]; }
  85. float & operator [] (uint inIndex) { return (&x)[inIndex]; }
  86. // Swizzling (note return value is const to prevent assignment to swizzled results)
  87. const float2 swizzle_xy() const { return float2(x, y); }
  88. const float2 swizzle_yx() const { return float2(y, x); }
  89. const float3 swizzle_xyz() const { return float3(x, y, z); }
  90. const float3 swizzle_xzy() const { return float3(x, z, y); }
  91. const float3 swizzle_yxz() const { return float3(y, x, z); }
  92. const float3 swizzle_yzx() const { return float3(y, z, x); }
  93. const float3 swizzle_zxy() const { return float3(z, x, y); }
  94. const float3 swizzle_zyx() const { return float3(z, y, x); }
  95. float x, y, z;
  96. };
  97. // Operators
  98. constexpr float3 operator - (const float3 &inA) { return float3(-inA.x, -inA.y, -inA.z); }
  99. constexpr float3 operator + (const float3 &inA, const float3 &inB) { return float3(inA.x + inB.x, inA.y + inB.y, inA.z + inB.z); }
  100. constexpr float3 operator - (const float3 &inA, const float3 &inB) { return float3(inA.x - inB.x, inA.y - inB.y, inA.z - inB.z); }
  101. constexpr float3 operator * (const float3 &inA, const float3 &inB) { return float3(inA.x * inB.x, inA.y * inB.y, inA.z * inB.z); }
  102. constexpr float3 operator / (const float3 &inA, const float3 &inB) { return float3(inA.x / inB.x, inA.y / inB.y, inA.z / inB.z); }
  103. constexpr float3 operator * (const float3 &inA, float inS) { return float3(inA.x * inS, inA.y * inS, inA.z * inS); }
  104. constexpr float3 operator * (float inS, const float3 &inA) { return inA * inS; }
  105. constexpr float3 operator / (const float3 &inA, float inS) { return float3(inA.x / inS, inA.y / inS, inA.z / inS); }
  106. // Dot product
  107. constexpr float dot(const float3 &inA, const float3 &inB) { return inA.x * inB.x + inA.y * inB.y + inA.z * inB.z; }
  108. // Min value
  109. constexpr float3 min(const float3 &inA, const float3 &inB) { return float3(min(inA.x, inB.x), min(inA.y, inB.y), min(inA.z, inB.z)); }
  110. // Max value
  111. constexpr float3 max(const float3 &inA, const float3 &inB) { return float3(max(inA.x, inB.x), max(inA.y, inB.y), max(inA.z, inB.z)); }
  112. // Length
  113. inline float length(const float3 &inV) { return sqrt(dot(inV, inV)); }
  114. // Normalization
  115. inline float3 normalize(const float3 &inV) { return inV / length(inV); }
  116. // Rounding to int
  117. inline float3 round(const float3 &inV) { return float3(round(inV.x), round(inV.y), round(inV.z)); }
  118. // Cross product
  119. constexpr float3 cross(const float3 &inA, const float3 &inB) { return float3(inA.y * inB.z - inA.z * inB.y, inA.z * inB.x - inA.x * inB.z, inA.x * inB.y - inA.y * inB.x); }
  120. //////////////////////////////////////////////////////////////////////////////////////////
  121. // float4
  122. //////////////////////////////////////////////////////////////////////////////////////////
  123. struct int4;
  124. struct float4
  125. {
  126. // Constructors
  127. inline float4() = default;
  128. constexpr float4(const float3 &inV, float inW) : x(inV.x), y(inV.y), z(inV.z), w(inW) { }
  129. constexpr float4(float inX, float inY, float inZ, float inW) : x(inX), y(inY), z(inZ), w(inW) { }
  130. explicit constexpr float4(float inS) : x(inS), y(inS), z(inS), w(inS) { }
  131. explicit constexpr float4(const int4 &inV);
  132. // Operators
  133. constexpr float4 & operator += (const float4 &inRHS) { x += inRHS.x; y += inRHS.y; z += inRHS.z; w += inRHS.w; return *this; }
  134. constexpr float4 & operator -= (const float4 &inRHS) { x -= inRHS.x; y -= inRHS.y; z -= inRHS.z; w -= inRHS.w; return *this; }
  135. constexpr float4 & operator *= (float inRHS) { x *= inRHS; y *= inRHS; z *= inRHS; w *= inRHS; return *this; }
  136. constexpr float4 & operator /= (float inRHS) { x /= inRHS; y /= inRHS; z /= inRHS; w /= inRHS; return *this; }
  137. constexpr float4 & operator *= (const float4 &inRHS) { x *= inRHS.x; y *= inRHS.y; z *= inRHS.z; w *= inRHS.w; return *this; }
  138. constexpr float4 & operator /= (const float4 &inRHS) { x /= inRHS.x; y /= inRHS.y; z /= inRHS.z; w /= inRHS.w; return *this; }
  139. // Equality
  140. constexpr bool operator == (const float4 &inRHS) const { return x == inRHS.x && y == inRHS.y && z == inRHS.z && w == inRHS.w; }
  141. constexpr bool operator != (const float4 &inRHS) const { return !(*this == inRHS); }
  142. // Component access
  143. const float & operator [] (uint inIndex) const { return (&x)[inIndex]; }
  144. float & operator [] (uint inIndex) { return (&x)[inIndex]; }
  145. // Swizzling (note return value is const to prevent assignment to swizzled results)
  146. const float2 swizzle_xy() const { return float2(x, y); }
  147. const float2 swizzle_yx() const { return float2(y, x); }
  148. const float3 swizzle_xyz() const { return float3(x, y, z); }
  149. const float3 swizzle_xzy() const { return float3(x, z, y); }
  150. const float3 swizzle_yxz() const { return float3(y, x, z); }
  151. const float3 swizzle_yzx() const { return float3(y, z, x); }
  152. const float3 swizzle_zxy() const { return float3(z, x, y); }
  153. const float3 swizzle_zyx() const { return float3(z, y, x); }
  154. const float4 swizzle_xywz() const { return float4(x, y, w, z); }
  155. const float4 swizzle_xwyz() const { return float4(x, w, y, z); }
  156. const float4 swizzle_wxyz() const { return float4(w, x, y, z); }
  157. float x, y, z, w;
  158. };
  159. // Operators
  160. constexpr float4 operator - (const float4 &inA) { return float4(-inA.x, -inA.y, -inA.z, -inA.w); }
  161. constexpr float4 operator + (const float4 &inA, const float4 &inB) { return float4(inA.x + inB.x, inA.y + inB.y, inA.z + inB.z, inA.w + inB.w); }
  162. constexpr float4 operator - (const float4 &inA, const float4 &inB) { return float4(inA.x - inB.x, inA.y - inB.y, inA.z - inB.z, inA.w - inB.w); }
  163. constexpr float4 operator * (const float4 &inA, const float4 &inB) { return float4(inA.x * inB.x, inA.y * inB.y, inA.z * inB.z, inA.w * inB.w); }
  164. constexpr float4 operator / (const float4 &inA, const float4 &inB) { return float4(inA.x / inB.x, inA.y / inB.y, inA.z / inB.z, inA.w / inB.w); }
  165. constexpr float4 operator * (const float4 &inA, float inS) { return float4(inA.x * inS, inA.y * inS, inA.z * inS, inA.w * inS); }
  166. constexpr float4 operator * (float inS, const float4 &inA) { return inA * inS; }
  167. constexpr float4 operator / (const float4 &inA, float inS) { return float4(inA.x / inS, inA.y / inS, inA.z / inS, inA.w / inS); }
  168. // Dot product
  169. constexpr float dot(const float4 &inA, const float4 &inB) { return inA.x * inB.x + inA.y * inB.y + inA.z * inB.z + inA.w * inB.w; }
  170. // Min value
  171. constexpr float4 min(const float4 &inA, const float4 &inB) { return float4(min(inA.x, inB.x), min(inA.y, inB.y), min(inA.z, inB.z), min(inA.w, inB.w)); }
  172. // Max value
  173. constexpr float4 max(const float4 &inA, const float4 &inB) { return float4(max(inA.x, inB.x), max(inA.y, inB.y), max(inA.z, inB.z), max(inA.w, inB.w)); }
  174. // Length
  175. inline float length(const float4 &inV) { return sqrt(dot(inV, inV)); }
  176. // Normalization
  177. inline float4 normalize(const float4 &inV) { return inV / length(inV); }
  178. // Rounding to int
  179. inline float4 round(const float4 &inV) { return float4(round(inV.x), round(inV.y), round(inV.z), round(inV.w)); }
  180. //////////////////////////////////////////////////////////////////////////////////////////
  181. // uint3
  182. //////////////////////////////////////////////////////////////////////////////////////////
  183. struct uint3
  184. {
  185. inline uint3() = default;
  186. constexpr uint3(uint32 inX, uint32 inY, uint32 inZ) : x(inX), y(inY), z(inZ) { }
  187. explicit constexpr uint3(const float3 &inV) : x(uint32(inV.x)), y(uint32(inV.y)), z(uint32(inV.z)) { }
  188. // Operators
  189. constexpr uint3 & operator += (const uint3 &inRHS) { x += inRHS.x; y += inRHS.y; z += inRHS.z; return *this; }
  190. constexpr uint3 & operator -= (const uint3 &inRHS) { x -= inRHS.x; y -= inRHS.y; z -= inRHS.z; return *this; }
  191. constexpr uint3 & operator *= (uint32 inRHS) { x *= inRHS; y *= inRHS; z *= inRHS; return *this; }
  192. constexpr uint3 & operator /= (uint32 inRHS) { x /= inRHS; y /= inRHS; z /= inRHS; return *this; }
  193. constexpr uint3 & operator *= (const uint3 &inRHS) { x *= inRHS.x; y *= inRHS.y; z *= inRHS.z; return *this; }
  194. constexpr uint3 & operator /= (const uint3 &inRHS) { x /= inRHS.x; y /= inRHS.y; z /= inRHS.z; return *this; }
  195. // Equality
  196. constexpr bool operator == (const uint3 &inRHS) const { return x == inRHS.x && y == inRHS.y && z == inRHS.z; }
  197. constexpr bool operator != (const uint3 &inRHS) const { return !(*this == inRHS); }
  198. // Component access
  199. const uint32 & operator [] (uint inIndex) const { return (&x)[inIndex]; }
  200. uint32 & operator [] (uint inIndex) { return (&x)[inIndex]; }
  201. // Swizzling (note return value is const to prevent assignment to swizzled results)
  202. const uint3 swizzle_xyz() const { return uint3(x, y, z); }
  203. const uint3 swizzle_xzy() const { return uint3(x, z, y); }
  204. const uint3 swizzle_yxz() const { return uint3(y, x, z); }
  205. const uint3 swizzle_yzx() const { return uint3(y, z, x); }
  206. const uint3 swizzle_zxy() const { return uint3(z, x, y); }
  207. const uint3 swizzle_zyx() const { return uint3(z, y, x); }
  208. uint32 x, y, z;
  209. };
  210. // Operators
  211. constexpr uint3 operator + (const uint3 &inA, const uint3 &inB) { return uint3(inA.x + inB.x, inA.y + inB.y, inA.z + inB.z); }
  212. constexpr uint3 operator - (const uint3 &inA, const uint3 &inB) { return uint3(inA.x - inB.x, inA.y - inB.y, inA.z - inB.z); }
  213. constexpr uint3 operator * (const uint3 &inA, const uint3 &inB) { return uint3(inA.x * inB.x, inA.y * inB.y, inA.z * inB.z); }
  214. constexpr uint3 operator / (const uint3 &inA, const uint3 &inB) { return uint3(inA.x / inB.x, inA.y / inB.y, inA.z / inB.z); }
  215. constexpr uint3 operator * (const uint3 &inA, uint32 inS) { return uint3(inA.x * inS, inA.y * inS, inA.z * inS); }
  216. constexpr uint3 operator * (uint32 inS, const uint3 &inA) { return inA * inS; }
  217. constexpr uint3 operator / (const uint3 &inA, uint32 inS) { return uint3(inA.x / inS, inA.y / inS, inA.z / inS); }
  218. // Dot product
  219. constexpr uint32 dot(const uint3 &inA, const uint3 &inB) { return inA.x * inB.x + inA.y * inB.y + inA.z * inB.z; }
  220. // Min value
  221. constexpr uint3 min(const uint3 &inA, const uint3 &inB) { return uint3(min(inA.x, inB.x), min(inA.y, inB.y), min(inA.z, inB.z)); }
  222. // Max value
  223. constexpr uint3 max(const uint3 &inA, const uint3 &inB) { return uint3(max(inA.x, inB.x), max(inA.y, inB.y), max(inA.z, inB.z)); }
  224. //////////////////////////////////////////////////////////////////////////////////////////
  225. // uint4
  226. //////////////////////////////////////////////////////////////////////////////////////////
  227. struct uint4
  228. {
  229. // Constructors
  230. inline uint4() = default;
  231. constexpr uint4(const uint3 &inV, uint32 inW) : x(inV.x), y(inV.y), z(inV.z), w(inW) { }
  232. constexpr uint4(uint32 inX, uint32 inY, uint32 inZ, uint32 inW) : x(inX), y(inY), z(inZ), w(inW) { }
  233. explicit constexpr uint4(uint32 inS) : x(inS), y(inS), z(inS), w(inS) { }
  234. // Operators
  235. constexpr uint4 & operator += (const uint4 &inRHS) { x += inRHS.x; y += inRHS.y; z += inRHS.z; w += inRHS.w; return *this; }
  236. constexpr uint4 & operator -= (const uint4 &inRHS) { x -= inRHS.x; y -= inRHS.y; z -= inRHS.z; w -= inRHS.w; return *this; }
  237. constexpr uint4 & operator *= (uint32 inRHS) { x *= inRHS; y *= inRHS; z *= inRHS; w *= inRHS; return *this; }
  238. constexpr uint4 & operator /= (uint32 inRHS) { x /= inRHS; y /= inRHS; z /= inRHS; w /= inRHS; return *this; }
  239. constexpr uint4 & operator *= (const uint4 &inRHS) { x *= inRHS.x; y *= inRHS.y; z *= inRHS.z; w *= inRHS.w; return *this; }
  240. constexpr uint4 & operator /= (const uint4 &inRHS) { x /= inRHS.x; y /= inRHS.y; z /= inRHS.z; w /= inRHS.w; return *this; }
  241. // Equality
  242. constexpr bool operator == (const uint4 &inRHS) const { return x == inRHS.x && y == inRHS.y && z == inRHS.z && w == inRHS.w; }
  243. constexpr bool operator != (const uint4 &inRHS) const { return !(*this == inRHS); }
  244. // Component access
  245. const uint32 & operator [] (uint inIndex) const { return (&x)[inIndex]; }
  246. uint32 & operator [] (uint inIndex) { return (&x)[inIndex]; }
  247. // Swizzling (note return value is const to prevent assignment to swizzled results)
  248. const uint3 swizzle_xyz() const { return uint3(x, y, z); }
  249. const uint3 swizzle_xzy() const { return uint3(x, z, y); }
  250. const uint3 swizzle_yxz() const { return uint3(y, x, z); }
  251. const uint3 swizzle_yzx() const { return uint3(y, z, x); }
  252. const uint3 swizzle_zxy() const { return uint3(z, x, y); }
  253. const uint3 swizzle_zyx() const { return uint3(z, y, x); }
  254. const uint4 swizzle_xywz() const { return uint4(x, y, w, z); }
  255. const uint4 swizzle_xwyz() const { return uint4(x, w, y, z); }
  256. const uint4 swizzle_wxyz() const { return uint4(w, x, y, z); }
  257. uint32 x, y, z, w;
  258. };
  259. // Operators
  260. constexpr uint4 operator + (const uint4 &inA, const uint4 &inB) { return uint4(inA.x + inB.x, inA.y + inB.y, inA.z + inB.z, inA.w + inB.w); }
  261. constexpr uint4 operator - (const uint4 &inA, const uint4 &inB) { return uint4(inA.x - inB.x, inA.y - inB.y, inA.z - inB.z, inA.w - inB.w); }
  262. constexpr uint4 operator * (const uint4 &inA, const uint4 &inB) { return uint4(inA.x * inB.x, inA.y * inB.y, inA.z * inB.z, inA.w * inB.w); }
  263. constexpr uint4 operator / (const uint4 &inA, const uint4 &inB) { return uint4(inA.x / inB.x, inA.y / inB.y, inA.z / inB.z, inA.w / inB.w); }
  264. constexpr uint4 operator * (const uint4 &inA, uint32 inS) { return uint4(inA.x * inS, inA.y * inS, inA.z * inS, inA.w * inS); }
  265. constexpr uint4 operator * (uint32 inS, const uint4 &inA) { return inA * inS; }
  266. constexpr uint4 operator / (const uint4 &inA, uint32 inS) { return uint4(inA.x / inS, inA.y / inS, inA.z / inS, inA.w / inS); }
  267. // Dot product
  268. constexpr uint32 dot(const uint4 &inA, const uint4 &inB) { return inA.x * inB.x + inA.y * inB.y + inA.z * inB.z + inA.w * inB.w; }
  269. // Min value
  270. constexpr uint4 min(const uint4 &inA, const uint4 &inB) { return uint4(min(inA.x, inB.x), min(inA.y, inB.y), min(inA.z, inB.z), min(inA.w, inB.w)); }
  271. // Max value
  272. constexpr uint4 max(const uint4 &inA, const uint4 &inB) { return uint4(max(inA.x, inB.x), max(inA.y, inB.y), max(inA.z, inB.z), max(inA.w, inB.w)); }
  273. //////////////////////////////////////////////////////////////////////////////////////////
  274. // int3
  275. //////////////////////////////////////////////////////////////////////////////////////////
  276. struct int3
  277. {
  278. inline int3() = default;
  279. constexpr int3(int inX, int inY, int inZ) : x(inX), y(inY), z(inZ) { }
  280. explicit constexpr int3(const float3 &inV) : x(int(inV.x)), y(int(inV.y)), z(int(inV.z)) { }
  281. // Operators
  282. constexpr int3 & operator += (const int3 &inRHS) { x += inRHS.x; y += inRHS.y; z += inRHS.z; return *this; }
  283. constexpr int3 & operator -= (const int3 &inRHS) { x -= inRHS.x; y -= inRHS.y; z -= inRHS.z; return *this; }
  284. constexpr int3 & operator *= (int inRHS) { x *= inRHS; y *= inRHS; z *= inRHS; return *this; }
  285. constexpr int3 & operator /= (int inRHS) { x /= inRHS; y /= inRHS; z /= inRHS; return *this; }
  286. constexpr int3 & operator *= (const int3 &inRHS) { x *= inRHS.x; y *= inRHS.y; z *= inRHS.z; return *this; }
  287. constexpr int3 & operator /= (const int3 &inRHS) { x /= inRHS.x; y /= inRHS.y; z /= inRHS.z; return *this; }
  288. // Equality
  289. constexpr bool operator == (const int3 &inRHS) const { return x == inRHS.x && y == inRHS.y && z == inRHS.z; }
  290. constexpr bool operator != (const int3 &inRHS) const { return !(*this == inRHS); }
  291. // Component access
  292. const int & operator [] (uint inIndex) const { return (&x)[inIndex]; }
  293. int & operator [] (uint inIndex) { return (&x)[inIndex]; }
  294. // Swizzling (note return value is const to prevent assignment to swizzled results)
  295. const int3 swizzle_xyz() const { return int3(x, y, z); }
  296. const int3 swizzle_xzy() const { return int3(x, z, y); }
  297. const int3 swizzle_yxz() const { return int3(y, x, z); }
  298. const int3 swizzle_yzx() const { return int3(y, z, x); }
  299. const int3 swizzle_zxy() const { return int3(z, x, y); }
  300. const int3 swizzle_zyx() const { return int3(z, y, x); }
  301. int x, y, z;
  302. };
  303. // Operators
  304. constexpr int3 operator - (const int3 &inA) { return int3(-inA.x, -inA.y, -inA.z); }
  305. constexpr int3 operator + (const int3 &inA, const int3 &inB) { return int3(inA.x + inB.x, inA.y + inB.y, inA.z + inB.z); }
  306. constexpr int3 operator - (const int3 &inA, const int3 &inB) { return int3(inA.x - inB.x, inA.y - inB.y, inA.z - inB.z); }
  307. constexpr int3 operator * (const int3 &inA, const int3 &inB) { return int3(inA.x * inB.x, inA.y * inB.y, inA.z * inB.z); }
  308. constexpr int3 operator / (const int3 &inA, const int3 &inB) { return int3(inA.x / inB.x, inA.y / inB.y, inA.z / inB.z); }
  309. constexpr int3 operator * (const int3 &inA, int inS) { return int3(inA.x * inS, inA.y * inS, inA.z * inS); }
  310. constexpr int3 operator * (int inS, const int3 &inA) { return inA * inS; }
  311. constexpr int3 operator / (const int3 &inA, int inS) { return int3(inA.x / inS, inA.y / inS, inA.z / inS); }
  312. // Dot product
  313. constexpr int dot(const int3 &inA, const int3 &inB) { return inA.x * inB.x + inA.y * inB.y + inA.z * inB.z; }
  314. // Min value
  315. constexpr int3 min(const int3 &inA, const int3 &inB) { return int3(min(inA.x, inB.x), min(inA.y, inB.y), min(inA.z, inB.z)); }
  316. // Max value
  317. constexpr int3 max(const int3 &inA, const int3 &inB) { return int3(max(inA.x, inB.x), max(inA.y, inB.y), max(inA.z, inB.z)); }
  318. //////////////////////////////////////////////////////////////////////////////////////////
  319. // int4
  320. //////////////////////////////////////////////////////////////////////////////////////////
  321. struct int4
  322. {
  323. // Constructors
  324. inline int4() = default;
  325. constexpr int4(const int3 &inV, int inW) : x(inV.x), y(inV.y), z(inV.z), w(inW) { }
  326. constexpr int4(int inX, int inY, int inZ, int inW) : x(inX), y(inY), z(inZ), w(inW) { }
  327. explicit constexpr int4(int inS) : x(inS), y(inS), z(inS), w(inS) { }
  328. explicit constexpr int4(const float4 &inV) : x(int(inV.x)), y(int(inV.y)), z(int(inV.z)), w(int(inV.w)) { }
  329. // Operators
  330. constexpr int4 & operator += (const int4 &inRHS) { x += inRHS.x; y += inRHS.y; z += inRHS.z; w += inRHS.w; return *this; }
  331. constexpr int4 & operator -= (const int4 &inRHS) { x -= inRHS.x; y -= inRHS.y; z -= inRHS.z; w -= inRHS.w; return *this; }
  332. constexpr int4 & operator *= (int inRHS) { x *= inRHS; y *= inRHS; z *= inRHS; w *= inRHS; return *this; }
  333. constexpr int4 & operator /= (int inRHS) { x /= inRHS; y /= inRHS; z /= inRHS; w /= inRHS; return *this; }
  334. constexpr int4 & operator *= (const int4 &inRHS) { x *= inRHS.x; y *= inRHS.y; z *= inRHS.z; w *= inRHS.w; return *this; }
  335. constexpr int4 & operator /= (const int4 &inRHS) { x /= inRHS.x; y /= inRHS.y; z /= inRHS.z; w /= inRHS.w; return *this; }
  336. // Equality
  337. constexpr bool operator == (const int4 &inRHS) const { return x == inRHS.x && y == inRHS.y && z == inRHS.z && w == inRHS.w; }
  338. constexpr bool operator != (const int4 &inRHS) const { return !(*this == inRHS); }
  339. // Component access
  340. const int & operator [] (uint inIndex) const { return (&x)[inIndex]; }
  341. int & operator [] (uint inIndex) { return (&x)[inIndex]; }
  342. // Swizzling (note return value is const to prevent assignment to swizzled results)
  343. const int3 swizzle_xyz() const { return int3(x, y, z); }
  344. const int3 swizzle_xzy() const { return int3(x, z, y); }
  345. const int3 swizzle_yxz() const { return int3(y, x, z); }
  346. const int3 swizzle_yzx() const { return int3(y, z, x); }
  347. const int3 swizzle_zxy() const { return int3(z, x, y); }
  348. const int3 swizzle_zyx() const { return int3(z, y, x); }
  349. const int4 swizzle_xywz() const { return int4(x, y, w, z); }
  350. const int4 swizzle_xwyz() const { return int4(x, w, y, z); }
  351. const int4 swizzle_wxyz() const { return int4(w, x, y, z); }
  352. int x, y, z, w;
  353. };
  354. // Operators
  355. constexpr int4 operator - (const int4 &inA) { return int4(-inA.x, -inA.y, -inA.z, -inA.w); }
  356. constexpr int4 operator + (const int4 &inA, const int4 &inB) { return int4(inA.x + inB.x, inA.y + inB.y, inA.z + inB.z, inA.w + inB.w); }
  357. constexpr int4 operator - (const int4 &inA, const int4 &inB) { return int4(inA.x - inB.x, inA.y - inB.y, inA.z - inB.z, inA.w - inB.w); }
  358. constexpr int4 operator * (const int4 &inA, const int4 &inB) { return int4(inA.x * inB.x, inA.y * inB.y, inA.z * inB.z, inA.w * inB.w); }
  359. constexpr int4 operator / (const int4 &inA, const int4 &inB) { return int4(inA.x / inB.x, inA.y / inB.y, inA.z / inB.z, inA.w / inB.w); }
  360. constexpr int4 operator * (const int4 &inA, int inS) { return int4(inA.x * inS, inA.y * inS, inA.z * inS, inA.w * inS); }
  361. constexpr int4 operator * (int inS, const int4 &inA) { return inA * inS; }
  362. constexpr int4 operator / (const int4 &inA, int inS) { return int4(inA.x / inS, inA.y / inS, inA.z / inS, inA.w / inS); }
  363. // Dot product
  364. constexpr int dot(const int4 &inA, const int4 &inB) { return inA.x * inB.x + inA.y * inB.y + inA.z * inB.z + inA.w * inB.w; }
  365. // Min value
  366. constexpr int4 min(const int4 &inA, const int4 &inB) { return int4(min(inA.x, inB.x), min(inA.y, inB.y), min(inA.z, inB.z), min(inA.w, inB.w)); }
  367. // Max value
  368. constexpr int4 max(const int4 &inA, const int4 &inB) { return int4(max(inA.x, inB.x), max(inA.y, inB.y), max(inA.z, inB.z), max(inA.w, inB.w)); }
  369. //////////////////////////////////////////////////////////////////////////////////////////
  370. // Mat44
  371. //////////////////////////////////////////////////////////////////////////////////////////
  372. struct Mat44
  373. {
  374. // Constructors
  375. inline Mat44() = default;
  376. constexpr Mat44(const float4 &inC0, const float4 &inC1, const float4 &inC2, const float4 &inC3) : c { inC0, inC1, inC2, inC3 } { }
  377. // Columns
  378. float4 & operator [] (uint inIndex) { return c[inIndex]; }
  379. const float4 & operator [] (uint inIndex) const { return c[inIndex]; }
  380. private:
  381. float4 c[4];
  382. };
  383. //////////////////////////////////////////////////////////////////////////////////////////
  384. // Other types
  385. //////////////////////////////////////////////////////////////////////////////////////////
  386. using Quat = float4;
  387. using Plane = float4;
  388. // Clamp value
  389. template <class T>
  390. constexpr T clamp(const T &inValue, const T &inMinValue, const T &inMaxValue)
  391. {
  392. return min(max(inValue, inMinValue), inMaxValue);
  393. }
  394. // Atomic add
  395. template <class T>
  396. T JPH_AtomicAdd(T &ioT, const T &inValue)
  397. {
  398. std::atomic<T> *value = reinterpret_cast<std::atomic<T> *>(&ioT);
  399. return value->fetch_add(inValue) + inValue;
  400. }
  401. // Bitcast float4 to int4
  402. inline int4 asint(const float4 &inV) { return int4(BitCast<int>(inV.x), BitCast<int>(inV.y), BitCast<int>(inV.z), BitCast<int>(inV.w)); }
  403. // Functions that couldn't be declared earlier
  404. constexpr float3::float3(const uint3 &inV) : x(float(inV.x)), y(float(inV.y)), z(float(inV.z)) { }
  405. constexpr float4::float4(const int4 &inV) : x(float(inV.x)), y(float(inV.y)), z(float(inV.z)), w(float(inV.w)) { }
  406. // Swizzle operators
  407. #define xy swizzle_xy()
  408. #define yx swizzle_yx()
  409. #define xyz swizzle_xyz()
  410. #define xzy swizzle_xzy()
  411. #define yxz swizzle_yxz()
  412. #define yzx swizzle_yzx()
  413. #define zxy swizzle_zxy()
  414. #define zyx swizzle_zyx()
  415. #define xywz swizzle_xywz()
  416. #define xwyz swizzle_xwyz()
  417. #define wxyz swizzle_wxyz()
  418. } // HLSLToCPP
  419. JPH_NAMESPACE_END