() const noexcept
{
return size_cast(std::make_index_sequence
{});
}
/// Returns a zero matrix, where every element is equal to zero.
static constexpr matrix zero() noexcept
{
return {};
}
/// @private
template
static constexpr inline matrix one(std::index_sequence) noexcept
{
//return {column_vector_type::one() ...};
// MSVC bug workaround (I must be referenced for parameter pack expansion)
return {(I ? column_vector_type::one() : column_vector_type::one()) ...};
}
/// Returns a matrix of ones, where every element is equal to one.
static constexpr matrix one() noexcept
{
return one(std::make_index_sequence{});
}
/// @private
template
static constexpr inline column_vector_type identity_column(std::size_t i, std::index_sequence) noexcept
{
return {(I == i ? T{1} : T{0}) ...};
}
/// @private
template
static constexpr inline matrix identity(std::index_sequence) noexcept
{
return {identity_column(I, std::make_index_sequence{}) ...};
}
/// Returns an identity matrix, with ones on the main diagonal and zeros elsewhere.
static constexpr matrix identity() noexcept
{
return identity(std::make_index_sequence{});
}
};
/// 2x2 matrix.
template
using matrix2 = matrix;
/// 2x2 matrix.
template
using matrix2x2 = matrix;
/// 3x3 matrix.
template
using matrix3 = matrix;
/// 3x3 matrix.
template
using matrix3x3 = matrix;
/// 4x4 matrix.
template
using matrix4 = matrix;
/// 4x4 matrix.
template
using matrix4x4 = matrix;
/**
* Adds two matrices.
*
* @param x First matrix.
* @param y Second matrix.
* @return Sum of the two matrices.
*/
template
constexpr matrix add(const matrix& x, const matrix& y);
/// @copydoc add(const matrix&, const matrix&)
template
constexpr matrix add(const matrix& x, const matrix& y);
/// @copydoc add(const matrix&, const matrix&)
template
constexpr matrix add(const matrix& x, const matrix& y);
/**
* Reinterprets data as an `NxM` matrix of type `T`.
*
* @tparam N Number of columns.
* @tparam M Number of rows.
* @tparam T Element type.
* @param data Data to reinterpret.
*/
template
constexpr matrix& as_matrix(T& data);
/**
* Calculates the determinant of a matrix.
*
* @param m Matrix of which to take the determinant.
*/
template
constexpr T determinant(const matrix& m);
/// @copydoc determinant(const matrix&)
template
constexpr T determinant(const matrix& m);
/// @copydoc determinant(const matrix&)
template
constexpr T determinant(const matrix& m);
/**
* Calculates the inverse of a matrix.
*
* @param m Matrix of which to take the inverse.
*/
template
constexpr matrix inverse(const matrix& m);
/// @copydoc inverse(const matrix&)
template
constexpr matrix inverse(const matrix& m);
/// @copydoc inverse(const matrix&)
template
constexpr matrix inverse(const matrix& m);
/**
* Performs a component-wise multiplication of two matrices.
*
* @param x First matrix multiplicand.
* @param y Second matrix multiplicand.
*/
template
constexpr matrix componentwise_mul(const matrix& x, const matrix& y);
/// @copydoc componentwise_mul(const matrix&, const matrix&)
template
constexpr matrix componentwise_mul(const matrix& x, const matrix& y);
/// @copydoc componentwise_mul(const matrix&, const matrix&)
template
constexpr matrix componentwise_mul(const matrix& x, const matrix& y);
/**
* Creates a viewing transformation matrix.
*
* @param position Position of the view point.
* @param target Position of the target.
* @param up Normalized direction of the up vector.
* @return Viewing transformation matrix.
*/
template
constexpr matrix look_at(const vector& position, const vector& target, vector up);
/**
* Multiplies two matrices.
*
* @param x First matrix.
* @param y Second matrix.
* @return Product of the two matrices.
*/
template
constexpr matrix mul(const matrix& x, const matrix& y);
/// @copydoc mul(const matrix&, const matrix&);
template
constexpr matrix mul(const matrix& x, const matrix& y);
/// @copydoc mul(const matrix&, const matrix&);
template
constexpr matrix mul(const matrix& x, const matrix& y);
/**
* Multiplies a matrix by a scalar.
*
* @param m Matrix.
* @param s Scalar.
* @return Product of the matrix and the scalar..
*/
template
constexpr matrix mul(const matrix& m, T s);
/**
* Transforms a vector by a matrix.
*
* @param m Matrix.
* @param v Vector.
* @return Transformed vector.
*/
template
constexpr vector mul(const matrix& m, const vector& v);
/// @copydoc mul(const matrix&, const vector&)
template
constexpr vector mul(const matrix& m, const vector& v);
/// @copydoc mul(const matrix&, const vector&)
template
constexpr vector mul(const matrix& m, const vector& v);
/**
* Creates an orthographic projection matrix which will transform the near and far clipping planes to `[-1, 1]`, respectively.
*
* @param left Signed distance to the left clipping plane.
* @param right Signed distance to the right clipping plane.
* @param bottom Signed distance to the bottom clipping plane.
* @param top Signed distance to the top clipping plane.
* @param z_near Signed distance to the near clipping plane.
* @param z_far Signed distance to the far clipping plane.
* @return Orthographic projection matrix.
*/
template
constexpr matrix ortho(T left, T right, T bottom, T top, T z_near, T z_far);
/**
* Creates an orthographic projection matrix which will transform the near and far clipping planes to `[0, 1]`, respectively.
*
* @param left Signed distance to the left clipping plane.
* @param right Signed distance to the right clipping plane.
* @param bottom Signed distance to the bottom clipping plane.
* @param top Signed distance to the top clipping plane.
* @param z_near Signed distance to the near clipping plane.
* @param z_far Signed distance to the far clipping plane.
* @return Orthographic projection matrix.
*/
template
constexpr matrix ortho_half_z(T left, T right, T bottom, T top, T z_near, T z_far);
/**
* Calculates the outer product of a pair of vectors.
*
* @param c Parameter to be treated as a column vector.
* @param r Parameter to be treated as a row vector.
*/
template
constexpr matrix outer_product(const vector& c, const vector& r);
/// @copydoc outer_product(const vector&, const vector&)
template
constexpr matrix outer_product(const vector& c, const vector& r);
/// @copydoc outer_product(const vector&, const vector&)
template
constexpr matrix outer_product(const vector& c, const vector r);
/**
* Creates a perspective projection matrix which will transform the near and far clipping planes to `[-1, 1]`, respectively.
*
* @param vertical_fov Vertical field of view angle, in radians.
* @param aspect_ratio Aspect ratio which determines the horizontal field of view.
* @param z_near Distance to the near clipping plane.
* @param z_far Distance to the far clipping plane.
* @return Perspective projection matrix.
*/
template
matrix perspective(T vertical_fov, T aspect_ratio, T z_near, T z_far);
/**
* Creates a perspective projection matrix which will transform the near and far clipping planes to `[0, 1]`, respectively.
*
* @param vertical_fov Vertical field of view angle, in radians.
* @param aspect_ratio Aspect ratio which determines the horizontal field of view.
* @param z_near Distance to the near clipping plane.
* @param z_far Distance to the far clipping plane.
* @return Perspective projection matrix.
*/
template
matrix perspective_half_z(T vertical_fov, T aspect_ratio, T z_near, T z_far);
/**
* Resizes a matrix. Any new elements will be set to `1` if in the diagonal, and `0` otherwise.
*
* @param m Matrix to resize.
* @return Resized matrix.
*/
template
constexpr matrix resize(const matrix& m);
/**
* Constructs a rotation matrix.
*
* @param angle Angle of rotation, in radians.
* @param axis Axis of rotation
* @return Rotation matrix.
*/
template
matrix rotate(T angle, const vector& axis);
/**
* Produces a matrix which rotates Cartesian coordinates about the x-axis by a given angle.
*
* @param angle Angle of rotation, in radians.
* @return Rotation matrix.
*/
template
matrix3 rotate_x(T angle);
/**
* Produces a matrix which rotates Cartesian coordinates about the y-axis by a given angle.
*
* @param angle Angle of rotation, in radians.
* @return Rotation matrix.
*/
template
matrix3 rotate_y(T angle);
/**
* Produces a matrix which rotates Cartesian coordinates about the z-axis by a given angle.
*
* @param angle Angle of rotation, in radians.
* @return Rotation matrix.
*/
template
matrix3 rotate_z(T angle);
/**
* Scales a matrix.
*
* @param m Matrix to scale.
* @param v Scale vector.
* @return Scaled matrix.
*/
template
constexpr matrix scale(const matrix& m, const vector& v);
/**
* Subtracts a matrix from another matrix.
*
* @param x First matrix.
* @param y Second matrix.
* @return Difference between the two matrices.
*/
template
constexpr matrix sub(const matrix& x, const matrix& y);
/// @copydoc sub(const matrix&, const matrix&)
template
constexpr matrix sub(const matrix& x, const matrix& y);
/// @copydoc sub(const matrix&, const matrix&)
template
constexpr matrix sub(const matrix& x, const matrix& y);
/**
* Translates a matrix.
*
* @param m Matrix to translate.
* @param v Translation vector.
* @return Translated matrix.
*/
template
constexpr matrix translate(const matrix& m, const vector& v);
/**
* Calculates the transpose of a matrix.
*
* @param m Matrix of which to take the transpose.
*/
template
constexpr matrix transpose(const matrix& m);
/// @copydoc transpose(const matrix&)
template
constexpr matrix transpose(const matrix& m);
/// @copydoc transpose(const matrix&)
template
constexpr matrix transpose(const matrix& m);
/**
* Types casts each matrix element and returns a matrix of the casted type.
*
* @tparam T2 Target matrix element type.
* @tparam T1 Source matrix element type.
* @tparam N Number of columns.
* @tparam M Number of rows.
* @param m Matrix to type cast.
* @return Type-casted matrix.
*/
template
constexpr matrix type_cast(const matrix& m);
template
constexpr matrix add(const matrix& x, const matrix& y)
{
return
{{
x[0] + y[0],
x[1] + y[1]
}};
}
template
constexpr matrix add(const matrix& x, const matrix& y)
{
return
{{
x[0] + y[0],
x[1] + y[1],
x[2] + y[2]
}};
}
template
constexpr matrix add(const matrix& x, const matrix& y)
{
return
{{
x[0] + y[0],
x[1] + y[1],
x[2] + y[2],
x[3] + y[3]
}};
}
template
constexpr inline matrix& as_matrix(T& data)
{
static_assert(std::is_pod>::value);
return reinterpret_cast&>(data);
}
template
constexpr T determinant(const matrix& m)
{
return m[0][0] * m[1][1] - m[0][1] * m[1][0];
}
template
constexpr T determinant(const matrix& m)
{
return m[0][0] * m [1][1] * m[2][2] +
m[0][1] * m[1][2] * m[2][0] +
m[0][2] * m[1][0] * m[2][1] -
m[0][0] * m[1][2] * m[2][1] -
m[0][1] * m[1][0] * m[2][2] -
m[0][2] * m[1][1] * m[2][0];
}
template
constexpr T determinant(const matrix& m)
{
return m[0][3] * m[1][2] * m[2][1] * m[3][0] - m[0][2] * m[1][3] * m[2][1] * m[3][0] -
m[0][3] * m[1][1] * m[2][2] * m[3][0] + m[0][1] * m[1][3] * m[2][2] * m[3][0] +
m[0][2] * m[1][1] * m[2][3] * m[3][0] - m[0][1] * m[1][2] * m[2][3] * m[3][0] -
m[0][3] * m[1][2] * m[2][0] * m[3][1] + m[0][2] * m[1][3] * m[2][0] * m[3][1] +
m[0][3] * m[1][0] * m[2][2] * m[3][1] - m[0][0] * m[1][3] * m[2][2] * m[3][1] -
m[0][2] * m[1][0] * m[2][3] * m[3][1] + m[0][0] * m[1][2] * m[2][3] * m[3][1] +
m[0][3] * m[1][1] * m[2][0] * m[3][2] - m[0][1] * m[1][3] * m[2][0] * m[3][2] -
m[0][3] * m[1][0] * m[2][1] * m[3][2] + m[0][0] * m[1][3] * m[2][1] * m[3][2] +
m[0][1] * m[1][0] * m[2][3] * m[3][2] - m[0][0] * m[1][1] * m[2][3] * m[3][2] -
m[0][2] * m[1][1] * m[2][0] * m[3][3] + m[0][1] * m[1][2] * m[2][0] * m[3][3] +
m[0][2] * m[1][0] * m[2][1] * m[3][3] - m[0][0] * m[1][2] * m[2][1] * m[3][3] -
m[0][1] * m[1][0] * m[2][2] * m[3][3] + m[0][0] * m[1][1] * m[2][2] * m[3][3];
}
template
constexpr matrix inverse(const matrix& m)
{
static_assert(std::is_floating_point::value);
const T rd(T(1) / determinant(m));
return
{{
{ m[1][1] * rd, -m[0][1] * rd},
{-m[1][0] * rd, m[0][0] * rd}
}};
}
template
constexpr matrix inverse(const matrix