dMatrix::dMatrix (const dMatrix & transformMatrix, const dVector & scale, const dMatrix & stretchAxis) { dMatrix scaledAxis; scaledAxis[0] = stretchAxis[0].Scale (scale[0]); scaledAxis[1] = stretchAxis[1].Scale (scale[1]); scaledAxis[2] = stretchAxis[2].Scale (scale[2]); scaledAxis[3] = stretchAxis[3]; *this = stretchAxis.Transpose() * scaledAxis * transformMatrix; }
//void dMatrix::PolarDecomposition (dMatrix& orthogonal, dMatrix& symetric) const void dMatrix::PolarDecomposition (dMatrix & transformMatrix, dVector & scale, dMatrix & stretchAxis, const dMatrix & initialStretchAxis) const { // a polar decomposition decompose matrix A = O * S // where S = sqrt (transpose (L) * L) // calculate transpose (L) * L dMatrix LL ((*this) * Transpose()); // check is this si a pure uniformScale * rotation * translation dFloat det2 = (LL[0][0] + LL[1][1] + LL[2][2]) * (1.0f / 3.0f); dFloat invdet2 = 1.0f / det2; dMatrix pureRotation (LL); pureRotation[0] = pureRotation[0].Scale (invdet2); pureRotation[1] = pureRotation[1].Scale (invdet2); pureRotation[2] = pureRotation[2].Scale (invdet2); //dFloat soureSign = ((*this)[0] * (*this)[1]) % (*this)[2]; dFloat sign = ((((*this)[0] * (*this)[1]) % (*this)[2]) > 0.0f) ? 1.0f : -1.0f; dFloat det = (pureRotation[0] * pureRotation[1]) % pureRotation[2]; if (dAbs (det - 1.0f) < 1.e-5f) { // this is a pure scale * rotation * translation det = sign * dSqrt (det2); scale[0] = det; scale[1] = det; scale[2] = det; scale[3] = 1.0f; det = 1.0f / det; transformMatrix.m_front = m_front.Scale (det); transformMatrix.m_up = m_up.Scale (det); transformMatrix.m_right = m_right.Scale (det); transformMatrix[0][3] = 0.0f; transformMatrix[1][3] = 0.0f; transformMatrix[2][3] = 0.0f; transformMatrix.m_posit = m_posit; stretchAxis = dGetIdentityMatrix(); } else { stretchAxis = LL.JacobiDiagonalization (scale, initialStretchAxis); // I need to deal with buy seeing of some of the Scale are duplicated // do this later (maybe by a given rotation around the non uniform axis but I do not know if it will work) // for now just us the matrix scale[0] = sign * dSqrt (scale[0]); scale[1] = sign * dSqrt (scale[1]); scale[2] = sign * dSqrt (scale[2]); scale[3] = 1.0f; dMatrix scaledAxis; scaledAxis[0] = stretchAxis[0].Scale (1.0f / scale[0]); scaledAxis[1] = stretchAxis[1].Scale (1.0f / scale[1]); scaledAxis[2] = stretchAxis[2].Scale (1.0f / scale[2]); scaledAxis[3] = stretchAxis[3]; dMatrix symetricInv (stretchAxis.Transpose() * scaledAxis); transformMatrix = symetricInv * (*this); transformMatrix.m_posit = m_posit; } }