mirror of https://github.com/mosra/magnum.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
14 KiB
260 lines
14 KiB
/* |
|
This file is part of Magnum. |
|
|
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
|
2020, 2021 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 BoolVector2, @ref BoolVector3, @ref BoolVector4 | @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 |
|
|
|
*/ |
|
}
|
|
|