nv-sgl 0.6.0__cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. include/tevclient.h +393 -0
  2. nv_sgl-0.6.0.dist-info/LICENSE +29 -0
  3. nv_sgl-0.6.0.dist-info/METADATA +21 -0
  4. nv_sgl-0.6.0.dist-info/RECORD +133 -0
  5. nv_sgl-0.6.0.dist-info/WHEEL +6 -0
  6. nv_sgl-0.6.0.dist-info/top_level.txt +1 -0
  7. sgl/__init__.py +15 -0
  8. sgl/__init__.pyi +6738 -0
  9. sgl/include/sgl/app/app.h +113 -0
  10. sgl/include/sgl/core/bitmap.h +302 -0
  11. sgl/include/sgl/core/crypto.h +89 -0
  12. sgl/include/sgl/core/data_type.h +46 -0
  13. sgl/include/sgl/core/dds_file.h +103 -0
  14. sgl/include/sgl/core/enum.h +201 -0
  15. sgl/include/sgl/core/error.h +161 -0
  16. sgl/include/sgl/core/file_stream.h +77 -0
  17. sgl/include/sgl/core/file_system_watcher.h +141 -0
  18. sgl/include/sgl/core/format.h +36 -0
  19. sgl/include/sgl/core/fwd.h +90 -0
  20. sgl/include/sgl/core/hash.h +45 -0
  21. sgl/include/sgl/core/input.h +522 -0
  22. sgl/include/sgl/core/logger.h +214 -0
  23. sgl/include/sgl/core/macros.h +184 -0
  24. sgl/include/sgl/core/maths.h +45 -0
  25. sgl/include/sgl/core/memory_mapped_file.h +112 -0
  26. sgl/include/sgl/core/memory_mapped_file_stream.h +32 -0
  27. sgl/include/sgl/core/memory_stream.h +74 -0
  28. sgl/include/sgl/core/object.h +683 -0
  29. sgl/include/sgl/core/platform.h +239 -0
  30. sgl/include/sgl/core/plugin.h +331 -0
  31. sgl/include/sgl/core/resolver.h +39 -0
  32. sgl/include/sgl/core/short_vector.h +141 -0
  33. sgl/include/sgl/core/static_vector.h +111 -0
  34. sgl/include/sgl/core/stream.h +54 -0
  35. sgl/include/sgl/core/string.h +276 -0
  36. sgl/include/sgl/core/struct.h +360 -0
  37. sgl/include/sgl/core/thread.h +28 -0
  38. sgl/include/sgl/core/timer.h +52 -0
  39. sgl/include/sgl/core/traits.h +15 -0
  40. sgl/include/sgl/core/type_utils.h +19 -0
  41. sgl/include/sgl/core/window.h +177 -0
  42. sgl/include/sgl/device/agility_sdk.h +24 -0
  43. sgl/include/sgl/device/blit.h +88 -0
  44. sgl/include/sgl/device/buffer_cursor.h +162 -0
  45. sgl/include/sgl/device/command.h +539 -0
  46. sgl/include/sgl/device/cuda_api.h +766 -0
  47. sgl/include/sgl/device/cuda_interop.h +39 -0
  48. sgl/include/sgl/device/cuda_utils.h +107 -0
  49. sgl/include/sgl/device/cursor_utils.h +129 -0
  50. sgl/include/sgl/device/device.h +668 -0
  51. sgl/include/sgl/device/device_resource.h +37 -0
  52. sgl/include/sgl/device/fence.h +91 -0
  53. sgl/include/sgl/device/formats.h +330 -0
  54. sgl/include/sgl/device/framebuffer.h +85 -0
  55. sgl/include/sgl/device/fwd.h +164 -0
  56. sgl/include/sgl/device/helpers.h +20 -0
  57. sgl/include/sgl/device/hot_reload.h +75 -0
  58. sgl/include/sgl/device/input_layout.h +74 -0
  59. sgl/include/sgl/device/kernel.h +69 -0
  60. sgl/include/sgl/device/memory_heap.h +155 -0
  61. sgl/include/sgl/device/native_formats.h +342 -0
  62. sgl/include/sgl/device/native_handle.h +73 -0
  63. sgl/include/sgl/device/native_handle_traits.h +65 -0
  64. sgl/include/sgl/device/pipeline.h +138 -0
  65. sgl/include/sgl/device/print.h +45 -0
  66. sgl/include/sgl/device/python/cursor_utils.h +853 -0
  67. sgl/include/sgl/device/query.h +52 -0
  68. sgl/include/sgl/device/raytracing.h +84 -0
  69. sgl/include/sgl/device/reflection.h +1254 -0
  70. sgl/include/sgl/device/resource.h +705 -0
  71. sgl/include/sgl/device/sampler.h +57 -0
  72. sgl/include/sgl/device/shader.h +516 -0
  73. sgl/include/sgl/device/shader_cursor.h +85 -0
  74. sgl/include/sgl/device/shader_object.h +94 -0
  75. sgl/include/sgl/device/shader_offset.h +67 -0
  76. sgl/include/sgl/device/shared_handle.h +12 -0
  77. sgl/include/sgl/device/slang_utils.h +54 -0
  78. sgl/include/sgl/device/swapchain.h +74 -0
  79. sgl/include/sgl/device/types.h +782 -0
  80. sgl/include/sgl/math/colorspace.h +56 -0
  81. sgl/include/sgl/math/constants.h +7 -0
  82. sgl/include/sgl/math/float16.h +146 -0
  83. sgl/include/sgl/math/matrix.h +6 -0
  84. sgl/include/sgl/math/matrix_math.h +746 -0
  85. sgl/include/sgl/math/matrix_types.h +207 -0
  86. sgl/include/sgl/math/python/primitivetype.h +33 -0
  87. sgl/include/sgl/math/quaternion.h +6 -0
  88. sgl/include/sgl/math/quaternion_math.h +484 -0
  89. sgl/include/sgl/math/quaternion_types.h +83 -0
  90. sgl/include/sgl/math/ray.h +47 -0
  91. sgl/include/sgl/math/scalar_math.h +249 -0
  92. sgl/include/sgl/math/scalar_types.h +107 -0
  93. sgl/include/sgl/math/vector.h +6 -0
  94. sgl/include/sgl/math/vector_math.h +1796 -0
  95. sgl/include/sgl/math/vector_types.h +336 -0
  96. sgl/include/sgl/python/nanobind.h +489 -0
  97. sgl/include/sgl/python/py_doc.h +11600 -0
  98. sgl/include/sgl/python/sgl_ext_pch.h +8 -0
  99. sgl/include/sgl/sgl.h +21 -0
  100. sgl/include/sgl/sgl_pch.h +6 -0
  101. sgl/include/sgl/stl/bit.h +377 -0
  102. sgl/include/sgl/tests/testing.h +54 -0
  103. sgl/include/sgl/ui/fwd.h +34 -0
  104. sgl/include/sgl/ui/imgui_config.h +43 -0
  105. sgl/include/sgl/ui/ui.h +71 -0
  106. sgl/include/sgl/ui/widgets.h +918 -0
  107. sgl/include/sgl/utils/python/slangpy.h +366 -0
  108. sgl/include/sgl/utils/renderdoc.h +50 -0
  109. sgl/include/sgl/utils/slangpy.h +153 -0
  110. sgl/include/sgl/utils/tev.h +93 -0
  111. sgl/include/sgl/utils/texture_loader.h +106 -0
  112. sgl/libgfx.so +0 -0
  113. sgl/libsgl.so +0 -0
  114. sgl/libslang-glslang.so +0 -0
  115. sgl/libslang.so +0 -0
  116. sgl/libtevclient.a +0 -0
  117. sgl/math/__init__.pyi +5083 -0
  118. sgl/platform/__init__.pyi +102 -0
  119. sgl/renderdoc/__init__.pyi +51 -0
  120. sgl/sgl_ext.cpython-313-x86_64-linux-gnu.so +0 -0
  121. sgl/shaders/sgl/device/blit.slang +93 -0
  122. sgl/shaders/sgl/device/nvapi.slang +5 -0
  123. sgl/shaders/sgl/device/nvapi.slangh +7 -0
  124. sgl/shaders/sgl/device/print.slang +445 -0
  125. sgl/shaders/sgl/math/constants.slang +4 -0
  126. sgl/shaders/sgl/math/ray.slang +29 -0
  127. sgl/shaders/sgl/ui/imgui.slang +49 -0
  128. sgl/slangpy/__init__.pyi +268 -0
  129. sgl/tev/__init__.pyi +108 -0
  130. sgl/thread/__init__.pyi +4 -0
  131. sgl/ui/__init__.pyi +1118 -0
  132. share/cmake/tevclient/tevclient-config-release.cmake +19 -0
  133. share/cmake/tevclient/tevclient-config.cmake +103 -0
@@ -0,0 +1,484 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+
3
+ // Most of this code is derived from the GLM library at https://github.com/g-truc/glm
4
+ // License: https://github.com/g-truc/glm/blob/master/copying.txt
5
+
6
+ #pragma once
7
+
8
+ #include "sgl/math/quaternion_types.h"
9
+ #include "sgl/math/matrix_types.h"
10
+ #include "sgl/math/scalar_math.h"
11
+ #include "sgl/math/vector_math.h"
12
+ #include "sgl/math/constants.h"
13
+ #include "sgl/core/error.h"
14
+
15
+ namespace sgl::math {
16
+
17
+ // ----------------------------------------------------------------------------
18
+ // Unary operators (component-wise)
19
+ // ----------------------------------------------------------------------------
20
+
21
+ /// Unary plus operator
22
+ template<typename T>
23
+ [[nodiscard]] constexpr quat<T> operator+(const quat<T> q) noexcept
24
+ {
25
+ return q;
26
+ }
27
+
28
+ /// Unary minus operator
29
+ template<typename T>
30
+ [[nodiscard]] constexpr quat<T> operator-(const quat<T> q) noexcept
31
+ {
32
+ return quat<T>{-q.x, -q.y, -q.z, -q.w};
33
+ }
34
+
35
+ // ----------------------------------------------------------------------------
36
+ // Binary operators (component-wise)
37
+ // ----------------------------------------------------------------------------
38
+
39
+ /// Binary + operator
40
+ template<typename T>
41
+ [[nodiscard]] constexpr quat<T> operator+(const quat<T>& lhs, const quat<T>& rhs) noexcept
42
+ {
43
+ return quat<T>{lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w};
44
+ }
45
+
46
+ /// Binary + operator
47
+ template<typename T>
48
+ [[nodiscard]] constexpr quat<T> operator+(const quat<T>& lhs, T rhs) noexcept
49
+ {
50
+ return quat<T>{lhs.x + rhs, lhs.y + rhs, lhs.z + rhs, lhs.w + rhs};
51
+ }
52
+
53
+ /// Binary + operator
54
+ template<typename T>
55
+ [[nodiscard]] constexpr quat<T> operator+(T lhs, const quat<T>& rhs) noexcept
56
+ {
57
+ return quat<T>{lhs + rhs.x, lhs + rhs.y, lhs + rhs.z, lhs + rhs.w};
58
+ }
59
+
60
+ /// Binary - operator
61
+ template<typename T>
62
+ [[nodiscard]] constexpr quat<T> operator-(const quat<T>& lhs, const quat<T>& rhs) noexcept
63
+ {
64
+ return quat<T>{lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w};
65
+ }
66
+
67
+ /// Binary - operator
68
+ template<typename T>
69
+ [[nodiscard]] constexpr quat<T> operator-(const quat<T>& lhs, T rhs) noexcept
70
+ {
71
+ return quat<T>{lhs.x - rhs, lhs.y - rhs, lhs.z - rhs, lhs.w - rhs};
72
+ }
73
+
74
+ /// Binary - operator
75
+ template<typename T>
76
+ [[nodiscard]] constexpr quat<T> operator-(T lhs, const quat<T>& rhs) noexcept
77
+ {
78
+ return quat<T>{lhs - rhs.x, lhs - rhs.y, lhs - rhs.z, lhs - rhs.w};
79
+ }
80
+
81
+ /// Binary * operator
82
+ template<typename T>
83
+ [[nodiscard]] constexpr quat<T> operator*(const quat<T>& lhs, T rhs) noexcept
84
+ {
85
+ return quat<T>{lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs};
86
+ }
87
+
88
+ /// Binary * operator
89
+ template<typename T>
90
+ [[nodiscard]] constexpr quat<T> operator*(T lhs, const quat<T>& rhs) noexcept
91
+ {
92
+ return quat<T>{lhs * rhs.x, lhs * rhs.y, lhs * rhs.z, lhs * rhs.w};
93
+ }
94
+
95
+ /// Binary / operator
96
+ template<typename T>
97
+ [[nodiscard]] constexpr quat<T> operator/(const quat<T>& lhs, T rhs) noexcept
98
+ {
99
+ return quat<T>{lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs};
100
+ }
101
+
102
+ /// Binary == operator
103
+ template<typename T>
104
+ [[nodiscard]] constexpr vector<bool, 4> operator==(const quat<T>& lhs, const quat<T>& rhs)
105
+ {
106
+ return bool4{lhs.x == rhs.x, lhs.y == rhs.y, lhs.z == rhs.z, lhs.w == rhs.w};
107
+ }
108
+
109
+ /// Binary != operator
110
+ template<typename T>
111
+ [[nodiscard]] constexpr vector<bool, 4> operator!=(const quat<T>& lhs, const quat<T>& rhs)
112
+ {
113
+ return bool4{lhs.x != rhs.x, lhs.y != rhs.y, lhs.z != rhs.z, lhs.w != rhs.w};
114
+ }
115
+
116
+ // ----------------------------------------------------------------------------
117
+ // Multiplication
118
+ // ----------------------------------------------------------------------------
119
+
120
+ /// Multiply quaternion with another quaternion.
121
+ template<typename T>
122
+ [[nodiscard]] constexpr quat<T> mul(const quat<T>& lhs, const quat<T>& rhs) noexcept
123
+ {
124
+ return quat<T>{
125
+ lhs.w * rhs.x + lhs.x * rhs.w + lhs.y * rhs.z - lhs.z * rhs.y, // x
126
+ lhs.w * rhs.y + lhs.y * rhs.w + lhs.z * rhs.x - lhs.x * rhs.z, // y
127
+ lhs.w * rhs.z + lhs.z * rhs.w + lhs.x * rhs.y - lhs.y * rhs.x, // z
128
+ lhs.w * rhs.w - lhs.x * rhs.x - lhs.y * rhs.y - lhs.z * rhs.z // w
129
+ };
130
+ }
131
+
132
+ /// Multiply quaternion and 3 component vector.
133
+ template<typename T>
134
+ [[nodiscard]] constexpr vector<T, 3> mul(const quat<T>& q, const vector<T, 3>& v) noexcept
135
+ {
136
+ vector<T, 3> qv(q.x, q.y, q.z);
137
+ vector<T, 3> uv(cross(qv, v));
138
+ vector<T, 3> uuv(cross(qv, uv));
139
+ return v + ((uv * q.w) + uuv) * T(2);
140
+ }
141
+
142
+ /// Transform a vector by a quaternion.
143
+ template<typename T>
144
+ [[nodiscard]] constexpr vector<T, 3> transform_vector(const quat<T>& q, const vector<T, 3>& v) noexcept
145
+ {
146
+ return mul(q, v);
147
+ }
148
+
149
+ // ----------------------------------------------------------------------------
150
+ // Floating point checks
151
+ // ----------------------------------------------------------------------------
152
+
153
+ /// isfinite
154
+ template<typename T>
155
+ [[nodiscard]] constexpr vector<bool, 4> isfinite(const quat<T>& q)
156
+ {
157
+ return vector<bool, 4>{isfinite(q.x), isfinite(q.y), isfinite(q.z), isfinite(q.w)};
158
+ }
159
+
160
+ /// isinf
161
+ template<typename T>
162
+ [[nodiscard]] constexpr vector<bool, 4> isinf(const quat<T>& q)
163
+ {
164
+ return vector<bool, 4>{isinf(q.x), isinf(q.y), isinf(q.z), isinf(q.w)};
165
+ }
166
+
167
+ /// isnan
168
+ template<typename T>
169
+ [[nodiscard]] constexpr vector<bool, 4> isnan(const quat<T>& q)
170
+ {
171
+ return vector<bool, 4>{isnan(q.x), isnan(q.y), isnan(q.z), isnan(q.w)};
172
+ }
173
+
174
+ // ----------------------------------------------------------------------------
175
+ // Geometryic functions
176
+ // ----------------------------------------------------------------------------
177
+
178
+ /// dot
179
+ template<typename T>
180
+ [[nodiscard]] constexpr T dot(const quat<T>& lhs, const quat<T>& rhs)
181
+ {
182
+ vector<T, 4> tmp{lhs.w * rhs.w, lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z};
183
+ return (tmp.x + tmp.y) + (tmp.z + tmp.w);
184
+ }
185
+
186
+ /// cross
187
+ template<typename T>
188
+ [[nodiscard]] constexpr quat<T> cross(const quat<T>& lhs, const quat<T>& rhs)
189
+ {
190
+ return quat<T>(
191
+ lhs.w * rhs.x + lhs.x * rhs.w + lhs.y * rhs.z - lhs.z * rhs.y, // x
192
+ lhs.w * rhs.y + lhs.y * rhs.w + lhs.z * rhs.x - lhs.x * rhs.z, // y
193
+ lhs.w * rhs.z + lhs.z * rhs.w + lhs.x * rhs.y - lhs.y * rhs.x, // z
194
+ lhs.w * rhs.w - lhs.x * rhs.x - lhs.y * rhs.y - lhs.z * rhs.z // w
195
+ );
196
+ }
197
+
198
+ /// length
199
+ template<typename T>
200
+ [[nodiscard]] T length(const quat<T>& q)
201
+ {
202
+ return sqrt(dot(q, q));
203
+ }
204
+
205
+ /// normalize
206
+ template<typename T>
207
+ [[nodiscard]] constexpr quat<T> normalize(const quat<T>& q)
208
+ {
209
+ T len = length(q);
210
+ if (len <= T(0))
211
+ return quat<T>(T(0), T(0), T(0), T(1));
212
+ return q * (T(1) / len);
213
+ }
214
+
215
+ /// conjugate
216
+ template<typename T>
217
+ [[nodiscard]] constexpr quat<T> conjugate(const quat<T>& q)
218
+ {
219
+ return quat<T>(-q.x, -q.y, -q.z, q.w);
220
+ }
221
+
222
+ /// inverse
223
+ template<typename T>
224
+ quat<T> inverse(const quat<T>& q)
225
+ {
226
+ return conjugate(q) / dot(q, q);
227
+ }
228
+
229
+ /// Linear interpolation.
230
+ template<typename T>
231
+ [[nodiscard]] constexpr quat<T> lerp(const quat<T>& x, const quat<T>& y, T t)
232
+ {
233
+ return x * (T(1) - t) + y * t;
234
+ }
235
+
236
+ /// Spherical linear interpolation.
237
+ template<typename T>
238
+ [[nodiscard]] constexpr quat<T> slerp(const quat<T>& x, const quat<T>& y_, T t)
239
+ {
240
+ quat<T> y = y_;
241
+
242
+ T cos_theta = dot(x, y);
243
+
244
+ // If cos_theta < 0, the interpolation will take the long way around the sphere.
245
+ // To fix this, one quat must be negated.
246
+ if (cos_theta < T(0)) {
247
+ y = -y;
248
+ cos_theta = -cos_theta;
249
+ }
250
+
251
+ // Perform a linear interpolation when cos_theta is close to 1 to avoid side effect of sin(angle) becoming a zero
252
+ // denominator
253
+ if (cos_theta > T(1) - std::numeric_limits<T>::epsilon()) {
254
+ // Linear interpolation
255
+ return lerp(x, y, t);
256
+ } else {
257
+ // Essential Mathematics, page 467
258
+ T angle = acos(cos_theta);
259
+ return (sin((T(1) - t) * angle) * x + sin(t * angle) * y) / sin(angle);
260
+ }
261
+ }
262
+
263
+ // ----------------------------------------------------------------------------
264
+ // Misc
265
+ // ----------------------------------------------------------------------------
266
+
267
+ /// Returns pitch value of euler angles expressed in radians.
268
+ template<typename T>
269
+ [[nodiscard]] constexpr T pitch(const quat<T>& q)
270
+ {
271
+ T y = T(2) * (q.y * q.z + q.w * q.x);
272
+ T x = q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z;
273
+
274
+ // Handle sigularity, avoid atan2(0,0)
275
+ if (abs(x) < std::numeric_limits<T>::epsilon() && abs(y) < std::numeric_limits<T>::epsilon())
276
+ return T(T(2) * atan2(q.x, q.w));
277
+
278
+ return atan2(y, x);
279
+ }
280
+
281
+ /// Returns yaw value of euler angles expressed in radians.
282
+ template<typename T>
283
+ [[nodiscard]] constexpr T yaw(const quat<T>& q)
284
+ {
285
+ return asin(clamp(T(-2) * (q.x * q.z - q.w * q.y), T(-1), T(1)));
286
+ }
287
+
288
+ /// Returns roll value of euler angles expressed in radians.
289
+ template<typename T>
290
+ [[nodiscard]] constexpr T roll(const quat<T>& q)
291
+ {
292
+ return atan2(T(2) * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z);
293
+ }
294
+
295
+ /// Extract the euler angles in radians from a quaternion (pitch as x, yaw as y, roll as z).
296
+ template<typename T>
297
+ [[nodiscard]] constexpr vector<T, 3> euler_angles(const quat<T>& q)
298
+ {
299
+ return vector<T, 3>(pitch(q), yaw(q), roll(q));
300
+ }
301
+
302
+ // ----------------------------------------------------------------------------
303
+ // Construction
304
+ // ----------------------------------------------------------------------------
305
+
306
+ /**
307
+ * Build a quaternion from an angle and a normalized axis.
308
+ * \param angle Angle expressed in radians.
309
+ * \param axis Axis of the quaternion (must be normalized).
310
+ */
311
+ template<typename T>
312
+ [[nodiscard]] inline quat<T> quat_from_angle_axis(T angle, const vector<T, 3>& axis)
313
+ {
314
+ T s = sin(angle * T(0.5));
315
+ T c = cos(angle * T(0.5));
316
+ return quat<T>(axis * s, c);
317
+ }
318
+
319
+ /**
320
+ * Compute the rotation between two vectors.
321
+ * \param from From vector (must to be normalized).
322
+ * \param to To vector (must to be normalized).
323
+ */
324
+ template<typename T>
325
+ [[nodiscard]] inline quat<T> quat_from_rotation_between_vectors(const vector<T, 3>& from, const vector<T, 3>& to)
326
+ {
327
+ T cos_theta = dot(from, to);
328
+ vector<T, 3> axis;
329
+
330
+ if (cos_theta >= T(1) - std::numeric_limits<T>::epsilon()) {
331
+ // from and to point in the same direction
332
+ return quat<T>::identity();
333
+ }
334
+
335
+ if (cos_theta < T(-1) + std::numeric_limits<T>::epsilon()) {
336
+ // special case when vectors in opposite directions :
337
+ // there is no "ideal" rotation axis
338
+ // So guess one; any will do as long as it's perpendicular to start
339
+ // This implementation favors a rotation around the Up axis (Y),
340
+ // since it's often what you want to do.
341
+ axis = cross(vector<T, 3>(0, 0, 1), from);
342
+ if (dot(axis, axis) < std::numeric_limits<T>::epsilon()) // bad luck, they were parallel, try again!
343
+ axis = cross(vector<T, 3>(1, 0, 0), from);
344
+
345
+ axis = normalize(axis);
346
+ return quat_from_angle_axis(T(M_PI), axis);
347
+ }
348
+
349
+ // Implementation from Stan Melax's Game Programming Gems 1 article
350
+ axis = cross(from, to);
351
+
352
+ T s = sqrt((T(1) + cos_theta) * T(2));
353
+ T invs = T(1) / s;
354
+
355
+ return quat<T>(axis.x * invs, axis.y * invs, axis.z * invs, s * T(0.5f));
356
+ }
357
+
358
+ /**
359
+ * Build a quaternion from euler angles (pitch, yaw, roll), in radians.
360
+ */
361
+ template<typename T>
362
+ [[nodiscard]] inline quat<T> quat_from_euler_angles(const vector<T, 3>& angles)
363
+ {
364
+ vector<T, 3> c = cos(angles * T(0.5));
365
+ vector<T, 3> s = sin(angles * T(0.5));
366
+
367
+ return quat<T>(
368
+ s.x * c.y * c.z - c.x * s.y * s.z, // x
369
+ c.x * s.y * c.z + s.x * c.y * s.z, // y
370
+ c.x * c.y * s.z - s.x * s.y * c.z, // z
371
+ c.x * c.y * c.z + s.x * s.y * s.z // w
372
+ );
373
+ }
374
+
375
+ /**
376
+ * Construct a quaternion from a 3x3 rotation matrix.
377
+ */
378
+ template<typename T>
379
+ [[nodiscard]] inline quat<T> quat_from_matrix(const matrix<T, 3, 3>& m)
380
+ {
381
+ T four_x_squared_minus_1 = m[0][0] - m[1][1] - m[2][2];
382
+ T four_y_squared_minus_1 = m[1][1] - m[0][0] - m[2][2];
383
+ T four_z_squared_minus_1 = m[2][2] - m[0][0] - m[1][1];
384
+ T four_w_squared_minus_1 = m[0][0] + m[1][1] + m[2][2];
385
+
386
+ int biggest_index = 0;
387
+ T four_biggest_squared_minus_1 = four_w_squared_minus_1;
388
+ if (four_x_squared_minus_1 > four_biggest_squared_minus_1) {
389
+ four_biggest_squared_minus_1 = four_x_squared_minus_1;
390
+ biggest_index = 1;
391
+ }
392
+ if (four_y_squared_minus_1 > four_biggest_squared_minus_1) {
393
+ four_biggest_squared_minus_1 = four_y_squared_minus_1;
394
+ biggest_index = 2;
395
+ }
396
+ if (four_z_squared_minus_1 > four_biggest_squared_minus_1) {
397
+ four_biggest_squared_minus_1 = four_z_squared_minus_1;
398
+ biggest_index = 3;
399
+ }
400
+
401
+ T biggest_val = sqrt(four_biggest_squared_minus_1 + T(1)) * T(0.5);
402
+ T mult = T(0.25) / biggest_val;
403
+
404
+ switch (biggest_index) {
405
+ case 0:
406
+ return quat<T>((m[2][1] - m[1][2]) * mult, (m[0][2] - m[2][0]) * mult, (m[1][0] - m[0][1]) * mult, biggest_val);
407
+ case 1:
408
+ return quat<T>(biggest_val, (m[1][0] + m[0][1]) * mult, (m[0][2] + m[2][0]) * mult, (m[2][1] - m[1][2]) * mult);
409
+ case 2:
410
+ return quat<T>((m[1][0] + m[0][1]) * mult, biggest_val, (m[2][1] + m[1][2]) * mult, (m[0][2] - m[2][0]) * mult);
411
+ case 3:
412
+ return quat<T>((m[0][2] + m[2][0]) * mult, (m[2][1] + m[1][2]) * mult, biggest_val, (m[1][0] - m[0][1]) * mult);
413
+ default:
414
+ SGL_UNREACHABLE();
415
+ }
416
+ }
417
+
418
+ /**
419
+ * Build a look-at quaternion.
420
+ * If right handed, forward direction is mapped onto -Z axis.
421
+ * If left handed, forward direction is mapped onto +Z axis.
422
+ * \param dir Forward direction (must to be normalized).
423
+ * \param up Up vector (must be normalized).
424
+ * \param handedness Coordinate system handedness.
425
+ */
426
+ template<typename T>
427
+ [[nodiscard]] inline quat<T>
428
+ quat_from_look_at(const vector<T, 3>& dir, const vector<T, 3>& up, Handedness handedness = Handedness::right_handed)
429
+ {
430
+ matrix<T, 3, 3> m;
431
+ m.set_col(2, handedness == Handedness::right_handed ? -dir : dir);
432
+ vector<T, 3> right = normalize(cross(up, m.get_col(2)));
433
+ m.set_col(0, right);
434
+ m.set_col(1, cross(m.get_col(2), m.get_col(0)));
435
+
436
+ return quat_from_matrix(m);
437
+ }
438
+
439
+ template<typename T>
440
+ [[nodiscard]] std::string to_string(const quat<T>& q)
441
+ {
442
+ return ::fmt::format("{}", q);
443
+ }
444
+
445
+ } // namespace sgl::math
446
+
447
+ template<typename T>
448
+ struct std::equal_to<::sgl::math::quat<T>> {
449
+ constexpr bool operator()(const ::sgl::math::quat<T>& lhs, const ::sgl::math::quat<T>& rhs) const
450
+ {
451
+ return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w;
452
+ }
453
+ };
454
+
455
+ template<typename T>
456
+ struct std::not_equal_to<::sgl::math::quat<T>> {
457
+ constexpr bool operator()(const ::sgl::math::quat<T>& lhs, const ::sgl::math::quat<T>& rhs) const
458
+ {
459
+ return lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != rhs.z || lhs.w != rhs.w;
460
+ }
461
+ };
462
+
463
+ template<typename T>
464
+ struct std::hash<::sgl::math::quat<T>> {
465
+ constexpr size_t operator()(const ::sgl::math::quat<T>& v) const
466
+ {
467
+ size_t result = 0;
468
+ for (size_t i = 0; i < 4; ++i)
469
+ result ^= std::hash<T>()(v[i]) + 0x9e3779b9 + (result << 6) + (result >> 2);
470
+ return result;
471
+ }
472
+ };
473
+
474
+ /// Quaternion string formatter.
475
+ template<typename T>
476
+ struct fmt::formatter<sgl::math::quat<T>> : formatter<T> {
477
+ template<typename FormatContext>
478
+ auto format(const sgl::math::quat<T>& v, FormatContext& ctx) const
479
+ {
480
+ auto out = ctx.out();
481
+ out = fmt::format_to(out, "{{{}, {}, {}, {}}}", v.x, v.y, v.z, v.w);
482
+ return out;
483
+ }
484
+ };
@@ -0,0 +1,83 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+
3
+ #pragma once
4
+
5
+ #include "sgl/math/scalar_types.h"
6
+ #include "sgl/math/vector_types.h"
7
+
8
+ #include <array>
9
+ #include <type_traits>
10
+
11
+ namespace sgl::math {
12
+
13
+ /**
14
+ * Quaternion type.
15
+ *
16
+ * A quaternion is an expression of the form:
17
+ *
18
+ * q = w + xi + yj + zk
19
+ *
20
+ * where w, x, y, and z are real numbers and i, j, and k are the imaginary units.
21
+ *
22
+ * The quaternion is normalized if:
23
+ * w^2 + x^2 + y^2 + z^2 = 1
24
+ *
25
+ * Quaternions are stored as (x, y, z, w) to make them better for interop with the GPU.
26
+ */
27
+ template<typename T>
28
+ struct quat {
29
+ using value_type = T;
30
+ static_assert(std::disjunction_v<std::is_same<T, float>, std::is_same<T, double>>, "Invalid quaternion type");
31
+
32
+ T x, y, z, w;
33
+
34
+ constexpr quat() noexcept
35
+ : x{T(0)}
36
+ , y{T(0)}
37
+ , z{T(0)}
38
+ , w{T(1)}
39
+ {
40
+ }
41
+
42
+ explicit constexpr quat(const vector<T, 3>& xyz, const T& w) noexcept
43
+ : x{xyz.x}
44
+ , y{xyz.y}
45
+ , z{xyz.z}
46
+ , w{w}
47
+ {
48
+ }
49
+
50
+ explicit constexpr quat(const T& x, const T& y, const T& z, const T& w) noexcept
51
+ : x{x}
52
+ , y{y}
53
+ , z{z}
54
+ , w{w}
55
+ {
56
+ }
57
+
58
+ template<typename U>
59
+ explicit constexpr quat(const std::array<U, 4>& a) noexcept
60
+ : x{T(a[0])}
61
+ , y{T(a[1])}
62
+ , z{T(a[2])}
63
+ , w{T(a[3])}
64
+ {
65
+ }
66
+
67
+ /// Identity quaternion.
68
+ [[nodiscard]] static quat identity() { return quat(T(0), T(0), T(0), T(1)); }
69
+
70
+ // Accesses
71
+ value_type& operator[](size_t i) { return (&x)[i]; }
72
+ const value_type& operator[](size_t i) const { return (&x)[i]; }
73
+ };
74
+
75
+ using quatf = quat<float>;
76
+
77
+ } // namespace sgl::math
78
+
79
+ namespace sgl {
80
+
81
+ using quatf = math::quatf;
82
+
83
+ } // namespace sgl
@@ -0,0 +1,47 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+
3
+ #pragma once
4
+
5
+ #include "sgl/math/vector.h"
6
+
7
+ #include <limits>
8
+
9
+ namespace sgl {
10
+
11
+ /**
12
+ * Ray type.
13
+ * This should match the layout of DXR RayDesc.
14
+ */
15
+ struct Ray {
16
+ float3 origin;
17
+ float t_min;
18
+ float3 dir;
19
+ float t_max;
20
+
21
+ /// Default constructor (uninitialized).
22
+ Ray() = default;
23
+
24
+ /// Constructor.
25
+ explicit Ray(float3 origin_, float3 dir_, float t_min_ = 0.f, float t_max_ = std::numeric_limits<float>::max())
26
+ : origin(origin_)
27
+ , t_min(t_min_)
28
+ , dir(dir_)
29
+ , t_max(t_max_)
30
+ {
31
+ }
32
+
33
+ /// Evaluate position on the ray at t.
34
+ [[nodiscard]] float3 eval(float t) const { return origin + t * dir; }
35
+
36
+ /// Evaluate position on the ray at t.
37
+ [[nodiscard]] float3 operator()(float t) const { return eval(t); }
38
+ };
39
+
40
+ // These are to ensure that the struct Ray match DXR RayDesc.
41
+ static_assert(offsetof(Ray, origin) == 0);
42
+ static_assert(offsetof(Ray, t_min) == sizeof(float3));
43
+ static_assert(offsetof(Ray, dir) == offsetof(Ray, t_min) + sizeof(float));
44
+ static_assert(offsetof(Ray, t_max) == offsetof(Ray, dir) + sizeof(float3));
45
+ static_assert(sizeof(Ray) == 32);
46
+
47
+ } // namespace sgl