Implemented COW into NzMatrix4; Optimized NzString COW

This commit is contained in:
Lynix 2012-05-07 13:02:07 +02:00
parent 8c420b48c3
commit 45f3fc4e28
7 changed files with 509 additions and 219 deletions

View File

@ -56,18 +56,18 @@
// Active les tests de sécurité basés sur le code (Conseillé pour le développement) // Active les tests de sécurité basés sur le code (Conseillé pour le développement)
#define NAZARA_CORE_SAFE 1 #define NAZARA_CORE_SAFE 1
// Protége le noyau des accès concurrentiels // Protége le module des accès concurrentiels
#define NAZARA_CORE_THREADSAFE 1 #define NAZARA_CORE_THREADSAFE 1
#if NAZARA_CORE_THREADSAFE #if NAZARA_CORE_THREADSAFE
#define NAZARA_THREADSAFETY_APPLICATION 1 // NzApplication #define NAZARA_THREADSAFETY_BYTEARRAY 1 // NzByteArray (COW)
#define NAZARA_THREADSAFETY_CLOCK 0 // NzClock #define NAZARA_THREADSAFETY_CLOCK 0 // NzClock
#define NAZARA_THREADSAFETY_DIRECTORY 1 // NzDirectory #define NAZARA_THREADSAFETY_DIRECTORY 1 // NzDirectory
#define NAZARA_THREADSAFETY_DYNLIB 1 // NzDynLib #define NAZARA_THREADSAFETY_DYNLIB 1 // NzDynLib
#define NAZARA_THREADSAFETY_FILE 1 // NzFile #define NAZARA_THREADSAFETY_FILE 1 // NzFile
#define NAZARA_THREADSAFETY_HASHDIGEST 0 // NzHashDigest #define NAZARA_THREADSAFETY_HASHDIGEST 0 // NzHashDigest
#define NAZARA_THREADSAFETY_LOG 1 // NzLog #define NAZARA_THREADSAFETY_LOG 1 // NzLog
#define NAZARA_THREADSAFETY_STRING 1 // NzString #define NAZARA_THREADSAFETY_STRING 1 // NzString (COW)
#define NAZARA_THREADSAFETY_STRINGSTREAM 0 // NzStringStream #define NAZARA_THREADSAFETY_STRINGSTREAM 0 // NzStringStream
#endif #endif

View File

@ -6,6 +6,7 @@
#include <Nazara/Core/Config.hpp> #include <Nazara/Core/Config.hpp>
// Ces macros peuvent changer pour n'importe quel fichier qui l'utilise, dans une même unité de compilation
#undef NazaraLock #undef NazaraLock
#undef NazaraMutex #undef NazaraMutex
#undef NazaraMutexAttrib #undef NazaraMutexAttrib

View File

@ -39,4 +39,12 @@
// Active les tests de sécurité basés sur le code (Conseillé pour le développement) // Active les tests de sécurité basés sur le code (Conseillé pour le développement)
#define NAZARA_MATH_SAFE 1 #define NAZARA_MATH_SAFE 1
// Protége le module des accès concurrentiels
#define NAZARA_MATH_THREADSAFE 1
#if NAZARA_MATH_THREADSAFE
#define NAZARA_THREADSAFETY_MATRIX3 1 // NzMatrix3 (COW)
#define NAZARA_THREADSAFETY_MATRIX4 1 // NzMatrix4 (COW)
#endif
#endif // NAZARA_CONFIG_MATH_HPP #endif // NAZARA_CONFIG_MATH_HPP

View File

@ -24,10 +24,11 @@ template<typename T> class NzMatrix4
T r31, T r32, T r33, T r34, T r31, T r32, T r33, T r34,
T r41, T r42, T r43, T r44); T r41, T r42, T r43, T r44);
NzMatrix4(T matrix[16]); NzMatrix4(T matrix[16]);
//NzMatrix4(const NzMatrix3<T>& mat); //NzMatrix4(const NzMatrix3<T>& matrix);
template<typename U> explicit NzMatrix4(const NzMatrix4<U>& mat); template<typename U> explicit NzMatrix4(const NzMatrix4<U>& matrix);
NzMatrix4(const NzMatrix4& mat) = default; NzMatrix4(const NzMatrix4& matrix);
~NzMatrix4() = default; NzMatrix4(NzMatrix4&& matrix);
~NzMatrix4();
T GetDeterminant() const; T GetDeterminant() const;
NzMatrix4 GetInverse() const; NzMatrix4 GetInverse() const;
@ -44,9 +45,10 @@ template<typename T> class NzMatrix4
T r31, T r32, T r33, T r34, T r31, T r32, T r33, T r34,
T r41, T r42, T r43, T r44); T r41, T r42, T r43, T r44);
void Set(T matrix[16]); void Set(T matrix[16]);
//NzMatrix4(const NzMatrix3<T>& mat); //NzMatrix4(const NzMatrix3<T>& matrix);
void Set(const NzMatrix4& mat); void Set(const NzMatrix4& matrix);
template<typename U> void Set(const NzMatrix4<U>& mat); void Set(NzMatrix4&& matrix);
template<typename U> void Set(const NzMatrix4<U>& matrix);
void SetIdentity(); void SetIdentity();
void SetLookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up); void SetLookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up);
void SetPerspective(T angle, T ratio, T zNear, T zFar); void SetPerspective(T angle, T ratio, T zNear, T zFar);
@ -69,13 +71,16 @@ template<typename T> class NzMatrix4
T& operator()(unsigned int x, unsigned int y); T& operator()(unsigned int x, unsigned int y);
const T& operator()(unsigned int x, unsigned int y) const; const T& operator()(unsigned int x, unsigned int y) const;
NzMatrix4 operator*(const NzMatrix4& mat) const; NzMatrix4& operator=(const NzMatrix4& matrix);
NzMatrix4& operator=(NzMatrix4&& matrix);
NzMatrix4 operator*(const NzMatrix4& matrix) const;
NzVector2<T> operator*(const NzVector2<T>& vector) const; NzVector2<T> operator*(const NzVector2<T>& vector) const;
NzVector3<T> operator*(const NzVector3<T>& vector) const; NzVector3<T> operator*(const NzVector3<T>& vector) const;
NzVector4<T> operator*(const NzVector4<T>& vector) const; NzVector4<T> operator*(const NzVector4<T>& vector) const;
NzMatrix4 operator*(T scalar) const; NzMatrix4 operator*(T scalar) const;
NzMatrix4& operator*=(const NzMatrix4& mat); NzMatrix4& operator*=(const NzMatrix4& matrix);
NzMatrix4& operator*=(T scalar); NzMatrix4& operator*=(T scalar);
static NzMatrix4 LookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up); static NzMatrix4 LookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up);
@ -84,13 +89,31 @@ template<typename T> class NzMatrix4
static NzMatrix4 Scale(const NzVector3<T>& scale); static NzMatrix4 Scale(const NzVector3<T>& scale);
static NzMatrix4 Translate(const NzVector3<T>& translation); static NzMatrix4 Translate(const NzVector3<T>& translation);
T m11, m12, m13, m14, struct SharedMatrix
m21, m22, m23, m24, {
m31, m32, m33, m34, SharedMatrix() : // Vivement GCC 4.7 sur Windows
m41, m42, m43, m44; refCount(1)
{
}
T m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44;
unsigned int refCount;
NazaraMutex(mutex)
};
private:
void EnsureOwnership();
void ReleaseMatrix();
SharedMatrix* m_sharedMatrix;
}; };
template<typename T> std::ostream& operator<<(std::ostream& out, const NzMatrix4<T>& mat); template<typename T> std::ostream& operator<<(std::ostream& out, const NzMatrix4<T>& matrix);
typedef NzMatrix4<double> NzMatrix4d; typedef NzMatrix4<double> NzMatrix4d;
typedef NzMatrix4<float> NzMatrix4f; typedef NzMatrix4<float> NzMatrix4f;

View File

@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/StringStream.hpp> #include <Nazara/Core/StringStream.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Math/Basic.hpp> #include <Nazara/Math/Basic.hpp>
#include <Nazara/Math/EulerAngles.hpp> #include <Nazara/Math/EulerAngles.hpp>
#include <Nazara/Math/Quaternion.hpp> #include <Nazara/Math/Quaternion.hpp>
@ -16,7 +17,8 @@
#include <Nazara/Core/Debug.hpp> #include <Nazara/Core/Debug.hpp>
template<typename T> template<typename T>
NzMatrix4<T>::NzMatrix4() NzMatrix4<T>::NzMatrix4() :
m_sharedMatrix(nullptr)
{ {
} }
@ -24,7 +26,8 @@ template<typename T>
NzMatrix4<T>::NzMatrix4(T r11, T r12, T r13, T r14, NzMatrix4<T>::NzMatrix4(T r11, T r12, T r13, T r14,
T r21, T r22, T r23, T r24, T r21, T r22, T r23, T r24,
T r31, T r32, T r33, T r34, T r31, T r32, T r33, T r34,
T r41, T r42, T r43, T r44) T r41, T r42, T r43, T r44) :
m_sharedMatrix(nullptr)
{ {
Set(r11, r12, r13, r14, Set(r11, r12, r13, r14,
r21, r22, r23, r24, r21, r22, r23, r24,
@ -33,86 +36,148 @@ NzMatrix4<T>::NzMatrix4(T r11, T r12, T r13, T r14,
} }
template<typename T> template<typename T>
NzMatrix4<T>::NzMatrix4(T matrix[16]) NzMatrix4<T>::NzMatrix4(T matrix[16]) :
m_sharedMatrix(nullptr)
{ {
Set(matrix); Set(matrix);
} }
template<typename T> template<typename T>
template<typename U> template<typename U>
NzMatrix4<T>::NzMatrix4(const NzMatrix4<U>& mat) NzMatrix4<T>::NzMatrix4(const NzMatrix4<U>& matrix) :
m_sharedMatrix(nullptr)
{ {
Set(mat); Set(matrix);
}
template<typename T>
NzMatrix4<T>::NzMatrix4(const NzMatrix4& matrix) :
m_sharedMatrix(nullptr)
{
Set(matrix);
}
template<typename T>
NzMatrix4<T>::NzMatrix4(NzMatrix4&& matrix) :
m_sharedMatrix(nullptr)
{
Set(matrix);
}
template<typename T>
NzMatrix4<T>::~NzMatrix4()
{
ReleaseMatrix();
} }
template<typename T> template<typename T>
T NzMatrix4<T>::GetDeterminant() const T NzMatrix4<T>::GetDeterminant() const
{ {
T A = m22 * (m33 * m44 - m43 * m34) - m32 * (m23 * m44 - m43 * m24) + m42 * (m23 * m34 - m33 * m24); #if NAZARA_MATH_SAFE
T B = m12 * (m33 * m44 - m43 * m34) - m32 * (m13 * m44 - m43 * m14) + m42 * (m13 * m34 - m33 * m14); if (!m_sharedMatrix)
T C = m12 * (m23 * m44 - m43 * m24) - m22 * (m13 * m44 - m43 * m14) + m42 * (m13 * m24 - m23 * m14); {
T D = m12 * (m23 * m34 - m33 * m24) - m22 * (m13 * m34 - m33 * m14) + m32 * (m13 * m24 - m23 * m14); NazaraError("Undefined matrix");
return 0.0;
}
#endif
return m11 * A - m21 * B + m31 * C - m41 * D; T A = m_sharedMatrix->m22 * (m_sharedMatrix->m33 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m34) - m_sharedMatrix->m32 * (m_sharedMatrix->m23 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m24) + m_sharedMatrix->m42 * (m_sharedMatrix->m23 * m_sharedMatrix->m34 - m_sharedMatrix->m33 * m_sharedMatrix->m24);
T B = m_sharedMatrix->m12 * (m_sharedMatrix->m33 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m34) - m_sharedMatrix->m32 * (m_sharedMatrix->m13 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m14) + m_sharedMatrix->m42 * (m_sharedMatrix->m13 * m_sharedMatrix->m34 - m_sharedMatrix->m33 * m_sharedMatrix->m14);
T C = m_sharedMatrix->m12 * (m_sharedMatrix->m23 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m24) - m_sharedMatrix->m22 * (m_sharedMatrix->m13 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m14) + m_sharedMatrix->m42 * (m_sharedMatrix->m13 * m_sharedMatrix->m24 - m_sharedMatrix->m23 * m_sharedMatrix->m14);
T D = m_sharedMatrix->m12 * (m_sharedMatrix->m23 * m_sharedMatrix->m34 - m_sharedMatrix->m33 * m_sharedMatrix->m24) - m_sharedMatrix->m22 * (m_sharedMatrix->m13 * m_sharedMatrix->m34 - m_sharedMatrix->m33 * m_sharedMatrix->m14) + m_sharedMatrix->m32 * (m_sharedMatrix->m13 * m_sharedMatrix->m24 - m_sharedMatrix->m23 * m_sharedMatrix->m14);
return m_sharedMatrix->m11 * A - m_sharedMatrix->m21 * B + m_sharedMatrix->m31 * C - m_sharedMatrix->m41 * D;
} }
template<typename T> template<typename T>
NzMatrix4<T> NzMatrix4<T>::GetInverse() const NzMatrix4<T> NzMatrix4<T>::GetInverse() const
{ {
NzMatrix4 mat; #if NAZARA_MATH_SAFE
if (!m_sharedMatrix)
{
NazaraError("Undefined matrix");
return NzMatrix4();
}
#endif
NzMatrix4 matrix;
T det = GetDeterminant(); T det = GetDeterminant();
if (det != 0.0) if (det != 0.0)
{ {
mat.m11 = (m22 * (m33 * m44 - m34 * m43) - m32 * (m23 * m44 - m43 * m24) + m42 * (m23 * m34 - m33 * m24)) / det; matrix(0, 0) = (m_sharedMatrix->m22 * (m_sharedMatrix->m33 * m_sharedMatrix->m44 - m_sharedMatrix->m34 * m_sharedMatrix->m43) - m_sharedMatrix->m32 * (m_sharedMatrix->m23 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m24) + m_sharedMatrix->m42 * (m_sharedMatrix->m23 * m_sharedMatrix->m34 - m_sharedMatrix->m33 * m_sharedMatrix->m24)) / det;
mat.m12 = -(m12 * (m33 * m44 - m43 * m34) - m32 * (m13 * m44 - m43 * m14) + m42 * (m13 * m34 - m33 * m14)) / det; matrix(0, 1) = -(m_sharedMatrix->m12 * (m_sharedMatrix->m33 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m34) - m_sharedMatrix->m32 * (m_sharedMatrix->m13 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m14) + m_sharedMatrix->m42 * (m_sharedMatrix->m13 * m_sharedMatrix->m34 - m_sharedMatrix->m33 * m_sharedMatrix->m14)) / det;
mat.m13 = (m12 * (m23 * m44 - m43 * m24) - m22 * (m13 * m44 - m43 * m14) + m42 * (m13 * m24 - m23 * m14)) / det; matrix(0, 2) = (m_sharedMatrix->m12 * (m_sharedMatrix->m23 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m24) - m_sharedMatrix->m22 * (m_sharedMatrix->m13 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m14) + m_sharedMatrix->m42 * (m_sharedMatrix->m13 * m_sharedMatrix->m24 - m_sharedMatrix->m23 * m_sharedMatrix->m14)) / det;
mat.m14 = -(m12 * (m23 * m34 - m33 * m24) - m22 * (m13 * m34 - m33 * m14) + m32 * (m13 * m24 - m23 * m14)) / det; matrix(0, 3) = -(m_sharedMatrix->m12 * (m_sharedMatrix->m23 * m_sharedMatrix->m34 - m_sharedMatrix->m33 * m_sharedMatrix->m24) - m_sharedMatrix->m22 * (m_sharedMatrix->m13 * m_sharedMatrix->m34 - m_sharedMatrix->m33 * m_sharedMatrix->m14) + m_sharedMatrix->m32 * (m_sharedMatrix->m13 * m_sharedMatrix->m24 - m_sharedMatrix->m23 * m_sharedMatrix->m14)) / det;
mat.m21 = -(m21 * (m33 * m44 - m34 * m43) - m23 * (m31 * m44 - m34 * m41) + m24 * (m31 * m43 - m33 * m41)) / det; matrix(1, 0) = -(m_sharedMatrix->m21 * (m_sharedMatrix->m33 * m_sharedMatrix->m44 - m_sharedMatrix->m34 * m_sharedMatrix->m43) - m_sharedMatrix->m23 * (m_sharedMatrix->m31 * m_sharedMatrix->m44 - m_sharedMatrix->m34 * m_sharedMatrix->m41) + m_sharedMatrix->m24 * (m_sharedMatrix->m31 * m_sharedMatrix->m43 - m_sharedMatrix->m33 * m_sharedMatrix->m41)) / det;
mat.m22 = (m11 * (m33 * m44 - m34 * m43) - m13 * (m31 * m44 - m34 * m41) + m14 * (m31 * m43 - m33 * m41)) / det; matrix(1, 1) = (m_sharedMatrix->m11 * (m_sharedMatrix->m33 * m_sharedMatrix->m44 - m_sharedMatrix->m34 * m_sharedMatrix->m43) - m_sharedMatrix->m13 * (m_sharedMatrix->m31 * m_sharedMatrix->m44 - m_sharedMatrix->m34 * m_sharedMatrix->m41) + m_sharedMatrix->m14 * (m_sharedMatrix->m31 * m_sharedMatrix->m43 - m_sharedMatrix->m33 * m_sharedMatrix->m41)) / det;
mat.m23 = -(m11 * (m23 * m44 - m24 * m43) - m13 * (m21 * m44 - m24 * m41) + m14 * (m21 * m43 - m23 * m41)) / det; matrix(1, 2) = -(m_sharedMatrix->m11 * (m_sharedMatrix->m23 * m_sharedMatrix->m44 - m_sharedMatrix->m24 * m_sharedMatrix->m43) - m_sharedMatrix->m13 * (m_sharedMatrix->m21 * m_sharedMatrix->m44 - m_sharedMatrix->m24 * m_sharedMatrix->m41) + m_sharedMatrix->m14 * (m_sharedMatrix->m21 * m_sharedMatrix->m43 - m_sharedMatrix->m23 * m_sharedMatrix->m41)) / det;
mat.m24 = (m11 * (m23 * m34 - m24 * m33) - m13 * (m21 * m34 - m24 * m31) + m14 * (m21 * m33 - m23 * m31)) / det; matrix(1, 3) = (m_sharedMatrix->m11 * (m_sharedMatrix->m23 * m_sharedMatrix->m34 - m_sharedMatrix->m24 * m_sharedMatrix->m33) - m_sharedMatrix->m13 * (m_sharedMatrix->m21 * m_sharedMatrix->m34 - m_sharedMatrix->m24 * m_sharedMatrix->m31) + m_sharedMatrix->m14 * (m_sharedMatrix->m21 * m_sharedMatrix->m33 - m_sharedMatrix->m23 * m_sharedMatrix->m31)) / det;
mat.m31 = (m21 * (m32 * m44 - m34 * m42) - m22 * (m31 * m44 - m34 * m41) + m24 * (m31 * m42 - m32 * m41)) / det; matrix(2, 0) = (m_sharedMatrix->m21 * (m_sharedMatrix->m32 * m_sharedMatrix->m44 - m_sharedMatrix->m34 * m_sharedMatrix->m42) - m_sharedMatrix->m22 * (m_sharedMatrix->m31 * m_sharedMatrix->m44 - m_sharedMatrix->m34 * m_sharedMatrix->m41) + m_sharedMatrix->m24 * (m_sharedMatrix->m31 * m_sharedMatrix->m42 - m_sharedMatrix->m32 * m_sharedMatrix->m41)) / det;
mat.m32 = -(m11 * (m32 * m44 - m34 * m42) - m12 * (m31 * m44 - m34 * m41) + m14 * (m31 * m42 - m32 * m41)) / det; matrix(2, 1) = -(m_sharedMatrix->m11 * (m_sharedMatrix->m32 * m_sharedMatrix->m44 - m_sharedMatrix->m34 * m_sharedMatrix->m42) - m_sharedMatrix->m12 * (m_sharedMatrix->m31 * m_sharedMatrix->m44 - m_sharedMatrix->m34 * m_sharedMatrix->m41) + m_sharedMatrix->m14 * (m_sharedMatrix->m31 * m_sharedMatrix->m42 - m_sharedMatrix->m32 * m_sharedMatrix->m41)) / det;
mat.m33 = (m11 * (m22 * m44 - m24 * m42) - m12 * (m21 * m44 - m24 * m41) + m14 * (m21 * m42 - m22 * m41)) / det; matrix(2, 2) = (m_sharedMatrix->m11 * (m_sharedMatrix->m22 * m_sharedMatrix->m44 - m_sharedMatrix->m24 * m_sharedMatrix->m42) - m_sharedMatrix->m12 * (m_sharedMatrix->m21 * m_sharedMatrix->m44 - m_sharedMatrix->m24 * m_sharedMatrix->m41) + m_sharedMatrix->m14 * (m_sharedMatrix->m21 * m_sharedMatrix->m42 - m_sharedMatrix->m22 * m_sharedMatrix->m41)) / det;
mat.m34 = -(m11 * (m22 * m34 - m24 * m32) - m12 * (m21 * m34 - m24 * m31) + m14 * (m21 * m32 - m22 * m31)) / det; matrix(2, 3) = -(m_sharedMatrix->m11 * (m_sharedMatrix->m22 * m_sharedMatrix->m34 - m_sharedMatrix->m24 * m_sharedMatrix->m32) - m_sharedMatrix->m12 * (m_sharedMatrix->m21 * m_sharedMatrix->m34 - m_sharedMatrix->m24 * m_sharedMatrix->m31) + m_sharedMatrix->m14 * (m_sharedMatrix->m21 * m_sharedMatrix->m32 - m_sharedMatrix->m22 * m_sharedMatrix->m31)) / det;
mat.m41 = -(m21 * (m32 * m43 - m33 * m42) - m22 * (m31 * m43 - m33 * m41) + m23 * (m31 * m42 - m32 * m41)) / det; matrix(3, 0) = -(m_sharedMatrix->m21 * (m_sharedMatrix->m32 * m_sharedMatrix->m43 - m_sharedMatrix->m33 * m_sharedMatrix->m42) - m_sharedMatrix->m22 * (m_sharedMatrix->m31 * m_sharedMatrix->m43 - m_sharedMatrix->m33 * m_sharedMatrix->m41) + m_sharedMatrix->m23 * (m_sharedMatrix->m31 * m_sharedMatrix->m42 - m_sharedMatrix->m32 * m_sharedMatrix->m41)) / det;
mat.m42 = (m11 * (m32 * m43 - m33 * m42) - m12 * (m31 * m43 - m33 * m41) + m13 * (m31 * m42 - m32 * m41)) / det; matrix(3, 1) = (m_sharedMatrix->m11 * (m_sharedMatrix->m32 * m_sharedMatrix->m43 - m_sharedMatrix->m33 * m_sharedMatrix->m42) - m_sharedMatrix->m12 * (m_sharedMatrix->m31 * m_sharedMatrix->m43 - m_sharedMatrix->m33 * m_sharedMatrix->m41) + m_sharedMatrix->m13 * (m_sharedMatrix->m31 * m_sharedMatrix->m42 - m_sharedMatrix->m32 * m_sharedMatrix->m41)) / det;
mat.m43 = -(m11 * (m22 * m43 - m23 * m42) - m12 * (m21 * m43 - m23 * m41) + m13 * (m21 * m42 - m22 * m41)) / det; matrix(3, 2) = -(m_sharedMatrix->m11 * (m_sharedMatrix->m22 * m_sharedMatrix->m43 - m_sharedMatrix->m23 * m_sharedMatrix->m42) - m_sharedMatrix->m12 * (m_sharedMatrix->m21 * m_sharedMatrix->m43 - m_sharedMatrix->m23 * m_sharedMatrix->m41) + m_sharedMatrix->m13 * (m_sharedMatrix->m21 * m_sharedMatrix->m42 - m_sharedMatrix->m22 * m_sharedMatrix->m41)) / det;
mat.m44 = (m11 * (m22 * m33 - m23 * m32) - m12 * (m21 * m33 - m23 * m31) + m13 * (m21 * m32 - m22 * m31)) / det; matrix(3, 3) = (m_sharedMatrix->m11 * (m_sharedMatrix->m22 * m_sharedMatrix->m33 - m_sharedMatrix->m23 * m_sharedMatrix->m32) - m_sharedMatrix->m12 * (m_sharedMatrix->m21 * m_sharedMatrix->m33 - m_sharedMatrix->m23 * m_sharedMatrix->m31) + m_sharedMatrix->m13 * (m_sharedMatrix->m21 * m_sharedMatrix->m32 - m_sharedMatrix->m22 * m_sharedMatrix->m31)) / det;
} }
return mat; return matrix;
} }
template<typename T> template<typename T>
NzVector3<T> NzMatrix4<T>::GetScale() const NzVector3<T> NzMatrix4<T>::GetScale() const
{ {
return NzVector3<T>(std::sqrt(m11 * m11 + m21 * m21 + m31 * m31), #if NAZARA_MATH_SAFE
std::sqrt(m12 * m12 + m22 * m22 + m32 * m32), if (!m_sharedMatrix)
std::sqrt(m13 * m13 + m23 * m23 + m33 * m33)); {
NazaraError("Undefined matrix");
return NzVector3<T>();
}
#endif
return NzVector3<T>(std::sqrt(m_sharedMatrix->m11 * m_sharedMatrix->m11 + m_sharedMatrix->m21 * m_sharedMatrix->m21 + m_sharedMatrix->m31 * m_sharedMatrix->m31),
std::sqrt(m_sharedMatrix->m12 * m_sharedMatrix->m12 + m_sharedMatrix->m22 * m_sharedMatrix->m22 + m_sharedMatrix->m32 * m_sharedMatrix->m32),
std::sqrt(m_sharedMatrix->m13 * m_sharedMatrix->m13 + m_sharedMatrix->m23 * m_sharedMatrix->m23 + m_sharedMatrix->m33 * m_sharedMatrix->m33));
} }
template<typename T> template<typename T>
NzVector3<T> NzMatrix4<T>::GetTranslation() const NzVector3<T> NzMatrix4<T>::GetTranslation() const
{ {
#if NAZARA_MATH_SAFE
if (!m_sharedMatrix)
{
NazaraError("Undefined matrix");
return NzVector3<T>();
}
#endif
#if NAZARA_MATH_MATRIX_COLUMN_MAJOR #if NAZARA_MATH_MATRIX_COLUMN_MAJOR
return NzVector3<T>(m41, m42, m43); return NzVector3<T>(m_sharedMatrix->m41, m_sharedMatrix->m42, m_sharedMatrix->m43);
#else #else
return NzVector3<T>(m14, m24, m34); return NzVector3<T>(m_sharedMatrix->m14, m_sharedMatrix->m24, m_sharedMatrix->m34);
#endif #endif
} }
template<typename T> template<typename T>
NzMatrix4<T> NzMatrix4<T>::GetTransposed() const NzMatrix4<T> NzMatrix4<T>::GetTransposed() const
{ {
return NzMatrix4(m11, m21, m31, m41, #if NAZARA_MATH_SAFE
m12, m22, m32, m42, if (!m_sharedMatrix)
m13, m23, m33, m43, {
m14, m24, m34, m44); NazaraError("Undefined matrix");
return NzMatrix4();
}
#endif
return NzMatrix4(m_sharedMatrix->m11, m_sharedMatrix->m21, m_sharedMatrix->m31, m_sharedMatrix->m41,
m_sharedMatrix->m12, m_sharedMatrix->m22, m_sharedMatrix->m32, m_sharedMatrix->m42,
m_sharedMatrix->m13, m_sharedMatrix->m23, m_sharedMatrix->m33, m_sharedMatrix->m43,
m_sharedMatrix->m14, m_sharedMatrix->m24, m_sharedMatrix->m34, m_sharedMatrix->m44);
} }
template<typename T> template<typename T>
@ -124,15 +189,23 @@ bool NzMatrix4<T>::HasNegativeScale() const
template<typename T> template<typename T>
bool NzMatrix4<T>::HasScale() const bool NzMatrix4<T>::HasScale() const
{ {
T t = m11 * m11 + m21 * m21 + m31 * m31; #if NAZARA_MATH_SAFE
if (!m_sharedMatrix)
{
NazaraError("Undefined matrix");
return false;
}
#endif
T t = m_sharedMatrix->m11 * m_sharedMatrix->m11 + m_sharedMatrix->m21 * m_sharedMatrix->m21 + m_sharedMatrix->m31 * m_sharedMatrix->m31;
if (1.0 - t > std::numeric_limits<T>::epsilon()) if (1.0 - t > std::numeric_limits<T>::epsilon())
return true; return true;
t = m12 * m12 + m22 * m22 + m32 * m32; t = m_sharedMatrix->m12 * m_sharedMatrix->m12 + m_sharedMatrix->m22 * m_sharedMatrix->m22 + m_sharedMatrix->m32 * m_sharedMatrix->m32;
if (1.0 - t > std::numeric_limits<T>::epsilon()) if (1.0 - t > std::numeric_limits<T>::epsilon())
return true; return true;
t = m13 * m13 + m23 * m23 + m33 * m33; t = m_sharedMatrix->m13 * m_sharedMatrix->m13 + m_sharedMatrix->m23 * m_sharedMatrix->m23 + m_sharedMatrix->m33 * m_sharedMatrix->m33;
if (1.0 - t > std::numeric_limits<T>::epsilon()) if (1.0 - t > std::numeric_limits<T>::epsilon())
return true; return true;
@ -145,56 +218,66 @@ void NzMatrix4<T>::Set(T r11, T r12, T r13, T r14,
T r31, T r32, T r33, T r34, T r31, T r32, T r33, T r34,
T r41, T r42, T r43, T r44) T r41, T r42, T r43, T r44)
{ {
m11 = r11; EnsureOwnership();
m12 = r12;
m13 = r13; m_sharedMatrix->m11 = r11;
m14 = r14; m_sharedMatrix->m12 = r12;
m21 = r21; m_sharedMatrix->m13 = r13;
m22 = r22; m_sharedMatrix->m14 = r14;
m23 = r23; m_sharedMatrix->m21 = r21;
m24 = r24; m_sharedMatrix->m22 = r22;
m31 = r31; m_sharedMatrix->m23 = r23;
m32 = r32; m_sharedMatrix->m24 = r24;
m33 = r33; m_sharedMatrix->m31 = r31;
m34 = r34; m_sharedMatrix->m32 = r32;
m41 = r41; m_sharedMatrix->m33 = r33;
m42 = r42; m_sharedMatrix->m34 = r34;
m43 = r43; m_sharedMatrix->m41 = r41;
m44 = r44; m_sharedMatrix->m42 = r42;
m_sharedMatrix->m43 = r43;
m_sharedMatrix->m44 = r44;
} }
template<typename T> void NzMatrix4<T>::Set(T matrix[16]) template<typename T>
void NzMatrix4<T>::Set(T matrix[16])
{ {
EnsureOwnership();
// Ici nous sommes certains de la continuité des éléments en mémoire // Ici nous sommes certains de la continuité des éléments en mémoire
std::memcpy(&m41, matrix, 16*sizeof(T)); std::memcpy(&m_sharedMatrix->m41, matrix, 16*sizeof(T));
} }
template<typename T> void NzMatrix4<T>::Set(const NzMatrix4& mat) template<typename T>
void NzMatrix4<T>::Set(const NzMatrix4& matrix)
{ {
// Pareil ReleaseMatrix();
std::memcpy(&m41, &mat.m41, 16*sizeof(T));
m_sharedMatrix = matrix.m_sharedMatrix;
if (m_sharedMatrix)
{
NazaraMutexLock(m_sharedMatrix->mutex);
m_sharedMatrix->refCount++;
NazaraMutexUnlock(m_sharedMatrix->mutex);
}
}
template<typename T>
void NzMatrix4<T>::Set(NzMatrix4&& matrix)
{
ReleaseMatrix();
m_sharedMatrix = matrix.m_sharedMatrix;
matrix.m_sharedMatrix = nullptr;
} }
template<typename T> template<typename T>
template<typename U> template<typename U>
void NzMatrix4<T>::Set(const NzMatrix4<U>& mat) void NzMatrix4<T>::Set(const NzMatrix4<U>& matrix)
{ {
m11 = static_cast<T>(mat.m11); Set(static_cast<T>(matrix.m11), static_cast<T>(matrix.m12), static_cast<T>(matrix.m13), static_cast<T>(matrix.m14),
m12 = static_cast<T>(mat.m12); static_cast<T>(matrix.m21), static_cast<T>(matrix.m22), static_cast<T>(matrix.m23), static_cast<T>(matrix.m24),
m13 = static_cast<T>(mat.m13); static_cast<T>(matrix.m31), static_cast<T>(matrix.m32), static_cast<T>(matrix.m33), static_cast<T>(matrix.m34),
m14 = static_cast<T>(mat.m14); static_cast<T>(matrix.m41), static_cast<T>(matrix.m42), static_cast<T>(matrix.m43), static_cast<T>(matrix.m44));
m21 = static_cast<T>(mat.m21);
m22 = static_cast<T>(mat.m22);
m23 = static_cast<T>(mat.m23);
m24 = static_cast<T>(mat.m24);
m31 = static_cast<T>(mat.m31);
m32 = static_cast<T>(mat.m32);
m33 = static_cast<T>(mat.m33);
m34 = static_cast<T>(mat.m34);
m41 = static_cast<T>(mat.m41);
m42 = static_cast<T>(mat.m42);
m43 = static_cast<T>(mat.m43);
m44 = static_cast<T>(mat.m44);
} }
template<typename T> template<typename T>
@ -311,47 +394,81 @@ void NzMatrix4<T>::SetZero()
template<typename T> template<typename T>
NzString NzMatrix4<T>::ToString() const NzString NzMatrix4<T>::ToString() const
{ {
NzStringStream ss; if (!m_sharedMatrix)
return "Matrix4(undefined)";
return ss << "Matrix4(" << m11 << ", " << m12 << ", " << m13 << ", " << m14 << ",\n" NzStringStream ss;
<< " " << m21 << ", " << m22 << ", " << m23 << ", " << m24 << ",\n" return ss << "Matrix4(" << m_sharedMatrix->m11 << ", " << m_sharedMatrix->m12 << ", " << m_sharedMatrix->m13 << ", " << m_sharedMatrix->m14 << ",\n"
<< " " << m31 << ", " << m32 << ", " << m33 << ", " << m34 << ",\n" << " " << m_sharedMatrix->m21 << ", " << m_sharedMatrix->m22 << ", " << m_sharedMatrix->m23 << ", " << m_sharedMatrix->m24 << ",\n"
<< " " << m41 << ", " << m42 << ", " << m43 << ", " << m44 << ')'; << " " << m_sharedMatrix->m31 << ", " << m_sharedMatrix->m32 << ", " << m_sharedMatrix->m33 << ", " << m_sharedMatrix->m34 << ",\n"
<< " " << m_sharedMatrix->m41 << ", " << m_sharedMatrix->m42 << ", " << m_sharedMatrix->m43 << ", " << m_sharedMatrix->m44 << ')';
} }
template<typename T> template<typename T>
NzVector2<T> NzMatrix4<T>::Transform(const NzVector2<T>& vector, T z, T w) const NzVector2<T> NzMatrix4<T>::Transform(const NzVector2<T>& vector, T z, T w) const
{ {
return NzVector2<T>(m11 * vector.x + m12 * vector.y + m13 * z + m14 * w, #if NAZARA_MATH_SAFE
m21 * vector.x + m22 * vector.y + m23 * z + m24 * w); if (!m_sharedMatrix)
{
NazaraError("Undefined matrix");
return vector;
}
#endif
return NzVector2<T>(m_sharedMatrix->m11 * vector.x + m_sharedMatrix->m12 * vector.y + m_sharedMatrix->m13 * z + m_sharedMatrix->m14 * w,
m_sharedMatrix->m21 * vector.x + m_sharedMatrix->m22 * vector.y + m_sharedMatrix->m23 * z + m_sharedMatrix->m24 * w);
} }
template<typename T> template<typename T>
NzVector3<T> NzMatrix4<T>::Transform(const NzVector3<T>& vector, T w) const NzVector3<T> NzMatrix4<T>::Transform(const NzVector3<T>& vector, T w) const
{ {
return NzVector3<T>(m11 * vector.x + m12 * vector.y + m13 * vector.z + m14 * w, #if NAZARA_MATH_SAFE
m21 * vector.x + m22 * vector.y + m23 * vector.z + m24 * w, if (!m_sharedMatrix)
m31 * vector.x + m32 * vector.y + m33 * vector.z + m34 * w); {
NazaraError("Undefined matrix");
return vector;
}
#endif
return NzVector3<T>(m_sharedMatrix->m11 * vector.x + m_sharedMatrix->m12 * vector.y + m_sharedMatrix->m13 * vector.z + m_sharedMatrix->m14 * w,
m_sharedMatrix->m21 * vector.x + m_sharedMatrix->m22 * vector.y + m_sharedMatrix->m23 * vector.z + m_sharedMatrix->m24 * w,
m_sharedMatrix->m31 * vector.x + m_sharedMatrix->m32 * vector.y + m_sharedMatrix->m33 * vector.z + m_sharedMatrix->m34 * w);
} }
template<typename T> template<typename T>
NzVector4<T> NzMatrix4<T>::Transform(const NzVector4<T>& vector) const NzVector4<T> NzMatrix4<T>::Transform(const NzVector4<T>& vector) const
{ {
return NzVector4<T>(m11 * vector.x + m12 * vector.y + m13 * vector.z + m14 * vector.w, #if NAZARA_MATH_SAFE
m21 * vector.x + m22 * vector.y + m23 * vector.z + m24 * vector.w, if (!m_sharedMatrix)
m31 * vector.x + m32 * vector.y + m33 * vector.z + m34 * vector.w, {
m41 * vector.x + m42 * vector.y + m43 * vector.z + m44 * vector.w); NazaraError("Undefined matrix");
return vector;
}
#endif
return NzVector4<T>(m_sharedMatrix->m11 * vector.x + m_sharedMatrix->m12 * vector.y + m_sharedMatrix->m13 * vector.z + m_sharedMatrix->m14 * vector.w,
m_sharedMatrix->m21 * vector.x + m_sharedMatrix->m22 * vector.y + m_sharedMatrix->m23 * vector.z + m_sharedMatrix->m24 * vector.w,
m_sharedMatrix->m31 * vector.x + m_sharedMatrix->m32 * vector.y + m_sharedMatrix->m33 * vector.z + m_sharedMatrix->m34 * vector.w,
m_sharedMatrix->m41 * vector.x + m_sharedMatrix->m42 * vector.y + m_sharedMatrix->m43 * vector.z + m_sharedMatrix->m44 * vector.w);
} }
template<typename T> template<typename T>
NzMatrix4<T>& NzMatrix4<T>::Transpose() NzMatrix4<T>& NzMatrix4<T>::Transpose()
{ {
std::swap(m12, m21); #if NAZARA_MATH_SAFE
std::swap(m13, m31); if (!m_sharedMatrix)
std::swap(m14, m41); {
std::swap(m23, m32); NazaraError("Undefined matrix");
std::swap(m24, m42); return *this;
std::swap(m34, m43); }
#endif
std::swap(m_sharedMatrix->m12, m_sharedMatrix->m21);
std::swap(m_sharedMatrix->m13, m_sharedMatrix->m31);
std::swap(m_sharedMatrix->m14, m_sharedMatrix->m41);
std::swap(m_sharedMatrix->m23, m_sharedMatrix->m32);
std::swap(m_sharedMatrix->m24, m_sharedMatrix->m42);
std::swap(m_sharedMatrix->m34, m_sharedMatrix->m43);
return *this; return *this;
} }
@ -359,13 +476,31 @@ NzMatrix4<T>& NzMatrix4<T>::Transpose()
template<typename T> template<typename T>
NzMatrix4<T>::operator T*() NzMatrix4<T>::operator T*()
{ {
return &m11; #if NAZARA_MATH_SAFE
if (!m_sharedMatrix)
{
NazaraError("Undefined matrix");
return nullptr;
}
#endif
EnsureOwnership();
return &m_sharedMatrix->m11;
} }
template<typename T> template<typename T>
NzMatrix4<T>::operator const T*() const NzMatrix4<T>::operator const T*() const
{ {
return &m11; #if NAZARA_MATH_SAFE
if (!m_sharedMatrix)
{
NazaraError("Undefined matrix");
return nullptr;
}
#endif
return &m_sharedMatrix->m11;
} }
template<typename T> template<typename T>
@ -381,13 +516,21 @@ T& NzMatrix4<T>::operator()(unsigned int x, unsigned int y)
} }
#endif #endif
return (&m11)[x*4+y]; EnsureOwnership();
return (&m_sharedMatrix->m11)[x*4+y];
} }
template<typename T> template<typename T>
const T& NzMatrix4<T>::operator()(unsigned int x, unsigned int y) const const T& NzMatrix4<T>::operator()(unsigned int x, unsigned int y) const
{ {
#if NAZARA_MATH_SAFE #if NAZARA_MATH_SAFE
if (!m_sharedMatrix)
{
NazaraError("Undefined matrix");
throw std::runtime_error("Tried to access element of undefined matrix");
}
if (x > 3 || y > 3) if (x > 3 || y > 3)
{ {
NzStringStream ss; NzStringStream ss;
@ -397,39 +540,63 @@ const T& NzMatrix4<T>::operator()(unsigned int x, unsigned int y) const
} }
#endif #endif
return (&m11)[x*4+y]; return (&m_sharedMatrix->m11)[x*4+y];
} }
template<typename T> template<typename T>
NzMatrix4<T> NzMatrix4<T>::operator*(const NzMatrix4& mat) const NzMatrix4<T>& NzMatrix4<T>::operator=(const NzMatrix4& matrix)
{ {
NzMatrix4 matrix; Set(matrix);
return *this;
}
template<typename T>
NzMatrix4<T>& NzMatrix4<T>::operator=(NzMatrix4&& matrix)
{
Set(matrix);
return *this;
}
template<typename T>
NzMatrix4<T> NzMatrix4<T>::operator*(const NzMatrix4& matrix) const
{
#if NAZARA_MATH_SAFE
if (!m_sharedMatrix)
{
NazaraError("Undefined matrix");
return matrix;
}
#endif
NzMatrix4 mat;
for(int k = 0; k < 4; k++) for(int k = 0; k < 4; k++)
{ {
for(int j = 0; j < 4; j++) for(int j = 0; j < 4; j++)
{ {
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
matrix(j, k) += (*this)(j, i) * mat(i, k); mat(j, k) += (*this)(j, i) * matrix(i, k);
} }
} }
return matrix; return mat;
/*return NzMatrix4(m11 * mat.m11 + m21 * mat.m12 + m31 * mat.m13 + m41 * mat.m14, /*return NzMatrix4(m11 * matrix.m11 + m21 * matrix.m12 + m31 * matrix.m13 + m41 * matrix.m14,
m12 * mat.m11 + m22 * mat.m12 + m32 * mat.m13 + m42 * mat.m14, m12 * matrix.m11 + m22 * matrix.m12 + m32 * matrix.m13 + m42 * matrix.m14,
m13 * mat.m11 + m23 * mat.m12 + m33 * mat.m13 + m43 * mat.m14, m13 * matrix.m11 + m23 * matrix.m12 + m33 * matrix.m13 + m43 * matrix.m14,
m14 * mat.m11 + m24 * mat.m12 + m34 * mat.m13 + m44 * mat.m14, m14 * matrix.m11 + m24 * matrix.m12 + m34 * matrix.m13 + m44 * matrix.m14,
m11 * mat.m21 + m21 * mat.m22 + m31 * mat.m23 + m41 * mat.m24, m11 * matrix.m21 + m21 * matrix.m22 + m31 * matrix.m23 + m41 * matrix.m24,
m12 * mat.m21 + m22 * mat.m22 + m32 * mat.m23 + m42 * mat.m24, m12 * matrix.m21 + m22 * matrix.m22 + m32 * matrix.m23 + m42 * matrix.m24,
m13 * mat.m21 + m23 * mat.m22 + m33 * mat.m23 + m43 * mat.m24, m13 * matrix.m21 + m23 * matrix.m22 + m33 * matrix.m23 + m43 * matrix.m24,
m14 * mat.m21 + m24 * mat.m22 + m34 * mat.m23 + m44 * mat.m24, m14 * matrix.m21 + m24 * matrix.m22 + m34 * matrix.m23 + m44 * matrix.m24,
m11 * mat.m31 + m21 * mat.m32 + m31 * mat.m33 + m41 * mat.m34, m11 * matrix.m31 + m21 * matrix.m32 + m31 * matrix.m33 + m41 * matrix.m34,
m12 * mat.m31 + m22 * mat.m32 + m32 * mat.m33 + m42 * mat.m34, m12 * matrix.m31 + m22 * matrix.m32 + m32 * matrix.m33 + m42 * matrix.m34,
m13 * mat.m31 + m23 * mat.m32 + m33 * mat.m33 + m43 * mat.m34, m13 * matrix.m31 + m23 * matrix.m32 + m33 * matrix.m33 + m43 * matrix.m34,
m14 * mat.m31 + m24 * mat.m32 + m34 * mat.m33 + m44 * mat.m34, m14 * matrix.m31 + m24 * matrix.m32 + m34 * matrix.m33 + m44 * matrix.m34,
m11 * mat.m41 + m21 * mat.m42 + m31 * mat.m43 + m41 * mat.m44, m11 * matrix.m41 + m21 * matrix.m42 + m31 * matrix.m43 + m41 * matrix.m44,
m12 * mat.m41 + m22 * mat.m42 + m32 * mat.m43 + m42 * mat.m44, m12 * matrix.m41 + m22 * matrix.m42 + m32 * matrix.m43 + m42 * matrix.m44,
m13 * mat.m41 + m23 * mat.m42 + m33 * mat.m43 + m43 * mat.m44, m13 * matrix.m41 + m23 * matrix.m42 + m33 * matrix.m43 + m43 * matrix.m44,
m14 * mat.m41 + m24 * mat.m42 + m34 * mat.m43 + m44 * mat.m44);*/ m14 * matrix.m41 + m24 * matrix.m42 + m34 * matrix.m43 + m44 * matrix.m44);*/
} }
@ -454,47 +621,54 @@ NzVector4<T> NzMatrix4<T>::operator*(const NzVector4<T>& vector) const
template<typename T> template<typename T>
NzMatrix4<T> NzMatrix4<T>::operator*(T scalar) const NzMatrix4<T> NzMatrix4<T>::operator*(T scalar) const
{ {
return NzMatrix4(m11 * scalar, m12 * scalar, m13 * scalar, m14 * scalar, #if NAZARA_MATH_SAFE
m21 * scalar, m22 * scalar, m23 * scalar, m24 * scalar, if (!m_sharedMatrix)
m31 * scalar, m32 * scalar, m33 * scalar, m34 * scalar, {
m41 * scalar, m42 * scalar, m43 * scalar, m44 * scalar); NazaraError("Undefined matrix");
return *this;
}
#endif
return NzMatrix4(m_sharedMatrix->m11 * scalar, m_sharedMatrix->m12 * scalar, m_sharedMatrix->m13 * scalar, m_sharedMatrix->m14 * scalar,
m_sharedMatrix->m21 * scalar, m_sharedMatrix->m22 * scalar, m_sharedMatrix->m23 * scalar, m_sharedMatrix->m24 * scalar,
m_sharedMatrix->m31 * scalar, m_sharedMatrix->m32 * scalar, m_sharedMatrix->m33 * scalar, m_sharedMatrix->m34 * scalar,
m_sharedMatrix->m41 * scalar, m_sharedMatrix->m42 * scalar, m_sharedMatrix->m43 * scalar, m_sharedMatrix->m44 * scalar);
} }
template<typename T> template<typename T>
NzMatrix4<T>& NzMatrix4<T>::operator*=(const NzMatrix4& mat) NzMatrix4<T>& NzMatrix4<T>::operator*=(const NzMatrix4& matrix)
{ {
T r11 = m11 * mat.m11 + m21 * mat.m12 + m31 * mat.m13 + m41 * mat.m14; #if NAZARA_MATH_SAFE
T r12 = m12 * mat.m11 + m22 * mat.m12 + m32 * mat.m13 + m42 * mat.m14; if (!m_sharedMatrix)
T r13 = m13 * mat.m11 + m23 * mat.m12 + m33 * mat.m13 + m43 * mat.m14; {
T r14 = m14 * mat.m11 + m24 * mat.m12 + m34 * mat.m13 + m44 * mat.m14; NazaraError("Undefined matrix");
T r21 = m11 * mat.m21 + m21 * mat.m22 + m31 * mat.m23 + m41 * mat.m24; return *this;
T r22 = m12 * mat.m21 + m22 * mat.m22 + m32 * mat.m23 + m42 * mat.m24; }
T r23 = m13 * mat.m21 + m23 * mat.m22 + m33 * mat.m23 + m43 * mat.m24; #endif
T r24 = m14 * mat.m21 + m24 * mat.m22 + m34 * mat.m23 + m44 * mat.m24;
T r31 = m11 * mat.m31 + m21 * mat.m32 + m31 * mat.m33 + m41 * mat.m34;
T r32 = m12 * mat.m31 + m22 * mat.m32 + m32 * mat.m33 + m42 * mat.m34;
T r33 = m13 * mat.m31 + m23 * mat.m32 + m33 * mat.m33 + m43 * mat.m34;
T r34 = m14 * mat.m31 + m24 * mat.m32 + m34 * mat.m33 + m44 * mat.m34;
T r41 = m11 * mat.m41 + m21 * mat.m42 + m31 * mat.m43 + m41 * mat.m44;
T r42 = m12 * mat.m41 + m22 * mat.m42 + m32 * mat.m43 + m42 * mat.m44;
T r43 = m13 * mat.m41 + m23 * mat.m42 + m33 * mat.m43 + m43 * mat.m44;
m44 = m14 * mat.m41 + m24 * mat.m42 + m34 * mat.m43 + m44 * mat.m44; // On calcule dans des variables temporaires
m43 = r43; T r11 = m_sharedMatrix->m11 * matrix.m_sharedMatrix->m11 + m_sharedMatrix->m21 * matrix.m_sharedMatrix->m12 + m_sharedMatrix->m31 * matrix.m_sharedMatrix->m13 + m_sharedMatrix->m41 * matrix.m_sharedMatrix->m14;
m42 = r42; T r12 = m_sharedMatrix->m12 * matrix.m_sharedMatrix->m11 + m_sharedMatrix->m22 * matrix.m_sharedMatrix->m12 + m_sharedMatrix->m32 * matrix.m_sharedMatrix->m13 + m_sharedMatrix->m42 * matrix.m_sharedMatrix->m14;
m41 = r41; T r13 = m_sharedMatrix->m13 * matrix.m_sharedMatrix->m11 + m_sharedMatrix->m23 * matrix.m_sharedMatrix->m12 + m_sharedMatrix->m33 * matrix.m_sharedMatrix->m13 + m_sharedMatrix->m43 * matrix.m_sharedMatrix->m14;
m34 = r34; T r14 = m_sharedMatrix->m14 * matrix.m_sharedMatrix->m11 + m_sharedMatrix->m24 * matrix.m_sharedMatrix->m12 + m_sharedMatrix->m34 * matrix.m_sharedMatrix->m13 + m_sharedMatrix->m44 * matrix.m_sharedMatrix->m14;
m33 = r33; T r21 = m_sharedMatrix->m11 * matrix.m_sharedMatrix->m21 + m_sharedMatrix->m21 * matrix.m_sharedMatrix->m22 + m_sharedMatrix->m31 * matrix.m_sharedMatrix->m23 + m_sharedMatrix->m41 * matrix.m_sharedMatrix->m24;
m32 = r32; T r22 = m_sharedMatrix->m12 * matrix.m_sharedMatrix->m21 + m_sharedMatrix->m22 * matrix.m_sharedMatrix->m22 + m_sharedMatrix->m32 * matrix.m_sharedMatrix->m23 + m_sharedMatrix->m42 * matrix.m_sharedMatrix->m24;
m31 = r31; T r23 = m_sharedMatrix->m13 * matrix.m_sharedMatrix->m21 + m_sharedMatrix->m23 * matrix.m_sharedMatrix->m22 + m_sharedMatrix->m33 * matrix.m_sharedMatrix->m23 + m_sharedMatrix->m43 * matrix.m_sharedMatrix->m24;
m24 = r24; T r24 = m_sharedMatrix->m14 * matrix.m_sharedMatrix->m21 + m_sharedMatrix->m24 * matrix.m_sharedMatrix->m22 + m_sharedMatrix->m34 * matrix.m_sharedMatrix->m23 + m_sharedMatrix->m44 * matrix.m_sharedMatrix->m24;
m23 = r23; T r31 = m_sharedMatrix->m11 * matrix.m_sharedMatrix->m31 + m_sharedMatrix->m21 * matrix.m_sharedMatrix->m32 + m_sharedMatrix->m31 * matrix.m_sharedMatrix->m33 + m_sharedMatrix->m41 * matrix.m_sharedMatrix->m34;
m22 = r22; T r32 = m_sharedMatrix->m12 * matrix.m_sharedMatrix->m31 + m_sharedMatrix->m22 * matrix.m_sharedMatrix->m32 + m_sharedMatrix->m32 * matrix.m_sharedMatrix->m33 + m_sharedMatrix->m42 * matrix.m_sharedMatrix->m34;
m21 = r21; T r33 = m_sharedMatrix->m13 * matrix.m_sharedMatrix->m31 + m_sharedMatrix->m23 * matrix.m_sharedMatrix->m32 + m_sharedMatrix->m33 * matrix.m_sharedMatrix->m33 + m_sharedMatrix->m43 * matrix.m_sharedMatrix->m34;
m14 = r14; T r34 = m_sharedMatrix->m14 * matrix.m_sharedMatrix->m31 + m_sharedMatrix->m24 * matrix.m_sharedMatrix->m32 + m_sharedMatrix->m34 * matrix.m_sharedMatrix->m33 + m_sharedMatrix->m44 * matrix.m_sharedMatrix->m34;
m13 = r13; T r41 = m_sharedMatrix->m11 * matrix.m_sharedMatrix->m41 + m_sharedMatrix->m21 * matrix.m_sharedMatrix->m42 + m_sharedMatrix->m31 * matrix.m_sharedMatrix->m43 + m_sharedMatrix->m41 * matrix.m_sharedMatrix->m44;
m12 = r12; T r42 = m_sharedMatrix->m12 * matrix.m_sharedMatrix->m41 + m_sharedMatrix->m22 * matrix.m_sharedMatrix->m42 + m_sharedMatrix->m32 * matrix.m_sharedMatrix->m43 + m_sharedMatrix->m42 * matrix.m_sharedMatrix->m44;
m11 = r11; T r43 = m_sharedMatrix->m13 * matrix.m_sharedMatrix->m41 + m_sharedMatrix->m23 * matrix.m_sharedMatrix->m42 + m_sharedMatrix->m33 * matrix.m_sharedMatrix->m43 + m_sharedMatrix->m43 * matrix.m_sharedMatrix->m44;
T r44 = m_sharedMatrix->m14 * matrix.m_sharedMatrix->m41 + m_sharedMatrix->m24 * matrix.m_sharedMatrix->m42 + m_sharedMatrix->m34 * matrix.m_sharedMatrix->m43 + m_sharedMatrix->m44 * matrix.m_sharedMatrix->m44;
// Et puis on affecte
Set(r11, r12, r13, r14,
r21, r22, r23, r24,
r31, r32, r33, r34,
r41, r42, r43, r44);
return *this; return *this;
} }
@ -502,22 +676,30 @@ NzMatrix4<T>& NzMatrix4<T>::operator*=(const NzMatrix4& mat)
template<typename T> template<typename T>
NzMatrix4<T>& NzMatrix4<T>::operator*=(T scalar) NzMatrix4<T>& NzMatrix4<T>::operator*=(T scalar)
{ {
m11 *= scalar; #if NAZARA_MATH_SAFE
m12 *= scalar; if (!m_sharedMatrix)
m13 *= scalar; {
m14 *= scalar; NazaraError("Undefined matrix");
m21 *= scalar; return *this;
m22 *= scalar; }
m23 *= scalar; #endif
m24 *= scalar;
m31 *= scalar; m_sharedMatrix->m11 *= scalar;
m32 *= scalar; m_sharedMatrix->m12 *= scalar;
m33 *= scalar; m_sharedMatrix->m13 *= scalar;
m34 *= scalar; m_sharedMatrix->m14 *= scalar;
m41 *= scalar; m_sharedMatrix->m21 *= scalar;
m42 *= scalar; m_sharedMatrix->m22 *= scalar;
m43 *= scalar; m_sharedMatrix->m23 *= scalar;
m44 *= scalar; m_sharedMatrix->m24 *= scalar;
m_sharedMatrix->m31 *= scalar;
m_sharedMatrix->m32 *= scalar;
m_sharedMatrix->m33 *= scalar;
m_sharedMatrix->m34 *= scalar;
m_sharedMatrix->m41 *= scalar;
m_sharedMatrix->m42 *= scalar;
m_sharedMatrix->m43 *= scalar;
m_sharedMatrix->m44 *= scalar;
return *this; return *this;
} }
@ -525,37 +707,37 @@ NzMatrix4<T>& NzMatrix4<T>::operator*=(T scalar)
template<typename T> template<typename T>
NzMatrix4<T> NzMatrix4<T>::LookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up) NzMatrix4<T> NzMatrix4<T>::LookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up)
{ {
NzMatrix4 mat; NzMatrix4 matrix;
mat.SetLookAt(eye, center, up); matrix.SetLookAt(eye, center, up);
return mat; return matrix;
} }
template<typename T> template<typename T>
NzMatrix4<T> NzMatrix4<T>::Perspective(T angle, T ratio, T zNear, T zFar) NzMatrix4<T> NzMatrix4<T>::Perspective(T angle, T ratio, T zNear, T zFar)
{ {
NzMatrix4 mat; NzMatrix4 matrix;
mat.SetPerspective(angle, ratio, zNear, zFar); matrix.SetPerspective(angle, ratio, zNear, zFar);
return mat; return matrix;
} }
template<typename T> template<typename T>
NzMatrix4<T> NzMatrix4<T>::Rotate(const NzQuaternion<T>& rotation) NzMatrix4<T> NzMatrix4<T>::Rotate(const NzQuaternion<T>& rotation)
{ {
NzMatrix4 mat; NzMatrix4 matrix;
mat.SetRotation(rotation); matrix.SetRotation(rotation);
return mat; return matrix;
} }
template<typename T> template<typename T>
NzMatrix4<T> NzMatrix4<T>::Scale(const NzVector3<T>& scale) NzMatrix4<T> NzMatrix4<T>::Scale(const NzVector3<T>& scale)
{ {
NzMatrix4 mat; NzMatrix4 matrix;
mat.SetScale(scale); matrix.SetScale(scale);
return mat; return matrix;
} }
template<typename T> template<typename T>
@ -568,9 +750,44 @@ NzMatrix4<T> NzMatrix4<T>::Translate(const NzVector3<T>& translation)
} }
template<typename T> template<typename T>
std::ostream& operator<<(std::ostream& out, const NzMatrix4<T>& mat) std::ostream& operator<<(std::ostream& out, const NzMatrix4<T>& matrix)
{ {
return out << mat.ToString(); return out << matrix.ToString();
} }
template<typename T>
void NzMatrix4<T>::EnsureOwnership()
{
if (m_sharedMatrix)
{
NazaraLock(m_sharedMatrix->mutex);
if (m_sharedMatrix->refCount > 1)
{
m_sharedMatrix->refCount--;
SharedMatrix* sharedMatrix = new SharedMatrix;
std::memcpy(&sharedMatrix->m11, &m_sharedMatrix->m11, 16*sizeof(T));
}
}
else
m_sharedMatrix = new SharedMatrix;
}
template<typename T>
void NzMatrix4<T>::ReleaseMatrix()
{
if (!m_sharedMatrix)
return;
NazaraMutexLock(m_sharedMatrix->mutex);
m_sharedMatrix->refCount--;
NazaraMutexUnlock(m_sharedMatrix->mutex);
if (m_sharedMatrix->refCount == 0)
delete m_sharedMatrix;
m_sharedMatrix = nullptr;
}
#include <Nazara/Core/DebugOff.hpp> #include <Nazara/Core/DebugOff.hpp>

View File

@ -0,0 +1,37 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
// Pas de header guard
#include <Nazara/Math/Config.hpp>
// Ces macros peuvent changer pour n'importe quel fichier qui l'utilise, dans une même unité de compilation
#undef NazaraLock
#undef NazaraMutex
#undef NazaraMutexAttrib
#undef NazaraMutexLock
#undef NazaraMutexUnlock
#undef NazaraNamedLock
#if NAZARA_MATH_THREADSAFE && (\
(NAZARA_THREADSAFETY_MATRIX3 && (defined(NAZARA_MATRIX3) || defined(NAZARA_MATRIX3_CPP))) || \
(NAZARA_THREADSAFETY_MATRIX4 && (defined(NAZARA_MATRIX4) || defined(NAZARA_MATRIX4_CPP))))
#include <Nazara/Core/Lock.hpp>
#include <Nazara/Core/Mutex.hpp>
#define NazaraLock(mutex) NzLock lock_mutex(mutex);
#define NazaraMutex(name) NzMutex name;
#define NazaraMutexAttrib(name, attribute) attribute NzMutex name;
#define NazaraMutexLock(mutex) mutex.Lock();
#define NazaraMutexUnlock(mutex) mutex.Unlock();
#define NazaraNamedLock(mutex, name) NzLock lock_##name(mutex);
#else
#define NazaraLock(mutex)
#define NazaraMutex(name)
#define NazaraMutexAttrib(name, attribute)
#define NazaraMutexLock(mutex)
#define NazaraMutexUnlock(mutex)
#define NazaraNamedLock(mutex, name)
#endif

View File

@ -4177,9 +4177,12 @@ NzString& NzString::operator=(const NzString& string)
ReleaseString(); ReleaseString();
m_sharedString = string.m_sharedString; m_sharedString = string.m_sharedString;
NazaraMutexLock(m_sharedString->mutex); if (m_sharedString != &emptyString)
m_sharedString->refCount++; {
NazaraMutexUnlock(m_sharedString->mutex); NazaraMutexLock(m_sharedString->mutex);
m_sharedString->refCount++;
NazaraMutexUnlock(m_sharedString->mutex);
}
return *this; return *this;
} }
@ -5026,6 +5029,9 @@ bool operator>=(const std::string& string, const NzString& nstring)
void NzString::EnsureOwnership() void NzString::EnsureOwnership()
{ {
if (m_sharedString == &emptyString)
return;
NazaraLock(m_sharedString->mutex); NazaraLock(m_sharedString->mutex);
if (m_sharedString->refCount > 1) if (m_sharedString->refCount > 1)
{ {
@ -5051,16 +5057,14 @@ void NzString::ReleaseString()
return; return;
NazaraMutexLock(m_sharedString->mutex); NazaraMutexLock(m_sharedString->mutex);
if (--m_sharedString->refCount == 0) m_sharedString->refCount--;
NazaraMutexUnlock(m_sharedString->mutex);
if (m_sharedString->refCount == 0)
{ {
NazaraMutexUnlock(m_sharedString->mutex);
delete[] m_sharedString->string; delete[] m_sharedString->string;
delete m_sharedString; delete m_sharedString;
} }
else
{
NazaraMutexUnlock(m_sharedString->mutex);
}
m_sharedString = &emptyString; m_sharedString = &emptyString;
} }