nv-sgl 0.6.0__cp313-cp313-win_amd64.whl
Sign up to get free protection for your applications and to get access to all the features.
- include/tevclient.h +393 -0
- nv_sgl-0.6.0.dist-info/LICENSE +29 -0
- nv_sgl-0.6.0.dist-info/METADATA +21 -0
- nv_sgl-0.6.0.dist-info/RECORD +142 -0
- nv_sgl-0.6.0.dist-info/WHEEL +5 -0
- nv_sgl-0.6.0.dist-info/top_level.txt +1 -0
- sgl/__init__.py +15 -0
- sgl/__init__.pyi +6738 -0
- sgl/d3d12/D3D12Core.dll +0 -0
- sgl/d3d12/d3d12SDKLayers.dll +0 -0
- sgl/dxcompiler.dll +0 -0
- sgl/dxil.dll +0 -0
- sgl/gfx.dll +0 -0
- sgl/include/sgl/app/app.h +113 -0
- sgl/include/sgl/core/bitmap.h +302 -0
- sgl/include/sgl/core/crypto.h +89 -0
- sgl/include/sgl/core/data_type.h +46 -0
- sgl/include/sgl/core/dds_file.h +103 -0
- sgl/include/sgl/core/enum.h +201 -0
- sgl/include/sgl/core/error.h +161 -0
- sgl/include/sgl/core/file_stream.h +77 -0
- sgl/include/sgl/core/file_system_watcher.h +141 -0
- sgl/include/sgl/core/format.h +36 -0
- sgl/include/sgl/core/fwd.h +90 -0
- sgl/include/sgl/core/hash.h +45 -0
- sgl/include/sgl/core/input.h +522 -0
- sgl/include/sgl/core/logger.h +214 -0
- sgl/include/sgl/core/macros.h +184 -0
- sgl/include/sgl/core/maths.h +45 -0
- sgl/include/sgl/core/memory_mapped_file.h +112 -0
- sgl/include/sgl/core/memory_mapped_file_stream.h +32 -0
- sgl/include/sgl/core/memory_stream.h +74 -0
- sgl/include/sgl/core/object.h +683 -0
- sgl/include/sgl/core/platform.h +239 -0
- sgl/include/sgl/core/plugin.h +331 -0
- sgl/include/sgl/core/resolver.h +39 -0
- sgl/include/sgl/core/short_vector.h +141 -0
- sgl/include/sgl/core/static_vector.h +111 -0
- sgl/include/sgl/core/stream.h +54 -0
- sgl/include/sgl/core/string.h +276 -0
- sgl/include/sgl/core/struct.h +360 -0
- sgl/include/sgl/core/thread.h +28 -0
- sgl/include/sgl/core/timer.h +52 -0
- sgl/include/sgl/core/traits.h +15 -0
- sgl/include/sgl/core/type_utils.h +19 -0
- sgl/include/sgl/core/window.h +177 -0
- sgl/include/sgl/device/agility_sdk.h +24 -0
- sgl/include/sgl/device/blit.h +88 -0
- sgl/include/sgl/device/buffer_cursor.h +162 -0
- sgl/include/sgl/device/command.h +539 -0
- sgl/include/sgl/device/cuda_api.h +766 -0
- sgl/include/sgl/device/cuda_interop.h +39 -0
- sgl/include/sgl/device/cuda_utils.h +107 -0
- sgl/include/sgl/device/cursor_utils.h +129 -0
- sgl/include/sgl/device/device.h +668 -0
- sgl/include/sgl/device/device_resource.h +37 -0
- sgl/include/sgl/device/fence.h +91 -0
- sgl/include/sgl/device/formats.h +330 -0
- sgl/include/sgl/device/framebuffer.h +85 -0
- sgl/include/sgl/device/fwd.h +164 -0
- sgl/include/sgl/device/helpers.h +20 -0
- sgl/include/sgl/device/hot_reload.h +75 -0
- sgl/include/sgl/device/input_layout.h +74 -0
- sgl/include/sgl/device/kernel.h +69 -0
- sgl/include/sgl/device/memory_heap.h +155 -0
- sgl/include/sgl/device/native_formats.h +342 -0
- sgl/include/sgl/device/native_handle.h +73 -0
- sgl/include/sgl/device/native_handle_traits.h +65 -0
- sgl/include/sgl/device/pipeline.h +138 -0
- sgl/include/sgl/device/print.h +45 -0
- sgl/include/sgl/device/python/cursor_utils.h +853 -0
- sgl/include/sgl/device/query.h +52 -0
- sgl/include/sgl/device/raytracing.h +84 -0
- sgl/include/sgl/device/reflection.h +1254 -0
- sgl/include/sgl/device/resource.h +705 -0
- sgl/include/sgl/device/sampler.h +57 -0
- sgl/include/sgl/device/shader.h +516 -0
- sgl/include/sgl/device/shader_cursor.h +85 -0
- sgl/include/sgl/device/shader_object.h +94 -0
- sgl/include/sgl/device/shader_offset.h +67 -0
- sgl/include/sgl/device/shared_handle.h +12 -0
- sgl/include/sgl/device/slang_utils.h +54 -0
- sgl/include/sgl/device/swapchain.h +74 -0
- sgl/include/sgl/device/types.h +782 -0
- sgl/include/sgl/math/colorspace.h +56 -0
- sgl/include/sgl/math/constants.h +7 -0
- sgl/include/sgl/math/float16.h +146 -0
- sgl/include/sgl/math/matrix.h +6 -0
- sgl/include/sgl/math/matrix_math.h +746 -0
- sgl/include/sgl/math/matrix_types.h +207 -0
- sgl/include/sgl/math/python/primitivetype.h +33 -0
- sgl/include/sgl/math/quaternion.h +6 -0
- sgl/include/sgl/math/quaternion_math.h +484 -0
- sgl/include/sgl/math/quaternion_types.h +83 -0
- sgl/include/sgl/math/ray.h +47 -0
- sgl/include/sgl/math/scalar_math.h +249 -0
- sgl/include/sgl/math/scalar_types.h +107 -0
- sgl/include/sgl/math/vector.h +6 -0
- sgl/include/sgl/math/vector_math.h +1796 -0
- sgl/include/sgl/math/vector_types.h +336 -0
- sgl/include/sgl/python/nanobind.h +489 -0
- sgl/include/sgl/python/py_doc.h +11600 -0
- sgl/include/sgl/python/sgl_ext_pch.h +8 -0
- sgl/include/sgl/sgl.h +21 -0
- sgl/include/sgl/sgl_pch.h +6 -0
- sgl/include/sgl/stl/bit.h +377 -0
- sgl/include/sgl/tests/testing.h +54 -0
- sgl/include/sgl/ui/fwd.h +34 -0
- sgl/include/sgl/ui/imgui_config.h +43 -0
- sgl/include/sgl/ui/ui.h +71 -0
- sgl/include/sgl/ui/widgets.h +918 -0
- sgl/include/sgl/utils/python/slangpy.h +366 -0
- sgl/include/sgl/utils/renderdoc.h +50 -0
- sgl/include/sgl/utils/slangpy.h +153 -0
- sgl/include/sgl/utils/tev.h +93 -0
- sgl/include/sgl/utils/texture_loader.h +106 -0
- sgl/math/__init__.pyi +5083 -0
- sgl/platform/__init__.pyi +102 -0
- sgl/renderdoc/__init__.pyi +51 -0
- sgl/sgl.dll +0 -0
- sgl/sgl_ext.cp313-win_amd64.pyd +0 -0
- sgl/shaders/nvapi/nvHLSLExtns.h +2315 -0
- sgl/shaders/nvapi/nvHLSLExtnsInternal.h +758 -0
- sgl/shaders/nvapi/nvShaderExtnEnums.h +142 -0
- sgl/shaders/sgl/device/blit.slang +93 -0
- sgl/shaders/sgl/device/nvapi.slang +5 -0
- sgl/shaders/sgl/device/nvapi.slangh +7 -0
- sgl/shaders/sgl/device/print.slang +445 -0
- sgl/shaders/sgl/math/constants.slang +4 -0
- sgl/shaders/sgl/math/ray.slang +29 -0
- sgl/shaders/sgl/ui/imgui.slang +49 -0
- sgl/slang-glslang.dll +0 -0
- sgl/slang-llvm.dll +0 -0
- sgl/slang-rt.dll +0 -0
- sgl/slang.dll +0 -0
- sgl/slangpy/__init__.pyi +268 -0
- sgl/tev/__init__.pyi +108 -0
- sgl/tevclient.lib +0 -0
- sgl/thread/__init__.pyi +4 -0
- sgl/ui/__init__.pyi +1118 -0
- share/cmake/tevclient/tevclient-config-release.cmake +19 -0
- share/cmake/tevclient/tevclient-config.cmake +108 -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
|