10#ifndef MATH_MATRIX_TOOLS_HEADER
11#define MATH_MATRIX_TOOLS_HEADER
30 T
const& top, T
const& right);
38 T
const& top, T
const& right);
48 Vector<T,3>
const& viewdir, Vector<T,3>
const& upvec);
56 Vector<T,3>
const& viewdir, Vector<T,3>
const& upvec);
69template <
typename T,
int N>
84template <
typename T,
int N>
91template <
typename T,
int N>
98template <
typename T,
int N>
113template <
typename T,
int N>
120template <
typename T,
int N>
128template <
typename T,
int N>
136template <
typename T,
int N>
144template <
typename T,
int N>
170 T
const* mat_b,
int cols_b, T* mat_res);
198template <
typename T,
int N>
205template <
typename T,
int N>
218 T
const& top, T
const& right)
221 proj(0,0) = znear / right;
222 proj(1,1) = znear / top;
223 proj(2,2) = -(zfar + znear) / (zfar - znear);
224 proj(2,3) = T(-2) * zfar * znear / (zfar - znear);
233 T
const& top, T
const& right)
236 iproj(0,0) = right / znear;
237 iproj(1,1) = top / znear;
239 iproj(3,2) = (zfar - znear) / (T(-2) * zfar * znear);
240 iproj(3,3) = -(zfar + znear) / (T(-2) * zfar * znear);
256 m(0,0) = x[0]; m(0,1) = x[1]; m(0,2) = x[2]; m(0,3) = 0.0f;
257 m(1,0) = y[0]; m(1,1) = y[1]; m(1,2) = y[2]; m(1,3) = 0.0f;
258 m(2,0) = z[0]; m(2,1) = z[1]; m(2,2) = z[2]; m(2,3) = 0.0f;
259 m(3,0) = 0.0f; m(3,1) = 0.0f; m(3,2) = 0.0f; m(3,3) = 1.0f;
262 m(0,3) = m(0,0) * t[0] + m(0,1) * t[1] + m(0,2) * t[2];
263 m(1,3) = m(1,0) * t[0] + m(1,1) * t[1] + m(1,2) * t[2];
264 m(2,3) = m(2,0) * t[0] + m(2,1) * t[1] + m(2,2) * t[2];
279 m(0,0) = x[0]; m(0,1) = y[0]; m(0,2) = z[0]; m(0,3) = campos[0];
280 m(1,0) = x[1]; m(1,1) = y[1]; m(1,2) = z[1]; m(1,3) = campos[1];
281 m(2,0) = x[2]; m(2,1) = y[2]; m(2,2) = z[2]; m(2,3) = campos[2];
282 m(3,0) = 0.0f; m(3,1) = 0.0f; m(3,2) = 0.0f; m(3,3) = 1.0f;
293 ret[0] = mat[0]; ret[1] = mat[4]; ret[2] = mat[8];
294 ret[4] = mat[1]; ret[5] = mat[5]; ret[6] = mat[9];
295 ret[8] = mat[2]; ret[9] = mat[6]; ret[10] = mat[10];
297 ret[3] = -(ret[0] * mat[3] + ret[1] * mat[7] + ret[2] * mat[11]);
298 ret[7] = -(ret[4] * mat[3] + ret[5] * mat[7] + ret[6] * mat[11]);
299 ret[11] = -(ret[8] * mat[3] + ret[9] * mat[7] + ret[10] * mat[11]);
305template <
typename T,
int N>
310 for (
int i = 0; i < N * N; i += N + 1)
319 int const len = n * n;
320 std::fill(mat, mat + len, T(0));
321 for (
int i = 0; i < len; i += n + 1)
326template <
typename T,
int N>
330 for (
int y = 0, i = 0; y < N; ++y)
331 for (
int x = 0; x < N; ++x, ++i)
338template <
typename T,
int N>
343 std::fill(*mat, *mat + N*N, T(0));
344 for (
int i = 0, j = 0; i < N*N; i += N+1, j += 1)
349template <
typename T,
int N>
353 for (
int i = 0, j = 0; i < N*N; i += N+1, j += 1)
358template <
typename T,
int N>
363 for (
int i = 0, j = 0; i < N*N; i += N+1, j += 1)
368template <
typename T,
int N>
373 for (
int i = 0; i < N * N; i += N + 1)
389 return mat[0] * mat[3] - mat[1] * mat [2];
396 return m[0] * m[4] * m[8] + m[1] * m[5] * m[6] + m[2] * m[3] * m[7]
397 - m[2] * m[4] * m[6] - m[1] * m[3] * m[8] - m[0] * m[5] * m[7];
404 return m[0] * (m[5] * m[10] * m[15] - m[5] * m[11] * m[14]
405 - m[9] * m[6] * m[15] + m[9] * m[7] * m[14]
406 + m[13] * m[6] * m[11] - m[13] * m[7] * m[10])
408 + m[1] * (-m[4] * m[10] * m[15] + m[4] * m[11] * m[14]
409 + m[8] * m[6] * m[15] - m[8] * m[7] * m[14]
410 - m[12] * m[6] * m[11] + m[12] * m[7] * m[10])
412 + m[2] * (m[4] * m[9] * m[15] - m[4] * m[11] * m[13]
413 - m[8] * m[5] * m[15] + m[8] * m[7] * m[13]
414 + m[12] * m[5] * m[11] - m[12] * m[7] * m[9])
416 + m[3] * (-m[4] * m[9] * m[14] + m[4] * m[10] * m[13]
417 + m[8] * m[5] * m[14] - m[8] * m[6] * m[13]
418 - m[12] * m[5] * m[10] + m[12] * m[6] * m[9]);
455 ret[0] = mat[3]; ret[1] = -mat[1];
456 ret[2] = -mat[2]; ret[3] = mat[0];
465 ret[0] = m[4] * m[8] - m[5] * m[7];
466 ret[1] = m[2] * m[7] - m[1] * m[8];
467 ret[2] = m[1] * m[5] - m[2] * m[4];
468 ret[3] = m[5] * m[6] - m[3] * m[8];
469 ret[4] = m[0] * m[8] - m[2] * m[6];
470 ret[5] = m[2] * m[3] - m[0] * m[5];
471 ret[6] = m[3] * m[7] - m[4] * m[6];
472 ret[7] = m[1] * m[6] - m[0] * m[7];
473 ret[8] = m[0] * m[4] - m[1] * m[3];
483 ret[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15]
484 + m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10];
485 ret[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15]
486 - m[9] * m[3] * m[14] - m[13] * m[2] * m[11] + m[13] * m[3] * m[10];
487 ret[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15]
488 + m[5] * m[3] * m[14] + m[13] * m[2] * m[7] - m[13] * m[3] * m[6];
489 ret[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11]
490 - m[5] * m[3] * m[10] - m[9] * m[2] * m[7] + m[9] * m[3] * m[6];
492 ret[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15]
493 - m[8] * m[7] * m[14] - m[12] * m[6] * m[11] + m[12] * m[7] * m[10];
494 ret[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15]
495 + m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10];
496 ret[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15]
497 - m[4] * m[3] * m[14] - m[12] * m[2] * m[7] + m[12] * m[3] * m[6];
498 ret[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11]
499 + m[4] * m[3] * m[10] + m[8] * m[2] * m[7] - m[8] * m[3] * m[6];
501 ret[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15]
502 + m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9];
503 ret[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15]
504 - m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9];
505 ret[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15]
506 + m[4] * m[3] * m[13] + m[12] * m[1] * m[7] - m[12] * m[3] * m[5];
507 ret[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11]
508 - m[4] * m[3] * m[9] - m[8] * m[1] * m[7] + m[8] * m[3] * m[5];
510 ret[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14]
511 - m[8] * m[6] * m[13] - m[12] * m[5] * m[10] + m[12] * m[6] * m[9];
512 ret[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14]
513 + m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9];
514 ret[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14]
515 - m[4] * m[2] * m[13] - m[12] * m[1] * m[6] + m[12] * m[2] * m[5];
516 ret[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10]
517 + m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - m[8] * m[2] * m[5];
519 T det = m[0] * ret[0] + m[1] * ret[4] + m[2] * ret[8] + m[3] * ret[12];
531 T
const ca = std::cos(angle);
532 T
const sa = std::sin(angle);
533 T
const omca = T(1) - ca;
537 rot[1] = axis[0] * axis[1] * omca - axis[2] * sa;
538 rot[2] = axis[0] * axis[2] * omca + axis[1] * sa;
540 rot[3] = axis[1] * axis[0] * omca + axis[2] * sa;
542 rot[5] = axis[1] * axis[2] * omca - axis[0] * sa;
544 rot[6] = axis[2] * axis[0] * omca - axis[1] * sa;
545 rot[7] = axis[2] * axis[1] * omca + axis[0] * sa;
556 T* tmp =
new T[rows * cols];
557 std::copy(mat, mat + rows * cols, tmp);
560 for (
int iter = 0, col = 0; col < cols; ++col)
561 for (
int row = 0; row < rows; ++row, ++iter)
562 mat[iter] = tmp[row * cols + col];
570 T
const* mat_b,
int cols_b, T* mat_res)
572 std::fill(mat_res, mat_res + rows_a * cols_b, T(0));
573 for (
int j = 0; j < cols_b; ++j)
575 for (
int i = 0; i < rows_a; ++i)
577 int const ica = i * cols_a;
578 int const icb = i * cols_b;
579 for (
int k = 0; k < cols_a; ++k)
580 mat_res[icb + j] += mat_a[ica + k] * mat_b[k * cols_b + j];
589 std::fill(mat_res, mat_res + cols * cols, T(0));
591 T
const* A_trans_iter = mat_a;
592 T
const* A_row = mat_a;
593 for (
int ri = 0; ri < rows; ++ri, A_row += cols)
596 for (
int c1 = 0; c1 < cols; ++c1, ++A_trans_iter)
597 for (
int c2 = 0; c2 < cols; ++c2, ++R_iter)
598 (*R_iter) += A_row[c2] * (*A_trans_iter);
606 for (
int y = 0; y < rows; ++y)
608 for (
int x = 0; x < y && x < cols; ++x)
611 for (
int x = y + 1; x < cols; ++x)
622 for (
int i = 0; i < rows; ++i, c1 += cols, c2 += cols)
632 for (
int i = 0; i < cols; ++i, ++r1, ++r2)
636template <
typename T,
int N>
640 for (
int i = 0, j = N * N - 1; i < j; ++i, --j)
644template <
typename T,
int N>
Matrix class for arbitrary dimensions and types.
Matrix< T, N, M > & fill(T const &value)
Fills all vector elements with the given value.
Vector class for arbitrary dimensions and types.
Vector< T, N > cross(Vector< T, N > const &other) const
Cross product between this and another vector.
#define MATH_EPSILON_EQ(x, v, eps)
#define MATH_NAMESPACE_BEGIN
#define MATH_NAMESPACE_END
void matrix_rotate_180_inplace(Matrix< T, N, N > *mat_a)
Rotates the entries of the given matrix by 180 degrees in-place.
Matrix< T, N, N > matrix_rotate_180(Matrix< T, N, N > const &mat_a)
Rotates the entries of the given matrix by 180 degrees.
Matrix< T, 4, 4 > matrix_invert_trans(Matrix< T, 4, 4 > const &mat)
Inverts a transformation matrix.
void matrix_multiply(T const *mat_a, int rows_a, int cols_a, T const *mat_b, int cols_b, T *mat_res)
Matrix multiplication of dynamically sized dense matrices.
Matrix< T, 4, 4 > matrix_inverse_gl_projection(T const &znear, T const &zfar, T const &top, T const &right)
Creates a symmetric inverse projection matrix as used in OpenGL.
Matrix< T, 3, 3 > matrix_rotation_from_axis_angle(Vector< T, 3 > const &axis, T const &angle)
Computes the 3x3 rotation matrix from axis and angle notation.
bool matrix_is_identity(Matrix< T, N, N > const &mat, T const &epsilon=T(0))
Returns true if and only if the given matrix is the identity matrix.
T matrix_trace(math::Matrix< T, N, N > const &mat)
Calculates the trace of the given matrix.
Matrix< T, N, N > matrix_inverse(Matrix< T, N, N > const &mat)
Calculates the inverse of the given matrix.
void matrix_swap_columns(T *const mat, int rows, int cols, int c1, int c2)
Swaps the columns c1 and c2 of matrix mat with dimension rows, cols.
void matrix_swap_rows(T *mat, int rows, int cols, int r1, int r2)
Swaps the rows r1 and r2 of matrix mat with dimension rows, cols.
Matrix< T, N, N > & matrix_set_identity(Matrix< T, N, N > *mat)
Sets the given square matrix to the identity matrix.
Matrix< T, 4, 4 > matrix_inverse_viewtrans(Vector< T, 3 > const &campos, Vector< T, 3 > const &viewdir, Vector< T, 3 > const &upvec)
Creates an inverse view transformation matrix.
void matrix_transpose(T const *mat, int rows, int cols)
In-place transpose of a dynamically sized dense matrix.
Matrix< T, N, N > matrix_from_diagonal(math::Vector< T, N > const &v)
Returns a diagonal matrix from the given vector.
Matrix< T, N, N > & matrix_set_diagonal(Matrix< T, N, N > &mat, T const *diag)
Sets the diagonal elements of the given matrix.
T matrix_determinant(Matrix< T, N, N > const &mat)
Calculates the determinant of the given matrix.
Matrix< T, 4, 4 > matrix_viewtrans(Vector< T, 3 > const &campos, Vector< T, 3 > const &viewdir, Vector< T, 3 > const &upvec)
Creates a view transformation matrix for camera parameters given as camera position,...
void matrix_transpose_multiply(T const *mat_a, int rows, int cols, T *mat_res)
Matrix multiplication of the transposed with itself.
Vector< T, N > matrix_get_diagonal(Matrix< T, N, N > const &mat)
Returns the diagonal elements of the matrix as a vector.
Matrix< T, 4, 4 > matrix_gl_projection(T const &znear, T const &zfar, T const &top, T const &right)
Creates a symmetric projection matrix as used in OpenGL.
bool matrix_is_diagonal(T *const mat, int rows, int cols, T const &epsilon=T(0))
Checks whether the input matrix is a diagonal matrix.
void swap(mve::Image< T > &a, mve::Image< T > &b)
Specialization of std::swap for efficient image swapping.