|
|
|
@ -22,7 +22,7 @@ |
|
|
|
DEALINGS IN THE SOFTWARE. |
|
|
|
DEALINGS IN THE SOFTWARE. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
namespace Magnum { namespace Math { |
|
|
|
namespace Magnum { |
|
|
|
/** @page matrix-vector Operations with matrices and vectors |
|
|
|
/** @page matrix-vector Operations with matrices and vectors |
|
|
|
|
|
|
|
|
|
|
|
@brief Introduction to essential classes of the graphics pipeline. |
|
|
|
@brief Introduction to essential classes of the graphics pipeline. |
|
|
|
@ -36,68 +36,79 @@ easier. |
|
|
|
|
|
|
|
|
|
|
|
@section matrix-vector-hierarchy Matrix and vector classes |
|
|
|
@section matrix-vector-hierarchy Matrix and vector classes |
|
|
|
|
|
|
|
|
|
|
|
%Magnum has three main matrix and vector classes: RectangularMatrix, (square) |
|
|
|
%Magnum has three main matrix and vector classes: @ref Math::RectangularMatrix, |
|
|
|
Matrix and Vector. To achieve greatest code reuse, %Matrix is internally |
|
|
|
(square) @ref Math::Matrix and @ref Math::Vector. To achieve greatest code |
|
|
|
square %RectangularMatrix and %RectangularMatrix is internally array of one or |
|
|
|
reuse, %Matrix is internally square %RectangularMatrix and %RectangularMatrix |
|
|
|
more %Vector instances. Both vectors and matrices can have arbitrary size |
|
|
|
is internally array of one or more %Vector instances. Both vectors and matrices |
|
|
|
(known at compile time) and can store any arithmetic type. |
|
|
|
can have arbitrary size (known at compile time) and can store any arithmetic |
|
|
|
|
|
|
|
type. |
|
|
|
|
|
|
|
|
|
|
|
Each subclass brings some specialization to its superclass and for most common |
|
|
|
Each subclass brings some specialization to its superclass and for most common |
|
|
|
vector and matrix sizes there are specialized classes Matrix3 and Matrix4, |
|
|
|
vector and matrix sizes there are specialized classes @ref Math::Matrix3 and |
|
|
|
implementing various transformation in 2D and 3D, Vector2, Vector3 and Vector4, |
|
|
|
@ref Math::Matrix4, implementing various transformations in 2D and 3D, |
|
|
|
implementing direct access to named components. Functions of each class try to |
|
|
|
@ref Math::Vector2, @ref Math::Vector3 and @ref Math::Vector4, implementing |
|
|
|
return the most specialized type known to make subsequent operations more |
|
|
|
direct access to named components. Functions of each class try to return the |
|
|
|
convenient - columns of %RectangularMatrix are returned as %Vector, but when |
|
|
|
most specialized type known to make subsequent operations more convenient -- |
|
|
|
accessing columns of e.g. %Matrix3, they are returned as %Vector3. |
|
|
|
columns of %RectangularMatrix are returned as %Vector, but when accessing |
|
|
|
|
|
|
|
columns of e.g. %Matrix3, they are returned as %Vector3. |
|
|
|
|
|
|
|
|
|
|
|
There are also even more specialized subclasses, e.g. Color3 and Color4 for |
|
|
|
There are also even more specialized subclasses, e.g. @ref Color3 and |
|
|
|
color handling and conversion. |
|
|
|
@ref Color4 for color handling and conversion. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Commonly used types have convenience aliases in @ref Magnum namespace, so you |
|
|
|
|
|
|
|
can write e.g. `%Vector3i` instead of `%Math::Vector3<Int>`. See @ref types and |
|
|
|
|
|
|
|
namespace documentation for more information. |
|
|
|
|
|
|
|
|
|
|
|
@section matrix-vector-construction Constructing matrices and vectors |
|
|
|
@section matrix-vector-construction Constructing matrices and vectors |
|
|
|
|
|
|
|
|
|
|
|
Default constructors of RectangularMatrix and Vector (and Vector2, Vector3, |
|
|
|
Default constructors of @ref Math::RectangularMatrix and @ref Math::Vector (and |
|
|
|
Vector4, Color3) create zero-filled objects. Matrix (and Matrix3, Matrix4) is |
|
|
|
@ref Math::Vector2, @ref Math::Vector3, @ref Math::Vector4, @ref Color3) create |
|
|
|
by default constructed as identity matrix. Color4 has alpha value set to opaque. |
|
|
|
zero-filled objects. @ref Math::Matrix (and @ref Math::Matrix3, @ref Math::Matrix4) |
|
|
|
|
|
|
|
is by default constructed as identity matrix. @ref Color4 has alpha value set |
|
|
|
|
|
|
|
to opaque. |
|
|
|
@code |
|
|
|
@code |
|
|
|
RectangularMatrix<2, 3, Int> a; // zero-filled |
|
|
|
Matrix2x3 a; // zero-filled |
|
|
|
Vector<3, Int> b; // zero-filled |
|
|
|
Vector3i b; // zero-filled |
|
|
|
|
|
|
|
|
|
|
|
Matrix<3, Int> identity; // diagonal set to 1 |
|
|
|
Matrix3 identity; // diagonal set to 1 |
|
|
|
Matrix<3, Int> zero(Matrix<3, Int>::Zero); // zero-filled |
|
|
|
Matrix3 zero(Matrix::Zero); // zero-filled |
|
|
|
|
|
|
|
|
|
|
|
Color4<Float> black1; // {0.0f, 0.0f, 0.0f, 1.0f} |
|
|
|
Color4 black1; // {0.0f, 0.0f, 0.0f, 1.0f} |
|
|
|
Color4<unsigned char> black2; // {0, 0, 0, 255} |
|
|
|
BasicColor4<UnsignedByte> black2; // {0, 0, 0, 255} |
|
|
|
@endcode |
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
|
|
Most common and most efficient way to create vector is to pass all values to |
|
|
|
Most common and most efficient way to create vector is to pass all values to |
|
|
|
constructor, matrix is created by passing all column vectors to the |
|
|
|
constructor, matrix is created by passing all column vectors to the |
|
|
|
constructor. |
|
|
|
constructor. |
|
|
|
@code |
|
|
|
@code |
|
|
|
Vector3<Int> vec(0, 1, 2); |
|
|
|
Vector3i vec(0, 1, 2); |
|
|
|
|
|
|
|
|
|
|
|
Matrix3<Int> mat({0, 1, 2}, |
|
|
|
Matrix3 mat({0.0f, 1.9f, 2.2f}, |
|
|
|
{3, 4, 5}, |
|
|
|
{3.5f, 4.0f, 5.1f}, |
|
|
|
{6, 7, 8}); |
|
|
|
{6.0f, 7.3f, 8.0f}); |
|
|
|
@endcode |
|
|
|
@endcode |
|
|
|
All constructors check number of passed arguments and the errors are catched |
|
|
|
All constructors check number of passed arguments and the errors are catched |
|
|
|
at compile time. |
|
|
|
at compile time. |
|
|
|
|
|
|
|
|
|
|
|
You can specify all components of vector or whole diagonal of square matrix at |
|
|
|
You can specify all components of vector or whole diagonal of square matrix at |
|
|
|
once: |
|
|
|
once or you can create diagonal matrix from vector: |
|
|
|
@code |
|
|
|
@code |
|
|
|
Matrix3<Int> diag(Matrix3<Int>::Identity, 2); // diagonal set to 2, zeros elsewhere |
|
|
|
Matrix3 diag(Matrix3::Identity, 2.0f); // diagonal set to 2.0f, zeros elsewhere |
|
|
|
Vector3<Int> fill(10); // {10, 10, 10} |
|
|
|
Vector3i fill(10); // {10, 10, 10} |
|
|
|
|
|
|
|
auto diag2 = Matrix3::fromDiagonal({3.0f, 2.0f, 1.0f}); |
|
|
|
@endcode |
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
|
|
It is possible to create matrices from other matrices and vectors with the |
|
|
|
It is possible to create matrices from other matrices and vectors with the same |
|
|
|
same row count; vectors from vector and scalar: |
|
|
|
row count; vectors from vector and scalar: |
|
|
|
@code |
|
|
|
@code |
|
|
|
RectangularMatrix<2, 3, Int> a; |
|
|
|
Math::RectangularMatrix<2, 3, Int> a; |
|
|
|
Vector3<Int> b, c; |
|
|
|
Math::Vector<3, Int> b, c; |
|
|
|
Matrix3<Int> mat(a, b); |
|
|
|
Math::Matrix3<Int> mat(a, b); |
|
|
|
Vector<8, Int> vec(1, b, 2, c); |
|
|
|
Math::Vector<8, Int> vec(1, b, 2, c); |
|
|
|
@endcode |
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@todo Implement this ^ already. |
|
|
|
|
|
|
|
|
|
|
|
It is also possible to create them from an C-style array. The function does |
|
|
|
It is also possible to create them from an C-style array. The function does |
|
|
|
simple type cast without any copying, so it's possible to conveniently operate |
|
|
|
simple type cast without any copying, so it's possible to conveniently operate |
|
|
|
on the array itself: |
|
|
|
on the array itself: |
|
|
|
@ -111,8 +122,8 @@ array is long enough to contain all elements, so use with caution. |
|
|
|
|
|
|
|
|
|
|
|
You can also *explicitly* convert between data types: |
|
|
|
You can also *explicitly* convert between data types: |
|
|
|
@code |
|
|
|
@code |
|
|
|
Vector4<Float> floating(1.3f, 2.7f, -15.0f, 7.0f); |
|
|
|
Vector4 floating(1.3f, 2.7f, -15.0f, 7.0f); |
|
|
|
Vector4<Int> integral(floating); // {1, 2, -15, 7} |
|
|
|
auto integral = Vector4i(floating); // {1, 2, -15, 7} |
|
|
|
@endcode |
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
|
|
@section matrix-vector-component-access Accessing matrix and vector components |
|
|
|
@section matrix-vector-component-access Accessing matrix and vector components |
|
|
|
@ -121,37 +132,98 @@ Column vectors of matrices and vector components can be accessed using square |
|
|
|
brackets, there is also round bracket operator for accessing matrix components |
|
|
|
brackets, there is also round bracket operator for accessing matrix components |
|
|
|
directly: |
|
|
|
directly: |
|
|
|
@code |
|
|
|
@code |
|
|
|
RectangularMatrix<3, 2, Int> a; |
|
|
|
Matrix3x2 a; |
|
|
|
a[2] /= 2; // third column (column major indexing, see explanation below) |
|
|
|
a[2] /= 2.0f; // third column (column major indexing, see explanation below) |
|
|
|
a[0][1] = 5; // first column, second element |
|
|
|
a[0][1] = 5.3f; // first column, second element |
|
|
|
|
|
|
|
|
|
|
|
Vector<3, Int> b; |
|
|
|
Vector3i b; |
|
|
|
b[1] = 1; // second element |
|
|
|
b[1] = 1; // second element |
|
|
|
@endcode |
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
|
|
Row vectors can be accessed too, but only for reading, and the access is slower |
|
|
|
Row vectors can be accessed too, but only for reading, and the access is slower |
|
|
|
due to the way the matrix is stored (see explanation below): |
|
|
|
due to the way the matrix is stored (see explanation below): |
|
|
|
@code |
|
|
|
@code |
|
|
|
Vector<2, Int> c = a.row(2); // third row |
|
|
|
Vector2i c = a.row(2); // third row |
|
|
|
@endcode |
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
|
|
Fixed-size vector subclasses have functions for accessing named components |
|
|
|
Fixed-size vector subclasses have functions for accessing named components |
|
|
|
and subparts: |
|
|
|
and subparts: |
|
|
|
@code |
|
|
|
@code |
|
|
|
Vector4<Int> a; |
|
|
|
Vector4i a; |
|
|
|
Int x = a.x(); |
|
|
|
Int x = a.x(); |
|
|
|
a.y() += 5; |
|
|
|
a.y() += 5; |
|
|
|
|
|
|
|
|
|
|
|
Vector3<Int> xyz = a.xyz(); |
|
|
|
Vector3i xyz = a.xyz(); |
|
|
|
xyz.xy() *= 5; |
|
|
|
xyz.xy() *= 5; |
|
|
|
@endcode |
|
|
|
@endcode |
|
|
|
Color3 and Color4 name their components `rgba` instead of `xyzw`. |
|
|
|
Color3 and Color4 name their components `rgba` instead of `xyzw`. |
|
|
|
|
|
|
|
|
|
|
|
For more involved operations with components there is the swizzle() function: |
|
|
|
For more involved operations with components there is the @ref swizzle() |
|
|
|
|
|
|
|
function: |
|
|
|
|
|
|
|
@code |
|
|
|
|
|
|
|
Vector4i original(-1, 2, 3, 4); |
|
|
|
|
|
|
|
Vector4i bgra = swizzle<'b', 'g', 'r', 'a'>(original); // { 3, 2, -1, 4 } |
|
|
|
|
|
|
|
Math::Vector<6, Int> w10xyz = swizzle<'w', '1', '0', 'x', 'y', 'z'>(original); // { 4, 1, 0, -1, 2, 3 } |
|
|
|
|
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@section matrix-vector-operations Operations with matrices and vectors |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vectors can be added, subtracted, negated and multiplied or divided with |
|
|
|
|
|
|
|
scalars, as is common in mathematics, Magnum also adds the ability to divide |
|
|
|
|
|
|
|
scalar with vector: |
|
|
|
|
|
|
|
@code |
|
|
|
|
|
|
|
Vector3 a(1.0f, 2.0f, 3.0f); |
|
|
|
|
|
|
|
Vector3 b = a*5.0f - Vector3(3.0f, -0.5f, -7.5f); // b == {5.0f, 9.5f, 7.5f} |
|
|
|
|
|
|
|
Vector3 c = 1.0f/a; // c == {1.0f, 0.5f, 0.333f} |
|
|
|
|
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
As in GLSL, vectors can be also multiplied or divided component-wise: |
|
|
|
|
|
|
|
@code |
|
|
|
|
|
|
|
Vector3 a(1.0f, 2.0f, 3.0f); |
|
|
|
|
|
|
|
Vector3 b = a*Vector3(-0.5f, 2.0f, -7.0f); // b == {-0.5f, 4.0f, -21.0f} |
|
|
|
|
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
When working with integral vectors (i.e. 24bit RGB values), it is often |
|
|
|
|
|
|
|
desirable to multiply them with floating-point values but with integral result. |
|
|
|
|
|
|
|
In %Magnum all mulitplication/division operations involving integral vectors |
|
|
|
|
|
|
|
will have integral result, you need to convert both arguments to the same |
|
|
|
|
|
|
|
floating-point type to have floating-point result. |
|
|
|
@code |
|
|
|
@code |
|
|
|
Vector<4, Int> original(-1, 2, 3, 4); |
|
|
|
BasicColor3<UnsignedByte> color(80, 116, 34); |
|
|
|
Vector<4, Int> bgra = swizzle<'b', 'g', 'r', 'a'>(original); // { 3, 2, -1, 4 } |
|
|
|
BasicColor3<UnsignedByte> lighter = color*1.5f; // lighter = {120, 174, 51} |
|
|
|
Vector<6, Int> w10xyz = swizzle<'w', '1', '0', 'x', 'y', 'z'>(original); // { 4, 1, 0, -1, 2, 3 } |
|
|
|
|
|
|
|
|
|
|
|
Vector3i a(4, 18, -90); |
|
|
|
|
|
|
|
Vector3 multiplier(2.2f, 0.25f, 0.1f); |
|
|
|
|
|
|
|
Vector3i b = a*multiplier; // b == {8, 4, -9} |
|
|
|
|
|
|
|
Vector3 c = Vector3(a)*multiplier; // c == {8.0f, 4.5f, -9.0f} |
|
|
|
|
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
You can use also all bitwise operations on integral vectors: |
|
|
|
|
|
|
|
@code |
|
|
|
|
|
|
|
Vector2i size(256, 256); |
|
|
|
|
|
|
|
Vector2i mipLevel3Size = size >> 3; // == {32, 32} |
|
|
|
|
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Matrices can be added, subtracted and multiplied with matrix multiplication. |
|
|
|
|
|
|
|
@code |
|
|
|
|
|
|
|
Matrix3x2 a; |
|
|
|
|
|
|
|
Matrix3x2 b; |
|
|
|
|
|
|
|
Matrix3x2 c = a + (-b); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Matrix2x3 d; |
|
|
|
|
|
|
|
Matrix2x2 e = d*b; |
|
|
|
|
|
|
|
Matrix3x3 f = b*d; |
|
|
|
|
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
You can also multiply (properly sized) vectors with matrices. These operations |
|
|
|
|
|
|
|
are just convenience shortcuts for multiplying with single-column matrices: |
|
|
|
|
|
|
|
@code |
|
|
|
|
|
|
|
Matrix3x4 a; |
|
|
|
|
|
|
|
Vector3 b; |
|
|
|
|
|
|
|
Vector4 c = a*b; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Math::RectangularMatrix<4, 1, Float> d; |
|
|
|
|
|
|
|
Matrix4x3 e = b*d; |
|
|
|
@endcode |
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
|
|
@section matrix-vector-column-major Matrices are column-major and vectors are columns |
|
|
|
@section matrix-vector-column-major Matrices are column-major and vectors are columns |
|
|
|
@ -163,21 +235,21 @@ implications and it may differ from what is common in mathematics: |
|
|
|
- Order of template arguments in specification of RectangularMatrix is also |
|
|
|
- Order of template arguments in specification of RectangularMatrix is also |
|
|
|
column-major: |
|
|
|
column-major: |
|
|
|
@code |
|
|
|
@code |
|
|
|
RectangularMatrix<2, 3, Int> mat; // two columns, three rows |
|
|
|
Math::RectangularMatrix<2, 3, Int> mat; // two columns, three rows |
|
|
|
@endcode |
|
|
|
@endcode |
|
|
|
- Order of components in matrix constructors is also column-major, further |
|
|
|
- Order of components in matrix constructors is also column-major, further |
|
|
|
emphasized by requirement that you have to pass directly column vectors: |
|
|
|
emphasized by requirement that you have to pass directly column vectors: |
|
|
|
@code |
|
|
|
@code |
|
|
|
Matrix3<Int> mat({0, 1, 2}, |
|
|
|
Math::Matrix3<Int> mat({0, 1, 2}, |
|
|
|
{3, 4, 5}, |
|
|
|
{3, 4, 5}, |
|
|
|
{6, 7, 8}); // first column is {0, 1, 2} |
|
|
|
{6, 7, 8}); // first column is {0, 1, 2} |
|
|
|
@endcode |
|
|
|
@endcode |
|
|
|
- Element accessing order is also column-major, thus the bracket operator is |
|
|
|
- Element accessing order is also column-major, thus the bracket operator is |
|
|
|
accessing columns. Returned vector has also its own bracket operator, which |
|
|
|
accessing columns. Returned vector has also its own bracket operator, which |
|
|
|
is then indexing rows. |
|
|
|
is then indexing rows. |
|
|
|
@code |
|
|
|
@code |
|
|
|
mat[0] *= 2; // first column |
|
|
|
mat[0] *= 2; // first column |
|
|
|
mat[2][0] = 5; // first element of first column |
|
|
|
mat[2][0] = 5; // first element of third column |
|
|
|
@endcode |
|
|
|
@endcode |
|
|
|
- Various algorithms which commonly operate on matrix rows (such as |
|
|
|
- Various algorithms which commonly operate on matrix rows (such as |
|
|
|
@ref Algorithms::gaussJordanInPlace() "Gauss-Jordan elimination") have faster |
|
|
|
@ref Algorithms::gaussJordanInPlace() "Gauss-Jordan elimination") have faster |
|
|
|
|