OpenVDB 13.1.0
Loading...
Searching...
No Matches
Math.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3
4/*!
5 \file Math.h
6
7 \author Ken Museth
8
9 \date January 8, 2020
10
11 \brief Math functions and classes
12
13*/
14
15#ifndef NANOVDB_MATH_MATH_H_HAS_BEEN_INCLUDED
16#define NANOVDB_MATH_MATH_H_HAS_BEEN_INCLUDED
17
18#include <nanovdb/util/Util.h>// for __hostdev__ and lots of other utility functions
19
20#if defined(__CUDA_ARCH__)
21#include <cuda/std/limits>// for ::cuda::std::numeric_limits
22#endif
23
24namespace nanovdb {// =================================================================
25
26namespace math {// =============================================================
27
28// ----------------------------> Various math functions <-------------------------------------
29
30//@{
31/// @brief Pi constant taken from Boost to match old behaviour
32template<typename T>
33inline __hostdev__ constexpr T pi()
34{
35 return 3.141592653589793238462643383279502884e+00;
36}
37template<>
38inline __hostdev__ constexpr float pi()
39{
40 return 3.141592653589793238462643383279502884e+00F;
41}
42template<>
43inline __hostdev__ constexpr double pi()
44{
45 return 3.141592653589793238462643383279502884e+00;
46}
47template<>
48inline __hostdev__ constexpr long double pi()
49{
50 return 3.141592653589793238462643383279502884e+00L;
51}
52//@}
53
54//@{
55/// Tolerance for floating-point comparison
56template<typename T>
57struct Tolerance;
58template<>
59struct Tolerance<float>
60{
61 __hostdev__ static float value() { return 1e-8f; }
62};
63template<>
64struct Tolerance<double>
65{
66 __hostdev__ static double value() { return 1e-15; }
67};
68//@}
69
70//@{
71/// Delta for small floating-point offsets
72template<typename T>
73struct Delta;
74template<>
75struct Delta<float>
76{
77 __hostdev__ static float value() { return 1e-5f; }
78};
79template<>
80struct Delta<double>
81{
82 __hostdev__ static double value() { return 1e-9; }
83};
84//@}
85
86//@{
87/// Maximum floating-point values
88template<typename T>
89struct Maximum;
90#if defined(__CUDA_ARCH__)
91template<typename T>
92struct Maximum
93{
94 __hostdev__ static T value() { return ::cuda::std::numeric_limits<T>::max(); }
95};
96#elif defined(__HIP__)
97template<>
98struct Maximum<int>
99{
100 __hostdev__ static int value() { return 2147483647; }
101};
102template<>
103struct Maximum<uint32_t>
104{
105 __hostdev__ static uint32_t value() { return 4294967295u; }
106};
107template<>
108struct Maximum<float>
109{
110 __hostdev__ static float value() { return 1e+38f; }
111};
112template<>
113struct Maximum<double>
114{
115 __hostdev__ static double value() { return 1e+308; }
116};
117#else
118template<typename T>
120{
121 static T value() { return std::numeric_limits<T>::max(); }
122};
123#endif
124//@}
125
126template<typename Type>
127__hostdev__ inline bool isApproxZero(const Type& x)
128{
129 return !(x > Tolerance<Type>::value()) && !(x < -Tolerance<Type>::value());
130}
131
132template<typename Type>
133__hostdev__ inline Type Min(Type a, Type b)
134{
135 return (a < b) ? a : b;
136}
137__hostdev__ inline int32_t Min(int32_t a, int32_t b)
138{
139 return int32_t(fminf(float(a), float(b)));
140}
141__hostdev__ inline uint32_t Min(uint32_t a, uint32_t b)
142{
143 return uint32_t(fminf(float(a), float(b)));
144}
145__hostdev__ inline float Min(float a, float b)
146{
147 return fminf(a, b);
148}
149__hostdev__ inline double Min(double a, double b)
150{
151 return fmin(a, b);
152}
153template<typename Type>
154__hostdev__ inline Type Max(Type a, Type b)
155{
156 return (a > b) ? a : b;
157}
158
159__hostdev__ inline int32_t Max(int32_t a, int32_t b)
160{
161 return int32_t(fmaxf(float(a), float(b)));
162}
163__hostdev__ inline uint32_t Max(uint32_t a, uint32_t b)
164{
165 return uint32_t(fmaxf(float(a), float(b)));
166}
167__hostdev__ inline float Max(float a, float b)
168{
169 return fmaxf(a, b);
170}
171__hostdev__ inline double Max(double a, double b)
172{
173 return fmax(a, b);
174}
175__hostdev__ inline float Clamp(float x, float a, float b)
176{
177 return Max(Min(x, b), a);
178}
179__hostdev__ inline double Clamp(double x, double a, double b)
180{
181 return Max(Min(x, b), a);
182}
183
184__hostdev__ inline float Fract(float x)
185{
186 return x - floorf(x);
187}
188__hostdev__ inline double Fract(double x)
189{
190 return x - floor(x);
191}
192
193__hostdev__ inline int32_t Floor(float x)
194{
195 return int32_t(floorf(x));
196}
197__hostdev__ inline int32_t Floor(double x)
198{
199 return int32_t(floor(x));
200}
201
202__hostdev__ inline int32_t Ceil(float x)
203{
204 return int32_t(ceilf(x));
205}
206__hostdev__ inline int32_t Ceil(double x)
207{
208 return int32_t(ceil(x));
209}
210
211template<typename T>
212__hostdev__ inline T Pow2(T x)
213{
214 return x * x;
215}
216
217template<typename T>
218__hostdev__ inline T Pow3(T x)
219{
220 return x * x * x;
221}
222
223template<typename T>
224__hostdev__ inline T Pow4(T x)
225{
226 return Pow2(x * x);
227}
228template<typename T>
229__hostdev__ inline T Abs(T x)
230{
231 return x < 0 ? -x : x;
232}
233
234template<>
235__hostdev__ inline float Abs(float x)
236{
237 return fabsf(x);
238}
239
240template<>
241__hostdev__ inline double Abs(double x)
242{
243 return fabs(x);
244}
245
246template<>
247__hostdev__ inline int Abs(int x)
248{
249 return abs(x);
250}
251
252template<typename CoordT, typename RealT, template<typename> class Vec3T>
253__hostdev__ inline CoordT Round(const Vec3T<RealT>& xyz);
254
255template<typename CoordT, template<typename> class Vec3T>
256__hostdev__ inline CoordT Round(const Vec3T<float>& xyz)
257{
258 return CoordT(int32_t(rintf(xyz[0])), int32_t(rintf(xyz[1])), int32_t(rintf(xyz[2])));
259 //return CoordT(int32_t(roundf(xyz[0])), int32_t(roundf(xyz[1])), int32_t(roundf(xyz[2])) );
260 //return CoordT(int32_t(floorf(xyz[0] + 0.5f)), int32_t(floorf(xyz[1] + 0.5f)), int32_t(floorf(xyz[2] + 0.5f)));
261}
262
263template<typename CoordT, template<typename> class Vec3T>
264__hostdev__ inline CoordT Round(const Vec3T<double>& xyz)
265{
266 return CoordT(int32_t(floor(xyz[0] + 0.5)), int32_t(floor(xyz[1] + 0.5)), int32_t(floor(xyz[2] + 0.5)));
267}
268
269template<typename CoordT, typename RealT, template<typename> class Vec3T>
270__hostdev__ inline CoordT RoundDown(const Vec3T<RealT>& xyz)
271{
272 return CoordT(Floor(xyz[0]), Floor(xyz[1]), Floor(xyz[2]));
273}
274
275//@{
276/// Return the square root of a floating-point value.
277__hostdev__ inline float Sqrt(float x)
278{
279 return sqrtf(x);
280}
281__hostdev__ inline double Sqrt(double x)
282{
283 return sqrt(x);
284}
285//@}
286
287/// Return the sign of the given value as an integer (either -1, 0 or 1).
288template<typename T>
289__hostdev__ inline T Sign(const T& x)
290{
291 return ((T(0) < x) ? T(1) : T(0)) - ((x < T(0)) ? T(1) : T(0));
292}
293
294template<typename Vec3T>
295__hostdev__ inline int MinIndex(const Vec3T& v)
296{
297#if 0
298 static const int hashTable[8] = {2, 1, 9, 1, 2, 9, 0, 0}; //9 are dummy values
299 const int hashKey = ((v[0] < v[1]) << 2) + ((v[0] < v[2]) << 1) + (v[1] < v[2]); // ?*4+?*2+?*1
300 return hashTable[hashKey];
301#else
302 if (v[0] < v[1] && v[0] < v[2])
303 return 0;
304 if (v[1] < v[2])
305 return 1;
306 else
307 return 2;
308#endif
309}
310
311template<typename Vec3T>
312__hostdev__ inline int MaxIndex(const Vec3T& v)
313{
314#if 0
315 static const int hashTable[8] = {2, 1, 9, 1, 2, 9, 0, 0}; //9 are dummy values
316 const int hashKey = ((v[0] > v[1]) << 2) + ((v[0] > v[2]) << 1) + (v[1] > v[2]); // ?*4+?*2+?*1
317 return hashTable[hashKey];
318#else
319 if (v[0] > v[1] && v[0] > v[2])
320 return 0;
321 if (v[1] > v[2])
322 return 1;
323 else
324 return 2;
325#endif
326}
327
328/// @brief round up byteSize to the nearest wordSize, e.g. to align to machine word: AlignUp<sizeof(size_t)(n)
329///
330/// @details both wordSize and byteSize are in byte units
331template<uint64_t wordSize>
332__hostdev__ inline uint64_t AlignUp(uint64_t byteCount)
333{
334 const uint64_t r = byteCount % wordSize;
335 return r ? byteCount - r + wordSize : byteCount;
336}
337
338// ------------------------------> Coord <--------------------------------------
339
340// forward declaration so we can define Coord::asVec3s and Coord::asVec3d
341template<typename>
342class Vec3;
343
344/// @brief Signed (i, j, k) 32-bit integer coordinate class, similar to openvdb::math::Coord
345class Coord
346{
347 int32_t mVec[3]; // private member data - three signed index coordinates
348public:
349 using ValueType = int32_t;
350 using IndexType = uint32_t;
351
352 /// @brief Initialize all coordinates to zero.
354 : mVec{0, 0, 0}
355 {
356 }
357
358 /// @brief Initializes all coordinates to the given signed integer.
360 : mVec{n, n, n}
361 {
362 }
363
364 /// @brief Initializes coordinate to the given signed integers.
366 : mVec{i, j, k}
367 {
368 }
369
371 : mVec{ptr[0], ptr[1], ptr[2]}
372 {
373 }
374
375 __hostdev__ int32_t x() const { return mVec[0]; }
376 __hostdev__ int32_t y() const { return mVec[1]; }
377 __hostdev__ int32_t z() const { return mVec[2]; }
378
379 __hostdev__ int32_t& x() { return mVec[0]; }
380 __hostdev__ int32_t& y() { return mVec[1]; }
381 __hostdev__ int32_t& z() { return mVec[2]; }
382
383 __hostdev__ static Coord max() { return Coord(int32_t((1u << 31) - 1)); }
384
385 __hostdev__ static Coord min() { return Coord(-int32_t((1u << 31) - 1) - 1); }
386
387 __hostdev__ static size_t memUsage() { return sizeof(Coord); }
388
389 /// @brief Return a const reference to the given Coord component.
390 /// @warning The argument is assumed to be 0, 1, or 2.
391 __hostdev__ const ValueType& operator[](IndexType i) const { return mVec[i]; }
392
393 /// @brief Return a non-const reference to the given Coord component.
394 /// @warning The argument is assumed to be 0, 1, or 2.
396
397 /// @brief Assignment operator that works with openvdb::Coord
398 template<typename CoordT>
399 __hostdev__ Coord& operator=(const CoordT& other)
400 {
401 static_assert(sizeof(Coord) == sizeof(CoordT), "Mis-matched sizeof");
402 mVec[0] = other[0];
403 mVec[1] = other[1];
404 mVec[2] = other[2];
405 return *this;
406 }
407
408 /// @brief Return a new instance with coordinates masked by the given unsigned integer.
409 __hostdev__ Coord operator&(IndexType n) const { return Coord(mVec[0] & n, mVec[1] & n, mVec[2] & n); }
410
411 // @brief Return a new instance with coordinates left-shifted by the given unsigned integer.
412 __hostdev__ Coord operator<<(IndexType n) const { return Coord(mVec[0] << n, mVec[1] << n, mVec[2] << n); }
413
414 // @brief Return a new instance with coordinates right-shifted by the given unsigned integer.
415 __hostdev__ Coord operator>>(IndexType n) const { return Coord(mVec[0] >> n, mVec[1] >> n, mVec[2] >> n); }
416
417 /// @brief Return true if this Coord is lexicographically less than the given Coord.
418 __hostdev__ bool operator<(const Coord& rhs) const
419 {
420 return mVec[0] < rhs[0] ? true
421 : mVec[0] > rhs[0] ? false
422 : mVec[1] < rhs[1] ? true
423 : mVec[1] > rhs[1] ? false
424 : mVec[2] < rhs[2] ? true : false;
425 }
426
427 /// @brief Return true if this Coord is lexicographically less or equal to the given Coord.
428 __hostdev__ bool operator<=(const Coord& rhs) const
429 {
430 return mVec[0] < rhs[0] ? true
431 : mVec[0] > rhs[0] ? false
432 : mVec[1] < rhs[1] ? true
433 : mVec[1] > rhs[1] ? false
434 : mVec[2] <=rhs[2] ? true : false;
435 }
436
437 // @brief Return true if this Coord is lexicographically greater than the given Coord.
438 __hostdev__ bool operator>(const Coord& rhs) const
439 {
440 return mVec[0] > rhs[0] ? true
441 : mVec[0] < rhs[0] ? false
442 : mVec[1] > rhs[1] ? true
443 : mVec[1] < rhs[1] ? false
444 : mVec[2] > rhs[2] ? true : false;
445 }
446
447 // @brief Return true if this Coord is lexicographically greater or equal to the given Coord.
448 __hostdev__ bool operator>=(const Coord& rhs) const
449 {
450 return mVec[0] > rhs[0] ? true
451 : mVec[0] < rhs[0] ? false
452 : mVec[1] > rhs[1] ? true
453 : mVec[1] < rhs[1] ? false
454 : mVec[2] >=rhs[2] ? true : false;
455 }
456
457 // @brief Return true if the Coord components are identical.
458 __hostdev__ bool operator==(const Coord& rhs) const { return mVec[0] == rhs[0] && mVec[1] == rhs[1] && mVec[2] == rhs[2]; }
459 __hostdev__ bool operator!=(const Coord& rhs) const { return mVec[0] != rhs[0] || mVec[1] != rhs[1] || mVec[2] != rhs[2]; }
461 {
462 mVec[0] &= n;
463 mVec[1] &= n;
464 mVec[2] &= n;
465 return *this;
466 }
468 {
469 mVec[0] <<= n;
470 mVec[1] <<= n;
471 mVec[2] <<= n;
472 return *this;
473 }
475 {
476 mVec[0] >>= n;
477 mVec[1] >>= n;
478 mVec[2] >>= n;
479 return *this;
480 }
482 {
483 mVec[0] += n;
484 mVec[1] += n;
485 mVec[2] += n;
486 return *this;
487 }
488 __hostdev__ Coord operator+(const Coord& rhs) const { return Coord(mVec[0] + rhs[0], mVec[1] + rhs[1], mVec[2] + rhs[2]); }
489 __hostdev__ Coord operator-(const Coord& rhs) const { return Coord(mVec[0] - rhs[0], mVec[1] - rhs[1], mVec[2] - rhs[2]); }
490 __hostdev__ Coord operator-() const { return Coord(-mVec[0], -mVec[1], -mVec[2]); }
492 {
493 mVec[0] += rhs[0];
494 mVec[1] += rhs[1];
495 mVec[2] += rhs[2];
496 return *this;
497 }
499 {
500 mVec[0] -= rhs[0];
501 mVec[1] -= rhs[1];
502 mVec[2] -= rhs[2];
503 return *this;
504 }
505
506 /// @brief Perform a component-wise minimum with the other Coord.
508 {
509 if (other[0] < mVec[0])
510 mVec[0] = other[0];
511 if (other[1] < mVec[1])
512 mVec[1] = other[1];
513 if (other[2] < mVec[2])
514 mVec[2] = other[2];
515 return *this;
516 }
517
518 /// @brief Perform a component-wise maximum with the other Coord.
520 {
521 if (other[0] > mVec[0])
522 mVec[0] = other[0];
523 if (other[1] > mVec[1])
524 mVec[1] = other[1];
525 if (other[2] > mVec[2])
526 mVec[2] = other[2];
527 return *this;
528 }
529#if defined(__CUDACC__) // the following functions only run on the GPU!
530 __device__ inline Coord& minComponentAtomic(const Coord& other)
531 {
532 atomicMin(&mVec[0], other[0]);
533 atomicMin(&mVec[1], other[1]);
534 atomicMin(&mVec[2], other[2]);
535 return *this;
536 }
537 __device__ inline Coord& maxComponentAtomic(const Coord& other)
538 {
539 atomicMax(&mVec[0], other[0]);
540 atomicMax(&mVec[1], other[1]);
541 atomicMax(&mVec[2], other[2]);
542 return *this;
543 }
544#endif
545
547 {
548 return Coord(mVec[0] + dx, mVec[1] + dy, mVec[2] + dz);
549 }
550
551 __hostdev__ Coord offsetBy(ValueType n) const { return this->offsetBy(n, n, n); }
552
553 /// Return true if any of the components of @a a are smaller than the
554 /// corresponding components of @a b.
555 __hostdev__ static inline bool lessThan(const Coord& a, const Coord& b)
556 {
557 return (a[0] < b[0] || a[1] < b[1] || a[2] < b[2]);
558 }
559
560 /// @brief Return the largest integer coordinates that are not greater
561 /// than @a xyz (node centered conversion).
562 template<typename Vec3T>
563 __hostdev__ static Coord Floor(const Vec3T& xyz) { return Coord(math::Floor(xyz[0]), math::Floor(xyz[1]), math::Floor(xyz[2])); }
564
565 /// @brief Return a hash key derived from the existing coordinates.
566 /// @details The hash function is originally taken from the SIGGRAPH paper:
567 /// "VDB: High-resolution sparse volumes with dynamic topology"
568 /// and the prime numbers are modified based on the ACM Transactions on Graphics paper:
569 /// "Real-time 3D reconstruction at scale using voxel hashing" (the second number had a typo!)
570 template<int Log2N = 3 + 4 + 5>
571 __hostdev__ uint32_t hash() const { return ((1 << Log2N) - 1) & (mVec[0] * 73856093 ^ mVec[1] * 19349669 ^ mVec[2] * 83492791); }
572
573 /// @brief Return the octant of this Coord
574 //__hostdev__ size_t octant() const { return (uint32_t(mVec[0])>>31) | ((uint32_t(mVec[1])>>31)<<1) | ((uint32_t(mVec[2])>>31)<<2); }
575 __hostdev__ uint8_t octant() const { return (uint8_t(bool(mVec[0] & (1u << 31)))) |
576 (uint8_t(bool(mVec[1] & (1u << 31))) << 1) |
577 (uint8_t(bool(mVec[2] & (1u << 31))) << 2); }
578
579 /// @brief Return a single precision floating-point vector of this coordinate
580 __hostdev__ inline Vec3<float> asVec3s() const;
581
582 /// @brief Return a double precision floating-point vector of this coordinate
583 __hostdev__ inline Vec3<double> asVec3d() const;
584
585 // returns a copy of itself, so it mimics the behaviour of Vec3<T>::round()
586 __hostdev__ inline Coord round() const { return *this; }
587}; // Coord class
588
589
590/// @brief Type alias for Coord so we have a consistent naming convention
591using Coord3 = Coord;
592
593
594template <typename T>
595class Vec2;
596
597/// @brief Signed (i, j) 32-bit integer coordinate class, similar to openvdb::math::Coord
599{
600 int32_t mVec[2]; // private member data - three signed index coordinates
601public:
602 using ValueType = int32_t;
603 using IndexType = uint32_t;
604
605 /// @brief Initialize all coordinates to zero.
607 : mVec{0, 0}
608 {
609 }
610
611 /// @brief Initializes all coordinates to the given signed integer.
613 : mVec{n, n}
614 {
615 }
616
617 /// @brief Initializes coordinate to the given signed integers.
619 : mVec{i, j}
620 {
621 }
622
624 : mVec{ptr[0], ptr[1]}
625 {
626 }
627
628 __hostdev__ int32_t x() const { return mVec[0]; }
629 __hostdev__ int32_t y() const { return mVec[1]; }
630
631 __hostdev__ int32_t& x() { return mVec[0]; }
632 __hostdev__ int32_t& y() { return mVec[1]; }
633
634 __hostdev__ static Coord2 max() { return Coord2(int32_t((1u << 31) - 1)); }
635
636 __hostdev__ static Coord2 min() { return Coord2(-int32_t((1u << 31) - 1) - 1); }
637
638 __hostdev__ static size_t memUsage() { return sizeof(Coord2); }
639
640 /// @brief Return a const reference to the given Coord component.
641 /// @warning The argument is assumed to be 0 or 1,
642 __hostdev__ const ValueType& operator[](IndexType i) const { return mVec[i]; }
643
644 /// @brief Return a non-const reference to the given Coord component.
645 /// @warning The argument is assumed to be 0 or 1.
647
648 /// @brief Assignment operator that works with openvdb::Coord
649 template<typename CoordT>
650 __hostdev__ Coord2& operator=(const CoordT& other)
651 {
652 static_assert(sizeof(Coord2) == sizeof(CoordT), "Mis-matched sizeof");
653 mVec[0] = other[0];
654 mVec[1] = other[1];
655 return *this;
656 }
657
658 /// @brief Return a new instance with coordinates masked by the given unsigned integer.
659 __hostdev__ Coord2 operator&(IndexType n) const { return Coord2(mVec[0] & n, mVec[1] & n); }
660
661 // @brief Return a new instance with coordinates left-shifted by the given unsigned integer.
662 __hostdev__ Coord2 operator<<(IndexType n) const { return Coord2(mVec[0] << n, mVec[1] << n); }
663
664 // @brief Return a new instance with coordinates right-shifted by the given unsigned integer.
665 __hostdev__ Coord2 operator>>(IndexType n) const { return Coord2(mVec[0] >> n, mVec[1] >> n); }
666
667 /// @brief Return true if this Coord is lexicographically less than the given Coord.
668 __hostdev__ bool operator<(const Coord2& rhs) const
669 {
670 return mVec[0] < rhs[0] ? true
671 : mVec[0] > rhs[0] ? false
672 : mVec[1] < rhs[1] ? true : false;
673 }
674
675 /// @brief Return true if this Coord is lexicographically less or equal to the given Coord.
676 __hostdev__ bool operator<=(const Coord2& rhs) const
677 {
678 return mVec[0] < rhs[0] ? true
679 : mVec[0] > rhs[0] ? false
680 : mVec[1] <= rhs[1] ? true : false;
681 }
682
683 // @brief Return true if this Coord is lexicographically greater than the given Coord.
684 __hostdev__ bool operator>(const Coord2& rhs) const
685 {
686 return mVec[0] > rhs[0] ? true
687 : mVec[0] < rhs[0] ? false
688 : mVec[1] > rhs[1] ? true : false;
689 }
690
691 // @brief Return true if this Coord is lexicographically greater or equal to the given Coord.
692 __hostdev__ bool operator>=(const Coord2& rhs) const
693 {
694 return mVec[0] > rhs[0] ? true
695 : mVec[0] < rhs[0] ? false
696 : mVec[1] >= rhs[1] ? true : false;
697 }
698
699 // @brief Return true if the Coord components are identical.
700 __hostdev__ bool operator==(const Coord2& rhs) const { return mVec[0] == rhs[0] && mVec[1] == rhs[1]; }
701 __hostdev__ bool operator!=(const Coord2& rhs) const { return mVec[0] != rhs[0] || mVec[1] != rhs[1]; }
703 {
704 mVec[0] &= n;
705 mVec[1] &= n;
706 return *this;
707 }
709 {
710 mVec[0] <<= n;
711 mVec[1] <<= n;
712 return *this;
713 }
715 {
716 mVec[0] >>= n;
717 mVec[1] >>= n;
718 return *this;
719 }
721 {
722 mVec[0] += n;
723 mVec[1] += n;
724 return *this;
725 }
726 __hostdev__ Coord2 operator+(const Coord2& rhs) const { return Coord2(mVec[0] + rhs[0], mVec[1] + rhs[1]); }
727 __hostdev__ Coord2 operator-(const Coord2& rhs) const { return Coord2(mVec[0] - rhs[0], mVec[1] - rhs[1]); }
728 __hostdev__ Coord2 operator-() const { return Coord2(-mVec[0], -mVec[1]); }
730 {
731 mVec[0] += rhs[0];
732 mVec[1] += rhs[1];
733 return *this;
734 }
736 {
737 mVec[0] -= rhs[0];
738 mVec[1] -= rhs[1];
739 return *this;
740 }
741
742 /// @brief Perform a component-wise minimum with the other Coord.
744 {
745 if (other[0] < mVec[0])
746 mVec[0] = other[0];
747 if (other[1] < mVec[1])
748 mVec[1] = other[1];
749 return *this;
750 }
751
752 /// @brief Perform a component-wise maximum with the other Coord.
754 {
755 if (other[0] > mVec[0])
756 mVec[0] = other[0];
757 if (other[1] > mVec[1])
758 mVec[1] = other[1];
759 return *this;
760 }
761#if defined(__CUDACC__) // the following functions only run on the GPU!
762 __device__ inline Coord2& minComponentAtomic(const Coord2& other)
763 {
764 atomicMin(&mVec[0], other[0]);
765 atomicMin(&mVec[1], other[1]);
766 return *this;
767 }
768 __device__ inline Coord2& maxComponentAtomic(const Coord2& other)
769 {
770 atomicMax(&mVec[0], other[0]);
771 atomicMax(&mVec[1], other[1]);
772 return *this;
773 }
774#endif
775
777 {
778 return Coord2(mVec[0] + dx, mVec[1] + dy);
779 }
780
781 __hostdev__ Coord2 offsetBy(ValueType n) const { return this->offsetBy(n, n); }
782
783 /// Return true if any of the components of @a a are smaller than the
784 /// corresponding components of @a b.
785 __hostdev__ static inline bool lessThan(const Coord2& a, const Coord2& b)
786 {
787 return (a[0] < b[0] || a[1] < b[1]);
788 }
789
790 /// @brief Return the largest integer coordinates that are not greater
791 /// than @a xyz (node centered conversion).
792 template<typename Vec2T>
793 __hostdev__ static Coord2 Floor(const Vec2T& xy) { return Coord2(math::Floor(xy[0]), math::Floor(xy[1])); }
794
795 /// @brief Return a single precision floating-point vector of this coordinate
796 __hostdev__ inline Vec2<float> asVec2s() const;
797
798 /// @brief Return a double precision floating-point vector of this coordinate
799 __hostdev__ inline Vec2<double> asVec2d() const;
800
801 // returns a copy of itself, so it mimics the behaviour of Vec3<T>::round()
802 __hostdev__ inline Coord2 round() const { return *this; }
803}; // Coord2 class
804
805// ----------------------------> Vec2 <--------------------------------------
806
807/// @brief A simple vector class with three components, similar to openvdb::math::Vec3
808template<typename T>
809class Vec2
810{
811 T mVec[2];
812
813public:
814 static const int SIZE = 2;
815 static const int size = 2; // in openvdb::math::Tuple
816 using ValueType = T;
817 Vec2() = default;
818 __hostdev__ explicit Vec2(T x)
819 : mVec{x, x}
820 {
821 }
823 : mVec{x, y}
824 {
825 }
826 template<template<class> class Vec2T, class T2>
827 __hostdev__ Vec2(const Vec2T<T2>& v)
828 : mVec{T(v[0]), T(v[1])}
829 {
830 static_assert(Vec2T<T2>::size == size, "expected Vec2T::size==2!");
831 }
832 template<typename T2>
833 __hostdev__ explicit Vec2(const Vec2<T2>& v)
834 : mVec{T(v[0]), T(v[1])}
835 {
836 }
837 __hostdev__ explicit Vec2(const Coord2& ijk)
838 : mVec{T(ijk[0]), T(ijk[1])}
839 {
840 }
841 __hostdev__ bool operator==(const Vec2& rhs) const { return mVec[0] == rhs[0] && mVec[1] == rhs[1]; }
842 __hostdev__ bool operator!=(const Vec2& rhs) const { return mVec[0] != rhs[0] || mVec[1] != rhs[1]; }
843 template<template<class> class Vec2T, class T2>
844 __hostdev__ Vec2& operator=(const Vec2T<T2>& rhs)
845 {
846 static_assert(Vec2T<T2>::size == size, "expected Vec2T::size==2!");
847 mVec[0] = rhs[0];
848 mVec[1] = rhs[1];
849 return *this;
850 }
851 __hostdev__ const T& operator[](int i) const { return mVec[i]; }
852 __hostdev__ T& operator[](int i) { return mVec[i]; }
853 template<typename Vec2T>
854 __hostdev__ T dot(const Vec2T& v) const { return mVec[0] * v[0] + mVec[1] * v[1]; }
856 {
857 return mVec[0] * mVec[0] + mVec[1] * mVec[1]; // 3 flops
858 }
859 __hostdev__ T length() const { return Sqrt(this->lengthSqr()); }
860 __hostdev__ Vec2 operator-() const { return Vec2(-mVec[0], -mVec[1]); }
861 __hostdev__ Vec2 operator*(const Vec2& v) const { return Vec2(mVec[0] * v[0], mVec[1] * v[1]); }
862 __hostdev__ Vec2 operator/(const Vec2& v) const { return Vec2(mVec[0] / v[0], mVec[1] / v[1]); }
863 __hostdev__ Vec2 operator+(const Vec2& v) const { return Vec2(mVec[0] + v[0], mVec[1] + v[1]); }
864 __hostdev__ Vec2 operator-(const Vec2& v) const { return Vec2(mVec[0] - v[0], mVec[1] - v[1]); }
865 __hostdev__ Vec2 operator+(const Coord& ijk) const { return Vec2(mVec[0] + ijk[0], mVec[1] + ijk[1]); }
866 __hostdev__ Vec2 operator-(const Coord& ijk) const { return Vec2(mVec[0] - ijk[0], mVec[1] - ijk[1]); }
867 __hostdev__ Vec2 operator*(const T& s) const { return Vec2(s * mVec[0], s * mVec[1]); }
868 __hostdev__ Vec2 operator/(const T& s) const { return (T(1) / s) * (*this); }
870 {
871 mVec[0] += v[0];
872 mVec[1] += v[1];
873 return *this;
874 }
876 {
877 mVec[0] += T(ijk[0]);
878 mVec[1] += T(ijk[1]);
879 return *this;
880 }
882 {
883 mVec[0] -= v[0];
884 mVec[1] -= v[1];
885 return *this;
886 }
888 {
889 mVec[0] -= T(ijk[0]);
890 mVec[1] -= T(ijk[1]);
891 return *this;
892 }
894 {
895 mVec[0] *= s;
896 mVec[1] *= s;
897 return *this;
898 }
899 __hostdev__ Vec2& operator/=(const T& s) { return (*this) *= T(1) / s; }
900 __hostdev__ Vec2& normalize() { return (*this) /= this->length(); }
901 /// @brief Perform a component-wise minimum with the other Coord.
903 {
904 if (other[0] < mVec[0])
905 mVec[0] = other[0];
906 if (other[1] < mVec[1])
907 mVec[1] = other[1];
908 return *this;
909 }
910
911 /// @brief Perform a component-wise maximum with the other Coord.
913 {
914 if (other[0] > mVec[0])
915 mVec[0] = other[0];
916 if (other[1] > mVec[1])
917 mVec[1] = other[1];
918 return *this;
919 }
920 /// @brief Return the smallest vector component
922 {
923 return mVec[0] < mVec[1] ? mVec[0] : mVec[1];
924 }
925 /// @brief Return the largest vector component
927 {
928 return mVec[0] > mVec[1] ? mVec[0] : mVec[1];
929 }
930 /// @brief Round each component if this Vec<T> up to its integer value
931 /// @return Return an integer Coord
932 __hostdev__ Coord2 floor() const { return Coord2(Floor(mVec[0]), Floor(mVec[1])); }
933 /// @brief Round each component if this Vec<T> down to its integer value
934 /// @return Return an integer Coord
935 __hostdev__ Coord2 ceil() const { return Coord2(Ceil(mVec[0]), Ceil(mVec[1])); }
936 /// @brief Round each component if this Vec<T> to its closest integer value
937 /// @return Return an integer Coord
939 {
940 if constexpr(util::is_same<T, float>::value) {
941 return Coord2(Floor(mVec[0] + 0.5f), Floor(mVec[1] + 0.5f));
942 } else if constexpr(util::is_same<T, int>::value) {
943 return Coord2(mVec[0], mVec[1]);
944 } else {
945 return Coord2(Floor(mVec[0] + 0.5), Floor(mVec[1] + 0.5));
946 }
947 }
948
949 /// @brief return a non-const raw constant pointer to array of three vector components
950 __hostdev__ T* asPointer() { return mVec; }
951 /// @brief return a const raw constant pointer to array of three vector components
952 __hostdev__ const T* asPointer() const { return mVec; }
953}; // Vec2<T>
954
955template<typename T1, typename T2>
956__hostdev__ inline Vec2<T2> operator*(T1 scalar, const Vec2<T2>& vec)
957{
958 return Vec2<T2>(scalar * vec[0], scalar * vec[1]);
959}
960template<typename T1, typename T2>
961__hostdev__ inline Vec2<T2> operator/(T1 scalar, const Vec2<T2>& vec)
962{
963 return Vec2<T2>(scalar / vec[0], scalar / vec[1]);
964}
965
966/// @brief Return a single precision floating-point vector of this coordinate
968{
969 return Vec2<float>(float(mVec[0]), float(mVec[1]));
970}
971
972/// @brief Return a double precision floating-point vector of this coordinate
974{
975 return Vec2<double>(double(mVec[0]), double(mVec[1]));
976}
977
978
979// Matrix base class
980template<typename T, int ROWS, int COLS>
981class MatBase {
982protected:
983 T mData[ROWS * COLS]; // 1D array storage
984
985 static constexpr int rows() { return ROWS; }
986 static constexpr int cols() { return COLS; }
987 static constexpr int size() { return ROWS * COLS; }
988
989public:
990 MatBase() = default;
991
992 template<typename S>
994 for (int i = 0; i < ROWS * COLS; ++i) {
995 mData[i] = static_cast<T>(array[i]);
996 }
997 }
998
999 // 2D array access
1001 return &mData[row * COLS];
1002 }
1003 __hostdev__ const T* operator[](int row) const {
1004 return &mData[row * COLS];
1005 }
1006};
1007
1008// Forward declarations
1009template<typename T> class Mat2;
1010template<typename T> class Mat2x3;
1011template<typename T> class Mat3x2;
1012template<typename T> class Mat3;
1013template<typename T> class Mat4;
1014
1015
1016
1017template <typename T>
1018class Mat2 : public MatBase<T, 2, 2> {
1019 using Base = MatBase<T, 2, 2>;
1020public:
1021 Mat2() = default;
1022 /// @brief Constructor given individual array elements, the ordering is in row major form:
1023 /** @verbatim
1024 a b
1025 c d
1026 @endverbatim */
1027 __hostdev__ Mat2(T a, T b, T c, T d) {
1028 this->mData[0] = a; this->mData[1] = b;
1029 this->mData[2] = c; this->mData[3] = d;
1030 }
1031
1032 /// @brief Constructor given array of elements, the ordering is in row major form
1033 template<typename Source>
1034 __hostdev__ Mat2(Source* array) : Base(array) {}
1035
1036 __hostdev__ Mat2 operator-() const { return Mat2(-(*this)[0][0], -(*this)[0][1], -(*this)[1][0], -(*this)[1][1]); }
1037
1038 /// @brief Multiply by 2x2 matrix @a m and return the resulting matrix.
1040 return Mat2<T>(
1041 (*this)[0][0] * m[0][0] + (*this)[0][1] * m[1][0],
1042 (*this)[0][0] * m[0][1] + (*this)[0][1] * m[1][1],
1043 (*this)[1][0] * m[0][0] + (*this)[1][1] * m[1][0],
1044 (*this)[1][0] * m[0][1] + (*this)[1][1] * m[1][1]
1045 );
1046 }
1047
1048 /// @brief Add each element of the given matrix to the corresponding element of this matrix.
1050 (*this)[0][0] += m[0][0];
1051 (*this)[0][1] += m[0][1];
1052 (*this)[1][0] += m[1][0];
1053 (*this)[1][1] += m[1][1];
1054 return *this;
1055 }
1056
1057 /// @brief returns transpose of this
1059 return Mat2<T>((*this)[0][0], (*this)[1][0], (*this)[0][1], (*this)[1][1]);
1060 }
1061
1062 /// @brief returns inverse of this
1064 T det = (*this)[0][0] * (*this)[1][1] - (*this)[0][1] * (*this)[1][0];
1065 if (isApproxZero(det)) {
1066 return Mat2<T>();
1067 }
1068 T invDet = 1.f / det;
1069 return Mat2<T>((*this)[1][1] * invDet, -(*this)[0][1] * invDet, -(*this)[1][0] * invDet, (*this)[0][0] * invDet);
1070 }
1071};
1072
1073template <typename T>
1074class Mat2x3 : public MatBase<T, 2, 3> {
1075 using Base = MatBase<T, 2, 3>;
1076public:
1077 Mat2x3() = default;
1078 /// @brief Constructor given individual array elements, the ordering is in row major form:
1079 /** @verbatim
1080 a b c
1081 d e f
1082 @endverbatim */
1083 __hostdev__ Mat2x3(T a, T b, T c, T d, T e, T f) {
1084 this->mData[0] = a; this->mData[1] = b; this->mData[2] = c;
1085 this->mData[3] = d; this->mData[4] = e; this->mData[5] = f;
1086 }
1087
1088 /// @brief Constructor given array of elements, the ordering is in row major form
1089 template<typename Source>
1090 __hostdev__ Mat2x3(Source* array) : Base(array) {}
1091
1092
1093 /// @brief Add two matrices and return the resulting matrix.
1095 return Mat2x3<T>(
1096 (*this)[0][0] + m[0][0], (*this)[0][1] + m[0][1], (*this)[0][2] + m[0][2],
1097 (*this)[1][0] + m[1][0], (*this)[1][1] + m[1][1], (*this)[1][2] + m[1][2]
1098 );
1099 }
1100
1101 /// @brief Add a 2x3 matrix to this matrix.
1103 (*this)[0][0] += m[0][0]; (*this)[0][1] += m[0][1]; (*this)[0][2] += m[0][2];
1104 (*this)[1][0] += m[1][0]; (*this)[1][1] += m[1][1]; (*this)[1][2] += m[1][2];
1105 return *this;
1106 }
1107
1108 /// @brief returns transpose of this
1110 return Mat3x2<T>(
1111 (*this)[0][0], (*this)[1][0], // First row
1112 (*this)[0][1], (*this)[1][1], // Second row
1113 (*this)[0][2], (*this)[1][2] // Third row
1114 );
1115 }
1116};
1117
1118template <typename T>
1119class Mat3x2: public MatBase<T, 3, 2> {
1120 using Base = MatBase<T, 3, 2>;
1121public:
1122 Mat3x2() = default;
1123
1124 /// @brief Constructor given individual array elements, the ordering is in row major form:
1125 /** @verbatim
1126 a b
1127 c d
1128 e f
1129 @endverbatim */
1130 template<typename Source>
1131 __hostdev__ Mat3x2(Source a, Source b, Source c, Source d, Source e, Source f)
1132 {
1133 this->mData[0] = a; this->mData[1] = b;
1134 this->mData[2] = c; this->mData[3] = d;
1135 this->mData[4] = e; this->mData[5] = f;
1136 }
1137
1138 /// @brief Constructor given array of elements, the ordering is in row major form
1139 template<typename Source>
1140 __hostdev__ Mat3x2(Source *a): Base(a) {}
1141
1142 /// @brief returns transpose of this
1144 return Mat2x3<T>((*this)[0][0], (*this)[1][0], (*this)[2][0], // First row
1145 (*this)[0][1], (*this)[1][1], (*this)[2][1]); // Second row
1146 }
1147
1148};
1149
1150template <typename T>
1151class Mat3 : public MatBase<T, 3, 3> {
1152 using Base = MatBase<T, 3, 3>;
1153public:
1154 Mat3() = default;
1155
1156 /// @brief Constructor given individual array elements, the ordering is in row major form:
1157 /** @verbatim
1158 a b c
1159 d e f
1160 g h i
1161 @endverbatim */
1162 template<typename Source>
1163 __hostdev__ Mat3(Source a, Source b, Source c,
1164 Source d, Source e, Source f,
1165 Source g, Source h, Source i)
1166 {
1167 this->mData[0] = a; this->mData[1] = b; this->mData[2] = c;
1168 this->mData[3] = d; this->mData[4] = e; this->mData[5] = f;
1169 this->mData[6] = g; this->mData[7] = h; this->mData[8] = i;
1170 }
1171
1172 /// @brief Constructor given array of elements, the ordering is in row major form
1173 template<typename Source>
1174 __hostdev__ Mat3(Source *a): Base(a) {}
1175
1176
1177 /// @brief Add two matrices and return the resulting matrix.
1179 return Mat3<T>(
1180 (*this)[0][0] + m[0][0], (*this)[0][1] + m[0][1], (*this)[0][2] + m[0][2],
1181 (*this)[1][0] + m[1][0], (*this)[1][1] + m[1][1], (*this)[1][2] + m[1][2],
1182 (*this)[2][0] + m[2][0], (*this)[2][1] + m[2][1], (*this)[2][2] + m[2][2]
1183 );
1184 }
1185
1186 /// @brief Multiply by @a v and return the resulting vector.
1188 return Vec3<T>(
1189 (*this)[0][0] * v[0] + (*this)[0][1] * v[1] + (*this)[0][2] * v[2],
1190 (*this)[1][0] * v[0] + (*this)[1][1] * v[1] + (*this)[1][2] * v[2],
1191 (*this)[2][0] * v[0] + (*this)[2][1] * v[1] + (*this)[2][2] * v[2]
1192 );
1193 }
1194
1195 /// @brief Multiply by 3x3 matrix @a m and return the resulting matrix.
1197 return Mat3<T>(
1198 (*this)[0][0] * m[0][0] + (*this)[0][1] * m[1][0] + (*this)[0][2] * m[2][0],
1199 (*this)[0][0] * m[0][1] + (*this)[0][1] * m[1][1] + (*this)[0][2] * m[2][1],
1200 (*this)[0][0] * m[0][2] + (*this)[0][1] * m[1][2] + (*this)[0][2] * m[2][2],
1201 (*this)[1][0] * m[0][0] + (*this)[1][1] * m[1][0] + (*this)[1][2] * m[2][0],
1202 (*this)[1][0] * m[0][1] + (*this)[1][1] * m[1][1] + (*this)[1][2] * m[2][1],
1203 (*this)[1][0] * m[0][2] + (*this)[1][1] * m[1][2] + (*this)[1][2] * m[2][2],
1204 (*this)[2][0] * m[0][0] + (*this)[2][1] * m[1][0] + (*this)[2][2] * m[2][0],
1205 (*this)[2][0] * m[0][1] + (*this)[2][1] * m[1][1] + (*this)[2][2] * m[2][1],
1206 (*this)[2][0] * m[0][2] + (*this)[2][1] * m[1][2] + (*this)[2][2] * m[2][2]
1207 );
1208 }
1209
1210 /// @brief Add each element of the given matrix to the corresponding element of this matrix.
1212 (*this)[0][0] += m[0][0]; (*this)[0][1] += m[0][1]; (*this)[0][2] += m[0][2];
1213 (*this)[1][0] += m[1][0]; (*this)[1][1] += m[1][1]; (*this)[1][2] += m[1][2];
1214 (*this)[2][0] += m[2][0]; (*this)[2][1] += m[2][1]; (*this)[2][2] += m[2][2];
1215 return *this;
1216 }
1217
1218 /// @brief returns transpose of this
1220 return Mat3((*this)[0][0], (*this)[1][0], (*this)[2][0],
1221 (*this)[0][1], (*this)[1][1], (*this)[2][1],
1222 (*this)[0][2], (*this)[1][2], (*this)[2][2]);
1223 }
1224};
1225
1226template <typename T>
1227class Mat4 : public MatBase<T, 4, 4> {
1228 using Base = MatBase<T, 4, 4>;
1229public:
1230 Mat4() = default;
1231
1232 /// @brief Constructor given individual array elements, the ordering is in row major form:
1233 /** @verbatim
1234 a b c d
1235 e f g h
1236 i j k l
1237 m n o p
1238 @endverbatim */
1239 template<typename Source>
1240 __hostdev__ Mat4(Source a, Source b, Source c, Source d,
1241 Source e, Source f, Source g, Source h,
1242 Source i, Source j, Source k, Source l,
1243 Source m, Source n, Source o, Source p)
1244 {
1245 this->mData[0] = a; this->mData[1] = b; this->mData[2] = c; this->mData[3] = d;
1246 this->mData[4] = e; this->mData[5] = f; this->mData[6] = g; this->mData[7] = h;
1247 this->mData[8] = i; this->mData[9] = j; this->mData[10] = k; this->mData[11] = l;
1248 this->mData[12] = m; this->mData[13] = n; this->mData[14] = o; this->mData[15] = p;
1249 }
1250
1251 /// @brief Constructor given array of elements, the ordering is in row major form
1252 template<typename Source>
1253 __hostdev__ Mat4(Source *a): Base(a) {}
1254
1255 /// @brief returns transpose of this
1257 return Mat4((*this)[0][0], (*this)[1][0], (*this)[2][0], (*this)[3][0],
1258 (*this)[0][1], (*this)[1][1], (*this)[2][1], (*this)[3][1],
1259 (*this)[0][2], (*this)[1][2], (*this)[2][2], (*this)[3][2],
1260 (*this)[0][3], (*this)[1][3], (*this)[2][3], (*this)[3][3]);
1261 }
1262};
1263
1264/// @brief Multiply a scalar by a 2x2 matrix, result is a 2x2 matrix
1265template<typename T>
1266__hostdev__ Mat2<T> operator*(const T& s, const Mat2<T>& m) {
1267 return Mat2<T>(m[0][0] * s, m[0][1] * s, m[1][0] * s, m[1][1] * s);
1268}
1269
1270/// @brief Multiply a 2x3 matrix by a 3x2 matrix, result is a 2x2 matrix
1271template<typename T>
1273 return Mat2<T>(
1274 // First row
1275 lhs[0][0] * rhs[0][0] + lhs[0][1] * rhs[1][0] + lhs[0][2] * rhs[2][0], // [0][0]
1276 lhs[0][0] * rhs[0][1] + lhs[0][1] * rhs[1][1] + lhs[0][2] * rhs[2][1], // [0][1]
1277
1278 // Second row
1279 lhs[1][0] * rhs[0][0] + lhs[1][1] * rhs[1][0] + lhs[1][2] * rhs[2][0], // [1][0]
1280 lhs[1][0] * rhs[0][1] + lhs[1][1] * rhs[1][1] + lhs[1][2] * rhs[2][1] // [1][1]
1281 );
1282}
1283/// @brief Multiply a 3x3 matrix by a 2x3 matrix, result is a 2x3 matrix
1284template<typename T>
1286 return Mat2x3<T>(
1287 // First row
1288 lhs[0][0] * rhs[0][0] + lhs[0][1] * rhs[1][0],
1289 lhs[0][0] * rhs[0][1] + lhs[0][1] * rhs[1][1],
1290 lhs[0][0] * rhs[0][2] + lhs[0][1] * rhs[1][2],
1291
1292 // Second row
1293 lhs[1][0] * rhs[0][0] + lhs[1][1] * rhs[1][0],
1294 lhs[1][0] * rhs[0][1] + lhs[1][1] * rhs[1][1],
1295 lhs[1][0] * rhs[0][2] + lhs[1][1] * rhs[1][2]
1296 );
1297}
1298/// @brief Multiply a 2x3 matrix by a 3x3 matrix, result is a 2x3 matrix
1299template<typename T>
1301 return Mat2x3<T>(
1302 // First row (3 elements)
1303 lhs[0][0] * rhs[0][0] + lhs[0][1] * rhs[1][0] + lhs[0][2] * rhs[2][0],
1304 lhs[0][0] * rhs[0][1] + lhs[0][1] * rhs[1][1] + lhs[0][2] * rhs[2][1],
1305 lhs[0][0] * rhs[0][2] + lhs[0][1] * rhs[1][2] + lhs[0][2] * rhs[2][2],
1306
1307 // Second row (3 elements)
1308 lhs[1][0] * rhs[0][0] + lhs[1][1] * rhs[1][0] + lhs[1][2] * rhs[2][0],
1309 lhs[1][0] * rhs[0][1] + lhs[1][1] * rhs[1][1] + lhs[1][2] * rhs[2][1],
1310 lhs[1][0] * rhs[0][2] + lhs[1][1] * rhs[1][2] + lhs[1][2] * rhs[2][2]
1311 );
1312}
1313/// @brief Multiply a 3x2 matrix by a 2x2 matrix, result is a 3x2 matrix
1314template<typename T>
1316 return Mat3x2<T>(
1317 lhs[0][0] * rhs[0][0] + lhs[0][1] * rhs[1][0],
1318 lhs[0][0] * rhs[0][1] + lhs[0][1] * rhs[1][1],
1319 lhs[1][0] * rhs[0][0] + lhs[1][1] * rhs[1][0],
1320 lhs[1][0] * rhs[0][1] + lhs[1][1] * rhs[1][1],
1321 lhs[2][0] * rhs[0][0] + lhs[2][1] * rhs[1][0],
1322 lhs[2][0] * rhs[0][1] + lhs[2][1] * rhs[1][1]
1323 );
1324}
1325/// @brief Multiply a 2x2 matrix by a 2x3 matrix, result is a 2x3 matrix
1326template<typename T>
1328 return Mat2x3<T>(
1329 // First row (3 elements)
1330 lhs[0][0] * rhs[0][0] + lhs[0][1] * rhs[1][0],
1331 lhs[0][0] * rhs[0][1] + lhs[0][1] * rhs[1][1],
1332 lhs[0][0] * rhs[0][2] + lhs[0][1] * rhs[1][2],
1333
1334 // Second row (3 elements)
1335 lhs[1][0] * rhs[0][0] + lhs[1][1] * rhs[1][0],
1336 lhs[1][0] * rhs[0][1] + lhs[1][1] * rhs[1][1],
1337 lhs[1][0] * rhs[0][2] + lhs[1][1] * rhs[1][2]
1338 );
1339}
1340/// @brief Multiply a 3x2 matrix by a 2x3 matrix, result is a 3x3 matrix
1341template<typename T>
1343 return Mat3<T>(
1344 lhs[0][0] * rhs[0][0] + lhs[0][1] * rhs[1][0],
1345 lhs[0][0] * rhs[0][1] + lhs[0][1] * rhs[1][1],
1346 lhs[0][0] * rhs[0][2] + lhs[0][1] * rhs[1][2],
1347
1348 lhs[1][0] * rhs[0][0] + lhs[1][1] * rhs[1][0],
1349 lhs[1][0] * rhs[0][1] + lhs[1][1] * rhs[1][1],
1350 lhs[1][0] * rhs[0][2] + lhs[1][1] * rhs[1][2],
1351
1352 lhs[2][0] * rhs[0][0] + lhs[2][1] * rhs[1][0],
1353 lhs[2][0] * rhs[0][1] + lhs[2][1] * rhs[1][1],
1354 lhs[2][0] * rhs[0][2] + lhs[2][1] * rhs[1][2]
1355 );
1356}
1357// ----------------------------> Vec3 <--------------------------------------
1358
1359/// @brief A simple vector class with three components, similar to openvdb::math::Vec3
1360template<typename T>
1361class Vec3
1362{
1363 T mVec[3];
1364
1365public:
1366 static const int SIZE = 3;
1367 static const int size = 3; // in openvdb::math::Tuple
1368 using ValueType = T;
1369 Vec3() = default;
1370 __hostdev__ explicit Vec3(T x)
1371 : mVec{x, x, x}
1372 {
1373 }
1374 __hostdev__ Vec3(T x, T y, T z)
1375 : mVec{x, y, z}
1376 {
1377 }
1378 template<template<class> class Vec3T, class T2>
1379 __hostdev__ Vec3(const Vec3T<T2>& v)
1380 : mVec{T(v[0]), T(v[1]), T(v[2])}
1381 {
1382 static_assert(Vec3T<T2>::size == size, "expected Vec3T::size==3!");
1383 }
1384 template<typename T2>
1385 __hostdev__ explicit Vec3(const Vec3<T2>& v)
1386 : mVec{T(v[0]), T(v[1]), T(v[2])}
1387 {
1388 }
1389 __hostdev__ explicit Vec3(const Coord& ijk)
1390 : mVec{T(ijk[0]), T(ijk[1]), T(ijk[2])}
1391 {
1392 }
1393 __hostdev__ bool operator==(const Vec3& rhs) const { return mVec[0] == rhs[0] && mVec[1] == rhs[1] && mVec[2] == rhs[2]; }
1394 __hostdev__ bool operator!=(const Vec3& rhs) const { return mVec[0] != rhs[0] || mVec[1] != rhs[1] || mVec[2] != rhs[2]; }
1395 template<template<class> class Vec3T, class T2>
1396 __hostdev__ Vec3& operator=(const Vec3T<T2>& rhs)
1397 {
1398 static_assert(Vec3T<T2>::size == size, "expected Vec3T::size==3!");
1399 mVec[0] = rhs[0];
1400 mVec[1] = rhs[1];
1401 mVec[2] = rhs[2];
1402 return *this;
1403 }
1404 __hostdev__ const T& operator[](int i) const { return mVec[i]; }
1405 __hostdev__ T& operator[](int i) { return mVec[i]; }
1406 template<typename Vec3T>
1407 __hostdev__ T dot(const Vec3T& v) const { return mVec[0] * v[0] + mVec[1] * v[1] + mVec[2] * v[2]; }
1408 template<typename Vec3T>
1409 __hostdev__ Vec3 cross(const Vec3T& v) const
1410 {
1411 return Vec3(mVec[1] * v[2] - mVec[2] * v[1],
1412 mVec[2] * v[0] - mVec[0] * v[2],
1413 mVec[0] * v[1] - mVec[1] * v[0]);
1414 }
1415 /// @brief Outer product of a 3x1 vector and a 1x3 vector, result is a 3x3 matrix
1416 template<typename Vec3T>
1417 __hostdev__ Mat3<ValueType> outer(const Vec3T& v) const
1418 {
1419 return Mat3<ValueType>(mVec[0] * v[0], mVec[0] * v[1], mVec[0] * v[2],
1420 mVec[1] * v[0], mVec[1] * v[1], mVec[1] * v[2],
1421 mVec[2] * v[0], mVec[2] * v[1], mVec[2] * v[2]);
1422 }
1424 {
1425 return mVec[0] * mVec[0] + mVec[1] * mVec[1] + mVec[2] * mVec[2]; // 5 flops
1426 }
1427 __hostdev__ T length() const { return Sqrt(this->lengthSqr()); }
1428 __hostdev__ Vec3 operator-() const { return Vec3(-mVec[0], -mVec[1], -mVec[2]); }
1429 __hostdev__ Vec3 operator*(const Vec3& v) const { return Vec3(mVec[0] * v[0], mVec[1] * v[1], mVec[2] * v[2]); }
1430 __hostdev__ Vec3 operator/(const Vec3& v) const { return Vec3(mVec[0] / v[0], mVec[1] / v[1], mVec[2] / v[2]); }
1431 __hostdev__ Vec3 operator+(const Vec3& v) const { return Vec3(mVec[0] + v[0], mVec[1] + v[1], mVec[2] + v[2]); }
1432 __hostdev__ Vec3 operator-(const Vec3& v) const { return Vec3(mVec[0] - v[0], mVec[1] - v[1], mVec[2] - v[2]); }
1433 __hostdev__ Vec3 operator+(const Coord& ijk) const { return Vec3(mVec[0] + ijk[0], mVec[1] + ijk[1], mVec[2] + ijk[2]); }
1434 __hostdev__ Vec3 operator-(const Coord& ijk) const { return Vec3(mVec[0] - ijk[0], mVec[1] - ijk[1], mVec[2] - ijk[2]); }
1435 __hostdev__ Vec3 operator*(const T& s) const { return Vec3(s * mVec[0], s * mVec[1], s * mVec[2]); }
1436 __hostdev__ Vec3 operator/(const T& s) const { return (T(1) / s) * (*this); }
1438 {
1439 mVec[0] += v[0];
1440 mVec[1] += v[1];
1441 mVec[2] += v[2];
1442 return *this;
1443 }
1445 {
1446 mVec[0] += T(ijk[0]);
1447 mVec[1] += T(ijk[1]);
1448 mVec[2] += T(ijk[2]);
1449 return *this;
1450 }
1452 {
1453 mVec[0] -= v[0];
1454 mVec[1] -= v[1];
1455 mVec[2] -= v[2];
1456 return *this;
1457 }
1459 {
1460 mVec[0] -= T(ijk[0]);
1461 mVec[1] -= T(ijk[1]);
1462 mVec[2] -= T(ijk[2]);
1463 return *this;
1464 }
1466 {
1467 mVec[0] *= s;
1468 mVec[1] *= s;
1469 mVec[2] *= s;
1470 return *this;
1471 }
1472 __hostdev__ Vec3& operator/=(const T& s) { return (*this) *= T(1) / s; }
1473 __hostdev__ Vec3& normalize() { return (*this) /= this->length(); }
1474 /// @brief Perform a component-wise minimum with the other Coord.
1476 {
1477 if (other[0] < mVec[0])
1478 mVec[0] = other[0];
1479 if (other[1] < mVec[1])
1480 mVec[1] = other[1];
1481 if (other[2] < mVec[2])
1482 mVec[2] = other[2];
1483 return *this;
1484 }
1485
1486 /// @brief Perform a component-wise maximum with the other Coord.
1488 {
1489 if (other[0] > mVec[0])
1490 mVec[0] = other[0];
1491 if (other[1] > mVec[1])
1492 mVec[1] = other[1];
1493 if (other[2] > mVec[2])
1494 mVec[2] = other[2];
1495 return *this;
1496 }
1497 /// @brief Return the smallest vector component
1499 {
1500 return mVec[0] < mVec[1] ? (mVec[0] < mVec[2] ? mVec[0] : mVec[2]) : (mVec[1] < mVec[2] ? mVec[1] : mVec[2]);
1501 }
1502 /// @brief Return the largest vector component
1504 {
1505 return mVec[0] > mVec[1] ? (mVec[0] > mVec[2] ? mVec[0] : mVec[2]) : (mVec[1] > mVec[2] ? mVec[1] : mVec[2]);
1506 }
1507 /// @brief Round each component if this Vec<T> up to its integer value
1508 /// @return Return an integer Coord
1509 __hostdev__ Coord floor() const { return Coord(Floor(mVec[0]), Floor(mVec[1]), Floor(mVec[2])); }
1510 /// @brief Round each component if this Vec<T> down to its integer value
1511 /// @return Return an integer Coord
1512 __hostdev__ Coord ceil() const { return Coord(Ceil(mVec[0]), Ceil(mVec[1]), Ceil(mVec[2])); }
1513 /// @brief Round each component if this Vec<T> to its closest integer value
1514 /// @return Return an integer Coord
1516 {
1517 if constexpr(util::is_same<T, float>::value) {
1518 return Coord(Floor(mVec[0] + 0.5f), Floor(mVec[1] + 0.5f), Floor(mVec[2] + 0.5f));
1519 } else if constexpr(util::is_same<T, int>::value) {
1520 return Coord(mVec[0], mVec[1], mVec[2]);
1521 } else {
1522 return Coord(Floor(mVec[0] + 0.5), Floor(mVec[1] + 0.5), Floor(mVec[2] + 0.5));
1523 }
1524 }
1525
1526 /// @brief return a non-const raw constant pointer to array of three vector components
1527 __hostdev__ T* asPointer() { return mVec; }
1528 /// @brief return a const raw constant pointer to array of three vector components
1529 __hostdev__ const T* asPointer() const { return mVec; }
1530}; // Vec3<T>
1531
1532template<typename T1, typename T2>
1533__hostdev__ inline Vec3<T2> operator*(T1 scalar, const Vec3<T2>& vec)
1534{
1535 return Vec3<T2>(scalar * vec[0], scalar * vec[1], scalar * vec[2]);
1536}
1537template<typename T1, typename T2>
1538__hostdev__ inline Vec3<T2> operator/(T1 scalar, const Vec3<T2>& vec)
1539{
1540 return Vec3<T2>(scalar / vec[0], scalar / vec[1], scalar / vec[2]);
1541}
1542
1543/// @brief Return a single precision floating-point vector of this coordinate
1545{
1546 return Vec3<float>(float(mVec[0]), float(mVec[1]), float(mVec[2]));
1547}
1548
1549/// @brief Return a double precision floating-point vector of this coordinate
1551{
1552 return Vec3<double>(double(mVec[0]), double(mVec[1]), double(mVec[2]));
1553}
1554
1555// ----------------------------> Vec4 <--------------------------------------
1556
1557/// @brief A simple vector class with four components, similar to openvdb::math::Vec4
1558template<typename T>
1559class Vec4
1560{
1561 T mVec[4];
1562
1563public:
1564 static const int SIZE = 4;
1565 static const int size = 4;
1566 using ValueType = T;
1567 Vec4() = default;
1568 __hostdev__ explicit Vec4(T x)
1569 : mVec{x, x, x, x}
1570 {
1571 }
1572 __hostdev__ Vec4(T x, T y, T z, T w)
1573 : mVec{x, y, z, w}
1574 {
1575 }
1576 template<typename T2>
1577 __hostdev__ explicit Vec4(const Vec4<T2>& v)
1578 : mVec{T(v[0]), T(v[1]), T(v[2]), T(v[3])}
1579 {
1580 }
1581 template<template<class> class Vec4T, class T2>
1582 __hostdev__ Vec4(const Vec4T<T2>& v)
1583 : mVec{T(v[0]), T(v[1]), T(v[2]), T(v[3])}
1584 {
1585 static_assert(Vec4T<T2>::size == size, "expected Vec4T::size==4!");
1586 }
1587 __hostdev__ bool operator==(const Vec4& rhs) const { return mVec[0] == rhs[0] && mVec[1] == rhs[1] && mVec[2] == rhs[2] && mVec[3] == rhs[3]; }
1588 __hostdev__ bool operator!=(const Vec4& rhs) const { return mVec[0] != rhs[0] || mVec[1] != rhs[1] || mVec[2] != rhs[2] || mVec[3] != rhs[3]; }
1589 template<template<class> class Vec4T, class T2>
1590 __hostdev__ Vec4& operator=(const Vec4T<T2>& rhs)
1591 {
1592 static_assert(Vec4T<T2>::size == size, "expected Vec4T::size==4!");
1593 mVec[0] = rhs[0];
1594 mVec[1] = rhs[1];
1595 mVec[2] = rhs[2];
1596 mVec[3] = rhs[3];
1597 return *this;
1598 }
1599
1600 __hostdev__ const T& operator[](int i) const { return mVec[i]; }
1601 __hostdev__ T& operator[](int i) { return mVec[i]; }
1602 template<typename Vec4T>
1603 __hostdev__ T dot(const Vec4T& v) const { return mVec[0] * v[0] + mVec[1] * v[1] + mVec[2] * v[2] + mVec[3] * v[3]; }
1605 {
1606 return mVec[0] * mVec[0] + mVec[1] * mVec[1] + mVec[2] * mVec[2] + mVec[3] * mVec[3]; // 7 flops
1607 }
1608 __hostdev__ T length() const { return Sqrt(this->lengthSqr()); }
1609 __hostdev__ Vec4 operator-() const { return Vec4(-mVec[0], -mVec[1], -mVec[2], -mVec[3]); }
1610 __hostdev__ Vec4 operator*(const Vec4& v) const { return Vec4(mVec[0] * v[0], mVec[1] * v[1], mVec[2] * v[2], mVec[3] * v[3]); }
1611 __hostdev__ Vec4 operator/(const Vec4& v) const { return Vec4(mVec[0] / v[0], mVec[1] / v[1], mVec[2] / v[2], mVec[3] / v[3]); }
1612 __hostdev__ Vec4 operator+(const Vec4& v) const { return Vec4(mVec[0] + v[0], mVec[1] + v[1], mVec[2] + v[2], mVec[3] + v[3]); }
1613 __hostdev__ Vec4 operator-(const Vec4& v) const { return Vec4(mVec[0] - v[0], mVec[1] - v[1], mVec[2] - v[2], mVec[3] - v[3]); }
1614 __hostdev__ Vec4 operator*(const T& s) const { return Vec4(s * mVec[0], s * mVec[1], s * mVec[2], s * mVec[3]); }
1615 __hostdev__ Vec4 operator/(const T& s) const { return (T(1) / s) * (*this); }
1617 {
1618 mVec[0] += v[0];
1619 mVec[1] += v[1];
1620 mVec[2] += v[2];
1621 mVec[3] += v[3];
1622 return *this;
1623 }
1625 {
1626 mVec[0] -= v[0];
1627 mVec[1] -= v[1];
1628 mVec[2] -= v[2];
1629 mVec[3] -= v[3];
1630 return *this;
1631 }
1633 {
1634 mVec[0] *= s;
1635 mVec[1] *= s;
1636 mVec[2] *= s;
1637 mVec[3] *= s;
1638 return *this;
1639 }
1640 __hostdev__ Vec4& operator/=(const T& s) { return (*this) *= T(1) / s; }
1641 __hostdev__ Vec4& normalize() { return (*this) /= this->length(); }
1642 /// @brief Perform a component-wise minimum with the other Coord.
1644 {
1645 if (other[0] < mVec[0])
1646 mVec[0] = other[0];
1647 if (other[1] < mVec[1])
1648 mVec[1] = other[1];
1649 if (other[2] < mVec[2])
1650 mVec[2] = other[2];
1651 if (other[3] < mVec[3])
1652 mVec[3] = other[3];
1653 return *this;
1654 }
1655
1656 /// @brief Perform a component-wise maximum with the other Coord.
1658 {
1659 if (other[0] > mVec[0])
1660 mVec[0] = other[0];
1661 if (other[1] > mVec[1])
1662 mVec[1] = other[1];
1663 if (other[2] > mVec[2])
1664 mVec[2] = other[2];
1665 if (other[3] > mVec[3])
1666 mVec[3] = other[3];
1667 return *this;
1668 }
1669}; // Vec4<T>
1670
1671template<typename T1, typename T2>
1672__hostdev__ inline Vec4<T2> operator*(T1 scalar, const Vec4<T2>& vec)
1673{
1674 return Vec4<T2>(scalar * vec[0], scalar * vec[1], scalar * vec[2], scalar * vec[3]);
1675}
1676template<typename T1, typename T2>
1677__hostdev__ inline Vec4<T2> operator/(T1 scalar, const Vec4<T2>& vec)
1678{
1679 return Vec4<T2>(scalar / vec[0], scalar / vec[1], scalar / vec[2], scalar / vec[3]);
1680}
1681/// @brief Return the matrix vector product of a 4x4 matrix and a 4d vector
1682/// @param m 4x4 matrix
1683/// @param v 4d vector
1684/// @return result of matrix-vector multiplication, i.e. m x v
1685template <typename T>
1686__hostdev__ inline Vec4<T> operator*(const Mat4<T>& m, const Vec4<T>& v) {
1687 return Vec4<T>(
1688 m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2] + m[0][3] * v[3],
1689 m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2] + m[1][3] * v[3],
1690 m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2] + m[2][3] * v[3],
1691 m[3][0] * v[0] + m[3][1] * v[1] + m[3][2] * v[2] + m[3][3] * v[3]
1692 );
1693}
1694
1695// ----------------------------> matMult <--------------------------------------
1696
1697/// @brief Multiply a 3x3 matrix and a 3d vector using 32bit floating point arithmetics
1698/// @note This corresponds to a linear mapping, e.g. scaling, rotation etc.
1699/// @tparam Vec3T Template type of the input and output 3d vectors
1700/// @param mat pointer to an array of floats with the 3x3 matrix
1701/// @param xyz input vector to be multiplied by the matrix
1702/// @return result of matrix-vector multiplication, i.e. mat x xyz
1703template<typename Vec3T>
1704__hostdev__ inline Vec3T matMult(const float* mat, const Vec3T& xyz)
1705{
1706 return Vec3T(fmaf(static_cast<float>(xyz[0]), mat[0], fmaf(static_cast<float>(xyz[1]), mat[1], static_cast<float>(xyz[2]) * mat[2])),
1707 fmaf(static_cast<float>(xyz[0]), mat[3], fmaf(static_cast<float>(xyz[1]), mat[4], static_cast<float>(xyz[2]) * mat[5])),
1708 fmaf(static_cast<float>(xyz[0]), mat[6], fmaf(static_cast<float>(xyz[1]), mat[7], static_cast<float>(xyz[2]) * mat[8]))); // 6 fmaf + 3 mult = 9 flops
1709}
1710
1711/// @brief Multiply a 3x3 matrix and a 3d vector using 64bit floating point arithmetics
1712/// @note This corresponds to a linear mapping, e.g. scaling, rotation etc.
1713/// @tparam Vec3T Template type of the input and output 3d vectors
1714/// @param mat pointer to an array of floats with the 3x3 matrix
1715/// @param xyz input vector to be multiplied by the matrix
1716/// @return result of matrix-vector multiplication, i.e. mat x xyz
1717template<typename Vec3T>
1718__hostdev__ inline Vec3T matMult(const double* mat, const Vec3T& xyz)
1719{
1720 return Vec3T(fma(static_cast<double>(xyz[0]), mat[0], fma(static_cast<double>(xyz[1]), mat[1], static_cast<double>(xyz[2]) * mat[2])),
1721 fma(static_cast<double>(xyz[0]), mat[3], fma(static_cast<double>(xyz[1]), mat[4], static_cast<double>(xyz[2]) * mat[5])),
1722 fma(static_cast<double>(xyz[0]), mat[6], fma(static_cast<double>(xyz[1]), mat[7], static_cast<double>(xyz[2]) * mat[8]))); // 6 fmaf + 3 mult = 9 flops
1723}
1724
1725/// @brief Multiply a 3x3 matrix to a 3d vector and add another 3d vector using 32bit floating point arithmetics
1726/// @note This corresponds to an affine transformation, i.e a linear mapping followed by a translation. e.g. scale/rotation and translation
1727/// @tparam Vec3T Template type of the input and output 3d vectors
1728/// @param mat pointer to an array of floats with the 3x3 matrix
1729/// @param vec 3d vector to be added AFTER the matrix multiplication
1730/// @param xyz input vector to be multiplied by the matrix and a translated by @c vec
1731/// @return result of affine transformation, i.e. (mat x xyz) + vec
1732template<typename Vec3T>
1733__hostdev__ inline Vec3T matMult(const float* mat, const float* vec, const Vec3T& xyz)
1734{
1735 return Vec3T(fmaf(static_cast<float>(xyz[0]), mat[0], fmaf(static_cast<float>(xyz[1]), mat[1], fmaf(static_cast<float>(xyz[2]), mat[2], vec[0]))),
1736 fmaf(static_cast<float>(xyz[0]), mat[3], fmaf(static_cast<float>(xyz[1]), mat[4], fmaf(static_cast<float>(xyz[2]), mat[5], vec[1]))),
1737 fmaf(static_cast<float>(xyz[0]), mat[6], fmaf(static_cast<float>(xyz[1]), mat[7], fmaf(static_cast<float>(xyz[2]), mat[8], vec[2])))); // 9 fmaf = 9 flops
1738}
1739
1740/// @brief Multiply a 3x3 matrix to a 3d vector and add another 3d vector using 64bit floating point arithmetics
1741/// @note This corresponds to an affine transformation, i.e a linear mapping followed by a translation. e.g. scale/rotation and translation
1742/// @tparam Vec3T Template type of the input and output 3d vectors
1743/// @param mat pointer to an array of floats with the 3x3 matrix
1744/// @param vec 3d vector to be added AFTER the matrix multiplication
1745/// @param xyz input vector to be multiplied by the matrix and a translated by @c vec
1746/// @return result of affine transformation, i.e. (mat x xyz) + vec
1747template<typename Vec3T>
1748__hostdev__ inline Vec3T matMult(const double* mat, const double* vec, const Vec3T& xyz)
1749{
1750 return Vec3T(fma(static_cast<double>(xyz[0]), mat[0], fma(static_cast<double>(xyz[1]), mat[1], fma(static_cast<double>(xyz[2]), mat[2], vec[0]))),
1751 fma(static_cast<double>(xyz[0]), mat[3], fma(static_cast<double>(xyz[1]), mat[4], fma(static_cast<double>(xyz[2]), mat[5], vec[1]))),
1752 fma(static_cast<double>(xyz[0]), mat[6], fma(static_cast<double>(xyz[1]), mat[7], fma(static_cast<double>(xyz[2]), mat[8], vec[2])))); // 9 fma = 9 flops
1753}
1754
1755/// @brief Multiply the transposed of a 3x3 matrix and a 3d vector using 32bit floating point arithmetics
1756/// @note This corresponds to an inverse linear mapping, e.g. inverse scaling, inverse rotation etc.
1757/// @tparam Vec3T Template type of the input and output 3d vectors
1758/// @param mat pointer to an array of floats with the 3x3 matrix
1759/// @param xyz input vector to be multiplied by the transposed matrix
1760/// @return result of matrix-vector multiplication, i.e. mat^T x xyz
1761template<typename Vec3T>
1762__hostdev__ inline Vec3T matMultT(const float* mat, const Vec3T& xyz)
1763{
1764 return Vec3T(fmaf(static_cast<float>(xyz[0]), mat[0], fmaf(static_cast<float>(xyz[1]), mat[3], static_cast<float>(xyz[2]) * mat[6])),
1765 fmaf(static_cast<float>(xyz[0]), mat[1], fmaf(static_cast<float>(xyz[1]), mat[4], static_cast<float>(xyz[2]) * mat[7])),
1766 fmaf(static_cast<float>(xyz[0]), mat[2], fmaf(static_cast<float>(xyz[1]), mat[5], static_cast<float>(xyz[2]) * mat[8]))); // 6 fmaf + 3 mult = 9 flops
1767}
1768
1769/// @brief Multiply the transposed of a 3x3 matrix and a 3d vector using 64bit floating point arithmetics
1770/// @note This corresponds to an inverse linear mapping, e.g. inverse scaling, inverse rotation etc.
1771/// @tparam Vec3T Template type of the input and output 3d vectors
1772/// @param mat pointer to an array of floats with the 3x3 matrix
1773/// @param xyz input vector to be multiplied by the transposed matrix
1774/// @return result of matrix-vector multiplication, i.e. mat^T x xyz
1775template<typename Vec3T>
1776__hostdev__ inline Vec3T matMultT(const double* mat, const Vec3T& xyz)
1777{
1778 return Vec3T(fma(static_cast<double>(xyz[0]), mat[0], fma(static_cast<double>(xyz[1]), mat[3], static_cast<double>(xyz[2]) * mat[6])),
1779 fma(static_cast<double>(xyz[0]), mat[1], fma(static_cast<double>(xyz[1]), mat[4], static_cast<double>(xyz[2]) * mat[7])),
1780 fma(static_cast<double>(xyz[0]), mat[2], fma(static_cast<double>(xyz[1]), mat[5], static_cast<double>(xyz[2]) * mat[8]))); // 6 fmaf + 3 mult = 9 flops
1781}
1782
1783template<typename Vec3T>
1784__hostdev__ inline Vec3T matMultT(const float* mat, const float* vec, const Vec3T& xyz)
1785{
1786 return Vec3T(fmaf(static_cast<float>(xyz[0]), mat[0], fmaf(static_cast<float>(xyz[1]), mat[3], fmaf(static_cast<float>(xyz[2]), mat[6], vec[0]))),
1787 fmaf(static_cast<float>(xyz[0]), mat[1], fmaf(static_cast<float>(xyz[1]), mat[4], fmaf(static_cast<float>(xyz[2]), mat[7], vec[1]))),
1788 fmaf(static_cast<float>(xyz[0]), mat[2], fmaf(static_cast<float>(xyz[1]), mat[5], fmaf(static_cast<float>(xyz[2]), mat[8], vec[2])))); // 9 fmaf = 9 flops
1789}
1790
1791template<typename Vec3T>
1792__hostdev__ inline Vec3T matMultT(const double* mat, const double* vec, const Vec3T& xyz)
1793{
1794 return Vec3T(fma(static_cast<double>(xyz[0]), mat[0], fma(static_cast<double>(xyz[1]), mat[3], fma(static_cast<double>(xyz[2]), mat[6], vec[0]))),
1795 fma(static_cast<double>(xyz[0]), mat[1], fma(static_cast<double>(xyz[1]), mat[4], fma(static_cast<double>(xyz[2]), mat[7], vec[1]))),
1796 fma(static_cast<double>(xyz[0]), mat[2], fma(static_cast<double>(xyz[1]), mat[5], fma(static_cast<double>(xyz[2]), mat[8], vec[2])))); // 9 fma = 9 flops
1797}
1798
1799// ----------------------------> BBox <-------------------------------------
1800
1801// Base-class for static polymorphism (cannot be constructed directly)
1802template<typename Vec3T>
1804{
1805 Vec3T mCoord[2];
1806 __hostdev__ bool operator==(const BaseBBox& rhs) const { return mCoord[0] == rhs.mCoord[0] && mCoord[1] == rhs.mCoord[1]; };
1807 __hostdev__ bool operator!=(const BaseBBox& rhs) const { return mCoord[0] != rhs.mCoord[0] || mCoord[1] != rhs.mCoord[1]; };
1808 __hostdev__ const Vec3T& operator[](int i) const { return mCoord[i]; }
1809 __hostdev__ Vec3T& operator[](int i) { return mCoord[i]; }
1810 __hostdev__ Vec3T& min() { return mCoord[0]; }
1811 __hostdev__ Vec3T& max() { return mCoord[1]; }
1812 __hostdev__ const Vec3T& min() const { return mCoord[0]; }
1813 __hostdev__ const Vec3T& max() const { return mCoord[1]; }
1814 __hostdev__ BaseBBox& translate(const Vec3T& xyz)
1815 {
1816 mCoord[0] += xyz;
1817 mCoord[1] += xyz;
1818 return *this;
1819 }
1820 /// @brief Expand this bounding box to enclose point @c xyz.
1821 __hostdev__ BaseBBox& expand(const Vec3T& xyz)
1822 {
1823 mCoord[0].minComponent(xyz);
1824 mCoord[1].maxComponent(xyz);
1825 return *this;
1826 }
1827
1828 /// @brief Expand this bounding box to enclose the given bounding box.
1830 {
1831 mCoord[0].minComponent(bbox[0]);
1832 mCoord[1].maxComponent(bbox[1]);
1833 return *this;
1834 }
1835
1836 /// @brief Intersect this bounding box with the given bounding box.
1838 {
1839 mCoord[0].maxComponent(bbox[0]);
1840 mCoord[1].minComponent(bbox[1]);
1841 return *this;
1842 }
1843
1844// __hostdev__ BaseBBox expandBy(typename Vec3T::ValueType padding) const
1845// {
1846// return BaseBBox(mCoord[0].offsetBy(-padding),mCoord[1].offsetBy(padding));
1847// }
1848 __hostdev__ bool isInside(const Vec3T& xyz)
1849 {
1850 if (xyz[0] < mCoord[0][0] || xyz[1] < mCoord[0][1] || xyz[2] < mCoord[0][2])
1851 return false;
1852 if (xyz[0] > mCoord[1][0] || xyz[1] > mCoord[1][1] || xyz[2] > mCoord[1][2])
1853 return false;
1854 return true;
1855 }
1856
1857protected:
1859 __hostdev__ BaseBBox(const Vec3T& min, const Vec3T& max)
1860 : mCoord{min, max}
1861 {
1862 }
1863}; // BaseBBox
1864
1865template<typename Vec3T, bool = util::is_floating_point<typename Vec3T::ValueType>::value>
1866struct BBox;
1867
1868/// @brief Partial template specialization for floating point coordinate types.
1869///
1870/// @note Min is inclusive and max is exclusive. If min = max the dimension of
1871/// the bounding box is zero and therefore it is also empty.
1872template<typename Vec3T>
1873struct BBox<Vec3T, true> : public BaseBBox<Vec3T>
1874{
1875 using Vec3Type = Vec3T;
1876 using ValueType = typename Vec3T::ValueType;
1877 static_assert(util::is_floating_point<ValueType>::value, "Expected a floating point coordinate type");
1879 using BaseT::mCoord;
1880 /// @brief Default construction sets BBox to an empty bbox
1882 : BaseT(Vec3T( Maximum<typename Vec3T::ValueType>::value()),
1883 Vec3T(-Maximum<typename Vec3T::ValueType>::value()))
1884 {
1885 }
1886 __hostdev__ BBox(const Vec3T& min, const Vec3T& max)
1887 : BaseT(min, max)
1888 {
1889 }
1891 : BaseT(Vec3T(ValueType(min[0]), ValueType(min[1]), ValueType(min[2])),
1892 Vec3T(ValueType(max[0] + 1), ValueType(max[1] + 1), ValueType(max[2] + 1)))
1893 {
1894 }
1896 {
1897 return BBox(min, min.offsetBy(dim));
1898 }
1899
1901 : BBox(bbox[0], bbox[1])
1902 {
1903 }
1904 __hostdev__ bool empty() const { return mCoord[0][0] >= mCoord[1][0] ||
1905 mCoord[0][1] >= mCoord[1][1] ||
1906 mCoord[0][2] >= mCoord[1][2]; }
1907 __hostdev__ operator bool() const { return mCoord[0][0] < mCoord[1][0] &&
1908 mCoord[0][1] < mCoord[1][1] &&
1909 mCoord[0][2] < mCoord[1][2]; }
1910 __hostdev__ Vec3T dim() const { return *this ? this->max() - this->min() : Vec3T(0); }
1911 __hostdev__ bool isInside(const Vec3T& p) const
1912 {
1913 return p[0] > mCoord[0][0] && p[1] > mCoord[0][1] && p[2] > mCoord[0][2] &&
1914 p[0] < mCoord[1][0] && p[1] < mCoord[1][1] && p[2] < mCoord[1][2];
1915 }
1916
1917}; // BBox<Vec3T, true>
1918
1919/// @brief Partial template specialization for integer coordinate types
1920///
1921/// @note Both min and max are INCLUDED in the bbox so dim = max - min + 1. So,
1922/// if min = max the bounding box contains exactly one point and dim = 1!
1923template<typename CoordT>
1924struct BBox<CoordT, false> : public BaseBBox<CoordT>
1925{
1926 static_assert(util::is_same<int, typename CoordT::ValueType>::value, "Expected \"int\" coordinate type");
1928 using BaseT::mCoord;
1929 /// @brief Iterator over the domain covered by a BBox
1930 /// @details z is the fastest-moving coordinate.
1932 {
1933 const BBox& mBBox;
1934 CoordT mPos;
1935
1936 public:
1938 : mBBox(b)
1939 , mPos(b.min())
1940 {
1941 }
1942 __hostdev__ Iterator(const BBox& b, const Coord& p)
1943 : mBBox(b)
1944 , mPos(p)
1945 {
1946 }
1948 {
1949 if (mPos[2] < mBBox[1][2]) { // this is the most common case
1950 ++mPos[2];// increment z
1951 } else if (mPos[1] < mBBox[1][1]) {
1952 mPos[2] = mBBox[0][2];// reset z
1953 ++mPos[1];// increment y
1954 } else if (mPos[0] <= mBBox[1][0]) {
1955 mPos[2] = mBBox[0][2];// reset z
1956 mPos[1] = mBBox[0][1];// reset y
1957 ++mPos[0];// increment x
1958 }
1959 return *this;
1960 }
1962 {
1963 auto tmp = *this;
1964 ++(*this);
1965 return tmp;
1966 }
1967 __hostdev__ bool operator==(const Iterator& rhs) const
1968 {
1969 NANOVDB_ASSERT(mBBox == rhs.mBBox);
1970 return mPos == rhs.mPos;
1971 }
1972 __hostdev__ bool operator!=(const Iterator& rhs) const
1973 {
1974 NANOVDB_ASSERT(mBBox == rhs.mBBox);
1975 return mPos != rhs.mPos;
1976 }
1977 __hostdev__ bool operator<(const Iterator& rhs) const
1978 {
1979 NANOVDB_ASSERT(mBBox == rhs.mBBox);
1980 return mPos < rhs.mPos;
1981 }
1982 __hostdev__ bool operator<=(const Iterator& rhs) const
1983 {
1984 NANOVDB_ASSERT(mBBox == rhs.mBBox);
1985 return mPos <= rhs.mPos;
1986 }
1987 /// @brief Return @c true if the iterator still points to a valid coordinate.
1988 __hostdev__ operator bool() const { return mPos <= mBBox[1]; }
1989 __hostdev__ const CoordT& operator*() const { return mPos; }
1990 }; // Iterator
1991 __hostdev__ Iterator begin() const { return Iterator{*this}; }
1992 __hostdev__ Iterator end() const { return Iterator{*this, CoordT(mCoord[1][0]+1, mCoord[0][1], mCoord[0][2])}; }
1994 : BaseT(CoordT::max(), CoordT::min())
1995 {
1996 }
1997 __hostdev__ BBox(const CoordT& min, const CoordT& max)
1998 : BaseT(min, max)
1999 {
2000 }
2001
2002 template<typename SplitT>
2003 __hostdev__ BBox(BBox& other, const SplitT&)
2004 : BaseT(other.mCoord[0], other.mCoord[1])
2005 {
2007 const int n = MaxIndex(this->dim());
2008 mCoord[1][n] = (mCoord[0][n] + mCoord[1][n]) >> 1;
2009 other.mCoord[0][n] = mCoord[1][n] + 1;
2010 }
2011
2012 __hostdev__ static BBox createCube(const CoordT& min, typename CoordT::ValueType dim)
2013 {
2014 return BBox(min, min.offsetBy(dim - 1));
2015 }
2016
2017 __hostdev__ static BBox createCube(typename CoordT::ValueType min, typename CoordT::ValueType max)
2018 {
2019 return BBox(CoordT(min), CoordT(max));
2020 }
2021
2022 __hostdev__ bool is_divisible() const { return mCoord[0][0] < mCoord[1][0] &&
2023 mCoord[0][1] < mCoord[1][1] &&
2024 mCoord[0][2] < mCoord[1][2]; }
2025 /// @brief Return true if this bounding box is empty, e.g. uninitialized
2026 __hostdev__ bool empty() const { return mCoord[0][0] > mCoord[1][0] ||
2027 mCoord[0][1] > mCoord[1][1] ||
2028 mCoord[0][2] > mCoord[1][2]; }
2029 /// @brief Convert this BBox to boolean true if it is not empty
2030 __hostdev__ operator bool() const { return mCoord[0][0] <= mCoord[1][0] &&
2031 mCoord[0][1] <= mCoord[1][1] &&
2032 mCoord[0][2] <= mCoord[1][2]; }
2033 __hostdev__ CoordT dim() const { return *this ? this->max() - this->min() + Coord(1) : Coord(0); }
2034 __hostdev__ uint64_t volume() const
2035 {
2036 auto d = this->dim();
2037 return uint64_t(d[0]) * uint64_t(d[1]) * uint64_t(d[2]);
2038 }
2039 __hostdev__ bool isInside(const CoordT& p) const { return !(CoordT::lessThan(p, this->min()) || CoordT::lessThan(this->max(), p)); }
2040 /// @brief Return @c true if the given bounding box is inside this bounding box.
2041 __hostdev__ bool isInside(const BBox& b) const
2042 {
2043 return !(CoordT::lessThan(b.min(), this->min()) || CoordT::lessThan(this->max(), b.max()));
2044 }
2045
2046 /// @brief Return @c true if the given bounding box overlaps with this bounding box.
2047 __hostdev__ bool hasOverlap(const BBox& b) const
2048 {
2049 return !(CoordT::lessThan(this->max(), b.min()) || CoordT::lessThan(b.max(), this->min()));
2050 }
2051
2052 /// @warning This converts a CoordBBox into a floating-point bounding box which implies that max += 1 !
2053 template<typename RealT = double>
2055 {
2056 static_assert(util::is_floating_point<RealT>::value, "CoordBBox::asReal: Expected a floating point coordinate");
2057 return BBox<Vec3<RealT>>(Vec3<RealT>(RealT(mCoord[0][0]), RealT(mCoord[0][1]), RealT(mCoord[0][2])),
2058 Vec3<RealT>(RealT(mCoord[1][0] + 1), RealT(mCoord[1][1] + 1), RealT(mCoord[1][2] + 1)));
2059 }
2060 /// @brief Return a new instance that is expanded by the specified padding.
2061 __hostdev__ BBox expandBy(typename CoordT::ValueType padding) const
2062 {
2063 return BBox(mCoord[0].offsetBy(-padding), mCoord[1].offsetBy(padding));
2064 }
2065
2066 /// @brief @brief transform this coordinate bounding box by the specified map
2067 /// @param map mapping of index to world coordinates
2068 /// @return world bounding box
2069 template<typename Map>
2070 __hostdev__ auto transform(const Map& map) const
2071 {
2072 using Vec3T = Vec3<double>;
2073 const Vec3T tmp = map.applyMap(Vec3T(mCoord[0][0], mCoord[0][1], mCoord[0][2]));
2074 BBox<Vec3T> bbox(tmp, tmp);// return value
2075 bbox.expand(map.applyMap(Vec3T(mCoord[0][0], mCoord[0][1], mCoord[1][2])));
2076 bbox.expand(map.applyMap(Vec3T(mCoord[0][0], mCoord[1][1], mCoord[0][2])));
2077 bbox.expand(map.applyMap(Vec3T(mCoord[1][0], mCoord[0][1], mCoord[0][2])));
2078 bbox.expand(map.applyMap(Vec3T(mCoord[1][0], mCoord[1][1], mCoord[0][2])));
2079 bbox.expand(map.applyMap(Vec3T(mCoord[1][0], mCoord[0][1], mCoord[1][2])));
2080 bbox.expand(map.applyMap(Vec3T(mCoord[0][0], mCoord[1][1], mCoord[1][2])));
2081 bbox.expand(map.applyMap(Vec3T(mCoord[1][0], mCoord[1][1], mCoord[1][2])));
2082 return bbox;
2083 }
2084
2085#if defined(__CUDACC__) // the following functions only run on the GPU!
2086 __device__ inline BBox& expandAtomic(const CoordT& ijk)
2087 {
2088 mCoord[0].minComponentAtomic(ijk);
2089 mCoord[1].maxComponentAtomic(ijk);
2090 return *this;
2091 }
2092 __device__ inline BBox& expandAtomic(const BBox& bbox)
2093 {
2094 mCoord[0].minComponentAtomic(bbox[0]);
2095 mCoord[1].maxComponentAtomic(bbox[1]);
2096 return *this;
2097 }
2098 __device__ inline BBox& intersectAtomic(const BBox& bbox)
2099 {
2100 mCoord[0].maxComponentAtomic(bbox[0]);
2101 mCoord[1].minComponentAtomic(bbox[1]);
2102 return *this;
2103 }
2104#endif
2105}; // BBox<CoordT, false>
2106
2107// --------------------------> Rgba8 <------------------------------------
2108
2109/// @brief 8-bit red, green, blue, alpha packed into 32 bit unsigned int
2111{
2112 union
2113 {
2114 uint8_t c[4]; // 4 integer color channels of red, green, blue and alpha components.
2115 uint32_t packed; // 32 bit packed representation
2116 } mData;
2117
2118public:
2119 static const int SIZE = 4;
2120 using ValueType = uint8_t;
2121
2122 /// @brief Default copy constructor
2123 Rgba8(const Rgba8&) = default;
2124
2125 /// @brief Default move constructor
2126 Rgba8(Rgba8&&) = default;
2127
2128 /// @brief Default move assignment operator
2129 /// @return non-const reference to this instance
2130 Rgba8& operator=(Rgba8&&) = default;
2131
2132 /// @brief Default copy assignment operator
2133 /// @return non-const reference to this instance
2134 Rgba8& operator=(const Rgba8&) = default;
2135
2136 /// @brief Default ctor initializes all channels to zero
2138 : mData{{0, 0, 0, 0}}
2139 {
2140 static_assert(sizeof(uint32_t) == sizeof(Rgba8), "Unexpected sizeof");
2141 }
2142
2143 /// @brief integer r,g,b,a ctor where alpha channel defaults to opaque
2144 /// @note all values should be in the range 0u to 255u
2145 __hostdev__ Rgba8(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255u)
2146 : mData{{r, g, b, a}}
2147 {
2148 }
2149
2150 /// @brief @brief ctor where all channels are initialized to the same value
2151 /// @note value should be in the range 0u to 255u
2152 explicit __hostdev__ Rgba8(uint8_t v)
2153 : mData{{v, v, v, v}}
2154 {
2155 }
2156
2157 /// @brief floating-point r,g,b,a ctor where alpha channel defaults to opaque
2158 /// @note all values should be in the range 0.0f to 1.0f
2159 __hostdev__ Rgba8(float r, float g, float b, float a = 1.0f)
2160 : mData{{static_cast<uint8_t>(0.5f + r * 255.0f), // round floats to nearest integers
2161 static_cast<uint8_t>(0.5f + g * 255.0f), // double {{}} is needed due to union
2162 static_cast<uint8_t>(0.5f + b * 255.0f),
2163 static_cast<uint8_t>(0.5f + a * 255.0f)}}
2164 {
2165 }
2166
2167 /// @brief Vec3f r,g,b ctor (alpha channel it set to 1)
2168 /// @note all values should be in the range 0.0f to 1.0f
2170 : Rgba8(rgb[0], rgb[1], rgb[2])
2171 {
2172 }
2173
2174 /// @brief Vec4f r,g,b,a ctor
2175 /// @note all values should be in the range 0.0f to 1.0f
2177 : Rgba8(rgba[0], rgba[1], rgba[2], rgba[3])
2178 {
2179 }
2180
2181 __hostdev__ bool operator< (const Rgba8& rhs) const { return mData.packed < rhs.mData.packed; }
2182 __hostdev__ bool operator==(const Rgba8& rhs) const { return mData.packed == rhs.mData.packed; }
2184 {
2185 return 0.0000153787005f * (float(mData.c[0]) * mData.c[0] +
2186 float(mData.c[1]) * mData.c[1] +
2187 float(mData.c[2]) * mData.c[2]); //1/255^2
2188 }
2189 __hostdev__ float length() const { return sqrtf(this->lengthSqr()); }
2190 /// @brief return n'th color channel as a float in the range 0 to 1
2191 __hostdev__ float asFloat(int n) const { return 0.003921569f*float(mData.c[n]); }// divide by 255
2192 __hostdev__ const uint8_t& operator[](int n) const { return mData.c[n]; }
2193 __hostdev__ uint8_t& operator[](int n) { return mData.c[n]; }
2194 __hostdev__ const uint32_t& packed() const { return mData.packed; }
2195 __hostdev__ uint32_t& packed() { return mData.packed; }
2196 __hostdev__ const uint8_t& r() const { return mData.c[0]; }
2197 __hostdev__ const uint8_t& g() const { return mData.c[1]; }
2198 __hostdev__ const uint8_t& b() const { return mData.c[2]; }
2199 __hostdev__ const uint8_t& a() const { return mData.c[3]; }
2200 __hostdev__ uint8_t& r() { return mData.c[0]; }
2201 __hostdev__ uint8_t& g() { return mData.c[1]; }
2202 __hostdev__ uint8_t& b() { return mData.c[2]; }
2203 __hostdev__ uint8_t& a() { return mData.c[3]; }
2204 __hostdev__ operator Vec3<float>() const {
2205 return Vec3<float>(this->asFloat(0), this->asFloat(1), this->asFloat(2));
2206 }
2207 __hostdev__ operator Vec4<float>() const {
2208 return Vec4<float>(this->asFloat(0), this->asFloat(1), this->asFloat(2), this->asFloat(3));
2209 }
2210}; // Rgba8
2211
2218
2223
2224}// namespace math ===============================================================
2225
2226using Rgba8 [[deprecated("Use math::Rgba8 instead.")]] = math::Rgba8;
2227using math::Coord;
2228
2235
2240
2243using BBoxR [[deprecated("Use Vec3dBBox instead.")]] = math::BBox<Vec3d>;
2244
2245} // namespace nanovdb ===================================================================
2246
2247#endif // end of NANOVDB_MATH_MATH_H_HAS_BEEN_INCLUDED
__hostdev__ Coord()
Initialize all coordinates to zero.
Definition Math.h:353
Iterator over the domain covered by a BBox.
Definition Math.h:1932
__hostdev__ Iterator operator++(int)
Definition Math.h:1961
__hostdev__ Iterator(const BBox &b)
Definition Math.h:1937
__hostdev__ const CoordT & operator*() const
Definition Math.h:1989
__hostdev__ bool operator!=(const Iterator &rhs) const
Definition Math.h:1972
__hostdev__ bool operator<(const Iterator &rhs) const
Definition Math.h:1977
__hostdev__ bool operator==(const Iterator &rhs) const
Definition Math.h:1967
__hostdev__ Iterator(const BBox &b, const Coord &p)
Definition Math.h:1942
__hostdev__ bool operator<=(const Iterator &rhs) const
Definition Math.h:1982
__hostdev__ Iterator & operator++()
Definition Math.h:1947
Signed (i, j) 32-bit integer coordinate class, similar to openvdb::math::Coord.
Definition Math.h:599
__hostdev__ Coord2 & minComponent(const Coord2 &other)
Perform a component-wise minimum with the other Coord.
Definition Math.h:743
__hostdev__ Coord2 operator+(const Coord2 &rhs) const
Definition Math.h:726
uint32_t IndexType
Definition Math.h:603
__hostdev__ Coord2 & operator+=(const Coord2 &rhs)
Definition Math.h:729
__hostdev__ Coord2 offsetBy(ValueType dx, ValueType dy) const
Definition Math.h:776
__hostdev__ bool operator<(const Coord2 &rhs) const
Return true if this Coord is lexicographically less than the given Coord.
Definition Math.h:668
__hostdev__ Coord2 & operator&=(int n)
Definition Math.h:702
__hostdev__ Coord2(ValueType i, ValueType j)
Initializes coordinate to the given signed integers.
Definition Math.h:618
static __hostdev__ Coord2 max()
Definition Math.h:634
static __hostdev__ bool lessThan(const Coord2 &a, const Coord2 &b)
Definition Math.h:785
__hostdev__ Coord2 offsetBy(ValueType n) const
Definition Math.h:781
__hostdev__ bool operator!=(const Coord2 &rhs) const
Definition Math.h:701
static __hostdev__ Coord2 Floor(const Vec2T &xy)
Return the largest integer coordinates that are not greater than xyz (node centered conversion).
Definition Math.h:793
__hostdev__ Coord2 operator&(IndexType n) const
Return a new instance with coordinates masked by the given unsigned integer.
Definition Math.h:659
__hostdev__ Coord2 & maxComponent(const Coord2 &other)
Perform a component-wise maximum with the other Coord.
Definition Math.h:753
__hostdev__ Coord2 & operator-=(const Coord2 &rhs)
Definition Math.h:735
__hostdev__ Coord2 operator-(const Coord2 &rhs) const
Definition Math.h:727
__hostdev__ bool operator>(const Coord2 &rhs) const
Definition Math.h:684
__hostdev__ Coord2 operator<<(IndexType n) const
Definition Math.h:662
__hostdev__ Coord2 & operator>>=(uint32_t n)
Definition Math.h:714
__hostdev__ const ValueType & operator[](IndexType i) const
Return a const reference to the given Coord component.
Definition Math.h:642
__hostdev__ Coord2 & operator<<=(uint32_t n)
Definition Math.h:708
__hostdev__ Coord2 operator>>(IndexType n) const
Definition Math.h:665
__hostdev__ Coord2 & operator=(const CoordT &other)
Assignment operator that works with openvdb::Coord.
Definition Math.h:650
__hostdev__ Coord2 & operator+=(int n)
Definition Math.h:720
__hostdev__ bool operator<=(const Coord2 &rhs) const
Return true if this Coord is lexicographically less or equal to the given Coord.
Definition Math.h:676
__hostdev__ int32_t & y()
Definition Math.h:632
__hostdev__ int32_t y() const
Definition Math.h:629
__hostdev__ ValueType & operator[](IndexType i)
Return a non-const reference to the given Coord component.
Definition Math.h:646
__hostdev__ Coord2 operator-() const
Definition Math.h:728
__hostdev__ Coord2(ValueType n)
Initializes all coordinates to the given signed integer.
Definition Math.h:612
static __hostdev__ Coord2 min()
Definition Math.h:636
__hostdev__ Coord2 round() const
Definition Math.h:802
__hostdev__ bool operator>=(const Coord2 &rhs) const
Definition Math.h:692
__hostdev__ int32_t & x()
Definition Math.h:631
__hostdev__ Vec2< double > asVec2d() const
Return a double precision floating-point vector of this coordinate.
Definition Math.h:973
__hostdev__ Vec2< float > asVec2s() const
Return a single precision floating-point vector of this coordinate.
Definition Math.h:967
__hostdev__ Coord2(ValueType *ptr)
Definition Math.h:623
__hostdev__ Coord2()
Initialize all coordinates to zero.
Definition Math.h:606
int32_t ValueType
Definition Math.h:602
__hostdev__ int32_t x() const
Definition Math.h:628
__hostdev__ bool operator==(const Coord2 &rhs) const
Definition Math.h:700
static __hostdev__ size_t memUsage()
Definition Math.h:638
Signed (i, j, k) 32-bit integer coordinate class, similar to openvdb::math::Coord.
Definition Math.h:346
__hostdev__ Coord operator+(const Coord &rhs) const
Definition Math.h:488
__hostdev__ Coord & operator+=(int n)
Definition Math.h:481
uint32_t IndexType
Definition Math.h:350
__hostdev__ uint32_t hash() const
Return a hash key derived from the existing coordinates.
Definition Math.h:571
__hostdev__ Coord & operator&=(int n)
Definition Math.h:460
__hostdev__ Coord & operator<<=(uint32_t n)
Definition Math.h:467
__hostdev__ bool operator>(const Coord &rhs) const
Definition Math.h:438
static __hostdev__ Coord max()
Definition Math.h:383
__hostdev__ bool operator<=(const Coord &rhs) const
Return true if this Coord is lexicographically less or equal to the given Coord.
Definition Math.h:428
__hostdev__ Vec3< double > asVec3d() const
Return a double precision floating-point vector of this coordinate.
Definition Math.h:1550
__hostdev__ Coord(ValueType i, ValueType j, ValueType k)
Initializes coordinate to the given signed integers.
Definition Math.h:365
__hostdev__ Coord & maxComponent(const Coord &other)
Perform a component-wise maximum with the other Coord.
Definition Math.h:519
__hostdev__ int32_t & z()
Definition Math.h:381
static __hostdev__ bool lessThan(const Coord &a, const Coord &b)
Definition Math.h:555
__hostdev__ const ValueType & operator[](IndexType i) const
Return a const reference to the given Coord component.
Definition Math.h:391
__hostdev__ bool operator>=(const Coord &rhs) const
Definition Math.h:448
__hostdev__ Coord & operator+=(const Coord &rhs)
Definition Math.h:491
__hostdev__ Coord(ValueType *ptr)
Definition Math.h:370
__hostdev__ Coord & operator-=(const Coord &rhs)
Definition Math.h:498
__hostdev__ Coord offsetBy(ValueType dx, ValueType dy, ValueType dz) const
Definition Math.h:546
__hostdev__ int32_t & y()
Definition Math.h:380
__hostdev__ int32_t z() const
Definition Math.h:377
__hostdev__ Coord operator>>(IndexType n) const
Definition Math.h:415
__hostdev__ Coord offsetBy(ValueType n) const
Definition Math.h:551
__hostdev__ int32_t y() const
Definition Math.h:376
__hostdev__ ValueType & operator[](IndexType i)
Return a non-const reference to the given Coord component.
Definition Math.h:395
__hostdev__ uint8_t octant() const
Return the octant of this Coord.
Definition Math.h:575
__hostdev__ Coord operator<<(IndexType n) const
Definition Math.h:412
__hostdev__ Coord & operator=(const CoordT &other)
Assignment operator that works with openvdb::Coord.
Definition Math.h:399
__hostdev__ Coord operator-() const
Definition Math.h:490
__hostdev__ Coord & minComponent(const Coord &other)
Perform a component-wise minimum with the other Coord.
Definition Math.h:507
__hostdev__ Coord()
Initialize all coordinates to zero.
Definition Math.h:353
__hostdev__ Vec3< float > asVec3s() const
Return a single precision floating-point vector of this coordinate.
Definition Math.h:1544
static __hostdev__ Coord min()
Definition Math.h:385
__hostdev__ bool operator<(const Coord &rhs) const
Return true if this Coord is lexicographically less than the given Coord.
Definition Math.h:418
__hostdev__ bool operator!=(const Coord &rhs) const
Definition Math.h:459
__hostdev__ Coord(ValueType n)
Initializes all coordinates to the given signed integer.
Definition Math.h:359
__hostdev__ bool operator==(const Coord &rhs) const
Definition Math.h:458
__hostdev__ int32_t & x()
Definition Math.h:379
__hostdev__ Coord & operator>>=(uint32_t n)
Definition Math.h:474
__hostdev__ Coord operator&(IndexType n) const
Return a new instance with coordinates masked by the given unsigned integer.
Definition Math.h:409
static __hostdev__ Coord Floor(const Vec3T &xyz)
Return the largest integer coordinates that are not greater than xyz (node centered conversion).
Definition Math.h:563
__hostdev__ Coord round() const
Definition Math.h:586
__hostdev__ Coord operator-(const Coord &rhs) const
Definition Math.h:489
int32_t ValueType
Definition Math.h:349
__hostdev__ int32_t x() const
Definition Math.h:375
static __hostdev__ size_t memUsage()
Definition Math.h:387
Definition Math.h:1018
__hostdev__ Mat2(T a, T b, T c, T d)
Constructor given individual array elements, the ordering is in row major form:
Definition Math.h:1027
__hostdev__ Mat2 operator-() const
Definition Math.h:1036
__hostdev__ Mat2< T > & operator+=(const Mat2< T > &m)
Add each element of the given matrix to the corresponding element of this matrix.
Definition Math.h:1049
__hostdev__ Mat2< T > transpose() const
returns transpose of this
Definition Math.h:1058
__hostdev__ Mat2< T > inverse() const
returns inverse of this
Definition Math.h:1063
__hostdev__ Mat2(Source *array)
Constructor given array of elements, the ordering is in row major form.
Definition Math.h:1034
__hostdev__ Mat2< T > operator*(const Mat2< T > &m) const
Multiply by 2x2 matrix m and return the resulting matrix.
Definition Math.h:1039
Definition Math.h:1074
__hostdev__ Mat2x3< T > & operator+=(const Mat2x3< T > &m)
Add a 2x3 matrix to this matrix.
Definition Math.h:1102
__hostdev__ Mat2x3(Source *array)
Constructor given array of elements, the ordering is in row major form.
Definition Math.h:1090
__hostdev__ Mat2x3< T > operator+(const Mat2x3< T > &m) const
Add two matrices and return the resulting matrix.
Definition Math.h:1094
__hostdev__ Mat2x3(T a, T b, T c, T d, T e, T f)
Constructor given individual array elements, the ordering is in row major form:
Definition Math.h:1083
__hostdev__ Mat3x2< T > transpose() const
returns transpose of this
Definition Math.h:1109
Definition Math.h:1151
__hostdev__ Mat3< T > operator+(const Mat3< T > &m) const
Add two matrices and return the resulting matrix.
Definition Math.h:1178
__hostdev__ Mat3< T > & operator+=(const Mat3< T > &m)
Add each element of the given matrix to the corresponding element of this matrix.
Definition Math.h:1211
__hostdev__ Mat3(Source *a)
Constructor given array of elements, the ordering is in row major form.
Definition Math.h:1174
__hostdev__ Vec3< T > operator*(const Vec3< T > &v) const
Multiply by v and return the resulting vector.
Definition Math.h:1187
__hostdev__ Mat3(Source a, Source b, Source c, Source d, Source e, Source f, Source g, Source h, Source i)
Constructor given individual array elements, the ordering is in row major form:
Definition Math.h:1163
__hostdev__ Mat3< T > operator*(const Mat3< T > &m) const
Multiply by 3x3 matrix m and return the resulting matrix.
Definition Math.h:1196
__hostdev__ Mat3 transpose() const
returns transpose of this
Definition Math.h:1219
Definition Math.h:1119
__hostdev__ Mat2x3< T > transpose() const
returns transpose of this
Definition Math.h:1143
__hostdev__ Mat3x2(Source *a)
Constructor given array of elements, the ordering is in row major form.
Definition Math.h:1140
__hostdev__ Mat3x2(Source a, Source b, Source c, Source d, Source e, Source f)
Constructor given individual array elements, the ordering is in row major form:
Definition Math.h:1131
Definition Math.h:1227
__hostdev__ Mat4(Source a, Source b, Source c, Source d, Source e, Source f, Source g, Source h, Source i, Source j, Source k, Source l, Source m, Source n, Source o, Source p)
Constructor given individual array elements, the ordering is in row major form:
Definition Math.h:1240
__hostdev__ Mat4 transpose() const
returns transpose of this
Definition Math.h:1256
__hostdev__ Mat4(Source *a)
Constructor given array of elements, the ordering is in row major form.
Definition Math.h:1253
__hostdev__ T * operator[](int row)
Definition Math.h:1000
__hostdev__ const T * operator[](int row) const
Definition Math.h:1003
static constexpr int cols()
Definition Math.h:986
T mData[ROWS *COLS]
Definition Math.h:983
static constexpr int rows()
Definition Math.h:985
__hostdev__ MatBase(S *array)
Definition Math.h:993
static constexpr int size()
Definition Math.h:987
8-bit red, green, blue, alpha packed into 32 bit unsigned int
Definition Math.h:2111
__hostdev__ uint8_t & a()
Definition Math.h:2203
Rgba8 & operator=(const Rgba8 &)=default
Default copy assignment operator.
__hostdev__ float lengthSqr() const
Definition Math.h:2183
__hostdev__ const uint8_t & operator[](int n) const
Definition Math.h:2192
uint32_t packed
Definition Math.h:2115
__hostdev__ uint8_t & g()
Definition Math.h:2201
__hostdev__ const uint8_t & r() const
Definition Math.h:2196
__hostdev__ Rgba8(uint8_t r, uint8_t g, uint8_t b, uint8_t a=255u)
integer r,g,b,a ctor where alpha channel defaults to opaque
Definition Math.h:2145
__hostdev__ Rgba8(const Vec3< float > &rgb)
Vec3f r,g,b ctor (alpha channel it set to 1)
Definition Math.h:2169
Rgba8(Rgba8 &&)=default
Default move constructor.
__hostdev__ const uint8_t & b() const
Definition Math.h:2198
__hostdev__ const uint8_t & g() const
Definition Math.h:2197
__hostdev__ const uint32_t & packed() const
Definition Math.h:2194
Rgba8 & operator=(Rgba8 &&)=default
Default move assignment operator.
__hostdev__ float asFloat(int n) const
return n'th color channel as a float in the range 0 to 1
Definition Math.h:2191
__hostdev__ uint8_t & b()
Definition Math.h:2202
__hostdev__ Rgba8()
Default ctor initializes all channels to zero.
Definition Math.h:2137
uint8_t ValueType
Definition Math.h:2120
__hostdev__ float length() const
Definition Math.h:2189
Rgba8(const Rgba8 &)=default
Default copy constructor.
__hostdev__ const uint8_t & a() const
Definition Math.h:2199
__hostdev__ Rgba8(float r, float g, float b, float a=1.0f)
floating-point r,g,b,a ctor where alpha channel defaults to opaque
Definition Math.h:2159
__hostdev__ Rgba8(uint8_t v)
ctor where all channels are initialized to the same value
Definition Math.h:2152
__hostdev__ Rgba8(const Vec4< float > &rgba)
Vec4f r,g,b,a ctor.
Definition Math.h:2176
uint8_t c[4]
Definition Math.h:2114
__hostdev__ uint8_t & operator[](int n)
Definition Math.h:2193
__hostdev__ uint32_t & packed()
Definition Math.h:2195
static const int SIZE
Definition Math.h:2119
__hostdev__ uint8_t & r()
Definition Math.h:2200
__hostdev__ bool operator==(const Rgba8 &rhs) const
Definition Math.h:2182
A simple vector class with three components, similar to openvdb::math::Vec3.
Definition Math.h:810
__hostdev__ Coord2 floor() const
Round each component if this Vec<T> up to its integer value.
Definition Math.h:932
__hostdev__ T & operator[](int i)
Definition Math.h:852
__hostdev__ Vec2 operator-() const
Definition Math.h:860
__hostdev__ Coord2 ceil() const
Round each component if this Vec<T> down to its integer value.
Definition Math.h:935
__hostdev__ const T * asPointer() const
return a const raw constant pointer to array of three vector components
Definition Math.h:952
__hostdev__ Vec2 & operator=(const Vec2T< T2 > &rhs)
Definition Math.h:844
__hostdev__ Vec2 & operator/=(const T &s)
Definition Math.h:899
__hostdev__ Vec2 & operator*=(const T &s)
Definition Math.h:893
__hostdev__ Vec2 operator/(const Vec2 &v) const
Definition Math.h:862
__hostdev__ T dot(const Vec2T &v) const
Definition Math.h:854
__hostdev__ Vec2 & minComponent(const Vec2 &other)
Perform a component-wise minimum with the other Coord.
Definition Math.h:902
__hostdev__ Vec2 operator*(const T &s) const
Definition Math.h:867
__hostdev__ Vec2 & operator-=(const Coord &ijk)
Definition Math.h:887
__hostdev__ Vec2 operator-(const Vec2 &v) const
Definition Math.h:864
__hostdev__ T * asPointer()
return a non-const raw constant pointer to array of three vector components
Definition Math.h:950
__hostdev__ T lengthSqr() const
Definition Math.h:855
__hostdev__ Vec2 & maxComponent(const Vec2 &other)
Perform a component-wise maximum with the other Coord.
Definition Math.h:912
__hostdev__ Vec2(T x)
Definition Math.h:818
__hostdev__ ValueType min() const
Return the smallest vector component.
Definition Math.h:921
__hostdev__ Vec2 & operator-=(const Vec2 &v)
Definition Math.h:881
__hostdev__ Vec2 operator+(const Vec2 &v) const
Definition Math.h:863
__hostdev__ Vec2 & operator+=(const Vec2 &v)
Definition Math.h:869
__hostdev__ Vec2 operator-(const Coord &ijk) const
Definition Math.h:866
__hostdev__ Vec2(const Vec2T< T2 > &v)
Definition Math.h:827
__hostdev__ Vec2(const Vec2< T2 > &v)
Definition Math.h:833
__hostdev__ bool operator!=(const Vec2 &rhs) const
Definition Math.h:842
static const int size
Definition Math.h:815
__hostdev__ Vec2(const Coord2 &ijk)
Definition Math.h:837
__hostdev__ Coord2 round() const
Round each component if this Vec<T> to its closest integer value.
Definition Math.h:938
__hostdev__ Vec2(T x, T y)
Definition Math.h:822
__hostdev__ ValueType max() const
Return the largest vector component.
Definition Math.h:926
__hostdev__ Vec2 & operator+=(const Coord &ijk)
Definition Math.h:875
__hostdev__ bool operator==(const Vec2 &rhs) const
Definition Math.h:841
__hostdev__ Vec2 & normalize()
Definition Math.h:900
__hostdev__ Vec2 operator+(const Coord &ijk) const
Definition Math.h:865
__hostdev__ Vec2 operator*(const Vec2 &v) const
Definition Math.h:861
__hostdev__ T length() const
Definition Math.h:859
T ValueType
Definition Math.h:816
__hostdev__ Vec2 operator/(const T &s) const
Definition Math.h:868
__hostdev__ const T & operator[](int i) const
Definition Math.h:851
static const int SIZE
Definition Math.h:814
A simple vector class with three components, similar to openvdb::math::Vec3.
Definition Math.h:1362
__hostdev__ Vec3 operator/(const Vec3 &v) const
Definition Math.h:1430
__hostdev__ bool operator==(const Vec3 &rhs) const
Definition Math.h:1393
__hostdev__ Vec3(T x, T y, T z)
Definition Math.h:1374
__hostdev__ Vec3(const Vec3T< T2 > &v)
Definition Math.h:1379
__hostdev__ Vec3 & normalize()
Definition Math.h:1473
__hostdev__ Vec3 & maxComponent(const Vec3 &other)
Perform a component-wise maximum with the other Coord.
Definition Math.h:1487
__hostdev__ Vec3(T x)
Definition Math.h:1370
__hostdev__ T & operator[](int i)
Definition Math.h:1405
__hostdev__ Vec3 & operator-=(const Vec3 &v)
Definition Math.h:1451
__hostdev__ Vec3 operator*(const T &s) const
Definition Math.h:1435
__hostdev__ Coord ceil() const
Round each component if this Vec<T> down to its integer value.
Definition Math.h:1512
__hostdev__ Vec3 & operator-=(const Coord &ijk)
Definition Math.h:1458
__hostdev__ Vec3 & operator+=(const Coord &ijk)
Definition Math.h:1444
__hostdev__ const T * asPointer() const
return a const raw constant pointer to array of three vector components
Definition Math.h:1529
__hostdev__ Coord floor() const
Round each component if this Vec<T> up to its integer value.
Definition Math.h:1509
__hostdev__ Vec3 operator/(const T &s) const
Definition Math.h:1436
__hostdev__ Vec3 & minComponent(const Vec3 &other)
Perform a component-wise minimum with the other Coord.
Definition Math.h:1475
__hostdev__ Vec3(const Coord &ijk)
Definition Math.h:1389
__hostdev__ T * asPointer()
return a non-const raw constant pointer to array of three vector components
Definition Math.h:1527
__hostdev__ Vec3 & operator*=(const T &s)
Definition Math.h:1465
__hostdev__ T lengthSqr() const
Definition Math.h:1423
__hostdev__ ValueType min() const
Return the smallest vector component.
Definition Math.h:1498
__hostdev__ Vec3 & operator=(const Vec3T< T2 > &rhs)
Definition Math.h:1396
__hostdev__ Vec3 cross(const Vec3T &v) const
Definition Math.h:1409
__hostdev__ Vec3 operator-() const
Definition Math.h:1428
__hostdev__ Mat3< ValueType > outer(const Vec3T &v) const
Outer product of a 3x1 vector and a 1x3 vector, result is a 3x3 matrix.
Definition Math.h:1417
static const int size
Definition Math.h:1367
__hostdev__ Vec3 & operator+=(const Vec3 &v)
Definition Math.h:1437
__hostdev__ Vec3 operator+(const Coord &ijk) const
Definition Math.h:1433
__hostdev__ Vec3 operator-(const Vec3 &v) const
Definition Math.h:1432
__hostdev__ Vec3 operator+(const Vec3 &v) const
Definition Math.h:1431
__hostdev__ Vec3 operator-(const Coord &ijk) const
Definition Math.h:1434
__hostdev__ ValueType max() const
Return the largest vector component.
Definition Math.h:1503
__hostdev__ T dot(const Vec3T &v) const
Definition Math.h:1407
__hostdev__ Coord round() const
Round each component if this Vec<T> to its closest integer value.
Definition Math.h:1515
__hostdev__ Vec3 & operator/=(const T &s)
Definition Math.h:1472
__hostdev__ Vec3(const Vec3< T2 > &v)
Definition Math.h:1385
__hostdev__ Vec3 operator*(const Vec3 &v) const
Definition Math.h:1429
__hostdev__ T length() const
Definition Math.h:1427
T ValueType
Definition Math.h:1368
__hostdev__ const T & operator[](int i) const
Definition Math.h:1404
static const int SIZE
Definition Math.h:1366
__hostdev__ bool operator!=(const Vec3 &rhs) const
Definition Math.h:1394
A simple vector class with four components, similar to openvdb::math::Vec4.
Definition Math.h:1560
__hostdev__ Vec4 operator/(const Vec4 &v) const
Definition Math.h:1611
__hostdev__ T & operator[](int i)
Definition Math.h:1601
__hostdev__ bool operator!=(const Vec4 &rhs) const
Definition Math.h:1588
__hostdev__ Vec4 operator-() const
Definition Math.h:1609
__hostdev__ Vec4(T x, T y, T z, T w)
Definition Math.h:1572
__hostdev__ Vec4 & minComponent(const Vec4 &other)
Perform a component-wise minimum with the other Coord.
Definition Math.h:1643
__hostdev__ Vec4 & operator=(const Vec4T< T2 > &rhs)
Definition Math.h:1590
__hostdev__ Vec4 operator*(const Vec4 &v) const
Definition Math.h:1610
__hostdev__ Vec4(T x)
Definition Math.h:1568
__hostdev__ Vec4 & operator*=(const T &s)
Definition Math.h:1632
__hostdev__ T dot(const Vec4T &v) const
Definition Math.h:1603
__hostdev__ Vec4 & maxComponent(const Vec4 &other)
Perform a component-wise maximum with the other Coord.
Definition Math.h:1657
__hostdev__ Vec4 & operator-=(const Vec4 &v)
Definition Math.h:1624
__hostdev__ Vec4(const Vec4< T2 > &v)
Definition Math.h:1577
__hostdev__ Vec4 & normalize()
Definition Math.h:1641
__hostdev__ Vec4 & operator+=(const Vec4 &v)
Definition Math.h:1616
__hostdev__ T lengthSqr() const
Definition Math.h:1604
__hostdev__ Vec4 operator+(const Vec4 &v) const
Definition Math.h:1612
__hostdev__ Vec4 operator*(const T &s) const
Definition Math.h:1614
__hostdev__ bool operator==(const Vec4 &rhs) const
Definition Math.h:1587
static const int size
Definition Math.h:1565
__hostdev__ Vec4 operator/(const T &s) const
Definition Math.h:1615
__hostdev__ Vec4 & operator/=(const T &s)
Definition Math.h:1640
__hostdev__ Vec4(const Vec4T< T2 > &v)
Definition Math.h:1582
__hostdev__ T length() const
Definition Math.h:1608
T ValueType
Definition Math.h:1566
__hostdev__ Vec4 operator-(const Vec4 &v) const
Definition Math.h:1613
__hostdev__ const T & operator[](int i) const
Definition Math.h:1600
static const int SIZE
Definition Math.h:1564
#define __hostdev__
Definition SampleFromVoxels.h:29
Definition DitherLUT.h:19
__hostdev__ T Abs(T x)
Definition Math.h:229
__hostdev__ int MaxIndex(const Vec3T &v)
Definition Math.h:312
__hostdev__ T Sign(const T &x)
Return the sign of the given value as an integer (either -1, 0 or 1).
Definition Math.h:289
__hostdev__ Vec2< T2 > operator/(T1 scalar, const Vec2< T2 > &vec)
Definition Math.h:961
__hostdev__ int32_t Floor(float x)
Definition Math.h:193
Vec3< uint8_t > Vec3u8
Definition Math.h:2216
__hostdev__ Vec3T matMultT(const float *mat, const Vec3T &xyz)
Multiply the transposed of a 3x3 matrix and a 3d vector using 32bit floating point arithmetics.
Definition Math.h:1762
__hostdev__ constexpr T pi()
Pi constant taken from Boost to match old behaviour.
Definition Math.h:33
Vec3< float > Vec3f
Definition Math.h:2213
Vec4< float > Vec4f
Definition Math.h:2221
Coord Coord3
Type alias for Coord so we have a consistent naming convention.
Definition Math.h:591
__hostdev__ int MinIndex(const Vec3T &v)
Definition Math.h:295
__hostdev__ T Pow3(T x)
Definition Math.h:218
__hostdev__ CoordT Round(const Vec3T< RealT > &xyz)
__hostdev__ T Pow2(T x)
Definition Math.h:212
Vec3< uint32_t > Vec3u
Definition Math.h:2215
__hostdev__ T Pow4(T x)
Definition Math.h:224
Vec3< double > Vec3d
Definition Math.h:2212
__hostdev__ CoordT RoundDown(const Vec3T< RealT > &xyz)
Definition Math.h:270
__hostdev__ Type Max(Type a, Type b)
Definition Math.h:154
__hostdev__ float Clamp(float x, float a, float b)
Definition Math.h:175
Vec4< double > Vec4R
Definition Math.h:2219
Vec4< int > Vec4i
Definition Math.h:2222
__hostdev__ uint64_t AlignUp(uint64_t byteCount)
round up byteSize to the nearest wordSize, e.g. to align to machine word: AlignUp<sizeof(size_t)(n)
Definition Math.h:332
Vec3< uint16_t > Vec3u16
Definition Math.h:2217
__hostdev__ int32_t Ceil(float x)
Definition Math.h:202
__hostdev__ float Fract(float x)
Definition Math.h:184
__hostdev__ bool isApproxZero(const Type &x)
Definition Math.h:127
Vec3< int32_t > Vec3i
Definition Math.h:2214
__hostdev__ float Sqrt(float x)
Return the square root of a floating-point value.
Definition Math.h:277
Vec4< double > Vec4d
Definition Math.h:2220
__hostdev__ Vec3T matMult(const float *mat, const Vec3T &xyz)
Multiply a 3x3 matrix and a 3d vector using 32bit floating point arithmetics.
Definition Math.h:1704
__hostdev__ Vec2< T2 > operator*(T1 scalar, const Vec2< T2 > &vec)
Definition Math.h:956
__hostdev__ Type Min(Type a, Type b)
Definition Math.h:133
Defines a simple memory pool used to call cub functions that use dynamic temporary storage.
Definition GridHandle.h:31
math::Vec4< float > Vec4f
Definition Math.h:2238
math::Vec4< int > Vec4i
Definition Math.h:2239
math::Vec3< uint32_t > Vec3u
Definition Math.h:2232
math::Vec3< uint16_t > Vec3u16
Definition Math.h:2234
math::Vec3< uint8_t > Vec3u8
Definition Math.h:2233
math::Vec3< int32_t > Vec3i
Definition Math.h:2231
math::Vec3< float > Vec3f
Definition Math.h:2230
math::Vec4< double > Vec4R
Definition Math.h:2236
math::BBox< Vec3d > Vec3dBBox
Definition Math.h:2242
math::Vec3< double > Vec3d
Definition Math.h:2229
math::BBox< Coord > CoordBBox
Definition Math.h:2241
math::Vec4< double > Vec4d
Definition Math.h:2237
Utility functions.
#define NANOVDB_ASSERT(x)
Definition Util.h:53
#define __device__
Definition Util.h:82
Definition Math.h:1866
Defines an affine transform and its inverse represented as a 3x3 matrix and a vec3 translation.
Definition NanoVDB.h:1415
Vec3T applyMap(const Vec3T &ijk) const
Apply the forward affine transformation to a vector using 64bit floating point arithmetics.
Definition NanoVDB.h:1469
static __hostdev__ BBox createCube(const CoordT &min, typename CoordT::ValueType dim)
Definition Math.h:2012
static __hostdev__ BBox createCube(typename CoordT::ValueType min, typename CoordT::ValueType max)
Definition Math.h:2017
__hostdev__ bool isInside(const BBox &b) const
Return true if the given bounding box is inside this bounding box.
Definition Math.h:2041
__hostdev__ BBox()
Definition Math.h:1993
__hostdev__ bool isInside(const CoordT &p) const
Definition Math.h:2039
CoordT mCoord[2]
Definition Math.h:1805
__hostdev__ auto transform(const Map &map) const
transform this coordinate bounding box by the specified map
Definition Math.h:2070
__hostdev__ Iterator begin() const
Definition Math.h:1991
BaseBBox< CoordT > BaseT
Definition Math.h:1927
__hostdev__ Iterator end() const
Definition Math.h:1992
__hostdev__ BBox(BBox &other, const SplitT &)
Definition Math.h:2003
__hostdev__ CoordT dim() const
Definition Math.h:2033
__hostdev__ uint64_t volume() const
Definition Math.h:2034
__hostdev__ bool is_divisible() const
Definition Math.h:2022
__hostdev__ BBox expandBy(typename CoordT::ValueType padding) const
Return a new instance that is expanded by the specified padding.
Definition Math.h:2061
__hostdev__ BBox(const CoordT &min, const CoordT &max)
Definition Math.h:1997
__hostdev__ bool hasOverlap(const BBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition Math.h:2047
__hostdev__ bool empty() const
Return true if this bounding box is empty, e.g. uninitialized.
Definition Math.h:2026
__hostdev__ BBox< Vec3< RealT > > asReal() const
Definition Math.h:2054
Vec3T mCoord[2]
Definition Math.h:1805
__hostdev__ BBox()
Default construction sets BBox to an empty bbox.
Definition Math.h:1881
__hostdev__ bool isInside(const Vec3T &p) const
Definition Math.h:1911
__hostdev__ BBox(const Vec3T &min, const Vec3T &max)
Definition Math.h:1886
__hostdev__ Vec3T dim() const
Definition Math.h:1910
Vec3T Vec3Type
Definition Math.h:1875
__hostdev__ BBox(const BaseBBox< Coord > &bbox)
Definition Math.h:1900
__hostdev__ BBox(const Coord &min, const Coord &max)
Definition Math.h:1890
BaseBBox< Vec3T > BaseT
Definition Math.h:1878
static __hostdev__ BBox createCube(const Coord &min, typename Coord::ValueType dim)
Definition Math.h:1895
typename Vec3T::ValueType ValueType
Definition Math.h:1876
__hostdev__ bool empty() const
Definition Math.h:1904
Definition Math.h:1866
CoordT mCoord[2]
Definition Math.h:1805
__hostdev__ BaseBBox & expand(const BaseBBox &bbox)
Expand this bounding box to enclose the given bounding box.
Definition Math.h:1829
__hostdev__ bool isInside(const Vec3T &xyz)
Definition Math.h:1848
__hostdev__ bool operator!=(const BaseBBox &rhs) const
Definition Math.h:1807
__hostdev__ BaseBBox & expand(const Vec3T &xyz)
Expand this bounding box to enclose point xyz.
Definition Math.h:1821
__hostdev__ const Vec3T & min() const
Definition Math.h:1812
__hostdev__ BaseBBox()
Definition Math.h:1858
__hostdev__ Vec3T & operator[](int i)
Definition Math.h:1809
__hostdev__ const Vec3T & max() const
Definition Math.h:1813
__hostdev__ BaseBBox & translate(const Vec3T &xyz)
Definition Math.h:1814
__hostdev__ Vec3T & max()
Definition Math.h:1811
__hostdev__ bool operator==(const BaseBBox &rhs) const
Definition Math.h:1806
__hostdev__ BaseBBox & intersect(const BaseBBox &bbox)
Intersect this bounding box with the given bounding box.
Definition Math.h:1837
__hostdev__ Vec3T & min()
Definition Math.h:1810
__hostdev__ BaseBBox(const Vec3T &min, const Vec3T &max)
Definition Math.h:1859
__hostdev__ const Vec3T & operator[](int i) const
Definition Math.h:1808
static __hostdev__ double value()
Definition Math.h:82
static __hostdev__ float value()
Definition Math.h:77
Delta for small floating-point offsets.
Definition Math.h:73
Maximum floating-point values.
Definition Math.h:120
static T value()
Definition Math.h:121
static __hostdev__ double value()
Definition Math.h:66
static __hostdev__ float value()
Definition Math.h:61
Tolerance for floating-point comparison.
Definition Math.h:57
static constexpr bool value
Definition Util.h:344
static constexpr bool value
Definition Util.h:328