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.
182 lines
7.1 KiB
182 lines
7.1 KiB
/* |
|
This file is part of Magnum. |
|
|
|
Copyright © 2010, 2011, 2012, 2013 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 { namespace Math { |
|
/** @page matrix-vector Operations with matrices and vectors |
|
|
|
@brief Introduction to essential classes of the graphics pipeline. |
|
|
|
@tableofcontents |
|
|
|
Matrices and vectors are the most important part of graphics programming and |
|
one of goals of %Magnum is to make their usage as intuitive as possible. This |
|
page will overview their usage and introduce some tricks to make your life |
|
easier. |
|
|
|
@section matrix-vector-hierarchy Matrix and vector classes |
|
|
|
%Magnum has three main matrix and vector classes: RectangularMatrix, (square) |
|
Matrix and Vector. To achieve greatest code reuse, %Matrix is internally |
|
square %RectangularMatrix and %RectangularMatrix is internally array of one or |
|
more %Vector instances. Both vectors and matrices 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 |
|
vector and matrix sizes there are specialized classes Matrix3 and Matrix4, |
|
implementing various transformation in 2D and 3D, Vector2, Vector3 and Vector4, |
|
implementing direct access to named components. Functions of each class try to |
|
return the most specialized type known to make subsequent operations more |
|
convenient - 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 |
|
color handling and conversion. |
|
|
|
@section matrix-vector-construction Constructing matrices and vectors |
|
|
|
Default constructors of RectangularMatrix and Vector (and Vector2, Vector3, |
|
Vector4, Color3) create zero-filled objects. Matrix (and Matrix3, Matrix4) is |
|
by default constructed as identity matrix. Color4 has alpha value set to opaque. |
|
@code |
|
RectangularMatrix<2, 3, Int> a; // zero-filled |
|
Vector<3, Int> b; // zero-filled |
|
|
|
Matrix<3, Int> identity; // diagonal set to 1 |
|
Matrix<3, Int> zero(Matrix<3, Int>::Zero); // zero-filled |
|
|
|
Color4<Float> black1; // {0.0f, 0.0f, 0.0f, 1.0f} |
|
Color4<unsigned char> black2; // {0, 0, 0, 255} |
|
@endcode |
|
|
|
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. |
|
@code |
|
Vector3<Int> vec(0, 1, 2); |
|
|
|
Matrix3<Int> mat({0, 1, 2}, |
|
{3, 4, 5}, |
|
{6, 7, 8}); |
|
@endcode |
|
All constructors check number of passed arguments and the errors are catched |
|
at compile time. |
|
|
|
You can specify all components of vector or whole diagonal of square matrix at |
|
once: |
|
@code |
|
Matrix3<Int> diag(Matrix3<Int>::Identity, 2); // diagonal set to 2, zeros elsewhere |
|
Vector3<Int> fill(10); // {10, 10, 10} |
|
@endcode |
|
|
|
It is possible to create matrices from other matrices and vectors with the |
|
same row count; vectors from vector and scalar: |
|
@code |
|
RectangularMatrix<2, 3, Int> a; |
|
Vector3<Int> b, c; |
|
Matrix3<Int> mat(a, b); |
|
Vector<8, Int> vec(1, b, 2, c); |
|
@endcode |
|
|
|
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 |
|
on the array itself: |
|
@code |
|
Int[] mat = { 2, 4, 6, |
|
1, 3, 5 }; |
|
RectangularMatrix<2, 3, Int>::from(mat) *= 2; // mat == { 4, 8, 12, 2, 6, 10 } |
|
@endcode |
|
Note that unlike constructors, this function has no way to check whether the |
|
array is long enough to contain all elements, so use with caution. |
|
|
|
You can also *explicitly* convert between data types: |
|
@code |
|
Vector4<Float> floating(1.3f, 2.7f, -15.0f, 7.0f); |
|
Vector4<Int> integral(floating); // {1, 2, -15, 7} |
|
@endcode |
|
|
|
@section matrix-vector-component-access Accessing matrix and vector components |
|
|
|
Column vectors of matrices and vector components can be accessed using square |
|
brackets, there is also round bracket operator for accessing matrix components |
|
directly: |
|
@code |
|
RectangularMatrix<3, 2, Int> a; |
|
a[2] /= 2; // third column (column major indexing, see explanation below) |
|
a[0][1] = 5; // first column, second element |
|
|
|
Vector<3, Int> b; |
|
b[1] = 1; // second element |
|
@endcode |
|
|
|
Fixed-size vector subclasses have functions for accessing named components |
|
and subparts: |
|
@code |
|
Vector4<Int> a; |
|
Int x = a.x(); |
|
a.y() += 5; |
|
|
|
Vector3<Int> xyz = a.xyz(); |
|
xyz.xy() *= 5; |
|
@endcode |
|
Color3 and Color4 name their components `rgba` instead of `xyzw`. |
|
|
|
For more involved operations with components there is the swizzle() function: |
|
@code |
|
Vector<4, Int> original(-1, 2, 3, 4); |
|
Vector<4, Int> bgra = swizzle<'b', 'g', 'r', 'a'>(original); // { 3, 2, -1, 4 } |
|
Vector<6, Int> w10xyz = swizzle<'w', '1', '0', 'x', 'y', 'z'>(original); // { 4, 1, 0, -1, 2, 3 } |
|
@endcode |
|
|
|
@section matrix-vector-column-major Matrices are column-major and vectors are columns |
|
|
|
OpenGL matrices are column-major, thus it is reasonable to have matrices in |
|
%Magnum also column major (and vectors as columns). This has naturally some |
|
implications and it may differ from what is common in mathematics: |
|
|
|
- Order of template arguments in specification of RectangularMatrix is also |
|
column-major: |
|
@code |
|
RectangularMatrix<2, 3, Int> mat; // two columns, three rows |
|
@endcode |
|
- Order of components in matrix constructors is also column-major, further |
|
emphasized by requirement that you have to pass directly column vectors: |
|
@code |
|
Matrix3<Int> mat({0, 1, 2}, |
|
{3, 4, 5}, |
|
{6, 7, 8}); // first column is {0, 1, 2} |
|
@endcode |
|
- Element accessing order is also column-major, thus the bracket operator is |
|
accessing columns. Returned vector has also its own bracket operator, which |
|
is then indexing rows. |
|
@code |
|
mat[0] *= 2; // first column |
|
mat[2][0] = 5; // first element of first column |
|
@endcode |
|
- Various algorithms which commonly operate on matrix rows (such as |
|
@ref Algorithms::gaussJordanInPlace() "Gauss-Jordan elimination") have faster |
|
alternatives which operate on columns. It's then up to user decision to |
|
operate with transposed matrices or use the slower non-transposed |
|
alternative of the algorithm. |
|
*/ |
|
}}
|
|
|