33 #ifndef __VMML__MATRIX__HPP__ 34 #define __VMML__MATRIX__HPP__ 36 #include <vmmlib/types.hpp> 45 #include <type_traits> 51 template <
size_t R,
size_t C,
typename T>
65 Matrix(
const T* begin,
const T* end);
77 template <
size_t P,
size_t Q>
87 typename std::enable_if<R == S + 1 && C == S + 1 && S == 3>::type* = 0);
97 typename std::enable_if<R == S + 1 && C == S + 1 && S == 3>::type* = 0);
108 bool equals(
const Matrix& other,
109 T tolerance = std::numeric_limits<T>::epsilon())
const;
121 template <
size_t O,
size_t P,
typename =
typename std::enable_if<
122 R == C && O == P && R == O>::type>
126 Matrix
operator+(
const Matrix& other)
const;
129 Matrix
operator-(
const Matrix& other)
const;
147 T&
operator()(
size_t rowIndex,
size_t colIndex);
150 T
operator()(
size_t rowIndex,
size_t colIndex)
const;
155 template <
size_t O,
size_t P>
157 size_t rowOffset,
size_t colOffset,
158 typename std::enable_if<O <= R && P <= C>::type* = 0)
const;
161 template <
size_t O,
size_t P>
162 typename std::enable_if<O <= R && P <= C>::type* setSubMatrix(
163 const Matrix<O, P, T>& sub_matrix,
size_t rowOffset,
size_t colOffset);
173 template <
size_t P,
size_t Q>
181 void operator=(
const std::vector<T>& data);
190 void setColumn(
size_t index,
const vector<R, T>& column);
199 vector<C - 1, T> getTranslation()
const;
210 typename std::enable_if<R == S + 1 && C == S + 1 &&
211 S == 3>::type* = 0)
const;
221 template <
size_t O,
size_t P>
222 typename std::enable_if<O == P && R == C && O == R && R >= 2>::type*
225 template <
size_t O,
size_t P>
226 typename std::enable_if<O == P && R == C && O == R && R >= 2>::type*
230 template <
size_t O,
size_t P>
231 T getMinor(
Matrix<O, P, T>& minor_,
size_t row_to_cut,
size_t col_to_cut,
232 typename std::enable_if<O == R - 1 && P == C - 1 && R == C &&
233 R >= 2>::type* = 0)
const;
237 template <
typename TT>
239 TT angle,
typename std::enable_if<R == C && R == 4, TT>::type* = 0);
241 template <
typename TT>
243 TT angle,
typename std::enable_if<R == C && R == 4, TT>::type* = 0);
245 template <
typename TT>
247 TT angle,
typename std::enable_if<R == C && R == 4, TT>::type* = 0);
249 template <
typename TT>
251 TT angle,
typename std::enable_if<R == C && R == 4, TT>::type* = 0);
253 template <
typename TT>
255 TT angle,
typename std::enable_if<R == C && R == 4, TT>::type* = 0);
257 template <
typename TT>
259 TT angle,
typename std::enable_if<R == C && R == 4, TT>::type* = 0);
261 template <
typename TT>
264 typename std::enable_if<R == C && R == 4, TT>::type* = 0);
266 template <
typename TT>
269 typename std::enable_if<R == C && R == 4, TT>::type* = 0);
272 friend std::ostream& operator<<(std::ostream& os,
275 const std::ios::fmtflags flags = os.flags();
276 const int prec = os.precision();
278 os.setf(std::ios::right, std::ios::adjustfield);
281 for (
size_t rowIndex = 0; rowIndex < R; ++rowIndex)
284 for (
size_t colIndex = 0; colIndex < C; ++colIndex)
285 os << std::setw(10) << matrix(rowIndex, colIndex) <<
" ";
286 os <<
"|" << std::endl;
297 #include <vmmlib/quaternion.hpp> 298 #include <vmmlib/vector.hpp> 304 template <
typename T>
307 return matrix_.
array[0];
310 template <
typename T>
313 return matrix_(0, 0) * matrix_(1, 1) - matrix_(0, 1) * matrix_(1, 0);
316 template <
typename T>
319 return m_(0, 0) * (m_(1, 1) * m_(2, 2) - m_(1, 2) * m_(2, 1)) +
320 m_(0, 1) * (m_(1, 2) * m_(2, 0) - m_(1, 0) * m_(2, 2)) +
321 m_(0, 2) * (m_(1, 0) * m_(2, 1) - m_(1, 1) * m_(2, 0));
324 template <
typename T>
327 return m(0, 3) * m(1, 2) * m(2, 1) * m(3, 0) -
328 m(0, 2) * m(1, 3) * m(2, 1) * m(3, 0) -
329 m(0, 3) * m(1, 1) * m(2, 2) * m(3, 0) +
330 m(0, 1) * m(1, 3) * m(2, 2) * m(3, 0) +
331 m(0, 2) * m(1, 1) * m(2, 3) * m(3, 0) -
332 m(0, 1) * m(1, 2) * m(2, 3) * m(3, 0) -
333 m(0, 3) * m(1, 2) * m(2, 0) * m(3, 1) +
334 m(0, 2) * m(1, 3) * m(2, 0) * m(3, 1) +
335 m(0, 3) * m(1, 0) * m(2, 2) * m(3, 1) -
336 m(0, 0) * m(1, 3) * m(2, 2) * m(3, 1) -
337 m(0, 2) * m(1, 0) * m(2, 3) * m(3, 1) +
338 m(0, 0) * m(1, 2) * m(2, 3) * m(3, 1) +
339 m(0, 3) * m(1, 1) * m(2, 0) * m(3, 2) -
340 m(0, 1) * m(1, 3) * m(2, 0) * m(3, 2) -
341 m(0, 3) * m(1, 0) * m(2, 1) * m(3, 2) +
342 m(0, 0) * m(1, 3) * m(2, 1) * m(3, 2) +
343 m(0, 1) * m(1, 0) * m(2, 3) * m(3, 2) -
344 m(0, 0) * m(1, 1) * m(2, 3) * m(3, 2) -
345 m(0, 2) * m(1, 1) * m(2, 0) * m(3, 3) +
346 m(0, 1) * m(1, 2) * m(2, 0) * m(3, 3) +
347 m(0, 2) * m(1, 0) * m(2, 1) * m(3, 3) -
348 m(0, 0) * m(1, 2) * m(2, 1) * m(3, 3) -
349 m(0, 1) * m(1, 0) * m(2, 2) * m(3, 3) +
350 m(0, 0) * m(1, 1) * m(2, 2) * m(3, 3);
353 template <
typename T>
359 template <
typename T>
362 const T det = computeDeterminant(m_);
363 if (std::abs(det) < std::numeric_limits<T>::epsilon())
365 std::vector<T>(4, std::numeric_limits<T>::quiet_NaN()));
368 m_.getAdjugate(inverse);
369 const T detinv = 1 / det;
370 inverse(0, 0) *= detinv;
371 inverse(0, 1) *= detinv;
372 inverse(1, 0) *= detinv;
373 inverse(1, 1) *= detinv;
377 template <
typename T>
383 inverse(0, 0) = m_(1, 1) * m_(2, 2) - m_(1, 2) * m_(2, 1);
384 inverse(0, 1) = m_(0, 2) * m_(2, 1) - m_(0, 1) * m_(2, 2);
385 inverse(0, 2) = m_(0, 1) * m_(1, 2) - m_(0, 2) * m_(1, 1);
386 inverse(1, 0) = m_(1, 2) * m_(2, 0) - m_(1, 0) * m_(2, 2);
387 inverse(1, 1) = m_(0, 0) * m_(2, 2) - m_(0, 2) * m_(2, 0);
388 inverse(1, 2) = m_(0, 2) * m_(1, 0) - m_(0, 0) * m_(1, 2);
389 inverse(2, 0) = m_(1, 0) * m_(2, 1) - m_(1, 1) * m_(2, 0);
390 inverse(2, 1) = m_(0, 1) * m_(2, 0) - m_(0, 0) * m_(2, 1);
391 inverse(2, 2) = m_(0, 0) * m_(1, 1) - m_(0, 1) * m_(1, 0);
393 const T determinant = m_(0, 0) * inverse(0, 0) + m_(0, 1) * inverse(1, 0) +
394 m_(0, 2) * inverse(2, 0);
396 if (std::abs(determinant) <= std::numeric_limits<T>::epsilon())
398 std::vector<T>(9, std::numeric_limits<T>::quiet_NaN()));
400 const T detinv =
static_cast<T
>(1.0) / determinant;
402 inverse(0, 0) *= detinv;
403 inverse(0, 1) *= detinv;
404 inverse(0, 2) *= detinv;
405 inverse(1, 0) *= detinv;
406 inverse(1, 1) *= detinv;
407 inverse(1, 2) *= detinv;
408 inverse(2, 0) *= detinv;
409 inverse(2, 1) *= detinv;
410 inverse(2, 2) *= detinv;
414 template <
typename T>
421 const T t1[6] = {array[2] * array[7] - array[6] * array[3],
422 array[2] * array[11] - array[10] * array[3],
423 array[2] * array[15] - array[14] * array[3],
424 array[6] * array[11] - array[10] * array[7],
425 array[6] * array[15] - array[14] * array[7],
426 array[10] * array[15] - array[14] * array[11]};
430 inv.
array[0] = array[5] * t1[5] - array[9] * t1[4] + array[13] * t1[3];
431 inv.
array[1] = array[9] * t1[2] - array[13] * t1[1] - array[1] * t1[5];
432 inv.
array[2] = array[13] * t1[0] - array[5] * t1[2] + array[1] * t1[4];
433 inv.
array[3] = array[5] * t1[1] - array[1] * t1[3] - array[9] * t1[0];
434 inv.
array[4] = array[8] * t1[4] - array[4] * t1[5] - array[12] * t1[3];
435 inv.
array[5] = array[0] * t1[5] - array[8] * t1[2] + array[12] * t1[1];
436 inv.
array[6] = array[4] * t1[2] - array[12] * t1[0] - array[0] * t1[4];
437 inv.
array[7] = array[0] * t1[3] - array[4] * t1[1] + array[8] * t1[0];
440 const T t2[6] = {array[0] * array[5] - array[4] * array[1],
441 array[0] * array[9] - array[8] * array[1],
442 array[0] * array[13] - array[12] * array[1],
443 array[4] * array[9] - array[8] * array[5],
444 array[4] * array[13] - array[12] * array[5],
445 array[8] * array[13] - array[12] * array[9]};
448 inv.
array[8] = array[7] * t2[5] - array[11] * t2[4] + array[15] * t2[3];
449 inv.
array[9] = array[11] * t2[2] - array[15] * t2[1] - array[3] * t2[5];
450 inv.
array[10] = array[15] * t2[0] - array[7] * t2[2] + array[3] * t2[4];
451 inv.
array[11] = array[7] * t2[1] - array[3] * t2[3] - array[11] * t2[0];
452 inv.
array[12] = array[10] * t2[4] - array[6] * t2[5] - array[14] * t2[3];
453 inv.
array[13] = array[2] * t2[5] - array[10] * t2[2] + array[14] * t2[1];
454 inv.
array[14] = array[6] * t2[2] - array[14] * t2[0] - array[2] * t2[4];
455 inv.
array[15] = array[2] * t2[3] - array[6] * t2[1] + array[10] * t2[0];
458 const T determinant = array[0] * inv.
array[0] + array[4] * inv.
array[1] +
459 array[8] * inv.
array[2] + array[12] * inv.
array[3];
462 const T detinv = T(1) / determinant;
463 for (
size_t i = 0; i != 16; ++i)
464 inv.
array[i] *= detinv;
468 template <
size_t R,
size_t C,
typename T>
471 throw std::runtime_error(
"Can't compute inverse of this matrix");
475 template <
size_t R,
size_t C,
typename T>
479 for (
size_t row = 0; row < R; ++row)
480 for (
size_t col = 0; col < C; ++col)
481 transposed(col, row) = matrix(row, col);
486 template <
size_t R,
size_t C,
typename T>
491 for (
size_t i = 0; i < R; ++i)
495 template <
size_t R,
size_t C,
typename T>
499 const T* to = std::min(end_, begin_ + R * C);
500 ::memcpy(
array, begin_, (to - begin_) *
sizeof(T));
503 template <
size_t R,
size_t C,
typename T>
509 template <
size_t R,
size_t C,
typename T>
510 template <
size_t P,
size_t Q>
516 template <
size_t R,
size_t C,
typename T>
520 typename std::enable_if<R == O + 1 && C == O + 1 && O == 3>::type*)
523 setTranslation(translation);
530 template <
size_t R,
size_t C,
typename T>
534 typename std::enable_if<R == S + 1 && C == S + 1 && S == 3>::type*)
538 const vector<3, T> s(vmml::normalize(vmml::cross(f, up)));
541 (*this)(0, 0) = s.x();
542 (*this)(0, 1) = s.y();
543 (*this)(0, 2) = s.z();
544 (*this)(1, 0) = u.x();
545 (*this)(1, 1) = u.y();
546 (*this)(1, 2) = u.z();
547 (*this)(2, 0) = -f.x();
548 (*this)(2, 1) = -f.y();
549 (*this)(2, 2) = -f.z();
550 (*this)(0, 3) = -vmml::dot(s, eye);
551 (*this)(1, 3) = -vmml::dot(u, eye);
552 (*this)(2, 3) = vmml::dot(f, eye);
556 template <
size_t R,
size_t C,
typename T>
559 if (rowIndex >= R || colIndex >= C)
560 throw std::runtime_error(
"matrix( row, column ) index out of bounds");
561 return array[colIndex * R + rowIndex];
564 template <
size_t R,
size_t C,
typename T>
567 if (rowIndex >= R || colIndex >= C)
568 throw std::runtime_error(
"matrix( row, column ) index out of bounds");
569 return array[colIndex * R + rowIndex];
572 template <
size_t R,
size_t C,
typename T>
575 for (
size_t i = 0; i < R * C; ++i)
581 template <
size_t R,
size_t C,
typename T>
587 template <
size_t R,
size_t C,
typename T>
589 const T tolerance)
const 591 for (
size_t i = 0; i < R * C; ++i)
592 if (std::abs(
array[i] - other.
array[i]) > tolerance)
597 template <
size_t R,
size_t C,
typename T>
600 ::memcpy(
array, source.
array, R * C *
sizeof(T));
604 template <
size_t R,
size_t C,
typename T>
605 template <
size_t P,
size_t Q>
608 const size_t minL = std::min(P, R);
609 const size_t minC = std::min(Q, C);
611 for (
size_t i = 0; i < minL; ++i)
612 for (
size_t j = 0; j < minC; ++j)
613 (*
this)(i, j) = source(i, j);
614 for (
size_t i = minL; i < R; ++i)
615 for (
size_t j = minC; j < C; ++j)
620 template <
size_t R,
size_t C,
typename T>
623 const size_t to = std::min(R * C, values.size());
624 ::memcpy(
array, values.data(), to *
sizeof(T));
628 ::memset(
array + to, 0, (R * C - to) *
sizeof(T));
630 ::bzero(
array + to, (R * C - to) *
sizeof(T));
635 template <
size_t R,
size_t C,
typename T>
646 for (
size_t rowIndex = 0; rowIndex < R; ++rowIndex)
648 for (
size_t colIndex = 0; colIndex < C; ++colIndex)
650 T& component = (*this)(rowIndex, colIndex);
651 component =
static_cast<T
>(0.0);
652 for (
size_t p = 0; p < P; p++)
653 component += left(rowIndex, p) * right(p, colIndex);
659 template <
size_t R,
size_t C,
typename T>
664 return result.
multiply(*
this, other);
667 template <
size_t R,
size_t C,
typename T>
668 template <
size_t O,
size_t P,
typename>
676 template <
size_t R,
size_t C,
typename T>
682 for (
size_t i = 0; i < R; ++i)
685 for (
size_t j = 0; j < C; ++j)
686 tmp += (*
this)(i, j) * vec(j);
692 template <
size_t R,
size_t C,
typename T>
696 for (
size_t i = 0; i < R * C; ++i)
701 template <
size_t R,
size_t C,
typename T>
705 throw std::runtime_error(
"getColumn() - index out of bounds.");
707 ::memcpy(&column.
array[0], &
array[R * index], R *
sizeof(T));
711 template <
size_t R,
size_t C,
typename T>
715 throw std::runtime_error(
"setColumn() - index out of bounds.");
716 memcpy(
array + R * index, column.
array, R *
sizeof(T));
719 template <
size_t R,
size_t C,
typename T>
723 throw std::runtime_error(
"getRow() - index out of bounds.");
726 for (
size_t colIndex = 0; colIndex < C; ++colIndex)
727 row(colIndex) = (*this)(index, colIndex);
731 template <
size_t R,
size_t C,
typename T>
735 throw std::runtime_error(
"setRow() - index out of bounds.");
737 for (
size_t colIndex = 0; colIndex < C; ++colIndex)
738 (*
this)(rowIndex, colIndex) = row(colIndex);
741 template <
size_t R,
size_t C,
typename T>
750 template <
size_t R,
size_t C,
typename T>
753 for (
size_t i = 0; i < R * C; ++i)
757 template <
size_t R,
size_t C,
typename T>
766 template <
size_t R,
size_t C,
typename T>
769 for (
size_t i = 0; i < R * C; ++i)
773 template <
size_t R,
size_t C,
typename T>
774 template <
size_t O,
size_t P>
776 size_t rowOffset,
size_t colOffset,
777 typename std::enable_if<O <= R && P <= C>::type*)
const 780 if (O + rowOffset > R || P + colOffset > C)
781 throw std::runtime_error(
"index out of bounds.");
783 for (
size_t row = 0; row < O; ++row)
784 for (
size_t col = 0; col < P; ++col)
785 result(row, col) = (*this)(rowOffset + row, colOffset + col);
790 template <
size_t R,
size_t C,
typename T>
791 template <
size_t O,
size_t P>
795 for (
size_t row = 0; row < O; ++row)
796 for (
size_t col = 0; col < P; ++col)
797 (*
this)(rowOffset + row, colOffset + col) = sub_matrix(row, col);
801 template <
size_t R,
size_t C,
typename T>
804 return computeInverse(*
this);
807 template <
size_t R,
size_t C,
typename T>
808 template <
size_t O,
size_t P>
809 typename std::enable_if<O == P && R == C && O == R && R >= 2>::type*
813 adjugate = transpose(adjugate);
817 template <
size_t R,
size_t C,
typename T>
818 template <
size_t O,
size_t P>
819 typename std::enable_if<O == P && R == C && O == R && R >= 2>::type*
822 Matrix<R - 1, C - 1, T> minor_;
824 const size_t _negate = 1u;
825 for (
size_t rowIndex = 0; rowIndex < R; ++rowIndex)
826 for (
size_t colIndex = 0; colIndex < C; ++colIndex)
827 if ((rowIndex + colIndex) & _negate)
828 cofactors(rowIndex, colIndex) =
829 -getMinor(minor_, rowIndex, colIndex);
831 cofactors(rowIndex, colIndex) =
832 getMinor(minor_, rowIndex, colIndex);
837 template <
size_t R,
size_t C,
typename T>
838 template <
size_t O,
size_t P>
841 typename std::enable_if<O == R - 1 && P == C - 1 && R == C &&
842 R >= 2>::type*)
const 844 size_t rowOffset = 0;
845 size_t colOffset = 0;
846 for (
size_t rowIndex = 0; rowIndex < R; ++rowIndex)
848 if (rowIndex == row_to_cut)
852 for (
size_t colIndex = 0; colIndex < R; ++colIndex)
854 if (colIndex == col_to_cut)
857 minor_(rowIndex + rowOffset, colIndex + colOffset) =
858 (*this)(rowIndex, colIndex);
863 return computeDeterminant(minor_);
866 template <
size_t R,
size_t C,
typename T>
867 template <
typename TT>
869 const TT angle_,
typename std::enable_if<R == C && R == 4, TT>::type*)
871 const T angle =
static_cast<T
>(angle_);
872 const T sine = std::sin(angle);
873 const T cosine = std::cos(angle);
896 template <
size_t R,
size_t C,
typename T>
897 template <
typename TT>
899 const TT angle_,
typename std::enable_if<R == C && R == 4, TT>::type*)
901 const T angle =
static_cast<T
>(angle_);
902 const T sine = std::sin(angle);
903 const T cosine = std::cos(angle);
926 template <
size_t R,
size_t C,
typename T>
927 template <
typename TT>
929 const TT angle_,
typename std::enable_if<R == C && R == 4, TT>::type*)
931 const T angle =
static_cast<T
>(angle_);
932 const T sine = std::sin(angle);
933 const T cosine = std::cos(angle);
956 template <
size_t R,
size_t C,
typename T>
957 template <
typename TT>
959 const TT angle_,
typename std::enable_if<R == C && R == 4, TT>::type*)
961 const T angle =
static_cast<T
>(angle_);
962 const T sine = std::sin(angle);
963 const T cosine = std::cos(angle);
986 template <
size_t R,
size_t C,
typename T>
987 template <
typename TT>
989 const TT angle_,
typename std::enable_if<R == C && R == 4, TT>::type*)
991 const T angle =
static_cast<T
>(angle_);
992 const T sine = std::sin(angle);
993 const T cosine = std::cos(angle);
1016 template <
size_t R,
size_t C,
typename T>
1017 template <
typename TT>
1019 const TT angle_,
typename std::enable_if<R == C && R == 4, TT>::type*)
1021 const T angle =
static_cast<T
>(angle_);
1022 const T sine = std::sin(angle);
1023 const T cosine = std::cos(angle);
1041 array[13] = tmp * -sine +
array[13] * cosine;
1046 template <
size_t R,
size_t C,
typename T>
1047 template <
typename TT>
1050 typename std::enable_if<R == C && R == 4, TT>::type*)
1052 array[0] *= scale_[0];
1053 array[1] *= scale_[0];
1054 array[2] *= scale_[0];
1055 array[3] *= scale_[0];
1056 array[4] *= scale_[1];
1057 array[5] *= scale_[1];
1058 array[6] *= scale_[1];
1059 array[7] *= scale_[1];
1060 array[8] *= scale_[2];
1061 array[9] *= scale_[2];
1062 array[10] *= scale_[2];
1063 array[11] *= scale_[2];
1067 template <
size_t R,
size_t C,
typename T>
1068 template <
typename TT>
1071 typename std::enable_if<R == C && R == 4, TT>::type*)
1073 array[12] *=
static_cast<T
>(scale_[0]);
1074 array[13] *=
static_cast<T
>(scale_[1]);
1075 array[14] *=
static_cast<T
>(scale_[2]);
1079 template <
size_t R,
size_t C,
typename T>
1083 for (
size_t i = 0; i < C - 1; ++i)
1084 array[i + R * (C - 1)] = trans[i];
1088 template <
size_t R,
size_t C,
typename T>
1092 for (
size_t i = 0; i < C - 1; ++i)
1093 result[i] =
array[i + R * (C - 1)];
1097 template <
size_t R,
size_t C,
typename T>
1101 typename std::enable_if<R == S + 1 && C == S + 1 && S == 3>::type*)
const 1110 lookAt = eye + lookAt;
Matrix< O, P, T > getSubMatrix(size_t rowOffset, size_t colOffset, typename std::enable_if< O<=R &&P<=C >::type *=0) const
Matrix< R, P, T > operator*(const Matrix< C, P, T > &other) const
Matrix operator+(const Matrix &other) const
Element-wise addition of two matrices.
bool operator==(const Matrix &other) const
Matrix< R, C, T > & operator*=(const Matrix< O, P, T > &right)
Multiply two square matrices.
Matrix()
Construct a zero-initialized matrix.
T array[R *C]
column by column storage
Matrix operator-(const Matrix &other) const
Element-wise substraction of two matrices.
bool equals(const Matrix &other, T tolerance=std::numeric_limits< T >::epsilon()) const
void operator-=(const Matrix &other)
Element-wise substraction of two matrices.
T & operator()(size_t rowIndex, size_t colIndex)
Matrix< 3, 3, T > getRotationMatrix() const
bool operator!=(const Matrix &other) const
Matrix< R, C, T > & multiply(const Matrix< R, P, T > &left, const Matrix< P, C, T > &right)
Set this to the product of the two matrices (left_RxP * right_PxC)
void operator+=(const Matrix &other)
Element-wise addition of two matrices.
Matrix with R rows and C columns of element type T.
std::enable_if< O<=R &&P<=C >::type *setSubMatrix(const Matrix< O, P, T > &sub_matrix, size_t rowOffset, size_t colOffset);const Matrix &operator=(const Matrix< R, C, T > &source_);template< size_t P, size_t Q > const Matrix &operator=(const Matrix< P, Q, T > &source_);void operator=(const std::vector< T > &data);Matrix< R, C, T > operator-() const ;vector< R, T > getColumn(size_t columnIndex) const ;void setColumn(size_t index, const vector< R, T > &column);vector< C, T > getRow(size_t index) const ;void setRow(size_t index, const vector< C, T > &row);vector< C-1, T > getTranslation() const ;Matrix< R, C, T > &setTranslation(const vector< C-1, T > &t);template< size_t S > void getLookAt(vector< S, T > &eye, vector< S, T > &lookAt, vector< S, T > &up, typename std::enable_if< R==S+1 &&C==S+1 &&S==3 >::type *=0) const ;Matrix< R, C, T > inverse() const ;template< size_t O, size_t P > typename std::enable_if< O==P &&R==C &&O==R &&R >=2 >::type *getAdjugate(Matrix< O, P, T > &adjugate) const ;template< size_t O, size_t P > typename std::enable_if< O==P &&R==C &&O==R &&R >=2 >::type * getCofactors(Matrix< O, P, T > &cofactors) const
Set the sub matrix of size OxP at the given start indices.