RavEngine
Loading...
Searching...
No Matches
NvFlowMath.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2014-2022 NVIDIA Corporation. All rights reserved.
26
27#pragma once
28
29#include "NvFlowTypes.h"
30
31#include <math.h>
32
33namespace NvFlowMath
34{
35 static const float pi = 3.141592654f;
36
37 NV_FLOW_INLINE NvFlowFloat4 operator+(const NvFlowFloat4& lhs, const NvFlowFloat4& rhs)
38 {
39 NvFlowFloat4 ret;
40 ret.x = lhs.x + rhs.x;
41 ret.y = lhs.y + rhs.y;
42 ret.z = lhs.z + rhs.z;
43 ret.w = lhs.w + rhs.w;
44 return ret;
45 }
46
47 NV_FLOW_INLINE NvFlowFloat4 operator-(const NvFlowFloat4& lhs, const NvFlowFloat4& rhs)
48 {
49 NvFlowFloat4 ret;
50 ret.x = lhs.x - rhs.x;
51 ret.y = lhs.y - rhs.y;
52 ret.z = lhs.z - rhs.z;
53 ret.w = lhs.w - rhs.w;
54 return ret;
55 }
56
57 NV_FLOW_INLINE NvFlowFloat4 operator*(const NvFlowFloat4& lhs, const NvFlowFloat4& rhs)
58 {
59 NvFlowFloat4 ret;
60 ret.x = lhs.x * rhs.x;
61 ret.y = lhs.y * rhs.y;
62 ret.z = lhs.z * rhs.z;
63 ret.w = lhs.w * rhs.w;
64 return ret;
65 }
66
67 NV_FLOW_INLINE NvFlowFloat4 operator/(const NvFlowFloat4& lhs, const NvFlowFloat4& rhs)
68 {
69 NvFlowFloat4 ret;
70 ret.x = lhs.x / rhs.x;
71 ret.y = lhs.y / rhs.y;
72 ret.z = lhs.z / rhs.z;
73 ret.w = lhs.w / rhs.w;
74 return ret;
75 }
76
77 NV_FLOW_INLINE NvFlowFloat4 operator*(float v, const NvFlowFloat4& rhs)
78 {
79 NvFlowFloat4 ret;
80 ret.x = v * rhs.x;
81 ret.y = v * rhs.y;
82 ret.z = v * rhs.z;
83 ret.w = v * rhs.w;
84 return ret;
85 }
86
87 NV_FLOW_INLINE NvFlowFloat4 operator*(const NvFlowFloat4& lhs, float v)
88 {
89 NvFlowFloat4 ret;
90 ret.x = lhs.x * v;
91 ret.y = lhs.y * v;
92 ret.z = lhs.z * v;
93 ret.w = lhs.w * v;
94 return ret;
95 }
96
97 NV_FLOW_INLINE NvFlowFloat4 vectorSplatX(const NvFlowFloat4& a)
98 {
99 return NvFlowFloat4{ a.x, a.x, a.x, a.x };
100 }
101
102 NV_FLOW_INLINE NvFlowFloat4 vectorSplatY(const NvFlowFloat4& a)
103 {
104 return NvFlowFloat4{ a.y, a.y, a.y, a.y };
105 }
106
107 NV_FLOW_INLINE NvFlowFloat4 vectorSplatZ(const NvFlowFloat4& a)
108 {
109 return NvFlowFloat4{ a.z, a.z, a.z, a.z };
110 }
111
112 NV_FLOW_INLINE NvFlowFloat4 vectorSplatW(const NvFlowFloat4& a)
113 {
114 return NvFlowFloat4{ a.w, a.w, a.w, a.w };
115 }
116
117 NV_FLOW_INLINE NvFlowFloat4 vector3Normalize(const NvFlowFloat4& v)
118 {
119 float magn = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);
120
121 if (magn > 0.f)
122 {
123 magn = 1.f / magn;
124 }
125
126 return NvFlowFloat4{ v.x * magn, v.y * magn, v.z * magn, v.w * magn };
127 }
128
129 NV_FLOW_INLINE NvFlowFloat4 vectorPerspectiveDivide(const NvFlowFloat4& v)
130 {
131 return v / vectorSplatW(v);
132 }
133
134 NV_FLOW_INLINE NvFlowFloat4 matrixMultiplyRow(const NvFlowFloat4x4& b, const NvFlowFloat4& r)
135 {
136 NvFlowFloat4 result;
137 result.x = b.x.x * r.x + b.y.x * r.y + b.z.x * r.z + b.w.x * r.w;
138 result.y = b.x.y * r.x + b.y.y * r.y + b.z.y * r.z + b.w.y * r.w;
139 result.z = b.x.z * r.x + b.y.z * r.y + b.z.z * r.z + b.w.z * r.w;
140 result.w = b.x.w * r.x + b.y.w * r.y + b.z.w * r.z + b.w.w * r.w;
141 return result;
142 }
143
144 NV_FLOW_INLINE NvFlowFloat4x4 matrixMultiply(const NvFlowFloat4x4& a, const NvFlowFloat4x4& b)
145 {
146 NvFlowFloat4x4 result;
147 result.x = matrixMultiplyRow(b, a.x);
148 result.y = matrixMultiplyRow(b, a.y);
149 result.z = matrixMultiplyRow(b, a.z);
150 result.w = matrixMultiplyRow(b, a.w);
151 return result;
152 }
153
154 NV_FLOW_INLINE NvFlowFloat4 matrixTransposeRow(const NvFlowFloat4x4& a, unsigned int offset)
155 {
156 NvFlowFloat4 result;
157 result.x = *((&a.x.x) + offset);
158 result.y = *((&a.y.x) + offset);
159 result.z = *((&a.z.x) + offset);
160 result.w = *((&a.w.x) + offset);
161 return result;
162 }
163
164 NV_FLOW_INLINE NvFlowFloat4x4 matrixTranspose(const NvFlowFloat4x4& a)
165 {
166 NvFlowFloat4x4 result;
167 result.x = matrixTransposeRow(a, 0u);
168 result.y = matrixTransposeRow(a, 1u);
169 result.z = matrixTransposeRow(a, 2u);
170 result.w = matrixTransposeRow(a, 3u);
171 return result;
172 }
173
174 NV_FLOW_INLINE NvFlowFloat4x4 matrixInverse(const NvFlowFloat4x4& a)
175 {
176 const NvFlowFloat4x4& m = a;
177
178 float f = (float(1.0) /
179 (m.x.x * m.y.y * m.z.z * m.w.w +
180 m.x.x * m.y.z * m.z.w * m.w.y +
181 m.x.x * m.y.w * m.z.y * m.w.z +
182 m.x.y * m.y.x * m.z.w * m.w.z +
183 m.x.y * m.y.z * m.z.x * m.w.w +
184 m.x.y * m.y.w * m.z.z * m.w.x +
185 m.x.z * m.y.x * m.z.y * m.w.w +
186 m.x.z * m.y.y * m.z.w * m.w.x +
187 m.x.z * m.y.w * m.z.x * m.w.y +
188 m.x.w * m.y.x * m.z.z * m.w.y +
189 m.x.w * m.y.y * m.z.x * m.w.z +
190 m.x.w * m.y.z * m.z.y * m.w.x +
191 -m.x.x * m.y.y * m.z.w * m.w.z +
192 -m.x.x * m.y.z * m.z.y * m.w.w +
193 -m.x.x * m.y.w * m.z.z * m.w.y +
194 -m.x.y * m.y.x * m.z.z * m.w.w +
195 -m.x.y * m.y.z * m.z.w * m.w.x +
196 -m.x.y * m.y.w * m.z.x * m.w.z +
197 -m.x.z * m.y.x * m.z.w * m.w.y +
198 -m.x.z * m.y.y * m.z.x * m.w.w +
199 -m.x.z * m.y.w * m.z.y * m.w.x +
200 -m.x.w * m.y.x * m.z.y * m.w.z +
201 -m.x.w * m.y.y * m.z.z * m.w.x +
202 -m.x.w * m.y.z * m.z.x * m.w.y));
203
204 float a00 = (m.y.y * m.z.z * m.w.w +
205 m.y.z * m.z.w * m.w.y +
206 m.y.w * m.z.y * m.w.z +
207 -m.y.y * m.z.w * m.w.z +
208 -m.y.z * m.z.y * m.w.w +
209 -m.y.w * m.z.z * m.w.y);
210
211 float a10 = (m.x.y * m.z.w * m.w.z +
212 m.x.z * m.z.y * m.w.w +
213 m.x.w * m.z.z * m.w.y +
214 -m.x.y * m.z.z * m.w.w +
215 -m.x.z * m.z.w * m.w.y +
216 -m.x.w * m.z.y * m.w.z);
217
218 float a20 = (m.x.y * m.y.z * m.w.w +
219 m.x.z * m.y.w * m.w.y +
220 m.x.w * m.y.y * m.w.z +
221 -m.x.y * m.y.w * m.w.z +
222 -m.x.z * m.y.y * m.w.w +
223 -m.x.w * m.y.z * m.w.y);
224
225 float a30 = (m.x.y * m.y.w * m.z.z +
226 m.x.z * m.y.y * m.z.w +
227 m.x.w * m.y.z * m.z.y +
228 -m.x.y * m.y.z * m.z.w +
229 -m.x.z * m.y.w * m.z.y +
230 -m.x.w * m.y.y * m.z.z);
231
232 float a01 = (m.y.x * m.z.w * m.w.z +
233 m.y.z * m.z.x * m.w.w +
234 m.y.w * m.z.z * m.w.x +
235 -m.y.x * m.z.z * m.w.w +
236 -m.y.z * m.z.w * m.w.x +
237 -m.y.w * m.z.x * m.w.z);
238
239 float a11 = (m.x.x * m.z.z * m.w.w +
240 m.x.z * m.z.w * m.w.x +
241 m.x.w * m.z.x * m.w.z +
242 -m.x.x * m.z.w * m.w.z +
243 -m.x.z * m.z.x * m.w.w +
244 -m.x.w * m.z.z * m.w.x);
245
246 float a21 = (m.x.x * m.y.w * m.w.z +
247 m.x.z * m.y.x * m.w.w +
248 m.x.w * m.y.z * m.w.x +
249 -m.x.x * m.y.z * m.w.w +
250 -m.x.z * m.y.w * m.w.x +
251 -m.x.w * m.y.x * m.w.z);
252
253 float a31 = (m.x.x * m.y.z * m.z.w +
254 m.x.z * m.y.w * m.z.x +
255 m.x.w * m.y.x * m.z.z +
256 -m.x.x * m.y.w * m.z.z +
257 -m.x.z * m.y.x * m.z.w +
258 -m.x.w * m.y.z * m.z.x);
259
260 float a02 = (m.y.x * m.z.y * m.w.w +
261 m.y.y * m.z.w * m.w.x +
262 m.y.w * m.z.x * m.w.y +
263 -m.y.x * m.z.w * m.w.y +
264 -m.y.y * m.z.x * m.w.w +
265 -m.y.w * m.z.y * m.w.x);
266
267 float a12 = (-m.x.x * m.z.y * m.w.w +
268 -m.x.y * m.z.w * m.w.x +
269 -m.x.w * m.z.x * m.w.y +
270 m.x.x * m.z.w * m.w.y +
271 m.x.y * m.z.x * m.w.w +
272 m.x.w * m.z.y * m.w.x);
273
274 float a22 = (m.x.x * m.y.y * m.w.w +
275 m.x.y * m.y.w * m.w.x +
276 m.x.w * m.y.x * m.w.y +
277 -m.x.x * m.y.w * m.w.y +
278 -m.x.y * m.y.x * m.w.w +
279 -m.x.w * m.y.y * m.w.x);
280
281 float a32 = (m.x.x * m.y.w * m.z.y +
282 m.x.y * m.y.x * m.z.w +
283 m.x.w * m.y.y * m.z.x +
284 -m.x.y * m.y.w * m.z.x +
285 -m.x.w * m.y.x * m.z.y +
286 -m.x.x * m.y.y * m.z.w);
287
288 float a03 = (m.y.x * m.z.z * m.w.y +
289 m.y.y * m.z.x * m.w.z +
290 m.y.z * m.z.y * m.w.x +
291 -m.y.x * m.z.y * m.w.z +
292 -m.y.y * m.z.z * m.w.x +
293 -m.y.z * m.z.x * m.w.y);
294
295 float a13 = (m.x.x * m.z.y * m.w.z +
296 m.x.y * m.z.z * m.w.x +
297 m.x.z * m.z.x * m.w.y +
298 -m.x.x * m.z.z * m.w.y +
299 -m.x.y * m.z.x * m.w.z +
300 -m.x.z * m.z.y * m.w.x);
301
302 float a23 = (m.x.x * m.y.z * m.w.y +
303 m.x.y * m.y.x * m.w.z +
304 m.x.z * m.y.y * m.w.x +
305 -m.x.x * m.y.y * m.w.z +
306 -m.x.y * m.y.z * m.w.x +
307 -m.x.z * m.y.x * m.w.y);
308
309 float a33 = (m.x.x * m.y.y * m.z.z +
310 m.x.y * m.y.z * m.z.x +
311 m.x.z * m.y.x * m.z.y +
312 -m.x.x * m.y.z * m.z.y +
313 -m.x.y * m.y.x * m.z.z +
314 -m.x.z * m.y.y * m.z.x);
315
316 return NvFlowFloat4x4{
317 a00*f, a10*f, a20*f, a30*f,
318 a01*f, a11*f, a21*f, a31*f,
319 a02*f, a12*f, a22*f, a32*f,
320 a03*f, a13*f, a23*f, a33*f };
321 }
322
323 NV_FLOW_INLINE NvFlowFloat4x4 matrixIdentity()
324 {
325 return NvFlowFloat4x4{
326 { 1.f, 0.f, 0.f, 0.f },
327 { 0.f, 1.f, 0.f, 0.f },
328 { 0.f, 0.f, 1.f, 0.f },
329 { 0.f, 0.f, 0.f, 1.f }
330 };
331 }
332
333 NV_FLOW_INLINE NvFlowFloat4x4 matrixScaling(float x, float y, float z)
334 {
335 return NvFlowFloat4x4{
336 x, 0.f, 0.f, 0.f,
337 0.f, y, 0.f, 0.f,
338 0.f, 0.f, z, 0.f,
339 0.f, 0.f, 0.f, 1.f
340 };
341 }
342
343 NV_FLOW_INLINE NvFlowFloat4x4 matrixTranslation(float x, float y, float z)
344 {
345 return NvFlowFloat4x4{
346 1.f, 0.f, 0.f, 0.f,
347 0.f, 1.f, 0.f, 0.f,
348 0.f, 0.f, 1.f, 0.f,
349 x, y, z, 1.f
350 };
351 }
352
353 NV_FLOW_INLINE NvFlowFloat4x4 matrixPerspectiveFovRH(float fovAngleY, float aspectRatio, float nearZ, float farZ)
354 {
355 float sinfov = sinf(0.5f * fovAngleY);
356 float cosfov = cosf(0.5f * fovAngleY);
357
358 float height = cosfov / sinfov;
359 float width = height / aspectRatio;
360 float frange = farZ / (nearZ - farZ);
361
362 if (nearZ == INFINITY)
363 {
364 return NvFlowFloat4x4{
365 { width, 0.f, 0.f, 0.f },
366 { 0.f, height, 0.f, 0.f },
367 { 0.f, 0.f, frange, -1.f },
368 { 0.f, 0.f, farZ, 0.f }
369 };
370 }
371
372 return NvFlowFloat4x4{
373 { width, 0.f, 0.f, 0.f },
374 { 0.f, height, 0.f, 0.f },
375 { 0.f, 0.f, frange, -1.f },
376 { 0.f, 0.f, frange * nearZ, 0.f }
377 };
378 }
379
380 NV_FLOW_INLINE NvFlowFloat4x4 matrixPerspectiveFovLH(float fovAngleY, float aspectRatio, float nearZ, float farZ)
381 {
382 float sinfov = sinf(0.5f * fovAngleY);
383 float cosfov = cosf(0.5f * fovAngleY);
384
385 float height = cosfov / sinfov;
386 float width = height / aspectRatio;
387 float frange = farZ / (farZ - nearZ);
388
389 if (nearZ == INFINITY)
390 {
391 return NvFlowFloat4x4{
392 { width, 0.f, 0.f, 0.f },
393 { 0.f, height, 0.f, 0.f },
394 { 0.f, 0.f, frange, 1.f },
395 { 0.f, 0.f, farZ, 0.f }
396 };
397 }
398
399 return NvFlowFloat4x4{
400 { width, 0.f, 0.f, 0.f },
401 { 0.f, height, 0.f, 0.f },
402 { 0.f, 0.f, frange, 1.f },
403 { 0.f, 0.f, -frange * nearZ, 0.f }
404 };
405 }
406
407 NV_FLOW_INLINE NvFlowBool32 matrixPerspectiveIsRH(const NvFlowFloat4x4& m)
408 {
409 return m.z.w < 0.f ? NV_FLOW_TRUE : NV_FLOW_FALSE;
410 }
411
412 NV_FLOW_INLINE NvFlowBool32 matrixPerspectiveIsReverseZ(const NvFlowFloat4x4& m)
413 {
414 float nearZ = -m.w.z / m.z.z;
415 float farZ = (m.w.w - m.w.z) / (m.z.z - m.z.w);
416 float singZ = -m.w.w / m.z.w;
417 return fabsf(farZ - singZ) < fabs(nearZ - singZ) ? NV_FLOW_TRUE : NV_FLOW_FALSE;
418 }
419
420 NV_FLOW_INLINE NvFlowFloat4x4 matrixOrthographicLH(float width, float height, float nearZ, float farZ)
421 {
422 float frange = 1.f / (farZ - nearZ);
423
424 return NvFlowFloat4x4{
425 { 2.f / width, 0.f, 0.f, 0.f },
426 { 0.f, 2.f / height, 0.f, 0.f },
427 { 0.f, 0.f, frange, 0.f },
428 { 0.f, 0.f, -frange * nearZ, 1.f }
429 };
430 }
431
432 NV_FLOW_INLINE NvFlowFloat4x4 matrixOrthographicRH(float width, float height, float nearZ, float farZ)
433 {
434 float frange = 1.f / (nearZ - farZ);
435
436 return NvFlowFloat4x4{
437 { 2.f / width, 0.f, 0.f, 0.f },
438 { 0.f, 2.f / height, 0.f, 0.f },
439 { 0.f, 0.f, frange, 0.f },
440 { 0.f, 0.f, frange * nearZ, 1.f }
441 };
442 }
443
444 NV_FLOW_INLINE NvFlowFloat4x4 matrixRotationNormal(NvFlowFloat4 normal, float angle)
445 {
446 float sinAngle = sinf(angle);
447 float cosAngle = cosf(angle);
448
449 NvFlowFloat4 a = { sinAngle, cosAngle, 1.f - cosAngle, 0.f };
450
451 NvFlowFloat4 c2 = vectorSplatZ(a);
452 NvFlowFloat4 c1 = vectorSplatY(a);
453 NvFlowFloat4 c0 = vectorSplatX(a);
454
455 NvFlowFloat4 n0 = { normal.y, normal.z, normal.x, normal.w };
456 NvFlowFloat4 n1 = { normal.z, normal.x, normal.y, normal.w };
457
458 NvFlowFloat4 v0 = c2 * n0;
459 v0 = v0 * n1;
460
461 NvFlowFloat4 r0 = c2 * normal;
462 r0 = (r0 * normal) + c1;
463
464 NvFlowFloat4 r1 = (c0 * normal) + v0;
465 NvFlowFloat4 r2 = v0 - (c0 * normal);
466
467 v0 = NvFlowFloat4{ r0.x, r0.y, r0.z, a.w };
468 NvFlowFloat4 v1 = { r1.z, r2.y, r2.z, r1.x };
469 NvFlowFloat4 v2 = { r1.y, r2.x, r1.y, r2.x };
470
471 return NvFlowFloat4x4{
472 { v0.x, v1.x, v1.y, v0.w },
473 { v1.z, v0.y, v1.w, v0.w },
474 { v2.x, v2.y, v0.z, v0.w },
475 { 0.f, 0.f, 0.f, 1.f }
476 };
477 }
478
479 NV_FLOW_INLINE NvFlowFloat4x4 matrixRotationAxis(NvFlowFloat4 axis, float angle)
480 {
481 NvFlowFloat4 normal = vector3Normalize(axis);
482 return matrixRotationNormal(normal, angle);
483 }
484
485 NV_FLOW_INLINE NvFlowFloat4 quaterionRotationRollPitchYawFromVector(NvFlowFloat4 angles)
486 {
487 NvFlowFloat4 sign = { 1.f, -1.f, -1.f, 1.f };
488
489 NvFlowFloat4 halfAngles = angles * NvFlowFloat4{ 0.5f, 0.5f, 0.5f, 0.5f };
490
491 NvFlowFloat4 sinAngle = NvFlowFloat4{ sinf(halfAngles.x), sinf(halfAngles.y), sinf(halfAngles.z), sinf(halfAngles.w) };
492 NvFlowFloat4 cosAngle = NvFlowFloat4{ cosf(halfAngles.x), cosf(halfAngles.y), cosf(halfAngles.z), cosf(halfAngles.w) };
493
494 NvFlowFloat4 p0 = { sinAngle.x, cosAngle.x, cosAngle.x, cosAngle.x };
495 NvFlowFloat4 y0 = { cosAngle.y, sinAngle.y, cosAngle.y, cosAngle.y };
496 NvFlowFloat4 r0 = { cosAngle.z, cosAngle.z, sinAngle.z, cosAngle.z };
497 NvFlowFloat4 p1 = { cosAngle.x, sinAngle.x, sinAngle.x, sinAngle.x };
498 NvFlowFloat4 y1 = { sinAngle.y, cosAngle.y, sinAngle.y, sinAngle.y };
499 NvFlowFloat4 r1 = { sinAngle.z, sinAngle.z, cosAngle.z, sinAngle.z };
500
501 NvFlowFloat4 q1 = p1 * sign;
502 NvFlowFloat4 q0 = p0 * y0;
503 q1 = q1 * y1;
504 q0 = q0 * r0;
505 NvFlowFloat4 q = (q1 * r1) + q0;
506
507 return q;
508 }
509
510 NV_FLOW_INLINE NvFlowFloat4x4 matrixRotationQuaternion(NvFlowFloat4 quaternion)
511 {
512 NvFlowFloat4 constant1110 = { 1.f, 1.f, 1.f, 0.f };
513
514 NvFlowFloat4 q0 = quaternion + quaternion;
515 NvFlowFloat4 q1 = quaternion * q0;
516
517 NvFlowFloat4 v0 = { q1.y, q1.x, q1.x, constant1110.w };
518 NvFlowFloat4 v1 = { q1.z, q1.z, q1.y, constant1110.w };
519 NvFlowFloat4 r0 = constant1110 - v0;
520 r0 = r0 - v1;
521
522 v0 = NvFlowFloat4{ quaternion.x, quaternion.x, quaternion.y, quaternion.w };
523 v1 = NvFlowFloat4{ q0.z, q0.y, q0.z, q0.w };
524 v0 = v0 * v1;
525
526 v1 = vectorSplatW(quaternion);
527 NvFlowFloat4 v2 = { q0.y, q0.z, q0.x, q0.w };
528 v1 = v1 * v2;
529
530 NvFlowFloat4 r1 = v0 + v1;
531 NvFlowFloat4 r2 = v0 - v1;
532
533 v0 = NvFlowFloat4{ r1.y, r2.x, r2.y, r1.z };
534 v1 = NvFlowFloat4{ r1.x, r2.z, r1.x, r2.z };
535
536 return NvFlowFloat4x4{
537 { r0.x, v0.x, v0.y, r0.w },
538 { v0.z, r0.y, v0.w, r0.w },
539 { v1.x, v1.y, r0.z, r0.w },
540 { 0.f, 0.f, 0.f, 1.f }
541 };
542 }
543
544 NV_FLOW_INLINE NvFlowFloat4x4 matrixRotationRollPitchYaw(float pitch, float yaw, float roll)
545 {
546 NvFlowFloat4 angles = { pitch, yaw, roll, 0.f };
547 NvFlowFloat4 q = quaterionRotationRollPitchYawFromVector(angles);
548 return matrixRotationQuaternion(q);
549 }
550
551 NV_FLOW_INLINE NvFlowFloat4 vectorLerp(NvFlowFloat4 a, NvFlowFloat4 b, float t)
552 {
553 return NvFlowFloat4{
554 (1.f - t) * a.x + t * b.x,
555 (1.f - t) * a.y + t * b.y,
556 (1.f - t) * a.z + t * b.z,
557 (1.f - t) * a.w + t * b.w
558 };
559 }
560
561 NV_FLOW_INLINE NvFlowFloat4x4 matrixInterpolateTranslation(const NvFlowFloat4x4& a, const NvFlowFloat4x4& b, float t)
562 {
563 NvFlowFloat4x4 ret;
564 if (t < 0.5f)
565 {
566 ret = a;
567 }
568 else
569 {
570 ret = b;
571 }
572 ret.w.x = (1.f - t) * a.w.x + t * b.w.x;
573 ret.w.y = (1.f - t) * a.w.y + t * b.w.y;
574 ret.w.z = (1.f - t) * a.w.z + t * b.w.z;
575 return ret;
576 }
577
578 NV_FLOW_INLINE NvFlowFloat4 vector4Normalize(const NvFlowFloat4& v)
579 {
580 float magn = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
581
582 if (magn > 0.f)
583 {
584 magn = 1.f / magn;
585 }
586
587 return NvFlowFloat4{v.x * magn, v.y * magn, v.z * magn, v.w * magn};
588 }
589
590 NV_FLOW_INLINE NvFlowFloat4x4 matrixNormalize(const NvFlowFloat4x4& a)
591 {
592 NvFlowFloat4x4 temp = a;
593 temp.x.w = 0.f;
594 temp.y.w = 0.f;
595 temp.z.w = 0.f;
596 temp.w.w = 1.f;
597 temp.w.x = 0.f;
598 temp.w.y = 0.f;
599 temp.w.z = 0.f;
600 NvFlowFloat4x4 ret = temp;
601 ret.x = vector4Normalize(ret.x);
602 ret.y = vector4Normalize(ret.y);
603 ret.z = vector4Normalize(ret.z);
604 return ret;
605 }
606
607 NV_FLOW_INLINE NvFlowFloat4 vector4Transform(const NvFlowFloat4& x, const NvFlowFloat4x4& A)
608 {
609 return NvFlowFloat4{
610 A.x.x * x.x + A.y.x * x.y + A.z.x * x.z + A.w.x * x.w,
611 A.x.y * x.x + A.y.y * x.y + A.z.y * x.z + A.w.y * x.w,
612 A.x.z * x.x + A.y.z * x.y + A.z.z * x.z + A.w.z * x.w,
613 A.x.w * x.x + A.y.w * x.y + A.z.w * x.z + A.w.w * x.w
614 };
615 }
616
617 NV_FLOW_INLINE NvFlowFloat4 vectorMin(const NvFlowFloat4& a, const NvFlowFloat4& b)
618 {
619 return NvFlowFloat4{
620 a.x < b.x ? a.x : b.x,
621 a.y < b.y ? a.y : b.y,
622 a.z < b.z ? a.z : b.z,
623 a.w < b.w ? a.w : b.w
624 };
625 }
626
627 NV_FLOW_INLINE NvFlowFloat4 vectorMax(const NvFlowFloat4& a, const NvFlowFloat4& b)
628 {
629 return NvFlowFloat4{
630 a.x > b.x ? a.x : b.x,
631 a.y > b.y ? a.y : b.y,
632 a.z > b.z ? a.z : b.z,
633 a.w > b.w ? a.w : b.w
634 };
635 }
636
637 NV_FLOW_INLINE NvFlowFloat4 vectorMultiply(const NvFlowFloat4& a, const NvFlowFloat4& b)
638 {
639 return NvFlowFloat4{a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w};
640 }
641
642 NV_FLOW_INLINE NvFlowFloat4 vectorFloor(const NvFlowFloat4& a)
643 {
644 return NvFlowFloat4{ floorf(a.x), floorf(a.y), floorf(a.z), floorf(a.w) };
645 }
646
647 NV_FLOW_INLINE NvFlowFloat4 vectorCeiling(const NvFlowFloat4& a)
648 {
649 return NvFlowFloat4{ceilf(a.x), ceilf(a.y), ceilf(a.z), ceilf(a.w)};
650 }
651
652 NV_FLOW_INLINE NvFlowFloat4 vector3Dot(const NvFlowFloat4& a, const NvFlowFloat4& b)
653 {
654 float magn = a.x * b.x + a.y * b.y + a.z * b.z;
655
656 return NvFlowFloat4{ magn, magn, magn, magn };
657 }
658
659 NV_FLOW_INLINE NvFlowFloat4 vector4Dot(const NvFlowFloat4& a, const NvFlowFloat4& b)
660 {
661 float magn = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
662
663 return NvFlowFloat4{ magn, magn, magn, magn };
664 }
665
666 NV_FLOW_INLINE NvFlowFloat4 vector3Cross(const NvFlowFloat4& a, const NvFlowFloat4& b)
667 {
668 return NvFlowFloat4{
669 a.y * b.z - a.z * b.y,
670 a.z * b.x - a.x * b.z,
671 a.x * b.y - a.y * b.x,
672 0.f
673 };
674 }
675
676 NV_FLOW_INLINE NvFlowFloat4 vector3Length(const NvFlowFloat4& a)
677 {
678 float magn = sqrtf(a.x * a.x + a.y * a.y + a.z * a.z);
679
680 return NvFlowFloat4{ magn, magn, magn, magn };
681 }
682
683 NV_FLOW_INLINE NvFlowFloat4 make_float4(NvFlowFloat3 a, float b)
684 {
685 return NvFlowFloat4{ a.x, a.y, a.z, b };
686 }
687
688 NV_FLOW_INLINE NvFlowFloat3 float4_to_float3(NvFlowFloat4 a)
689 {
690 return NvFlowFloat3{ a.x, a.y, a.z };
691 }
692
693 NV_FLOW_INLINE NvFlowUint log2ui(NvFlowUint val)
694 {
695 NvFlowUint ret = 0;
696 for (NvFlowUint i = 0; i < 32; i++)
697 {
698 if ((1u << i) >= val)
699 {
700 ret = i;
701 break;
702 }
703 }
704 return ret;
705 }
706
707 NV_FLOW_INLINE NvFlowFloat4 computeRayOrigin(const NvFlowFloat4x4& viewInv, const NvFlowFloat4x4& projectionInv, NvFlowFloat2 ndc, float nearZ)
708 {
709 NvFlowFloat4 viewPos = vector4Transform(NvFlowFloat4{ ndc.x, ndc.y, nearZ, 1.f }, projectionInv);
710 return vectorPerspectiveDivide(vector4Transform(viewPos, viewInv));
711 }
712
713 NV_FLOW_INLINE NvFlowFloat4 computeRayDir(const NvFlowFloat4x4& viewInv, const NvFlowFloat4x4& projectionInv, NvFlowFloat2 ndc, float nearZ)
714 {
715 NvFlowFloat4x4 projectionInvT = matrixTranspose(projectionInv);
716 NvFlowFloat4 ndc_ext = NvFlowFloat4{ ndc.x, ndc.y, 0.f, 1.f };
717 NvFlowFloat4 dir = {
718 -projectionInvT.w.z * vector4Dot(projectionInvT.x, ndc_ext).x,
719 -projectionInvT.w.z * vector4Dot(projectionInvT.y, ndc_ext).x,
720 -projectionInvT.w.z * vector4Dot(projectionInvT.z, ndc_ext).x +
721 projectionInvT.z.z * vector4Dot(projectionInvT.w, ndc_ext).x,
722 0.f
723 };
724 if (nearZ > 0.5f)
725 {
726 dir = NvFlowFloat4{ 0.f, 0.f, 0.f, 0.f } - dir;
727 }
728 return vector4Transform(dir, viewInv);
729 }
730
732 {
733 NvFlowFloat4 rayOrigin00;
734 NvFlowFloat4 rayOrigin10;
735 NvFlowFloat4 rayOrigin01;
736 NvFlowFloat4 rayOrigin11;
737 NvFlowFloat4 rayDir00;
738 NvFlowFloat4 rayDir10;
739 NvFlowFloat4 rayDir01;
740 NvFlowFloat4 rayDir11;
741 float nearZ;
742 NvFlowBool32 isReverseZ;
743 };
744
745 NV_FLOW_INLINE void computeFrustumRays(FrustumRays* ptr, const NvFlowFloat4x4& viewInv, const NvFlowFloat4x4& projectionInv)
746 {
747 NvFlowFloat4 nearPoint = vector4Transform(NvFlowFloat4{ 0.f, 0.f, 0.f, 1.f }, projectionInv);
748 NvFlowFloat4 farPoint = vector4Transform(NvFlowFloat4{ 0.f, 0.f, 1.f, 1.f }, projectionInv);
749
750 nearPoint = nearPoint / vectorSplatW(nearPoint);
751 farPoint = farPoint / vectorSplatW(farPoint);
752
753 float nearZ = fabsf(nearPoint.z) < fabsf(farPoint.z) ? 0.f : 1.f;
754
755 ptr->rayOrigin00 = computeRayOrigin(viewInv, projectionInv, NvFlowFloat2{ -1.f, +1.f }, nearZ);
756 ptr->rayOrigin10 = computeRayOrigin(viewInv, projectionInv, NvFlowFloat2{ +1.f, +1.f }, nearZ);
757 ptr->rayOrigin01 = computeRayOrigin(viewInv, projectionInv, NvFlowFloat2{ -1.f, -1.f }, nearZ);
758 ptr->rayOrigin11 = computeRayOrigin(viewInv, projectionInv, NvFlowFloat2{ +1.f, -1.f }, nearZ);
759
760 ptr->rayDir00 = computeRayDir(viewInv, projectionInv, NvFlowFloat2{ -1.f, +1.f }, nearZ);
761 ptr->rayDir10 = computeRayDir(viewInv, projectionInv, NvFlowFloat2{ +1.f, +1.f }, nearZ);
762 ptr->rayDir01 = computeRayDir(viewInv, projectionInv, NvFlowFloat2{ -1.f, -1.f }, nearZ);
763 ptr->rayDir11 = computeRayDir(viewInv, projectionInv, NvFlowFloat2{ +1.f, -1.f }, nearZ);
764
765 ptr->nearZ = nearZ;
766 ptr->isReverseZ = fabsf(nearPoint.z) >= fabsf(farPoint.z);
767 }
768}
GLM_FUNC_DECL T roll(qua< T, Q > const &x)
Definition quaternion.inl:16
GLM_FUNC_DECL T pitch(qua< T, Q > const &x)
Definition quaternion.inl:22
GLM_FUNC_DECL T yaw(qua< T, Q > const &x)
Definition quaternion.inl:35
Definition NvFlowMath.h:732
Definition type_quat.hpp:20