Added Identity Matrix optimization

Former-commit-id: c426c3098659f9cf74fd7da33cadabe38a158358
This commit is contained in:
Lynix 2013-05-30 02:58:20 +02:00
parent b3f60e90fd
commit 465a7c246d
2 changed files with 88 additions and 4 deletions

View File

@ -53,6 +53,7 @@ class NzMatrix4
NzMatrix4& InverseAffine(bool* succeeded = nullptr);
bool IsAffine() const;
bool IsIdentity() const;
NzMatrix4& MakeIdentity();
NzMatrix4& MakeLookAt(const NzVector3<T>& eye, const NzVector3<T>& target, const NzVector3<T>& up = NzVector3<T>::Up());
@ -117,10 +118,12 @@ class NzMatrix4
static NzMatrix4 Transform(const NzVector3<T>& translation, const NzQuaternion<T>& rotation, const NzVector3<T>& scale);
static NzMatrix4 Zero();
private:
T m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44;
mutable bool m_isIdentity;
};
template<typename T> std::ostream& operator<<(std::ostream& out, const NzMatrix4<T>& matrix);

View File

@ -57,6 +57,7 @@ NzMatrix4<T>& NzMatrix4<T>::ApplyScale(const NzVector3<T>& scale)
m31 *= scale.z;
m32 *= scale.z;
m33 *= scale.z;
m_isIdentity = false;
return *this;
}
@ -69,6 +70,9 @@ NzMatrix4<T>& NzMatrix4<T>::Concatenate(const NzMatrix4& matrix)
return ConcatenateAffine(matrix);
#endif
if (m_isIdentity)
return Set(matrix);
return Set(m11*matrix.m11 + m12*matrix.m21 + m13*matrix.m31 + m14*matrix.m41,
m11*matrix.m12 + m12*matrix.m22 + m13*matrix.m32 + m14*matrix.m42,
m11*matrix.m13 + m12*matrix.m23 + m13*matrix.m33 + m14*matrix.m43,
@ -107,6 +111,9 @@ NzMatrix4<T>& NzMatrix4<T>::ConcatenateAffine(const NzMatrix4& matrix)
}
#endif
if (m_isIdentity)
return Set(matrix);
return Set(m11*matrix.m11 + m12*matrix.m21 + m13*matrix.m31,
m11*matrix.m12 + m12*matrix.m22 + m13*matrix.m32,
m11*matrix.m13 + m12*matrix.m23 + m13*matrix.m33,
@ -131,6 +138,9 @@ NzMatrix4<T>& NzMatrix4<T>::ConcatenateAffine(const NzMatrix4& matrix)
template<typename T>
T NzMatrix4<T>::GetDeterminant() const
{
if (m_isIdentity)
return F(1.0);
T A = m22*(m33*m44 - m43*m34) - m32*(m23*m44 - m43*m24) + m42*(m23*m34 - m33*m24);
T B = m12*(m33*m44 - m43*m34) - m32*(m13*m44 - m43*m14) + m42*(m13*m34 - m33*m14);
T C = m12*(m23*m44 - m43*m24) - m22*(m13*m44 - m43*m14) + m42*(m13*m24 - m23*m14);
@ -142,6 +152,9 @@ T NzMatrix4<T>::GetDeterminant() const
template<typename T>
T NzMatrix4<T>::GetDeterminantAffine() const
{
if (m_isIdentity)
return F(1.0);
T A = m22*m33 - m32*m23;
T B = m12*m33 - m32*m13;
T C = m12*m23 - m22*m13;
@ -161,6 +174,12 @@ bool NzMatrix4<T>::GetInverse(NzMatrix4* dest) const
}
#endif
if (m_isIdentity)
{
dest->MakeIdentity();
return true;
}
T det = GetDeterminant();
if (!NzNumberEquals(det, F(0.0)))
{
@ -310,6 +329,12 @@ bool NzMatrix4<T>::GetInverseAffine(NzMatrix4* dest) const
}
#endif
if (m_isIdentity)
{
dest->MakeIdentity();
return true;
}
T det = GetDeterminantAffine();
if (!NzNumberEquals(det, F(0.0)))
{
@ -388,6 +413,9 @@ bool NzMatrix4<T>::GetInverseAffine(NzMatrix4* dest) const
template<typename T>
NzQuaternion<T> NzMatrix4<T>::GetRotation() const
{
if (m_isIdentity)
return NzQuaternion<T>::Identity();
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
NzQuaternion<T> quat;
@ -437,6 +465,9 @@ NzQuaternion<T> NzMatrix4<T>::GetRotation() const
template<typename T>
NzVector3<T> NzMatrix4<T>::GetScale() const
{
if (m_isIdentity)
return NzVector3<T>::Unit();
return NzVector3<T>(std::sqrt(m11*m11 + m21*m21 + m31*m31),
std::sqrt(m12*m12 + m22*m22 + m32*m32),
std::sqrt(m13*m13 + m23*m23 + m33*m33));
@ -455,17 +486,25 @@ void NzMatrix4<T>::GetTransposed(NzMatrix4* dest) const
m12, m22, m32, m42,
m13, m23, m33, m43,
m14, m24, m34, m44);
dest->m_isIdentity = m_isIdentity;
}
template<typename T>
bool NzMatrix4<T>::HasNegativeScale() const
{
if (m_isIdentity)
return false;
return GetDeterminant() < F(0.0);
}
template<typename T>
bool NzMatrix4<T>::HasScale() const
{
if (m_isIdentity)
return false;
T t = m11*m11 + m21*m21 + m31*m31;
if (!NzNumberEquals(t, F(1.0)))
return true;
@ -510,6 +549,24 @@ bool NzMatrix4<T>::IsAffine() const
NzNumberEquals(m44, F(1.0));
}
template<typename T>
bool NzMatrix4<T>::IsIdentity() const
{
if (m_isIdentity)
return true;
if (NzNumberEquals(m11, F(1.0)) && NzNumberEquals(m12, F(0.0)) && NzNumberEquals(m13, F(0.0)) && NzNumberEquals(m14, F(0.0)) &&
NzNumberEquals(m11, F(0.0)) && NzNumberEquals(m12, F(1.0)) && NzNumberEquals(m13, F(0.0)) && NzNumberEquals(m14, F(0.0)) &&
NzNumberEquals(m11, F(0.0)) && NzNumberEquals(m12, F(0.0)) && NzNumberEquals(m13, F(1.0)) && NzNumberEquals(m14, F(0.0)) &&
NzNumberEquals(m11, F(0.0)) && NzNumberEquals(m12, F(0.0)) && NzNumberEquals(m13, F(0.0)) && NzNumberEquals(m14, F(1.0)))
{
m_isIdentity = true;
return true;
}
return false;
}
template<typename T>
NzMatrix4<T>& NzMatrix4<T>::MakeIdentity()
{
@ -518,6 +575,8 @@ NzMatrix4<T>& NzMatrix4<T>::MakeIdentity()
F(0.0), F(0.0), F(1.0), F(0.0),
F(0.0), F(0.0), F(0.0), F(1.0));
m_isIdentity = true;
return *this;
}
@ -582,6 +641,7 @@ NzMatrix4<T>& NzMatrix4<T>::MakeRotation(const NzQuaternion<T>& rotation)
m42 = F(0.0);
m43 = F(0.0);
m44 = F(1.0);
m_isIdentity = false;
return *this;
}
@ -621,6 +681,8 @@ NzMatrix4<T>& NzMatrix4<T>::MakeTransform(const NzVector3<T>& translation, const
m34 = F(0.0);
m44 = F(1.0);
// Pas besoin de mettre à jour l'identité (Déjà fait par Set*)
return *this;
}
@ -668,6 +730,7 @@ NzMatrix4<T>& NzMatrix4<T>::Set(T r11, T r12, T r13, T r14,
m42 = r42;
m43 = r43;
m44 = r44;
m_isIdentity = false;
return *this;
}
@ -677,6 +740,7 @@ NzMatrix4<T>& NzMatrix4<T>::Set(const T matrix[16])
{
// Ici nous sommes certains de la continuité des éléments en mémoire
std::memcpy(&m11, matrix, 16*sizeof(T));
m_isIdentity = false;
return *this;
}
@ -698,6 +762,8 @@ NzMatrix4<T>& NzMatrix4<T>::Set(const NzMatrix4<U>& matrix)
F(matrix.m31), F(matrix.m32), F(matrix.m33), F(matrix.m34),
F(matrix.m41), F(matrix.m42), F(matrix.m43), F(matrix.m44));
m_isIdentity = matrix.IsIdentity();
return *this;
}
@ -728,6 +794,7 @@ NzMatrix4<T>& NzMatrix4<T>::SetRotation(const NzQuaternion<T>& rotation)
m31 = txz + twy;
m32 = tyz - twx;
m33 = F(1.0) - (txx + tyy);
m_isIdentity = false;
return *this;
}
@ -738,6 +805,7 @@ NzMatrix4<T>& NzMatrix4<T>::SetScale(const NzVector3<T>& scale)
m11 = scale.x;
m22 = scale.y;
m33 = scale.z;
m_isIdentity = false;
return *this;
}
@ -748,6 +816,7 @@ NzMatrix4<T>& NzMatrix4<T>::SetTranslation(const NzVector3<T>& translation)
m41 = translation.x;
m42 = translation.y;
m43 = translation.z;
m_isIdentity = false;
return *this;
}
@ -765,6 +834,9 @@ NzString NzMatrix4<T>::ToString() const
template<typename T>
NzVector2<T> NzMatrix4<T>::Transform(const NzVector2<T>& vector, T z, T w) const
{
if (m_isIdentity)
return vector;
return NzVector2<T>(m11*vector.x + m21*vector.y + m31*z + m41*w,
m12*vector.x + m22*vector.y + m32*z + m42*w);
}
@ -772,6 +844,9 @@ NzVector2<T> NzMatrix4<T>::Transform(const NzVector2<T>& vector, T z, T w) const
template<typename T>
NzVector3<T> NzMatrix4<T>::Transform(const NzVector3<T>& vector, T w) const
{
if (m_isIdentity)
return vector;
return NzVector3<T>(m11*vector.x + m21*vector.y + m31*vector.z + m41*w,
m12*vector.x + m22*vector.y + m32*vector.z + m42*w,
m13*vector.x + m23*vector.y + m33*vector.z + m43*w);
@ -780,6 +855,9 @@ NzVector3<T> NzMatrix4<T>::Transform(const NzVector3<T>& vector, T w) const
template<typename T>
NzVector4<T> NzMatrix4<T>::Transform(const NzVector4<T>& vector) const
{
if (m_isIdentity)
return vector;
return NzVector4<T>(m11*vector.x + m21*vector.y + m31*vector.z + m41*vector.w,
m12*vector.x + m22*vector.y + m32*vector.z + m42*vector.w,
m13*vector.x + m23*vector.y + m33*vector.z + m43*vector.w,
@ -802,6 +880,7 @@ NzMatrix4<T>& NzMatrix4<T>::Transpose()
template<typename T>
NzMatrix4<T>::operator T*()
{
m_isIdentity = false;
return &m11;
}
@ -824,6 +903,7 @@ T& NzMatrix4<T>::operator()(unsigned int x, unsigned int y)
}
#endif
m_isIdentity = false;
return (&m11)[y*4+x];
}
@ -890,6 +970,7 @@ NzMatrix4<T>& NzMatrix4<T>::operator*=(const NzMatrix4& matrix)
template<typename T>
NzMatrix4<T>& NzMatrix4<T>::operator*=(T scalar)
{
m_isIdentity = false;
for (unsigned int i = 0; i < 16; ++i)
(&m11)[i] *= scalar;