|
|
|
|
/*
|
|
|
|
|
This file is part of Magnum.
|
|
|
|
|
|
|
|
|
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
|
|
|
|
|
2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz>
|
|
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
copy of this software and associated documentation files (the "Software"),
|
|
|
|
|
to deal in the Software without restriction, including without limitation
|
|
|
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
|
and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
|
Software is furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included
|
|
|
|
|
in all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
|
DEALINGS IN THE SOFTWARE.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
namespace Magnum {
|
|
|
|
|
/** @page types Math type system
|
|
|
|
|
@brief Type aliases, naming and compatibility with OpenGL, Vulkan and GLSL types.
|
|
|
|
|
|
|
|
|
|
@tableofcontents
|
|
|
|
|
@m_footernavigation
|
|
|
|
|
@m_keyword{Type system,,}
|
|
|
|
|
|
|
|
|
|
Magnum defines a variety of scalar, vector and matrix types. Most of the
|
|
|
|
|
functionality is implemented using template classes in the @ref Math library,
|
|
|
|
|
with the most common variants brought as typedefs into the root @ref Magnum
|
|
|
|
|
namespace.
|
|
|
|
|
|
|
|
|
|
@section types-builtin Builtin types
|
|
|
|
|
|
|
|
|
|
Magnum provides its own typedefs for builtin integral and floating-point
|
|
|
|
|
arithmetic types to ensure portability, maintain consistency and reduce
|
|
|
|
|
confusion. E.g., the @ref Int typedef is guaranteed to *always* be 32-bit and
|
|
|
|
|
Magnum's own code and documentation prefers to use it over a wild mixture of
|
|
|
|
|
@ref std::int32_t, @cpp int @ce, @cpp GLint @ce or @cpp ALint @ce that all
|
|
|
|
|
refer to the same type.
|
|
|
|
|
|
|
|
|
|
| Magnum type | Size | Equivalent GLSL type |
|
|
|
|
|
| ------------------ | -------------- | ----------------------- |
|
|
|
|
|
| @ref UnsignedByte | 8bit unsigned | (*none*) |
|
|
|
|
|
| @ref Byte | 8bit signed | (*none*) |
|
|
|
|
|
| @ref UnsignedShort | 16bit unsigned | (*none*) |
|
|
|
|
|
| @ref Short | 16bit signed | (*none*) |
|
|
|
|
|
| @ref UnsignedInt | 32bit unsigned | @glsl uint @ce <b></b> |
|
|
|
|
|
| @ref Int | 32bit signed | @glsl int @ce <b></b> |
|
|
|
|
|
| @ref UnsignedLong | 64bit unsigned | (*none*) |
|
|
|
|
|
| @ref Long | 64bit signed | (*none*) |
|
|
|
|
|
| @ref Half | 16bit | (*none*) |
|
|
|
|
|
| @ref Float | 32bit | @glsl float @ce <b></b> |
|
|
|
|
|
| @ref Double | 64bit | @glsl double @ce <b></b> |
|
|
|
|
|
|
|
|
|
|
Types not meant to be used in arithmetic (such as @cpp bool @ce or
|
|
|
|
|
@cpp std::size_t @ce) or types which have no use in GPU computations (such as
|
|
|
|
|
@cpp long double @ce) have no typedefs.
|
|
|
|
|
|
|
|
|
|
Types from the above table are then used to define other types. All following
|
|
|
|
|
types are aliases of corresponding types in @ref Math namespace. No suffix
|
|
|
|
|
after type name means @ref Float underlying type, `h` means @ref Half, `d` is
|
|
|
|
|
@ref Double, `ub` @ref UnsignedByte, `b` @ref Byte, `us` @ref UnsignedShort,
|
|
|
|
|
`s` @ref Short, `ui` @ref UnsignedInt and `i` is @ref Int.
|
|
|
|
|
|
|
|
|
|
@section types-matrix Matrix/vector types
|
|
|
|
|
|
|
|
|
|
| Magnum vector type | Equivalent GLSL type |
|
|
|
|
|
| ---------------------------------------------- | ------------------------- |
|
|
|
|
|
| @ref BitVector2, @ref BitVector3, @ref BitVector4 | @glsl bvec2 @ce, @glsl bvec3 @ce, @glsl bvec4 @ce |
|
|
|
|
|
| @ref Vector2, @ref Vector3, @ref Color3, @ref Vector4, @ref Color4 | @glsl vec2 @ce, @glsl vec3 @ce, @glsl vec4 @ce |
|
|
|
|
|
| @ref Vector2h, @ref Vector3h, @ref Color3h, @ref Vector4h, @ref Color4h | (*none*) |
|
|
|
|
|
| @ref Vector2d, @ref Vector3d, @ref Vector4d | @glsl dvec2 @ce, @glsl dvec3 @ce, @glsl dvec4 @ce |
|
|
|
|
|
| @ref Vector2ub, @ref Vector3ub, @ref Vector4ub, @ref Color3ub, @ref Color4ub | (*none*) |
|
|
|
|
|
| @ref Vector2b, @ref Vector3b, @ref Vector4b | (*none*) |
|
|
|
|
|
| @ref Vector2us, @ref Vector3us, @ref Vector4us, @ref Color3us, @ref Color4us | (*none*) |
|
|
|
|
|
| @ref Vector2s, @ref Vector3s, @ref Vector4s | (*none*) |
|
|
|
|
|
| @ref Vector2ui, @ref Vector3ui, @ref Vector4ui | @glsl uvec2 @ce, @glsl uvec3 @ce, @glsl uvec4 @ce |
|
|
|
|
|
| @ref Vector2i, @ref Vector3i, @ref Vector4i | @glsl ivec2 @ce, @glsl ivec3 @ce, @glsl ivec4 @ce |
|
|
|
|
|
|
|
|
|
|
| Magnum matrix type | Equivalent GLSL type |
|
|
|
|
|
| ---------------------------------------------------------------- | ------------------------------------- |
|
|
|
|
|
| @ref Matrix2x2 or @ref Matrix2x2d | @glsl mat2 @ce / @glsl mat2x2 @ce or @glsl dmat2 @ce / @glsl dmat2x2 @ce |
|
|
|
|
|
| @ref Matrix2x2h, @ref Matrix2x2b, @ref Matrix2x2s | (*none*) |
|
|
|
|
|
| @ref Matrix3 / @ref Matrix3x3 or @ref Matrix3d / @ref Matrix3x3d | @glsl mat3 @ce / @glsl mat3x3 @ce or @glsl dmat3 @ce / @glsl dmat3x3 @ce |
|
|
|
|
|
| @ref Matrix3x3h, @ref Matrix3x3b, @ref Matrix3x3s | (*none*) |
|
|
|
|
|
| @ref Matrix4 / @ref Matrix4x4 or @ref Matrix4d / @ref Matrix4x4d | @glsl mat4 @ce / @glsl mat4x4 @ce or @glsl dmat4 @ce / @glsl dmat4x4 @ce |
|
|
|
|
|
| @ref Matrix4x4h, @ref Matrix4x4b, @ref Matrix4x4s | (*none*) |
|
|
|
|
|
| @ref Matrix2x3 or @ref Matrix2x3d | @glsl mat2x3 @ce or @glsl dmat2x3 @ce |
|
|
|
|
|
| @ref Matrix2x3h, @ref Matrix2x3b, @ref Matrix2x3s | (*none*) |
|
|
|
|
|
| @ref Matrix3x2 or @ref Matrix3x2d | @glsl mat3x2 @ce or @glsl dmat3x2 @ce |
|
|
|
|
|
| @ref Matrix3x2h, @ref Matrix3x2b, @ref Matrix3x2s | (*none*) |
|
|
|
|
|
| @ref Matrix2x4 or @ref Matrix2x4d | @glsl mat2x4 @ce or @glsl dmat2x4 @ce |
|
|
|
|
|
| @ref Matrix2x4h, @ref Matrix2x4b, @ref Matrix2x4s | (*none*) |
|
|
|
|
|
| @ref Matrix4x2 or @ref Matrix4x2d | @glsl mat4x2 @ce or @glsl dmat4x2 @ce |
|
|
|
|
|
| @ref Matrix4x2h, @ref Matrix4x2b, @ref Matrix4x2s | (*none*) |
|
|
|
|
|
| @ref Matrix3x4 or @ref Matrix3x4d | @glsl mat3x4 @ce or @glsl dmat3x4 @ce |
|
|
|
|
|
| @ref Matrix3x4h, @ref Matrix3x4b, @ref Matrix3x4s | (*none*) |
|
|
|
|
|
| @ref Matrix4x3 or @ref Matrix4x3d | @glsl mat4x3 @ce or @glsl dmat4x3 @ce |
|
|
|
|
|
| @ref Matrix4x3h, @ref Matrix4x3b, @ref Matrix4x3s | (*none*) |
|
|
|
|
|
|
|
|
|
|
Any super- or sub-class of the same size and underlying type can be used
|
|
|
|
|
equivalently (e.g. @ref Math::Vector "Math::Vector<Float>" or @ref Color3
|
|
|
|
|
instead of @ref Vector3).
|
|
|
|
|
|
|
|
|
|
For easier entering of (s)RGB colors in hexadecimal format there are
|
|
|
|
|
@link Math::Literals::operator""_srgb() _srgb @endlink /
|
|
|
|
|
@link Math::Literals::operator""_srgbf() _srgbf @endlink,
|
|
|
|
|
@link Math::Literals::operator""_srgba() _srgba @endlink /
|
|
|
|
|
@link Math::Literals::operator""_srgbaf() _srgbaf @endlink,
|
|
|
|
|
@link Math::Literals::operator""_rgb() _rgb @endlink /
|
|
|
|
|
@link Math::Literals::operator""_rgbf() _rgbf @endlink and
|
|
|
|
|
@link Math::Literals::operator""_rgba() _rgba @endlink /
|
|
|
|
|
@link Math::Literals::operator""_rgbaf() _rgbaf @endlink literals in
|
|
|
|
|
@ref Math::Literals namespace. See their documentation for more information
|
|
|
|
|
about the differences.
|
|
|
|
|
|
|
|
|
|
@snippet MagnumMath.cpp types-literals-colors
|
|
|
|
|
|
|
|
|
|
@section types-binary Binary representation
|
|
|
|
|
|
|
|
|
|
Scalar types with a GLSL equivalent are guaranteed to have exactly the same
|
|
|
|
|
binary representation. Consequently, matrix and vector classes also have the
|
|
|
|
|
same binary representation as corresponding array of numeric values without any
|
|
|
|
|
additional data or padding (e.g. @cpp sizeof(Vector3i) == sizeof(Int[3]) @ce).
|
|
|
|
|
All matrices are stored in column-major order.
|
|
|
|
|
|
|
|
|
|
This means that all scalar, matrix and vector types can be used directly for
|
|
|
|
|
filling GPU buffers and textures without any need for data extraction or
|
|
|
|
|
conversion. For convenience all vector and matrix classes provide a
|
|
|
|
|
@ref Math::RectangularMatrix::data() "data()" function, which returns a pointer
|
|
|
|
|
to the internal data array.
|
|
|
|
|
|
|
|
|
|
@section types-half Half-precision arithmetic
|
|
|
|
|
|
|
|
|
|
The @ref Half type represents half-precision floating point values. The sole
|
|
|
|
|
purpose of the type is to make creation, conversion and visualization of
|
|
|
|
|
half-float values easier. By design it doesn't support any arithmetic
|
|
|
|
|
operations as not all CPU architecture have native support for half-floats and
|
|
|
|
|
thus the operations would be done faster in a regular single-precision
|
|
|
|
|
@ref Float. The class provides explicit constructors and conversion operators
|
|
|
|
|
from/to @ref Float and @ref UnsignedShort and you can also use the
|
|
|
|
|
@link Math::Literals::operator""_h() _h @endlink literal that is provided in
|
|
|
|
|
the @ref Math::Literals namespace:
|
|
|
|
|
|
|
|
|
|
@snippet MagnumMath.cpp types-literals-half
|
|
|
|
|
|
|
|
|
|
Half-precision vector and matrix types such as @ref Vector3h or @ref Matrix3x3h
|
|
|
|
|
work similarly --- you can construct them and convert them from/to other types,
|
|
|
|
|
but can't perform any arithmetic.
|
|
|
|
|
|
|
|
|
|
@section types-special Special types
|
|
|
|
|
|
|
|
|
|
Magnum has a special type for strongly-typed representation of angles, namely
|
|
|
|
|
the @ref Deg and @ref Rad classes (or @ref Degd / @ref Degh and @ref Radd /
|
|
|
|
|
@ref Radh with @ref Double / @ref Half as underlying type). Their purpose is to
|
|
|
|
|
avoid common degree-vs-radian bugs (i.e. entering a degree value where radians
|
|
|
|
|
should be and vice versa) and make the conversion between these two
|
|
|
|
|
representations easier. They are just a tiny @cpp constexpr @ce wrapper around
|
|
|
|
|
the native type and they support all meaningful numeric operations. The wrapper
|
|
|
|
|
API may have a slight overhead on debug builds, but the safety benefits
|
|
|
|
|
outweight that in most practical use cases.
|
|
|
|
|
|
|
|
|
|
These classes are *not* implicitly constructible or convertible from/to
|
|
|
|
|
@ref Float or @ref Double, you have to either construct/convert them explicitly
|
|
|
|
|
or use custom @link Math::Literals::operator""_degf() _degf @endlink /
|
|
|
|
|
@link Math::Literals::operator""_deg() _deg @endlink and @link Math::Literals::operator""_radf() _radf @endlink
|
|
|
|
|
/ @link Math::Literals::operator""_rad() _rad @endlink literals that are
|
|
|
|
|
provided in the @ref Math::Literals namespace:
|
|
|
|
|
|
|
|
|
|
@snippet MagnumMath.cpp types-literals-angles
|
|
|
|
|
|
|
|
|
|
They can be implicitly converted to each other, but conversion to different
|
|
|
|
|
underlying type is *explicit* to avoid precision loss (or, on the other hand,
|
|
|
|
|
unnecessarily high precision) during computations:
|
|
|
|
|
|
|
|
|
|
@snippet MagnumMath.cpp types-literals-angle-conversion
|
|
|
|
|
|
|
|
|
|
These classes are used exclusively in all functions taking and returning angles
|
|
|
|
|
--- trigonometry, angle computation, rotating transformation etc. Thanks to
|
|
|
|
|
implicit conversion you can seamlessly use either radians or degrees without
|
|
|
|
|
any need to care about what input the function expects:
|
|
|
|
|
|
|
|
|
|
@snippet MagnumMath.cpp types-literals-usage
|
|
|
|
|
|
|
|
|
|
@section types-other Other types
|
|
|
|
|
|
|
|
|
|
Other types, which don't have their GLSL equivalent, are:
|
|
|
|
|
|
|
|
|
|
- @ref QuadraticBezier2D or @ref QuadraticBezier2Dd, @ref QuadraticBezier3D
|
|
|
|
|
or @ref QuadraticBezier3Dd
|
|
|
|
|
- @ref CubicBezier2D or @ref CubicBezier2Dd, @ref CubicBezier3D
|
|
|
|
|
or @ref CubicBezier3Dd
|
|
|
|
|
- @ref CubicHermite1D or @ref CubicHermite1Dd, @ref CubicHermite2D or
|
|
|
|
|
@ref CubicHermite2Dd, @ref CubicHermite3D or @ref CubicHermite3Dd
|
|
|
|
|
- @ref Complex or @ref Complexd, @ref DualComplex or @ref DualComplexd
|
|
|
|
|
- @ref Frustum or @ref Frustumd
|
|
|
|
|
- @ref Quaternion or @ref Quaterniond, @ref DualQuaternion or
|
|
|
|
|
@ref DualQuaterniond
|
|
|
|
|
- @ref CubicHermiteComplex or @ref CubicHermiteComplexd
|
|
|
|
|
- @ref CubicHermiteQuaternion or @ref CubicHermiteQuaterniond
|
|
|
|
|
- @ref Range1D / @ref Range2D / @ref Range3D, @ref Range1Di / @ref Range2Di /
|
|
|
|
|
@ref Range3Di or @ref Range1Dd / @ref Range2Dd / @ref Range3Dd
|
|
|
|
|
|
|
|
|
|
These types can be used in GLSL either by extracting values from their
|
|
|
|
|
underlying structure or converting them to types supported by GLSL (e.g.
|
|
|
|
|
quaternion to matrix).
|
|
|
|
|
|
|
|
|
|
For your convenience, there is also a structure with often used constants
|
|
|
|
|
--- @ref Constants, or @ref Constantsd for the double-precision variants.
|
|
|
|
|
|
|
|
|
|
@section types-initialization Initialization
|
|
|
|
|
|
|
|
|
|
Vectors, general matrices and range types are by default zero-initialized,
|
|
|
|
|
transformation types (square matrices, (dual) complex numbers and quaternions)
|
|
|
|
|
are set to identity transformation. It is possible to initialize the instances
|
|
|
|
|
differently using so-called *tags* or use the tag to make the choice appear
|
|
|
|
|
explicit:
|
|
|
|
|
|
|
|
|
|
- @ref Math::ZeroInit zero-initializes the contents (works for all types).
|
|
|
|
|
- @ref Math::IdentityInit initializes the contents to identity transformation
|
|
|
|
|
(works only for transformation types, where it is also the default).
|
|
|
|
|
- @ref NoInit leaves the contents uninitialized (useful if you will overwrite
|
|
|
|
|
the contents anyway, works for all types).
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
@snippet MagnumMath.cpp types-literals-init
|
|
|
|
|
|
|
|
|
|
@section types-thirdparty-integration Integration with types from 3rd party APIs
|
|
|
|
|
|
|
|
|
|
To simplify the workflow when interacting with 3rd party APIs, all Magnum math
|
|
|
|
|
types can be made explicitly convertible to and from types coming from external
|
|
|
|
|
libraries. Currently, various Magnum libraries provide these conversion, see
|
|
|
|
|
documentation of each `Integration.h` header for details:
|
|
|
|
|
|
|
|
|
|
- Math-related Vulkan structures --- @ref Magnum/Vk/Integration.h, part of
|
|
|
|
|
the @ref Vk library
|
|
|
|
|
- All Eigen types --- @ref Magnum/EigenIntegration/Integration.h and
|
|
|
|
|
@ref Magnum/EigenIntegration/GeometryIntegration.h, part of the
|
|
|
|
|
@ref EigenIntegration library
|
|
|
|
|
- All GLM types --- @ref Magnum/GlmIntegration/Integration.h,
|
|
|
|
|
@ref Magnum/GlmIntegration/GtcIntegration.h and
|
|
|
|
|
@ref Magnum/GlmIntegration/GtxIntegration.h, part of the
|
|
|
|
|
@ref GlmIntegration library
|
|
|
|
|
- Bullet Physics math types --- @ref Magnum/BulletIntegration/Integration.h,
|
|
|
|
|
part of the @ref BulletIntegration library
|
|
|
|
|
- Oculus VR SDK math types -- @ref Magnum/OvrIntegration/Integration.h, part
|
|
|
|
|
of the @ref OvrIntegration library
|
|
|
|
|
- Dear ImGui math types --- @ref Magnum/ImGuiIntegration/Integration.h, part
|
|
|
|
|
of the @ref ImGuiIntegration library
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
}
|