/////////////////////////////////////////////////////////////////////////////////////////////////// // OpenGL Mathematics Copyright (c) 2005 - 2010 G-Truc Creation (www.g-truc.net) /////////////////////////////////////////////////////////////////////////////////////////////////// // Created : 2007-02-21 // Updated : 2007-02-21 // Licence : This source is under MIT License // File : glm/gtx/matx.inl /////////////////////////////////////////////////////////////////////////////////////////////////// #include #include namespace glm{ namespace detail{ template const typename _xmatxGTX::size_type _xmatxGTX::value_size = N; ////////////////////////////////////////////////////////////// // _xmatxGTX constructors template inline _xmatxGTX::_xmatxGTX() { for(int i = 0; i < N; ++i) this->value[i][i] = T(0); } template inline _xmatxGTX::_xmatxGTX(const T f) { for(int i = 0; i < N; ++i) this->value[i][i] = f; } ////////////////////////////////////////////////////////////// // _xmatxGTX operators // This function shouldn't required but it seems that VC7.1 have an optimisation bug if this operator wasn't declared template inline _xmatxGTX& _xmatxGTX::operator= (const _xmatxGTX& m) { //memcpy could be faster //memcpy(&this->value, &m.value, 16 * sizeof(T)); for(int i = 0; i < N; ++i) this->value[i] = m[i]; return *this; } template inline _xmatxGTX& _xmatxGTX::operator+= (const T s) { for(int i = 0; i < N; ++i) this->value[i] += s; return *this; } template inline _xmatxGTX& _xmatxGTX::operator+= (const _xmatxGTX& m) { for(int i = 0; i < N; ++i) this->value[i] += m[i]; return *this; } template inline _xmatxGTX& _xmatxGTX::operator-= (const T s) { for(int i = 0; i < N; ++i) this->value[i] -= s; return *this; } template inline _xmatxGTX& _xmatxGTX::operator-= (const _xmatxGTX& m) { for(int i = 0; i < N; ++i) this->value[i] -= m[i]; return *this; } template inline _xmatxGTX& _xmatxGTX::operator*= (const T s) { for(int i = 0; i < N; ++i) this->value[i] *= s; return *this; } template inline _xmatxGTX& _xmatxGTX::operator*= (const _xmatxGTX& m) { return (*this = *this * m); } template inline _xmatxGTX& _xmatxGTX::operator/= (const T s) { for(int i = 0; i < N; ++i) this->value[i] /= s; return *this; } template inline _xmatxGTX& _xmatxGTX::operator/= (const _xmatxGTX& m) { return (*this = *this / m); } template inline _xmatxGTX& _xmatxGTX::operator-- () { for(int i = 0; i < N; ++i) --this->value[i]; return *this; } template inline _xmatxGTX& _xmatxGTX::operator++ () { for(int i = 0; i < N; ++i) ++this->value[i]; return *this; } // Private functions template inline _xmatxGTX _xmatxGTX::_inverse() const { _xmatxGTX Result = *this; int ColIndex[N]; int RowIndex[N]; bool Pivoted[N]; memset(ColIndex, 0, N * sizeof(int)); memset(RowIndex, 0, N * sizeof(int)); memset(Pivoted, 0, N * sizeof(bool)); int iRow = 0, iCol = 0; // elimination by full pivoting for(int i0 = 0; i0 < N; i0++) { // search matrix (excluding pivoted rows) for maximum absolute entry T fMax = T(0); for(int i1 = 0; i1 < N; i1++) { if(Pivoted[i1]) continue; for(int i2 = 0; i2 < N; i2++) { if(Pivoted[i2]) continue; T Abs = abs(Result[i1][i2]); if(Abs > fMax) { fMax = Abs; iRow = i1; iCol = i2; } } } if(fMax == T(0)) { return _xmatxGTX(1.0f); // Error } Pivoted[iCol] = true; // swap rows so that A[iCol][iCol] contains the pivot entry if(iRow != iCol) { _xvecxGTX Row = rowGTX(Result, iRow); _xvecxGTX Col = rowGTX(Result, iCol); rowGTX(Result, iRow, Col); rowGTX(Result, iCol, Row); } // keep track of the permutations of the rows RowIndex[i0] = iRow; ColIndex[i0] = iCol; // scale the row so that the pivot entry is 1 T fInv = T(1) / Result[iCol][iCol]; Result[iCol][iCol] = T(1); for(int i2 = 0; i2 < N; i2++) Result[iCol][i2] *= fInv; // zero out the pivot column locations in the other rows for(int i1 = 0; i1 < N; ++i1) { if(i1 == iCol) continue; T Tmp = Result[i1][iCol]; Result[i1][iCol] = T(0); for(int i2 = 0; i2 < N; i2++) Result[i1][i2] -= Result[iCol][i2] * Tmp; } } // reorder rows so that A[][] stores the inverse of the original matrix for(int i1 = N-1; i1 >= 0; --i1) { if(RowIndex[i1] == ColIndex[i1]) continue; for(int i2 = 0; i2 < N; ++i2) std::swap(Result[i2][RowIndex[i1]], Result[i2][ColIndex[i1]]); } return Result; } // Binary operators template inline _xmatxGTX operator+ (const _xmatxGTX& m, const T s) { _xmatxGTX result; for(int i = 0; i < N; ++i) result[i] = m[i] + s; return result; } template inline _xmatxGTX operator+ (const T s, const _xmatxGTX& m) { _xmatxGTX result; for(int i = 0; i < N; ++i) result[i] = s + m[i]; return result; } /* template inline tvec4 operator+ (const _xmatxGTX& m, const tvec4& v) { } template inline tvec4 operator+ (const tvec4& v, const _xmatxGTX& m) { } */ template inline _xmatxGTX operator+ (const _xmatxGTX& m1, const _xmatxGTX& m2) { _xmatxGTX result; for(int i = 0; i < N; ++i) result[i] = m1[i] + m2[i]; return result; } template inline _xmatxGTX operator- (const _xmatxGTX& m, const T s) { _xmatxGTX result; for(int i = 0; i < N; ++i) result[i] = m[i] - s; return result; } template inline _xmatxGTX operator- (const T s, const _xmatxGTX& m) { _xmatxGTX result; for(int i = 0; i < N; ++i) result[i] = s - m[i]; return result; } /* template inline tvec4 operator- (const _xmatxGTX& m, const tvec4& v) { } template inline tvec4 operator- (const tvec4& v, const _xmatxGTX& m) { } */ template inline _xmatxGTX operator- (const _xmatxGTX& m1, const _xmatxGTX& m2) { _xmatxGTX result; for(int i = 0; i < N; ++i) result[i] = m1[i] - m2[i]; return result; } template inline _xmatxGTX operator* (const _xmatxGTX& m, const T s) { _xmatxGTX result; for(int i = 0; i < N; ++i) result[i] = m[i] * s; return result; } template inline _xmatxGTX operator* (const T s, const _xmatxGTX& m) { _xmatxGTX result; for(int i = 0; i < N; ++i) result[i] = s * m[i]; return result; } template inline _xvecxGTX operator* (const _xmatxGTX& m, const _xvecxGTX& v) { _xvecxGTX result(T(0)); for(int j = 0; j < N; ++j) for(int i = 0; i < N; ++i) result[j] += m[i][j] * v[i]; return result; } template inline _xvecxGTX operator* (const _xvecxGTX& v, const _xmatxGTX& m) { _xvecxGTX result(T(0)); for(int j = 0; j < N; ++j) for(int i = 0; i < N; ++i) result[j] += m[j][i] * v[i]; return result; } template inline _xmatxGTX operator* (const _xmatxGTX& m1, const _xmatxGTX& m2) { _xmatxGTX Result(T(0)); for(int k = 0; k < N; ++k) for(int j = 0; j < N; ++j) for(int i = 0; i < N; ++i) Result[k][j] += m1[i][j] * m2[k][i]; return Result; } template inline _xmatxGTX operator/ (const _xmatxGTX& m, const T s) { _xmatxGTX result; for(int i = 0; i < N; ++i) result[i] = m[i] / s; return result; } template inline _xmatxGTX operator/ (const T s, const _xmatxGTX& m) { _xmatxGTX result; for(int i = 0; i < N; ++i) result[i] = s / m[i]; return result; } template inline _xvecxGTX operator/ (const _xmatxGTX& m, const _xvecxGTX& v) { return m._inverse() * v; } template inline _xvecxGTX operator/ (const _xvecxGTX& v, const _xmatxGTX& m) { return v * m._inverse(); } template inline _xmatxGTX operator/ (const _xmatxGTX& m1, const _xmatxGTX& m2) { return m1 * m2._inverse(); } // Unary constant operators template inline const _xmatxGTX operator- (const _xmatxGTX& m) { _xmatxGTX result; for(int i = 0; i < N; ++i) result[i] = -m[i]; return result; } template inline const _xmatxGTX operator++ (const _xmatxGTX& m, int) { _xmatxGTX result; for(int i = 0; i < N; ++i) result[i] = m[i] + T(1); return result; } template inline const _xmatxGTX operator-- (const _xmatxGTX& m, int) { _xmatxGTX result; for(int i = 0; i < N; ++i) result[i] = m[i] - T(1); return result; } }//namespace detail // Matrix Functions template inline detail::_xmatxGTX matrixCompMultGTX(const detail::_xmatxGTX& x, const detail::_xmatxGTX& y) { detail::_xmatxGTX result; for(int j = 0; j < N; ++j) for(int i = 0; i < N; ++i) result[j][i] = x[j][i] * y[j][i]; return result; } template inline detail::_xmatxGTX outerProductGTX(const detail::_xvecxGTX& c, const detail::_xvecxGTX& r) { detail::_xmatxGTX result; for(int j = 0; j < N; ++j) for(int i = 0; i < N; ++i) result[j][i] = c[i] * r[j]; return result; } template inline detail::_xmatxGTX transposeGTX(const detail::_xmatxGTX& m) { detail::_xmatxGTX result; for(int j = 0; j < N; ++j) for(int i = 0; i < N; ++i) result[j][i] = m[i][j]; return result; } template inline T determinantGTX(const detail::_xmatxGTX& m) { } template inline detail::_xmatxGTX inverseTransposeGTX(const detail::_xmatxGTX& m) { } template inline void columnGTX(detail::_xmatxGTX& m, int ColIndex, const detail::_xvecxGTX& v) { m[ColIndex] = v; } template inline void rowGTX(detail::_xmatxGTX& m, int RowIndex, const detail::_xvecxGTX& v) { for(int i = 0; i < N; ++i) m[i][RowIndex] = v[i]; } template inline detail::_xvecxGTX columnGTX(const detail::_xmatxGTX& m, int ColIndex) { return m[ColIndex]; } template inline detail::_xvecxGTX rowGTX(const detail::_xmatxGTX& m, int RowIndex) { detail::_xvecxGTX v; for(int i = 0; i < N; ++i) v[i] = m[i][RowIndex]; return v; } } //namespace glm