From 3f81ab4742a1851dafb37e6db761c9490c2f7fbd Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 15 Jun 2014 01:13:40 +0200 Subject: [PATCH 01/15] Alphabetical commit Former-commit-id: 3f04840ed109e31cef0e6eda085320aaa17c9f2f --- src/Nazara/Audio/Music.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index aa25ac2bf..4e3a62c44 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -22,8 +22,8 @@ struct NzMusicImpl NzSoundStream* stream; NzThread thread; bool loop = false; - bool streaming = false; bool paused = false; + bool streaming = false; unsigned int sampleRate; }; From 55c205a5e56c7dd35fab51d470952b5bdc027d2e Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 15 Jun 2014 01:17:57 +0200 Subject: [PATCH 02/15] Improved MemoryPool class It's size is now dynamic (defaulted to 1024) Added MemoryPool::GetFreeBlocks() Added MemoryPool::GetSize() Tried to make it thread-safe It supports dynamics allocations (in case where it can't allocate memory from the pool for some reasons) Former-commit-id: d42804a47eaafbbc1c0b151f8fcaeb5ddb086ff5 --- include/Nazara/Core/MemoryPool.hpp | 12 +++-- include/Nazara/Core/MemoryPool.inl | 77 +++++++++++++++++------------- 2 files changed, 52 insertions(+), 37 deletions(-) diff --git a/include/Nazara/Core/MemoryPool.hpp b/include/Nazara/Core/MemoryPool.hpp index 0e9fb32e9..64efc4ccd 100644 --- a/include/Nazara/Core/MemoryPool.hpp +++ b/include/Nazara/Core/MemoryPool.hpp @@ -8,27 +8,33 @@ #define NAZARA_MEMORYPOOL_HPP #include +#include #include -template +template class NzMemoryPool { public: - NzMemoryPool(); + NzMemoryPool(unsigned int size = 1024); ~NzMemoryPool() = default; template T* Allocate(); void* Allocate(unsigned int size); + void Free(void* ptr); + unsigned int GetFreeBlocks() const; + unsigned int GetSize() const; + private: NzMemoryPool(NzMemoryPool* pool); std::unique_ptr m_freeList; std::unique_ptr m_pool; std::unique_ptr m_next; + std::atomic_uint m_freeCount; NzMemoryPool* m_previous; - unsigned int m_freeCount; + unsigned int m_size; }; #include diff --git a/include/Nazara/Core/MemoryPool.inl b/include/Nazara/Core/MemoryPool.inl index 592fb38fc..1d44075ad 100644 --- a/include/Nazara/Core/MemoryPool.inl +++ b/include/Nazara/Core/MemoryPool.inl @@ -5,70 +5,67 @@ #include #include -template -NzMemoryPool::NzMemoryPool() : +template +NzMemoryPool::NzMemoryPool(unsigned int count) : +m_freeCount(count), m_previous(nullptr), -m_freeCount(count) +m_size(count) { - m_pool.reset(new nzUInt8[typeSize * count]); + m_pool.reset(new nzUInt8[blockSize * count]); m_freeList.reset(new void*[count]); // Remplissage de la free list for (unsigned int i = 0; i < count; ++i) - m_freeList[i] = &m_pool[typeSize * (count-i-1)]; + m_freeList[i] = &m_pool[blockSize * (count-i-1)]; } -template -NzMemoryPool::NzMemoryPool(NzMemoryPool* pool) : -NzMemoryPool() +template +NzMemoryPool::NzMemoryPool(NzMemoryPool* pool) : +NzMemoryPool(pool->m_size) { m_previous = pool; } -template +template template -T* NzMemoryPool::Allocate() +T* NzMemoryPool::Allocate() { - static_assert(sizeof(T) <= typeSize, "This type is too large for this memory pool"); + static_assert(sizeof(T) <= blockSize, "This type is too large for this memory pool"); return static_cast(Allocate(sizeof(T))); } -template -void* NzMemoryPool::Allocate(unsigned int size) +template +void* NzMemoryPool::Allocate(unsigned int size) { - if (size > typeSize) + if (size <= blockSize) { - throw std::bad_alloc(); - return nullptr; + if (m_freeCount > 0) + return m_freeList[--m_freeCount]; + else if (canGrow) + { + if (!m_next) + m_next.reset(new NzMemoryPool(this)); + + return m_next->Allocate(size); + } } - if (m_freeCount > 0) - return m_freeList[--m_freeCount]; - else if (canGrow) - { - if (!m_next) - m_next.reset(new NzMemoryPool(this)); - - return m_next->Allocate(size); - } - - throw std::bad_alloc(); - return nullptr; + return operator new(size); } -template -void NzMemoryPool::Free(void* ptr) +template +void NzMemoryPool::Free(void* ptr) { if (ptr) { // Le pointer nous appartient-il ? nzUInt8* freePtr = static_cast(ptr); nzUInt8* poolPtr = m_pool.get(); - if (freePtr >= poolPtr && freePtr < poolPtr + typeSize*count) + if (freePtr >= poolPtr && freePtr < poolPtr + blockSize*m_size) { #if NAZARA_CORE_SAFE - if ((freePtr - poolPtr) % typeSize != 0) + if ((freePtr - poolPtr) % blockSize != 0) { throw std::runtime_error("Pointer does not belong to memory pool"); return; @@ -78,7 +75,7 @@ void NzMemoryPool::Free(void* ptr) m_freeList[m_freeCount++] = ptr; // Si nous sommes vide et l'extension d'un autre pool, on se suicide - if (m_freeCount == count && m_previous && !m_next) + if (m_freeCount == m_size && m_previous && !m_next) { m_previous->m_next.release(); delete this; // Suicide @@ -89,9 +86,21 @@ void NzMemoryPool::Free(void* ptr) if (m_next) m_next->Free(ptr); else - throw std::runtime_error("Pointer does not belong to memory pool"); + operator delete(ptr); } } } +template +unsigned int NzMemoryPool::GetFreeBlocks() const +{ + return m_freeCount; +} + +template +unsigned int NzMemoryPool::GetSize() const +{ + return m_size; +} + #include From dc3f3eb344372c74e741bf9b44993af1aba459e6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 15 Jun 2014 01:55:07 +0200 Subject: [PATCH 03/15] Fixed some of the pull request code in order to merge it Former-commit-id: d8a9734fc622cb57f98b3b6abd2579922d562aa0 --- examples/HardwareInfo/main.cpp | 8 ++- include/Nazara/Math/Box.inl | 8 +-- include/Nazara/Math/Frustum.inl | 4 +- include/Nazara/Math/Matrix4.inl | 4 +- include/Nazara/Math/OrientedBox.inl | 17 ++----- include/Nazara/Math/Rect.hpp | 2 +- include/Nazara/Math/Rect.inl | 2 + include/Nazara/Math/Sphere.hpp | 1 - include/Nazara/Math/Sphere.inl | 54 +++++++++++++-------- src/Nazara/Core/Win32/TaskSchedulerImpl.cpp | 4 +- 10 files changed, 56 insertions(+), 48 deletions(-) diff --git a/examples/HardwareInfo/main.cpp b/examples/HardwareInfo/main.cpp index 07beced54..d1a12dade 100644 --- a/examples/HardwareInfo/main.cpp +++ b/examples/HardwareInfo/main.cpp @@ -24,9 +24,6 @@ int main() // On va afficher le tout via un ostringstream, pour écrire dans la console et aussi dans un fichier std::ostringstream oss; - - char accentAigu = static_cast(130); // C'est crade, mais ça marche chez 95% des Windowsiens - oss << "--Processeur--" << std::endl; // Plutôt que d'initialiser le Renderer de Nazara, nous initialisons les deux classes utilisées ici // Elles sont compatibles avec NzInitialiser et seront donc libérées automatiquement @@ -44,7 +41,7 @@ int main() oss << std::endl; // Ensuite, Nazara récupère les capacités du processeur, dont des jeux d'extensions supplémentaires - oss << "Report des capacit" << accentAigu << "s: " << std::endl; + oss << "Rapport des capacites: " << std::endl;// Pas d'accent car écriture dans un fichier (et on ne va pas s'embêter avec ça) printCap(oss, "-64bits", NzHardwareInfo::HasCapability(nzProcessorCap_x64)); printCap(oss, "-AVX", NzHardwareInfo::HasCapability(nzProcessorCap_AVX)); printCap(oss, "-FMA3", NzHardwareInfo::HasCapability(nzProcessorCap_FMA3)); @@ -81,7 +78,7 @@ int main() oss << std::endl; // Ainsi qu'un report des capacités de la carte graphique (avec le driver actuel) - oss << "Report des capacit" << accentAigu << "s: " << std::endl; + oss << "Rapport des capacites: " << std::endl; // Pas d'accent car écriture dans un fichier (et on ne va pas s'embêter avec ça) printCap(oss, "-Calculs 64bits", NzOpenGL::IsSupported(nzOpenGLExtension_FP64)); printCap(oss, "-Compression de textures (s3tc)", NzOpenGL::IsSupported(nzOpenGLExtension_TextureCompression_s3tc)); printCap(oss, "-Filtrage anisotrope", NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter)); @@ -108,6 +105,7 @@ int main() reportFile.Write(oss.str()); // Conversion implicite en NzString reportFile.Close(); + char accentAigu = static_cast(130); // C'est crade, mais ça marche chez 95% des Windowsiens std::cout << "Un fichier (RapportHardwareInfo.txt) contenant le rapport a " << accentAigu << 't' << accentAigu << " cr" << accentAigu << accentAigu << std::endl; } else diff --git a/include/Nazara/Math/Box.inl b/include/Nazara/Math/Box.inl index 989e7108e..e8f9b8fed 100644 --- a/include/Nazara/Math/Box.inl +++ b/include/Nazara/Math/Box.inl @@ -159,7 +159,7 @@ NzSphere NzBox::GetBoundingSphere() const template NzVector3 NzBox::GetCenter() const { - return GetPosition() + F(0.5)*GetLengths(); + return GetPosition() + GetLengths()/F(2.0); } template @@ -237,7 +237,7 @@ template T NzBox::GetSquaredRadius() const { NzVector3 size(GetLengths()); - size *= F(0.5); // La taille étant relative à la position (minimum) de la boite et non pas à son centre + size /= F(2.0); // La taille étant relative à la position (minimum) de la boite et non pas à son centre return size.GetSquaredLength(); } @@ -394,7 +394,7 @@ template NzBox& NzBox::Transform(const NzMatrix4& matrix, bool applyTranslation) { NzVector3 center = matrix.Transform(GetCenter(), (applyTranslation) ? F(1.0) : F(0.0)); // Valeur multipliant la translation - NzVector3 halfSize = GetLengths() * F(0.5); + NzVector3 halfSize = GetLengths()/F(2.0); halfSize.Set(std::fabs(matrix(0,0))*halfSize.x + std::fabs(matrix(1,0))*halfSize.y + std::fabs(matrix(2,0))*halfSize.z, std::fabs(matrix(0,1))*halfSize.x + std::fabs(matrix(1,1))*halfSize.y + std::fabs(matrix(2,1))*halfSize.z, @@ -465,6 +465,7 @@ NzBox& NzBox::operator*=(T scalar) width *= scalar; height *= scalar; depth *= scalar; + return *this; } @@ -474,6 +475,7 @@ NzBox& NzBox::operator*=(const NzVector3& vec) width *= vec.x; height *= vec.y; depth *= vec.z; + return *this; } diff --git a/include/Nazara/Math/Frustum.inl b/include/Nazara/Math/Frustum.inl index 300031d88..8541a34f1 100644 --- a/include/Nazara/Math/Frustum.inl +++ b/include/Nazara/Math/Frustum.inl @@ -24,9 +24,9 @@ template NzFrustum& NzFrustum::Build(T angle, T ratio, T zNear, T zFar, const NzVector3& eye, const NzVector3& target, const NzVector3& up) { #if NAZARA_MATH_ANGLE_RADIAN - angle *= F(0.5); + angle /= F(2.0); #else - angle = NzDegreeToRadian(angle * F(0.5)); + angle = NzDegreeToRadian(angle/F(2.0)); #endif T tangent = std::tan(angle); diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index 173653ebb..2531b51dd 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -573,9 +573,9 @@ NzMatrix4& NzMatrix4::MakePerspective(T angle, T ratio, T zNear, T zFar) { // http://msdn.microsoft.com/en-us/library/windows/desktop/bb204945(v=vs.85).aspx #if NAZARA_MATH_ANGLE_RADIAN - angle *= F(0.5); + angle /= F(2.0); #else - angle = NzDegreeToRadian(angle * F(0.5)); + angle = NzDegreeToRadian(angle/F(2.0)); #endif T yScale = F(1.0) / std::tan(angle); diff --git a/include/Nazara/Math/OrientedBox.inl b/include/Nazara/Math/OrientedBox.inl index fcc91e4d1..33a131c72 100644 --- a/include/Nazara/Math/OrientedBox.inl +++ b/include/Nazara/Math/OrientedBox.inl @@ -7,6 +7,8 @@ #include #include +///DOC: Pour que les coins soient valides, la méthode Update doit être appelée + #define F(a) static_cast(a) template @@ -60,8 +62,7 @@ template NzOrientedBox& NzOrientedBox::MakeZero() { localBox.MakeZero(); - for (unsigned int i = 0; i <= nzCorner_Max; ++i) - m_corners[i].Set(NzVector3::Zero()); + return *this; } @@ -70,8 +71,6 @@ NzOrientedBox& NzOrientedBox::Set(T X, T Y, T Z, T Width, T Height, T Dept { localBox.Set(X, Y, Z, Width, Height, Depth); - for (unsigned int i = 0; i <= nzCorner_Max; ++i) - m_corners[i].Set(localBox.GetCorner(static_cast(i))); return *this; } @@ -80,8 +79,6 @@ NzOrientedBox& NzOrientedBox::Set(const NzBox& box) { localBox.Set(box); - for (unsigned int i = 0; i <= nzCorner_Max; ++i) - m_corners[i].Set(localBox.GetCorner(static_cast(i))); return *this; } @@ -98,8 +95,6 @@ NzOrientedBox& NzOrientedBox::Set(const NzVector3& vec1, const NzVector { localBox.Set(vec1, vec2); - for (unsigned int i = 0; i <= nzCorner_Max; ++i) - m_corners[i].Set(localBox.GetCorner(static_cast(i))); return *this; } @@ -134,7 +129,7 @@ template void NzOrientedBox::Update(const NzMatrix4& transformMatrix) { for (unsigned int i = 0; i <= nzCorner_Max; ++i) - m_corners[i] = transformMatrix.Transform(m_corners[i]); + m_corners[i] = transformMatrix.Transform(localBox.GetCorner(static_cast(i))); } template @@ -189,8 +184,6 @@ NzOrientedBox NzOrientedBox::operator*(T scalar) const NzOrientedBox box(*this); box *= scalar; - for (unsigned int i = 0; i <= nzCorner_Max; ++i) - box.m_corners[i].Set(box.GetCorner(static_cast(i))); return box; } @@ -199,8 +192,6 @@ NzOrientedBox& NzOrientedBox::operator*=(T scalar) { localBox *= scalar; - for (unsigned int i = 0; i <= nzCorner_Max; ++i) - m_corners[i].Set(localBox.GetCorner(static_cast(i))); return *this; } diff --git a/include/Nazara/Math/Rect.hpp b/include/Nazara/Math/Rect.hpp index df7611b13..a133b7ed6 100644 --- a/include/Nazara/Math/Rect.hpp +++ b/include/Nazara/Math/Rect.hpp @@ -68,7 +68,7 @@ class NzRect NzRect& operator*=(T scalar); NzRect& operator*=(const NzVector2& vec); - NzRect& operator/=(T scalar); + NzRect& operator/=(T scalar); NzRect& operator/=(const NzVector2& vec); bool operator==(const NzRect& rect) const; diff --git a/include/Nazara/Math/Rect.inl b/include/Nazara/Math/Rect.inl index b2fd3a3e4..ab35b30c5 100644 --- a/include/Nazara/Math/Rect.inl +++ b/include/Nazara/Math/Rect.inl @@ -353,6 +353,7 @@ NzRect& NzRect::operator*=(T scalar) { width *= scalar; height *= scalar; + return *this; } @@ -361,6 +362,7 @@ NzRect& NzRect::operator*=(const NzVector2& vec) { width *= vec.x; height *= vec.y; + return *this; } diff --git a/include/Nazara/Math/Sphere.hpp b/include/Nazara/Math/Sphere.hpp index 975893076..64378a949 100644 --- a/include/Nazara/Math/Sphere.hpp +++ b/include/Nazara/Math/Sphere.hpp @@ -8,7 +8,6 @@ #define NAZARA_SPHERE_HPP #include -#include #include template diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index 2f74945dc..9c56fac16 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -81,7 +82,6 @@ template NzSphere& NzSphere::ExtendTo(T X, T Y, T Z) { T distance = SquaredDistance(X, Y, Z); - if (distance > radius*radius) radius = std::sqrt(distance); @@ -120,32 +120,48 @@ NzVector3 NzSphere::GetPositiveVertex(const NzVector3& normal) const template bool NzSphere::Intersect(const NzBox& box) const { - // Arvo's algorithm. - T dmin = T(0); - if (x < box.x) - dmin += (x - box.x) * (x - box.x); - else if (x > box.x + box.width) - dmin += (x - (box.x + box.width)) * (x - (box.x + box.width)); + // Arvo's algorithm. + T squaredDistance = T(0.0); + if (x < box.x) + { + T diff = x - box.x; + squaredDistance += diff*diff; + } + else if (x > box.x + box.width) + { + T diff = x - (box.x + box.width); + squaredDistance += diff*diff; + } - if (y < box.y) - dmin += (y - box.y) * (y - box.y); - else if (x > box.x + box.width) - dmin += (y - (box.y + box.height)) * (y - (box.y + box.height)); + if (y < box.y) + { + T diff = y - box.y; + squaredDistance += diff*diff; + } + else if (y > box.y + box.height) + { + T diff = y - (box.y + box.height); + squaredDistance += diff*diff; + } - if (z < box.z) - dmin += (z - box.z) * (z - box.z); - else if (x > box.x + box.width) - dmin += (z - (box.z + box.depth)) * (z - (box.z + box.depth)); + if (z < box.z) + { + T diff = z - box.z; + squaredDistance += diff*diff; + } + else if (z > box.z + box.depth) + { + T diff = z - (box.z + box.depth); + squaredDistance += diff*diff; + } - if (dmin <= radius * radius) - return true; - return false; + return squaredDistance <= radius * radius; } template bool NzSphere::Intersect(const NzSphere& sphere) const { - return std::abs(SquaredDistance(sphere.x, sphere.y, sphere.z) - radius*radius) <= sphere.radius*sphere.radius; + return SquaredDistance(sphere.x, sphere.y, sphere.z) - radius*radius <= sphere.radius*sphere.radius; } template diff --git a/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp b/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp index 0dccbff11..c55d84202 100644 --- a/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp +++ b/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp @@ -4,10 +4,10 @@ #include #include -#include #include -#include +#include // std::ldiv #include +#include bool NzTaskSchedulerImpl::Initialize(unsigned int workerCount) { From 6751baaadbadac2edc7ef106645122fc5d79cf86 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 17 Jun 2014 11:38:47 +0200 Subject: [PATCH 04/15] Added Gawaboumga to the "Thanks to" list Former-commit-id: 144487c12be17d39a7da27d6aa1ff78b28cafe2e --- readme.md | 7 ++++--- readme_fr.md | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 8aa970dc2..759f901e9 100644 --- a/readme.md +++ b/readme.md @@ -31,7 +31,7 @@ Contribute - Extending the [wiki](http://wiki.digitalpulsesoftware.com/index.php?title=Nazara) (**\*Broken link***) - Submitting a patch to GitHub - Post suggestions/bugs on the forum or the [GitHub tracker](https://github.com/DigitalPulseSoftware/NazaraEngine/issues) -- [Fork the project](https://github.com/DigitalPulseSoftware/NazaraEngine/fork) on GitHub and [pull your changes](https://github.com/DigitalPulseSoftware/NazaraEngine/pulls) +- [Fork the project](https://github.com/DigitalPulseSoftware/NazaraEngine/fork) on GitHub and [push your changes](https://github.com/DigitalPulseSoftware/NazaraEngine/pulls) - Talking about Nazara Engine to other people - Doing anything else that might help us @@ -43,5 +43,6 @@ Links ###Thanks to:### - **RafBill** and **Raakz:** Finding bugs and/or testing -- **Fissal "DrFisher" Hannoun**: Helped a lot in architecture design -- **Alexandre "Danman" Janniaux**: Made the Core POSIX implementation +- **Fissal "DrFisher" Hannoun**: Helping a lot in architecture design +- **Alexandre "Danman" Janniaux**: Helping making the POSIX implementation +- **Gawaboumga**: Improving the engine code by merging on GitHub diff --git a/readme_fr.md b/readme_fr.md index 60fa62a7d..fd8aaaf91 100644 --- a/readme_fr.md +++ b/readme_fr.md @@ -44,4 +44,5 @@ Liens ###Remerciements:### - **RafBill** et **Raakz:** Recherche de bugs et/ou tests - **Fissal "DrFisher" Hannoun**: Aide et conseils lors de la conception de l'architecture du moteur -- **Alexandre "Danman" Janniaux**: Implémentation POSIX du noyau +- **Alexandre "Danman" Janniaux**: Aide sur l'implémentation POSIX +- **Gawaboumga**: Amélioration du code via le merging sur GitHub From 48eb59eba8131a5c5cbfe399c42b1f2cbcaa9bf4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 17 Jun 2014 15:53:57 +0200 Subject: [PATCH 06/15] Commited missing file (from 7dfb82) Former-commit-id: 90aba1cc976830fd78efdd3d03764345b92df24d --- include/Nazara/Math/Quaternion.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index 216f2dbb5..3e27982f6 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -213,7 +213,7 @@ NzQuaternion& NzQuaternion::Set(T angle, const NzVector3& axis) angle = NzDegreeToRadian(angle); #endif - angle *= F(0.5); + angle /= F(2.0); NzVector3 normalizedAxis = axis.GetNormal(); From 9f17722afdb8b78e98dfceb498133768739aa86e Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Fri, 27 Jun 2014 19:11:45 +0200 Subject: [PATCH 07/15] Little corrections HashDigest: Simultaneous use of int and short EulerAngles: Use of the macro Geom: cone was missing Former-commit-id: ecc3a586732a6711b57ce3e79c5450ef7327bb5b --- include/Nazara/Core/HashDigest.hpp | 4 ++-- include/Nazara/Math/EulerAngles.inl | 6 +++--- src/Nazara/Core/HashDigest.cpp | 2 +- src/Nazara/Physics/Geom.cpp | 3 +++ 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/include/Nazara/Core/HashDigest.hpp b/include/Nazara/Core/HashDigest.hpp index 8083f2999..9e6459d04 100644 --- a/include/Nazara/Core/HashDigest.hpp +++ b/include/Nazara/Core/HashDigest.hpp @@ -28,7 +28,7 @@ class NAZARA_API NzHashDigest NzString ToHex() const; - nzUInt8 operator[](unsigned short pos) const; + nzUInt8 operator[](unsigned int pos) const; NzHashDigest& operator=(const NzHashDigest& rhs); NzHashDigest& operator=(NzHashDigest&& rhs) noexcept; @@ -45,7 +45,7 @@ class NAZARA_API NzHashDigest private: NzString m_hashName; nzUInt8* m_digest; - unsigned short m_digestLength; + unsigned int m_digestLength; }; #endif // NAZARA_HASHDIGEST_HPP diff --git a/include/Nazara/Math/EulerAngles.inl b/include/Nazara/Math/EulerAngles.inl index 36527087a..a085d99cf 100644 --- a/include/Nazara/Math/EulerAngles.inl +++ b/include/Nazara/Math/EulerAngles.inl @@ -83,9 +83,9 @@ template template void NzEulerAngles::Set(const NzEulerAngles& angles) { - pitch = static_cast(angles.pitch); - yaw = static_cast(angles.yaw); - roll = static_cast(angles.roll); + pitch = F(angles.pitch); + yaw = F(angles.yaw); + roll = F(angles.roll); } template diff --git a/src/Nazara/Core/HashDigest.cpp b/src/Nazara/Core/HashDigest.cpp index 74b80100a..27aa22db3 100644 --- a/src/Nazara/Core/HashDigest.cpp +++ b/src/Nazara/Core/HashDigest.cpp @@ -89,7 +89,7 @@ NzString NzHashDigest::ToHex() const return NzString(new NzString::SharedString(1, length, length, hexOutput)); } -nzUInt8 NzHashDigest::operator[](unsigned short pos) const +nzUInt8 NzHashDigest::operator[](unsigned int pos) const { #if NAZARA_CORE_SAFE if (pos >= m_digestLength) diff --git a/src/Nazara/Physics/Geom.cpp b/src/Nazara/Physics/Geom.cpp index 0eb463ab9..a7e348f07 100644 --- a/src/Nazara/Physics/Geom.cpp +++ b/src/Nazara/Physics/Geom.cpp @@ -17,6 +17,9 @@ namespace case nzPrimitiveType_Box: return new NzBoxGeom(physWorld, primitive.box.lengths, primitive.matrix); + case nzPrimitiveType_Cone: + return new NzConeGeom(physWorld, primitive.cone.length, primitive.cone.radius, primitive.matrix); + case nzPrimitiveType_Plane: return new NzBoxGeom(physWorld, NzVector3f(primitive.plane.size.x, 0.01f, primitive.plane.size.y), primitive.matrix); ///TODO: PlaneGeom? From ca595bca20e283177d5d1a161965f2c9e3564f13 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Fri, 27 Jun 2014 19:33:28 +0200 Subject: [PATCH 08/15] Add of some mathematical functions Plane: Getters and classic planes Sphere: Getter Vector2: Angle between two vectors Vector3: Same in 3D Former-commit-id: 07e6421def813743e5fd8248fe2e9503cebbb8a8 --- include/Nazara/Math/Plane.hpp | 8 +++++++- include/Nazara/Math/Plane.inl | 30 ++++++++++++++++++++++++++++++ include/Nazara/Math/Sphere.hpp | 1 + include/Nazara/Math/Sphere.inl | 7 +++++++ include/Nazara/Math/Vector2.hpp | 2 ++ include/Nazara/Math/Vector2.inl | 9 +++++++++ include/Nazara/Math/Vector3.hpp | 2 ++ include/Nazara/Math/Vector3.inl | 24 ++++++++++++++++++++++++ 8 files changed, 82 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Math/Plane.hpp b/include/Nazara/Math/Plane.hpp index 2b95141ee..965b840af 100644 --- a/include/Nazara/Math/Plane.hpp +++ b/include/Nazara/Math/Plane.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2014 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -27,6 +27,9 @@ class NzPlane T Distance(const NzVector3& point) const; T Distance(T x, T y, T z) const; + NzVector3 GetNormal() const; + T GetDistance() const; + NzPlane& Set(T normalX, T normalY, T normalZ, T Distance); NzPlane& Set(const T plane[4]); NzPlane& Set(const NzPlane& plane); @@ -38,6 +41,9 @@ class NzPlane NzString ToString() const; static NzPlane Lerp(const NzPlane& from, const NzPlane& to, T interpolation); + static NzPlane XY(); + static NzPlane XZ(); + static NzPlane YZ(); NzVector3 normal; T distance; diff --git a/include/Nazara/Math/Plane.inl b/include/Nazara/Math/Plane.inl index 640e9ea2f..186953134 100644 --- a/include/Nazara/Math/Plane.inl +++ b/include/Nazara/Math/Plane.inl @@ -58,6 +58,18 @@ T NzPlane::Distance(T x, T y, T z) const return Distance(NzVector3(x, y, z)); } +template +NzVector3 NzPlane::GetNormal() const +{ + return normal; +} + +template +T NzPlane::GetDistance() const +{ + return distance; +} + template NzPlane& NzPlane::Set(T normalX, T normalY, T normalZ, T D) { @@ -152,6 +164,24 @@ NzPlane NzPlane::Lerp(const NzPlane& from, const NzPlane& to, T interpolat return plane; } +template +NzPlane NzPlane::XY() +{ + return NzPlane(F(0.0), F(0.0), F(1.0), F(0.0)); +} + +template +NzPlane NzPlane::XZ() +{ + return NzPlane(F(0.0), F(1.0), F(0.0), F(0.0)); +} + +template +NzPlane NzPlane::YZ() +{ + return NzPlane(F(1.0), F(0.0), F(0.0), F(0.0)); +} + template std::ostream& operator<<(std::ostream& out, const NzPlane& plane) { diff --git a/include/Nazara/Math/Sphere.hpp b/include/Nazara/Math/Sphere.hpp index 64378a949..989bb6962 100644 --- a/include/Nazara/Math/Sphere.hpp +++ b/include/Nazara/Math/Sphere.hpp @@ -39,6 +39,7 @@ class NzSphere NzVector3 GetNegativeVertex(const NzVector3& normal) const; NzVector3 GetPosition() const; NzVector3 GetPositiveVertex(const NzVector3& normal) const; + T GetRadius() const; bool Intersect(const NzBox& box) const; bool Intersect(const NzSphere& sphere) const; diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index 9c56fac16..1f469f6d7 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -117,6 +117,13 @@ NzVector3 NzSphere::GetPositiveVertex(const NzVector3& normal) const return pos; } + +template +T NzSphere::GetRadius() const +{ + return radius; +} + template bool NzSphere::Intersect(const NzBox& box) const { diff --git a/include/Nazara/Math/Vector2.hpp b/include/Nazara/Math/Vector2.hpp index e0c060e21..186860066 100644 --- a/include/Nazara/Math/Vector2.hpp +++ b/include/Nazara/Math/Vector2.hpp @@ -23,6 +23,8 @@ class NzVector2 T AbsDotProduct(const NzVector2& vec) const; + T AngleBetween(const NzVector2& vec, bool toDegree = true) const; + T Distance(const NzVector2& vec) const; float Distancef(const NzVector2& vec) const; diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index 5da704243..a5e5f4712 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -54,6 +54,15 @@ inline unsigned int NzVector2::AbsDotProduct(const NzVector2 +T NzVector2::AngleBetween(const NzVector2& vec, bool toDegree) const +{ + if (toDegree) + return NzRadianToDegree(std::atan2(vec.y, vec.x) - std::atan2(y, x)); + else + return std::atan2(vec.y, vec.x) - std::atan2(y, x); +} + template T NzVector2::Distance(const NzVector2& vec) const { diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index fe2e33881..b8a980ae5 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -24,6 +24,8 @@ template class NzVector3 T AbsDotProduct(const NzVector3& vec) const; + T AngleBetween(const NzVector3& vec, bool toDegree = true) const; + NzVector3 CrossProduct(const NzVector3& vec) const; T Distance(const NzVector3& vec) const; diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index a90410a0d..f2940e279 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -60,6 +60,30 @@ inline unsigned int NzVector3::AbsDotProduct(const NzVector3 +T NzVector3::AngleBetween(const NzVector3& vec, bool toDegree) const +{ + T alpha = DotProduct(vec); + T divisor = (GetLength() * vec.GetLength()); + + #if NAZARA_MATH_SAFE + if (NzNumberEquals(divisor, F(0.0))) + { + NzString error("Division by zero"); + + NazaraError(error); + throw std::domain_error(error); + } + #endif + + alpha /= divisor; + + if (toDegree) + return NzRadianToDegree(std::acos(NzClamp(alpha, F(-1.0), F(1.0)))); + else + return std::acos(NzClamp(alpha, F(-1.0), F(1.0))); +} + template NzVector3 NzVector3::CrossProduct(const NzVector3& vec) const { From f3ccd60b5fccb3151fd2b36712ce2898ca9be109 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Fri, 27 Jun 2014 19:39:51 +0200 Subject: [PATCH 09/15] New class ray Class ray who represents a ray in space and who can be used as a line. Support of classical intersections. Former-commit-id: 2ea5af0cf749dbefdd841f9b02bfab2af5058cdb --- include/Nazara/Math.hpp | 1 + include/Nazara/Math/Ray.hpp | 71 ++++++ include/Nazara/Math/Ray.inl | 415 ++++++++++++++++++++++++++++++++++++ 3 files changed, 487 insertions(+) create mode 100644 include/Nazara/Math/Ray.hpp create mode 100644 include/Nazara/Math/Ray.inl diff --git a/include/Nazara/Math.hpp b/include/Nazara/Math.hpp index e69eab49c..e70158c4a 100644 --- a/include/Nazara/Math.hpp +++ b/include/Nazara/Math.hpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/Math/Ray.hpp b/include/Nazara/Math/Ray.hpp new file mode 100644 index 000000000..8b7276e6c --- /dev/null +++ b/include/Nazara/Math/Ray.hpp @@ -0,0 +1,71 @@ +// Copyright (C) 2014 Rémi Bèges - Jérôme Leclercq +// This file is part of the "Nazara Engine - Mathematics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_RAY_HPP +#define NAZARA_RAY_HPP + +#include +#include +#include +#include +#include +#include +#include + +template class NzRay +{ + public: + NzRay() = default; + NzRay(T X, T Y, T Z, T directionX, T directionY, T directionZ); + NzRay(const T origin[3], const T direction[3]); + NzRay(const NzVector3& origin, const NzVector3& direction); + NzRay(const NzPlane& planeOne, const NzPlane& planeTwo); + template explicit NzRay(const NzVector3& origin, const NzVector3& direction); + template explicit NzRay(const NzRay& ray); + NzRay(const NzRay& ray) = default; + ~NzRay() = default; + + NzVector3 GetClosestPoint(const NzVector3& point) const; + NzVector3 GetDirection() const; + NzVector3 GetOrigin() const; + NzVector3 GetPoint(T lambda) const; + + bool Intersect(const NzBox& box, NzVector3 * hitPoint = nullptr, NzVector3 * hitSecondPoint = nullptr) const; + bool Intersect(const NzOrientedBox& orientedBox, const NzMatrix4& matrix, NzVector3 * hitPoint = nullptr, NzVector3 * hitSecondPoint = nullptr) const; + bool Intersect(const NzPlane& plane, NzVector3 * hitPoint = nullptr) const; + bool Intersect(const NzSphere& sphere, NzVector3 * hitPoint = nullptr, NzVector3 * hitSecondPoint = nullptr) const; + + NzVector3 operator*(T lambda) const; + + NzRay& Set(T X, T Y, T Z, T directionX, T directionY, T directionZ); + NzRay& Set(const T origin[3], const T direction[3]); + NzRay& Set(const NzVector3& origin, const NzVector3& direction); + NzRay& Set(const NzPlane& planeOne, const NzPlane& planeTwo); + template NzRay& Set(const NzVector3& origin, const NzVector3& direction); + template NzRay& Set(const NzRay& ray); + NzRay& Set(const NzRay& ray); + + NzRay& SetDirection(const NzVector3& direction); + NzRay& SetOrigin(const NzVector3& origin); + + NzString ToString() const; + + static NzRay Lerp(const NzRay& from, const NzRay& to, T interpolation); + static NzRay UnitX(); + static NzRay UnitY(); + static NzRay UnitZ(); + + NzVector3 direction, origin; +}; + +template std::ostream& operator<<(std::ostream& out, const NzRay& vec); + +typedef NzRay NzRayd; +typedef NzRay NzRayf; + +#include + +#endif // NAZARA_RAY_HPP diff --git a/include/Nazara/Math/Ray.inl b/include/Nazara/Math/Ray.inl new file mode 100644 index 000000000..2bd72da58 --- /dev/null +++ b/include/Nazara/Math/Ray.inl @@ -0,0 +1,415 @@ +// Copyright (C) 2014 Jérôme Leclercq +// This file is part of the "Nazara Engine - Mathematics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +#define F(a) static_cast(a) + +template +NzRay::NzRay(T X, T Y, T Z, T DirectionX, T DirectionY, T DirectionZ) +{ + Set(X, Y, Z, DirectionX, DirectionY, DirectionZ); +} + +template +NzRay::NzRay(const T Origin[3], const T Direction[3]) +{ + Set(Origin, Direction); +} + +template +NzRay::NzRay(const NzVector3& Origin, const NzVector3& Direction) +{ + Set(Origin, Direction); +} + +template +NzRay::NzRay(const NzPlane& planeOne, const NzPlane& planeTwo) +{ + Set(planeOne, planeTwo); +} + +template +template +NzRay::NzRay(const NzVector3& Origin, const NzVector3& Direction) +{ + Set(Origin, Direction); +} + +template +template +NzRay::NzRay(const NzRay& ray) +{ + Set(ray); +} + +template +NzVector3 NzRay::GetClosestPoint(const NzVector3& point) const +{ + NzVector3 delta = point - origin; + T vsq = direction.GetSquaredLength(); + T proj = delta.DotProduct(direction); + + return GetPoint(proj/vsq); +} + +template +NzVector3 NzRay::GetDirection() const +{ + return direction; +} + +template +NzVector3 NzRay::GetOrigin() const +{ + return origin; +} + +template +NzVector3 NzRay::GetPoint(T lambda) const +{ + return NzVector3(origin + direction * lambda); +} + +template +bool NzRay::Intersect(const NzBox& box, NzVector3 * hitPoint, NzVector3 * hitSecondPoint) const +{ + // Slab method + + #if NAZARA_MATH_SAFE + if (NzNumberEquals(direction.x, F(0.0)) || NzNumberEquals(direction.y, F(0.0)) || NzNumberEquals(direction.z, F(0.0))) + { + NazaraWarning("Division by zero !"); // The algorithm is still correct. + } + #endif + + T tx1 = (box.x - origin.x) / direction.x; + T tx2 = (box.x + box.width - origin.x) / direction.x; + + T tmin = std::min(tx1, tx2); + T tmax = std::max(tx1, tx2); + + T ty1 = (box.y - origin.y) / direction.y; + T ty2 = (box.y + box.height - origin.y) / direction.y; + + tmin = std::max(tmin, std::min(ty1, ty2)); + tmax = std::min(tmax, std::max(ty1, ty2)); + + T tz1 = (box.z - origin.z) / direction.z; + T tz2 = (box.z + box.depth - origin.z) / direction.z; + + tmin = std::max(tmin, std::min(tz1, tz2)); + tmax = std::min(tmax, std::max(tz1, tz2)); + + if (hitPoint) + hitPoint->Set(GetPoint(tmin)); + if (hitSecondPoint) + hitSecondPoint->Set(GetPoint(tmax)); + + return tmax >= std::max(F(0.0), tmin) && tmin < INFINITY; +} + +template +bool NzRay::Intersect(const NzOrientedBox& orientedBox, const NzMatrix4& matrix, NzVector3 * hitPoint, NzVector3 * hitSecondPoint) const +{ + // Intersection method from Real-Time Rendering and Essential Mathematics for Games + + T tMin = F(0.0); + T tMax = INFINITY; + + NzVector3 OBBposition_worldspace(matrix[3].x, matrix[3].y, matrix[3].z); + + NzVector3 delta = OBBposition_worldspace - origin; + + // Test intersection with the 2 planes perpendicular to the OBB's X axis + NzVector3 xaxis(matrix[0].x, matrix[0].y, matrix[0].z); + T e = xaxis.DotProduct(delta); + T f = direction.DotProduct(xaxis); + + if (std::abs(f) > F(0.0)) + { // Standard case + + T t1 = (e + orientedBox.localBox.x) / f; // Intersection with the "left" plane + T t2 = (e + (orientedBox.localBox.x + orientedBox.localBox.width)) / f; // Intersection with the "right" plane + // t1 and t2 now contain distances betwen ray origin and ray-plane intersections + + // We want t1 to represent the nearest intersection, + // so if it's not the case, invert t1 and t2 + if (t1 > t2) + { T w = t1; t1 = t2; t2 = w; } // swap t1 and t2 + + // tMax is the nearest "far" intersection (amongst the X,Y and Z planes pairs) + if (t2 < tMax) + tMax = t2; + // tMin is the farthest "near" intersection (amongst the X,Y and Z planes pairs) + if (t1 > tMin) + tMin = t1; + + // And here's the trick : + // If "far" is closer than "near", then there is NO intersection. + // See the images in the tutorials for the visual explanation. + if (tMax < tMin) + return false; + } + else + // Rare case : the ray is almost parallel to the planes, so they don't have any "intersection" + if (-e + orientedBox.localBox.x > F(0.0) || -e + (orientedBox.localBox.x + orientedBox.localBox.width) < F(0.0)) + return false; + + // Test intersection with the 2 planes perpendicular to the OBB's Y axis + // Exactly the same thing than above. + NzVector3 yaxis(matrix[1].x, matrix[1].y, matrix[1].z); + e = yaxis.DotProduct(delta); + f = direction.DotProduct(yaxis); + + if (std::abs(f) > F(0.0)) + { + + T t1 = (e + orientedBox.localBox.y) / f; + T t2 = (e + (orientedBox.localBox.y + orientedBox.localBox.height)) / f; + + if (t1 > t2) + { T w = t1; t1 = t2; t2 = w; } // swap t1 and t2 + + if (t2 < tMax) + tMax = t2; + if (t1 > tMin) + tMin = t1; + if (tMin > tMax) + return false; + + } + else + if (-e + orientedBox.localBox.y > F(0.0) || -e + (orientedBox.localBox.y + orientedBox.localBox.height) < F(0.0)) + return false; + + + // Test intersection with the 2 planes perpendicular to the OBB's Z axis + // Exactly the same thing than above. + NzVector3 zaxis(matrix[2].x, matrix[2].y, matrix[2].z); + e = zaxis.DotProduct(delta); + f = direction.DotProduct(zaxis); + + if (std::abs(f) > F(0.0)) + { + T t1 = (e + orientedBox.localBox.z) / f; + T t2 = (e + (orientedBox.localBox.z + orientedBox.localBox.depth)) / f; + + if (t1 > t2) + { T w = t1; t1 = t2; t2 = w; } // swap t1 and t2 + + if (t2 < tMax) + tMax = t2; + if (t1 > tMin) + tMin = t1; + if (tMin > tMax) + return false; + + } + else + if (-e + orientedBox.localBox.z > F(0.0) || -e + (orientedBox.localBox.z + orientedBox.localBox.depth) < F(0.0)) + return false; + + if (hitPoint) + hitPoint->Set(GetPoint(tMin)); + if (hitSecondPoint) + hitSecondPoint->Set(GetPoint(tMax)); + + return true; +} + +template +bool NzRay::Intersect(const NzPlane& plane, NzVector3 * hitPoint) const +{ + T divisor = plane.normal.DotProduct(direction); + + if (NzNumberEquals(divisor, F(0.0))) + return false; // perpendicular + + if (!hitPoint) + return true; + + T lambda = - (plane.normal.DotProduct(origin) - plane.distance) / divisor; // The plane is ax+by+cz=d + hitPoint->Set(GetPoint(lambda)); + + return true; +} + +template +bool NzRay::Intersect(const NzSphere& sphere, NzVector3 * hitPoint, NzVector3 * hitSecondPoint) const +{ + NzVector3 distanceCenterOrigin = sphere.GetPosition() - origin; + T length = distanceCenterOrigin.DotProduct(direction); + + if (length < F(0.0)) + return false; // ray is perpendicular to the vector origin - center + + T squaredDistance = distanceCenterOrigin.GetSquaredLength() - length * length; + + T squaredRadius = sphere.GetRadius() * sphere.GetRadius(); + + if (squaredDistance > squaredRadius) + return false; // if the ray is further than the radius + + if (!hitPoint) + return true; + + T deltaLambda = std::sqrt(squaredRadius - squaredDistance); + + if (hitPoint) + hitPoint->Set(GetPoint(length - deltaLambda)); + if (hitSecondPoint) + hitSecondPoint->Set(GetPoint(length + deltaLambda)); + + return true; +} + +template +NzVector3 NzRay::operator*(T lambda) const +{ + return GetPoint(lambda); +} + +template +NzRay& NzRay::Set(T X, T Y, T Z, T directionX, T directionY, T directionZ) +{ + direction = NzVector3(directionX, directionY, directionZ); + origin = NzVector3(X, Y, Z); + + return *this; +} + +template +NzRay& NzRay::Set(const T Origin[3], const T Direction[3]) +{ + direction = NzVector3(Direction); + origin = NzVector3(Origin); + + return *this; +} + +template +NzRay& NzRay::Set(const NzVector3& Origin, const NzVector3& Direction) +{ + direction = Direction; + origin = Origin; + + return *this; +} + +template +NzRay& NzRay::Set(const NzPlane& planeOne, const NzPlane& planeTwo) +{ + T termOne = planeOne.normal.GetLength(); + T termTwo = planeOne.normal.DotProduct(planeTwo.normal); + T termFour = planeTwo.normal.GetLength(); + T det = termOne * termFour - termTwo * termTwo; + + #if NAZARA_MATH_SAFE + if (NzNumberEquals(det, F(0.0))) + { + + NzString error("Planes are parallel."); + + NazaraError(error); + throw std::domain_error(error); + } + #endif + + T invdet = F(1.0) / det; + T fc0 = (termFour * -planeOne.distance + termTwo * planeTwo.distance) * invdet; + T fc1 = (termOne * -planeTwo.distance + termTwo * planeOne.distance) * invdet; + + direction = planeOne.normal.CrossProduct(planeTwo.normal); + origin = planeOne.normal * fc0 + planeTwo.normal * fc1; + + return *this; +} + +template +template +NzRay& NzRay::Set(const NzVector3& Origin, const NzVector3& Direction) +{ + direction = NzVector3(Direction); + origin = NzVector3(Origin); + + return *this; +} + +template +template +NzRay& NzRay::Set(const NzRay& ray) +{ + direction = NzVector3(ray.direction); + origin = NzVector3(ray.origin); + + return *this; +} + +template +NzRay& NzRay::Set(const NzRay& ray) +{ + std::memcpy(this, &ray, sizeof(NzRay)); + + return *this; +} + +template +NzRay& NzRay::SetDirection(const NzVector3& Direction) +{ + direction = Direction; + + return *this; +} + +template +NzRay& NzRay::SetOrigin(const NzVector3& Origin) +{ + origin = Origin; + + return *this; +} + +template +NzString NzRay::ToString() const +{ + NzStringStream ss; + + return ss << "Ray(" << origin.x << ", " << origin.y << ", " << origin.z << " | direction: " << direction.x << ", " << direction.y << ", " << direction.z << ')'; +} + +template +NzRay NzRay::Lerp(const NzRay& from, const NzRay& to, T interpolation) +{ + return NzRay(from.origin.Lerp(to.origin, interpolation), from.direction.Lerp(to.direction, interpolation)); +} + +template +NzRay NzRay::UnitX() +{ + return NzRay(NzVector3::Zero(), NzVector3::UnitX()); +} + +template +NzRay NzRay::UnitY() +{ + return NzRay(NzVector3::Zero(), NzVector3::UnitY()); +} + +template +NzRay NzRay::UnitZ() +{ + return NzRay(NzVector3::Zero(), NzVector3::UnitZ()); +} + +template +std::ostream& operator<<(std::ostream& out, const NzRay& ray) +{ + return out << ray.ToString(); +} + +#undef F + +#include From 5e709001adaea419b6990fc1ecbc1d6f7e9633db Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sat, 28 Jun 2014 09:03:56 +0200 Subject: [PATCH 10/15] Little fail Plane: Forgot Former-commit-id: 46f5c4a501fcf1ed841e28474cf5bca8e7baa438 --- include/Nazara/Math/Plane.hpp | 2 +- include/Nazara/Math/Plane.inl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Math/Plane.hpp b/include/Nazara/Math/Plane.hpp index 965b840af..e2bbcaa52 100644 --- a/include/Nazara/Math/Plane.hpp +++ b/include/Nazara/Math/Plane.hpp @@ -27,7 +27,7 @@ class NzPlane T Distance(const NzVector3& point) const; T Distance(T x, T y, T z) const; - NzVector3 GetNormal() const; + NzVector3 GetNormal() const; T GetDistance() const; NzPlane& Set(T normalX, T normalY, T normalZ, T Distance); diff --git a/include/Nazara/Math/Plane.inl b/include/Nazara/Math/Plane.inl index 186953134..1101a7b81 100644 --- a/include/Nazara/Math/Plane.inl +++ b/include/Nazara/Math/Plane.inl @@ -59,7 +59,7 @@ T NzPlane::Distance(T x, T y, T z) const } template -NzVector3 NzPlane::GetNormal() const +NzVector3 NzPlane::GetNormal() const { return normal; } From 7ba72ef1c6e197c4ae54fb1fc30e3c1c30cf73e3 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sat, 28 Jun 2014 11:45:10 +0200 Subject: [PATCH 11/15] Little fail again Wrong getter Former-commit-id: 951d0a46d189c13009854f4bad43e7a243470f03 --- include/Nazara/Math/Ray.inl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/Nazara/Math/Ray.inl b/include/Nazara/Math/Ray.inl index 2bd72da58..0309d5f35 100644 --- a/include/Nazara/Math/Ray.inl +++ b/include/Nazara/Math/Ray.inl @@ -119,12 +119,12 @@ bool NzRay::Intersect(const NzOrientedBox& orientedBox, const NzMatrix4 T tMin = F(0.0); T tMax = INFINITY; - NzVector3 OBBposition_worldspace(matrix[3].x, matrix[3].y, matrix[3].z); + NzVector3 OBBposition_worldspace(matrix(3, 0), matrix(3, 1), matrix(3, 2)); NzVector3 delta = OBBposition_worldspace - origin; // Test intersection with the 2 planes perpendicular to the OBB's X axis - NzVector3 xaxis(matrix[0].x, matrix[0].y, matrix[0].z); + NzVector3 xaxis(matrix(0, 0), matrix(0, 1), matrix(0, 2)); T e = xaxis.DotProduct(delta); T f = direction.DotProduct(xaxis); @@ -160,7 +160,7 @@ bool NzRay::Intersect(const NzOrientedBox& orientedBox, const NzMatrix4 // Test intersection with the 2 planes perpendicular to the OBB's Y axis // Exactly the same thing than above. - NzVector3 yaxis(matrix[1].x, matrix[1].y, matrix[1].z); + NzVector3 yaxis(matrix(1, 0), matrix(1, 1), matrix(1, 2)); e = yaxis.DotProduct(delta); f = direction.DotProduct(yaxis); @@ -188,7 +188,7 @@ bool NzRay::Intersect(const NzOrientedBox& orientedBox, const NzMatrix4 // Test intersection with the 2 planes perpendicular to the OBB's Z axis // Exactly the same thing than above. - NzVector3 zaxis(matrix[2].x, matrix[2].y, matrix[2].z); + NzVector3 zaxis(matrix(2, 0), matrix(2, 1), matrix(2, 2)); e = zaxis.DotProduct(delta); f = direction.DotProduct(zaxis); @@ -383,7 +383,7 @@ NzString NzRay::ToString() const template NzRay NzRay::Lerp(const NzRay& from, const NzRay& to, T interpolation) { - return NzRay(from.origin.Lerp(to.origin, interpolation), from.direction.Lerp(to.direction, interpolation)); + return NzRay(from.origin.Lerp(to.origin, interpolation), from.direction.Lerp(to.direction, interpolation)); } template From 45fc9158e406b4d65d6d2dcf07ba2b73e2b0631e Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Tue, 1 Jul 2014 10:57:43 +0200 Subject: [PATCH 12/15] Add of source Add of the source Former-commit-id: f3d01ef18ccc1ae906693f388e696c0763576a3b --- include/Nazara/Math/Ray.inl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Math/Ray.inl b/include/Nazara/Math/Ray.inl index 0309d5f35..230dc092e 100644 --- a/include/Nazara/Math/Ray.inl +++ b/include/Nazara/Math/Ray.inl @@ -114,6 +114,8 @@ bool NzRay::Intersect(const NzBox& box, NzVector3 * hitPoint, NzVector3 template bool NzRay::Intersect(const NzOrientedBox& orientedBox, const NzMatrix4& matrix, NzVector3 * hitPoint, NzVector3 * hitSecondPoint) const { + // Traduction from http://www.opengl-tutorial.org/miscellaneous/clicking-on-objects/picking-with-custom-ray-obb-function/ written by Arnaud Masserann + // Intersection method from Real-Time Rendering and Essential Mathematics for Games T tMin = F(0.0); @@ -185,7 +187,6 @@ bool NzRay::Intersect(const NzOrientedBox& orientedBox, const NzMatrix4 if (-e + orientedBox.localBox.y > F(0.0) || -e + (orientedBox.localBox.y + orientedBox.localBox.height) < F(0.0)) return false; - // Test intersection with the 2 planes perpendicular to the OBB's Z axis // Exactly the same thing than above. NzVector3 zaxis(matrix(2, 0), matrix(2, 1), matrix(2, 2)); From 31d54d4706763d6ed7eef54526a3d81240894cb1 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Tue, 1 Jul 2014 11:06:16 +0200 Subject: [PATCH 13/15] UTF8 Former-commit-id: 3cbdbcc5dd8cc73b5efc40f62e3b6a9619f628cc --- include/Nazara/Math/Ray.hpp | 2 +- include/Nazara/Math/Ray.inl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Math/Ray.hpp b/include/Nazara/Math/Ray.hpp index 8b7276e6c..74c8e9833 100644 --- a/include/Nazara/Math/Ray.hpp +++ b/include/Nazara/Math/Ray.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges - Jérôme Leclercq +// Copyright (C) 2014 Rémi Bèges - Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Ray.inl b/include/Nazara/Math/Ray.inl index 230dc092e..621d68c3f 100644 --- a/include/Nazara/Math/Ray.inl +++ b/include/Nazara/Math/Ray.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2014 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp From ba7f3606a07d771a1118c809a7ab18977064f5b6 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Fri, 4 Jul 2014 11:22:47 +0200 Subject: [PATCH 14/15] Obb intersect ray New method Former-commit-id: 282a82d773f61fcec8026eb4ccb74e8b2de9784f --- include/Nazara/Math/Ray.hpp | 2 +- include/Nazara/Math/Ray.inl | 122 +++++++----------------------------- 2 files changed, 24 insertions(+), 100 deletions(-) diff --git a/include/Nazara/Math/Ray.hpp b/include/Nazara/Math/Ray.hpp index 74c8e9833..4704cf866 100644 --- a/include/Nazara/Math/Ray.hpp +++ b/include/Nazara/Math/Ray.hpp @@ -34,7 +34,7 @@ template class NzRay NzVector3 GetPoint(T lambda) const; bool Intersect(const NzBox& box, NzVector3 * hitPoint = nullptr, NzVector3 * hitSecondPoint = nullptr) const; - bool Intersect(const NzOrientedBox& orientedBox, const NzMatrix4& matrix, NzVector3 * hitPoint = nullptr, NzVector3 * hitSecondPoint = nullptr) const; + bool Intersect(const NzOrientedBox& orientedBox, NzVector3 * hitPoint = nullptr, NzVector3 * hitSecondPoint = nullptr) const; bool Intersect(const NzPlane& plane, NzVector3 * hitPoint = nullptr) const; bool Intersect(const NzSphere& sphere, NzVector3 * hitPoint = nullptr, NzVector3 * hitSecondPoint = nullptr) const; diff --git a/include/Nazara/Math/Ray.inl b/include/Nazara/Math/Ray.inl index 621d68c3f..4cb075ecd 100644 --- a/include/Nazara/Math/Ray.inl +++ b/include/Nazara/Math/Ray.inl @@ -112,113 +112,37 @@ bool NzRay::Intersect(const NzBox& box, NzVector3 * hitPoint, NzVector3 } template -bool NzRay::Intersect(const NzOrientedBox& orientedBox, const NzMatrix4& matrix, NzVector3 * hitPoint, NzVector3 * hitSecondPoint) const +bool NzRay::Intersect(const NzOrientedBox& orientedBox, NzVector3 * hitPoint, NzVector3 * hitSecondPoint) const { - // Traduction from http://www.opengl-tutorial.org/miscellaneous/clicking-on-objects/picking-with-custom-ray-obb-function/ written by Arnaud Masserann + NzVector3 width = (orientedBox.GetCorner(nzCorner_NearLeftBottom) - orientedBox.GetCorner(nzCorner_FarLeftBottom)).Normalize(); + NzVector3 height = (orientedBox.GetCorner(nzCorner_FarLeftTop) - orientedBox.GetCorner(nzCorner_FarLeftBottom)).Normalize(); + NzVector3 depth = (orientedBox.GetCorner(nzCorner_FarRightBottom) - orientedBox.GetCorner(nzCorner_FarLeftBottom)).Normalize(); - // Intersection method from Real-Time Rendering and Essential Mathematics for Games + // Construction of the inverse of the matrix who did the rotation -> orthogonal matrix. + NzMatrix4 transformation(width.x, height.x, depth.x, F(0.0), + width.y, height.y, depth.y, F(0.0), + width.z, height.z, depth.z, F(0.0), + F(0.0), F(0.0), F(0.0), F(1.0)); - T tMin = F(0.0); - T tMax = INFINITY; + // Reduction to aabb problem + NzVector3 newOrigin = transformation.Transform(origin); + NzVector3 newDirection = transformation.Transform(direction); - NzVector3 OBBposition_worldspace(matrix(3, 0), matrix(3, 1), matrix(3, 2)); - - NzVector3 delta = OBBposition_worldspace - origin; - - // Test intersection with the 2 planes perpendicular to the OBB's X axis - NzVector3 xaxis(matrix(0, 0), matrix(0, 1), matrix(0, 2)); - T e = xaxis.DotProduct(delta); - T f = direction.DotProduct(xaxis); - - if (std::abs(f) > F(0.0)) - { // Standard case - - T t1 = (e + orientedBox.localBox.x) / f; // Intersection with the "left" plane - T t2 = (e + (orientedBox.localBox.x + orientedBox.localBox.width)) / f; // Intersection with the "right" plane - // t1 and t2 now contain distances betwen ray origin and ray-plane intersections - - // We want t1 to represent the nearest intersection, - // so if it's not the case, invert t1 and t2 - if (t1 > t2) - { T w = t1; t1 = t2; t2 = w; } // swap t1 and t2 - - // tMax is the nearest "far" intersection (amongst the X,Y and Z planes pairs) - if (t2 < tMax) - tMax = t2; - // tMin is the farthest "near" intersection (amongst the X,Y and Z planes pairs) - if (t1 > tMin) - tMin = t1; - - // And here's the trick : - // If "far" is closer than "near", then there is NO intersection. - // See the images in the tutorials for the visual explanation. - if (tMax < tMin) - return false; - } - else - // Rare case : the ray is almost parallel to the planes, so they don't have any "intersection" - if (-e + orientedBox.localBox.x > F(0.0) || -e + (orientedBox.localBox.x + orientedBox.localBox.width) < F(0.0)) - return false; - - // Test intersection with the 2 planes perpendicular to the OBB's Y axis - // Exactly the same thing than above. - NzVector3 yaxis(matrix(1, 0), matrix(1, 1), matrix(1, 2)); - e = yaxis.DotProduct(delta); - f = direction.DotProduct(yaxis); - - if (std::abs(f) > F(0.0)) + NzVector3 tmp, tmp2; + if (NzRay(newOrigin, newDirection).Intersect(NzBox(orientedBox.GetCorner(nzCorner_NearRightTop), orientedBox.GetCorner(nzCorner_FarLeftBottom)), &tmp, &tmp2)) { + if (hitPoint) + { + transformation.Transpose(); + hitPoint->Set(transformation.Transform(tmp)); + if (hitSecondPoint) + hitSecondPoint->Set(transformation.Transform(tmp2)); + } - T t1 = (e + orientedBox.localBox.y) / f; - T t2 = (e + (orientedBox.localBox.y + orientedBox.localBox.height)) / f; - - if (t1 > t2) - { T w = t1; t1 = t2; t2 = w; } // swap t1 and t2 - - if (t2 < tMax) - tMax = t2; - if (t1 > tMin) - tMin = t1; - if (tMin > tMax) - return false; - + return true; } - else - if (-e + orientedBox.localBox.y > F(0.0) || -e + (orientedBox.localBox.y + orientedBox.localBox.height) < F(0.0)) - return false; - // Test intersection with the 2 planes perpendicular to the OBB's Z axis - // Exactly the same thing than above. - NzVector3 zaxis(matrix(2, 0), matrix(2, 1), matrix(2, 2)); - e = zaxis.DotProduct(delta); - f = direction.DotProduct(zaxis); - - if (std::abs(f) > F(0.0)) - { - T t1 = (e + orientedBox.localBox.z) / f; - T t2 = (e + (orientedBox.localBox.z + orientedBox.localBox.depth)) / f; - - if (t1 > t2) - { T w = t1; t1 = t2; t2 = w; } // swap t1 and t2 - - if (t2 < tMax) - tMax = t2; - if (t1 > tMin) - tMin = t1; - if (tMin > tMax) - return false; - - } - else - if (-e + orientedBox.localBox.z > F(0.0) || -e + (orientedBox.localBox.z + orientedBox.localBox.depth) < F(0.0)) - return false; - - if (hitPoint) - hitPoint->Set(GetPoint(tMin)); - if (hitSecondPoint) - hitSecondPoint->Set(GetPoint(tMax)); - - return true; + return false; } template From 60d045e139d673754c99db7ee374bcecfd7b573c Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Fri, 4 Jul 2014 11:31:51 +0200 Subject: [PATCH 15/15] Suppressions of getters Former-commit-id: db5ae144a8eb8794e7df9981805d2250bbd8b4ee --- include/Nazara/Math/Plane.hpp | 3 --- include/Nazara/Math/Plane.inl | 12 ------------ include/Nazara/Math/Ray.hpp | 2 -- include/Nazara/Math/Ray.inl | 14 +------------- include/Nazara/Math/Sphere.hpp | 1 - include/Nazara/Math/Sphere.inl | 6 ------ 6 files changed, 1 insertion(+), 37 deletions(-) diff --git a/include/Nazara/Math/Plane.hpp b/include/Nazara/Math/Plane.hpp index e2bbcaa52..b816ae195 100644 --- a/include/Nazara/Math/Plane.hpp +++ b/include/Nazara/Math/Plane.hpp @@ -27,9 +27,6 @@ class NzPlane T Distance(const NzVector3& point) const; T Distance(T x, T y, T z) const; - NzVector3 GetNormal() const; - T GetDistance() const; - NzPlane& Set(T normalX, T normalY, T normalZ, T Distance); NzPlane& Set(const T plane[4]); NzPlane& Set(const NzPlane& plane); diff --git a/include/Nazara/Math/Plane.inl b/include/Nazara/Math/Plane.inl index 1101a7b81..4e7c81029 100644 --- a/include/Nazara/Math/Plane.inl +++ b/include/Nazara/Math/Plane.inl @@ -58,18 +58,6 @@ T NzPlane::Distance(T x, T y, T z) const return Distance(NzVector3(x, y, z)); } -template -NzVector3 NzPlane::GetNormal() const -{ - return normal; -} - -template -T NzPlane::GetDistance() const -{ - return distance; -} - template NzPlane& NzPlane::Set(T normalX, T normalY, T normalZ, T D) { diff --git a/include/Nazara/Math/Ray.hpp b/include/Nazara/Math/Ray.hpp index 4704cf866..d342dcc26 100644 --- a/include/Nazara/Math/Ray.hpp +++ b/include/Nazara/Math/Ray.hpp @@ -29,8 +29,6 @@ template class NzRay ~NzRay() = default; NzVector3 GetClosestPoint(const NzVector3& point) const; - NzVector3 GetDirection() const; - NzVector3 GetOrigin() const; NzVector3 GetPoint(T lambda) const; bool Intersect(const NzBox& box, NzVector3 * hitPoint = nullptr, NzVector3 * hitSecondPoint = nullptr) const; diff --git a/include/Nazara/Math/Ray.inl b/include/Nazara/Math/Ray.inl index 4cb075ecd..1b423f900 100644 --- a/include/Nazara/Math/Ray.inl +++ b/include/Nazara/Math/Ray.inl @@ -55,18 +55,6 @@ NzVector3 NzRay::GetClosestPoint(const NzVector3& point) const return GetPoint(proj/vsq); } -template -NzVector3 NzRay::GetDirection() const -{ - return direction; -} - -template -NzVector3 NzRay::GetOrigin() const -{ - return origin; -} - template NzVector3 NzRay::GetPoint(T lambda) const { @@ -302,7 +290,7 @@ NzString NzRay::ToString() const { NzStringStream ss; - return ss << "Ray(" << origin.x << ", " << origin.y << ", " << origin.z << " | direction: " << direction.x << ", " << direction.y << ", " << direction.z << ')'; + return ss << "Ray(origin: " << origin.ToString() << ", direction: " << direction.ToString() << ")"; } template diff --git a/include/Nazara/Math/Sphere.hpp b/include/Nazara/Math/Sphere.hpp index 989bb6962..64378a949 100644 --- a/include/Nazara/Math/Sphere.hpp +++ b/include/Nazara/Math/Sphere.hpp @@ -39,7 +39,6 @@ class NzSphere NzVector3 GetNegativeVertex(const NzVector3& normal) const; NzVector3 GetPosition() const; NzVector3 GetPositiveVertex(const NzVector3& normal) const; - T GetRadius() const; bool Intersect(const NzBox& box) const; bool Intersect(const NzSphere& sphere) const; diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index 1f469f6d7..b9a97eb43 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -118,12 +118,6 @@ NzVector3 NzSphere::GetPositiveVertex(const NzVector3& normal) const return pos; } -template -T NzSphere::GetRadius() const -{ - return radius; -} - template bool NzSphere::Intersect(const NzBox& box) const {