From 45f3fc4e2868b7e6503aef245074735b8dae646e Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 7 May 2012 13:02:07 +0200 Subject: [PATCH] Implemented COW into NzMatrix4; Optimized NzString COW --- include/Nazara/Core/Config.hpp | 16 +- include/Nazara/Core/ThreadSafety.hpp | 1 + include/Nazara/Math/Config.hpp | 8 + include/Nazara/Math/Matrix4.hpp | 51 ++- include/Nazara/Math/Matrix4.inl | 593 ++++++++++++++++++--------- include/Nazara/Math/ThreadSafety.hpp | 37 ++ src/Nazara/Core/String.cpp | 22 +- 7 files changed, 509 insertions(+), 219 deletions(-) create mode 100644 include/Nazara/Math/ThreadSafety.hpp diff --git a/include/Nazara/Core/Config.hpp b/include/Nazara/Core/Config.hpp index a2d597a10..549e10aa4 100644 --- a/include/Nazara/Core/Config.hpp +++ b/include/Nazara/Core/Config.hpp @@ -56,18 +56,18 @@ // Active les tests de sécurité basés sur le code (Conseillé pour le développement) #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 #if NAZARA_CORE_THREADSAFE - #define NAZARA_THREADSAFETY_APPLICATION 1 // NzApplication - #define NAZARA_THREADSAFETY_CLOCK 0 // NzClock - #define NAZARA_THREADSAFETY_DIRECTORY 1 // NzDirectory - #define NAZARA_THREADSAFETY_DYNLIB 1 // NzDynLib - #define NAZARA_THREADSAFETY_FILE 1 // NzFile + #define NAZARA_THREADSAFETY_BYTEARRAY 1 // NzByteArray (COW) + #define NAZARA_THREADSAFETY_CLOCK 0 // NzClock + #define NAZARA_THREADSAFETY_DIRECTORY 1 // NzDirectory + #define NAZARA_THREADSAFETY_DYNLIB 1 // NzDynLib + #define NAZARA_THREADSAFETY_FILE 1 // NzFile #define NAZARA_THREADSAFETY_HASHDIGEST 0 // NzHashDigest - #define NAZARA_THREADSAFETY_LOG 1 // NzLog - #define NAZARA_THREADSAFETY_STRING 1 // NzString + #define NAZARA_THREADSAFETY_LOG 1 // NzLog + #define NAZARA_THREADSAFETY_STRING 1 // NzString (COW) #define NAZARA_THREADSAFETY_STRINGSTREAM 0 // NzStringStream #endif diff --git a/include/Nazara/Core/ThreadSafety.hpp b/include/Nazara/Core/ThreadSafety.hpp index 6ffa86fc1..339c1abfe 100644 --- a/include/Nazara/Core/ThreadSafety.hpp +++ b/include/Nazara/Core/ThreadSafety.hpp @@ -6,6 +6,7 @@ #include +// 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 diff --git a/include/Nazara/Math/Config.hpp b/include/Nazara/Math/Config.hpp index ae8445ed5..c56f716d0 100644 --- a/include/Nazara/Math/Config.hpp +++ b/include/Nazara/Math/Config.hpp @@ -39,4 +39,12 @@ // Active les tests de sécurité basés sur le code (Conseillé pour le développement) #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 diff --git a/include/Nazara/Math/Matrix4.hpp b/include/Nazara/Math/Matrix4.hpp index b2c20244e..aab7e6efa 100644 --- a/include/Nazara/Math/Matrix4.hpp +++ b/include/Nazara/Math/Matrix4.hpp @@ -24,10 +24,11 @@ template class NzMatrix4 T r31, T r32, T r33, T r34, T r41, T r42, T r43, T r44); NzMatrix4(T matrix[16]); - //NzMatrix4(const NzMatrix3& mat); - template explicit NzMatrix4(const NzMatrix4& mat); - NzMatrix4(const NzMatrix4& mat) = default; - ~NzMatrix4() = default; + //NzMatrix4(const NzMatrix3& matrix); + template explicit NzMatrix4(const NzMatrix4& matrix); + NzMatrix4(const NzMatrix4& matrix); + NzMatrix4(NzMatrix4&& matrix); + ~NzMatrix4(); T GetDeterminant() const; NzMatrix4 GetInverse() const; @@ -44,9 +45,10 @@ template class NzMatrix4 T r31, T r32, T r33, T r34, T r41, T r42, T r43, T r44); void Set(T matrix[16]); - //NzMatrix4(const NzMatrix3& mat); - void Set(const NzMatrix4& mat); - template void Set(const NzMatrix4& mat); + //NzMatrix4(const NzMatrix3& matrix); + void Set(const NzMatrix4& matrix); + void Set(NzMatrix4&& matrix); + template void Set(const NzMatrix4& matrix); void SetIdentity(); void SetLookAt(const NzVector3& eye, const NzVector3& center, const NzVector3& up); void SetPerspective(T angle, T ratio, T zNear, T zFar); @@ -69,13 +71,16 @@ template class NzMatrix4 T& operator()(unsigned int x, unsigned int y); 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 operator*(const NzVector2& vector) const; NzVector3 operator*(const NzVector3& vector) const; NzVector4 operator*(const NzVector4& vector) const; NzMatrix4 operator*(T scalar) const; - NzMatrix4& operator*=(const NzMatrix4& mat); + NzMatrix4& operator*=(const NzMatrix4& matrix); NzMatrix4& operator*=(T scalar); static NzMatrix4 LookAt(const NzVector3& eye, const NzVector3& center, const NzVector3& up); @@ -84,13 +89,31 @@ template class NzMatrix4 static NzMatrix4 Scale(const NzVector3& scale); static NzMatrix4 Translate(const NzVector3& translation); - T m11, m12, m13, m14, - m21, m22, m23, m24, - m31, m32, m33, m34, - m41, m42, m43, m44; + struct SharedMatrix + { + SharedMatrix() : // Vivement GCC 4.7 sur Windows + 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 std::ostream& operator<<(std::ostream& out, const NzMatrix4& mat); +template std::ostream& operator<<(std::ostream& out, const NzMatrix4& matrix); typedef NzMatrix4 NzMatrix4d; typedef NzMatrix4 NzMatrix4f; diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index bd3637f48..ca3b68307 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include @@ -16,7 +17,8 @@ #include template -NzMatrix4::NzMatrix4() +NzMatrix4::NzMatrix4() : +m_sharedMatrix(nullptr) { } @@ -24,7 +26,8 @@ template NzMatrix4::NzMatrix4(T r11, T r12, T r13, T r14, T r21, T r22, T r23, T r24, 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, r21, r22, r23, r24, @@ -33,86 +36,148 @@ NzMatrix4::NzMatrix4(T r11, T r12, T r13, T r14, } template -NzMatrix4::NzMatrix4(T matrix[16]) +NzMatrix4::NzMatrix4(T matrix[16]) : +m_sharedMatrix(nullptr) { Set(matrix); } template template -NzMatrix4::NzMatrix4(const NzMatrix4& mat) +NzMatrix4::NzMatrix4(const NzMatrix4& matrix) : +m_sharedMatrix(nullptr) { - Set(mat); + Set(matrix); +} + +template +NzMatrix4::NzMatrix4(const NzMatrix4& matrix) : +m_sharedMatrix(nullptr) +{ + Set(matrix); +} + +template +NzMatrix4::NzMatrix4(NzMatrix4&& matrix) : +m_sharedMatrix(nullptr) +{ + Set(matrix); +} + +template +NzMatrix4::~NzMatrix4() +{ + ReleaseMatrix(); } template T NzMatrix4::GetDeterminant() const { - 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); - T D = m12 * (m23 * m34 - m33 * m24) - m22 * (m13 * m34 - m33 * m14) + m32 * (m13 * m24 - m23 * m14); + #if NAZARA_MATH_SAFE + if (!m_sharedMatrix) + { + 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 NzMatrix4 NzMatrix4::GetInverse() const { - NzMatrix4 mat; + #if NAZARA_MATH_SAFE + if (!m_sharedMatrix) + { + NazaraError("Undefined matrix"); + return NzMatrix4(); + } + #endif + + NzMatrix4 matrix; T det = GetDeterminant(); if (det != 0.0) { - mat.m11 = (m22 * (m33 * m44 - m34 * m43) - m32 * (m23 * m44 - m43 * m24) + m42 * (m23 * m34 - m33 * m24)) / det; - mat.m12 = -(m12 * (m33 * m44 - m43 * m34) - m32 * (m13 * m44 - m43 * m14) + m42 * (m13 * m34 - m33 * m14)) / det; - mat.m13 = (m12 * (m23 * m44 - m43 * m24) - m22 * (m13 * m44 - m43 * m14) + m42 * (m13 * m24 - m23 * m14)) / det; - mat.m14 = -(m12 * (m23 * m34 - m33 * m24) - m22 * (m13 * m34 - m33 * m14) + m32 * (m13 * m24 - m23 * m14)) / 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; + 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; + 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; + 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; - mat.m22 = (m11 * (m33 * m44 - m34 * m43) - m13 * (m31 * m44 - m34 * m41) + m14 * (m31 * m43 - m33 * m41)) / det; - mat.m23 = -(m11 * (m23 * m44 - m24 * m43) - m13 * (m21 * m44 - m24 * m41) + m14 * (m21 * m43 - m23 * m41)) / det; - mat.m24 = (m11 * (m23 * m34 - m24 * m33) - m13 * (m21 * m34 - m24 * m31) + m14 * (m21 * m33 - m23 * m31)) / 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; + 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; + 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; + 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; - mat.m32 = -(m11 * (m32 * m44 - m34 * m42) - m12 * (m31 * m44 - m34 * m41) + m14 * (m31 * m42 - m32 * m41)) / det; - mat.m33 = (m11 * (m22 * m44 - m24 * m42) - m12 * (m21 * m44 - m24 * m41) + m14 * (m21 * m42 - m22 * m41)) / det; - mat.m34 = -(m11 * (m22 * m34 - m24 * m32) - m12 * (m21 * m34 - m24 * m31) + m14 * (m21 * m32 - m22 * m31)) / 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; + 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; + 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; + 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; - mat.m42 = (m11 * (m32 * m43 - m33 * m42) - m12 * (m31 * m43 - m33 * m41) + m13 * (m31 * m42 - m32 * m41)) / det; - mat.m43 = -(m11 * (m22 * m43 - m23 * m42) - m12 * (m21 * m43 - m23 * m41) + m13 * (m21 * m42 - m22 * m41)) / det; - mat.m44 = (m11 * (m22 * m33 - m23 * m32) - m12 * (m21 * m33 - m23 * m31) + m13 * (m21 * m32 - m22 * m31)) / 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; + 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; + 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; + 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 NzVector3 NzMatrix4::GetScale() const { - return NzVector3(std::sqrt(m11 * m11 + m21 * m21 + m31 * m31), - std::sqrt(m12 * m12 + m22 * m22 + m32 * m32), - std::sqrt(m13 * m13 + m23 * m23 + m33 * m33)); + #if NAZARA_MATH_SAFE + if (!m_sharedMatrix) + { + NazaraError("Undefined matrix"); + return NzVector3(); + } + #endif + + return NzVector3(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 NzVector3 NzMatrix4::GetTranslation() const { + #if NAZARA_MATH_SAFE + if (!m_sharedMatrix) + { + NazaraError("Undefined matrix"); + return NzVector3(); + } + #endif + #if NAZARA_MATH_MATRIX_COLUMN_MAJOR - return NzVector3(m41, m42, m43); + return NzVector3(m_sharedMatrix->m41, m_sharedMatrix->m42, m_sharedMatrix->m43); #else - return NzVector3(m14, m24, m34); + return NzVector3(m_sharedMatrix->m14, m_sharedMatrix->m24, m_sharedMatrix->m34); #endif } template NzMatrix4 NzMatrix4::GetTransposed() const { - return NzMatrix4(m11, m21, m31, m41, - m12, m22, m32, m42, - m13, m23, m33, m43, - m14, m24, m34, m44); + #if NAZARA_MATH_SAFE + if (!m_sharedMatrix) + { + 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 @@ -124,15 +189,23 @@ bool NzMatrix4::HasNegativeScale() const template bool NzMatrix4::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::epsilon()) 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::epsilon()) 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::epsilon()) return true; @@ -145,56 +218,66 @@ void NzMatrix4::Set(T r11, T r12, T r13, T r14, T r31, T r32, T r33, T r34, T r41, T r42, T r43, T r44) { - m11 = r11; - m12 = r12; - m13 = r13; - m14 = r14; - m21 = r21; - m22 = r22; - m23 = r23; - m24 = r24; - m31 = r31; - m32 = r32; - m33 = r33; - m34 = r34; - m41 = r41; - m42 = r42; - m43 = r43; - m44 = r44; + EnsureOwnership(); + + m_sharedMatrix->m11 = r11; + m_sharedMatrix->m12 = r12; + m_sharedMatrix->m13 = r13; + m_sharedMatrix->m14 = r14; + m_sharedMatrix->m21 = r21; + m_sharedMatrix->m22 = r22; + m_sharedMatrix->m23 = r23; + m_sharedMatrix->m24 = r24; + m_sharedMatrix->m31 = r31; + m_sharedMatrix->m32 = r32; + m_sharedMatrix->m33 = r33; + m_sharedMatrix->m34 = r34; + m_sharedMatrix->m41 = r41; + m_sharedMatrix->m42 = r42; + m_sharedMatrix->m43 = r43; + m_sharedMatrix->m44 = r44; } -template void NzMatrix4::Set(T matrix[16]) +template +void NzMatrix4::Set(T matrix[16]) { + EnsureOwnership(); + // 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 void NzMatrix4::Set(const NzMatrix4& mat) +template +void NzMatrix4::Set(const NzMatrix4& matrix) { - // Pareil - std::memcpy(&m41, &mat.m41, 16*sizeof(T)); + ReleaseMatrix(); + + m_sharedMatrix = matrix.m_sharedMatrix; + if (m_sharedMatrix) + { + NazaraMutexLock(m_sharedMatrix->mutex); + m_sharedMatrix->refCount++; + NazaraMutexUnlock(m_sharedMatrix->mutex); + } +} + +template +void NzMatrix4::Set(NzMatrix4&& matrix) +{ + ReleaseMatrix(); + + m_sharedMatrix = matrix.m_sharedMatrix; + matrix.m_sharedMatrix = nullptr; } template template -void NzMatrix4::Set(const NzMatrix4& mat) +void NzMatrix4::Set(const NzMatrix4& matrix) { - m11 = static_cast(mat.m11); - m12 = static_cast(mat.m12); - m13 = static_cast(mat.m13); - m14 = static_cast(mat.m14); - m21 = static_cast(mat.m21); - m22 = static_cast(mat.m22); - m23 = static_cast(mat.m23); - m24 = static_cast(mat.m24); - m31 = static_cast(mat.m31); - m32 = static_cast(mat.m32); - m33 = static_cast(mat.m33); - m34 = static_cast(mat.m34); - m41 = static_cast(mat.m41); - m42 = static_cast(mat.m42); - m43 = static_cast(mat.m43); - m44 = static_cast(mat.m44); + Set(static_cast(matrix.m11), static_cast(matrix.m12), static_cast(matrix.m13), static_cast(matrix.m14), + static_cast(matrix.m21), static_cast(matrix.m22), static_cast(matrix.m23), static_cast(matrix.m24), + static_cast(matrix.m31), static_cast(matrix.m32), static_cast(matrix.m33), static_cast(matrix.m34), + static_cast(matrix.m41), static_cast(matrix.m42), static_cast(matrix.m43), static_cast(matrix.m44)); } template @@ -311,47 +394,81 @@ void NzMatrix4::SetZero() template NzString NzMatrix4::ToString() const { - NzStringStream ss; + if (!m_sharedMatrix) + return "Matrix4(undefined)"; - return ss << "Matrix4(" << m11 << ", " << m12 << ", " << m13 << ", " << m14 << ",\n" - << " " << m21 << ", " << m22 << ", " << m23 << ", " << m24 << ",\n" - << " " << m31 << ", " << m32 << ", " << m33 << ", " << m34 << ",\n" - << " " << m41 << ", " << m42 << ", " << m43 << ", " << m44 << ')'; + NzStringStream ss; + return ss << "Matrix4(" << m_sharedMatrix->m11 << ", " << m_sharedMatrix->m12 << ", " << m_sharedMatrix->m13 << ", " << m_sharedMatrix->m14 << ",\n" + << " " << m_sharedMatrix->m21 << ", " << m_sharedMatrix->m22 << ", " << m_sharedMatrix->m23 << ", " << m_sharedMatrix->m24 << ",\n" + << " " << 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 NzVector2 NzMatrix4::Transform(const NzVector2& vector, T z, T w) const { - return NzVector2(m11 * vector.x + m12 * vector.y + m13 * z + m14 * w, - m21 * vector.x + m22 * vector.y + m23 * z + m24 * w); + #if NAZARA_MATH_SAFE + if (!m_sharedMatrix) + { + NazaraError("Undefined matrix"); + return vector; + } + #endif + + return NzVector2(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 NzVector3 NzMatrix4::Transform(const NzVector3& vector, T w) const { - return NzVector3(m11 * vector.x + m12 * vector.y + m13 * vector.z + m14 * w, - m21 * vector.x + m22 * vector.y + m23 * vector.z + m24 * w, - m31 * vector.x + m32 * vector.y + m33 * vector.z + m34 * w); + #if NAZARA_MATH_SAFE + if (!m_sharedMatrix) + { + NazaraError("Undefined matrix"); + return vector; + } + #endif + + return NzVector3(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 NzVector4 NzMatrix4::Transform(const NzVector4& vector) const { - return NzVector4(m11 * vector.x + m12 * vector.y + m13 * vector.z + m14 * vector.w, - m21 * vector.x + m22 * vector.y + m23 * vector.z + m24 * vector.w, - m31 * vector.x + m32 * vector.y + m33 * vector.z + m34 * vector.w, - m41 * vector.x + m42 * vector.y + m43 * vector.z + m44 * vector.w); + #if NAZARA_MATH_SAFE + if (!m_sharedMatrix) + { + NazaraError("Undefined matrix"); + return vector; + } + #endif + + return NzVector4(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 NzMatrix4& NzMatrix4::Transpose() { - std::swap(m12, m21); - std::swap(m13, m31); - std::swap(m14, m41); - std::swap(m23, m32); - std::swap(m24, m42); - std::swap(m34, m43); + #if NAZARA_MATH_SAFE + if (!m_sharedMatrix) + { + NazaraError("Undefined matrix"); + return *this; + } + #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; } @@ -359,13 +476,31 @@ NzMatrix4& NzMatrix4::Transpose() template NzMatrix4::operator T*() { - return &m11; + #if NAZARA_MATH_SAFE + if (!m_sharedMatrix) + { + NazaraError("Undefined matrix"); + return nullptr; + } + #endif + + EnsureOwnership(); + + return &m_sharedMatrix->m11; } template NzMatrix4::operator const T*() const { - return &m11; + #if NAZARA_MATH_SAFE + if (!m_sharedMatrix) + { + NazaraError("Undefined matrix"); + return nullptr; + } + #endif + + return &m_sharedMatrix->m11; } template @@ -381,13 +516,21 @@ T& NzMatrix4::operator()(unsigned int x, unsigned int y) } #endif - return (&m11)[x*4+y]; + EnsureOwnership(); + + return (&m_sharedMatrix->m11)[x*4+y]; } template const T& NzMatrix4::operator()(unsigned int x, unsigned int y) const { #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) { NzStringStream ss; @@ -397,39 +540,63 @@ const T& NzMatrix4::operator()(unsigned int x, unsigned int y) const } #endif - return (&m11)[x*4+y]; + return (&m_sharedMatrix->m11)[x*4+y]; } template -NzMatrix4 NzMatrix4::operator*(const NzMatrix4& mat) const +NzMatrix4& NzMatrix4::operator=(const NzMatrix4& matrix) { - NzMatrix4 matrix; + Set(matrix); + + return *this; +} + +template +NzMatrix4& NzMatrix4::operator=(NzMatrix4&& matrix) +{ + Set(matrix); + + return *this; +} + +template +NzMatrix4 NzMatrix4::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 j = 0; j < 4; j++) { 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 NzMatrix4(m11 * mat.m11 + m21 * mat.m12 + m31 * mat.m13 + m41 * mat.m14, - m12 * mat.m11 + m22 * mat.m12 + m32 * mat.m13 + m42 * mat.m14, - m13 * mat.m11 + m23 * mat.m12 + m33 * mat.m13 + m43 * mat.m14, - m14 * mat.m11 + m24 * mat.m12 + m34 * mat.m13 + m44 * mat.m14, - m11 * mat.m21 + m21 * mat.m22 + m31 * mat.m23 + m41 * mat.m24, - m12 * mat.m21 + m22 * mat.m22 + m32 * mat.m23 + m42 * mat.m24, - m13 * mat.m21 + m23 * mat.m22 + m33 * mat.m23 + m43 * mat.m24, - m14 * mat.m21 + m24 * mat.m22 + m34 * mat.m23 + m44 * mat.m24, - m11 * mat.m31 + m21 * mat.m32 + m31 * mat.m33 + m41 * mat.m34, - m12 * mat.m31 + m22 * mat.m32 + m32 * mat.m33 + m42 * mat.m34, - m13 * mat.m31 + m23 * mat.m32 + m33 * mat.m33 + m43 * mat.m34, - m14 * mat.m31 + m24 * mat.m32 + m34 * mat.m33 + m44 * mat.m34, - m11 * mat.m41 + m21 * mat.m42 + m31 * mat.m43 + m41 * mat.m44, - m12 * mat.m41 + m22 * mat.m42 + m32 * mat.m43 + m42 * mat.m44, - m13 * mat.m41 + m23 * mat.m42 + m33 * mat.m43 + m43 * mat.m44, - m14 * mat.m41 + m24 * mat.m42 + m34 * mat.m43 + m44 * mat.m44);*/ + return mat; + /*return NzMatrix4(m11 * matrix.m11 + m21 * matrix.m12 + m31 * matrix.m13 + m41 * matrix.m14, + m12 * matrix.m11 + m22 * matrix.m12 + m32 * matrix.m13 + m42 * matrix.m14, + m13 * matrix.m11 + m23 * matrix.m12 + m33 * matrix.m13 + m43 * matrix.m14, + m14 * matrix.m11 + m24 * matrix.m12 + m34 * matrix.m13 + m44 * matrix.m14, + m11 * matrix.m21 + m21 * matrix.m22 + m31 * matrix.m23 + m41 * matrix.m24, + m12 * matrix.m21 + m22 * matrix.m22 + m32 * matrix.m23 + m42 * matrix.m24, + m13 * matrix.m21 + m23 * matrix.m22 + m33 * matrix.m23 + m43 * matrix.m24, + m14 * matrix.m21 + m24 * matrix.m22 + m34 * matrix.m23 + m44 * matrix.m24, + m11 * matrix.m31 + m21 * matrix.m32 + m31 * matrix.m33 + m41 * matrix.m34, + m12 * matrix.m31 + m22 * matrix.m32 + m32 * matrix.m33 + m42 * matrix.m34, + m13 * matrix.m31 + m23 * matrix.m32 + m33 * matrix.m33 + m43 * matrix.m34, + m14 * matrix.m31 + m24 * matrix.m32 + m34 * matrix.m33 + m44 * matrix.m34, + m11 * matrix.m41 + m21 * matrix.m42 + m31 * matrix.m43 + m41 * matrix.m44, + m12 * matrix.m41 + m22 * matrix.m42 + m32 * matrix.m43 + m42 * matrix.m44, + m13 * matrix.m41 + m23 * matrix.m42 + m33 * matrix.m43 + m43 * matrix.m44, + m14 * matrix.m41 + m24 * matrix.m42 + m34 * matrix.m43 + m44 * matrix.m44);*/ } @@ -454,47 +621,54 @@ NzVector4 NzMatrix4::operator*(const NzVector4& vector) const template NzMatrix4 NzMatrix4::operator*(T scalar) const { - return NzMatrix4(m11 * scalar, m12 * scalar, m13 * scalar, m14 * scalar, - m21 * scalar, m22 * scalar, m23 * scalar, m24 * scalar, - m31 * scalar, m32 * scalar, m33 * scalar, m34 * scalar, - m41 * scalar, m42 * scalar, m43 * scalar, m44 * scalar); + #if NAZARA_MATH_SAFE + if (!m_sharedMatrix) + { + 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 -NzMatrix4& NzMatrix4::operator*=(const NzMatrix4& mat) +NzMatrix4& NzMatrix4::operator*=(const NzMatrix4& matrix) { - T r11 = m11 * mat.m11 + m21 * mat.m12 + m31 * mat.m13 + m41 * mat.m14; - T r12 = m12 * mat.m11 + m22 * mat.m12 + m32 * mat.m13 + m42 * mat.m14; - 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; - T r21 = m11 * mat.m21 + m21 * mat.m22 + m31 * mat.m23 + m41 * mat.m24; - 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; - 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; + #if NAZARA_MATH_SAFE + if (!m_sharedMatrix) + { + NazaraError("Undefined matrix"); + return *this; + } + #endif - m44 = m14 * mat.m41 + m24 * mat.m42 + m34 * mat.m43 + m44 * mat.m44; - m43 = r43; - m42 = r42; - m41 = r41; - m34 = r34; - m33 = r33; - m32 = r32; - m31 = r31; - m24 = r24; - m23 = r23; - m22 = r22; - m21 = r21; - m14 = r14; - m13 = r13; - m12 = r12; - m11 = r11; + // On calcule dans des variables temporaires + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; } @@ -502,22 +676,30 @@ NzMatrix4& NzMatrix4::operator*=(const NzMatrix4& mat) template NzMatrix4& NzMatrix4::operator*=(T scalar) { - m11 *= scalar; - m12 *= scalar; - m13 *= scalar; - m14 *= scalar; - m21 *= scalar; - m22 *= scalar; - m23 *= scalar; - m24 *= scalar; - m31 *= scalar; - m32 *= scalar; - m33 *= scalar; - m34 *= scalar; - m41 *= scalar; - m42 *= scalar; - m43 *= scalar; - m44 *= scalar; + #if NAZARA_MATH_SAFE + if (!m_sharedMatrix) + { + NazaraError("Undefined matrix"); + return *this; + } + #endif + + 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; return *this; } @@ -525,37 +707,37 @@ NzMatrix4& NzMatrix4::operator*=(T scalar) template NzMatrix4 NzMatrix4::LookAt(const NzVector3& eye, const NzVector3& center, const NzVector3& up) { - NzMatrix4 mat; - mat.SetLookAt(eye, center, up); + NzMatrix4 matrix; + matrix.SetLookAt(eye, center, up); - return mat; + return matrix; } template NzMatrix4 NzMatrix4::Perspective(T angle, T ratio, T zNear, T zFar) { - NzMatrix4 mat; - mat.SetPerspective(angle, ratio, zNear, zFar); + NzMatrix4 matrix; + matrix.SetPerspective(angle, ratio, zNear, zFar); - return mat; + return matrix; } template NzMatrix4 NzMatrix4::Rotate(const NzQuaternion& rotation) { - NzMatrix4 mat; - mat.SetRotation(rotation); + NzMatrix4 matrix; + matrix.SetRotation(rotation); - return mat; + return matrix; } template NzMatrix4 NzMatrix4::Scale(const NzVector3& scale) { - NzMatrix4 mat; - mat.SetScale(scale); + NzMatrix4 matrix; + matrix.SetScale(scale); - return mat; + return matrix; } template @@ -568,9 +750,44 @@ NzMatrix4 NzMatrix4::Translate(const NzVector3& translation) } template -std::ostream& operator<<(std::ostream& out, const NzMatrix4& mat) +std::ostream& operator<<(std::ostream& out, const NzMatrix4& matrix) { - return out << mat.ToString(); + return out << matrix.ToString(); } +template +void NzMatrix4::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 +void NzMatrix4::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 diff --git a/include/Nazara/Math/ThreadSafety.hpp b/include/Nazara/Math/ThreadSafety.hpp new file mode 100644 index 000000000..e5c7bbde2 --- /dev/null +++ b/include/Nazara/Math/ThreadSafety.hpp @@ -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 + +// 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 + #include + + #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 diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 83f99199c..0ce229ab1 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -4177,9 +4177,12 @@ NzString& NzString::operator=(const NzString& string) ReleaseString(); m_sharedString = string.m_sharedString; - NazaraMutexLock(m_sharedString->mutex); - m_sharedString->refCount++; - NazaraMutexUnlock(m_sharedString->mutex); + if (m_sharedString != &emptyString) + { + NazaraMutexLock(m_sharedString->mutex); + m_sharedString->refCount++; + NazaraMutexUnlock(m_sharedString->mutex); + } return *this; } @@ -5026,6 +5029,9 @@ bool operator>=(const std::string& string, const NzString& nstring) void NzString::EnsureOwnership() { + if (m_sharedString == &emptyString) + return; + NazaraLock(m_sharedString->mutex); if (m_sharedString->refCount > 1) { @@ -5051,16 +5057,14 @@ void NzString::ReleaseString() return; 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; } - else - { - NazaraMutexUnlock(m_sharedString->mutex); - } m_sharedString = &emptyString; }