diff --git a/docs/Doxyfile b/docs/Doxyfile index d3fcd66e..d18f881d 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -4,14 +4,20 @@ GENERATE_LATEX = NO GENERATE_MAN = NO GENERATE_RTF = NO CASE_SENSE_NAMES = NO -INPUT = ../src/Imath ../src/Half +INPUT = ../src/Imath/ RECURSIVE = YES QUIET = YES JAVADOC_AUTOBRIEF = YES GENERATE_HTML = NO GENERATE_XML = YES +DISTRIBUTE_GROUP_DOC = YES MACRO_EXPANSION = YES ENABLE_PREPROCESSING = YES PREDEFINED = IMATH_CONSTEXPR14=constexpr \ - IMATH_HOSTDEVICE= + IMATH_HOSTDEVICE= \ + IMATH_INTERNAL_NAMESPACE=Imath \ + IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER="namespace Imath {" \ + IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT="}" \ + IMATH_INTERNAL_NAMESPACE_HEADER_ENTER="namespace Imath {" \ + IMATH_INTERNAL_NAMESPACE_HEADER_EXIT="}" \ No newline at end of file diff --git a/docs/classes/Box.rst b/docs/classes/Box.rst index 29bca4d1..23f337c8 100644 --- a/docs/classes/Box.rst +++ b/docs/classes/Box.rst @@ -32,16 +32,16 @@ Example: .. doxygentypedef:: Box3d .. doxygenclass:: Imath::Box - :members: :undoc-members: + :members: .. doxygenclass:: Imath::Box< Vec2< T > > - :members: :undoc-members: + :members: .. doxygenclass:: Imath::Box< Vec3< T > > - :members: :undoc-members: + :members: diff --git a/docs/classes/Color3.rst b/docs/classes/Color3.rst index 4bf0c5a7..3e84061b 100644 --- a/docs/classes/Color3.rst +++ b/docs/classes/Color3.rst @@ -4,7 +4,7 @@ Color3 The ``Color3`` class template represents a 3-component color, with pre-defined typedefs of ``unsigned char``, ``half``, and ``float``. -The ``Color3`` class is derived from ``Imath::Vec3`` and thus has +The ``Color3`` class inherits from ``Vec3`` and thus has fields named ``x``, ``y``, and ``z``. The class itself implies no specific interpretation of the values. @@ -26,6 +26,6 @@ Example: .. doxygentypedef:: C3f .. doxygenclass:: Imath::Color3 - :members: :undoc-members: + :members: diff --git a/docs/classes/Color4.rst b/docs/classes/Color4.rst index a33ef649..20e6bba0 100644 --- a/docs/classes/Color4.rst +++ b/docs/classes/Color4.rst @@ -5,8 +5,8 @@ The ``Color4`` class template represents a 4-component color (red, green, blue, and alpha), with pre-defined typedefs of ``unsigned char``, ``half``, and ``float``. -The ``Color4`` class is *not* derived from ``Imath::Vec4``. Its -fields are named ``r``, ``g``, ``b``, and ``a``. The class itself implies no +The ``Color4`` class is *not* derived from ``Vec4``. Its fields are +named ``r``, ``g``, ``b``, and ``a``. The class itself implies no specific interpretation of the values. Example: @@ -27,6 +27,6 @@ Example: .. doxygentypedef:: C4f .. doxygenclass:: Imath::Color4 - :members: :undoc-members: + :members: diff --git a/docs/classes/Euler.rst b/docs/classes/Euler.rst index c5cc6ecc..ff33d855 100644 --- a/docs/classes/Euler.rst +++ b/docs/classes/Euler.rst @@ -20,8 +20,8 @@ Example: .. doxygentypedef:: Eulerd .. doxygenclass:: Imath::Euler - :members: :undoc-members: + :members: diff --git a/docs/classes/Frustum.rst b/docs/classes/Frustum.rst index c7a3408c..1b31c064 100644 --- a/docs/classes/Frustum.rst +++ b/docs/classes/Frustum.rst @@ -14,7 +14,7 @@ Example: .. doxygentypedef:: Frustumd .. doxygenclass:: Imath::Frustum - :members: :undoc-members: + :members: diff --git a/docs/classes/Interval.rst b/docs/classes/Interval.rst index a11f949b..eddb0445 100644 --- a/docs/classes/Interval.rst +++ b/docs/classes/Interval.rst @@ -21,7 +21,7 @@ Example: .. doxygentypedef:: Intervald .. doxygenclass:: Imath::Interval - :members: :undoc-members: + :members: diff --git a/docs/classes/Line3.rst b/docs/classes/Line3.rst index c04212b5..836d34f2 100644 --- a/docs/classes/Line3.rst +++ b/docs/classes/Line3.rst @@ -14,8 +14,8 @@ Example: .. doxygentypedef:: Line3d .. doxygenclass:: Imath::Line3 - :members: :undoc-members: + :members: diff --git a/docs/classes/Matrix22.rst b/docs/classes/Matrix22.rst index 2b401877..bdfefde4 100644 --- a/docs/classes/Matrix22.rst +++ b/docs/classes/Matrix22.rst @@ -14,6 +14,6 @@ Example: .. doxygentypedef:: M22d .. doxygenclass:: Imath::Matrix22 - :members: :undoc-members: + :members: diff --git a/docs/classes/Matrix44.rst b/docs/classes/Matrix44.rst index 4a0f8c28..c8a72e12 100644 --- a/docs/classes/Matrix44.rst +++ b/docs/classes/Matrix44.rst @@ -14,6 +14,6 @@ Example: .. doxygentypedef:: M44d .. doxygenclass:: Imath::Matrix44 - :members: :undoc-members: + :members: diff --git a/docs/classes/Plane3.rst b/docs/classes/Plane3.rst index c93ef6e6..6eeb6001 100644 --- a/docs/classes/Plane3.rst +++ b/docs/classes/Plane3.rst @@ -14,8 +14,8 @@ Example: .. doxygentypedef:: Plane3d .. doxygenclass:: Imath::Plane3 - :members: :undoc-members: + :members: diff --git a/docs/classes/Quat.rst b/docs/classes/Quat.rst index ae064317..31e709c3 100644 --- a/docs/classes/Quat.rst +++ b/docs/classes/Quat.rst @@ -13,5 +13,5 @@ Example: .. doxygentypedef:: Quatf .. doxygenclass:: Imath::Quat - :members: :undoc-members: + :members: diff --git a/docs/classes/Rand32.rst b/docs/classes/Rand32.rst index debe8c45..c6b1670b 100644 --- a/docs/classes/Rand32.rst +++ b/docs/classes/Rand32.rst @@ -6,8 +6,8 @@ generates a uniformly distributed sequence with a period length of 2^32. .. doxygenclass:: Imath::Rand32 - :members: :undoc-members: + :members: diff --git a/docs/classes/Rand48.rst b/docs/classes/Rand48.rst index aeb0ba6a..ede94574 100644 --- a/docs/classes/Rand48.rst +++ b/docs/classes/Rand48.rst @@ -6,7 +6,7 @@ the C Standard Library functions erand48(), nrand48() & company. It generates a uniformly distributed sequence. .. doxygenclass:: Imath::Rand48 - :members: :undoc-members: + :members: diff --git a/docs/classes/Shear6.rst b/docs/classes/Shear6.rst index 038564d3..57aba124 100644 --- a/docs/classes/Shear6.rst +++ b/docs/classes/Shear6.rst @@ -12,6 +12,6 @@ Example: .. doxygentypedef:: Shear6f .. doxygenclass:: Imath::Shear6 - :members: :undoc-members: + :members: diff --git a/docs/classes/Sphere3.rst b/docs/classes/Sphere3.rst index 749a5d0a..aee43c29 100644 --- a/docs/classes/Sphere3.rst +++ b/docs/classes/Sphere3.rst @@ -12,6 +12,6 @@ Example: .. doxygentypedef:: Sphere3f .. doxygenclass:: Imath::Sphere3 - :members: :undoc-members: + :members: diff --git a/docs/classes/Vec2.rst b/docs/classes/Vec2.rst index cb65992b..e7dfa78d 100644 --- a/docs/classes/Vec2.rst +++ b/docs/classes/Vec2.rst @@ -18,5 +18,6 @@ Example: .. doxygentypedef:: V2d .. doxygenclass:: Imath::Vec2 + :undoc-members: :members: diff --git a/docs/classes/Vec3.rst b/docs/classes/Vec3.rst index 9c790669..830354b2 100644 --- a/docs/classes/Vec3.rst +++ b/docs/classes/Vec3.rst @@ -18,5 +18,6 @@ Example: .. doxygentypedef:: V3d .. doxygenclass:: Imath::Vec3 + :undoc-members: :members: diff --git a/docs/classes/Vec4.rst b/docs/classes/Vec4.rst index 21c31f5d..36eb5091 100644 --- a/docs/classes/Vec4.rst +++ b/docs/classes/Vec4.rst @@ -18,5 +18,6 @@ Example: .. doxygentypedef:: V4d .. doxygenclass:: Imath::Vec4 + :undoc-members: :members: diff --git a/docs/classes/half.rst b/docs/classes/half.rst index 6575d4ee..9ae5e54e 100644 --- a/docs/classes/half.rst +++ b/docs/classes/half.rst @@ -9,5 +9,5 @@ Example: :language: c++ .. doxygenclass:: Imath::half - :members: :undoc-members: + :members: diff --git a/docs/conf.py b/docs/conf.py index aa3a8b24..4d8ceb54 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -61,16 +61,16 @@ # General information about the project. project = 'Imath' -copyright = '2020, Contributors to the OpenEXR Project' +copyright = '2021, Contributors to the OpenEXR Project' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '3.0' +version = '1.0' # The full version, including alpha/beta/rc tags. -release = '3.0.0' +release = '1.0.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -116,10 +116,10 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. #html_theme = 'agogo' -#html_theme = 'default' +#html_theme = 'default' # good #html_theme = 'nature' # too green -#html_theme = 'bizstyle' # OK -html_theme = 'sphinxdoc' +html_theme = 'bizstyle' # OK +#html_theme = 'sphinxdoc' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the diff --git a/docs/functions/box.rst b/docs/functions/box.rst new file mode 100644 index 00000000..c29b84d7 --- /dev/null +++ b/docs/functions/box.rst @@ -0,0 +1,20 @@ +Box +### + +Functions to operate on bounding boxes. + +.. doxygenfunction:: clip + +.. doxygenfunction:: closestPointInBox + +.. doxygenfunction:: transform + +.. doxygenfunction:: affineTransform + +.. doxygenfunction:: findEntryAndExitPoints + +.. doxygenfunction:: intersects + + + + diff --git a/docs/functions/color.rst b/docs/functions/color.rst new file mode 100644 index 00000000..3471cfbd --- /dev/null +++ b/docs/functions/color.rst @@ -0,0 +1,22 @@ +Color +##### + +Functions that operate on colors. + +.. doxygenfunction:: hsv2rgb + +.. doxygenfunction:: template constexpr Color4 hsv2rgb(const Color4 &hsv) noexcept + +.. doxygenfunction:: template constexpr Vec3 hsv2rgb(const Vec3 &hsv) noexcept + +.. doxygenfunction:: template constexpr Color4 rgb2hsv(const Color4 &rgb) noexcept + +.. doxygenfunction:: template constexpr Vec3 rgb2hsv(const Vec3 &rgb) noexcept + +.. doxygenfunction:: template constexpr PackedColor rgb2packed(const Color4 &c) noexcept + +.. doxygenfunction:: template constexpr PackedColor rgb2packed(const Vec3 &c) noexcept + +.. doxygenfunction:: template void packed2rgb(PackedColor packed, Color4 &out) noexcept + +.. doxygenfunction:: template void packed2rgb(PackedColor packed, Vec3 &out) noexcept diff --git a/docs/functions/limits.rst b/docs/functions/limits.rst index fbcbf0da..539a9546 100644 --- a/docs/functions/limits.rst +++ b/docs/functions/limits.rst @@ -9,53 +9,3 @@ template specializations for most basic types. :members: :undoc-members: -.. doxygenstruct:: Imath::limits< char > - :members: - :undoc-members: - -.. doxygenstruct:: Imath::limits< signed char > - :members: - :undoc-members: - -.. doxygenstruct:: Imath::limits< unsigned char > - :members: - :undoc-members: - -.. doxygenstruct:: Imath::limits< short > - :members: - :undoc-members: - -.. doxygenstruct:: Imath::limits< unsigned short > - :members: - :undoc-members: - -.. doxygenstruct:: Imath::limits< int > - :members: - :undoc-members: - -.. doxygenstruct:: Imath::limits< unsigned int > - :members: - :undoc-members: - -.. doxygenstruct:: Imath::limits< long > - :members: - :undoc-members: - -.. doxygenstruct:: Imath::limits< unsigned long > - :members: - :undoc-members: - -.. doxygenstruct:: Imath::limits< float > - :members: - :undoc-members: - -.. doxygenstruct:: Imath::limits< double > - :members: - :undoc-members: - -.. doxygenstruct:: Imath::limits< long double > - :members: - :undoc-members: - - - diff --git a/docs/functions/roots.rst b/docs/functions/roots.rst index 231235e0..bbfabd6c 100644 --- a/docs/functions/roots.rst +++ b/docs/functions/roots.rst @@ -3,13 +3,13 @@ Roots Functions to compute roots of simple equations. -.. doxygenfunction:: solveLinear(T a, T b, T& x) +.. doxygenfunction:: solveLinear -.. doxygenfunction:: solveQuadratic(T a, T b, T c, T x[2]) +.. doxygenfunction:: solveQuadratic -.. doxygenfunction:: solveNormalizedCubic(T r, T s, T t, T x[3]) +.. doxygenfunction:: solveNormalizedCubic -.. doxygenfunction:: solveCubic(T a, T b, T c, T d, T x[3]) +.. doxygenfunction:: solveCubic diff --git a/docs/index.rst b/docs/index.rst index 7b09115f..bf060186 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -38,6 +38,8 @@ Imath Documentation :caption: Imath Functions :maxdepth: 3 + functions/box + functions/color functions/frame functions/gl functions/glu diff --git a/src/Imath/ImathBox.h b/src/Imath/ImathBox.h index bd33c8fe..2ffb6b42 100644 --- a/src/Imath/ImathBox.h +++ b/src/Imath/ImathBox.h @@ -3,6 +3,10 @@ // Copyright Contributors to the OpenEXR Project. // +// +// Axis-aligned bounding box +// + #ifndef INCLUDED_IMATHBOX_H #define INCLUDED_IMATHBOX_H @@ -25,25 +29,26 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER /// /// `V` must also provide a function `V::dimensions()` which returns the /// number of dimensions in the class (since its assumed its a vector) -- -/// preferably, this returns a constant expression, typically `2` or `3`. +/// preferably, this returns a constant expression, typically 2 or 3. /// template class Box { public: - //------------------------- - // Data Members are public - //------------------------- + /// @{ + /// @name Direct access to bounds + /// The minimum value of the box. V min; /// The maximum value of the box. V max; - //----------------------------------------------------- - // Constructors - an "empty" box is created by default - //----------------------------------------------------- + /// @} + + /// @{ + /// @name Constructors /// Construct an empty bounding box. This initializes the mimimum to /// `V::baseTypeMax()` and the maximum to `V::baseTypeMin()`. @@ -55,44 +60,48 @@ template class Box /// Construct a bounding box with the given minimum and maximum values. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box (const V& minV, const V& maxV) noexcept; - //-------------------- - // Operators: ==, != - //-------------------- + /// @} - /// Compare two Box objects for equality. + /// @{ + /// @name Comparison + + /// Equality IMATH_HOSTDEVICE constexpr bool operator== (const Box& src) const noexcept; - /// Compare two Box objects for inequality. + /// Inequality IMATH_HOSTDEVICE constexpr bool operator!= (const Box& src) const noexcept; - //------------------ - // Box manipulation - //------------------ + /// @} - /// Set the Box to be empty. A Box is empty if the mimimum is greater + /// @{ + /// @name Manipulation + + /// Set the box to be empty. A box is empty if the mimimum is greater /// than the maximum. makeEmpty() sets the mimimum to `V::baseTypeMax()` /// and the maximum to `V::baseTypeMin()`. IMATH_HOSTDEVICE void makeEmpty() noexcept; - /// Extend the Box to include the given point. + /// Extend the box to include the given point. IMATH_HOSTDEVICE void extendBy (const V& point) noexcept; - /// Extend the Box to include the given box. + /// Extend the box to include the given box. IMATH_HOSTDEVICE void extendBy (const Box& box) noexcept; - /// Make the box include the entire range of V. + /// Make the box include the entire range of `V`. IMATH_HOSTDEVICE void makeInfinite() noexcept; - //--------------------------------------------------- - // Query functions - these compute results each time - //--------------------------------------------------- + /// @} - /// Return the size of the box. The size is of type `V`, defined as - /// (max-min). An empty box has a size of V(0), i.e. 0 in each dimension. + /// @{ + /// @name Query + + /// Return the size of the box. The size is of type `V`, defined + /// as `(max-min)`. An empty box has a size of `V(0)`, i.e. 0 in + /// each dimension. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 V size() const noexcept; /// Return the center of the box. The center is defined as - /// (max+min)/2. The center of an empty box is undefined. + /// `(max+min)/2`. The center of an empty box is undefined. IMATH_HOSTDEVICE constexpr V center() const noexcept; /// Return true if the given point is inside the box, false otherwise. @@ -105,10 +114,6 @@ template class Box /// the greatest difference between maximum and minimum. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 unsigned int majorAxis() const noexcept; - //---------------- - // Classification - //---------------- - /// Return true if the box is empty, false otherwise. An empty box's /// minimum is greater than its maximum. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isEmpty() const noexcept; @@ -120,40 +125,38 @@ template class Box /// An infinite box has a mimimum of`V::baseTypeMin()` /// and a maximum of `V::baseTypeMax()`. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isInfinite() const noexcept; + + /// @} }; //-------------------- // Convenient typedefs //-------------------- -/// 2D Box of base type `short`. +/// 2D box of base type `short`. typedef Box Box2s; -/// 2D Box of base type `int`. +/// 2D box of base type `int`. typedef Box Box2i; -/// 2D Box of base type `float`. +/// 2D box of base type `float`. typedef Box Box2f; -/// 2D Box of base type `double`. +/// 2D box of base type `double`. typedef Box Box2d; -/// 3D Box of base type `short`. +/// 3D box of base type `short`. typedef Box Box3s; -/// 3D Box of base type `int`. +/// 3D box of base type `int`. typedef Box Box3i; -/// 3D Box of base type `float`. +/// 3D box of base type `float`. typedef Box Box3f; -/// 3D Box of base type `double`. +/// 3D box of base type `double`. typedef Box Box3d; -//---------------- -// Implementation -//---------------- - template IMATH_CONSTEXPR14 inline Box::Box() noexcept { makeEmpty(); @@ -344,59 +347,101 @@ template class Box; template class Box> { public: - //------------------------- - // Data Members are public - //------------------------- + /// @{ + /// @name Direct access to bounds + + /// The minimum value of the box. Vec2 min; + + /// The maximum value of the box. Vec2 max; - //----------------------------------------------------- - // Constructors - an "empty" box is created by default - //----------------------------------------------------- + /// @} + + /// @{ + /// @name Constructors and Assignment + /// Empty by default IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box() noexcept; + + /// Construct a bounding box that contains a single point. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box (const Vec2& point) noexcept; + + /// Construct a bounding box with the given minimum and maximum points IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box (const Vec2& minT, const Vec2& maxT) noexcept; - //-------------------- - // Operators: ==, != - //-------------------- + /// @} + /// @{ + /// @name Comparison + + /// Equality IMATH_HOSTDEVICE constexpr bool operator== (const Box>& src) const noexcept; + + /// Inequality IMATH_HOSTDEVICE constexpr bool operator!= (const Box>& src) const noexcept; - //------------------ - // Box manipulation - //------------------ + /// @} + + /// @{ + /// @name Manipulation + /// Set the Box to be empty. A Box is empty if the mimimum is greater + /// than the maximum. makeEmpty() sets the mimimum to `limits::max()' + /// and the maximum to `limits::min()`. IMATH_HOSTDEVICE void makeEmpty() noexcept; + + /// Extend the Box to include the given point. IMATH_HOSTDEVICE void extendBy (const Vec2& point) noexcept; + + /// Extend the Box to include the given box. IMATH_HOSTDEVICE void extendBy (const Box>& box) noexcept; + + /// Make the box include the entire range of T. IMATH_HOSTDEVICE void makeInfinite() noexcept; - //--------------------------------------------------- - // Query functions - these compute results each time - //--------------------------------------------------- + /// @} + /// @{ + /// @name Query + + /// Return the size of the box. The size is of type `V`, defined as + /// `(max-min)`. An empty box has a size of `V(0)`, i.e. 0 in each dimension. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec2 size() const noexcept; + + /// Return the center of the box. The center is defined as + /// `(max+min)/2`. The center of an empty box is undefined. IMATH_HOSTDEVICE constexpr Vec2 center() const noexcept; + + /// Return true if the given point is inside the box, false otherwise. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersects (const Vec2& point) const noexcept; + + /// Return true if the given box is inside the box, false otherwise. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersects (const Box>& box) const noexcept; + /// Return the major axis of the box. The major axis is the dimension with + /// the greatest difference between maximum and minimum. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 unsigned int majorAxis() const noexcept; - //---------------- - // Classification - //---------------- - + /// Return true if the box is empty, false otherwise. An empty box's + /// minimum is greater than its maximum. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isEmpty() const noexcept; + + /// Return true if the box is larger than a single point, false otherwise. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool hasVolume() const noexcept; + + /// Return true if the box contains all points, false otherwise. + /// An infinite box has a mimimum of `V::baseTypeMin()` + /// and a maximum of `V::baseTypeMax()`. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isInfinite() const noexcept; + + /// @} }; //---------------- // Implementation +//---------------- template IMATH_CONSTEXPR14 inline Box>::Box() noexcept { @@ -562,68 +607,92 @@ Box>::majorAxis() const noexcept } /// -/// The Box> template represents a 3D bounding box defined by -/// minimum and maximum values of type Vec3. The min and max members are -/// public. +/// The Box template represents a 3D bounding box defined by +/// minimum and maximum values of type Vec3. /// - - template class Box> { public: - //------------------------- - // Data Members are public - //------------------------- + /// @{ + /// @name Direct access to bounds + + /// The minimum value of the box. Vec3 min; + + /// The maximum value of the box. Vec3 max; - //----------------------------------------------------- - // Constructors - an "empty" box is created by default - //----------------------------------------------------- + /// @} + + /// @{ + /// @name Constructors + /// Empty by default IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box() noexcept; + + /// Construct a bounding box that contains a single point. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box (const Vec3& point) noexcept; + + /// Construct a bounding box with the given minimum and maximum points IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box (const Vec3& minT, const Vec3& maxT) noexcept; - //-------------------- - // Operators: ==, != - //-------------------- + /// @} + /// Equality IMATH_HOSTDEVICE constexpr bool operator== (const Box>& src) const noexcept; - IMATH_HOSTDEVICE constexpr bool operator!= (const Box>& src) const noexcept; - //------------------ - // Box manipulation - //------------------ + /// Inequality + IMATH_HOSTDEVICE constexpr bool operator!= (const Box>& src) const noexcept; + /// Set the Box to be empty. A Box is empty if the mimimum is greater + /// than the maximum. makeEmpty() sets the mimimum to `limits::max()` + /// and the maximum to `limits::min()`. IMATH_HOSTDEVICE void makeEmpty() noexcept; + + /// Extend the Box to include the given point. IMATH_HOSTDEVICE void extendBy (const Vec3& point) noexcept; + /// Extend the Box to include the given box. + IMATH_HOSTDEVICE void extendBy (const Box>& box) noexcept; - IMATH_HOSTDEVICE void makeInfinite() noexcept; - //--------------------------------------------------- - // Query functions - these compute results each time - //--------------------------------------------------- + /// Make the box include the entire range of T. + IMATH_HOSTDEVICE void makeInfinite() noexcept; + /// Return the size of the box. The size is of type `V`, defined as + /// (max-min). An empty box has a size of V(0), i.e. 0 in each dimension. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec3 size() const noexcept; + + /// Return the center of the box. The center is defined as + /// (max+min)/2. The center of an empty box is undefined. IMATH_HOSTDEVICE constexpr Vec3 center() const noexcept; + + /// Return true if the given point is inside the box, false otherwise. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersects (const Vec3& point) const noexcept; + + /// Return true if the given box is inside the box, false otherwise. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersects (const Box>& box) const noexcept; + /// Return the major axis of the box. The major axis is the dimension with + /// the greatest difference between maximum and minimum. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 unsigned int majorAxis() const noexcept; - //---------------- - // Classification - //---------------- - + /// Return true if the box is empty, false otherwise. An empty box's + /// minimum is greater than its maximum. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isEmpty() const noexcept; + + /// Return true if the box is larger than a single point, false otherwise. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool hasVolume() const noexcept; + + /// Return true if the box contains all points, false otherwise. + /// An infinite box has a mimimum of`V::baseTypeMin()` + /// and a maximum of `V::baseTypeMax()`. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isInfinite() const noexcept; }; //---------------- // Implementation +//---------------- template IMATH_CONSTEXPR14 inline Box>::Box() noexcept { diff --git a/src/Imath/ImathBoxAlgo.h b/src/Imath/ImathBoxAlgo.h index 55fe6bf6..5984bbb2 100644 --- a/src/Imath/ImathBoxAlgo.h +++ b/src/Imath/ImathBoxAlgo.h @@ -3,45 +3,12 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHBOXALGO_H -#define INCLUDED_IMATHBOXALGO_H - -//--------------------------------------------------------------------------- -// -// This file contains algorithms applied to or in conjunction -// with bounding boxes (Imath::Box). These algorithms require -// more headers to compile. The assumption made is that these -// functions are called much less often than the basic box -// functions or these functions require more support classes. -// -// Contains: -// -// T clip(const T& in, const Box& box) -// -// Vec3 closestPointOnBox(const Vec3&, const Box>& ) -// -// Vec3 closestPointInBox(const Vec3&, const Box>& ) -// -// Box< Vec3 > transform(const Box>&, const Matrix44&) -// Box< Vec3 > affineTransform(const Box>&, const Matrix44&) -// -// void transform(const Box>&, const Matrix44&, Box>&) -// void affineTransform(const Box>&, -// const Matrix44&, -// Box>&) -// -// bool findEntryAndExitPoints(const Line &line, -// const Box< Vec3 > &box, -// Vec3 &enterPoint, -// Vec3 &exitPoint) // -// bool intersects(const Box> &box, -// const Line3 &ray, -// Vec3 intersectionPoint) +// Axis-aligned bounding box utility functions // -// bool intersects(const Box> &box, const Line3 &ray) -// -//--------------------------------------------------------------------------- + +#ifndef INCLUDED_IMATHBOXALGO_H +#define INCLUDED_IMATHBOXALGO_H #include "ImathBox.h" #include "ImathLineAlgo.h" @@ -51,15 +18,15 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER +/// +/// Clip the coordinates of a point, `p`, against a `Box`, `box`. +/// Return the closest point to `p` that is inside the box. +/// + template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline T clip (const T& p, const Box& box) noexcept { - // - // Clip the coordinates of a point, p, against a box. - // The result, q, is the closest point to p that is inside the box. - // - T q; for (int i = 0; i < int (box.min.dimensions()); i++) @@ -75,6 +42,11 @@ clip (const T& p, const Box& box) noexcept return q; } +/// +/// Return the point in or on the `Box`, `box`, that is closesest to +/// the point, `p`. +/// + template IMATH_HOSTDEVICE constexpr inline T closestPointInBox (const T& p, const Box& box) noexcept @@ -82,17 +54,17 @@ closestPointInBox (const T& p, const Box& box) noexcept return clip (p, box); } +/// +/// Return the point on the surface of the `Box`, `box`, that is +/// closest to point `p`. +/// +/// If the box is empty, return `p`. +/// + template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec3 closestPointOnBox (const Vec3& p, const Box>& box) noexcept { - // - // Find the point, q, on the surface of - // the box, that is closest to point p. - // - // If the box is empty, return p. - // - if (box.isEmpty()) return p; @@ -124,24 +96,22 @@ closestPointOnBox (const Vec3& p, const Box>& box) noexcept return q; } +/// +/// Transform a 3D box by a matrix, and compute a new box that +/// tightly encloses the transformed box. Return the transformed box. +/// +/// If `m` is an affine transform, then we use James Arvo's fast +/// method as described in "Graphics Gems", Academic Press, 1990, +/// pp. 548-550. +/// +/// A transformed empty box is still empty, and a transformed infinite box +/// is still infinite. +/// + template IMATH_HOSTDEVICE Box> transform (const Box>& box, const Matrix44& m) noexcept { - // - // Transform a 3D box by a matrix, and compute a new box that - // tightly encloses the transformed box. - // - // If m is an affine transform, then we use James Arvo's fast - // method as described in "Graphics Gems", Academic Press, 1990, - // pp. 548-550. - // - - // - // A transformed empty box is still empty, and a transformed infinite box - // is still infinite - // - if (box.isEmpty() || box.isInfinite()) return box; @@ -206,24 +176,23 @@ transform (const Box>& box, const Matrix44& m) noexcept return newBox; } +/// +/// Transform a 3D box by a matrix, and compute a new box that +/// tightly encloses the transformed box. The transformed box is +/// returned in the `result` argument. +/// +/// If m is an affine transform, then we use James Arvo's fast +/// method as described in "Graphics Gems", Academic Press, 1990, +/// pp. 548-550. +/// +/// A transformed empty box is still empty, and a transformed infinite +/// box is still infinite +/// + template IMATH_HOSTDEVICE void transform (const Box>& box, const Matrix44& m, Box>& result) noexcept { - // - // Transform a 3D box by a matrix, and compute a new box that - // tightly encloses the transformed box. - // - // If m is an affine transform, then we use James Arvo's fast - // method as described in "Graphics Gems", Academic Press, 1990, - // pp. 548-550. - // - - // - // A transformed empty box is still empty, and a transformed infinite - // box is still infinite - // - if (box.isEmpty() || box.isInfinite()) { return; @@ -284,27 +253,23 @@ transform (const Box>& box, const Matrix44& m, Box>& result) result.extendBy (points[i] * m); } +/// +/// Transform a 3D box by a matrix whose rightmost column `(0 0 0 1)`, +/// and compute a new box that tightly encloses the transformed +/// box. Return the transformed box. +/// +/// As in the transform() function, use James Arvo's fast method if +/// possible. +/// +/// A transformed empty or infinite box is still empty or infinite. +/// + template IMATH_HOSTDEVICE Box> affineTransform (const Box>& box, const Matrix44& m) noexcept { - // - // Transform a 3D box by a matrix whose rightmost column - // is (0 0 0 1), and compute a new box that tightly encloses - // the transformed box. - // - // As in the transform() function, above, we use James Arvo's - // fast method. - // - if (box.isEmpty() || box.isInfinite()) - { - // - // A transformed empty or infinite box is still empty or infinite - // - return box; - } Box> newBox; @@ -335,33 +300,30 @@ affineTransform (const Box>& box, const Matrix44& m) noexcept return newBox; } +/// +/// Transform a 3D box by a matrix whose rightmost column is +/// `(0 0 0 1)`, and compute a new box that tightly encloses +/// the transformed box. Return the transformed box in the `result` +/// argument. +/// +/// As in the transform() function, use James Arvo's fast method if +/// possible. +/// +/// A transformed empty or infinite box is still empty or infinite. +/// + template IMATH_HOSTDEVICE void affineTransform (const Box>& box, const Matrix44& m, Box>& result) noexcept { - // - // Transform a 3D box by a matrix whose rightmost column - // is (0 0 0 1), and compute a new box that tightly encloses - // the transformed box. - // - // As in the transform() function, above, we use James Arvo's - // fast method. - // - if (box.isEmpty()) { - // - // A transformed empty box is still empty - // result.makeEmpty(); return; } if (box.isInfinite()) { - // - // A transformed infinite box is still infinite - // result.makeInfinite(); return; } @@ -391,32 +353,23 @@ affineTransform (const Box>& box, const Matrix44& m, Box>& re } } +/// +/// Compute the points where a ray, `r`, enters and exits a 3D box, `b`: +/// +/// Return true if the ray starts inside the box or if the ray starts +/// outside and intersects the box, or return false otherwise (that +/// is, if the ray does not intersect the box). +/// +/// The entry and exit points are the points on two of the faces of +/// the box when the function returns true (the entry end exit points +/// may be on either side of the ray's origin), or undefined if the +/// the function returns false. +/// + template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool findEntryAndExitPoints (const Line3& r, const Box>& b, Vec3& entry, Vec3& exit) noexcept { - // - // Compute the points where a ray, r, enters and exits a box, b: - // - // findEntryAndExitPoints() returns - // - // - true if the ray starts inside the box or if the - // ray starts outside and intersects the box - // - // - false otherwise (that is, if the ray does not - // intersect the box) - // - // The entry and exit points are - // - // - points on two of the faces of the box when - // findEntryAndExitPoints() returns true - // (The entry end exit points may be on either - // side of the ray's origin) - // - // - undefined when findEntryAndExitPoints() - // returns false - // - if (b.isEmpty()) { // @@ -665,34 +618,34 @@ findEntryAndExitPoints (const Line3& r, const Box>& b, Vec3& entry return tFrontMax <= tBackMin; } +/// +/// Intersect a ray, `r`, with a 3D box, `b, and compute the intersection +/// point, returned in `ip`. +/// +/// intersect() returns: +/// +/// - true if the ray starts inside the box or if the +/// ray starts outside and intersects the box +/// +/// - false if the ray starts outside the box and intersects it, +/// but the intersection is behind the ray's origin. +/// +/// - false if the ray starts outside and does not intersect it +/// +/// The intersection point is +/// +/// - the ray's origin if the ray starts inside the box +/// +/// - a point on one of the faces of the box if the ray +/// starts outside the box +/// +/// - undefined when intersect() returns false +/// + template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersects (const Box>& b, const Line3& r, Vec3& ip) noexcept { - // - // Intersect a ray, r, with a box, b, and compute the intersection - // point, ip: - // - // intersect() returns - // - // - true if the ray starts inside the box or if the - // ray starts outside and intersects the box - // - // - false if the ray starts outside the box and intersects it, - // but the intersection is behind the ray's origin. - // - // - false if the ray starts outside and does not intersect it - // - // The intersection point is - // - // - the ray's origin if the ray starts inside the box - // - // - a point on one of the faces of the box if the ray - // starts outside the box - // - // - undefined when intersect() returns false - // - if (b.isEmpty()) { // @@ -943,6 +896,10 @@ intersects (const Box>& b, const Line3& r, Vec3& ip) noexcept return tFrontMax <= tBackMin; } +/// +/// Return whether the the ray `ray` interects the 3D box `box`. +/// + template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersects (const Box>& box, const Line3& ray) noexcept diff --git a/src/Imath/ImathColor.h b/src/Imath/ImathColor.h index 582e4137..bcd9bbd8 100644 --- a/src/Imath/ImathColor.h +++ b/src/Imath/ImathColor.h @@ -3,14 +3,12 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHCOLOR_H -#define INCLUDED_IMATHCOLOR_H - -//---------------------------------------------------- // -// A three and four component color class template. +// 3-channel and 4-channel color representations // -//---------------------------------------------------- + +#ifndef INCLUDED_IMATHCOLOR_H +#define INCLUDED_IMATHCOLOR_H #include "ImathNamespace.h" #include "ImathVec.h" @@ -18,216 +16,293 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER +/// +/// 3-channel color class that inherits from Vec3. +/// +/// This class does not impose interpretation on the channels, which +/// can represent either rgb or hsv color values. +/// +/// Note: because Color3 inherits from Vec3, its member fields are +/// called `x`, `y`, and `z`. + template class Color3 : public Vec3 { public: - //------------- - // Constructors - //------------- - IMATH_HOSTDEVICE Color3() noexcept; // no initialization - IMATH_HOSTDEVICE constexpr explicit Color3 (T a) noexcept; // (a a a) - IMATH_HOSTDEVICE constexpr Color3 (T a, T b, T c) noexcept; // (a b c) + /// @{ + /// @name Constructors and Assignemt + + /// No initialization by default + IMATH_HOSTDEVICE Color3() noexcept; + + /// Initialize to (a a a) + IMATH_HOSTDEVICE constexpr explicit Color3 (T a) noexcept; + + /// Initialize to (a b c) + IMATH_HOSTDEVICE constexpr Color3 (T a, T b, T c) noexcept; + + /// Construct from Color3 + IMATH_HOSTDEVICE constexpr Color3 (const Color3& c) noexcept; + + /// Construct from Vec3 + template IMATH_HOSTDEVICE constexpr Color3 (const Vec3& v) noexcept; + + /// Destructor ~Color3() = default; - //--------------------------------- - // Copy constructors and assignment - //--------------------------------- + /// Component-wise assignment + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& operator= (const Color3& c) noexcept; - IMATH_HOSTDEVICE constexpr Color3 (const Color3& c) noexcept; - template IMATH_HOSTDEVICE constexpr Color3 (const Vec3& v) noexcept; + /// @} + + /// @{ + /// @name Arithmetic + + /// Component-wise addition + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& operator+= (const Color3& c) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& operator= (const Color3& c) noexcept; + /// Component-wise addition + IMATH_HOSTDEVICE constexpr Color3 operator+ (const Color3& c) const noexcept; - //------------------------ - // Component-wise addition - //------------------------ + /// Component-wise subtraction + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& operator-= (const Color3& c) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& operator+= (const Color3& c) noexcept; - IMATH_HOSTDEVICE constexpr Color3 operator+ (const Color3& c) const noexcept; + /// Component-wise subtraction + IMATH_HOSTDEVICE constexpr Color3 operator- (const Color3& c) const noexcept; - //--------------------------- - // Component-wise subtraction - //--------------------------- + /// Component-wise multiplication by -1 + IMATH_HOSTDEVICE constexpr Color3 operator-() const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& operator-= (const Color3& c) noexcept; - IMATH_HOSTDEVICE constexpr Color3 operator- (const Color3& c) const noexcept; + /// Component-wise multiplication by -1 + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& negate() noexcept; - //------------------------------------ - // Component-wise multiplication by -1 - //------------------------------------ + /// Component-wise multiplication + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& operator*= (const Color3& c) noexcept; - IMATH_HOSTDEVICE constexpr Color3 operator-() const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& negate() noexcept; + /// Component-wise multiplication + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& operator*= (T a) noexcept; - //------------------------------ - // Component-wise multiplication - //------------------------------ + /// Component-wise multiplication + IMATH_HOSTDEVICE constexpr Color3 operator* (const Color3& c) const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& operator*= (const Color3& c) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& operator*= (T a) noexcept; - IMATH_HOSTDEVICE constexpr Color3 operator* (const Color3& c) const noexcept; - IMATH_HOSTDEVICE constexpr Color3 operator* (T a) const noexcept; + /// Component-wise multiplication + IMATH_HOSTDEVICE constexpr Color3 operator* (T a) const noexcept; - //------------------------ - // Component-wise division - //------------------------ + /// Component-wise division + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& operator/= (const Color3& c) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& operator/= (const Color3& c) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& operator/= (T a) noexcept; - IMATH_HOSTDEVICE constexpr Color3 operator/ (const Color3& c) const noexcept; - IMATH_HOSTDEVICE constexpr Color3 operator/ (T a) const noexcept; + /// Component-wise division + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color3& operator/= (T a) noexcept; + + /// Component-wise division + IMATH_HOSTDEVICE constexpr Color3 operator/ (const Color3& c) const noexcept; + + /// Component-wise division + IMATH_HOSTDEVICE constexpr Color3 operator/ (T a) const noexcept; + + /// @} }; +/// +/// A 4-channel color class: 3 channels plus alpha. +/// +/// For convenience, the fields are named `r`, `g`, and `b`, although +/// this class does not impose interpretation on the channels, which +/// can represent either rgb or hsv color values. +/// + template class Color4 { public: - //------------------- - // Access to elements - //------------------- + + /// @{ + /// @name Direct access to elements T r, g, b, a; - IMATH_HOSTDEVICE T& operator[] (int i) noexcept; - IMATH_HOSTDEVICE const T& operator[] (int i) const noexcept; + /// @} - //------------- - // Constructors - //------------- + /// @{ + /// @name Constructors and Assignment - IMATH_HOSTDEVICE Color4() noexcept; // no initialization - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 explicit Color4 (T a) noexcept; // (a a a a) - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Color4 (T a, T b, T c, T d) noexcept; // (a b c d) - ~Color4() = default; + /// No initialization by default + IMATH_HOSTDEVICE Color4() noexcept; - //--------------------------------- - // Copy constructors and assignment - //--------------------------------- + /// Initialize to `(a a a a)` + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 explicit Color4 (T a) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Color4 (const Color4& v) noexcept; - template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Color4 (const Color4& v) noexcept; + /// Initialize to `(a b c d)` + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Color4 (T a, T b, T c, T d) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& operator= (const Color4& v) noexcept; + /// Construct from Color4 + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Color4 (const Color4& v) noexcept; - //---------------------- - // Compatibility with Sb - //---------------------- + /// Construct from Color4 + template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Color4 (const Color4& v) noexcept; - template IMATH_HOSTDEVICE void setValue (S a, S b, S c, S d) noexcept; + /// Destructor + ~Color4() = default; - template IMATH_HOSTDEVICE void setValue (const Color4& v) noexcept; + /// Assignment + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& operator= (const Color4& v) noexcept; - template IMATH_HOSTDEVICE void getValue (S& a, S& b, S& c, S& d) const noexcept; + /// Component-wise value + IMATH_HOSTDEVICE T& operator[] (int i) noexcept; - template IMATH_HOSTDEVICE void getValue (Color4& v) const noexcept; + /// Component-wise value + IMATH_HOSTDEVICE const T& operator[] (int i) const noexcept; - IMATH_HOSTDEVICE T* getValue() noexcept; - IMATH_HOSTDEVICE const T* getValue() const noexcept; + /// @} + + /// @{ + /// @name Arithmetic and Comparison + + /// Equality + template IMATH_HOSTDEVICE constexpr bool operator== (const Color4& v) const noexcept; - //--------- - // Equality - //--------- + /// Inequality + template IMATH_HOSTDEVICE constexpr bool operator!= (const Color4& v) const noexcept; - template IMATH_HOSTDEVICE constexpr bool operator== (const Color4& v) const noexcept; + /// Component-wise addition + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& operator+= (const Color4& v) noexcept; - template IMATH_HOSTDEVICE constexpr bool operator!= (const Color4& v) const noexcept; + /// Component-wise addition + IMATH_HOSTDEVICE constexpr Color4 operator+ (const Color4& v) const noexcept; - //------------------------ - // Component-wise addition - //------------------------ + /// Component-wise subtraction + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& operator-= (const Color4& v) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& operator+= (const Color4& v) noexcept; - IMATH_HOSTDEVICE constexpr Color4 operator+ (const Color4& v) const noexcept; + /// Component-wise subtraction + IMATH_HOSTDEVICE constexpr Color4 operator- (const Color4& v) const noexcept; - //--------------------------- - // Component-wise subtraction - //--------------------------- + /// Component-wise multiplication by -1 + IMATH_HOSTDEVICE constexpr Color4 operator-() const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& operator-= (const Color4& v) noexcept; - IMATH_HOSTDEVICE constexpr Color4 operator- (const Color4& v) const noexcept; + /// Component-wise multiplication by -1 + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& negate() noexcept; - //------------------------------------ - // Component-wise multiplication by -1 - //------------------------------------ + /// Component-wise multiplication + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& operator*= (const Color4& v) noexcept; - IMATH_HOSTDEVICE constexpr Color4 operator-() const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& negate() noexcept; + /// Component-wise multiplication + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& operator*= (T a) noexcept; - //------------------------------ - // Component-wise multiplication - //------------------------------ + /// Component-wise multiplication + IMATH_HOSTDEVICE constexpr Color4 operator* (const Color4& v) const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& operator*= (const Color4& v) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& operator*= (T a) noexcept; - IMATH_HOSTDEVICE constexpr Color4 operator* (const Color4& v) const noexcept; - IMATH_HOSTDEVICE constexpr Color4 operator* (T a) const noexcept; + /// Component-wise multiplication + IMATH_HOSTDEVICE constexpr Color4 operator* (T a) const noexcept; - //------------------------ - // Component-wise division - //------------------------ + /// Component-wise division + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& operator/= (const Color4& v) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& operator/= (const Color4& v) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& operator/= (T a) noexcept; - IMATH_HOSTDEVICE constexpr Color4 operator/ (const Color4& v) const noexcept; - IMATH_HOSTDEVICE constexpr Color4 operator/ (T a) const noexcept; + /// Component-wise division + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Color4& operator/= (T a) noexcept; - //---------------------------------------------------------- - // Number of dimensions, i.e. number of elements in a Color4 - //---------------------------------------------------------- + /// Component-wise division + IMATH_HOSTDEVICE constexpr Color4 operator/ (const Color4& v) const noexcept; + /// Component-wise division + IMATH_HOSTDEVICE constexpr Color4 operator/ (T a) const noexcept; + + /// @} + + /// @{ + /// @name Numeric Limits + + /// Number of dimensions (channels), i.e. 4 for a Color4 IMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 4; } - //------------------------------------------------- - // Limitations of type T (see also class limits) - //------------------------------------------------- + /// Largest possible negative value + IMATH_HOSTDEVICE constexpr static T baseTypeMin() noexcept { return limits::min(); } + + /// Largest possible positive value + IMATH_HOSTDEVICE constexpr static T baseTypeMax() noexcept { return limits::max(); } - IMATH_HOSTDEVICE constexpr static T baseTypeMin() noexcept { return limits::min(); } - IMATH_HOSTDEVICE constexpr static T baseTypeMax() noexcept { return limits::max(); } - IMATH_HOSTDEVICE constexpr static T baseTypeSmallest() noexcept { return limits::smallest(); } - IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() noexcept { return limits::epsilon(); } + /// Smallest possible positive value + IMATH_HOSTDEVICE constexpr static T baseTypeSmallest() noexcept { return limits::smallest(); } - //-------------------------------------------------------------- - // Base type -- in templates, which accept a parameter, V, which - // could be a Color4, you can refer to T as - // V::BaseType - //-------------------------------------------------------------- + /// Smallest possible e for which 1+e != 1 + IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() noexcept { return limits::epsilon(); } + /// @} + + /// The base type: In templates that accept a parameter `V` (could + /// be a Color4), you can refer to `T` as `V::BaseType` typedef T BaseType; -}; -//-------------- -// Stream output -//-------------- + /// @{ + /// @name Compatibilty with Sb -template std::ostream& operator<< (std::ostream& s, const Color4& v); + /// Set the value + template IMATH_HOSTDEVICE void setValue (S a, S b, S c, S d) noexcept; -//---------------------------------------------------- -// Reverse multiplication: S * Color4 -//---------------------------------------------------- + /// Set the value + template IMATH_HOSTDEVICE void setValue (const Color4& v) noexcept; -template constexpr Color4 operator* (S a, const Color4& v) noexcept; + /// Return the value + template IMATH_HOSTDEVICE void getValue (S& a, S& b, S& c, S& d) const noexcept; -//------------------------- -// Typedefs for convenience -//------------------------- + /// Return the value + template IMATH_HOSTDEVICE void getValue (Color4& v) const noexcept; + /// Return raw pointer to the value + IMATH_HOSTDEVICE T* getValue() noexcept; + + /// Return raw pointer to the value + IMATH_HOSTDEVICE const T* getValue() const noexcept; + + /// @} +}; + +/// std::ostream output +template std::ostream& operator<< (std::ostream& s, const Color4& v); + +/// Reverse multiplication: S * Color4 +template constexpr Color4 operator* (S a, const Color4& v) noexcept; + +/// 3 float channels typedef Color3 Color3f; + +/// 3 half channels typedef Color3 Color3h; + +/// 3 8-bit integer channels typedef Color3 Color3c; + +/// 3 half channels typedef Color3 C3h; + +/// 3 float channels typedef Color3 C3f; + +/// 3 8-bit integer channels typedef Color3 C3c; + +/// 4 float channels typedef Color4 Color4f; + +/// 4 half channels typedef Color4 Color4h; + +/// 4 8-bit integer channels typedef Color4 Color4c; + +/// 4 float channels typedef Color4 C4f; + +/// 4 half channels typedef Color4 C4h; + +/// 4 8-bit integer channels typedef Color4 C4c; + +/// Packed 32-bit integer typedef unsigned int PackedColor; -//------------------------- +// // Implementation of Color3 -//------------------------- +// template inline Color3::Color3() noexcept : Vec3() { @@ -369,9 +444,9 @@ Color3::operator/ (T a) const noexcept return Color3 (*(Vec3*) this / a); } -//----------------------- +// // Implementation of Color4 -//----------------------- +// template inline T& @@ -641,9 +716,9 @@ operator<< (std::ostream& s, const Color4& v) return s << '(' << v.r << ' ' << v.g << ' ' << v.b << ' ' << v.a << ')'; } -//----------------------------------------- +// // Implementation of reverse multiplication -//----------------------------------------- +// template constexpr inline Color4 diff --git a/src/Imath/ImathColorAlgo.cpp b/src/Imath/ImathColorAlgo.cpp index eb2c0b88..aed56586 100644 --- a/src/Imath/ImathColorAlgo.cpp +++ b/src/Imath/ImathColorAlgo.cpp @@ -3,11 +3,11 @@ // Copyright Contributors to the OpenEXR Project. // -//---------------------------------------------------------------------------- -// -// Implementation of non-template items declared in ImathColorAlgo.h -// -//---------------------------------------------------------------------------- +/// +/// @file ImathColorAlgo.cpp +/// +/// @brief Implementation of non-template items declared in ImathColorAlgo.h +/// #include "ImathColorAlgo.h" diff --git a/src/Imath/ImathColorAlgo.h b/src/Imath/ImathColorAlgo.h index 7cfd1299..8b0faa71 100644 --- a/src/Imath/ImathColorAlgo.h +++ b/src/Imath/ImathColorAlgo.h @@ -3,6 +3,10 @@ // Copyright Contributors to the OpenEXR Project. // +// +// Color conversion functions and general color algorithms +// + #ifndef INCLUDED_IMATHCOLORALGO_H #define INCLUDED_IMATHCOLORALGO_H @@ -15,24 +19,29 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER // -// Non-templated helper routines for color conversion. -// These routines eliminate type warnings under g++. +// Non-templated helper routines for color conversion. +// These routines eliminate type warnings under g++. // +/// +/// Convert 3-channel hsv to rgb. Non-templated helper routine. IMATH_EXPORT Vec3 hsv2rgb_d (const Vec3& hsv) noexcept; +/// +/// Convert 4-channel hsv to rgb (with alpha). Non-templated helper routine. IMATH_EXPORT Color4 hsv2rgb_d (const Color4& hsv) noexcept; +/// +/// Convert 3-channel rgb to hsv. Non-templated helper routine. IMATH_EXPORT Vec3 rgb2hsv_d (const Vec3& rgb) noexcept; +/// +/// Convert 4-channel rgb to hsv. Non-templated helper routine. IMATH_EXPORT Color4 rgb2hsv_d (const Color4& rgb) noexcept; -// -// Color conversion functions and general color algorithms -// -// hsv2rgb(), rgb2hsv(), rgb2packed(), packed2rgb() -// see each funtion definition for details. -// +/// +/// Convert 3-channel hsv to rgb. +/// template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec3 @@ -56,6 +65,10 @@ hsv2rgb (const Vec3& hsv) noexcept } } +/// +/// Convert 4-channel hsv to rgb (with alpha). +/// + template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Color4 hsv2rgb (const Color4& hsv) noexcept @@ -80,6 +93,10 @@ hsv2rgb (const Color4& hsv) noexcept } } +/// +/// Convert 3-channel rgb to hsv. +/// + template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec3 rgb2hsv (const Vec3& rgb) noexcept @@ -102,6 +119,10 @@ rgb2hsv (const Vec3& rgb) noexcept } } +/// +/// Convert 4-channel rgb to hsv (with alpha). +/// + template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Color4 rgb2hsv (const Color4& rgb) noexcept @@ -126,6 +147,10 @@ rgb2hsv (const Color4& rgb) noexcept } } +/// +/// Convert 3-channel rgb to PackedColor +/// + template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 PackedColor rgb2packed (const Vec3& c) noexcept @@ -147,6 +172,10 @@ rgb2packed (const Vec3& c) noexcept } } +/// +/// Convert 4-channel rgb to PackedColor (with alpha) +/// + template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 PackedColor rgb2packed (const Color4& c) noexcept @@ -170,11 +199,10 @@ rgb2packed (const Color4& c) noexcept } } -// -// This guy can't return the result because the template -// parameter would not be in the function signiture. So instead, -// its passed in as an argument. -// +/// +/// Convert PackedColor to 3-channel rgb. Return the result in the +/// `out` parameter. +/// template IMATH_HOSTDEVICE void @@ -196,6 +224,11 @@ packed2rgb (PackedColor packed, Vec3& out) noexcept } } +/// +/// Convert PackedColor to 4-channel rgb (with alpha). Return the +/// result in the `out` parameter. +/// + template IMATH_HOSTDEVICE void packed2rgb (PackedColor packed, Color4& out) noexcept diff --git a/src/Imath/ImathEuler.h b/src/Imath/ImathEuler.h index 6c897e66..5dc198e2 100644 --- a/src/Imath/ImathEuler.h +++ b/src/Imath/ImathEuler.h @@ -3,95 +3,12 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHEULER_H -#define INCLUDED_IMATHEULER_H - -//---------------------------------------------------------------------- -// -// template class Euler -// -// This class represents euler angle orientations. The class -// inherits from Vec3 to it can be freely cast. The additional -// information is the euler priorities rep. This class is -// essentially a rip off of Ken Shoemake's GemsIV code. It has -// been modified minimally to make it more understandable, but -// hardly enough to make it easy to grok completely. -// -// There are 24 possible combonations of Euler angle -// representations of which 12 are common in CG and you will -// probably only use 6 of these which in this scheme are the -// non-relative-non-repeating types. -// -// The representations can be partitioned according to two -// criteria: -// -// 1) Are the angles measured relative to a set of fixed axis -// or relative to each other (the latter being what happens -// when rotation matrices are multiplied together and is -// almost ubiquitous in the cg community) -// -// 2) Is one of the rotations repeated (ala XYX rotation) -// -// When you construct a given representation from scratch you -// must order the angles according to their priorities. So, the -// easiest is a softimage or aerospace (yaw/pitch/roll) ordering -// of ZYX. -// -// float x_rot = 1; -// float y_rot = 2; -// float z_rot = 3; -// -// Eulerf angles(z_rot, y_rot, x_rot, Eulerf::ZYX); -// -or- -// Eulerf angles( V3f(z_rot,y_rot,z_rot), Eulerf::ZYX ); -// -// If instead, the order was YXZ for instance you would have to -// do this: -// -// float x_rot = 1; -// float y_rot = 2; -// float z_rot = 3; -// -// Eulerf angles(y_rot, x_rot, z_rot, Eulerf::YXZ); -// -or- -// Eulerf angles( V3f(y_rot,x_rot,z_rot), Eulerf::YXZ ); -// -// Notice how the order you put the angles into the three slots -// should correspond to the enum (YXZ) ordering. The input angle -// vector is called the "ijk" vector -- not an "xyz" vector. The -// ijk vector order is the same as the enum. If you treat the -// Euler<> as a Vec<> (which it inherts from) you will find the -// angles are ordered in the same way, i.e.: -// -// V3f v = angles; -// // v.x == y_rot, v.y == x_rot, v.z == z_rot -// -// If you just want the x, y, and z angles stored in a vector in -// that order, you can do this: -// -// V3f v = angles.toXYZVector() -// // v.x == x_rot, v.y == y_rot, v.z == z_rot -// -// If you want to set the Euler with an XYZVector use the -// optional layout argument: -// -// Eulerf angles(x_rot, y_rot, z_rot, -// Eulerf::YXZ, -// Eulerf::XYZLayout); -// -// This is the same as: -// -// Eulerf angles(y_rot, x_rot, z_rot, Eulerf::YXZ); // -// Note that this won't do anything intelligent if you have a -// repeated axis in the euler angles (e.g. XYX) +// Euler angle representation of rotation/orientation // -// If you need to use the "relative" versions of these, you will -// need to use the "r" enums. -// -// The units of the rotation angles are assumed to be radians. -// -//---------------------------------------------------------------------- + +#ifndef INCLUDED_IMATHEULER_H +#define INCLUDED_IMATHEULER_H #include "ImathLimits.h" #include "ImathMath.h" @@ -109,6 +26,95 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER # pragma warning(disable : 4244) #endif +/// +/// Template class `Euler` +/// +/// This class represents euler angle orientations. The class +/// inherits from Vec3 to it can be freely cast. The additional +/// information is the euler priorities rep. This class is +/// essentially a rip off of Ken Shoemake's GemsIV code. It has +/// been modified minimally to make it more understandable, but +/// hardly enough to make it easy to grok completely. +/// +/// There are 24 possible combonations of Euler angle +/// representations of which 12 are common in CG and you will +/// probably only use 6 of these which in this scheme are the +/// non-relative-non-repeating types. +/// +/// The representations can be partitioned according to two +/// criteria: +/// +/// 1) Are the angles measured relative to a set of fixed axis +/// or relative to each other (the latter being what happens +/// when rotation matrices are multiplied together and is +/// almost ubiquitous in the cg community) +/// +/// 2) Is one of the rotations repeated (ala XYX rotation) +/// +/// When you construct a given representation from scratch you +/// must order the angles according to their priorities. So, the +/// easiest is a softimage or aerospace (yaw/pitch/roll) ordering +/// of ZYX. +/// +/// float x_rot = 1; +/// float y_rot = 2; +/// float z_rot = 3; +/// +/// Eulerf angles(z_rot, y_rot, x_rot, Eulerf::ZYX); +/// +/// or: +/// +/// Eulerf angles( V3f(z_rot,y_rot,z_rot), Eulerf::ZYX ); +/// +/// +/// If instead, the order was YXZ for instance you would have to +/// do this: +/// +/// float x_rot = 1; +/// float y_rot = 2; +/// float z_rot = 3; +/// +/// Eulerf angles(y_rot, x_rot, z_rot, Eulerf::YXZ); +/// +/// or: +/// +/// +/// Eulerf angles( V3f(y_rot,x_rot,z_rot), Eulerf::YXZ ); +/// +/// Notice how the order you put the angles into the three slots +/// should correspond to the enum (YXZ) ordering. The input angle +/// vector is called the "ijk" vector -- not an "xyz" vector. The +/// ijk vector order is the same as the enum. If you treat the +/// Euler as a Vec3 (which it inherts from) you will find the +/// angles are ordered in the same way, i.e.: +/// +/// V3f v = angles; +/// v.x == y_rot, v.y == x_rot, v.z == z_rot +/// +/// If you just want the x, y, and z angles stored in a vector in +/// that order, you can do this: +/// +/// V3f v = angles.toXYZVector() +/// v.x == x_rot, v.y == y_rot, v.z == z_rot +/// +/// If you want to set the Euler with an XYZVector use the +/// optional layout argument: +/// +/// Eulerf angles(x_rot, y_rot, z_rot, Eulerf::YXZ, Eulerf::XYZLayout); +/// +/// This is the same as: +/// +/// Eulerf angles(y_rot, x_rot, z_rot, Eulerf::YXZ); +/// +/// Note that this won't do anything intelligent if you have a +/// repeated axis in the euler angles (e.g. XYX) +/// +/// If you need to use the "relative" versions of these, you will +/// need to use the "r" enums. +/// +/// The units of the rotation angles are assumed to be radians. +/// + template class Euler : public Vec3 { public: @@ -116,12 +122,12 @@ template class Euler : public Vec3 using Vec3::y; using Vec3::z; + + /// + /// All 24 possible orderings + /// enum Order { - // - // All 24 possible orderings - // - XYZ = 0x0101, // "usual" orderings XZY = 0x0001, YZX = 0x1101, @@ -149,9 +155,10 @@ template class Euler : public Vec3 YZYr = 0x1010, ZYZr = 0x0110, ZXZr = 0x0010, - // |||| - // VVVV - // Legend: ABCD + // |||| + // VVVV + // ABCD + // Legend: // A -> Initial Axis (0==x, 1==y, 2==z) // B -> Parity Even (1==true) // C -> Initial Repeated (1==true) @@ -166,6 +173,9 @@ template class Euler : public Vec3 Default = XYZ }; + /// + /// Axes + /// enum Axis { X = 0, @@ -173,156 +183,199 @@ template class Euler : public Vec3 Z = 2 }; + /// + /// Layout + /// + enum InputLayout { XYZLayout, IJKLayout }; - //-------------------------------------------------------------------- - // Constructors -- all default to ZYX non-relative ala softimage - // (where there is no argument to specify it) - // - // The Euler-from-matrix constructors assume that the matrix does - // not include shear or non-uniform scaling, but the constructors - // do not examine the matrix to verify this assumption. If necessary, - // you can adjust the matrix by calling the removeScalingAndShear() - // function, defined in ImathMatrixAlgo.h. - //-------------------------------------------------------------------- - + /// @{ + /// @name Constructors + /// + /// All default to `ZYX` non-relative (ala Softimage 3D/Maya), + /// where there is no argument to specify it. + /// + /// The Euler-from-matrix constructors assume that the matrix does + /// not include shear or non-uniform scaling, but the constructors + /// do not examine the matrix to verify this assumption. If necessary, + /// you can adjust the matrix by calling the removeScalingAndShear() + /// function, defined in ImathMatrixAlgo.h. + + /// No initialization by default IMATH_HOSTDEVICE constexpr Euler() noexcept; + + /// Copy constructor IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Euler (const Euler&) noexcept; + + /// Construct from given Order IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Euler (Order p) noexcept; + + /// Construct from vector, order, layout IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Euler (const Vec3& v, Order o = Default, InputLayout l = IJKLayout) noexcept; + /// Construct from explicit axes, order, layout IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Euler (T i, T j, T k, Order o = Default, InputLayout l = IJKLayout) noexcept; + + /// Copy constructor with new Order IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Euler (const Euler& euler, Order newp) noexcept; + + /// Construct from Matrix33 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Euler (const Matrix33&, Order o = Default) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Euler (const Matrix44&, Order o = Default) noexcept; - //------------- - // Destructor - //------------- + /// Construct from Matrix44 + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Euler (const Matrix44&, Order o = Default) noexcept; + /// Destructor ~Euler() = default; - //--------------------------------- - // Algebraic functions/ Operators - //--------------------------------- + /// @} + + /// @{ + /// @name Query + + /// Return whether the given value is a legal Order + IMATH_HOSTDEVICE constexpr static bool legal (Order) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Euler& operator= (const Euler&) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Euler& operator= (const Vec3&) noexcept; + /// Return the order + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Order order() const noexcept; + + /// Return frameStatic + IMATH_HOSTDEVICE constexpr bool frameStatic() const { return _frameStatic; } - //-------------------------------------------------------- - // Set the euler value - // This does NOT convert the angles, but setXYZVector() - // does reorder the input vector. - //-------------------------------------------------------- + /// Return intialRepeated + IMATH_HOSTDEVICE constexpr bool initialRepeated() const { return _initialRepeated; } - IMATH_HOSTDEVICE constexpr static bool legal (Order) noexcept; + /// Return partityEven + IMATH_HOSTDEVICE constexpr bool parityEven() const { return _parityEven; } - IMATH_HOSTDEVICE void setXYZVector (const Vec3&) noexcept; + /// Return initialAxis + IMATH_HOSTDEVICE constexpr Axis initialAxis() const { return _initialAxis; } - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Order order() const noexcept; + /// Unpack angles from ijk form + IMATH_HOSTDEVICE void angleOrder (int& i, int& j, int& k) const noexcept; + + /// Determine mapping from xyz to ijk (reshuffle the xyz to match the order) + IMATH_HOSTDEVICE void angleMapping (int& i, int& j, int& k) const noexcept; + + /// @} + + /// @{ + /// @name Set Value + + /// Set the order. This does NOT convert the angles, but it + /// does reorder the input vector. IMATH_HOSTDEVICE void setOrder (Order) noexcept; + /// Set the euler value: set the first angle to `v[0]`, the second to + /// `v[1]`, the third to `v[2]`. + IMATH_HOSTDEVICE void setXYZVector (const Vec3&) noexcept; + + /// Set the value. IMATH_HOSTDEVICE void set (Axis initial, bool relative, bool parityEven, bool firstRepeats) noexcept; - //------------------------------------------------------------ - // Conversions, toXYZVector() reorders the angles so that - // the X rotation comes first, followed by the Y and Z - // in cases like XYX ordering, the repeated angle will be - // in the "z" component - // - // The Euler-from-matrix extract() functions assume that the - // matrix does not include shear or non-uniform scaling, but - // the extract() functions do not examine the matrix to verify - // this assumption. If necessary, you can adjust the matrix - // by calling the removeScalingAndShear() function, defined - // in ImathMatrixAlgo.h. - //------------------------------------------------------------ + /// @} + + /// @{ + /// @name Assignments and Conversions + /// + + /// Assignment + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Euler& operator= (const Euler&) noexcept; + + /// Assignment + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Euler& operator= (const Vec3&) noexcept; + /// Assign from Matrix33, assumed to be affine IMATH_HOSTDEVICE void extract (const Matrix33&) noexcept; + + /// Assign from Matrix44, assumed to be affine IMATH_HOSTDEVICE void extract (const Matrix44&) noexcept; + + /// Assign from Quaternion IMATH_HOSTDEVICE void extract (const Quat&) noexcept; - IMATH_HOSTDEVICE Matrix33 toMatrix33() const noexcept; - IMATH_HOSTDEVICE Matrix44 toMatrix44() const noexcept; - IMATH_HOSTDEVICE Quat toQuat() const noexcept; - IMATH_HOSTDEVICE Vec3 toXYZVector() const noexcept; - //--------------------------------------------------- - // Use this function to unpack angles from ijk form - //--------------------------------------------------- + /// Convert to Matrix33 + IMATH_HOSTDEVICE Matrix33 toMatrix33() const noexcept; - IMATH_HOSTDEVICE void angleOrder (int& i, int& j, int& k) const noexcept; + /// Convert to Matrix44 + IMATH_HOSTDEVICE Matrix44 toMatrix44() const noexcept; - //--------------------------------------------------- - // Use this function to determine mapping from xyz to ijk - // - reshuffles the xyz to match the order - //--------------------------------------------------- + /// Convert to Quat + IMATH_HOSTDEVICE Quat toQuat() const noexcept; - IMATH_HOSTDEVICE void angleMapping (int& i, int& j, int& k) const noexcept; + /// Reorder the angles so that the X rotation comes first, + /// followed by the Y and Z in cases like XYX ordering, the + /// repeated angle will be in the "z" component + IMATH_HOSTDEVICE Vec3 toXYZVector() const noexcept; - //---------------------------------------------------------------------- - // - // Utility methods for getting continuous rotations. None of these - // methods change the orientation given by its inputs (or at least - // that is the intent). - // - // angleMod() converts an angle to its equivalent in [-PI, PI] - // - // simpleXYZRotation() adjusts xyzRot so that its components differ - // from targetXyzRot by no more than +-PI - // - // nearestRotation() adjusts xyzRot so that its components differ - // from targetXyzRot by as little as possible. - // Note that xyz here really means ijk, because - // the order must be provided. - // - // makeNear() adjusts "this" Euler so that its components differ - // from target by as little as possible. This method - // might not make sense for Eulers with different order - // and it probably doesn't work for repeated axis and - // relative orderings (TODO). - // - //----------------------------------------------------------------------- + /// @} + + /// @{ + /// @name Utility Methods + /// + /// Utility methods for getting continuous rotations. None of these + /// methods change the orientation given by its inputs (or at least + /// that is the intent). + /// Convert an angle to its equivalent in [-PI, PI] IMATH_HOSTDEVICE IMATH_CONSTEXPR14 static float angleMod (T angle) noexcept; + /// Adjust xyzRot so that its components differ from targetXyzRot by no more than +/-PI IMATH_HOSTDEVICE static void simpleXYZRotation (Vec3& xyzRot, const Vec3& targetXyzRot) noexcept; + + /// Adjust xyzRot so that its components differ from targetXyzRot by as little as possible. + /// Note that xyz here really means ijk, because the order must be provided. IMATH_HOSTDEVICE static void nearestRotation (Vec3& xyzRot, const Vec3& targetXyzRot, Order order = XYZ) noexcept; + /// Adjusts "this" Euler so that its components differ from target + /// by as little as possible. This method might not make sense for + /// Eulers with different order and it probably doesn't work for + /// repeated axis and relative orderings (TODO). IMATH_HOSTDEVICE void makeNear (const Euler& target) noexcept; - IMATH_HOSTDEVICE constexpr bool frameStatic() const { return _frameStatic; } - IMATH_HOSTDEVICE constexpr bool initialRepeated() const { return _initialRepeated; } - IMATH_HOSTDEVICE constexpr bool parityEven() const { return _parityEven; } - IMATH_HOSTDEVICE constexpr Axis initialAxis() const { return _initialAxis; } + /// @} protected: - bool _frameStatic : 1; // relative or static rotations - bool _initialRepeated : 1; // init axis repeated as last - bool _parityEven : 1; // "parity of axis permutation" + + /// relative or static rotations + bool _frameStatic : 1; + + /// init axis repeated as last + bool _initialRepeated : 1; + + /// "parity of axis permutation" + bool _parityEven : 1; + #if defined _WIN32 || defined _WIN64 - Axis _initialAxis; // First axis of rotation + /// First axis of rotation + Axis _initialAxis; #else - Axis _initialAxis : 2; // First axis of rotation + /// First axis of rotation + Axis _initialAxis : 2; #endif }; -//-------------------- +// // Convenient typedefs -//-------------------- +// +/// Euler of type float typedef Euler Eulerf; +/// Euler of type double typedef Euler Eulerd; -//--------------- +// // Implementation -//--------------- +// + +/// @cond Doxygen_Suppress template inline void @@ -878,6 +931,7 @@ Euler::operator= (const Vec3& v) noexcept return *this; } +/// Stream ouput template std::ostream& operator<< (std::ostream& o, const Euler& euler) noexcept @@ -973,6 +1027,8 @@ Euler::makeNear (const Euler& target) noexcept # pragma warning(default : 4244) #endif +/// @endcond + IMATH_INTERNAL_NAMESPACE_HEADER_EXIT #endif // INCLUDED_IMATHEULER_H diff --git a/src/Imath/ImathForward.h b/src/Imath/ImathForward.h index 33ca7b9d..9fd1b9af 100644 --- a/src/Imath/ImathForward.h +++ b/src/Imath/ImathForward.h @@ -10,6 +10,8 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER +/// @cond Doxygen_Suppress + // // Basic template type declarations. // @@ -38,6 +40,8 @@ template class Vec4; class Rand32; class Rand48; +/// @endcond + IMATH_INTERNAL_NAMESPACE_HEADER_EXIT #endif // INCLUDED_IMATHFORWARD_H diff --git a/src/Imath/ImathFrame.h b/src/Imath/ImathFrame.h index a2d66201..c85319d8 100644 --- a/src/Imath/ImathFrame.h +++ b/src/Imath/ImathFrame.h @@ -3,6 +3,10 @@ // Copyright Contributors to the OpenEXR Project. // +// +// Functions for computing reference frames. +// + #ifndef INCLUDED_IMATHFRAME_H #define INCLUDED_IMATHFRAME_H @@ -10,26 +14,31 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER +/// @cond Doxygen_Suppress template class Vec3; template class Matrix44; +/// @endcond + +/// +/// @{ +/// @name Functions for computing reference frames +/// +/// These methods compute a set of reference frames, defined by their +/// transformation matrix, along a curve. It is designed so that the +/// array of points and the array of matrices used to fetch these +/// routines don't need to be ordered as the curve. +/// +/// A typical usage would be : +/// +/// m[0] = IMATH_INTERNAL_NAMESPACE::firstFrame( p[0], p[1], p[2] ); +/// for( int i = 1; i < n - 1; i++ ) +/// { +/// m[i] = IMATH_INTERNAL_NAMESPACE::nextFrame( m[i-1], p[i-1], p[i], t[i-1], t[i] ); +/// } +/// m[n-1] = IMATH_INTERNAL_NAMESPACE::lastFrame( m[n-2], p[n-2], p[n-1] ); +/// +/// See Graphics Gems I for the underlying algorithm. -// -// These methods compute a set of reference frames, defined by their -// transformation matrix, along a curve. It is designed so that the -// array of points and the array of matrices used to fetch these routines -// don't need to be ordered as the curve. -// -// A typical usage would be : -// -// m[0] = IMATH_INTERNAL_NAMESPACE::firstFrame( p[0], p[1], p[2] ); -// for( int i = 1; i < n - 1; i++ ) -// { -// m[i] = IMATH_INTERNAL_NAMESPACE::nextFrame( m[i-1], p[i-1], p[i], t[i-1], t[i] ); -// } -// m[n-1] = IMATH_INTERNAL_NAMESPACE::lastFrame( m[n-2], p[n-2], p[n-1] ); -// -// See Graphics Gems I for the underlying algorithm. -// template Matrix44 constexpr firstFrame (const Vec3&, // First point @@ -48,21 +57,27 @@ Matrix44 constexpr lastFrame (const Matrix44&, // Previous matrix const Vec3&, // Previous point const Vec3&) noexcept; // Last point -// -// firstFrame - Compute the first reference frame along a curve. -// -// This function returns the transformation matrix to the reference frame -// defined by the three points 'pi', 'pj' and 'pk'. Note that if the two -// vectors and are colinears, an arbitrary twist value will -// be choosen. -// -// Throw 'NullVecExc' if 'pi' and 'pj' are equals. -// - +/// +/// Compute the first reference frame along a curve. +/// +/// This function returns the transformation matrix to the reference +/// frame defined by the three points `pi`, `pj` and `pk`. Note that +/// if the two vectors <`pi`,`pj`> and <`pi`,`pk`> are colinears, an +/// arbitrary twist value will be choosen. +/// +/// Throw `std::domain_error` if `pi` and `pj` are equal. +/// +/// @param pi +/// First point +/// @param pj +/// Second point +/// @param pk +/// Third point +/// template -Matrix44 constexpr firstFrame (const Vec3& pi, // First point - const Vec3& pj, // Second point - const Vec3& pk) noexcept // Third point +Matrix44 constexpr firstFrame (const Vec3& pi, // first point + const Vec3& pj, // secont point + const Vec3& pk) noexcept // third point { Vec3 t = pj - pi; t.normalizeExc(); @@ -102,13 +117,23 @@ Matrix44 constexpr firstFrame (const Vec3& pi, // First point return M; } -// -// nextFrame - Compute the next reference frame along a curve. -// -// This function returns the transformation matrix to the next reference -// frame defined by the previously computed transformation matrix and the -// new point and tangent vector along the curve. -// +/// +/// Compute the next reference frame along a curve. +/// +/// This function returns the transformation matrix to the next reference +/// frame defined by the previously computed transformation matrix and the +/// new point and tangent vector along the curve. +/// +/// @param Mi +/// The previous matrix +/// @param pi +/// The previous point +/// @param pj +/// The current point +/// @param ti +/// The previous tangent vector +/// @param tj +/// The current tangent vector template Matrix44 constexpr nextFrame (const Matrix44& Mi, // Previous matrix @@ -117,7 +142,7 @@ Matrix44 constexpr nextFrame (const Matrix44& Mi, // Previous matrix Vec3& ti, // Previous tangent vector Vec3& tj) noexcept // Current tangent vector { - Vec3 a (0.0, 0.0, 0.0); // Rotation axis. + Vec3 a (0.0, 0.0, 0.0); /// Rotation axis. T r = 0.0; // Rotation angle. if (ti.length() != 0.0 && tj.length() != 0.0) @@ -159,13 +184,19 @@ Matrix44 constexpr nextFrame (const Matrix44& Mi, // Previous matrix } } -// -// lastFrame - Compute the last reference frame along a curve. -// -// This function returns the transformation matrix to the last reference -// frame defined by the previously computed transformation matrix and the -// last point along the curve. -// +/// +/// Compute the last reference frame along a curve. +/// +/// This function returns the transformation matrix to the last reference +/// frame defined by the previously computed transformation matrix and the +/// last point along the curve. +/// +/// @param Mi +/// The previous matrix +/// @param pi +/// The previous point +/// @param pj +/// The last point template Matrix44 constexpr lastFrame (const Matrix44& Mi, // Previous matrix @@ -178,6 +209,8 @@ Matrix44 constexpr lastFrame (const Matrix44& Mi, // Previous matrix return Mi * Tr; } +/// @} + IMATH_INTERNAL_NAMESPACE_HEADER_EXIT #endif // INCLUDED_IMATHFRAME_H diff --git a/src/Imath/ImathFrustum.h b/src/Imath/ImathFrustum.h index 7fbf1337..22faf532 100644 --- a/src/Imath/ImathFrustum.h +++ b/src/Imath/ImathFrustum.h @@ -3,6 +3,10 @@ // Copyright Contributors to the OpenEXR Project. // +// +// A viewing frustum class +// + #ifndef INCLUDED_IMATHFRUSTUM_H #define INCLUDED_IMATHFRUSTUM_H @@ -16,138 +20,225 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER -// -// template class Frustum -// -// The frustum is always located with the eye point at the -// origin facing down -Z. This makes the Frustum class -// compatable with OpenGL (or anything that assumes a camera -// looks down -Z, hence with a right-handed coordinate system) -// but not with RenderMan which assumes the camera looks down -// +Z. Additional functions are provided for conversion from -// and from various camera coordinate spaces. -// -// nearPlane/farPlane: near/far are keywords used by Microsoft's -// compiler, so we use nearPlane/farPlane instead to avoid -// issues. +/// +/// Template class `Frustum` +/// +/// The frustum is always located with the eye point at the origin +/// facing down -Z. This makes the Frustum class compatable with +/// OpenGL (or anything that assumes a camera looks down -Z, hence +/// with a right-handed coordinate system) but not with RenderMan +/// which assumes the camera looks down +Z. Additional functions are +/// provided for conversion from and from various camera coordinate +/// spaces. +/// +/// nearPlane/farPlane: near/far are keywords used by Microsoft's +/// compiler, so we use nearPlane/farPlane instead to avoid +/// issues. template class Frustum { public: + + /// @{ + /// @name Constructors and Assignment + /// + + /// Initialize with default values: + /// near=0.1, far=1000.0, left=-1.0, right=1.0, top=1.0, bottom=-1.0, ortho=false IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Frustum() noexcept; + + /// Copy constructor IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Frustum (const Frustum&) noexcept; + + /// Initialize to specific values IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Frustum (T nearPlane, T farPlane, T left, T right, T top, T bottom, bool ortho = false) noexcept; + + /// Initialize with fov and aspect IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Frustum (T nearPlane, T farPlane, T fovx, T fovy, T aspect) noexcept; - virtual ~Frustum() noexcept; - //-------------------- - // Assignment operator - //-------------------- + /// Destructor + virtual ~Frustum() noexcept; + /// Component-wise assignment IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Frustum& operator= (const Frustum&) noexcept; - //-------------------- - // Operators: ==, != - //-------------------- - - IMATH_HOSTDEVICE constexpr bool operator== (const Frustum& src) const noexcept; - IMATH_HOSTDEVICE constexpr bool operator!= (const Frustum& src) const noexcept; - - //-------------------------------------------------------- - // Set functions change the entire state of the Frustum - //-------------------------------------------------------- - - IMATH_HOSTDEVICE void - set (T nearPlane, T farPlane, T left, T right, T top, T bottom, bool ortho = false) noexcept; - - IMATH_HOSTDEVICE void set (T nearPlane, T farPlane, T fovx, T fovy, T aspect) noexcept; - void setExc (T nearPlane, T farPlane, T fovx, T fovy, T aspect); + /// @} - //------------------------------------------------------ - // These functions modify an already valid frustum state - //------------------------------------------------------ + /// @{ + /// @name Comparison - IMATH_HOSTDEVICE void modifyNearAndFar (T nearPlane, T farPlane) noexcept; - IMATH_HOSTDEVICE void setOrthographic (bool) noexcept; + /// Equality + IMATH_HOSTDEVICE constexpr bool operator== (const Frustum& src) const noexcept; - //-------------- - // Access - //-------------- + /// Inequality + IMATH_HOSTDEVICE constexpr bool operator!= (const Frustum& src) const noexcept; + /// @} + + /// @{ + /// @name Query + + /// Return true if the frustum is orthographic, false if perspective IMATH_HOSTDEVICE constexpr bool orthographic() const noexcept { return _orthographic; } + + /// Return the near clipping plane IMATH_HOSTDEVICE constexpr T nearPlane() const noexcept { return _nearPlane; } + + /// Return the near clipping plane IMATH_HOSTDEVICE constexpr T hither() const noexcept { return _nearPlane; } + + /// Return the far clipping plane IMATH_HOSTDEVICE constexpr T farPlane() const noexcept { return _farPlane; } + + /// Return the far clipping plane IMATH_HOSTDEVICE constexpr T yon() const noexcept { return _farPlane; } + + /// Return the left of the frustum IMATH_HOSTDEVICE constexpr T left() const noexcept { return _left; } - IMATH_HOSTDEVICE constexpr T right() const noexcept { return _right; } - IMATH_HOSTDEVICE constexpr T bottom() const noexcept { return _bottom; } - IMATH_HOSTDEVICE constexpr T top() const noexcept { return _top; } - //----------------------------------------------------------------------- - // Sets the planes in p to be the six bounding planes of the frustum, in - // the following order: top, right, bottom, left, near, far. - // Note that the planes have normals that point out of the frustum. - // The version of this routine that takes a matrix applies that matrix - // to transform the frustum before setting the planes. - //----------------------------------------------------------------------- + /// Return the right of the frustum + IMATH_HOSTDEVICE constexpr T right() const noexcept { return _right; } - IMATH_HOSTDEVICE void planes (Plane3 p[6]) const noexcept; - IMATH_HOSTDEVICE void planes (Plane3 p[6], const Matrix44& M) const noexcept; + /// Return the bottom of the frustum + IMATH_HOSTDEVICE constexpr T bottom() const noexcept { return _bottom; } - //---------------------- - // Derived Quantities - //---------------------- + /// Return the top of the frustum + IMATH_HOSTDEVICE constexpr T top() const noexcept { return _top; } + /// Return the field of view in X IMATH_HOSTDEVICE constexpr T fovx() const noexcept; + + /// Return the field of view in Y IMATH_HOSTDEVICE constexpr T fovy() const noexcept; + + /// Return the aspect ratio IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T aspect() const noexcept; + + /// Return the aspect ratio. Throw an exception if the aspect + /// ratio is undefined. IMATH_CONSTEXPR14 T aspectExc() const; + + /// Return the project matrix that the frustum defines IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44 projectionMatrix() const noexcept; + + /// Return the project matrix that the frustum defines. Throw an + /// exception if the frustum is degenerate. IMATH_CONSTEXPR14 Matrix44 projectionMatrixExc() const; + + /// Return true if the frustum is degenerate. IMATH_HOSTDEVICE constexpr bool degenerate() const noexcept; - //----------------------------------------------------------------------- - // Takes a rectangle in the screen space (i.e., -1 <= left <= right <= 1 - // and -1 <= bottom <= top <= 1) of this Frustum, and returns a new - // Frustum whose near clipping-plane window is that rectangle in local - // space. - //----------------------------------------------------------------------- + /// @} + + /// @{ + /// @name Set Value + + /// Set functions change the entire state of the Frustum + IMATH_HOSTDEVICE void + set (T nearPlane, T farPlane, T left, T right, T top, T bottom, bool ortho = false) noexcept; + + /// Set functions change the entire state of the Frustum using + /// field of view and aspect ratio + IMATH_HOSTDEVICE void set (T nearPlane, T farPlane, T fovx, T fovy, T aspect) noexcept; + + /// Set functions change the entire state of the Frustum using + /// field of view and aspect ratio. Throw an exception if `fovx` + /// and/or `fovy` are invalid. + void setExc (T nearPlane, T farPlane, T fovx, T fovy, T aspect); + + /// Set the near and far clipping planes + IMATH_HOSTDEVICE void modifyNearAndFar (T nearPlane, T farPlane) noexcept; + + /// Set the ortographic state + IMATH_HOSTDEVICE void setOrthographic (bool) noexcept; + + /// Set the planes in p to be the six bounding planes of the frustum, in + /// the following order: top, right, bottom, left, near, far. + /// Note that the planes have normals that point out of the frustum. + IMATH_HOSTDEVICE void planes (Plane3 p[6]) const noexcept; + + /// Set the planes in p to be the six bounding planes of the + /// frustum, in the following order: top, right, bottom, left, + /// near, far. Note that the planes have normals that point out + /// of the frustum. Apply the given matrix to transform the + /// frustum before setting the planes. + IMATH_HOSTDEVICE void planes (Plane3 p[6], const Matrix44& M) const noexcept; + /// Takes a rectangle in the screen space (i.e., -1 <= left <= right <= 1 + /// and -1 <= bottom <= top <= 1) of this Frustum, and returns a new + /// Frustum whose near clipping-plane window is that rectangle in local + /// space. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 IMATH_HOSTDEVICE Frustum window (T left, T right, T top, T bottom) const noexcept; - //---------------------------------------------------------- - // Projection is in screen space / Conversion from Z-Buffer - //---------------------------------------------------------- + /// @} + /// @{ + /// @name Utility Methods + + /// Project a point in screen spaced to 3d ray IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Line3 projectScreenToRay (const Vec2&) const noexcept; + + /// Project a 3D point into screen coordinates IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec2 projectPointToScreen (const Vec3&) const noexcept; + + /// Project a 3D point into screen coordinates. Throw an + /// exception if the point cannot be projected. IMATH_CONSTEXPR14 Vec2 projectPointToScreenExc (const Vec3&) const; + /// Map a z value to its depth in the frustum. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T ZToDepth (long zval, long min, long max) const noexcept; + /// Map a z value to its depth in the frustum. IMATH_CONSTEXPR14 T ZToDepthExc (long zval, long min, long max) const; + + /// Map a normalized z value to its depth in the frustum. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T normalizedZToDepth (T zval) const noexcept; + + /// Map a normalized z value to its depth in the frustum. Throw an + /// exception on error. IMATH_CONSTEXPR14 T normalizedZToDepthExc (T zval) const; + + /// Map depth to z value. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 long DepthToZ (T depth, long zmin, long zmax) const noexcept; + + /// Map depth to z value. Throw an exception on error. IMATH_CONSTEXPR14 long DepthToZExc (T depth, long zmin, long zmax) const; + /// Compute worldRadius IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T worldRadius (const Vec3& p, T radius) const noexcept; + + /// Compute worldRadius. Throw an exception on error. IMATH_CONSTEXPR14 T worldRadiusExc (const Vec3& p, T radius) const; + + /// Compute screen radius IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T screenRadius (const Vec3& p, T radius) const noexcept; + + /// Compute screen radius. Throw an exception on error. IMATH_CONSTEXPR14 T screenRadiusExc (const Vec3& p, T radius) const; + /// @} + protected: + + /// Map point from screen space to local space IMATH_HOSTDEVICE constexpr Vec2 screenToLocal (const Vec2&) const noexcept; + + /// Map point from local space to screen space IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec2 localToScreen (const Vec2&) const noexcept; + + /// Map point from local space to screen space. Throw an exception + /// on error. IMATH_CONSTEXPR14 Vec2 localToScreenExc (const Vec2&) const; protected: + + /// @cond Doxygen_Suppress + T _nearPlane; T _farPlane; T _left; @@ -155,6 +246,8 @@ template class Frustum T _top; T _bottom; bool _orthographic; + + /// @endcond }; template IMATH_CONSTEXPR14 inline Frustum::Frustum() noexcept @@ -861,7 +954,10 @@ Frustum::planes (Plane3 p[6], const Matrix44& M) const noexcept } } +/// Frustum of type float typedef Frustum Frustumf; + +/// Frustum of type double typedef Frustum Frustumd; IMATH_INTERNAL_NAMESPACE_HEADER_EXIT diff --git a/src/Imath/ImathFrustumTest.h b/src/Imath/ImathFrustumTest.h index f916428b..6182dfae 100644 --- a/src/Imath/ImathFrustumTest.h +++ b/src/Imath/ImathFrustumTest.h @@ -3,17 +3,17 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHFRUSTUMTEST_H -#define INCLUDED_IMATHFRUSTUMTEST_H - -//------------------------------------------------------------------------- // -// This file contains algorithms applied to or in conjunction with -// Frustum visibility testing (Imath::Frustum). +// A viewing frustum class // -// Methods for frustum-based rejection of primitives are contained here. +// This file contains algorithms applied to or in conjunction with +// Frustum visibility testing (Imath::Frustum). // -//------------------------------------------------------------------------- +// Methods for frustum-based rejection of primitives are contained here. +// + +#ifndef INCLUDED_IMATHFRUSTUMTEST_H +#define INCLUDED_IMATHFRUSTUMTEST_H #include "ImathBox.h" #include "ImathFrustum.h" @@ -24,72 +24,69 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER -///////////////////////////////////////////////////////////////// -// FrustumTest -// -// template class FrustumTest -// -// This is a helper class, designed to accelerate the case -// where many tests are made against the same frustum. -// That's a really common case. -// -// The acceleration is achieved by pre-computing the planes of -// the frustum, along with the ablsolute values of the plane normals. -// - -////////////////////////////////////////////////////////////////// -// How to use this -// -// Given that you already have: -// Imath::Frustum myFrustum -// Imath::Matrix44 myCameraWorldMatrix -// -// First, make a frustum test object: -// FrustumTest myFrustumTest(myFrustum, myCameraWorldMatrix) -// -// Whenever the camera or frustum changes, call: -// myFrustumTest.setFrustum(myFrustum, myCameraWorldMatrix) -// -// For each object you want to test for visibility, call: -// myFrustumTest.isVisible(myBox) -// myFrustumTest.isVisible(mySphere) -// myFrustumTest.isVisible(myVec3) -// myFrustumTest.completelyContains(myBox) -// myFrustumTest.completelyContains(mySphere) -// - -////////////////////////////////////////////////////////////////// -// Explanation of how it works -// -// -// We store six world-space Frustum planes (nx, ny, nz, offset) -// -// Points: To test a Vec3 for visibility, test it against each plane -// using the normal (v dot n - offset) method. (the result is exact) -// -// BBoxes: To test an axis-aligned bbox, test the center against each plane -// using the normal (v dot n - offset) method, but offset by the -// box extents dot the abs of the plane normal. (the result is NOT -// exact, but will not return false-negatives.) -// -// Spheres: To test a sphere, test the center against each plane -// using the normal (v dot n - offset) method, but offset by the -// sphere's radius. (the result is NOT exact, but will not return -// false-negatives.) -// -// -// SPECIAL NOTE: "Where are the dot products?" -// Actual dot products are currently slow for most SIMD architectures. -// In order to keep this code optimization-ready, the dot products -// are all performed using vector adds and multipies. -// -// In order to do this, the plane equations are stored in "transpose" -// form, with the X components grouped into an X vector, etc. -// +/// +/// template class FrustumTest +/// +/// This is a helper class, designed to accelerate the case +/// where many tests are made against the same frustum. +/// That's a really common case. +/// +/// The acceleration is achieved by pre-computing the planes of +/// the frustum, along with the ablsolute values of the plane normals. +/// +/// How to use this +/// +/// Given that you already have: +/// Imath::Frustum myFrustum +/// Imath::Matrix44 myCameraWorldMatrix +/// +/// First, make a frustum test object: +/// FrustumTest myFrustumTest(myFrustum, myCameraWorldMatrix) +/// +/// Whenever the camera or frustum changes, call: +/// myFrustumTest.setFrustum(myFrustum, myCameraWorldMatrix) +/// +/// For each object you want to test for visibility, call: +/// myFrustumTest.isVisible(myBox) +/// myFrustumTest.isVisible(mySphere) +/// myFrustumTest.isVisible(myVec3) +/// myFrustumTest.completelyContains(myBox) +/// myFrustumTest.completelyContains(mySphere) +/// +/// Explanation of how it works +/// +/// We store six world-space Frustum planes (nx, ny, nz, offset) +/// +/// Points: To test a Vec3 for visibility, test it against each plane +/// using the normal (v dot n - offset) method. (the result is exact) +/// +/// BBoxes: To test an axis-aligned bbox, test the center against each plane +/// using the normal (v dot n - offset) method, but offset by the +/// box extents dot the abs of the plane normal. (the result is NOT +/// exact, but will not return false-negatives.) +/// +/// Spheres: To test a sphere, test the center against each plane +/// using the normal (v dot n - offset) method, but offset by the +/// sphere's radius. (the result is NOT exact, but will not return +/// false-negatives.) +/// +/// +/// SPECIAL NOTE: "Where are the dot products?" +/// Actual dot products are currently slow for most SIMD architectures. +/// In order to keep this code optimization-ready, the dot products +/// are all performed using vector adds and multipies. +/// +/// In order to do this, the plane equations are stored in "transpose" +/// form, with the X components grouped into an X vector, etc. +/// template class FrustumTest { public: + /// @{ + /// @name Constructors + + /// Initialize camera matrix to identity FrustumTest() noexcept { Frustum frust; @@ -97,59 +94,80 @@ template class FrustumTest cameraMat.makeIdentity(); setFrustum (frust, cameraMat); } + + /// Initialize to a given frustum and camera matrix. FrustumTest (const Frustum& frustum, const Matrix44& cameraMat) noexcept { setFrustum (frustum, cameraMat); } - //////////////////////////////////////////////////////////////////// - // setFrustum() - // This updates the frustum test with a new frustum and matrix. - // This should usually be called just once per frame. + /// @} + + /// @{ + /// @name Set Value + + /// Update the frustum test with a new frustum and matrix. + /// This should usually be called just once per frame, or however + /// often the camera moves. void setFrustum (const Frustum& frustum, const Matrix44& cameraMat) noexcept; - //////////////////////////////////////////////////////////////////// - // isVisible() - // Check to see if shapes are visible. + /// @} + + /// @{ + /// @name Query + + /// Return true if any part of the sphere is inside the frustum. + /// The result MAY return close false-positives, but not false-negatives. bool isVisible (const Sphere3& sphere) const noexcept; + + /// Return true if any part of the box is inside the frustum. + /// The result MAY return close false-positives, but not false-negatives. bool isVisible (const Box>& box) const noexcept; + + /// Return true if the point is inside the frustum. bool isVisible (const Vec3& vec) const noexcept; - //////////////////////////////////////////////////////////////////// - // completelyContains() - // Check to see if shapes are entirely contained. + /// Return true if every part of the sphere is inside the frustum. + /// The result MAY return close false-negatives, but not false-positives. bool completelyContains (const Sphere3& sphere) const noexcept; + + /// Return true if every part of the box is inside the frustum. + /// The result MAY return close false-negatives, but not false-positives. bool completelyContains (const Box>& box) const noexcept; - // These next items are kept primarily for debugging tools. - // It's useful for drawing the culling environment, and also - // for getting an "outside view" of the culling frustum. + /// Return the camera matrix (primarily for debugging) IMATH_INTERNAL_NAMESPACE::Matrix44 cameraMat() const noexcept { return cameraMatrix; } + + /// Return the viewing frustum (primarily for debugging) IMATH_INTERNAL_NAMESPACE::Frustum currentFrustum() const noexcept { return currFrustum; } + /// @} + protected: + // To understand why the planes are stored this way, see // the SPECIAL NOTE above. - Vec3 planeNormX[2]; // The X compunents from 6 plane equations - Vec3 planeNormY[2]; // The Y compunents from 6 plane equations - Vec3 planeNormZ[2]; // The Z compunents from 6 plane equations + + /// @cond Doxygen_Suppress + + Vec3 planeNormX[2]; // The X components from 6 plane equations + Vec3 planeNormY[2]; // The Y components from 6 plane equations + Vec3 planeNormZ[2]; // The Z components from 6 plane equations Vec3 planeOffsetVec[2]; // The distance offsets from 6 plane equations // The absolute values are stored to assist with bounding box tests. - Vec3 planeNormAbsX[2]; // The abs(X) compunents from 6 plane equations - Vec3 planeNormAbsY[2]; // The abs(X) compunents from 6 plane equations - Vec3 planeNormAbsZ[2]; // The abs(X) compunents from 6 plane equations + Vec3 planeNormAbsX[2]; // The abs(X) components from 6 plane equations + Vec3 planeNormAbsY[2]; // The abs(X) components from 6 plane equations + Vec3 planeNormAbsZ[2]; // The abs(X) components from 6 plane equations // These are kept primarily for debugging tools. Frustum currFrustum; Matrix44 cameraMatrix; + + /// @endcond }; -//////////////////////////////////////////////////////////////////// -// setFrustum() -// This should usually only be called once per frame, or however -// often the camera moves. template void FrustumTest::setFrustum (const Frustum& frustum, const Matrix44& cameraMat) noexcept @@ -191,12 +209,6 @@ FrustumTest::setFrustum (const Frustum& frustum, const Matrix44& camera cameraMatrix = cameraMat; } -//////////////////////////////////////////////////////////////////// -// isVisible(Sphere) -// Returns true if any part of the sphere is inside -// the frustum. -// The result MAY return close false-positives, but not false-negatives. -// template bool FrustumTest::isVisible (const Sphere3& sphere) const noexcept @@ -220,12 +232,6 @@ FrustumTest::isVisible (const Sphere3& sphere) const noexcept return true; } -//////////////////////////////////////////////////////////////////// -// completelyContains(Sphere) -// Returns true if every part of the sphere is inside -// the frustum. -// The result MAY return close false-negatives, but not false-positives. -// template bool FrustumTest::completelyContains (const Sphere3& sphere) const noexcept @@ -249,12 +255,6 @@ FrustumTest::completelyContains (const Sphere3& sphere) const noexcept return true; } -//////////////////////////////////////////////////////////////////// -// isVisible(Box) -// Returns true if any part of the axis-aligned box -// is inside the frustum. -// The result MAY return close false-positives, but not false-negatives. -// template bool FrustumTest::isVisible (const Box>& box) const noexcept @@ -283,12 +283,6 @@ FrustumTest::isVisible (const Box>& box) const noexcept return true; } -//////////////////////////////////////////////////////////////////// -// completelyContains(Box) -// Returns true if every part of the axis-aligned box -// is inside the frustum. -// The result MAY return close false-negatives, but not false-positives. -// template bool FrustumTest::completelyContains (const Box>& box) const noexcept @@ -317,10 +311,6 @@ FrustumTest::completelyContains (const Box>& box) const noexcept return true; } -//////////////////////////////////////////////////////////////////// -// isVisible(Vec3) -// Returns true if the point is inside the frustum. -// template bool FrustumTest::isVisible (const Vec3& vec) const noexcept @@ -341,7 +331,10 @@ FrustumTest::isVisible (const Vec3& vec) const noexcept return true; } +/// FrustymTest of type float typedef FrustumTest FrustumTestf; + +/// FrustymTest of type double typedef FrustumTest FrustumTestd; IMATH_INTERNAL_NAMESPACE_HEADER_EXIT diff --git a/src/Imath/ImathGL.h b/src/Imath/ImathGL.h index a42461eb..d83bdc7c 100644 --- a/src/Imath/ImathGL.h +++ b/src/Imath/ImathGL.h @@ -3,6 +3,10 @@ // Copyright Contributors to the OpenEXR Project. // +// +// Convenience functions that call GL with Imath types +// + #ifndef INCLUDED_IMATHGL_H #define INCLUDED_IMATHGL_H @@ -13,42 +17,49 @@ #include "ImathNamespace.h" #include "ImathVec.h" +/// Call glVertex3f inline void glVertex (const IMATH_INTERNAL_NAMESPACE::V3f& v) { glVertex3f (v.x, v.y, v.z); } +/// Call glVertex2f inline void glVertex (const IMATH_INTERNAL_NAMESPACE::V2f& v) { glVertex2f (v.x, v.y); } +/// Call glNormal3f inline void glNormal (const IMATH_INTERNAL_NAMESPACE::V3f& n) { glNormal3f (n.x, n.y, n.z); } +/// Call glColor3f inline void glColor (const IMATH_INTERNAL_NAMESPACE::V3f& c) { glColor3f (c.x, c.y, c.z); } +/// Call glTranslatef inline void glTranslate (const IMATH_INTERNAL_NAMESPACE::V3f& t) { glTranslatef (t.x, t.y, t.z); } +/// Call glTexCoord2f inline void glTexCoord (const IMATH_INTERNAL_NAMESPACE::V2f& t) { glTexCoord2f (t.x, t.y); } +/// Disable GL textures inline void glDisableTexture() { @@ -72,6 +83,7 @@ badFloat (float f) } // namespace +/// Throw an exception if m is not a valid matrix for GL inline void throwBadMatrix (const IMATH_INTERNAL_NAMESPACE::M44f& m) { @@ -82,6 +94,7 @@ throwBadMatrix (const IMATH_INTERNAL_NAMESPACE::M44f& m) throw IEX_NAMESPACE::OverflowExc ("GL matrix overflow"); } +/// Call glMultmatrixf. Throw an exception if m is not a valid matrix for GL. inline void glMultMatrix (const IMATH_INTERNAL_NAMESPACE::M44f& m) { @@ -89,6 +102,7 @@ glMultMatrix (const IMATH_INTERNAL_NAMESPACE::M44f& m) glMultMatrixf ((GLfloat*) m[0]); } +/// Call glMultmatrixf. Throw an exception if m is not a valid matrix for GL. inline void glMultMatrix (const IMATH_INTERNAL_NAMESPACE::M44f* m) { @@ -96,6 +110,7 @@ glMultMatrix (const IMATH_INTERNAL_NAMESPACE::M44f* m) glMultMatrixf ((GLfloat*) (*m)[0]); } +/// Call glLoadmatrixf. Throw an exception if m is not a valid matrix for GL. inline void glLoadMatrix (const IMATH_INTERNAL_NAMESPACE::M44f& m) { @@ -103,6 +118,7 @@ glLoadMatrix (const IMATH_INTERNAL_NAMESPACE::M44f& m) glLoadMatrixf ((GLfloat*) m[0]); } +/// Call glLoadmatrixf. Throw an exception if m is not a valid matrix for GL. inline void glLoadMatrix (const IMATH_INTERNAL_NAMESPACE::M44f* m) { @@ -112,10 +128,10 @@ glLoadMatrix (const IMATH_INTERNAL_NAMESPACE::M44f* m) IMATH_INTERNAL_NAMESPACE_HEADER_ENTER -// -// Class objects that push/pop the GL state. These objects assist with -// proper cleanup of the state when exceptions are thrown. -// +/// +/// A class object that pushes/pops the GL matrix. This object assists with +/// proper cleanup of the state when exceptions are thrown. +/// class GLPushMatrix { @@ -124,17 +140,34 @@ class GLPushMatrix ~GLPushMatrix() { glPopMatrix(); } }; +/// +/// A class object that pushes/pops the current GL attribute state. This object assists with +/// proper cleanup of the state when exceptions are thrown. +/// + class GLPushAttrib { public: + /// call glPushAttrib() GLPushAttrib (GLbitfield mask) { glPushAttrib (mask); } + + /// call glPopAttrib() ~GLPushAttrib() { glPopAttrib(); } }; +/// +/// A class object that wraps glBegin/glEnd. The constructor calls +/// glBegin(). The destructor calls glEnd(). +/// + class GLBegin { public: + + /// Call glBegin() GLBegin (GLenum mode) { glBegin (mode); } + + /// Call glEnd() ~GLBegin() { glEnd(); } }; diff --git a/src/Imath/ImathGLU.h b/src/Imath/ImathGLU.h index 5bf0a7cf..231da831 100644 --- a/src/Imath/ImathGLU.h +++ b/src/Imath/ImathGLU.h @@ -3,6 +3,10 @@ // Copyright Contributors to the OpenEXR Project. // +// +// Convenience functions that call GLU with Imath types +// + #ifndef INCLUDED_IMATHGLU_H #define INCLUDED_IMATHGLU_H @@ -11,6 +15,7 @@ #include "ImathVec.h" +/// Call gluLookAt with the given position, interest, and up-vector. inline void gluLookAt (const IMATH_INTERNAL_NAMESPACE::V3f& pos, const IMATH_INTERNAL_NAMESPACE::V3f& interest, diff --git a/src/Imath/ImathHalfLimits.h b/src/Imath/ImathHalfLimits.h index d94afdf1..32660e47 100644 --- a/src/Imath/ImathHalfLimits.h +++ b/src/Imath/ImathHalfLimits.h @@ -3,14 +3,12 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHHALFLIMITS_H -#define INCLUDED_IMATHHALFLIMITS_H - -//-------------------------------------------------- // -// Imath-style limits for class half. +// Imath-style limits for class half. // -//-------------------------------------------------- + +#ifndef INCLUDED_IMATHHALFLIMITS_H +#define INCLUDED_IMATHHALFLIMITS_H #include "ImathLimits.h" #include "ImathNamespace.h" @@ -19,13 +17,27 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER +/// +/// class of static methods return limit values of type half. +/// + template <> struct limits { + /// Largest possible negative value IMATH_HOSTDEVICE static constexpr float min() noexcept { return -HALF_MAX; } + + /// Largest possible positive value IMATH_HOSTDEVICE static constexpr float max() noexcept { return HALF_MAX; } + + /// Smallest possible positive value IMATH_HOSTDEVICE static constexpr float smallest() noexcept { return HALF_MIN; } + + /// Smallest possible e for which 1+e != 1 IMATH_HOSTDEVICE static constexpr float epsilon() noexcept { return HALF_EPSILON; } + + /// Return false: half is not integral. IMATH_HOSTDEVICE static constexpr bool isIntegral() noexcept { return false; } + /// Return true: half is signed. IMATH_HOSTDEVICE static constexpr bool isSigned() noexcept { return true; } }; diff --git a/src/Imath/ImathInt64.h b/src/Imath/ImathInt64.h index 037168e0..8ee31c77 100644 --- a/src/Imath/ImathInt64.h +++ b/src/Imath/ImathInt64.h @@ -3,14 +3,12 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATH_INT64_H -#define INCLUDED_IMATH_INT64_H - -//---------------------------------------------------------------------------- // -// Int64 -- unsigned 64-bit integers +// 64-bit integer types // -//---------------------------------------------------------------------------- + +#ifndef INCLUDED_IMATH_INT64_H +#define INCLUDED_IMATH_INT64_H #include "ImathNamespace.h" #include @@ -18,13 +16,19 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER #if (defined _WIN32 || defined _WIN64) && _MSC_VER >= 1300 +/// Int64 - unsigned 64-bit integer typedef unsigned __int64 Int64; +/// SInt64 - signed 64-bit integer typedef __int64 SInt64; #elif ULONG_MAX == 18446744073709551615LU +/// Int64 - unsigned 64-bit integer typedef long unsigned int Int64; +/// SInt64 - signed 64-bit integer typedef long int SInt64; #else +/// Int64 - unsigned 64-bit integer typedef long long unsigned int Int64; +/// SInt64 - signed 64-bit integer typedef long long int SInt64; #endif diff --git a/src/Imath/ImathInterval.h b/src/Imath/ImathInterval.h index 0eb36db6..bc5006d3 100644 --- a/src/Imath/ImathInterval.h +++ b/src/Imath/ImathInterval.h @@ -3,91 +3,126 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHINTERVAL_H -#define INCLUDED_IMATHINTERVAL_H - -//------------------------------------------------------------------- -// -// class Imath::Interval -// -------------------------------- // -// An Interval has a min and a max and some miscellaneous -// functions. It is basically a Box that allows T to be -// a scalar. +// An interval class // -//------------------------------------------------------------------- + +#ifndef INCLUDED_IMATHINTERVAL_H +#define INCLUDED_IMATHINTERVAL_H #include "ImathNamespace.h" #include "ImathVec.h" IMATH_INTERNAL_NAMESPACE_HEADER_ENTER +/// +/// An Interval has a min and a max and some miscellaneous +/// functions. It is basically a Box that allows T to be a scalar. +/// + template class Interval { public: - //------------------------- - // Data Members are public - //------------------------- + /// @{ + /// @name Direct access to bounds + + /// The minimum value of the interval T min; + + /// The minimum value of the interval T max; - //----------------------------------------------------- - // Constructors - an "empty" Interval is created by default - //----------------------------------------------------- + /// @} + + /// @{ + /// @name Constructors + /// Initialize to the empty interval IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Interval() noexcept; + + /// Intitialize to a single point IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Interval (const T& point) noexcept; + + /// Intitialize to a given (min,max) IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Interval (const T& minT, const T& maxT) noexcept; - //-------------------------------- - // Operators: we get != from STL - //-------------------------------- + /// @} + + /// @{ + /// @name Comparison + /// Equality IMATH_HOSTDEVICE constexpr bool operator== (const Interval& src) const noexcept; + /// Inequality IMATH_HOSTDEVICE constexpr bool operator!= (const Interval& src) const noexcept; - //------------------ - // Interval manipulation - //------------------ + /// @} + /// @{ + /// @name Manipulation + + /// Set the interval to be empty. An interval is empty if the + /// minimum is greater than the maximum. IMATH_HOSTDEVICE void makeEmpty() noexcept; + + /// Extend the interval to include the given point. IMATH_HOSTDEVICE void extendBy (const T& point) noexcept; + + /// Extend the interval to include the given interval IMATH_HOSTDEVICE void extendBy (const Interval& interval) noexcept; + + /// Make the interval include the entire range of the base type. IMATH_HOSTDEVICE void makeInfinite() noexcept; - //--------------------------------------------------- - // Query functions - these compute results each time - //--------------------------------------------------- + /// @} + /// @{ + /// @name Query + + /// Return the size of the interval. The size is (max-min). An empty box has a size of 0. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T size() const noexcept; + + /// Return the center of the interval. The center is defined as + /// (max+min)/2. The center of an empty interval is undefined. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T center() const noexcept; + + /// Return true if the given point is inside the interval, false otherwise. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersects (const T& point) const noexcept; + + /// Return true if the given interval is inside the interval, false otherwise. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersects (const Interval& interval) const noexcept; - //---------------- - // Classification - //---------------- + /// Return true if the interval is empty, false otherwise. An + /// empty interval's minimum is greater than its maximum. + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isEmpty() const noexcept; + /// Return true if the interval is larger than a single point, + /// false otherwise. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool hasVolume() const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isEmpty() const noexcept; + + /// Return true if the interval contains all points, false + /// otherwise. An infinite box has a mimimum of `limits::min` + /// and a maximum of `limits::max` IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isInfinite() const noexcept; + + /// @} }; +/// Stream output template std::ostream& operator<< (std::ostream& s, const Interval& v); -//-------------------- -// Convenient typedefs -//-------------------- - +/// Interval of type float typedef Interval Intervalf; + +/// Interval of type double typedef Interval Intervald; + +/// Interval of type short typedef Interval Intervals; -typedef Interval Intervali; -//---------------- -// Implementation -//---------------- +/// Interval of type integer +typedef Interval Intervali; template inline IMATH_CONSTEXPR14 Interval::Interval() noexcept { @@ -214,6 +249,7 @@ Interval::isInfinite() const noexcept return true; } +/// Stream output template std::ostream& operator<< (std::ostream& s, const Interval& v) diff --git a/src/Imath/ImathLimits.h b/src/Imath/ImathLimits.h index c0978ea6..f4fbfb65 100644 --- a/src/Imath/ImathLimits.h +++ b/src/Imath/ImathLimits.h @@ -3,14 +3,12 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHLIMITS_H -#define INCLUDED_IMATHLIMITS_H - -//---------------------------------------------------------------- // -// Limitations of the basic C++ numerical data types +// Limitations of the basic C++ numerical data types // -//---------------------------------------------------------------- + +#ifndef INCLUDED_IMATHLIMITS_H +#define INCLUDED_IMATHLIMITS_H #include "ImathNamespace.h" #include @@ -31,7 +29,6 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER -//----------------------------------------------------------------- // // Template class limits returns information about the limits // of numerical data type T: @@ -80,21 +77,34 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER // are implemented as inlines. No objects of type limits are // ever created. // -//----------------------------------------------------------------- + +/// +/// Template class limits returns information about the limits +/// of numerical data type T. +/// template struct limits { + /// Largest possible negative value IMATH_HOSTDEVICE static constexpr T min() noexcept; + + /// Largest possible positive value IMATH_HOSTDEVICE static constexpr T max() noexcept; + + /// Smallest possible positive value IMATH_HOSTDEVICE static constexpr T smallest() noexcept; + + /// Smallest possible e for which 1+e != 1 IMATH_HOSTDEVICE static constexpr T epsilon() noexcept; + + /// Return true if the type is integral. IMATH_HOSTDEVICE static constexpr bool isIntegral() noexcept; + + /// Return true if the type is signed. IMATH_HOSTDEVICE static constexpr bool isSigned() noexcept; }; -//--------------- -// Implementation -//--------------- +/// @cond Doxygen_Suppress template <> struct limits { @@ -216,6 +226,8 @@ template <> struct limits IMATH_HOSTDEVICE static constexpr bool isSigned() noexcept { return true; } }; +/// @endcond + IMATH_INTERNAL_NAMESPACE_HEADER_EXIT #endif // INCLUDED_IMATHLIMITS_H diff --git a/src/Imath/ImathLine.h b/src/Imath/ImathLine.h index 74f50ecb..5a8afeed 100644 --- a/src/Imath/ImathLine.h +++ b/src/Imath/ImathLine.h @@ -3,14 +3,12 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHLINE_H -#define INCLUDED_IMATHLINE_H - -//------------------------------------- // -// A 3D line class template +// A 3D line class template // -//------------------------------------- + +#ifndef INCLUDED_IMATHLINE_H +#define INCLUDED_IMATHLINE_H #include "ImathLimits.h" #include "ImathMatrix.h" @@ -19,51 +17,73 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER +/// +/// The `Line3` class represents a 3D line, defined by a point and a +/// direction vector. +/// + template class Line3 { public: + + /// @{ + /// @name Direct access to member fields + + /// A point on the line Vec3 pos; + + /// The direction of the line Vec3 dir; - //------------------------------------------------------------- - // Constructors - default is normalized units along direction - //------------------------------------------------------------- + /// @} + + /// @{ + /// @name Constructors + /// Uninitialized by default IMATH_HOSTDEVICE constexpr Line3() noexcept {} - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Line3 (const Vec3& point1, const Vec3& point2) noexcept; - //------------------ - // State Query/Set - //------------------ + /// Initialize with two points. The direction is the difference + /// between the points. + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Line3 (const Vec3& point1, const Vec3& point2) noexcept; + /// @} + + /// @{ + /// @name Manipulation + + /// Set the line defined by two points. The direction is the difference + /// between the points. IMATH_HOSTDEVICE void set (const Vec3& point1, const Vec3& point2) noexcept; - //------- - // F(t) - //------- + /// @} + /// @{ + /// @name Utility Methods + + /// Return the point on the line at the given parameter value, + /// e.g. L(t) IMATH_HOSTDEVICE constexpr Vec3 operator() (T parameter) const noexcept; - //--------- - // Query - //--------- - + /// Return the distance to the given point IMATH_HOSTDEVICE constexpr T distanceTo (const Vec3& point) const noexcept; + /// Return the distance to the given line IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T distanceTo (const Line3& line) const noexcept; + + /// Return the point on the line closest to the given point IMATH_HOSTDEVICE constexpr Vec3 closestPointTo (const Vec3& point) const noexcept; + + /// Return the point on the line closest to the given line IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec3 closestPointTo (const Line3& line) const noexcept; -}; -//-------------------- -// Convenient typedefs -//-------------------- + /// @} +}; +/// Line of type float typedef Line3 Line3f; -typedef Line3 Line3d; -//--------------- -// Implementation -//--------------- +/// Line of type double +typedef Line3 Line3d; template IMATH_CONSTEXPR14 inline Line3::Line3 (const Vec3& p0, const Vec3& p1) noexcept { @@ -135,6 +155,7 @@ Line3::closestPointTo (const Line3& line) const noexcept return pos + dir * (num / denom); } +/// Stream output template std::ostream& operator<< (std::ostream& o, const Line3& line) @@ -142,6 +163,7 @@ operator<< (std::ostream& o, const Line3& line) return o << "(" << line.pos << ", " << line.dir << ")"; } +/// Transform a line by a matrix template constexpr inline Line3 operator* (const Line3& line, const Matrix44& M) noexcept diff --git a/src/Imath/ImathLineAlgo.h b/src/Imath/ImathLineAlgo.h index 692325e7..0ec3c508 100644 --- a/src/Imath/ImathLineAlgo.h +++ b/src/Imath/ImathLineAlgo.h @@ -3,42 +3,12 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHLINEALGO_H -#define INCLUDED_IMATHLINEALGO_H - -//------------------------------------------------------------------ -// -// This file contains algorithms applied to or in conjunction -// with lines (Imath::Line). These algorithms may require -// more headers to compile. The assumption made is that these -// functions are called much less often than the basic line -// functions or these functions require more support classes -// -// Contains: -// -// bool closestPoints(const Line& line1, -// const Line& line2, -// Vec3& point1, -// Vec3& point2) -// -// bool intersect( const Line3 &line, -// const Vec3 &v0, -// const Vec3 &v1, -// const Vec3 &v2, -// Vec3 &pt, -// Vec3 &barycentric, -// bool &front) -// -// V3f -// closestVertex(const Vec3 &v0, -// const Vec3 &v1, -// const Vec3 &v2, -// const Line3 &l) // -// V3f -// rotatePoint(const Vec3 p, Line3 l, float angle) +// Algorithms applied to or in conjunction with Imath::Line class // -//------------------------------------------------------------------ + +#ifndef INCLUDED_IMATHLINEALGO_H +#define INCLUDED_IMATHLINEALGO_H #include "ImathFun.h" #include "ImathLine.h" @@ -47,18 +17,19 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER +/// +/// Compute point1 and point2 such that point1 is on line1, point2 +/// is on line2 and the distance between point1 and point2 is minimal. +/// +/// This function returns true if point1 and point2 can be computed, +/// or false if line1 and line2 are parallel or nearly parallel. +/// This function assumes that line1.dir and line2.dir are normalized. +/// + template IMATH_CONSTEXPR14 bool closestPoints (const Line3& line1, const Line3& line2, Vec3& point1, Vec3& point2) noexcept { - // - // Compute point1 and point2 such that point1 is on line1, point2 - // is on line2 and the distance between point1 and point2 is minimal. - // This function returns true if point1 and point2 can be computed, - // or false if line1 and line2 are parallel or nearly parallel. - // This function assumes that line1.dir and line2.dir are normalized. - // - Vec3 w = line1.pos - line2.pos; T d1w = line1.dir ^ w; T d2w = line2.dir ^ w; @@ -80,6 +51,30 @@ closestPoints (const Line3& line1, const Line3& line2, Vec3& point1, Ve } } +/// +/// Given a line and a triangle (v0, v1, v2), the intersect() function +/// finds the intersection of the line and the plane that contains the +/// triangle. +/// +/// If the intersection point cannot be computed, either because the +/// line and the triangle's plane are nearly parallel or because the +/// triangle's area is very small, intersect() returns false. +/// +/// If the intersection point is outside the triangle, intersect +/// returns false. +/// +/// If the intersection point, pt, is inside the triangle, intersect() +/// computes a front-facing flag and the barycentric coordinates of +/// the intersection point, and returns true. +/// +/// The front-facing flag is true if the dot product of the triangle's +/// normal, (v2-v1)%(v1-v0), and the line's direction is negative. +/// +/// The barycentric coordinates have the following property: +/// +/// pt = v0 * barycentric.x + v1 * barycentric.y + v2 * barycentric.z +/// + template IMATH_CONSTEXPR14 bool intersect (const Line3& line, @@ -90,30 +85,6 @@ intersect (const Line3& line, Vec3& barycentric, bool& front) noexcept { - // - // Given a line and a triangle (v0, v1, v2), the intersect() function - // finds the intersection of the line and the plane that contains the - // triangle. - // - // If the intersection point cannot be computed, either because the - // line and the triangle's plane are nearly parallel or because the - // triangle's area is very small, intersect() returns false. - // - // If the intersection point is outside the triangle, intersect - // returns false. - // - // If the intersection point, pt, is inside the triangle, intersect() - // computes a front-facing flag and the barycentric coordinates of - // the intersection point, and returns true. - // - // The front-facing flag is true if the dot product of the triangle's - // normal, (v2-v1)%(v1-v0), and the line's direction is negative. - // - // The barycentric coordinates have the following property: - // - // pt = v0 * barycentric.x + v1 * barycentric.y + v2 * barycentric.z - // - Vec3 edge0 = v1 - v0; Vec3 edge1 = v2 - v1; Vec3 normal = edge1 % edge0; @@ -183,6 +154,11 @@ intersect (const Line3& line, return true; } +/// +/// Return the vertex that is closest to the given line. The returned +/// point is either v0, v1, or v2. +/// + template IMATH_CONSTEXPR14 Vec3 closestVertex (const Vec3& v0, const Vec3& v1, const Vec3& v2, const Line3& l) noexcept @@ -208,14 +184,14 @@ closestVertex (const Vec3& v0, const Vec3& v1, const Vec3& v2, const Li return nearest; } +/// +/// Rotate the point p around the line l by the given angle. +/// + template IMATH_CONSTEXPR14 Vec3 rotatePoint (const Vec3 p, Line3 l, T angle) noexcept { - // - // Rotate the point p around the line l by the given angle. - // - // // Form a coordinate frame with . The rotation is the in xy // plane. diff --git a/src/Imath/ImathMath.h b/src/Imath/ImathMath.h index 9072412e..058b0152 100644 --- a/src/Imath/ImathMath.h +++ b/src/Imath/ImathMath.h @@ -3,6 +3,11 @@ // Copyright Contributors to the OpenEXR Project. // +// +// Obsolete functions provided for compatibility, deprecated in favor +// of std:: functions. +// + #ifndef INCLUDED_IMATHMATH_H #define INCLUDED_IMATHMATH_H @@ -28,6 +33,7 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER // //---------------------------------------------------------------------------- +/// @cond Doxygen_Suppress template struct Math { IMATH_HOSTDEVICE IMATH_DEPRECATED("use std::math functions") @@ -99,13 +105,11 @@ template struct Math IMATH_HOSTDEVICE IMATH_DEPRECATED("use std::math functions") static T hypot (T x, T y) { return std::hypot (x, y); } }; +/// @endcond -//-------------------------------------------------------------------------- -// Don Hatch's version of sin(x)/x, which is accurate for very small x. -// Returns 1 for x == 0. -//-------------------------------------------------------------------------- - +/// Don Hatch's version of sin(x)/x, which is accurate for very small x. +/// Returns 1 for x == 0. template IMATH_HOSTDEVICE inline T sinx_over_x (T x) @@ -116,25 +120,12 @@ sinx_over_x (T x) return std::sin (x) / x; } -//-------------------------------------------------------------------------- -// Compare two numbers and test if they are "approximately equal": -// -// equalWithAbsError (x1, x2, e) -// -// Returns true if x1 is the same as x2 with an absolute error of -// no more than e, -// -// abs (x1 - x2) <= e -// -// equalWithRelError (x1, x2, e) -// -// Returns true if x1 is the same as x2 with an relative error of -// no more than e, -// -// abs (x1 - x2) <= e * x1 -// -//-------------------------------------------------------------------------- - +/// Compare two numbers and test if they are "approximately equal": +/// +/// @return Ttrue if x1 is the same as x2 with an absolute error of +/// no more than e: +/// +/// abs (x1 - x2) <= e template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool equalWithAbsError (T x1, T x2, T e) noexcept @@ -142,6 +133,12 @@ equalWithAbsError (T x1, T x2, T e) noexcept return ((x1 > x2) ? x1 - x2 : x2 - x1) <= e; } +/// Compare two numbers and test if they are "approximately equal": +/// +/// @return True if x1 is the same as x2 with an relative error of +/// no more than e, +/// +/// abs (x1 - x2) <= e * x1 template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool equalWithRelError (T x1, T x2, T e) noexcept diff --git a/src/Imath/ImathMatrix.h b/src/Imath/ImathMatrix.h index 46d828f2..113bd213 100644 --- a/src/Imath/ImathMatrix.h +++ b/src/Imath/ImathMatrix.h @@ -3,14 +3,12 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHMATRIX_H -#define INCLUDED_IMATHMATRIX_H - -//---------------------------------------------------------------- // -// 2D (3x3) and 3D (4x4) transformation matrix templates. +// 2x2, 3x3, and 4x4 transformation matrix templates // -//---------------------------------------------------------------- + +#ifndef INCLUDED_IMATHMATRIX_H +#define INCLUDED_IMATHMATRIX_H #include "ImathFun.h" #include "ImathNamespace.h" @@ -30,237 +28,254 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER +/// Enum used to indicate uninitialized construction of Matrix22, +/// Matrix33, Matrix44 enum Uninitialized { UNINITIALIZED }; +/// +/// 2x2 transformation matrix +/// + template class Matrix22 { public: - //------------------- - // Access to elements - //------------------- + /// @{ + /// @name Direct access to elements + + /// Matrix elements T x[2][2]; + /// @} + + /// Row access IMATH_HOSTDEVICE T* operator[] (int i) noexcept; + + /// Row access IMATH_HOSTDEVICE const T* operator[] (int i) const noexcept; - //------------- - // Constructors - //------------- + /// @{ + /// @name Constructors and Assignment + /// Uninitialized IMATH_HOSTDEVICE Matrix22 (Uninitialized) noexcept {} + /// Default constructor: initialize to identity + /// + /// 1 0 + /// 0 1 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22() noexcept; - // 1 0 - // 0 1 + /// Initialize to scalar constant: + /// + /// a a + /// a a IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22 (T a) noexcept; - // a a - // a a + /// Construct from 2x2 array: + /// + /// a[0][0] a[0][1] + /// a[1][0] a[1][1] IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22 (const T a[2][2]) noexcept; - // a[0][0] a[0][1] - // a[1][0] a[1][1] + /// Construct from given scalar values: + /// + /// a b + /// c d IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22 (T a, T b, T c, T d) noexcept; - // a b - // c d - - //-------------------------------- - // Copy constructor and assignment - //-------------------------------- + /// Copy constructor IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22 (const Matrix22& v) noexcept; + + /// Construct from Matrix22 of another base type template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 explicit Matrix22 (const Matrix22& v) noexcept; + /// Assignment IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator= (const Matrix22& v) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator= (T a) noexcept; - //------------ - // Destructor - //------------ + /// Assignment from scalar + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator= (T a) noexcept; + /// Destructor ~Matrix22() noexcept = default; - //---------------------- - // Compatibility with Sb - //---------------------- + /// @} + /// @{ + /// @name Compatibility with Sb + + /// Return a raw pointer to the array of values IMATH_HOSTDEVICE T* getValue() noexcept; + + /// Return a raw pointer to the array of values IMATH_HOSTDEVICE const T* getValue() const noexcept; + /// Return the value in `v` template IMATH_HOSTDEVICE void getValue (Matrix22& v) const noexcept; + + /// Set the value template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22& setValue (const Matrix22& v) noexcept; + /// Set the value template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22& setTheMatrix (const Matrix22& v) noexcept; - //--------- - // Identity - //--------- - - IMATH_HOSTDEVICE void makeIdentity() noexcept; - - //--------- - // Equality - //--------- + /// @} + /// @{ + /// @name Arithmetic and Comparison + + /// Equality IMATH_HOSTDEVICE constexpr bool operator== (const Matrix22& v) const noexcept; - IMATH_HOSTDEVICE constexpr bool operator!= (const Matrix22& v) const noexcept; - //----------------------------------------------------------------------- - // Compare two matrices and test if they are "approximately equal": - // - // equalWithAbsError (m, e) - // - // Returns true if the coefficients of this and m are the same with - // an absolute error of no more than e, i.e., for all i, j - // - // abs (this[i][j] - m[i][j]) <= e - // - // equalWithRelError (m, e) - // - // Returns true if the coefficients of this and m are the same with - // a relative error of no more than e, i.e., for all i, j - // - // abs (this[i] - v[i][j]) <= e * abs (this[i][j]) - //----------------------------------------------------------------------- + /// Inequality + IMATH_HOSTDEVICE constexpr bool operator!= (const Matrix22& v) const noexcept; + /// Compare two matrices and test if they are "approximately equal": + /// @return True if the coefficients of this and `m` are the same + /// with an absolute error of no more than e, i.e., for all i, j: + /// + /// abs (this[i][j] - m[i][j]) <= e IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError (const Matrix22& v, T e) const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Matrix22& v, T e) const noexcept; - //------------------------ - // Component-wise addition - //------------------------ + /// Compare two matrices and test if they are "approximately equal": + /// @return True if the coefficients of this and m are the same with + /// a relative error of no more than e, i.e., for all i, j: + /// + /// abs (this[i] - v[i][j]) <= e * abs (this[i][j]) + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Matrix22& v, T e) const noexcept; + /// Component-wise addition IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator+= (const Matrix22& v) noexcept; + + /// Component-wise addition IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator+= (T a) noexcept; - IMATH_HOSTDEVICE constexpr Matrix22 operator+ (const Matrix22& v) const noexcept; - //--------------------------- - // Component-wise subtraction - //--------------------------- + /// Component-wise addition + IMATH_HOSTDEVICE constexpr Matrix22 operator+ (const Matrix22& v) const noexcept; + /// Component-wise subtraction IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator-= (const Matrix22& v) noexcept; + + /// Component-wise subtraction IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator-= (T a) noexcept; - IMATH_HOSTDEVICE constexpr Matrix22 operator- (const Matrix22& v) const noexcept; - //------------------------------------ - // Component-wise multiplication by -1 - //------------------------------------ + /// Component-wise subtraction + IMATH_HOSTDEVICE constexpr Matrix22 operator- (const Matrix22& v) const noexcept; + /// Component-wise multiplication by -1 IMATH_HOSTDEVICE constexpr Matrix22 operator-() const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& negate() noexcept; - //------------------------------ - // Component-wise multiplication - //------------------------------ + /// Component-wise multiplication by -1 + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& negate() noexcept; + /// Component-wise multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator*= (T a) noexcept; + + /// Component-wise multiplication IMATH_HOSTDEVICE constexpr Matrix22 operator* (T a) const noexcept; - //----------------------------------- - // Matrix-times-matrix multiplication - //----------------------------------- + /// Component-wise division + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator/= (T a) noexcept; + + /// Component-wise division + IMATH_HOSTDEVICE constexpr Matrix22 operator/ (T a) const noexcept; + /// Matrix-matrix multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator*= (const Matrix22& v) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22 operator* (const Matrix22& v) const noexcept; - //----------------------------------------------------------------- - // Vector-times-matrix multiplication; see also the "operator *" - // functions defined below. - // - // m.multDirMatrix(src,dst) multiplies src by the matrix m. - //----------------------------------------------------------------- + /// Matrix-matrix multiplication + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22 operator* (const Matrix22& v) const noexcept; + /// Vector * matrix multiplication + /// @param[in] src Input vector + /// @param[out] dst transformed vector template IMATH_HOSTDEVICE void multDirMatrix (const Vec2& src, Vec2& dst) const noexcept; - //------------------------ - // Component-wise division - //------------------------ + /// @} - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator/= (T a) noexcept; - IMATH_HOSTDEVICE constexpr Matrix22 operator/ (T a) const noexcept; + /// @{ + /// @name Maniplation - //------------------ - // Transposed matrix - //------------------ + /// Set to the identity + IMATH_HOSTDEVICE void makeIdentity() noexcept; + /// Transpose IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& transpose() noexcept; - IMATH_HOSTDEVICE constexpr Matrix22 transposed() const noexcept; - //------------------------------------------------------------ - // Inverse matrix: If singExc is false, inverting a singular - // matrix produces an identity matrix. If singExc is true, - // inverting a singular matrix throws std::invalid_argument. - // - // inverse() and invert() invert matrices using determinants. - // - //------------------------------------------------------------ + /// Return the transpose + IMATH_HOSTDEVICE constexpr Matrix22 transposed() const noexcept; + /// Invert in place + /// @param singExc If true, throw an exception if the matrix cannot be inverted. + /// @return const reference to this IMATH_CONSTEXPR14 const Matrix22& invert (bool singExc); + + /// Invert in place + /// @return const reference to this IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& invert() noexcept; + /// Return the inverse, leaving this unmodified. + /// @param singExc If true, throw an exception if the matrix cannot be inverted. IMATH_CONSTEXPR14 Matrix22 inverse (bool singExc) const; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22 inverse() const noexcept; - //------------ - // Determinant - //------------ + /// Return the inverse, leaving this unmodified. + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22 inverse() const noexcept; + /// Determinant IMATH_HOSTDEVICE constexpr T determinant() const noexcept; - //----------------------------------------- - // Set matrix to rotation by r (in radians) - //----------------------------------------- - + /// Set matrix to rotation by r (in radians) + /// @return const referenced to this template IMATH_HOSTDEVICE const Matrix22& setRotation (S r) noexcept; - //----------------------------- - // Rotate the given matrix by r - //----------------------------- - + /// Rotate the given matrix by r (in radians) + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& rotate (S r) noexcept; - //-------------------------------------------- - // Set matrix to scale by given uniform factor - //-------------------------------------------- - + /// Set matrix to scale by given uniform factor + /// @return const referenced to this IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& setScale (T s) noexcept; - //------------------------------------ - // Set matrix to scale by given vector - //------------------------------------ - + /// Set matrix to scale by given vector + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& setScale (const Vec2& s) noexcept; - //---------------------- // Scale the matrix by s - //---------------------- - + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& scale (const Vec2& s) noexcept; - //-------------------------------------------------------- - // Number of the row and column dimensions, since - // Matrix22 is a square matrix. - //-------------------------------------------------------- - - IMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 2; } - - //------------------------------------------------- - // Limitations of type T (see also class limits) - //------------------------------------------------- - + /// @} + + /// @{ + /// @name Numeric Limits + + /// Largest possible negative value IMATH_HOSTDEVICE constexpr static T baseTypeMin() noexcept { return limits::min(); } + + /// Largest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeMax() noexcept { return limits::max(); } + + /// Smallest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeSmallest() noexcept { return limits::smallest(); } + + /// Smallest possible e for which 1+e != 1 IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() noexcept { return limits::epsilon(); } + /// @} + + /// Return the number of the row and column dimensions, i.e. 2. + IMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 2; } + + /// The base type: In templates that accept a parameter `V`, you + /// can refer to `T` as `V::BaseType` typedef T BaseType; + + /// The base vector type typedef Vec2 BaseVecType; private: @@ -281,314 +296,312 @@ template class Matrix22 }; }; +/// +/// 3x3 transformation matrix +/// + template class Matrix33 { public: - //------------------- - // Access to elements - //------------------- + /// @{ + /// @name Direct access to elements + + /// Matrix elements T x[3][3]; + /// @} + + /// Row access IMATH_HOSTDEVICE T* operator[] (int i) noexcept; + + /// Row access IMATH_HOSTDEVICE const T* operator[] (int i) const noexcept; - //------------- - // Constructors - //------------- + /// @{ + /// @name Constructors and Assignment + /// Uninitialized IMATH_HOSTDEVICE Matrix33 (Uninitialized) noexcept {} + /// Default constructor: initialize to identity + /// 1 0 0 + /// 0 1 0 + /// 0 0 1 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33() noexcept; - // 1 0 0 - // 0 1 0 - // 0 0 1 + /// Initialize to scalar constant + /// a a a + /// a a a + /// a a a IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33 (T a) noexcept; - // a a a - // a a a - // a a a + /// Construct from 3x3 array + /// a[0][0] a[0][1] a[0][2] + /// a[1][0] a[1][1] a[1][2] + /// a[2][0] a[2][1] a[2][2] IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33 (const T a[3][3]) noexcept; - // a[0][0] a[0][1] a[0][2] - // a[1][0] a[1][1] a[1][2] - // a[2][0] a[2][1] a[2][2] + /// Construct from given scalar values + /// a b c + /// d e f + /// g h i IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33 (T a, T b, T c, T d, T e, T f, T g, T h, T i) noexcept; - // a b c - // d e f - // g h i - - //-------------------------------- - // Copy constructor and assignment - //-------------------------------- + /// Copy constructor IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33 (const Matrix33& v) noexcept; + + /// Construct from Matrix33 of another base type template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 explicit Matrix33 (const Matrix33& v) noexcept; + /// Assignment operator IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator= (const Matrix33& v) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator= (T a) noexcept; - //------------ - // Destructor - //------------ + /// Assignment from scalar + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator= (T a) noexcept; + /// Destructor ~Matrix33() noexcept = default; - //---------------------- - // Compatibility with Sb - //---------------------- + /// @} + + /// @{ + /// @name Compatibility with Sb + /// Return a raw pointer to the array of values IMATH_HOSTDEVICE T* getValue() noexcept; + + /// Return a raw pointer to the array of values IMATH_HOSTDEVICE const T* getValue() const noexcept; + /// Return the value in `v` template IMATH_HOSTDEVICE void getValue (Matrix33& v) const noexcept; + + /// Set the value template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33& setValue (const Matrix33& v) noexcept; + /// Set the value template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33& setTheMatrix (const Matrix33& v) noexcept; - //--------- - // Identity - //--------- - - IMATH_HOSTDEVICE void makeIdentity() noexcept; - - //--------- - // Equality - //--------- - + /// @} + + /// @{ + /// @name Arithmetic and Comparison + + /// Equality IMATH_HOSTDEVICE constexpr bool operator== (const Matrix33& v) const noexcept; - IMATH_HOSTDEVICE constexpr bool operator!= (const Matrix33& v) const noexcept; - //----------------------------------------------------------------------- - // Compare two matrices and test if they are "approximately equal": - // - // equalWithAbsError (m, e) - // - // Returns true if the coefficients of this and m are the same with - // an absolute error of no more than e, i.e., for all i, j - // - // abs (this[i][j] - m[i][j]) <= e - // - // equalWithRelError (m, e) - // - // Returns true if the coefficients of this and m are the same with - // a relative error of no more than e, i.e., for all i, j - // - // abs (this[i] - v[i][j]) <= e * abs (this[i][j]) - //----------------------------------------------------------------------- + /// Inequality + IMATH_HOSTDEVICE constexpr bool operator!= (const Matrix33& v) const noexcept; + /// Compare two matrices and test if they are "approximately equal": + /// @return True if the coefficients of this and `m` are the same + /// with an absolute error of no more than e, i.e., for all i, j: + /// + /// abs (this[i][j] - m[i][j]) <= e IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError (const Matrix33& v, T e) const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Matrix33& v, T e) const noexcept; - //------------------------ - // Component-wise addition - //------------------------ + /// Compare two matrices and test if they are "approximately equal": + /// @return True if the coefficients of this and m are the same with + /// a relative error of no more than e, i.e., for all i, j: + /// + /// abs (this[i] - v[i][j]) <= e * abs (this[i][j]) + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Matrix33& v, T e) const noexcept; + /// Component-wise addition IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator+= (const Matrix33& v) noexcept; + + /// Component-wise addition IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator+= (T a) noexcept; - IMATH_HOSTDEVICE constexpr Matrix33 operator+ (const Matrix33& v) const noexcept; - //--------------------------- - // Component-wise subtraction - //--------------------------- + /// Component-wise addition + IMATH_HOSTDEVICE constexpr Matrix33 operator+ (const Matrix33& v) const noexcept; + /// Component-wise subtraction IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator-= (const Matrix33& v) noexcept; + + /// Component-wise subtraction IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator-= (T a) noexcept; - IMATH_HOSTDEVICE constexpr Matrix33 operator- (const Matrix33& v) const noexcept; - //------------------------------------ - // Component-wise multiplication by -1 - //------------------------------------ + /// Component-wise subtraction + IMATH_HOSTDEVICE constexpr Matrix33 operator- (const Matrix33& v) const noexcept; + /// Component-wise multiplication by -1 IMATH_HOSTDEVICE constexpr Matrix33 operator-() const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& negate() noexcept; - //------------------------------ - // Component-wise multiplication - //------------------------------ + /// Component-wise multiplication by -1 + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& negate() noexcept; + /// Component-wise multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator*= (T a) noexcept; + + /// Component-wise multiplication IMATH_HOSTDEVICE constexpr Matrix33 operator* (T a) const noexcept; - //----------------------------------- - // Matrix-times-matrix multiplication - //----------------------------------- + /// Component-wise division + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator/= (T a) noexcept; + + /// Component-wise division + IMATH_HOSTDEVICE constexpr Matrix33 operator/ (T a) const noexcept; + /// Matrix-matrix multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator*= (const Matrix33& v) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33 operator* (const Matrix33& v) const noexcept; - //----------------------------------------------------------------- - // Vector-times-matrix multiplication; see also the "operator *" - // functions defined below. - // - // m.multVecMatrix(src,dst) implements a homogeneous transformation - // by computing Vec3 (src.x, src.y, 1) * m and dividing by the - // result's third element. - // - // m.multDirMatrix(src,dst) multiplies src by the upper left 2x2 - // submatrix, ignoring the rest of matrix m. - //----------------------------------------------------------------- + /// Matrix-matrix multiplication + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33 operator* (const Matrix33& v) const noexcept; + /// Vector-matrix multiplication: a homogeneous transformation + /// by computing Vec3 (src.x, src.y, 1) * m and dividing by the + /// result's third element. + /// @param[in] src The input vector + /// @param[out] dst The output vector template IMATH_HOSTDEVICE void multVecMatrix (const Vec2& src, Vec2& dst) const noexcept; + /// Vector-matrix multiplication: multiply `src` by the upper left 2x2 + /// submatrix, ignoring the rest of matrix. + /// @param[in] src The input vector + /// @param[out] dst The output vector template IMATH_HOSTDEVICE void multDirMatrix (const Vec2& src, Vec2& dst) const noexcept; - //------------------------ - // Component-wise division - //------------------------ + /// @} - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator/= (T a) noexcept; - IMATH_HOSTDEVICE constexpr Matrix33 operator/ (T a) const noexcept; + /// @{ + /// @name Maniplation - //------------------ - // Transposed matrix - //------------------ + /// Set to the identity matrix + IMATH_HOSTDEVICE void makeIdentity() noexcept; + /// Transpose IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& transpose() noexcept; - IMATH_HOSTDEVICE constexpr Matrix33 transposed() const noexcept; - //------------------------------------------------------------ - // Inverse matrix: If singExc is false, inverting a singular - // matrix produces an identity matrix. If singExc is true, - // inverting a singular matrix throws a std::invalid_argument. - // - // inverse() and invert() invert matrices using determinants; - // gjInverse() and gjInvert() use the Gauss-Jordan method. - // - // inverse() and invert() are significantly faster than - // gjInverse() and gjInvert(), but the results may be slightly - // less accurate. - // - //------------------------------------------------------------ + /// Return the transpose + IMATH_HOSTDEVICE constexpr Matrix33 transposed() const noexcept; + /// Invert in place using the determinant. + /// @param singExc If true, throw an exception if the matrix cannot be inverted. + /// @return const reference to this IMATH_CONSTEXPR14 const Matrix33& invert (bool singExc); + + /// Invert in place using the determinant. + /// @return const reference to this IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& invert() noexcept; + /// Return the inverse using the determinant, leaving this unmodified. + /// @param singExc If true, throw an exception if the matrix cannot be inverted. IMATH_CONSTEXPR14 Matrix33 inverse (bool singExc) const; + + /// Return the inverse using the determinant, leaving this unmodified. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33 inverse() const noexcept; + /// Invert in place using the Gauss-Jordan method. Significantly slower + /// but more accurate than invert(). + /// @param singExc If true, throw an exception if the matrix cannot be inverted. + /// @return const reference to this const Matrix33& gjInvert (bool singExc); + + /// Invert in place using the Gauss-Jordan method. Significantly slower + /// but more accurate than invert(). + /// @return const reference to this IMATH_HOSTDEVICE const Matrix33& gjInvert() noexcept; + /// Return the inverse using the Gauss-Jordan method, leaving this + /// unmodified. Significantly slower but more accurate than inverse(). Matrix33 gjInverse (bool singExc) const; - IMATH_HOSTDEVICE Matrix33 gjInverse() const noexcept; - //------------------------------------------------ - // Calculate the matrix minor of the (r,c) element - //------------------------------------------------ + /// Return the inverse using the Gauss-Jordan method. Significantly slower, + /// leaving this unmodified. Slower but more accurate than inverse(). + IMATH_HOSTDEVICE Matrix33 gjInverse() const noexcept; + /// Calculate the matrix minor of the (r,c) element IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T minorOf (const int r, const int c) const noexcept; - //--------------------------------------------------- - // Build a minor using the specified rows and columns - //--------------------------------------------------- - + /// Build a minor using the specified rows and columns IMATH_HOSTDEVICE constexpr T fastMinor (const int r0, const int r1, const int c0, const int c1) const noexcept; - //------------ - // Determinant - //------------ - + /// Determinant IMATH_HOSTDEVICE constexpr T determinant() const noexcept; - //----------------------------------------- - // Set matrix to rotation by r (in radians) - //----------------------------------------- - + /// Set matrix to rotation by r (in radians) + /// @return const referenced to this template IMATH_HOSTDEVICE const Matrix33& setRotation (S r) noexcept; - //----------------------------- - // Rotate the given matrix by r - //----------------------------- - + // Rotate the given matrix by r (in radians) + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& rotate (S r) noexcept; - //-------------------------------------------- - // Set matrix to scale by given uniform factor - //-------------------------------------------- - + /// Set matrix to scale by given uniform factor + /// @return const referenced to this IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& setScale (T s) noexcept; - //------------------------------------ - // Set matrix to scale by given vector - //------------------------------------ - + /// Set matrix to scale by given vector + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& setScale (const Vec2& s) noexcept; - //---------------------- - // Scale the matrix by s - //---------------------- - + /// Scale the matrix by s + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& scale (const Vec2& s) noexcept; - //------------------------------------------ - // Set matrix to translation by given vector - //------------------------------------------ - + /// Set matrix to translation by given vector + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& setTranslation (const Vec2& t) noexcept; - //----------------------------- - // Return translation component - //----------------------------- - + /// Return the translation component IMATH_HOSTDEVICE constexpr Vec2 translation() const noexcept; - //-------------------------- - // Translate the matrix by t - //-------------------------- - + /// Translate the matrix by t + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& translate (const Vec2& t) noexcept; - //----------------------------------------------------------- - // Set matrix to shear x for each y coord. by given factor xy - //----------------------------------------------------------- - + /// Set matrix to shear x for each y coord. by given factor xy + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& setShear (const S& h) noexcept; - //------------------------------------------------------------- - // Set matrix to shear x for each y coord. by given factor h[0] - // and to shear y for each x coord. by given factor h[1] - //------------------------------------------------------------- - + /// Set matrix to shear x for each y coord. by given factor h[0] + /// and to shear y for each x coord. by given factor h[1] + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& setShear (const Vec2& h) noexcept; - //----------------------------------------------------------- - // Shear the matrix in x for each y coord. by given factor xy - //----------------------------------------------------------- - + /// Shear the matrix in x for each y coord. by given factor xy + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& shear (const S& xy) noexcept; - //----------------------------------------------------------- - // Shear the matrix in x for each y coord. by given factor xy - // and shear y for each x coord. by given factor yx - //----------------------------------------------------------- - + /// Shear the matrix in x for each y coord. by given factor xy + /// and shear y for each x coord. by given factor yx + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& shear (const Vec2& h) noexcept; - //-------------------------------------------------------- - // Number of the row and column dimensions, since - // Matrix33 is a square matrix. - //-------------------------------------------------------- - - IMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 3; } - - //------------------------------------------------- - // Limitations of type T (see also class limits) - //------------------------------------------------- - + /// @} + + /// @{ + /// @name Numeric Limits + + /// Largest possible negative value IMATH_HOSTDEVICE constexpr static T baseTypeMin() noexcept { return limits::min(); } + + /// Largest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeMax() noexcept { return limits::max(); } + + /// Smallest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeSmallest() noexcept { return limits::smallest(); } + + /// Smallest possible e for which 1+e != 1 IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() noexcept { return limits::epsilon(); } + /// @} + + /// Return the number of the row and column dimensions, i.e. 3. + IMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 3; } + + /// The base type: In templates that accept a parameter `V` (could be a Color4), you can refer to `T` as `V::BaseType` typedef T BaseType; + + /// The base vector type typedef Vec3 BaseVecType; private: @@ -609,227 +622,246 @@ template class Matrix33 }; }; +/// +/// 4x4 transformation matrix +/// + template class Matrix44 { public: - //------------------- - // Access to elements - //------------------- + /// @{ + /// @name Direct access to elements + + /// Matrix elements T x[4][4]; + /// @} + + /// Row access IMATH_HOSTDEVICE T* operator[] (int i) noexcept; + + /// Row access IMATH_HOSTDEVICE const T* operator[] (int i) const noexcept; - //------------- - // Constructors - //------------- + /// @{ + /// @name Constructors and Assignment + /// Uninitialized IMATH_HOSTDEVICE constexpr Matrix44 (Uninitialized) noexcept {} + /// Default constructor: initialize to identity + /// 1 0 0 0 + /// 0 1 0 0 + /// 0 0 1 0 + /// 0 0 0 1 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44() noexcept; - // 1 0 0 0 - // 0 1 0 0 - // 0 0 1 0 - // 0 0 0 1 + /// Initialize to scalar constant + /// a a a a + /// a a a a + /// a a a a + /// a a a a IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44 (T a) noexcept; - // a a a a - // a a a a - // a a a a - // a a a a + /// Construct from 4x4 array + /// a[0][0] a[0][1] a[0][2] a[0][3] + /// a[1][0] a[1][1] a[1][2] a[1][3] + /// a[2][0] a[2][1] a[2][2] a[2][3] + /// a[3][0] a[3][1] a[3][2] a[3][3] IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44 (const T a[4][4]) noexcept; - // a[0][0] a[0][1] a[0][2] a[0][3] - // a[1][0] a[1][1] a[1][2] a[1][3] - // a[2][0] a[2][1] a[2][2] a[2][3] - // a[3][0] a[3][1] a[3][2] a[3][3] + /// Construct from given scalar values + /// a b c d + /// e f g h + /// i j k l + /// m n o p IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44 (T a, T b, T c, T d, T e, T f, T g, T h, T i, T j, T k, T l, T m, T n, T o, T p) noexcept; - // a b c d - // e f g h - // i j k l - // m n o p + /// Construct from a 3x3 rotation matrix and a translation vector + /// r r r 0 + /// r r r 0 + /// r r r 0 + /// t t t 1 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44 (Matrix33 r, Vec3 t) noexcept; - // r r r 0 - // r r r 0 - // r r r 0 - // t t t 1 - - //------------ - // Destructor - //------------ - - ~Matrix44() noexcept = default; - - //-------------------------------- - // Copy constructor and assignment - //-------------------------------- + /// Copy constructor IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44 (const Matrix44& v) noexcept; + + /// Construct from Matrix44 of another base type template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 explicit Matrix44 (const Matrix44& v) noexcept; + /// Assignment operator IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator= (const Matrix44& v) noexcept; + + /// Assignment from scalar IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator= (T a) noexcept; - //---------------------- - // Compatibility with Sb - //---------------------- + /// Destructor + ~Matrix44() noexcept = default; + + /// @} + + /// @{ + /// @name Compatibility with Sb + /// Return a raw pointer to the array of values IMATH_HOSTDEVICE T* getValue() noexcept; + + /// Return a raw pointer to the array of values IMATH_HOSTDEVICE const T* getValue() const noexcept; + /// Return the value in `v` template IMATH_HOSTDEVICE void getValue (Matrix44& v) const noexcept; + + /// Set the value template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44& setValue (const Matrix44& v) noexcept; + /// Set the value template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44& setTheMatrix (const Matrix44& v) noexcept; - //--------- - // Identity - //--------- - - IMATH_HOSTDEVICE void makeIdentity() noexcept; - - //--------- - // Equality - //--------- + /// @} + /// @{ + /// @name Arithmetic and Comparison + + /// Equality IMATH_HOSTDEVICE constexpr bool operator== (const Matrix44& v) const noexcept; - IMATH_HOSTDEVICE constexpr bool operator!= (const Matrix44& v) const noexcept; - //----------------------------------------------------------------------- - // Compare two matrices and test if they are "approximately equal": - // - // equalWithAbsError (m, e) - // - // Returns true if the coefficients of this and m are the same with - // an absolute error of no more than e, i.e., for all i, j - // - // abs (this[i][j] - m[i][j]) <= e - // - // equalWithRelError (m, e) - // - // Returns true if the coefficients of this and m are the same with - // a relative error of no more than e, i.e., for all i, j - // - // abs (this[i] - v[i][j]) <= e * abs (this[i][j]) - //----------------------------------------------------------------------- + /// Inequality + IMATH_HOSTDEVICE constexpr bool operator!= (const Matrix44& v) const noexcept; + /// Compare two matrices and test if they are "approximately equal": + /// @return True if the coefficients of this and `m` are the same + /// with an absolute error of no more than e, i.e., for all i, j: + /// + /// abs (this[i][j] - m[i][j]) <= e IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError (const Matrix44& v, T e) const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Matrix44& v, T e) const noexcept; - //------------------------ - // Component-wise addition - //------------------------ + /// Compare two matrices and test if they are "approximately equal": + /// @return True if the coefficients of this and m are the same with + /// a relative error of no more than e, i.e., for all i, j: + /// + /// abs (this[i] - v[i][j]) <= e * abs (this[i][j]) + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Matrix44& v, T e) const noexcept; + /// Component-wise addition IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator+= (const Matrix44& v) noexcept; + + /// Component-wise addition IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator+= (T a) noexcept; - IMATH_HOSTDEVICE constexpr Matrix44 operator+ (const Matrix44& v) const noexcept; - //--------------------------- - // Component-wise subtraction - //--------------------------- + /// Component-wise addition + IMATH_HOSTDEVICE constexpr Matrix44 operator+ (const Matrix44& v) const noexcept; + /// Component-wise subtraction IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator-= (const Matrix44& v) noexcept; + + /// Component-wise subtraction IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator-= (T a) noexcept; - IMATH_HOSTDEVICE constexpr Matrix44 operator- (const Matrix44& v) const noexcept; - //------------------------------------ - // Component-wise multiplication by -1 - //------------------------------------ + /// Component-wise subtraction + IMATH_HOSTDEVICE constexpr Matrix44 operator- (const Matrix44& v) const noexcept; + /// Component-wise multiplication by -1 IMATH_HOSTDEVICE constexpr Matrix44 operator-() const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& negate() noexcept; - //------------------------------ - // Component-wise multiplication - //------------------------------ + /// Component-wise multiplication by -1 + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& negate() noexcept; + /// Component-wise multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator*= (T a) noexcept; + + /// Component-wise multiplication IMATH_HOSTDEVICE constexpr Matrix44 operator* (T a) const noexcept; - //----------------------------------- - // Matrix-times-matrix multiplication - //----------------------------------- + /// Component-wise division + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator/= (T a) noexcept; + + /// Component-wise division + IMATH_HOSTDEVICE constexpr Matrix44 operator/ (T a) const noexcept; + /// Matrix-matrix multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator*= (const Matrix44& v) noexcept; + + /// Matrix-matrix multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44 operator* (const Matrix44& v) const noexcept; + /// Matrix-matrix multiplication: compute c = a * b IMATH_HOSTDEVICE static void multiply (const Matrix44& a, // assumes that const Matrix44& b, // &a != &c and Matrix44& c) noexcept; // &b != &c. - //----------------------------------------------------------------- - // Vector-times-matrix multiplication; see also the "operator *" - // functions defined below. - // - // m.multVecMatrix(src,dst) implements a homogeneous transformation - // by computing Vec4 (src.x, src.y, src.z, 1) * m and dividing by - // the result's third element. - // - // m.multDirMatrix(src,dst) multiplies src by the upper left 3x3 - // submatrix, ignoring the rest of matrix m. - //----------------------------------------------------------------- - + /// Vector-matrix multiplication: a homogeneous transformation + /// by computing Vec3 (src.x, src.y, src.z, 1) * m and dividing by the + /// result's third element. + /// @param[in] src The input vector + /// @param[out] dst The output vector template IMATH_HOSTDEVICE void multVecMatrix (const Vec3& src, Vec3& dst) const noexcept; + /// Vector-matrix multiplication: multiply `src` by the upper left 2x2 + /// submatrix, ignoring the rest of matrix. + /// @param[in] src The input vector + /// @param[out] dst The output vector template IMATH_HOSTDEVICE void multDirMatrix (const Vec3& src, Vec3& dst) const noexcept; - //------------------------ - // Component-wise division - //------------------------ + /// @} - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator/= (T a) noexcept; - IMATH_HOSTDEVICE constexpr Matrix44 operator/ (T a) const noexcept; + /// @{ + /// @name Maniplation - //------------------ - // Transposed matrix - //------------------ + /// Set to the identity matrix + IMATH_HOSTDEVICE void makeIdentity() noexcept; + /// Transpose IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& transpose() noexcept; - IMATH_HOSTDEVICE constexpr Matrix44 transposed() const noexcept; - //------------------------------------------------------------ - // Inverse matrix: If singExc is false, inverting a singular - // matrix produces an identity matrix. If singExc is true, - // inverting a singular matrix throws a std::invalid_argument. - // - // inverse() and invert() invert matrices using determinants; - // gjInverse() and gjInvert() use the Gauss-Jordan method. - // - // inverse() and invert() are significantly faster than - // gjInverse() and gjInvert(), but the results may be slightly - // less accurate. - // - //------------------------------------------------------------ + /// Return the transpose + IMATH_HOSTDEVICE constexpr Matrix44 transposed() const noexcept; + /// Invert in place using the determinant. + /// @param singExc If true, throw an exception if the matrix cannot be inverted. + /// @return const reference to this IMATH_CONSTEXPR14 const Matrix44& invert (bool singExc); + + /// Invert in place using the determinant. + /// @return const reference to this IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& invert() noexcept; + /// Return the inverse using the determinant, leaving this unmodified. + /// @param singExc If true, throw an exception if the matrix cannot be inverted. IMATH_CONSTEXPR14 Matrix44 inverse (bool singExc) const; + + /// Return the inverse using the determinant, leaving this unmodified. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44 inverse() const noexcept; + /// Invert in place using the Gauss-Jordan method. Significantly slower + /// but more accurate than invert(). + /// @param singExc If true, throw an exception if the matrix cannot be inverted. + /// @return const reference to this IMATH_CONSTEXPR14 const Matrix44& gjInvert (bool singExc); + + /// Invert in place using the Gauss-Jordan method. Significantly slower + /// but more accurate than invert(). + /// @return const reference to this IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& gjInvert() noexcept; + /// Return the inverse using the Gauss-Jordan method, leaving this + /// unmodified. Significantly slower but more accurate than inverse(). Matrix44 gjInverse (bool singExc) const; - IMATH_HOSTDEVICE Matrix44 gjInverse() const noexcept; - //------------------------------------------------ - // Calculate the matrix minor of the (r,c) element - //------------------------------------------------ + /// Return the inverse using the Gauss-Jordan method, leaving this + /// unmodified Significantly slower but more accurate than inverse(). + IMATH_HOSTDEVICE Matrix44 gjInverse() const noexcept; + /// Calculate the matrix minor of the (r,c) element IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T minorOf (const int r, const int c) const noexcept; - //--------------------------------------------------- - // Build a minor using the specified rows and columns - //--------------------------------------------------- - + /// Build a minor using the specified rows and columns IMATH_HOSTDEVICE constexpr T fastMinor (const int r0, const int r1, @@ -838,134 +870,113 @@ template class Matrix44 const int c1, const int c2) const noexcept; - //------------ - // Determinant - //------------ - + /// Determinant IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T determinant() const noexcept; - //-------------------------------------------------------- - // Set matrix to rotation by XYZ euler angles (in radians) - //-------------------------------------------------------- - + /// Set matrix to rotation by XYZ euler angles (in radians) + /// @return const referenced to this template IMATH_HOSTDEVICE const Matrix44& setEulerAngles (const Vec3& r) noexcept; - //-------------------------------------------------------- - // Set matrix to rotation around given axis by given angle - //-------------------------------------------------------- - + /// Set matrix to rotation around given axis by given angle (in radians) + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& setAxisAngle (const Vec3& ax, S ang) noexcept; - //------------------------------------------- - // Rotate the matrix by XYZ euler angles in r - //------------------------------------------- - + /// Rotate the matrix by XYZ euler angles in r (in radians) + /// @return const referenced to this template IMATH_HOSTDEVICE const Matrix44& rotate (const Vec3& r) noexcept; - //-------------------------------------------- - // Set matrix to scale by given uniform factor - //-------------------------------------------- - + /// Set matrix to scale by given uniform factor + /// @return const referenced to this IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& setScale (T s) noexcept; - //------------------------------------ - // Set matrix to scale by given vector - //------------------------------------ - + /// Set matrix to scale by given vector + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& setScale (const Vec3& s) noexcept; - //---------------------- - // Scale the matrix by s - //---------------------- - + /// Scale the matrix by s + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& scale (const Vec3& s) noexcept; - //------------------------------------------ - // Set matrix to translation by given vector - //------------------------------------------ - + /// Set matrix to translation by given vector + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& setTranslation (const Vec3& t) noexcept; - //----------------------------- - // Return translation component - //----------------------------- - + /// Return translation component IMATH_HOSTDEVICE constexpr const Vec3 translation() const noexcept; - //-------------------------- - // Translate the matrix by t - //-------------------------- - + /// Translate the matrix by t + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& translate (const Vec3& t) noexcept; - //------------------------------------------------------------- - // Set matrix to shear by given vector h. The resulting matrix - // will shear x for each y coord. by a factor of h[0] ; - // will shear x for each z coord. by a factor of h[1] ; - // will shear y for each z coord. by a factor of h[2] . - //------------------------------------------------------------- - + /// Set matrix to shear by given vector h. The resulting matrix + /// - will shear x for each y coord. by a factor of h[0] ; + /// - will shear x for each z coord. by a factor of h[1] ; + /// - will shear y for each z coord. by a factor of h[2] . + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& setShear (const Vec3& h) noexcept; - //------------------------------------------------------------ - // Set matrix to shear by given factors. The resulting matrix - // will shear x for each y coord. by a factor of h.xy ; - // will shear x for each z coord. by a factor of h.xz ; - // will shear y for each z coord. by a factor of h.yz ; - // will shear y for each x coord. by a factor of h.yx ; - // will shear z for each x coord. by a factor of h.zx ; - // will shear z for each y coord. by a factor of h.zy . - //------------------------------------------------------------ - + /// Set matrix to shear by given factors. The resulting matrix + /// - will shear x for each y coord. by a factor of h.xy ; + /// - will shear x for each z coord. by a factor of h.xz ; + /// - will shear y for each z coord. by a factor of h.yz ; + /// - will shear y for each x coord. by a factor of h.yx ; + /// - will shear z for each x coord. by a factor of h.zx ; + /// - will shear z for each y coord. by a factor of h.zy . + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& setShear (const Shear6& h) noexcept; - //-------------------------------------------------------- - // Shear the matrix by given vector. The composed matrix - // will be * , where the shear matrix ... - // will shear x for each y coord. by a factor of h[0] ; - // will shear x for each z coord. by a factor of h[1] ; - // will shear y for each z coord. by a factor of h[2] . - //-------------------------------------------------------- - + /// Shear the matrix by given vector. The composed matrix + /// will be `shear` * `this`, where the shear matrix ... + /// - will shear x for each y coord. by a factor of h[0] ; + /// - will shear x for each z coord. by a factor of h[1] ; + /// - will shear y for each z coord. by a factor of h[2] . + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& shear (const Vec3& h) noexcept; - //-------------------------------------------------------- - // Number of the row and column dimensions, since - // Matrix44 is a square matrix. - //-------------------------------------------------------- - - IMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 4; } - - //------------------------------------------------------------ - // Shear the matrix by the given factors. The composed matrix - // will be * , where the shear matrix ... - // will shear x for each y coord. by a factor of h.xy ; - // will shear x for each z coord. by a factor of h.xz ; - // will shear y for each z coord. by a factor of h.yz ; - // will shear y for each x coord. by a factor of h.yx ; - // will shear z for each x coord. by a factor of h.zx ; - // will shear z for each y coord. by a factor of h.zy . - //------------------------------------------------------------ - + /// Shear the matrix by the given factors. The composed matrix + /// will be `shear` * `this`, where the shear matrix ... + /// - will shear x for each y coord. by a factor of h.xy ; + /// - will shear x for each z coord. by a factor of h.xz ; + /// - will shear y for each z coord. by a factor of h.yz ; + /// - will shear y for each x coord. by a factor of h.yx ; + /// - will shear z for each x coord. by a factor of h.zx ; + /// - will shear z for each y coord. by a factor of h.zy . + /// @return const referenced to this template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& shear (const Shear6& h) noexcept; - //------------------------------------------------- - // Limitations of type T (see also class limits) - //------------------------------------------------- - + /// @} + + /// @{ + /// @name Numeric Limits + + /// Largest possible negative value IMATH_HOSTDEVICE constexpr static T baseTypeMin() noexcept { return limits::min(); } + + /// Largest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeMax() noexcept { return limits::max(); } + + /// Smallest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeSmallest() noexcept { return limits::smallest(); } + + /// Smallest possible e for which 1+e != 1 IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() noexcept { return limits::epsilon(); } + /// @} + + /// Return the number of the row and column dimensions, i.e. 4 + IMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 4; } + + /// The base type: In templates that accept a parameter `V` (could be a Color4), you can refer to `T` as `V::BaseType` typedef T BaseType; + + /// The base vector type typedef Vec4 BaseVecType; private: @@ -986,47 +997,56 @@ template class Matrix44 }; }; -//-------------- -// Stream output -//-------------- - +/// Stream output template std::ostream& operator<< (std::ostream& s, const Matrix22& m); +/// Stream output template std::ostream& operator<< (std::ostream& s, const Matrix33& m); +/// Stream output template std::ostream& operator<< (std::ostream& s, const Matrix44& m); //--------------------------------------------- // Vector-times-matrix multiplication operators //--------------------------------------------- +/// Vector-matrix multiplication: v *= m template IMATH_HOSTDEVICE inline const Vec2& operator*= (Vec2& v, const Matrix22& m) noexcept; +/// Vector-matrix multiplication: r = v * m template IMATH_HOSTDEVICE inline Vec2 operator* (const Vec2& v, const Matrix22& m) noexcept; +/// Vector-matrix multiplication: v *= m template IMATH_HOSTDEVICE inline const Vec2& operator*= (Vec2& v, const Matrix33& m) noexcept; +/// Vector-matrix multiplication: r = v * m template IMATH_HOSTDEVICE inline Vec2 operator* (const Vec2& v, const Matrix33& m) noexcept; +/// Vector-matrix multiplication: v *= m template IMATH_HOSTDEVICE inline const Vec3& operator*= (Vec3& v, const Matrix33& m) noexcept; +/// Vector-matrix multiplication: r = v * m template IMATH_HOSTDEVICE inline Vec3 operator* (const Vec3& v, const Matrix33& m) noexcept; +/// Vector-matrix multiplication: v *= m template IMATH_HOSTDEVICE inline const Vec3& operator*= (Vec3& v, const Matrix44& m) noexcept; +/// Vector-matrix multiplication: r = v * m template IMATH_HOSTDEVICE inline Vec3 operator* (const Vec3& v, const Matrix44& m) noexcept; +/// Vector-matrix multiplication: v *= m template IMATH_HOSTDEVICE inline const Vec4& operator*= (Vec4& v, const Matrix44& m) noexcept; +/// Vector-matrix multiplication: r = v * m template IMATH_HOSTDEVICE inline Vec4 operator* (const Vec4& v, const Matrix44& m) noexcept; @@ -1034,11 +1054,22 @@ IMATH_HOSTDEVICE inline Vec4 operator* (const Vec4& v, const Matrix44& // Typedefs for convenience //------------------------- +/// 2x2 matrix of float typedef Matrix22 M22f; + +/// 2x2 matrix of double typedef Matrix22 M22d; + +/// 3x3 matrix of float typedef Matrix33 M33f; + +/// 3x3 matrix of double typedef Matrix33 M33d; + +/// 4x4 matrix of float typedef Matrix44 M44f; + +/// 4x4 matrix of double typedef Matrix44 M44d; //--------------------------- @@ -1348,6 +1379,7 @@ Matrix22::operator* (T a) const noexcept return Matrix22 (x[0][0] * a, x[0][1] * a, x[1][0] * a, x[1][1] * a); } +/// Matrix-scalar multiplication template inline Matrix22 operator* (T a, const Matrix22& v) noexcept @@ -2042,6 +2074,7 @@ Matrix33::operator* (T a) const noexcept x[2][2] * a); } +/// Matrix-scalar multiplication template inline Matrix33 constexpr operator* (T a, const Matrix33& v) noexcept @@ -3458,6 +3491,7 @@ Matrix44::operator* (T a) const noexcept x[3][3] * a); } +/// Matrix-scalar multiplication template inline Matrix44 operator* (T a, const Matrix44& v) noexcept diff --git a/src/Imath/ImathMatrixAlgo.cpp b/src/Imath/ImathMatrixAlgo.cpp index f0116534..a0796509 100644 --- a/src/Imath/ImathMatrixAlgo.cpp +++ b/src/Imath/ImathMatrixAlgo.cpp @@ -3,11 +3,14 @@ // Copyright Contributors to the OpenEXR Project. // -//---------------------------------------------------------------------------- -// -// Implementation of non-template items declared in ImathMatrixAlgo.h -// -//---------------------------------------------------------------------------- +/// +/// @file ImathMatrixAlgo.cpp +/// +/// @brief Functions operating on Matrix22, Matrix33, and Matrix44 types. +/// + +// clang-format off +/// @cond Doxygen_Suppress #include "ImathMatrixAlgo.h" #include @@ -21,27 +24,20 @@ IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER -// clang-format off - EXPORT_CONST M22f identity22f ( 1, 0, 0, 1); - EXPORT_CONST M22d identity22d ( 1, 0, 0, 1); - EXPORT_CONST M33f identity33f ( 1, 0, 0, 0, 1, 0, 0, 0, 1); - EXPORT_CONST M33d identity33d ( 1, 0, 0, 0, 1, 0, 0, 0, 1); - EXPORT_CONST M44f identity44f ( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - EXPORT_CONST M44d identity44d ( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, @@ -230,6 +226,13 @@ procrustesRotationAndTranslation (const Vec3* A, T (1)); } // procrustesRotationAndTranslation +/// +/// Return the procrustes transformation of a set of points: the +/// rotation, translation, and optionally the scale that comes closest +/// in a least squares sense to transforming the `A` points into +/// `B`. +/// + template M44d procrustesRotationAndTranslation (const Vec3* A, @@ -240,19 +243,23 @@ procrustesRotationAndTranslation (const Vec3* A, return procrustesRotationAndTranslation (A, B, (const T*) 0, numPoints, doScale); } // procrustesRotationAndTranslation +/// TODO template IMATH_EXPORT M44d procrustesRotationAndTranslation (const V3d* from, const V3d* to, const size_t numPoints, const bool doScale); +/// TODO template IMATH_EXPORT M44d procrustesRotationAndTranslation (const V3f* from, const V3f* to, const size_t numPoints, const bool doScale); +/// TODO template IMATH_EXPORT M44d procrustesRotationAndTranslation (const V3d* from, const V3d* to, const double* weights, const size_t numPoints, const bool doScale); +/// TODO template IMATH_EXPORT M44d procrustesRotationAndTranslation (const V3f* from, const V3f* to, const float* weights, @@ -900,6 +907,7 @@ twoSidedJacobiSVD (IMATH_INTERNAL_NAMESPACE::Matrix44 A, } // namespace +/// TODO template void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix33& A, @@ -912,6 +920,7 @@ jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix33& A, twoSidedJacobiSVD (A, U, S, V, tol, forcePositiveDeterminant); } +/// TODO template void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix44& A, @@ -924,24 +933,28 @@ jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix44& A, twoSidedJacobiSVD (A, U, S, V, tol, forcePositiveDeterminant); } +/// TODO template IMATH_EXPORT void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix33& A, IMATH_INTERNAL_NAMESPACE::Matrix33& U, IMATH_INTERNAL_NAMESPACE::Vec3& S, IMATH_INTERNAL_NAMESPACE::Matrix33& V, const float tol, const bool forcePositiveDeterminant); +/// TODO template IMATH_EXPORT void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix33& A, IMATH_INTERNAL_NAMESPACE::Matrix33& U, IMATH_INTERNAL_NAMESPACE::Vec3& S, IMATH_INTERNAL_NAMESPACE::Matrix33& V, const double tol, const bool forcePositiveDeterminant); +/// TODO template IMATH_EXPORT void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix44& A, IMATH_INTERNAL_NAMESPACE::Matrix44& U, IMATH_INTERNAL_NAMESPACE::Vec4& S, IMATH_INTERNAL_NAMESPACE::Matrix44& V, const float tol, const bool forcePositiveDeterminant); +/// TODO template IMATH_EXPORT void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix44& A, IMATH_INTERNAL_NAMESPACE::Matrix44& U, IMATH_INTERNAL_NAMESPACE::Vec4& S, @@ -1227,4 +1240,7 @@ template IMATH_EXPORT void minEigenVector (Matrix44& A, Vec4& S); template IMATH_EXPORT void minEigenVector (Matrix33& A, Vec3& S); template IMATH_EXPORT void minEigenVector (Matrix44& A, Vec4& S); + IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT + +/// @endcond diff --git a/src/Imath/ImathMatrixAlgo.h b/src/Imath/ImathMatrixAlgo.h index a513cbe9..70ec0a1f 100644 --- a/src/Imath/ImathMatrixAlgo.h +++ b/src/Imath/ImathMatrixAlgo.h @@ -3,20 +3,15 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHMATRIXALGO_H -#define INCLUDED_IMATHMATRIXALGO_H - -//------------------------------------------------------------------------- // -// This file contains algorithms applied to or in conjunction with -// transformation matrices (Imath::Matrix33 and Imath::Matrix44). -// The assumption made is that these functions are called much less -// often than the basic point functions or these functions require -// more support classes. // -// This file also defines a few predefined constant matrices. +// Functions operating on Matrix22, Matrix33, and Matrix44 types +// +// This file also defines a few predefined constant matrices. // -//------------------------------------------------------------------------- + +#ifndef INCLUDED_IMATHMATRIXALGO_H +#define INCLUDED_IMATHMATRIXALGO_H #include "ImathEuler.h" #include "ImathExport.h" @@ -33,11 +28,17 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER // Identity matrices //------------------ +/// M22f identity matrix IMATH_EXPORT_CONST M22f identity22f; +/// M33f identity matrix IMATH_EXPORT_CONST M33f identity33f; +/// M44f identity matrix IMATH_EXPORT_CONST M44f identity44f; +/// M22d identity matrix IMATH_EXPORT_CONST M22d identity22d; +/// M33d identity matrix IMATH_EXPORT_CONST M33d identity33d; +/// M44d identity matrix IMATH_EXPORT_CONST M44d identity44d; //---------------------------------------------------------------------- @@ -87,32 +88,106 @@ IMATH_EXPORT_CONST M44d identity44d; // Declarations for 4x4 matrix. // +/// Extract the scaling component of the given 4x4 matrix. +/// +/// @param[in] mat The input matrix +/// @param[out] scl The extracted scale, i.e. the output value +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. +/// @return True if the scale could be extracted, false if the matrix is degenerate. template bool extractScaling (const Matrix44& mat, Vec3& scl, bool exc = true); +/// Return the given 4x4 matrix with scaling removed. +/// +/// @param[in] mat The input matrix +/// @param[in] exc If true, throw an exception if the scaling in `mat` template Matrix44 sansScaling (const Matrix44& mat, bool exc = true); +/// Remove scaling from the given 4x4 matrix in place. Return true if the +/// scale could be successfully extracted, false if the matrix is +/// degenerate. +// +/// @param[in] mat The matrix to operate on +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. +/// @return True if the scale could be extracted, false if the matrix is degenerate. template bool removeScaling (Matrix44& mat, bool exc = true); -template -bool extractScalingAndShear (const Matrix44& mat, Vec3& scl, Vec3& shr, bool exc = true); - +/// Extract the scaling and shear components of the given 4x4 matrix. +/// Return true if the scale could be successfully extracted, false if +/// the matrix is degenerate. +/// +/// @param[in] mat The input matrix +/// @param[out] scl The extracted scale +/// @param[out] shr The extracted shear +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. +/// @return True if the scale could be extracted, false if the matrix is degenerate. +template bool extractScalingAndShear (const Matrix44& mat, Vec3& scl, Vec3& shr, bool exc = true); + +/// Return the given 4x4 matrix with scaling and shear removed. +/// +/// @param[in] mat The input matrix +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. template Matrix44 sansScalingAndShear (const Matrix44& mat, bool exc = true); +/// Extract scaling and shear from the given 4x4 matrix in-place. +/// +/// @param[in,out] result The output matrix +/// @param[in] mat The return value if `result` is degenerate +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. template void sansScalingAndShear (Matrix44& result, const Matrix44& mat, bool exc = true); +/// Remove scaling and shear from the given 4x4 matrix in place. +// +/// @param[in,out] mat The matrix to operate on +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. +/// @return True if the scale could be extracted, false if the matrix is degenerate. template bool removeScalingAndShear (Matrix44& mat, bool exc = true); +/// Remove scaling and shear from the given 4x4 matrix in place, returning +/// the extracted values. +// +/// @param[in,out] mat The matrix to operate on +/// @param[out] scl The extracted scale +/// @param[out] shr The extracted shear +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. +/// @return True if the scale could be extracted, false if the matrix is degenerate. template bool extractAndRemoveScalingAndShear (Matrix44& mat, Vec3& scl, Vec3& shr, bool exc = true); +/// Extract the rotation from the given 4x4 matrix in the form of XYZ +/// euler angles. +/// +/// @param[in] mat The input matrix +/// @param[out] rot The extracted XYZ euler angle vector template void extractEulerXYZ (const Matrix44& mat, Vec3& rot); +/// Extract the rotation from the given 4x4 matrix in the form of ZYX +/// euler angles. +/// +/// @param[in] mat The input matrix +/// @param[out] rot The extracted ZYX euler angle vector template void extractEulerZYX (const Matrix44& mat, Vec3& rot); +/// Extract the rotation from the given 4x4 matrix in the form of a quaternion. +/// +/// @param[in] mat The input matrix +/// @return The extracted quaternion template Quat extractQuat (const Matrix44& mat); +/// Extract the scaling, shear, rotation, and translation components +/// of the given 4x4 matrix. The values are such that: +/// +/// M = S * H * R * T +/// +/// @param[in] mat The input matrix +/// @param[out] s The extracted scale +/// @param[out] h The extracted shear +/// @param[out] r The extracted rotation +/// @param[out] t The extracted translation +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. +/// @param[in] rOrder The order with which to extract the rotation +/// @return True if the values could be extracted, false if the matrix is degenerate. template bool extractSHRT (const Matrix44& mat, Vec3& s, @@ -122,6 +197,16 @@ bool extractSHRT (const Matrix44& mat, bool exc /*= true*/, typename Euler::Order rOrder); +/// Extract the scaling, shear, rotation, and translation components +/// of the given 4x4 matrix. +/// +/// @param[in] mat The input matrix +/// @param[out] s The extracted scale +/// @param[out] h The extracted shear +/// @param[out] r The extracted rotation, in XYZ euler angles +/// @param[out] t The extracted translation +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. +/// @return True if the values could be extracted, false if the matrix is degenerate. template bool extractSHRT (const Matrix44& mat, Vec3& s, @@ -130,6 +215,16 @@ bool extractSHRT (const Matrix44& mat, Vec3& t, bool exc = true); +/// Extract the scaling, shear, rotation, and translation components +/// of the given 4x4 matrix. +/// +/// @param[in] mat The input matrix +/// @param[out] s The extracted scale +/// @param[out] h The extracted shear +/// @param[out] r The extracted rotation, in Euler angles +/// @param[out] t The extracted translation +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. +/// @return True if the values could be extracted, false if the matrix is degenerate. template bool extractSHRT (const Matrix44& mat, Vec3& s, @@ -138,68 +233,66 @@ bool extractSHRT (const Matrix44& mat, Vec3& t, bool exc = true); -// -// Internal utility function. -// - +/// Return true if the given scale can be removed from the given row +/// matrix, false if `scl` is small enough that the operation would +/// overflow. If `exc` is true, throw an exception on overflow. template bool checkForZeroScaleInRow (const T& scl, const Vec3& row, bool exc = true); +/// Return the 4x4 outer product two 4-vectors template Matrix44 outerProduct (const Vec4& a, const Vec4& b); -// -// Returns a matrix that rotates "fromDirection" vector to "toDirection" -// vector. -// - +/// +/// Return a 4x4 matrix that rotates the vector `fromDirection` to `toDirection` +/// template Matrix44 rotationMatrix (const Vec3& fromDirection, const Vec3& toDirection); -// -// Returns a matrix that rotates the "fromDir" vector -// so that it points towards "toDir". You may also -// specify that you want the up vector to be pointing -// in a certain direction "upDir". -// - +/// +/// Return a 4x4 matrix that rotates the `fromDir` vector +/// so that it points towards `toDir1. You may also +/// specify that you want the up vector to be pointing +/// in a certain direction 1upDir`. template Matrix44 rotationMatrixWithUpDir (const Vec3& fromDir, const Vec3& toDir, const Vec3& upDir); -// -// Constructs a matrix that rotates the z-axis so that it -// points towards "targetDir". You must also specify -// that you want the up vector to be pointing in a -// certain direction "upDir". -// -// Notes: The following degenerate cases are handled: -// (a) when the directions given by "toDir" and "upDir" -// are parallel or opposite; -// (the direction vectors must have a non-zero cross product) -// (b) when any of the given direction vectors have zero length -// - +/// +/// Construct a 4x4 matrix that rotates the z-axis so that it points +/// towards `targetDir`. You must also specify that you want the up +/// vector to be pointing in a certain direction `upDir`. +/// +/// Notes: The following degenerate cases are handled: +/// (a) when the directions given by `toDir` and `upDir` +/// are parallel or opposite (the direction vectors must have a non-zero cross product); +/// (b) when any of the given direction vectors have zero length +/// +/// @param[out] result The output matrix +/// @param[in] targetDir The target direction vector +/// @param[in] upDir The up direction vector template void alignZAxisWithTargetDir (Matrix44& result, Vec3 targetDir, Vec3 upDir); -// Compute an orthonormal direct frame from : a position, an x axis direction and a normal to the y axis -// If the x axis and normal are perpendicular, then the normal will have the same direction as the z axis. -// Inputs are : -// -the position of the frame -// -the x axis direction of the frame -// -a normal to the y axis of the frame -// Return is the orthonormal frame +/// Compute an orthonormal direct 4x4 frame from a position, an x axis +/// direction and a normal to the y axis. If the x axis and normal are +/// perpendicular, then the normal will have the same direction as the +/// z axis. +/// +/// @param[in] p The position of the frame +/// @param[in] xDir The x axis direction of the frame +/// @param[in] normal A normal to the y axis of the frame +/// @return The orthonormal frame template Matrix44 computeLocalFrame (const Vec3& p, const Vec3& xDir, const Vec3& normal); -// Add a translate/rotate/scale offset to an input frame -// and put it in another frame of reference -// Inputs are : -// - input frame -// - translate offset -// - rotate offset in degrees -// - scale offset -// - frame of reference -// Output is the offsetted frame +/// Add a translate/rotate/scale offset to a 4x4 input frame +/// and put it in another frame of reference +/// +/// @param[in] inMat Input frame +/// @param[in] tOffset Translation offset +/// @param[in] rOffset Rotation offset in degrees +/// @param[in] sOffset Scale offset +/// @param[in] ref Frame of reference +/// @return The offsetted frame template Matrix44 addOffset (const Matrix44& inMat, const Vec3& tOffset, @@ -207,51 +300,118 @@ Matrix44 addOffset (const Matrix44& inMat, const Vec3& sOffset, const Vec3& ref); -// Compute Translate/Rotate/Scale matrix from matrix A with the Rotate/Scale of Matrix B -// Inputs are : -// -keepRotateA : if true keep rotate from matrix A, use B otherwise -// -keepScaleA : if true keep scale from matrix A, use B otherwise -// -Matrix A -// -Matrix B -// Return Matrix A with tweaked rotation/scale +/// Compute 4x4 translate/rotate/scale matrix from `A` with the +/// rotate/scale of `B`. +/// +/// @param[in] keepRotateA If true, keep rotate from matrix `A`, use `B` otherwise +/// @param[in] keepScaleA If true, keep scale from matrix `A`, use `B` otherwise +/// @param[in] A Matrix A +/// @param[in] B Matrix B +/// @return Matrix `A` with tweaked rotation/scale template Matrix44 computeRSMatrix (bool keepRotateA, bool keepScaleA, const Matrix44& A, const Matrix44& B); -//---------------------------------------------------------------------- - // // Declarations for 3x3 matrix. // +/// Extract the scaling component of the given 3x3 matrix. +/// +/// @param[in] mat The input matrix +/// @param[out] scl The extracted scale, i.e. the output value +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. +/// @return True if the scale could be extracted, false if the matrix is degenerate. template bool extractScaling (const Matrix33& mat, Vec2& scl, bool exc = true); +/// Return the given 3x3 matrix with scaling removed. +/// +/// @param[in] mat The input matrix +/// @param[in] exc If true, throw an exception if the scaling in `mat` template Matrix33 sansScaling (const Matrix33& mat, bool exc = true); +/// Remove scaling from the given 3x3 matrix in place. Return true if the +/// scale could be successfully extracted, false if the matrix is +/// degenerate. +// +/// @param[in] mat The matrix to operate on +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. +/// @return True if the scale could be extracted, false if the matrix is degenerate. template bool removeScaling (Matrix33& mat, bool exc = true); +/// Extract the scaling and shear components of the given 3x3 matrix. +/// Return true if the scale could be successfully extracted, false if +/// the matrix is degenerate. +/// +/// @param[in] mat The input matrix +/// @param[out] scl The extracted scale +/// @param[out] shr The extracted shear +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. +/// @return True if the scale could be extracted, false if the matrix is degenerate. template -bool extractScalingAndShear (const Matrix33& mat, Vec2& scl, T& h, bool exc = true); +bool extractScalingAndShear (const Matrix33& mat, Vec2& scl, T& shr, bool exc = true); +/// Return the given 3x3 matrix with scaling and shear removed. +/// +/// @param[in] mat The input matrix +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. template Matrix33 sansScalingAndShear (const Matrix33& mat, bool exc = true); + +/// Remove scaling and shear from the given 3x3e matrix in place. +// +/// @param[in,out] mat The matrix to operate on +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. +/// @return True if the scale could be extracted, false if the matrix is degenerate. template bool removeScalingAndShear (Matrix33& mat, bool exc = true); +/// Remove scaling and shear from the given 3x3 matrix in place, returning +/// the extracted values. +// +/// @param[in,out] mat The matrix to operate on +/// @param[out] scl The extracted scale +/// @param[out] shr The extracted shear +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. +/// @return True if the scale could be extracted, false if the matrix is degenerate. template bool extractAndRemoveScalingAndShear (Matrix33& mat, Vec2& scl, T& shr, bool exc = true); +/// Extract the rotation from the given 2x2 matrix +/// +/// @param[in] mat The input matrix +/// @param[out] rot The extracted rotation value template void extractEuler (const Matrix22& mat, T& rot); +/// Extract the rotation from the given 3x3 matrix +/// +/// @param[in] mat The input matrix +/// @param[out] rot The extracted rotation value template void extractEuler (const Matrix33& mat, T& rot); +/// Extract the scaling, shear, rotation, and translation components +/// of the given 3x3 matrix. The values are such that: +/// +/// M = S * H * R * T +/// +/// @param[in] mat The input matrix +/// @param[out] s The extracted scale +/// @param[out] h The extracted shear +/// @param[out] r The extracted rotation +/// @param[out] t The extracted translation +/// @param[in] exc If true, throw an exception if the scaling in `mat` is very close to zero. +/// @return True if the values could be extracted, false if the matrix is degenerate. template bool extractSHRT (const Matrix33& mat, Vec2& s, T& h, T& r, Vec2& t, bool exc = true); +/// Return true if the given scale can be removed from the given row +/// matrix, false if `scl` is small enough that the operation would +/// overflow. If `exc` is true, throw an exception on overflow. template bool checkForZeroScaleInRow (const T& scl, const Vec2& row, bool exc = true); +/// Return the 3xe outer product two 3-vectors template Matrix33 outerProduct (const Vec3& a, const Vec3& b); -//----------------------------------------------------------------------------- +//------------------------------ // Implementation for 4x4 Matrix //------------------------------ @@ -637,8 +797,8 @@ extractSHRT (const Matrix44& mat, if (rOrder != Euler::XYZ) { - IMATH_INTERNAL_NAMESPACE::Euler eXYZ (r, IMATH_INTERNAL_NAMESPACE::Euler::XYZ); - IMATH_INTERNAL_NAMESPACE::Euler e (eXYZ, rOrder); + Euler eXYZ (r, Euler::XYZ); + Euler e (eXYZ, rOrder); r = e.toXYZVector(); } @@ -649,7 +809,7 @@ template bool extractSHRT (const Matrix44& mat, Vec3& s, Vec3& h, Vec3& r, Vec3& t, bool exc) { - return extractSHRT (mat, s, h, r, t, exc, IMATH_INTERNAL_NAMESPACE::Euler::XYZ); + return extractSHRT (mat, s, h, r, t, exc, Euler::XYZ); } template @@ -732,12 +892,12 @@ rotationMatrixWithUpDir (const Vec3& fromDir, const Vec3& toDir, const Vec else { - Matrix44 zAxis2FromDir (IMATH_INTERNAL_NAMESPACE::UNINITIALIZED); + Matrix44 zAxis2FromDir (UNINITIALIZED); alignZAxisWithTargetDir (zAxis2FromDir, fromDir, Vec3 (0, 1, 0)); Matrix44 fromDir2zAxis = zAxis2FromDir.transposed(); - Matrix44 zAxis2ToDir (IMATH_INTERNAL_NAMESPACE::UNINITIALIZED); + Matrix44 zAxis2ToDir (UNINITIALIZED); alignZAxisWithTargetDir (zAxis2ToDir, toDir, upDir); return fromDir2zAxis * zAxis2ToDir; @@ -854,15 +1014,15 @@ computeLocalFrame (const Vec3& p, const Vec3& xDir, const Vec3& normal) return L; } -// Add a translate/rotate/scale offset to an input frame -// and put it in another frame of reference -// Inputs are : -// - input frame -// - translate offset -// - rotate offset in degrees -// - scale offset -// - frame of reference -// Output is the offsetted frame +/// Add a translate/rotate/scale offset to an input frame and put it +/// in another frame of reference. +/// +/// @param inMat input frame +/// @param tOffset translate offset +/// @param rOffset rotate offset in degrees +/// @param sOffset scale offset +/// @param ref Frame of reference +/// @return The offsetted frame template Matrix44 addOffset (const Matrix44& inMat, @@ -1165,6 +1325,7 @@ extractSHRT (const Matrix33& mat, Vec2& s, T& h, T& r, Vec2& t, bool ex return true; } +/// @cond Doxygen_Suppress template bool checkForZeroScaleInRow (const T& scl, const Vec2& row, bool exc /* = true */) @@ -1182,6 +1343,7 @@ checkForZeroScaleInRow (const T& scl, const Vec2& row, bool exc /* = true */) return true; } +/// @endcond template Matrix33 @@ -1198,74 +1360,116 @@ outerProduct (const Vec3& a, const Vec3& b) a.z * b.z); } -// Computes the translation and rotation that brings the 'from' points -// as close as possible to the 'to' points under the Frobenius norm. -// To be more specific, let x be the matrix of 'from' points and y be -// the matrix of 'to' points, we want to find the matrix A of the form -// [ R t ] -// [ 0 1 ] -// that minimizes -// || (A*x - y)^T * W * (A*x - y) ||_F -// If doScaling is true, then a uniform scale is allowed also. +/// Computes the translation and rotation that brings the 'from' points +/// as close as possible to the 'to' points under the Frobenius norm. +/// To be more specific, let x be the matrix of 'from' points and y be +/// the matrix of 'to' points, we want to find the matrix A of the form +/// [ R t ] +/// [ 0 1 ] +/// that minimizes +/// || (A*x - y)^T * W * (A*x - y) ||_F +/// If doScaling is true, then a uniform scale is allowed also. +/// @param A From points +/// @param B To points +/// @param weights Per-point weights +/// @param numPoints The number of points in `A`, `B`, and `weights` (must be equal) +/// @param doScaling If true, include a scaling transformation +/// @return The procrustes transformation template -IMATH_INTERNAL_NAMESPACE::M44d -procrustesRotationAndTranslation (const IMATH_INTERNAL_NAMESPACE::Vec3* A, // From these - const IMATH_INTERNAL_NAMESPACE::Vec3* B, // To these +M44d +procrustesRotationAndTranslation (const Vec3* A, + const Vec3* B, const T* weights, const size_t numPoints, const bool doScaling = false); -// Unweighted: +/// Computes the translation and rotation that brings the 'from' points +/// as close as possible to the 'to' points under the Frobenius norm. +/// To be more specific, let x be the matrix of 'from' points and y be +/// the matrix of 'to' points, we want to find the matrix A of the form +/// [ R t ] +/// [ 0 1 ] +/// that minimizes +/// || (A*x - y)^T * W * (A*x - y) ||_F +/// If doScaling is true, then a uniform scale is allowed also. +/// @param A From points +/// @param B To points +/// @param numPoints The number of points in `A` and `B` (must be equal) +/// @param doScaling If true, include a scaling transformation +/// @return The procrustes transformation template -IMATH_INTERNAL_NAMESPACE::M44d -procrustesRotationAndTranslation (const IMATH_INTERNAL_NAMESPACE::Vec3* A, - const IMATH_INTERNAL_NAMESPACE::Vec3* B, +M44d +procrustesRotationAndTranslation (const Vec3* A, + const Vec3* B, const size_t numPoints, const bool doScaling = false); -// Compute the SVD of a 3x3 matrix using Jacobi transformations. This method -// should be quite accurate (competitive with LAPACK) even for poorly -// conditioned matrices, and because it has been written specifically for the -// 3x3/4x4 case it is much faster than calling out to LAPACK. -// -// The SVD of a 3x3/4x4 matrix A is defined as follows: -// A = U * S * V^T -// where S is the diagonal matrix of singular values and both U and V are -// orthonormal. By convention, the entries S are all positive and sorted from -// the largest to the smallest. However, some uses of this function may -// require that the matrix U*V^T have positive determinant; in this case, we -// may make the smallest singular value negative to ensure that this is -// satisfied. -// -// Currently only available for single- and double-precision matrices. +/// Compute the SVD of a 3x3 matrix using Jacobi transformations. This method +/// should be quite accurate (competitive with LAPACK) even for poorly +/// conditioned matrices, and because it has been written specifically for the +/// 3x3/4x4 case it is much faster than calling out to LAPACK. +/// +/// The SVD of a 3x3/4x4 matrix A is defined as follows: +/// A = U * S * V^T +/// where S is the diagonal matrix of singular values and both U and V are +/// orthonormal. By convention, the entries S are all positive and sorted from +/// the largest to the smallest. However, some uses of this function may +/// require that the matrix U*V^T have positive determinant; in this case, we +/// may make the smallest singular value negative to ensure that this is +/// satisfied. +/// +/// Currently only available for single- and double-precision matrices. template -void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix33& A, - IMATH_INTERNAL_NAMESPACE::Matrix33& U, - IMATH_INTERNAL_NAMESPACE::Vec3& S, - IMATH_INTERNAL_NAMESPACE::Matrix33& V, - const T tol = IMATH_INTERNAL_NAMESPACE::limits::epsilon(), +void jacobiSVD (const Matrix33& A, + Matrix33& U, + Vec3& S, + Matrix33& V, + const T tol = limits::epsilon(), const bool forcePositiveDeterminant = false); +/// Compute the SVD of a 3x3 matrix using Jacobi transformations. This method +/// should be quite accurate (competitive with LAPACK) even for poorly +/// conditioned matrices, and because it has been written specifically for the +/// 3x3/4x4 case it is much faster than calling out to LAPACK. +/// +/// The SVD of a 3x3/4x4 matrix A is defined as follows: +/// A = U * S * V^T +/// where S is the diagonal matrix of singular values and both U and V are +/// orthonormal. By convention, the entries S are all positive and sorted from +/// the largest to the smallest. However, some uses of this function may +/// require that the matrix U*V^T have positive determinant; in this case, we +/// may make the smallest singular value negative to ensure that this is +/// satisfied. +/// +/// Currently only available for single- and double-precision matrices. template -void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix44& A, - IMATH_INTERNAL_NAMESPACE::Matrix44& U, - IMATH_INTERNAL_NAMESPACE::Vec4& S, - IMATH_INTERNAL_NAMESPACE::Matrix44& V, - const T tol = IMATH_INTERNAL_NAMESPACE::limits::epsilon(), +void jacobiSVD (const Matrix44& A, + Matrix44& U, + Vec4& S, + Matrix44& V, + const T tol = limits::epsilon(), const bool forcePositiveDeterminant = false); -// Compute the eigenvalues (S) and the eigenvectors (V) of -// a real symmetric matrix using Jacobi transformation. -// -// Jacobi transformation of a 3x3/4x4 matrix A outputs S and V: -// A = V * S * V^T -// where V is orthonormal and S is the diagonal matrix of eigenvalues. -// Input matrix A must be symmetric. A is also modified during -// the computation so that upper diagonal entries of A become zero. -// +/// Compute the eigenvalues (S) and the eigenvectors (V) of a real +/// symmetric matrix using Jacobi transformation, using a given +/// tolerance `tol`. +/// +/// Jacobi transformation of a 3x3/4x4 matrix A outputs S and V: +/// A = V * S * V^T +/// where V is orthonormal and S is the diagonal matrix of eigenvalues. +/// Input matrix A must be symmetric. A is also modified during +/// the computation so that upper diagonal entries of A become zero. template void jacobiEigenSolver (Matrix33& A, Vec3& S, Matrix33& V, const T tol); +/// Compute the eigenvalues (S) and the eigenvectors (V) of +/// a real symmetric matrix using Jacobi transformation. +/// +/// Jacobi transformation of a 3x3/4x4 matrix A outputs S and V: +/// A = V * S * V^T +/// where V is orthonormal and S is the diagonal matrix of eigenvalues. +/// Input matrix A must be symmetric. A is also modified during +/// the computation so that upper diagonal entries of A become zero. template inline void jacobiEigenSolver (Matrix33& A, Vec3& S, Matrix33& V) @@ -1273,9 +1477,26 @@ jacobiEigenSolver (Matrix33& A, Vec3& S, Matrix33& V) jacobiEigenSolver (A, S, V, limits::epsilon()); } +/// Compute the eigenvalues (S) and the eigenvectors (V) of a real +/// symmetric matrix using Jacobi transformation, using a given +/// tolerance `tol`. +/// +/// Jacobi transformation of a 3x3/4x4 matrix A outputs S and V: +/// A = V * S * V^T +/// where V is orthonormal and S is the diagonal matrix of eigenvalues. +/// Input matrix A must be symmetric. A is also modified during +/// the computation so that upper diagonal entries of A become zero. template void jacobiEigenSolver (Matrix44& A, Vec4& S, Matrix44& V, const T tol); +/// Compute the eigenvalues (S) and the eigenvectors (V) of +/// a real symmetric matrix using Jacobi transformation. +/// +/// Jacobi transformation of a 3x3/4x4 matrix A outputs S and V: +/// A = V * S * V^T +/// where V is orthonormal and S is the diagonal matrix of eigenvalues. +/// Input matrix A must be symmetric. A is also modified during +/// the computation so that upper diagonal entries of A become zero. template inline void jacobiEigenSolver (Matrix44& A, Vec4& S, Matrix44& V) @@ -1283,9 +1504,12 @@ jacobiEigenSolver (Matrix44& A, Vec4& S, Matrix44& V) jacobiEigenSolver (A, S, V, limits::epsilon()); } -// Compute a eigenvector corresponding to the abs max/min eigenvalue -// of a real symmetric matrix using Jacobi transformation. +/// Compute a eigenvector corresponding to the abs max eigenvalue +/// of a real symmetric matrix using Jacobi transformation. template void maxEigenVector (TM& A, TV& S); + +/// Compute a eigenvector corresponding to the abs min eigenvalue +/// of a real symmetric matrix using Jacobi transformation. template void minEigenVector (TM& A, TV& S); IMATH_INTERNAL_NAMESPACE_HEADER_EXIT diff --git a/src/Imath/ImathNamespace.h b/src/Imath/ImathNamespace.h index 0b823d16..64d750e1 100644 --- a/src/Imath/ImathNamespace.h +++ b/src/Imath/ImathNamespace.h @@ -3,9 +3,8 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHNAMESPACE_H -#define INCLUDED_IMATHNAMESPACE_H - +// +// The Imath library namespace // // The purpose of this file is to make it possible to specify an // IMATH_INTERNAL_NAMESPACE as a preprocessor definition and have all of the @@ -42,10 +41,11 @@ // } // -// -// Open Source version of this file pulls in the IlmBaseConfig.h file -// for the configure time options. -// +#ifndef INCLUDED_IMATHNAMESPACE_H +#define INCLUDED_IMATHNAMESPACE_H + +/// @cond Doxygen_Suppress + #include "ImathConfig.h" #ifndef IMATH_NAMESPACE @@ -87,4 +87,6 @@ using namespace IMATH_INTERNAL_NAMESPACE; { #define IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT } +/// @endcond + #endif /* INCLUDED_IMATHNAMESPACE_H */ diff --git a/src/Imath/ImathPlane.h b/src/Imath/ImathPlane.h index 9cb37360..7fde3076 100644 --- a/src/Imath/ImathPlane.h +++ b/src/Imath/ImathPlane.h @@ -3,23 +3,12 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHPLANE_H -#define INCLUDED_IMATHPLANE_H - -//---------------------------------------------------------------------- // -// template class Plane3 +// A 3D plane class template // -// The Imath::Plane3<> class represents a half space, so the -// normal may point either towards or away from origin. The -// plane P can be represented by Imath::Plane3 as either p or -p -// corresponding to the two half-spaces on either side of the -// plane. Any function which computes a distance will return -// either negative or positive values for the distance indicating -// which half-space the point is in. Note that reflection, and -// intersection functions will operate as expected. -// -//---------------------------------------------------------------------- + +#ifndef INCLUDED_IMATHPLANE_H +#define INCLUDED_IMATHPLANE_H #include "ImathLine.h" #include "ImathNamespace.h" @@ -27,49 +16,96 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER +/// +/// The `Plane3` class represents a half space in 3D, so the normal +/// may point either towards or away from origin. The plane `P` can +/// be represented by Plane3 as either `p` or `-p` corresponding to +/// the two half-spaces on either side of the plane. Any function +/// which computes a distance will return either negative or positive +/// values for the distance indicating which half-space the point is +/// in. Note that reflection, and intersection functions will operate +/// as expected. + template class Plane3 { public: + + /// @{ + /// @name Direct access to member fields + + /// The normal to the plane Vec3 normal; + + /// The distance from the origin to the plane T distance; + /// @} + + /// @{ + /// @name Constructors + + /// Uninitialized by default IMATH_HOSTDEVICE constexpr Plane3() noexcept {} + + /// Initialize with a normal and distance IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Plane3 (const Vec3& normal, T distance) noexcept; + + /// Initialize with a point and a normal IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Plane3 (const Vec3& point, const Vec3& normal) noexcept; + + /// Initialize with three points IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Plane3 (const Vec3& point1, const Vec3& point2, const Vec3& point3) noexcept; - //---------------------- - // Various set methods - //---------------------- - + /// @} + + /// @{ + /// @name Manipulation + + /// Set via a given normal and distance IMATH_HOSTDEVICE void set (const Vec3& normal, T distance) noexcept; + /// Set via a given point and normal IMATH_HOSTDEVICE void set (const Vec3& point, const Vec3& normal) noexcept; + /// Set via three points IMATH_HOSTDEVICE void set (const Vec3& point1, const Vec3& point2, const Vec3& point3) noexcept; - //---------------------- - // Utilities - //---------------------- - + /// @} + + /// @{ + /// @name Utility Methods + + /// Determine if a line intersects the plane. + /// @param line The line + /// @param[out] intersection The point of intersection + /// @return True if the line intersects the plane. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersect (const Line3& line, Vec3& intersection) const noexcept; + /// Determine if a line intersects the plane. + /// @param line The line + /// @param[out] parameter The parametric value of the point of intersection + /// @return True if the line intersects the plane. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersectT (const Line3& line, T& parameter) const noexcept; - IMATH_HOSTDEVICE constexpr T distanceTo (const Vec3&) const noexcept; + /// Return the distance from a point to the plane. + IMATH_HOSTDEVICE constexpr T distanceTo (const Vec3& point) const noexcept; - IMATH_HOSTDEVICE constexpr Vec3 reflectPoint (const Vec3&) const noexcept; - IMATH_HOSTDEVICE constexpr Vec3 reflectVector (const Vec3&) const noexcept; -}; + /// Reflect the given point around the plane. + IMATH_HOSTDEVICE constexpr Vec3 reflectPoint (const Vec3& point) const noexcept; + + /// Reflect the direction vector around the plane + IMATH_HOSTDEVICE constexpr Vec3 reflectVector (const Vec3& vec) const noexcept; -//-------------------- -// Convenient typedefs -//-------------------- + /// @} +}; +/// Plane of type float typedef Plane3 Plane3f; + +/// Plane of type double typedef Plane3 Plane3d; //--------------- @@ -163,6 +199,7 @@ Plane3::intersectT (const Line3& line, T& t) const noexcept return true; } +/// Stream output template std::ostream& operator<< (std::ostream& o, const Plane3& plane) @@ -170,6 +207,7 @@ operator<< (std::ostream& o, const Plane3& plane) return o << "(" << plane.normal << ", " << plane.distance << ")"; } +/// Transform a plane by a matrix template IMATH_CONSTEXPR14 Plane3 operator* (const Plane3& plane, const Matrix44& M) noexcept @@ -205,6 +243,7 @@ operator* (const Plane3& plane, const Matrix44& M) noexcept return Plane3 (point * M, (point + dir2) * M, (point + dir1) * M); } +/// Reflect the pla template constexpr inline Plane3 operator- (const Plane3& plane) noexcept diff --git a/src/Imath/ImathPlatform.h b/src/Imath/ImathPlatform.h index 844e5036..7009740c 100644 --- a/src/Imath/ImathPlatform.h +++ b/src/Imath/ImathPlatform.h @@ -3,18 +3,16 @@ // Copyright Contributors to the OpenEXR Project. // +// +// This file contains functions and constants which aren't +// provided by the system libraries, compilers, or includes on +// certain platforms. +// + #ifndef INCLUDED_IMATHPLATFORM_H #define INCLUDED_IMATHPLATFORM_H -//---------------------------------------------------------------------------- -// -// ImathPlatform.h -// -// This file contains functions and constants which aren't -// provided by the system libraries, compilers, or includes on -// certain platforms. -// -//---------------------------------------------------------------------------- +/// @cond Doxygen_Suppress #include #include @@ -23,7 +21,6 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER - // // Helpful macros for checking which C++ standard we are compiling with. // @@ -94,4 +91,6 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER IMATH_INTERNAL_NAMESPACE_HEADER_EXIT +/// @endcond + #endif // INCLUDED_IMATHPLATFORM_H diff --git a/src/Imath/ImathQuat.h b/src/Imath/ImathQuat.h index 7e4c6801..2fc37ef6 100644 --- a/src/Imath/ImathQuat.h +++ b/src/Imath/ImathQuat.h @@ -3,26 +3,19 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHQUAT_H -#define INCLUDED_IMATHQUAT_H - -//---------------------------------------------------------------------- // -// template class Quat +// A quaternion // -// "Quaternions came from Hamilton ... and have been an unmixed -// evil to those who have touched them in any way. Vector is a -// useless survival ... and has never been of the slightest use -// to any creature." +// "Quaternions came from Hamilton ... and have been an unmixed +// evil to those who have touched them in any way. Vector is a +// useless survival ... and has never been of the slightest use +// to any creature." // -// - Lord Kelvin +// - Lord Kelvin // -// This class implements the quaternion numerical type -- you -// will probably want to use this class to represent orientations -// in R3 and to convert between various euler angle reps. You -// should probably use Imath::Euler<> for that. -// -//---------------------------------------------------------------------- + +#ifndef INCLUDED_IMATHQUAT_H +#define INCLUDED_IMATHQUAT_H #include "ImathMatrix.h" #include "ImathNamespace.h" @@ -36,92 +29,162 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER # pragma warning(disable : 4244) #endif +/// +/// The Quat class implements the quaternion numerical type -- you +/// will probably want to use this class to represent orientations +/// in R3 and to convert between various euler angle reps. You +/// should probably use Imath::Euler<> for that. +/// + template class Quat { public: - T r; // real part - Vec3 v; // imaginary vector - //----------------------------------------------------- - // Constructors - default constructor is identity quat - //----------------------------------------------------- + /// @{ + /// @name Direct access to elements + + /// The real part + T r; + + /// The imaginary vector + Vec3 v; + + /// @} + + /// Element access: q[0] is the real part, (q[1],q[2],q[3]) is the + /// imaginary part. + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T& operator[] (int index) noexcept; // as 4D vector + /// Element access: q[0] is the real part, (q[1],q[2],q[3]) is the + /// imaginary part. + IMATH_HOSTDEVICE constexpr T operator[] (int index) const noexcept; + + /// @{ + /// @name Constructors + + /// Default constructor is the identity quat IMATH_HOSTDEVICE constexpr Quat() noexcept; - template IMATH_HOSTDEVICE constexpr Quat (const Quat& q) noexcept; + /// Copy constructor + IMATH_HOSTDEVICE constexpr Quat (const Quat& q) noexcept; + + /// Construct from a quaternion of a another base type + template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Quat (const Quat& q) noexcept; + /// Initialize with real part `s` and imaginary vector 1(i,j,k)` IMATH_HOSTDEVICE constexpr Quat (T s, T i, T j, T k) noexcept; + /// Initialize with real part `s` and imaginary vector `d` IMATH_HOSTDEVICE constexpr Quat (T s, Vec3 d) noexcept; + /// The identity quaternion IMATH_HOSTDEVICE constexpr static Quat identity() noexcept; - //------------------- - // Copy constructor - //------------------- - - IMATH_HOSTDEVICE constexpr Quat (const Quat& q) noexcept; - - //------------- - // Destructor - //------------- + /// Assignment + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Quat& operator= (const Quat& q) noexcept; + /// Destructor ~Quat() noexcept = default; - //------------------------------------------------- - // Basic Algebra - Operators and Methods - // The operator return values are *NOT* normalized - // - // operator^ and euclideanInnnerProduct() both - // implement the 4D dot product - // - // operator/ uses the inverse() quaternion - // - // operator~ is conjugate -- if (S+V) is quat then - // the conjugate (S+V)* == (S-V) + /// @} + + /// @{ + /// @name Basic Algebra + /// + /// Note that the operator return values are *NOT* normalized // - // some operators (*,/,*=,/=) treat the quat as - // a 4D vector when one of the operands is scalar - //------------------------------------------------- - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Quat& operator= (const Quat& q) noexcept; + /// Quaternion multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Quat& operator*= (const Quat& q) noexcept; + + /// Scalar multiplication: multiply both real and imaginary parts + /// by the given scalar. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Quat& operator*= (T t) noexcept; + + /// Quaterion division, using the inverse() IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Quat& operator/= (const Quat& q) noexcept; + + /// Scalar division: multiply both real and imaginary parts + /// by the given scalar. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Quat& operator/= (T t) noexcept; + + /// Quaternion addition IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Quat& operator+= (const Quat& q) noexcept; + + /// Quaternion subtraction IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Quat& operator-= (const Quat& q) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T& operator[] (int index) noexcept; // as 4D vector - IMATH_HOSTDEVICE constexpr T operator[] (int index) const noexcept; + /// Equality template IMATH_HOSTDEVICE constexpr bool operator== (const Quat& q) const noexcept; - template IMATH_HOSTDEVICE constexpr bool operator!= (const Quat& q) const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Quat& invert() noexcept; // this -> 1 / this - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Quat inverse() const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Quat& normalize() noexcept; // returns this - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Quat normalized() const noexcept; - IMATH_HOSTDEVICE constexpr T length() const noexcept; // in R4 - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec3 rotateVector (const Vec3& original) const noexcept; - IMATH_HOSTDEVICE constexpr T euclideanInnerProduct (const Quat& q) const noexcept; + /// Inequality + template IMATH_HOSTDEVICE constexpr bool operator!= (const Quat& q) const noexcept; - //----------------------- - // Rotation conversion - //----------------------- + /// @} - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Quat& setAxisAngle (const Vec3& axis, T radians) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Quat& - setRotation (const Vec3& fromDirection, const Vec3& toDirection) noexcept; + /// @{ + /// @name Query + + /// Return the R4 length + IMATH_HOSTDEVICE constexpr T length() const noexcept; // in R4 + /// Return the angle of the axis/angle representation IMATH_HOSTDEVICE constexpr T angle() const noexcept; + + /// Return the axis of the axis/angle representation IMATH_HOSTDEVICE constexpr Vec3 axis() const noexcept; + /// Return a 3x3 rotation matrix IMATH_HOSTDEVICE constexpr Matrix33 toMatrix33() const noexcept; + + /// Return a 4x4 rotation matrix IMATH_HOSTDEVICE constexpr Matrix44 toMatrix44() const noexcept; + + /// Return the logarithm of the quaterion IMATH_HOSTDEVICE Quat log() const noexcept; + + /// Return the exponent of the quaterion IMATH_HOSTDEVICE Quat exp() const noexcept; + /// @} + + /// @{ + /// @name Utility Methods + + /// Invert in place: this = 1 / this. + /// @return const reference to this. + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Quat& invert() noexcept; + + /// Return 1/this, leaving this unchanged. + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Quat inverse() const noexcept; + + /// Normalize in place + /// @return const reference to this. + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Quat& normalize() noexcept; + + /// Return a normalized quaternion, leaving this unmodified. + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Quat normalized() const noexcept; + + /// Rotate the given point by the quaterion. + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec3 rotateVector (const Vec3& original) const noexcept; + + /// Return the Euclidean inner product. + IMATH_HOSTDEVICE constexpr T euclideanInnerProduct (const Quat& q) const noexcept; + + /// Set the quaterion to be a rotation around the given axis by the + /// given angle. + /// @return const reference to this. + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Quat& setAxisAngle (const Vec3& axis, T radians) noexcept; + + /// Set the quaternion to be a rotation that transforms the + /// direction vector `fromDirection` to `toDirection` + /// @return const reference to this. + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Quat& + setRotation (const Vec3& fromDirection, const Vec3& toDirection) noexcept; + + /// @} + private: IMATH_HOSTDEVICE void setRotationInternal (const Vec3& f0, const Vec3& t0, Quat& q) noexcept; }; @@ -135,6 +198,12 @@ template IMATH_CONSTEXPR14 Quat squad (const Quat& q1, const Quat& q2, const Quat& qa, const Quat& qb, T t) noexcept; +/// +/// From advanced Animation and Rendering Techniques by Watt and Watt, +/// Page 366: +/// +/// computing the inner quadrangle points (qa and qb) to guarantee +/// tangent continuity. template void intermediate (const Quat& q0, const Quat& q1, @@ -169,11 +238,10 @@ template constexpr Quat operator- (const Quat& q) noexcept; template IMATH_CONSTEXPR14 Vec3 operator* (const Vec3& v, const Quat& q) noexcept; -//-------------------- -// Convenient typedefs -//-------------------- - +/// Quaternion of type float typedef Quat Quatf; + +/// Quaternion of type double typedef Quat Quatd; //--------------- @@ -187,7 +255,7 @@ template constexpr inline Quat::Quat() noexcept : r (1), v (0, 0, 0 template template -constexpr inline Quat::Quat (const Quat& q) noexcept : r (q.r), v (q.v) +IMATH_CONSTEXPR14 inline Quat::Quat (const Quat& q) noexcept : r (q.r), v (q.v) { // empty } @@ -307,6 +375,7 @@ Quat::operator!= (const Quat& q) const noexcept return r != q.r || v != q.v; } +/// 4D dot product template IMATH_HOSTDEVICE constexpr inline T operator^ (const Quat& q1, const Quat& q2) noexcept @@ -400,15 +469,13 @@ Quat::euclideanInnerProduct (const Quat& q) const noexcept return r * q.r + v.x * q.v.x + v.y * q.v.y + v.z * q.v.z; } +/// +/// Compute the angle between two quaternions, +/// interpreting the quaternions as 4D vectors. template IMATH_CONSTEXPR14 inline T angle4D (const Quat& q1, const Quat& q2) noexcept { - // - // Compute the angle between two quaternions, - // interpreting the quaternions as 4D vectors. - // - Quat d = q1 - q2; T lengthD = std::sqrt (d ^ d); @@ -418,29 +485,27 @@ angle4D (const Quat& q1, const Quat& q2) noexcept return 2 * std::atan2 (lengthD, lengthS); } +/// +/// Spherical linear interpolation. +/// Assumes q1 and q2 are normalized and that q1 != -q2. +/// +/// This method does *not* interpolate along the shortest +/// arc between q1 and q2. If you desire interpolation +/// along the shortest arc, and q1^q2 is negative, then +/// consider calling slerpShortestArc(), below, or flipping +/// the second quaternion explicitly. +/// +/// The implementation of squad() depends on a slerp() +/// that interpolates as is, without the automatic +/// flipping. +/// +/// Don Hatch explains the method we use here on his +/// web page, The Right Way to Calculate Stuff, at +/// http://www.plunk.org/~hatch/rightway.php template IMATH_CONSTEXPR14 inline Quat slerp (const Quat& q1, const Quat& q2, T t) noexcept { - // - // Spherical linear interpolation. - // Assumes q1 and q2 are normalized and that q1 != -q2. - // - // This method does *not* interpolate along the shortest - // arc between q1 and q2. If you desire interpolation - // along the shortest arc, and q1^q2 is negative, then - // consider calling slerpShortestArc(), below, or flipping - // the second quaternion explicitly. - // - // The implementation of squad() depends on a slerp() - // that interpolates as is, without the automatic - // flipping. - // - // Don Hatch explains the method we use here on his - // web page, The Right Way to Calculate Stuff, at - // http://www.plunk.org/~hatch/rightway.php - // - T a = angle4D (q1, q2); T s = 1 - t; @@ -450,48 +515,42 @@ slerp (const Quat& q1, const Quat& q2, T t) noexcept return q.normalized(); } +/// +/// Spherical linear interpolation along the shortest +/// arc from q1 to either q2 or -q2, whichever is closer. +/// Assumes q1 and q2 are unit quaternions. template IMATH_CONSTEXPR14 inline Quat slerpShortestArc (const Quat& q1, const Quat& q2, T t) noexcept { - // - // Spherical linear interpolation along the shortest - // arc from q1 to either q2 or -q2, whichever is closer. - // Assumes q1 and q2 are unit quaternions. - // - if ((q1 ^ q2) >= 0) return slerp (q1, q2, t); else return slerp (q1, -q2, t); } +/// +/// Spherical Cubic Spline Interpolation - from Advanced Animation and +/// Rendering Techniques by Watt and Watt, Page 366: +/// +/// A spherical curve is constructed using three spherical linear +/// interpolations of a quadrangle of unit quaternions: q1, qa, qb, +/// q2. Given a set of quaternion keys: q0, q1, q2, q3, this routine +/// does the interpolation between q1 and q2 by constructing two +/// intermediate quaternions: qa and qb. The qa and qb are computed by +/// the intermediate function to guarantee the continuity of tangents +/// across adjacent cubic segments. The qa represents in-tangent for +/// q1 and the qb represents the out-tangent for q2. +/// +/// The q1 q2 is the cubic segment being interpolated. +/// +/// The q0 is from the previous adjacent segment and q3 is from the +/// next adjacent segment. The q0 and q3 are used in computing qa and +/// qb. template IMATH_CONSTEXPR14 inline Quat spline (const Quat& q0, const Quat& q1, const Quat& q2, const Quat& q3, T t) noexcept { - // - // Spherical Cubic Spline Interpolation - - // from Advanced Animation and Rendering - // Techniques by Watt and Watt, Page 366: - // A spherical curve is constructed using three - // spherical linear interpolations of a quadrangle - // of unit quaternions: q1, qa, qb, q2. - // Given a set of quaternion keys: q0, q1, q2, q3, - // this routine does the interpolation between - // q1 and q2 by constructing two intermediate - // quaternions: qa and qb. The qa and qb are - // computed by the intermediate function to - // guarantee the continuity of tangents across - // adjacent cubic segments. The qa represents in-tangent - // for q1 and the qb represents the out-tangent for q2. - // - // The q1 q2 is the cubic segment being interpolated. - // The q0 is from the previous adjacent segment and q3 is - // from the next adjacent segment. The q0 and q3 are used - // in computing qa and qb. - // - Quat qa = intermediate (q0, q1, q2); Quat qb = intermediate (q1, q2, q3); Quat result = squad (q1, qa, qb, q2, t); @@ -499,19 +558,17 @@ spline (const Quat& q0, const Quat& q1, const Quat& q2, const Quat& return result; } +/// +/// Spherical Quadrangle Interpolation - from Advanced Animation and +/// Rendering Techniques by Watt and Watt, Page 366: +/// +/// It constructs a spherical cubic interpolation as a series of three +/// spherical linear interpolations of a quadrangle of unit +/// quaternions. template IMATH_CONSTEXPR14 inline Quat squad (const Quat& q1, const Quat& qa, const Quat& qb, const Quat& q2, T t) noexcept { - // - // Spherical Quadrangle Interpolation - - // from Advanced Animation and Rendering - // Techniques by Watt and Watt, Page 366: - // It constructs a spherical cubic interpolation as - // a series of three spherical linear interpolations - // of a quadrangle of unit quaternions. - // - Quat r1 = slerp (q1, q2, t); Quat r2 = slerp (qa, qb, t); Quat result = slerp (r1, r2, 2 * t * (1 - t)); @@ -519,18 +576,12 @@ squad (const Quat& q1, const Quat& qa, const Quat& qb, const Quat& q return result; } +/// Compute the intermediate point between three quaternions `q0`, `q1`, +/// and `q2`. template IMATH_CONSTEXPR14 inline Quat intermediate (const Quat& q0, const Quat& q1, const Quat& q2) noexcept { - // - // From advanced Animation and Rendering - // Techniques by Watt and Watt, Page 366: - // computing the inner quadrangle - // points (qa and qb) to guarantee tangent - // continuity. - // - Quat q1inv = q1.inverse(); Quat c1 = q1inv * q2; Quat c2 = q1inv * q0; @@ -756,6 +807,8 @@ Quat::toMatrix44() const noexcept 1); } +/// Transform the quaternion by the matrix +/// @return M * q template constexpr inline Matrix33 operator* (const Matrix33& M, const Quat& q) noexcept @@ -763,6 +816,8 @@ operator* (const Matrix33& M, const Quat& q) noexcept return M * q.toMatrix33(); } +/// Transform the matrix by the quaterion: +/// @return q * M template constexpr inline Matrix33 operator* (const Quat& q, const Matrix33& M) noexcept @@ -770,6 +825,7 @@ operator* (const Quat& q, const Matrix33& M) noexcept return q.toMatrix33() * M; } +/// Stream output template std::ostream& operator<< (std::ostream& o, const Quat& q) @@ -777,6 +833,7 @@ operator<< (std::ostream& o, const Quat& q) return o << "(" << q.r << " " << q.v.x << " " << q.v.y << " " << q.v.z << ")"; } +/// Quaterion multiplication template constexpr inline Quat operator* (const Quat& q1, const Quat& q2) noexcept @@ -784,6 +841,7 @@ operator* (const Quat& q1, const Quat& q2) noexcept return Quat (q1.r * q2.r - (q1.v ^ q2.v), q1.r * q2.v + q1.v * q2.r + q1.v % q2.v); } +/// Quaterion division template constexpr inline Quat operator/ (const Quat& q1, const Quat& q2) noexcept @@ -791,6 +849,7 @@ operator/ (const Quat& q1, const Quat& q2) noexcept return q1 * q2.inverse(); } +/// Quaterion division template constexpr inline Quat operator/ (const Quat& q, T t) noexcept @@ -798,6 +857,8 @@ operator/ (const Quat& q, T t) noexcept return Quat (q.r / t, q.v / t); } +/// Quaterion*scalar multiplication +/// @return q * t template constexpr inline Quat operator* (const Quat& q, T t) noexcept @@ -805,6 +866,8 @@ operator* (const Quat& q, T t) noexcept return Quat (q.r * t, q.v * t); } +/// Quaterion*scalar multiplication +/// @return q * t template constexpr inline Quat operator* (T t, const Quat& q) noexcept @@ -812,6 +875,7 @@ operator* (T t, const Quat& q) noexcept return Quat (q.r * t, q.v * t); } +/// Quaterion addition template constexpr inline Quat operator+ (const Quat& q1, const Quat& q2) noexcept @@ -819,6 +883,7 @@ operator+ (const Quat& q1, const Quat& q2) noexcept return Quat (q1.r + q2.r, q1.v + q2.v); } +/// Quaterion subtraction template constexpr inline Quat operator- (const Quat& q1, const Quat& q2) noexcept @@ -826,6 +891,7 @@ operator- (const Quat& q1, const Quat& q2) noexcept return Quat (q1.r - q2.r, q1.v - q2.v); } +/// Compute the conjugate template constexpr inline Quat operator~ (const Quat& q) noexcept @@ -833,6 +899,7 @@ operator~ (const Quat& q) noexcept return Quat (q.r, -q.v); } +/// Negate the quaterion template constexpr inline Quat operator- (const Quat& q) noexcept @@ -840,6 +907,8 @@ operator- (const Quat& q) noexcept return Quat (-q.r, -q.v); } +/// Quaterion*vector multiplcation +/// @return v * q template IMATH_CONSTEXPR14 inline Vec3 operator* (const Vec3& v, const Quat& q) noexcept diff --git a/src/Imath/ImathRandom.cpp b/src/Imath/ImathRandom.cpp index 875a588d..c2553c71 100644 --- a/src/Imath/ImathRandom.cpp +++ b/src/Imath/ImathRandom.cpp @@ -70,24 +70,22 @@ rand48Next (unsigned short state[3]) } // namespace +/// +/// Generate double-precision floating-point values between 0.0 and 1.0: +/// +/// The exponent is set to 0x3ff, which indicates a value greater +/// than or equal to 1.0, and less than 2.0. The 48 most significant +/// bits of the significand (mantissa) are filled with pseudo-random +/// bits generated by rand48Next(). The remaining 4 bits are a copy +/// of the 4 most significant bits of the significand. This results +/// in bit patterns between 0x3ff0000000000000 and 0x3fffffffffffffff, +/// which correspond to uniformly distributed floating-point values +/// between 1.0 and 1.99999999999999978. Subtracting 1.0 from those +/// values produces numbers between 0.0 and 0.99999999999999978, that +/// is, between 0.0 and 1.0-DBL_EPSILON. double erand48 (unsigned short state[3]) { - // - // Generate double-precision floating-point values between 0.0 and 1.0: - // - // The exponent is set to 0x3ff, which indicates a value greater - // than or equal to 1.0, and less than 2.0. The 48 most significant - // bits of the significand (mantissa) are filled with pseudo-random - // bits generated by rand48Next(). The remaining 4 bits are a copy - // of the 4 most significant bits of the significand. This results - // in bit patterns between 0x3ff0000000000000 and 0x3fffffffffffffff, - // which correspond to uniformly distributed floating-point values - // between 1.0 and 1.99999999999999978. Subtracting 1.0 from those - // values produces numbers between 0.0 and 0.99999999999999978, that - // is, between 0.0 and 1.0-DBL_EPSILON. - // - rand48Next (state); union @@ -107,19 +105,17 @@ erand48 (unsigned short state[3]) return u.d - 1; } +/// Return erand48() double drand48() { return IMATH_INTERNAL_NAMESPACE::erand48 (staticState); } +/// Generate uniformly distributed integers between 0 and 0x7fffffff. long int nrand48 (unsigned short state[3]) { - // - // Generate uniformly distributed integers between 0 and 0x7fffffff. - // - rand48Next (state); // clang-format off @@ -128,6 +124,7 @@ nrand48 (unsigned short state[3]) // clang-format on } +/// Return nrand48() long int lrand48() { diff --git a/src/Imath/ImathRandom.h b/src/Imath/ImathRandom.h index e8729411..24a0d3da 100644 --- a/src/Imath/ImathRandom.h +++ b/src/Imath/ImathRandom.h @@ -3,28 +3,20 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHRANDOM_H -#define INCLUDED_IMATHRANDOM_H - -//----------------------------------------------------------------------------- // -// Generators for uniformly distributed pseudo-random numbers and -// functions that use those generators to generate numbers with -// non-uniform distributions: +// Generators for uniformly distributed pseudo-random numbers and +// functions that use those generators to generate numbers with +// non-uniform distributions // -// class Rand32 -// class Rand48 -// solidSphereRand() -// hollowSphereRand() -// gaussRand() -// gaussSphereRand() +// Note: class Rand48() calls erand48() and nrand48(), which are not +// available on all operating systems. For compatibility we include +// our own versions of erand48() and nrand48(). Our functions +// have been reverse-engineered from the corresponding Unix/Linux +// man page. // -// Note: class Rand48() calls erand48() and nrand48(), which are not -// available on all operating systems. For compatibility we include -// our own versions of erand48() and nrand48(). Our functions have -// been reverse-engineered from the corresponding Unix/Linux man page. -// -//----------------------------------------------------------------------------- + +#ifndef INCLUDED_IMATHRANDOM_H +#define INCLUDED_IMATHRANDOM_H #include "ImathExport.h" #include "ImathNamespace.h" @@ -34,49 +26,29 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER -//----------------------------------------------- -// Fast random-number generator that generates -// a uniformly distributed sequence with a period -// length of 2^32. -//----------------------------------------------- - +/// Fast random-number generator that generates +/// a uniformly distributed sequence with a period +/// length of 2^32. class IMATH_EXPORT Rand32 { public: - //------------ - // Constructor - //------------ + /// Constructor, given a seed IMATH_HOSTDEVICE Rand32 (unsigned long int seed = 0); - //-------------------------------- - // Re-initialize with a given seed - //-------------------------------- - + /// Re-initialize with a given seed IMATH_HOSTDEVICE void init (unsigned long int seed); - //---------------------------------------------------------- - // Get the next value in the sequence (range: [false, true]) - //---------------------------------------------------------- - + /// Get the next value in the sequence (range: [false, true]) IMATH_HOSTDEVICE bool nextb(); - //--------------------------------------------------------------- - // Get the next value in the sequence (range: [0 ... 0xffffffff]) - //--------------------------------------------------------------- - + /// Get the next value in the sequence (range: [0 ... 0xffffffff]) IMATH_HOSTDEVICE unsigned long int nexti(); - //------------------------------------------------------ - // Get the next value in the sequence (range: [0 ... 1[) - //------------------------------------------------------ - + /// Get the next value in the sequence (range: [0 ... 1[) IMATH_HOSTDEVICE float nextf(); - //------------------------------------------------------------------- - // Get the next value in the sequence (range [rangeMin ... rangeMax[) - //------------------------------------------------------------------- - + /// Get the next value in the sequence (range [rangeMin ... rangeMax[) IMATH_HOSTDEVICE float nextf (float rangeMin, float rangeMax); private: @@ -85,93 +57,63 @@ class IMATH_EXPORT Rand32 unsigned long int _state; }; -//-------------------------------------------------------- -// Random-number generator based on the C Standard Library -// functions erand48(), nrand48() & company; generates a -// uniformly distributed sequence. -//-------------------------------------------------------- - +/// Random-number generator based on the C Standard Library +/// functions erand48(), nrand48() & company; generates a +/// uniformly distributed sequence. class Rand48 { public: - //------------ - // Constructor - //------------ + /// Constructor IMATH_HOSTDEVICE Rand48 (unsigned long int seed = 0); - //-------------------------------- - // Re-initialize with a given seed - //-------------------------------- - + /// Re-initialize with a given seed IMATH_HOSTDEVICE void init (unsigned long int seed); - //---------------------------------------------------------- - // Get the next value in the sequence (range: [false, true]) - //---------------------------------------------------------- - + /// Get the next value in the sequence (range: [false, true]) IMATH_HOSTDEVICE bool nextb(); - //--------------------------------------------------------------- - // Get the next value in the sequence (range: [0 ... 0x7fffffff]) - //--------------------------------------------------------------- - + /// Get the next value in the sequence (range: [0 ... 0x7fffffff]) IMATH_HOSTDEVICE long int nexti(); - //------------------------------------------------------ - // Get the next value in the sequence (range: [0 ... 1[) - //------------------------------------------------------ - + /// Get the next value in the sequence (range: [0 ... 1[) IMATH_HOSTDEVICE double nextf(); - //------------------------------------------------------------------- - // Get the next value in the sequence (range [rangeMin ... rangeMax[) - //------------------------------------------------------------------- - + /// Get the next value in the sequence (range [rangeMin ... rangeMax[) IMATH_HOSTDEVICE double nextf (double rangeMin, double rangeMax); private: unsigned short int _state[3]; }; -//------------------------------------------------------------ -// Return random points uniformly distributed in a sphere with -// radius 1 around the origin (distance from origin <= 1). -//------------------------------------------------------------ - +/// Return random points uniformly distributed in a sphere with +/// radius 1 around the origin (distance from origin <= 1). template IMATH_HOSTDEVICE Vec solidSphereRand (Rand& rand); -//------------------------------------------------------------- -// Return random points uniformly distributed on the surface of -// a sphere with radius 1 around the origin. -//------------------------------------------------------------- - +/// Return random points uniformly distributed on the surface of +/// a sphere with radius 1 around the origin. template IMATH_HOSTDEVICE Vec hollowSphereRand (Rand& rand); -//----------------------------------------------- -// Return random numbers with a normal (Gaussian) -// distribution with zero mean and unit variance. -//----------------------------------------------- - +/// Return random numbers with a normal (Gaussian) +/// distribution with zero mean and unit variance. template IMATH_HOSTDEVICE float gaussRand (Rand& rand); -//---------------------------------------------------- -// Return random points whose distance from the origin -// has a normal (Gaussian) distribution with zero mean -// and unit variance. -//---------------------------------------------------- - +/// Return random points whose distance from the origin +/// has a normal (Gaussian) distribution with zero mean +/// and unit variance. template IMATH_HOSTDEVICE Vec gaussSphereRand (Rand& rand); //--------------------------------- // erand48(), nrand48() and friends //--------------------------------- +/// @cond Doxygen_Suppress IMATH_HOSTDEVICE IMATH_EXPORT double erand48 (unsigned short state[3]); IMATH_HOSTDEVICE IMATH_EXPORT double drand48(); IMATH_HOSTDEVICE IMATH_EXPORT long int nrand48 (unsigned short state[3]); IMATH_HOSTDEVICE IMATH_EXPORT long int lrand48(); IMATH_HOSTDEVICE IMATH_EXPORT void srand48 (long int seed); +/// @endcond //--------------- // Implementation diff --git a/src/Imath/ImathRoots.h b/src/Imath/ImathRoots.h index a45aff00..5a44d691 100644 --- a/src/Imath/ImathRoots.h +++ b/src/Imath/ImathRoots.h @@ -3,18 +3,25 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHROOTS_H -#define INCLUDED_IMATHROOTS_H - -//--------------------------------------------------------------------- // -// Functions to solve linear, quadratic or cubic equations +// Functions to solve linear, quadratic or cubic equations +// +// Note: It is possible that an equation has real solutions, but that +// the solutions (or some intermediate result) are not representable. +// In this case, either some of the solutions returned are invalid +// (nan or infinity), or, if floating-point exceptions have been +// enabled, an exception is thrown. // -//--------------------------------------------------------------------- + +#ifndef INCLUDED_IMATHROOTS_H +#define INCLUDED_IMATHROOTS_H #include "ImathMath.h" #include "ImathNamespace.h" #include + +/// @cond Doxygen_Suppress + #ifdef __CUDACC__ # include # define COMPLEX_NAMESPACE thrust @@ -22,45 +29,54 @@ # define COMPLEX_NAMESPACE std #endif -IMATH_INTERNAL_NAMESPACE_HEADER_ENTER +/// @endcond -//-------------------------------------------------------------------------- -// Find the real solutions of a linear, quadratic or cubic equation: -// -// function equation solved -// -// solveLinear (a, b, x) a * x + b == 0 -// solveQuadratic (a, b, c, x) a * x*x + b * x + c == 0 -// solveNormalizedCubic (r, s, t, x) x*x*x + r * x*x + s * x + t == 0 -// solveCubic (a, b, c, d, x) a * x*x*x + b * x*x + c * x + d == 0 -// -// Return value: -// -// 3 three real solutions, stored in x[0], x[1] and x[2] -// 2 two real solutions, stored in x[0] and x[1] -// 1 one real solution, stored in x[1] -// 0 no real solutions -// -1 all real numbers are solutions -// -// Notes: -// -// * It is possible that an equation has real solutions, but that the -// solutions (or some intermediate result) are not representable. -// In this case, either some of the solutions returned are invalid -// (nan or infinity), or, if floating-point exceptions have been -// enabled with Iex::mathExcOn(), an Iex::MathExc exception is -// thrown. -// -// * Cubic equations are solved using Cardano's Formula; even though -// only real solutions are produced, some intermediate results are -// complex (std::complex). -// -//-------------------------------------------------------------------------- +IMATH_INTERNAL_NAMESPACE_HEADER_ENTER +/// +/// Solve for x in the linear equation: +/// +/// a * x + b == 0 +/// +/// @return 1 if the equation has a solution, 0 if there is no +/// solution, and -1 if all real numbers are solutions. template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 int solveLinear (T a, T b, T& x); + +/// +/// Solve for x in the quadratic equation: +/// +/// a * x*x + b * x + c == 0 +/// +/// @return 2 if the equation has two solutions, 1 if the equation has +/// a single solution, 0 if there is no solution, and -1 if all real +/// numbers are solutions. template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 int solveQuadratic (T a, T b, T c, T x[2]); template + +/// +/// Solve for x in the normalized cubic equation: +/// +/// x*x*x + r * x*x + s * x + t == 0 +/// +/// The equation is solved using Cardano's Formula; even though only +/// real solutions are produced, some intermediate results are complex +/// (std::complex). +/// +/// @return 0 if there is no solution, and -1 if all real +/// numbers are solutions, otherwise return the number of solutions. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 int solveNormalizedCubic (T r, T s, T t, T x[3]); + +/// +/// Solve for x in the cubic equation: +/// +/// a * x*x*x + b * x*x + c * x + d == 0 +/// +/// The equation is solved using Cardano's Formula; even though only +/// real solutions are produced, some intermediate results are complex +/// (std::complex). +/// +/// @return 0 if there is no solution, and -1 if all real +/// numbers are solutions, otherwise return the number of solutions. template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 int solveCubic (T a, T b, T c, T d, T x[3]); //--------------- diff --git a/src/Imath/ImathShear.h b/src/Imath/ImathShear.h index fd54d8b8..c290728c 100644 --- a/src/Imath/ImathShear.h +++ b/src/Imath/ImathShear.h @@ -3,14 +3,12 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHSHEAR_H -#define INCLUDED_IMATHSHEAR_H - -//---------------------------------------------------- // -// Shear6 class template. +// A representation of a shear transformation // -//---------------------------------------------------- + +#ifndef INCLUDED_IMATHSHEAR_H +#define INCLUDED_IMATHSHEAR_H #include "ImathLimits.h" #include "ImathMath.h" @@ -20,179 +18,288 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER +/// +/// Shear6 class template. +/// +/// A shear matrix is technically defined as having a single nonzero +/// off-diagonal element; more generally, a shear transformation is +/// defined by those off-diagonal elements, so in 3D, that means there +/// are 6 possible elements/coefficients: +/// +/// | X' | | 1 YX ZX 0 | | X | +/// | Y' | | XY 1 ZY 0 | | Y | +/// | Z' | = | XZ YZ 1 0 | = | Z | +/// | 1 | | 0 0 0 1 | | 1 | +/// +/// X' = X + YX * Y + ZX * Z +/// Y' = YX * X + Y + ZY * Z +/// Z` = XZ * X + YZ * Y + Z +/// +/// See +/// https://www.cs.drexel.edu/~david/Classes/CS430/Lectures/L-04_3DTransformations.6.pdf +/// +/// Those variable elements correspond to the 6 values in a Shear6. +/// So, looking at those equations, "Shear YX", for example, means +/// that for any point transformed by that matrix, its X values will +/// have some of their Y values added. If you're talking +/// about "Axis A has values from Axis B added to it", there are 6 +/// permutations for A and B (XY, XZ, YX, YZ, ZX, ZY). +/// +/// Not that Maya has only three values, which represent the +/// lower/upper (depending on column/row major) triangle of the +/// matrix. Houdini is the same as Maya (see +/// https://www.sidefx.com/docs/houdini/props/obj.html) in this +/// respect. +/// +/// There's another way to look at it. A general affine transformation +/// in 3D has 12 degrees of freedom - 12 "available" elements in the +/// 4x4 matrix since a single row/column must be (0,0,0,1). If you +/// add up the degrees of freedom from Maya: +/// +/// - 3 translation +/// - 3 rotation +/// - 3 scale +/// - 3 shear +/// +/// You obviously get the full 12. So technically, the Shear6 option +/// of having all 6 shear options is overkill; Imath/Shear6 has 15 +/// values for a 12-degree-of-freedom transformation. This means that +/// any nonzero values in those last 3 shear coefficients can be +/// represented in those standard 12 degrees of freedom. Here's a +/// python example of how to do that: +/// +/// +/// >>> import imath +/// >>> M = imath.M44f() +/// >>> s = imath.V3f() +/// >>> h = imath.V3f() +/// >>> r = imath.V3f() +/// >>> t = imath.V3f() +/// # Use Shear.YX (index 3), which is an "extra" shear value +/// >>> M.setShear((0,0,0,1,0,0)) +/// M44f((1, 1, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)) +/// >>> M.extractSHRT(s, h, r, t) +/// 1 +/// >>> s +/// V3f(1.41421354, 0.707106769, 1) +/// >>> h +/// V3f(1, 0, 0) +/// >>> r +/// V3f(0, -0, 0.785398185) +/// >>> t +/// V3f(0, 0, 0) +/// +/// That shows how to decompose a transform matrix with one of those +/// "extra" shear coefficients into those standard 12 degrees of +/// freedom. But it's not necessarily intuitive; in this case, a +/// single non-zero shear coefficient resulted in a transform that has +/// non-uniform scale, a single "standard" shear value, and some +/// rotation. +/// +/// So, it would seem that any transform with those extra shear +/// values set could be translated into Maya to produce the exact same +/// transformation matrix; but doing this is probably pretty +/// undesirable, since the result would have some surprising values on +/// the other transformation attributes, despite being technically +/// correct. +/// +/// This usage of "degrees of freedom" is a bit hand-wavey here; +/// having a total of 12 inputs into the construction of a standard +/// transformation matrix doesn't necessarily mean that the matrix has +/// 12 true degrees of freedom, but the standard +/// translation/rotation/scale/shear matrices have the right +/// construction to ensure that. +/// + template class Shear6 { public: - //------------------- - // Access to elements - //------------------- + + /// @{ + /// @name Direct access to members T xy, xz, yz, yx, zx, zy; + /// @} + + /// Element access IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T& operator[] (int i); + + /// Element access IMATH_HOSTDEVICE constexpr const T& operator[] (int i) const; - //------------- - // Constructors - //------------- + /// @{ + /// @name Constructors and Assignment + + /// Initialize to 0 + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6(); + + /// Initialize to the given XY, XZ, YZ values + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (T XY, T XZ, T YZ); + + /// Initialize to the given XY, XZ, YZ values held in (v.x, v.y, v.z) + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (const Vec3& v); - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6(); // (0 0 0 0 0 0) - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (T XY, T XZ, T YZ); // (XY XZ YZ 0 0 0) - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (const Vec3& v); // (v.x v.y v.z 0 0 0) + /// Initialize to the given XY, XZ, YZ values held in (v.x, v.y, v.z) template - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (const Vec3& v); // (v.x v.y v.z 0 0 0) - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (T XY, // (XY XZ YZ YX ZX ZY) + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (const Vec3& v); + + /// Initialize to the given (XY XZ YZ YX ZX ZY) values + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (T XY, T XZ, T YZ, T YX, T ZX, T ZY); - //--------------------------------- - // Copy constructors and assignment - //--------------------------------- - + /// Copy constructor IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (const Shear6& h); + + /// Construct from a Shear6 object of another base type template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Shear6 (const Shear6& h); + /// Assignment IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator= (const Shear6& h); + + /// Assignment from vector template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator= (const Vec3& v); - //------------ - // Destructor - //------------ - + /// Destructor ~Shear6() = default; - //---------------------- - // Compatibility with Sb - //---------------------- + /// @} + + /// @{ + /// @name Compatibility with Sb + /// Set the value template IMATH_HOSTDEVICE void setValue (S XY, S XZ, S YZ, S YX, S ZX, S ZY); + /// Set the value template IMATH_HOSTDEVICE void setValue (const Shear6& h); + /// Return the values template IMATH_HOSTDEVICE void getValue (S& XY, S& XZ, S& YZ, S& YX, S& ZX, S& ZY) const; + /// Return the value in `h` template IMATH_HOSTDEVICE void getValue (Shear6& h) const; + /// Return a raw pointer to the array of values IMATH_HOSTDEVICE T* getValue(); + + /// Return a raw pointer to the array of values IMATH_HOSTDEVICE const T* getValue() const; - //--------- - // Equality - //--------- + /// @} + /// @{ + /// @name Arithmetic and Comparison + + /// Equality template IMATH_HOSTDEVICE constexpr bool operator== (const Shear6& h) const; + /// Inequality template IMATH_HOSTDEVICE constexpr bool operator!= (const Shear6& h) const; - //----------------------------------------------------------------------- - // Compare two shears and test if they are "approximately equal": - // - // equalWithAbsError (h, e) - // - // Returns true if the coefficients of this and h are the same with - // an absolute error of no more than e, i.e., for all i - // - // abs (this[i] - h[i]) <= e - // - // equalWithRelError (h, e) - // - // Returns true if the coefficients of this and h are the same with - // a relative error of no more than e, i.e., for all i - // - // abs (this[i] - h[i]) <= e * abs (this[i]) - //----------------------------------------------------------------------- - + /// Compare two shears and test if they are "approximately equal": + /// @return True if the coefficients of this and h are the same with + /// an absolute error of no more than e, i.e., for all i + /// abs (this[i] - h[i]) <= e IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError (const Shear6& h, T e) const; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Shear6& h, T e) const; - //------------------------ - // Component-wise addition - //------------------------ + /// Compare two shears and test if they are "approximately equal": + /// @return True if the coefficients of this and h are the same with + /// a relative error of no more than e, i.e., for all i + /// abs (this[i] - h[i]) <= e * abs (this[i]) + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Shear6& h, T e) const; + /// Component-wise addition IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator+= (const Shear6& h); - IMATH_HOSTDEVICE constexpr Shear6 operator+ (const Shear6& h) const; - //--------------------------- - // Component-wise subtraction - //--------------------------- + /// Component-wise addition + IMATH_HOSTDEVICE constexpr Shear6 operator+ (const Shear6& h) const; + /// Component-wise subtraction IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator-= (const Shear6& h); - IMATH_HOSTDEVICE constexpr Shear6 operator- (const Shear6& h) const; - //------------------------------------ - // Component-wise multiplication by -1 - //------------------------------------ + /// Component-wise subtraction + IMATH_HOSTDEVICE constexpr Shear6 operator- (const Shear6& h) const; + /// Component-wise multiplication by -1 IMATH_HOSTDEVICE constexpr Shear6 operator-() const; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& negate(); - //------------------------------ - // Component-wise multiplication - //------------------------------ + /// Component-wise multiplication by -1 + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& negate(); + /// Component-wise multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator*= (const Shear6& h); + /// Scalar multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator*= (T a); + + /// Component-wise multiplication IMATH_HOSTDEVICE constexpr Shear6 operator* (const Shear6& h) const; - IMATH_HOSTDEVICE constexpr Shear6 operator* (T a) const; - //------------------------ - // Component-wise division - //------------------------ + /// Scalar multiplication + IMATH_HOSTDEVICE constexpr Shear6 operator* (T a) const; + /// Component-wise division IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator/= (const Shear6& h); - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator/= (T a); - IMATH_HOSTDEVICE constexpr Shear6 operator/ (const Shear6& h) const; - IMATH_HOSTDEVICE constexpr Shear6 operator/ (T a) const; - //---------------------------------------------------------- - // Number of dimensions, i.e. number of elements in a Shear6 - //---------------------------------------------------------- + /// Scalar division + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Shear6& operator/= (T a); - IMATH_HOSTDEVICE constexpr static unsigned int dimensions() { return 6; } + /// Component-wise division + IMATH_HOSTDEVICE constexpr Shear6 operator/ (const Shear6& h) const; - //------------------------------------------------- - // Limitations of type T (see also class limits) - //------------------------------------------------- + /// Scalar division + IMATH_HOSTDEVICE constexpr Shear6 operator/ (T a) const; + /// @} + + /// @{ + /// @name Numerical Limits + + /// Largest possible negative value IMATH_HOSTDEVICE constexpr static T baseTypeMin() { return limits::min(); } + + /// Largest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeMax() { return limits::max(); } + + /// Smallest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeSmallest() { return limits::smallest(); } + + /// Smallest possible e for which 1+e != 1 IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() { return limits::epsilon(); } - //-------------------------------------------------------------- - // Base type -- in templates, which accept a parameter, V, which - // could be either a Vec2 or a Shear6, you can refer to T as - // V::BaseType - //-------------------------------------------------------------- + /// @} + + /// Return the number of dimensions, i.e. 6 + IMATH_HOSTDEVICE constexpr static unsigned int dimensions() { return 6; } + /// The base type: In templates that accept a parameter `V` (could + /// be a Color4), you can refer to `T` as `V::BaseType` typedef T BaseType; }; -//-------------- -// Stream output -//-------------- - +/// Stream output template std::ostream& operator<< (std::ostream& s, const Shear6& h); -//---------------------------------------------------- -// Reverse multiplication: scalar * Shear6 -//---------------------------------------------------- - +/// Reverse multiplication: scalar * Shear6 template IMATH_HOSTDEVICE constexpr Shear6 operator* (S a, const Shear6& h); -//------------------------- -// Typedefs for convenience -//------------------------- - +/// 3D shear of type float typedef Vec3 Shear3f; + +/// 3D shear of type double typedef Vec3 Shear3d; + +/// Shear6 of type float typedef Shear6 Shear6f; + +/// Shear6 of type double typedef Shear6 Shear6d; //----------------------- diff --git a/src/Imath/ImathSphere.h b/src/Imath/ImathSphere.h index 171226bc..1d90c8dd 100644 --- a/src/Imath/ImathSphere.h +++ b/src/Imath/ImathSphere.h @@ -3,14 +3,12 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHSPHERE_H -#define INCLUDED_IMATHSPHERE_H - -//------------------------------------- // -// A 3D sphere class template +// A 3D sphere class template // -//------------------------------------- + +#ifndef INCLUDED_IMATHSPHERE_H +#define INCLUDED_IMATHSPHERE_H #include "ImathBox.h" #include "ImathLine.h" @@ -19,53 +17,74 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER +/// +/// A 3D sphere +/// + template class Sphere3 { public: + + /// @{ + /// @name Direct access to member fields + + /// Center Vec3 center; + + /// Radius T radius; - //--------------- - // Constructors - //--------------- + /// @} + /// @{ + /// @name Constructors + + /// Default is center at (0,0,0) and radius of 0. IMATH_HOSTDEVICE constexpr Sphere3() : center (0, 0, 0), radius (0) {} - IMATH_HOSTDEVICE constexpr Sphere3 (const Vec3& c, T r) : center (c), radius (r) {} - //------------------------------------------------------------------- - // Utilities: - // - // s.circumscribe(b) sets center and radius of sphere s - // so that the s tightly encloses box b. - // - // s.intersectT (l, t) If sphere s and line l intersect, then - // intersectT() computes the smallest t, - // t >= 0, so that l(t) is a point on the - // sphere. intersectT() then returns true. - // - // If s and l do not intersect, intersectT() - // returns false. - // - // s.intersect (l, i) If sphere s and line l intersect, then - // intersect() calls s.intersectT(l,t) and - // computes i = l(t). - // - // If s and l do not intersect, intersect() - // returns false. - // - //------------------------------------------------------------------- + /// Initialize to a given center and radius + IMATH_HOSTDEVICE constexpr Sphere3 (const Vec3& c, T r) : center (c), radius (r) {} + /// @} + + /// @{ + /// @name Manipulation + + /// Set the center and radius of the sphere so that it tightly + /// encloses Box b. IMATH_HOSTDEVICE void circumscribe (const Box>& box); + + /// @} + + /// @{ + /// @name Utility Methods + + /// If the sphere and line `l` intersect, then compute the + /// smallest `t` with `t>=0` so that `l(t)` is a point on the sphere. + /// + /// @param[in] l The line + /// @param[out] intersection The point of intersection + /// @return True if the sphere and line intersect, false if they + /// do not. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersect (const Line3& l, Vec3& intersection) const; + + /// If the sphere and line `l` intersect, then compute the + /// smallest `t` with `t>=0` so that `l(t)` is a point on the sphere. + /// + /// @param[in] l The line + /// @param[out] t The parameter of the line at the intersection point + /// @return True if the sphere and line intersect, false if they + /// do not. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersectT (const Line3& l, T& t) const; -}; -//-------------------- -// Convenient typedefs -//-------------------- + /// @} +}; +/// Sphere of type float typedef Sphere3 Sphere3f; + +/// Sphere of type double typedef Sphere3 Sphere3d; //--------------- diff --git a/src/Imath/ImathVec.h b/src/Imath/ImathVec.h index e9823717..6bbcac9f 100644 --- a/src/Imath/ImathVec.h +++ b/src/Imath/ImathVec.h @@ -3,14 +3,12 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHVEC_H -#define INCLUDED_IMATHVEC_H - -//---------------------------------------------------- // -// 2D, 3D and 4D point/vector class templates +// 2D, 3D and 4D point/vector class templates // -//---------------------------------------------------- + +#ifndef INCLUDED_IMATHVEC_H +#define INCLUDED_IMATHVEC_H #include "ImathLimits.h" #include "ImathMath.h" @@ -31,593 +29,705 @@ template class Vec2; template class Vec3; template class Vec4; +/// Enum for the Vec4 to Vec3 conversion constructor enum InfException { INF_EXCEPTION }; +/// +/// 2-element vector +/// + template class Vec2 { public: - //------------------- - // Access to elements - //------------------- + /// @{ + /// @name Direct access to elements + T x, y; + /// @} + + /// Element access by index. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T& operator[] (int i) noexcept; + + /// Element access by index. IMATH_HOSTDEVICE constexpr const T& operator[] (int i) const noexcept; - //------------- - // Constructors - //------------- + /// @{ + /// @name Constructors and Assignment + + /// Uninitialized by default + IMATH_HOSTDEVICE Vec2() noexcept; - IMATH_HOSTDEVICE Vec2() noexcept; // no initialization - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 explicit Vec2 (T a) noexcept; // (a a) - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec2 (T a, T b) noexcept; // (a b) + /// Initialize to a scalar `(a,a)` + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 explicit Vec2 (T a) noexcept; - //--------------------------------- - // Copy constructors and assignment - //--------------------------------- + /// Initialize to given elements `(a,b)` + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec2 (T a, T b) noexcept; + /// Copy constructor IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec2 (const Vec2& v) noexcept; + + /// Construct from Vec2 of another base type template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec2 (const Vec2& v) noexcept; + /// Assignment IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2& operator= (const Vec2& v) noexcept; - //------------ - // Destructor - //------------ - + /// Destructor ~Vec2() noexcept = default; - //---------------------- - // Compatibility with Sb - //---------------------- + /// @} + + /// @{ + /// @name Compatibility with Sb + /// Set the value template IMATH_HOSTDEVICE void setValue (S a, S b) noexcept; + /// Set the value template IMATH_HOSTDEVICE void setValue (const Vec2& v) noexcept; + /// Return the value in `a` and `b` template IMATH_HOSTDEVICE void getValue (S& a, S& b) const noexcept; + /// Return the value in `v` template IMATH_HOSTDEVICE void getValue (Vec2& v) const noexcept; + /// Return a raw pointer to the array of values IMATH_HOSTDEVICE T* getValue() noexcept; - IMATH_HOSTDEVICE const T* getValue() const noexcept; - //--------- - // Equality - //--------- + /// Return a raw pointer to the array of values + IMATH_HOSTDEVICE const T* getValue() const noexcept; + /// @} + + /// @{ + /// @name Arithmetic and Comparison + + /// Equality template IMATH_HOSTDEVICE constexpr bool operator== (const Vec2& v) const noexcept; - template IMATH_HOSTDEVICE constexpr bool operator!= (const Vec2& v) const noexcept; - //----------------------------------------------------------------------- - // Compare two vectors and test if they are "approximately equal": - // - // equalWithAbsError (v, e) - // - // Returns true if the coefficients of this and v are the same with - // an absolute error of no more than e, i.e., for all i - // - // abs (this[i] - v[i]) <= e - // - // equalWithRelError (v, e) - // - // Returns true if the coefficients of this and v are the same with - // a relative error of no more than e, i.e., for all i - // - // abs (this[i] - v[i]) <= e * abs (this[i]) - //----------------------------------------------------------------------- + /// Inequality + template IMATH_HOSTDEVICE constexpr bool operator!= (const Vec2& v) const noexcept; + /// Compare two matrices and test if they are "approximately equal": + /// @return True if the coefficients of this and `m` are the same + /// with an absolute error of no more than e, i.e., for all i, j: + /// + /// abs (this[i][j] - m[i][j]) <= e IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError (const Vec2& v, T e) const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Vec2& v, T e) const noexcept; - //------------ - // Dot product - //------------ + /// Compare two matrices and test if they are "approximately equal": + /// @return True if the coefficients of this and m are the same with + /// a relative error of no more than e, i.e., for all i, j: + /// + /// abs (this[i] - v[i][j]) <= e * abs (this[i][j]) + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Vec2& v, T e) const noexcept; + /// Dot product IMATH_HOSTDEVICE constexpr T dot (const Vec2& v) const noexcept; - IMATH_HOSTDEVICE constexpr T operator^ (const Vec2& v) const noexcept; - //------------------------------------------------ - // Right-handed cross product, i.e. z component of - // Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0) - //------------------------------------------------ + /// Dot product + IMATH_HOSTDEVICE constexpr T operator^ (const Vec2& v) const noexcept; + /// Right-handed cross product, i.e. z component of + /// Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0) IMATH_HOSTDEVICE constexpr T cross (const Vec2& v) const noexcept; - IMATH_HOSTDEVICE constexpr T operator% (const Vec2& v) const noexcept; - //------------------------ - // Component-wise addition - //------------------------ + /// Right-handed cross product, i.e. z component of + /// Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0) + IMATH_HOSTDEVICE constexpr T operator% (const Vec2& v) const noexcept; + /// Component-wise addition IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2& operator+= (const Vec2& v) noexcept; - IMATH_HOSTDEVICE constexpr Vec2 operator+ (const Vec2& v) const noexcept; - //--------------------------- - // Component-wise subtraction - //--------------------------- + /// Component-wise addition + IMATH_HOSTDEVICE constexpr Vec2 operator+ (const Vec2& v) const noexcept; + /// Component-wise subtraction IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2& operator-= (const Vec2& v) noexcept; - IMATH_HOSTDEVICE constexpr Vec2 operator- (const Vec2& v) const noexcept; - //------------------------------------ - // Component-wise multiplication by -1 - //------------------------------------ + /// Component-wise subtraction + IMATH_HOSTDEVICE constexpr Vec2 operator- (const Vec2& v) const noexcept; + /// Component-wise multiplication by -1 IMATH_HOSTDEVICE constexpr Vec2 operator-() const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2& negate() noexcept; - //------------------------------ - // Component-wise multiplication - //------------------------------ + /// Component-wise multiplication by -1 + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2& negate() noexcept; + /// Component-wise multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2& operator*= (const Vec2& v) noexcept; + + /// Component-wise multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2& operator*= (T a) noexcept; + + /// Component-wise multiplication IMATH_HOSTDEVICE constexpr Vec2 operator* (const Vec2& v) const noexcept; - IMATH_HOSTDEVICE constexpr Vec2 operator* (T a) const noexcept; - //------------------------ - // Component-wise division - //------------------------ + /// Component-wise multiplication + IMATH_HOSTDEVICE constexpr Vec2 operator* (T a) const noexcept; + /// Component-wise division IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2& operator/= (const Vec2& v) noexcept; + + /// Component-wise division IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2& operator/= (T a) noexcept; + + /// Component-wise division IMATH_HOSTDEVICE constexpr Vec2 operator/ (const Vec2& v) const noexcept; + + /// Component-wise division IMATH_HOSTDEVICE constexpr Vec2 operator/ (T a) const noexcept; - //---------------------------------------------------------------- - // Length and normalization: If v.length() is 0.0, v.normalize() - // and v.normalized() produce a null vector; v.normalizeExc() and - // v.normalizedExc() throw a std::domain_error. - // v.normalizeNonNull() and v.normalizedNonNull() are slightly - // faster than the other normalization routines, but if v.length() - // is 0.0, the result is undefined. - //---------------------------------------------------------------- + /// @} + /// @{ + /// @name Query and Manipulation + + /// Return the Euclidean norm IMATH_HOSTDEVICE T length() const noexcept; + + /// Return the square of the Euclidean norm, i.e. the dot product + /// with itself. IMATH_HOSTDEVICE constexpr T length2() const noexcept; - IMATH_HOSTDEVICE const Vec2& normalize() noexcept; // modifies *this + /// Normalize in place. If length()==0, return a null vector. + IMATH_HOSTDEVICE const Vec2& normalize() noexcept; + + /// Normalize in place. If length()==0, throw an exception. const Vec2& normalizeExc(); + + /// Normalize without any checks for length()==0. Slightly faster + /// than the other normalization routines, but if v.length() is + /// 0.0, the result is undefined. IMATH_HOSTDEVICE const Vec2& normalizeNonNull() noexcept; - IMATH_HOSTDEVICE Vec2 normalized() const noexcept; // does not modify *this - Vec2 normalizedExc() const; - IMATH_HOSTDEVICE Vec2 normalizedNonNull() const noexcept; + /// Return a normalized vector. Does not modify *this. + IMATH_HOSTDEVICE Vec2 normalized() const noexcept; - //-------------------------------------------------------- - // Number of dimensions, i.e. number of elements in a Vec2 - //-------------------------------------------------------- + /// Return a normalized vector. Does not modify *this. Throw an + /// exception if length()==0. + Vec2 normalizedExc() const; - IMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 2; } + /// Return a normalized vector. Does not modify *this, and does + /// not check for length()==0. Slightly faster than the other + /// normalization routines, but if v.length() is 0.0, the result + /// is undefined. + IMATH_HOSTDEVICE Vec2 normalizedNonNull() const noexcept; - //------------------------------------------------- - // Limitations of type T (see also class limits) - //------------------------------------------------- + /// @} + /// @{ + /// @name Numeric Limits + + /// Largest possible negative value IMATH_HOSTDEVICE constexpr static T baseTypeMin() noexcept { return limits::min(); } + + /// Largest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeMax() noexcept { return limits::max(); } + + /// Smallest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeSmallest() noexcept { return limits::smallest(); } + + /// Smallest possible e for which 1+e != 1 IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() noexcept { return limits::epsilon(); } - //-------------------------------------------------------------- - // Base type -- in templates, which accept a parameter, V, which - // could be either a Vec2, a Vec3, or a Vec4 you can - // refer to T as V::BaseType - //-------------------------------------------------------------- + /// @} + + /// Return the number of dimensions, i.e. 2 + IMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 2; } + /// The base type: In templates that accept a parameter `V`, you + /// can refer to `T` as `V::BaseType` typedef T BaseType; private: + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T lengthTiny() const noexcept; }; +/// +/// 3-element vector +/// + template class Vec3 { public: - //------------------- - // Access to elements - //------------------- + + /// @{ + /// @name Direct access to elements T x, y, z; + /// @} + + /// Element access by index. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T& operator[] (int i) noexcept; + + /// Element access by index. IMATH_HOSTDEVICE constexpr const T& operator[] (int i) const noexcept; - //------------- - // Constructors - //------------- + /// @{ + /// @name Constructors and Assignment - IMATH_HOSTDEVICE constexpr Vec3() noexcept; // no initialization - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 explicit Vec3 (T a) noexcept; // (a a a) - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec3 (T a, T b, T c) noexcept; // (a b c) + /// Uninitialized by default + IMATH_HOSTDEVICE constexpr Vec3() noexcept; + + /// Initialize to a scalar `(a,a,a)` + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 explicit Vec3 (T a) noexcept; - //--------------------------------- - // Copy constructors and assignment - //--------------------------------- + /// Initialize to given elements `(a,b,c)` + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec3 (T a, T b, T c) noexcept; + /// Copy constructor IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec3 (const Vec3& v) noexcept; - template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec3 (const Vec3& v) noexcept; - - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3& operator= (const Vec3& v) noexcept; - - //----------- - // Destructor - //----------- - - ~Vec3() noexcept = default; - //--------------------------------------------------------- - // Vec4 to Vec3 conversion, divides x, y and z by w: - // - // The one-argument conversion function divides by w even - // if w is zero. The result depends on how the environment - // handles floating-point exceptions. - // - // The two-argument version throws an InfPointExc exception - // if w is zero or if division by w would overflow. - //--------------------------------------------------------- + /// Construct from Vec3 of another base type + template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec3 (const Vec3& v) noexcept; + /// Vec4 to Vec3 conversion: divide x, y and z by w, even if w is + /// 0. The result depends on how the environment handles + /// floating-point exceptions. template IMATH_HOSTDEVICE explicit IMATH_CONSTEXPR14 Vec3 (const Vec4& v) noexcept; + + /// Vec4 to Vec3 conversion: divide x, y and z by w. Throws an + /// exception if w is zero or if division by w would overflow. template explicit IMATH_CONSTEXPR14 Vec3 (const Vec4& v, InfException); - //---------------------- - // Compatibility with Sb - //---------------------- + /// Assignment + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3& operator= (const Vec3& v) noexcept; + + /// Destructor + ~Vec3() noexcept = default; + + /// @} + + /// @{ + /// @name Compatibility with Sb + /// Set the value template IMATH_HOSTDEVICE void setValue (S a, S b, S c) noexcept; + /// Set the value template IMATH_HOSTDEVICE void setValue (const Vec3& v) noexcept; + /// Return the value in `a`, `b`, and `c` template IMATH_HOSTDEVICE void getValue (S& a, S& b, S& c) const noexcept; + /// Return the value in `v` template IMATH_HOSTDEVICE void getValue (Vec3& v) const noexcept; + /// Return a raw pointer to the array of values IMATH_HOSTDEVICE T* getValue() noexcept; + + /// Return a raw pointer to the array of values IMATH_HOSTDEVICE const T* getValue() const noexcept; - //--------- - // Equality - //--------- + /// @} + /// @{ + /// @name Arithmetic and Comparison + + /// Equality template IMATH_HOSTDEVICE constexpr bool operator== (const Vec3& v) const noexcept; + /// Inequality template IMATH_HOSTDEVICE constexpr bool operator!= (const Vec3& v) const noexcept; - //----------------------------------------------------------------------- - // Compare two vectors and test if they are "approximately equal": - // - // equalWithAbsError (v, e) - // - // Returns true if the coefficients of this and v are the same with - // an absolute error of no more than e, i.e., for all i - // - // abs (this[i] - v[i]) <= e - // - // equalWithRelError (v, e) - // - // Returns true if the coefficients of this and v are the same with - // a relative error of no more than e, i.e., for all i - // - // abs (this[i] - v[i]) <= e * abs (this[i]) - //----------------------------------------------------------------------- - + /// Compare two matrices and test if they are "approximately equal": + /// @return True if the coefficients of this and `m` are the same + /// with an absolute error of no more than e, i.e., for all i, j: + /// + /// abs (this[i][j] - m[i][j]) <= e IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError (const Vec3& v, T e) const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Vec3& v, T e) const noexcept; - //------------ - // Dot product - //------------ + /// Compare two matrices and test if they are "approximately equal": + /// @return True if the coefficients of this and m are the same with + /// a relative error of no more than e, i.e., for all i, j: + /// + /// abs (this[i] - v[i][j]) <= e * abs (this[i][j]) + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Vec3& v, T e) const noexcept; + /// Dot product IMATH_HOSTDEVICE constexpr T dot (const Vec3& v) const noexcept; - IMATH_HOSTDEVICE constexpr T operator^ (const Vec3& v) const noexcept; - //--------------------------- - // Right-handed cross product - //--------------------------- + /// Dot product + IMATH_HOSTDEVICE constexpr T operator^ (const Vec3& v) const noexcept; + /// Right-handed cross product IMATH_HOSTDEVICE constexpr Vec3 cross (const Vec3& v) const noexcept; + + /// Right-handed cross product IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3& operator%= (const Vec3& v) noexcept; - IMATH_HOSTDEVICE constexpr Vec3 operator% (const Vec3& v) const noexcept; - //------------------------ - // Component-wise addition - //------------------------ + /// Right-handed cross product + IMATH_HOSTDEVICE constexpr Vec3 operator% (const Vec3& v) const noexcept; + /// Component-wise addition IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3& operator+= (const Vec3& v) noexcept; - IMATH_HOSTDEVICE constexpr Vec3 operator+ (const Vec3& v) const noexcept; - //--------------------------- - // Component-wise subtraction - //--------------------------- + /// Component-wise addition + IMATH_HOSTDEVICE constexpr Vec3 operator+ (const Vec3& v) const noexcept; + /// Component-wise subtraction IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3& operator-= (const Vec3& v) noexcept; - IMATH_HOSTDEVICE constexpr Vec3 operator- (const Vec3& v) const noexcept; - //------------------------------------ - // Component-wise multiplication by -1 - //------------------------------------ + /// Component-wise subtraction + IMATH_HOSTDEVICE constexpr Vec3 operator- (const Vec3& v) const noexcept; + /// Component-wise multiplication by -1 IMATH_HOSTDEVICE constexpr Vec3 operator-() const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3& negate() noexcept; - //------------------------------ - // Component-wise multiplication - //------------------------------ + /// Component-wise multiplication by -1 + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3& negate() noexcept; + /// Component-wise multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3& operator*= (const Vec3& v) noexcept; + + /// Component-wise multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3& operator*= (T a) noexcept; + + /// Component-wise multiplication IMATH_HOSTDEVICE constexpr Vec3 operator* (const Vec3& v) const noexcept; - IMATH_HOSTDEVICE constexpr Vec3 operator* (T a) const noexcept; - //------------------------ - // Component-wise division - //------------------------ + /// Component-wise multiplication + IMATH_HOSTDEVICE constexpr Vec3 operator* (T a) const noexcept; + /// Component-wise division IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3& operator/= (const Vec3& v) noexcept; + + /// Component-wise division IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3& operator/= (T a) noexcept; + + /// Component-wise division IMATH_HOSTDEVICE constexpr Vec3 operator/ (const Vec3& v) const noexcept; + + /// Component-wise division IMATH_HOSTDEVICE constexpr Vec3 operator/ (T a) const noexcept; - //---------------------------------------------------------------- - // Length and normalization: If v.length() is 0.0, v.normalize() - // and v.normalized() produce a null vector; v.normalizeExc() and - // v.normalizedExc() throw a std::domain_error. - // v.normalizeNonNull() and v.normalizedNonNull() are slightly - // faster than the other normalization routines, but if v.length() + /// @} - // is 0.0, the result is undefined. - //---------------------------------------------------------------- + /// @{ + /// @name Query and Manipulation + /// Return the Euclidean norm IMATH_HOSTDEVICE T length() const noexcept; + + /// Return the square of the Euclidean norm, i.e. the dot product + /// with itself. IMATH_HOSTDEVICE constexpr T length2() const noexcept; - IMATH_HOSTDEVICE const Vec3& normalize() noexcept; // modifies *this + /// Normalize in place. If length()==0, return a null vector. + IMATH_HOSTDEVICE const Vec3& normalize() noexcept; + + /// Normalize in place. If length()==0, throw an exception. const Vec3& normalizeExc(); + + /// Normalize without any checks for length()==0. Slightly faster + /// than the other normalization routines, but if v.length() is + /// 0.0, the result is undefined. IMATH_HOSTDEVICE const Vec3& normalizeNonNull() noexcept; + /// Return a normalized vector. Does not modify *this. IMATH_HOSTDEVICE Vec3 normalized() const noexcept; // does not modify *this + + /// Return a normalized vector. Does not modify *this. Throw an + /// exception if length()==0. Vec3 normalizedExc() const; - IMATH_HOSTDEVICE Vec3 normalizedNonNull() const noexcept; - //-------------------------------------------------------- - // Number of dimensions, i.e. number of elements in a Vec3 - //-------------------------------------------------------- + /// Return a normalized vector. Does not modify *this, and does + /// not check for length()==0. Slightly faster than the other + /// normalization routines, but if v.length() is 0.0, the result + /// is undefined. + IMATH_HOSTDEVICE Vec3 normalizedNonNull() const noexcept; - IMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 3; } + /// @} - //------------------------------------------------- - // Limitations of type T (see also class limits) - //------------------------------------------------- + /// @{ + /// @name Numeric Limits + /// Largest possible negative value IMATH_HOSTDEVICE constexpr static T baseTypeMin() noexcept { return limits::min(); } + + /// Largest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeMax() noexcept { return limits::max(); } + + /// Smallest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeSmallest() noexcept { return limits::smallest(); } + + /// Smallest possible e for which 1+e != 1 IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() noexcept { return limits::epsilon(); } - //-------------------------------------------------------------- - // Base type -- in templates, which accept a parameter, V, which - // could be either a Vec2, a Vec3, or a Vec4 you can - // refer to T as V::BaseType - //-------------------------------------------------------------- + /// @} + + /// Return the number of dimensions, i.e. 3 + IMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 3; } + /// The base type: In templates that accept a parameter `V`, you + /// can refer to `T` as `V::BaseType` typedef T BaseType; private: IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T lengthTiny() const noexcept; }; +/// +/// 4-element vector +/// + template class Vec4 { public: - //------------------- - // Access to elements - //------------------- + + /// @{ + /// @name Direct access to elements T x, y, z, w; + /// @} + + /// Element access by index. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T& operator[] (int i) noexcept; + + /// Element access by index. IMATH_HOSTDEVICE constexpr const T& operator[] (int i) const noexcept; - //------------- - // Constructors - //------------- + /// @{ + /// @name Constructors and Assignment + /// Uninitialized by default IMATH_HOSTDEVICE constexpr Vec4() noexcept; // no initialization + + /// Initialize to a scalar `(a,a,a,a)` IMATH_HOSTDEVICE IMATH_CONSTEXPR14 explicit Vec4 (T a) noexcept; // (a a a a) - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec4 (T a, T b, T c, T d) noexcept; // (a b c d) - //--------------------------------- - // Copy constructors and assignment - //--------------------------------- + /// Initialize to given elements `(a,b,c,d)` + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec4 (T a, T b, T c, T d) noexcept; // (a b c d) + /// Copy constructor IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec4 (const Vec4& v) noexcept; + + /// Construct from Vec4 of another base type template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec4 (const Vec4& v) noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4& operator= (const Vec4& v) noexcept; + /// Vec3 to Vec4 conversion, sets w to 1. + template IMATH_HOSTDEVICE explicit IMATH_CONSTEXPR14 Vec4 (const Vec3& v) noexcept; - //----------- - // Destructor - //----------- + /// Assignment + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4& operator= (const Vec4& v) noexcept; + /// Destructor ~Vec4() noexcept = default; - //------------------------------------- - // Vec3 to Vec4 conversion, sets w to 1 - //------------------------------------- - - template IMATH_HOSTDEVICE explicit IMATH_CONSTEXPR14 Vec4 (const Vec3& v) noexcept; - - //--------- - // Equality - //--------- - + /// @} + + /// @{ + /// @name Arithmetic and Comparison + + /// Equality template IMATH_HOSTDEVICE constexpr bool operator== (const Vec4& v) const noexcept; + /// Inequality template IMATH_HOSTDEVICE constexpr bool operator!= (const Vec4& v) const noexcept; - //----------------------------------------------------------------------- - // Compare two vectors and test if they are "approximately equal": - // - // equalWithAbsError (v, e) - // - // Returns true if the coefficients of this and v are the same with - // an absolute error of no more than e, i.e., for all i - // - // abs (this[i] - v[i]) <= e - // - // equalWithRelError (v, e) - // - // Returns true if the coefficients of this and v are the same with - // a relative error of no more than e, i.e., for all i - // - // abs (this[i] - v[i]) <= e * abs (this[i]) - //----------------------------------------------------------------------- - + /// Compare two matrices and test if they are "approximately equal": + /// @return True if the coefficients of this and `m` are the same + /// with an absolute error of no more than e, i.e., for all i, j: + /// + /// abs (this[i][j] - m[i][j]) <= e IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError (const Vec4& v, T e) const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Vec4& v, T e) const noexcept; - //------------ - // Dot product - //------------ + /// Compare two matrices and test if they are "approximately equal": + /// @return True if the coefficients of this and m are the same with + /// a relative error of no more than e, i.e., for all i, j: + /// + /// abs (this[i] - v[i][j]) <= e * abs (this[i][j]) + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Vec4& v, T e) const noexcept; + /// Dot product IMATH_HOSTDEVICE constexpr T dot (const Vec4& v) const noexcept; - IMATH_HOSTDEVICE constexpr T operator^ (const Vec4& v) const noexcept; - - //----------------------------------- - // Cross product is not defined in 4D - //----------------------------------- - //------------------------ - // Component-wise addition - //------------------------ + /// Dot product + IMATH_HOSTDEVICE constexpr T operator^ (const Vec4& v) const noexcept; + /// Component-wise addition IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4& operator+= (const Vec4& v) noexcept; - IMATH_HOSTDEVICE constexpr Vec4 operator+ (const Vec4& v) const noexcept; - //--------------------------- - // Component-wise subtraction - //--------------------------- + /// Component-wise addition + IMATH_HOSTDEVICE constexpr Vec4 operator+ (const Vec4& v) const noexcept; + /// Component-wise subtraction IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4& operator-= (const Vec4& v) noexcept; - IMATH_HOSTDEVICE constexpr Vec4 operator- (const Vec4& v) const noexcept; - //------------------------------------ - // Component-wise multiplication by -1 - //------------------------------------ + /// Component-wise subtraction + IMATH_HOSTDEVICE constexpr Vec4 operator- (const Vec4& v) const noexcept; + /// Component-wise multiplication by -1 IMATH_HOSTDEVICE constexpr Vec4 operator-() const noexcept; - IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4& negate() noexcept; - //------------------------------ - // Component-wise multiplication - //------------------------------ + /// Component-wise multiplication by -1 + IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4& negate() noexcept; + /// Component-wise multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4& operator*= (const Vec4& v) noexcept; + + /// Component-wise multiplication IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4& operator*= (T a) noexcept; + + /// Component-wise multiplication IMATH_HOSTDEVICE constexpr Vec4 operator* (const Vec4& v) const noexcept; - IMATH_HOSTDEVICE constexpr Vec4 operator* (T a) const noexcept; - //------------------------ - // Component-wise division - //------------------------ + /// Component-wise multiplication + IMATH_HOSTDEVICE constexpr Vec4 operator* (T a) const noexcept; + /// Component-wise division IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4& operator/= (const Vec4& v) noexcept; + + /// Component-wise division IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4& operator/= (T a) noexcept; + + /// Component-wise division IMATH_HOSTDEVICE constexpr Vec4 operator/ (const Vec4& v) const noexcept; + + /// Component-wise division IMATH_HOSTDEVICE constexpr Vec4 operator/ (T a) const noexcept; - //---------------------------------------------------------------- - // Length and normalization: If v.length() is 0.0, v.normalize() - // and v.normalized() produce a null vector; v.normalizeExc() and - // v.normalizedExc() throw a std::domain_error. - // v.normalizeNonNull() and v.normalizedNonNull() are slightly - // faster than the other normalization routines, but if v.length() - // is 0.0, the result is undefined. - //---------------------------------------------------------------- + /// @} + /// @{ + /// @name Query and Manipulation + + /// Return the Euclidean norm IMATH_HOSTDEVICE T length() const noexcept; + + /// Return the square of the Euclidean norm, i.e. the dot product + /// with itself. IMATH_HOSTDEVICE constexpr T length2() const noexcept; + /// Normalize in place. If length()==0, return a null vector. IMATH_HOSTDEVICE const Vec4& normalize() noexcept; // modifies *this + + /// Normalize in place. If length()==0, throw an exception. const Vec4& normalizeExc(); + + /// Normalize without any checks for length()==0. Slightly faster + /// than the other normalization routines, but if v.length() is + /// 0.0, the result is undefined. IMATH_HOSTDEVICE const Vec4& normalizeNonNull() noexcept; + /// Return a normalized vector. Does not modify *this. IMATH_HOSTDEVICE Vec4 normalized() const noexcept; // does not modify *this - Vec4 normalizedExc() const; - IMATH_HOSTDEVICE Vec4 normalizedNonNull() const noexcept; - //-------------------------------------------------------- - // Number of dimensions, i.e. number of elements in a Vec4 - //-------------------------------------------------------- - - IMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 4; } + /// Return a normalized vector. Does not modify *this. Throw an + /// exception if length()==0. + Vec4 normalizedExc() const; - //------------------------------------------------- - // Limitations of type T (see also class limits) - //------------------------------------------------- + /// Return a normalized vector. Does not modify *this, and does + /// not check for length()==0. Slightly faster than the other + /// normalization routines, but if v.length() is 0.0, the result + /// is undefined. + IMATH_HOSTDEVICE Vec4 normalizedNonNull() const noexcept; + /// @} + + /// @{ + /// @name Numeric Limits + + /// Largest possible negative value IMATH_HOSTDEVICE constexpr static T baseTypeMin() noexcept { return limits::min(); } + + /// Largest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeMax() noexcept { return limits::max(); } + + /// Smallest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeSmallest() noexcept { return limits::smallest(); } + + /// Smallest possible e for which 1+e != 1 IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() noexcept { return limits::epsilon(); } - //-------------------------------------------------------------- - // Base type -- in templates, which accept a parameter, V, which - // could be either a Vec2, a Vec3, or a Vec4 you can - // refer to T as V::BaseType - //-------------------------------------------------------------- + /// @} + + /// Return the number of dimensions, i.e. 4 + IMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 4; } + /// The base type: In templates that accept a parameter `V`, you + /// can refer to `T` as `V::BaseType` typedef T BaseType; private: IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T lengthTiny() const noexcept; }; -//-------------- -// Stream output -//-------------- - +/// Stream output template std::ostream& operator<< (std::ostream& s, const Vec2& v); +/// Stream output template std::ostream& operator<< (std::ostream& s, const Vec3& v); +/// Stream output template std::ostream& operator<< (std::ostream& s, const Vec4& v); -//---------------------------------------------------- -// Reverse multiplication: S * Vec2 and S * Vec3 -//---------------------------------------------------- - +/// Reverse multiplication: S * Vec2 template IMATH_HOSTDEVICE constexpr Vec2 operator* (T a, const Vec2& v) noexcept; + +/// Reverse multiplication: S * Vec3 template IMATH_HOSTDEVICE constexpr Vec3 operator* (T a, const Vec3& v) noexcept; + +/// Reverse multiplication: S * Vec4 template IMATH_HOSTDEVICE constexpr Vec4 operator* (T a, const Vec4& v) noexcept; //------------------------- // Typedefs for convenience //------------------------- +/// Vec2 of short typedef Vec2 V2s; + +/// Vec2 of integer typedef Vec2 V2i; + +/// Vec2 of float typedef Vec2 V2f; + +/// Vec2 of double typedef Vec2 V2d; + +/// Vec3 of short typedef Vec3 V3s; + +/// Vec3 of integer typedef Vec3 V3i; + +/// Vec3 of float typedef Vec3 V3f; + +/// Vec3 of double typedef Vec3 V3d; + +/// Vec4 of short typedef Vec4 V4s; + +/// Vec4 of integer typedef Vec4 V4i; + +/// Vec4 of float typedef Vec4 V4f; + +/// Vec4 of double typedef Vec4 V4d; -//------------------------------------------- +//---------------------------------------------------------------------------- // Specializations for VecN, VecN +// // Normalize and length don't make sense for integer vectors, so disable them. -//------------------------------------------- +//---------------------------------------------------------------------------- // Vec2 template <> short Vec2::length() const noexcept = delete; diff --git a/src/Imath/ImathVecAlgo.h b/src/Imath/ImathVecAlgo.h index 0866592f..5f3bc056 100644 --- a/src/Imath/ImathVecAlgo.h +++ b/src/Imath/ImathVecAlgo.h @@ -3,18 +3,17 @@ // Copyright Contributors to the OpenEXR Project. // -#ifndef INCLUDED_IMATHVECALGO_H -#define INCLUDED_IMATHVECALGO_H - -//------------------------------------------------------------------------- // -// This file contains algorithms applied to or in conjunction -// with points (Imath::Vec2 and Imath::Vec3). -// The assumption made is that these functions are called much -// less often than the basic point functions or these functions -// require more support classes. +// Algorithms applied to or in conjunction with points (Imath::Vec2 +// and Imath::Vec3). // -//------------------------------------------------------------------------- +// The assumption made is that these functions are called much +// less often than the basic point functions or these functions +// require more support classes. +// + +#ifndef INCLUDED_IMATHVECALGO_H +#define INCLUDED_IMATHVECALGO_H #include "ImathLimits.h" #include "ImathNamespace.h" @@ -22,10 +21,9 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER -//----------------------------------------------------------------- -// Find the projection of vector t onto vector s (Vec2, Vec3, Vec4) -//----------------------------------------------------------------- - +/// Find the projection of vector `t` onto vector `s` (`Vec2`, `Vec3`, `Vec4`) +/// +/// Only defined for floating-point types, e.g. `V2f`, `V3d`, etc. template ::value)> IMATH_CONSTEXPR14 inline Vec @@ -35,11 +33,10 @@ project (const Vec& s, const Vec& t) noexcept return sNormalized * (sNormalized ^ t); } -//------------------------------------------------ -// Find a vector that is perpendicular to s and -// in the same plane as s and t (Vec2, Vec3, Vec4) -//------------------------------------------------ - +/// Find a vector that is perpendicular to `s` and +/// in the same plane as `s` and `t` (`Vec2`, `Vec3`, `Vec4`) +/// +/// Only defined for floating-point types, e.g. `V2f`, `V3d`, etc. template ::value)> constexpr inline Vec @@ -48,11 +45,10 @@ orthogonal (const Vec& s, const Vec& t) noexcept return t - project (s, t); } -//----------------------------------------------- -// Find the direction of a ray s after reflection -// off a plane with normal t (Vec2, Vec3, Vec4) -//----------------------------------------------- - +/// Find the direction of a ray `s` after reflection +/// off a plane with normal `t` (`Vec2`, `Vec3`, `Vec4`) +/// +/// Only defined for floating-point types, e.g. `V2f`, `V3d`, etc. template ::value)> constexpr inline Vec @@ -61,12 +57,8 @@ reflect (const Vec& s, const Vec& t) noexcept return s - typename Vec::BaseType (2) * (s - project (t, s)); } - -//-------------------------------------------------------------------- -// Find the vertex of triangle (v0, v1, v2) that is closest to point p -// (Vec2, Vec3, Vec4) -//-------------------------------------------------------------------- - +/// Find the vertex of triangle `(v0, v1, v2)` that is closest to point `p` +/// (`Vec2`, `Vec3`, `Vec4`) template IMATH_CONSTEXPR14 Vec closestVertex (const Vec& v0, const Vec& v1, const Vec& v2, const Vec& p) noexcept; diff --git a/src/Imath/half.h b/src/Imath/half.h index b87e5f60..b9bcdd58 100644 --- a/src/Imath/half.h +++ b/src/Imath/half.h @@ -58,6 +58,8 @@ #ifndef _HALF_H_ #define _HALF_H_ +/// @cond Doxygen_Suppress + #include "ImathNamespace.h" #include "ImathExport.h" #include @@ -686,4 +688,8 @@ using half = IMATH_INTERNAL_NAMESPACE::half; # include #endif +/// @endcond + #endif + + diff --git a/src/Imath/halfFunction.h b/src/Imath/halfFunction.h index de0ff5f8..91cc7fd0 100644 --- a/src/Imath/halfFunction.h +++ b/src/Imath/halfFunction.h @@ -49,6 +49,8 @@ #ifndef _HALF_FUNCTION_H_ #define _HALF_FUNCTION_H_ +/// @cond Doxygen_Suppress + #include "half.h" #include "ImathConfig.h" @@ -138,4 +140,8 @@ halfFunction::operator() (half x) const return _lut[x.bits()]; } + +/// @endcond + + #endif diff --git a/src/Imath/halfLimits.h b/src/Imath/halfLimits.h index eb1bb3f7..9090bad5 100644 --- a/src/Imath/halfLimits.h +++ b/src/Imath/halfLimits.h @@ -21,6 +21,8 @@ #include "half.h" #include +/// @cond Doxygen_Suppress + namespace std { @@ -71,6 +73,8 @@ template <> class numeric_limits // constexpr (and my not be able to be in C++11). }; +/// @endcond + } // namespace std #endif