+ template<typename S>
+ SGMatrix& preMultTranslate(const SGVec3<S>& t)
+ {
+ for (unsigned i = 0; i < 3; ++i) {
+ T tmp = T(t(i));
+ if (tmp == 0)
+ continue;
+ (*this)(i,0) += tmp*(*this)(3,0);
+ (*this)(i,1) += tmp*(*this)(3,1);
+ (*this)(i,2) += tmp*(*this)(3,2);
+ (*this)(i,3) += tmp*(*this)(3,3);
+ }
+ return *this;
+ }
+ template<typename S>
+ SGMatrix& postMultTranslate(const SGVec3<S>& t)
+ {
+ SGVec4<T> col3((*this)(0,3), (*this)(1,3), (*this)(2,3), (*this)(3,3));
+ for (unsigned i = 0; i < SGMatrix<T>::nCols-1; ++i) {
+ SGVec4<T> tmp((*this)(0,i), (*this)(1,i), (*this)(2,i), (*this)(3,i));
+ col3 += T(t(i))*tmp;
+ }
+ (*this)(0,3) = col3(0); (*this)(1,3) = col3(1);
+ (*this)(2,3) = col3(2); (*this)(3,3) = col3(3);
+ return *this;
+ }
+
+ SGMatrix& preMultRotate(const SGQuat<T>& r)
+ {
+ for (unsigned i = 0; i < SGMatrix<T>::nCols; ++i) {
+ SGVec3<T> col((*this)(0,i), (*this)(1,i), (*this)(2,i));
+ col = r.transform(col);
+ (*this)(0,i) = col(0); (*this)(1,i) = col(1); (*this)(2,i) = col(2);
+ }
+ return *this;
+ }
+ SGMatrix& postMultRotate(const SGQuat<T>& r)
+ {
+ for (unsigned i = 0; i < SGMatrix<T>::nCols; ++i) {
+ SGVec3<T> col((*this)(i,0), (*this)(i,1), (*this)(i,2));
+ col = r.backTransform(col);
+ (*this)(i,0) = col(0); (*this)(i,1) = col(1); (*this)(i,2) = col(2);
+ }
+ return *this;
+ }
+