diff --git a/include/Nazara/Math/AxisAlignedBox.hpp b/include/Nazara/Math/AxisAlignedBox.hpp deleted file mode 100644 index 9abcf2d96..000000000 --- a/include/Nazara/Math/AxisAlignedBox.hpp +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (C) 2012 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 - -#ifndef NAZARA_AXISALIGNEDBOX_HPP -#define NAZARA_AXISALIGNEDBOX_HPP - -#include -#include -#include -#include -#include - -template -class NzAxisAlignedBox -{ - public: - NzAxisAlignedBox(); - NzAxisAlignedBox(nzExtend Extend); - NzAxisAlignedBox(T X, T Y, T Z, T Width, T Height, T Depth); - NzAxisAlignedBox(const NzCube& Cube); - NzAxisAlignedBox(const NzVector3& vec1, const NzVector3& vec2); - template explicit NzAxisAlignedBox(const NzAxisAlignedBox& box); - NzAxisAlignedBox(const NzAxisAlignedBox& box) = default; - ~NzAxisAlignedBox() = default; - - bool Contains(T X, T Y, T Z) const; - bool Contains(const NzAxisAlignedBox& box) const; - bool Contains(const NzVector3& vector) const; - - NzAxisAlignedBox& ExtendTo(T X, T Y, T Z); - NzAxisAlignedBox& ExtendTo(const NzAxisAlignedBox& box); - NzAxisAlignedBox& ExtendTo(const NzVector3& vector); - - NzVector3 GetCorner(nzCorner corner) const; - NzVector3 GetCenter() const; - NzCube GetCube() const; - nzExtend GetExtend() const; - NzVector3 GetNegativeVertex(const NzVector3& normal) const; - NzVector3 GetPosition() const; - NzVector3 GetPositiveVertex(const NzVector3& normal) const; - NzVector3 GetSize() const; - - bool Intersect(const NzAxisAlignedBox& box, NzAxisAlignedBox* intersection = nullptr) const; - - bool IsFinite() const; - bool IsInfinite() const; - bool IsNull() const; - - NzAxisAlignedBox& MakeInfinite(); - NzAxisAlignedBox& MakeNull(); - - NzAxisAlignedBox& Set(nzExtend Extend); - NzAxisAlignedBox& Set(T X, T Y, T Z, T Width, T Height, T Depth); - NzAxisAlignedBox& Set(const NzAxisAlignedBox& box); - NzAxisAlignedBox& Set(const NzCube& Cube); - NzAxisAlignedBox& Set(const NzVector3& vec1, const NzVector3& vec2); - template NzAxisAlignedBox& Set(const NzAxisAlignedBox& box); - - NzString ToString() const; - - NzAxisAlignedBox& Transform(const NzMatrix4& matrix, bool applyTranslation = true); - - NzAxisAlignedBox operator*(T scalar) const; - - NzAxisAlignedBox& operator*=(T scalar); - - bool operator==(const NzAxisAlignedBox& box) const; - bool operator!=(const NzAxisAlignedBox& box) const; - - static NzAxisAlignedBox Infinite(); - static NzAxisAlignedBox Lerp(const NzAxisAlignedBox& from, const NzAxisAlignedBox& to, T interpolation); - static NzAxisAlignedBox Null(); - - nzExtend extend; - NzCube cube; -}; - -template -std::ostream& operator<<(std::ostream& out, const NzAxisAlignedBox& box); - -typedef NzAxisAlignedBox NzAxisAlignedBoxd; -typedef NzAxisAlignedBox NzAxisAlignedBoxf; - -#include - -#endif // NAZARA_AXISALIGNEDBOX_HPP diff --git a/include/Nazara/Math/AxisAlignedBox.inl b/include/Nazara/Math/AxisAlignedBox.inl deleted file mode 100644 index 8abaa6b34..000000000 --- a/include/Nazara/Math/AxisAlignedBox.inl +++ /dev/null @@ -1,610 +0,0 @@ -// Copyright (C) 2012 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 -#include -#include -#include -#include - -#define F(a) static_cast(a) - -template -NzAxisAlignedBox::NzAxisAlignedBox() : -extend(nzExtend_Null) -{ -} - -template -NzAxisAlignedBox::NzAxisAlignedBox(nzExtend Extend) -{ - Set(Extend); -} - -template -NzAxisAlignedBox::NzAxisAlignedBox(T X, T Y, T Z, T Width, T Height, T Depth) -{ - Set(X, Y, Z, Width, Height, Depth); -} - -template -NzAxisAlignedBox::NzAxisAlignedBox(const NzCube& Cube) -{ - Set(Cube); -} - -template -NzAxisAlignedBox::NzAxisAlignedBox(const NzVector3& vec1, const NzVector3& vec2) -{ - Set(vec1, vec2); -} - -template -template -NzAxisAlignedBox::NzAxisAlignedBox(const NzAxisAlignedBox& box) -{ - Set(box); -} - -template -bool NzAxisAlignedBox::Contains(T x, T y, T z) const -{ - switch (extend) - { - case nzExtend_Finite: - return cube.Contains(x, y, z); - - case nzExtend_Infinite: - return true; - - case nzExtend_Null: - return false; - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (0x" + NzString::Number(extend, 16) + ')'); - return false; -} - -template -bool NzAxisAlignedBox::Contains(const NzAxisAlignedBox& box) const -{ - if (extend == nzExtend_Null || box.extend == nzExtend_Null) - return false; - else if (extend == nzExtend_Infinite || box.extend == nzExtend_Infinite) - return true; - - return cube.Contains(box.cube); -} - -template -bool NzAxisAlignedBox::Contains(const NzVector3& vector) const -{ - switch (extend) - { - case nzExtend_Finite: - return cube.Contains(vector); - - case nzExtend_Infinite: - return true; - - case nzExtend_Null: - return false; - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (0x" + NzString::Number(extend, 16) + ')'); - return false; -} - -template -NzAxisAlignedBox& NzAxisAlignedBox::ExtendTo(T X, T Y, T Z) -{ - switch (extend) - { - case nzExtend_Finite: - cube.ExtendTo(X, Y, Z); - return *this; - - case nzExtend_Infinite: - return *this; // Rien à faire - - case nzExtend_Null: - return Set(cube.Set(X, Y, Z, F(0.0), F(0.0), F(0.0)));; - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (0x" + NzString::Number(extend, 16) + ')'); - return *this; -} - -template -NzAxisAlignedBox& NzAxisAlignedBox::ExtendTo(const NzAxisAlignedBox& box) -{ - switch (extend) - { - case nzExtend_Finite: - switch (box.extend) - { - case nzExtend_Finite: - cube.ExtendTo(box.cube); - return *this; - - case nzExtend_Infinite: - return MakeInfinite(); - - case nzExtend_Null: - return *this; - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (0x" + NzString::Number(box.extend, 16) + ')'); - return *this; - - case nzExtend_Infinite: - return *this; // Rien à faire - - case nzExtend_Null: - return Set(box); - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (0x" + NzString::Number(extend, 16) + ')'); - return *this; -} - -template -NzAxisAlignedBox& NzAxisAlignedBox::ExtendTo(const NzVector3& vector) -{ - return ExtendTo(vector.x, vector.y, vector.z); -} - -template -NzVector3 NzAxisAlignedBox::GetCorner(nzCorner corner) const -{ - switch (extend) - { - case nzExtend_Finite: - return cube.GetCorner(corner); - - case nzExtend_Infinite: - // Il est possible de renvoyer un vecteur avec des flottants infinis dont le signe dépend du coin - // Bien que ça soit plus juste mathématiquement, je ne vois pas l'intérêt... - NazaraError("Infinite AABB has no corner"); - return NzVector3(); - - case nzExtend_Null: - return NzVector3::Zero(); - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (0x" + NzString::Number(extend, 16) + ')'); - return NzVector3(); -} - -template -NzCube NzAxisAlignedBox::GetCube() const -{ - return cube; -} - -template -nzExtend NzAxisAlignedBox::GetExtend() const -{ - return extend; -} - -template -NzVector3 NzAxisAlignedBox::GetNegativeVertex(const NzVector3& normal) const -{ - switch (extend) - { - case nzExtend_Finite: - return cube.GetNegativeVertex(normal); - - case nzExtend_Infinite: - // Il est possible de renvoyer un vecteur avec des flottants infinis dont le signe dépend de la normale - // Bien que ça soit plus juste mathématiquement, je ne vois pas l'intérêt... - NazaraError("Infinite AABB has no negative vertex"); - return NzVector3(); - - case nzExtend_Null: - return NzVector3::Zero(); - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (0x" + NzString::Number(extend, 16) + ')'); - return NzVector3(); -} - -template -NzVector3 NzAxisAlignedBox::GetPosition() const -{ - switch (extend) - { - case nzExtend_Finite: - return cube.GetPosition(); - - case nzExtend_Infinite: - // Il est possible de renvoyer un vecteur avec des flottants infinis - // Bien que ça soit plus juste mathématiquement, je ne vois pas l'intérêt... - NazaraError("Infinite AABB has no position"); - return NzVector3(); - - case nzExtend_Null: - return NzVector3::Zero(); - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (0x" + NzString::Number(extend, 16) + ')'); - return NzVector3(); -} - -template -NzVector3 NzAxisAlignedBox::GetPositiveVertex(const NzVector3& normal) const -{ - switch (extend) - { - case nzExtend_Finite: - return cube.GetPositiveVertex(normal); - - case nzExtend_Infinite: - // Il est possible de renvoyer un vecteur avec des flottants infinis dont le signe dépend de la normale - // Bien que ça soit plus juste mathématiquement, je ne vois pas l'intérêt... - NazaraError("Infinite AABB has no corner"); - return NzVector3(); - - case nzExtend_Null: - return NzVector3::Zero(); - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (0x" + NzString::Number(extend, 16) + ')'); - return NzVector3(); -} - -template -NzVector3 NzAxisAlignedBox::GetSize() const -{ - switch (extend) - { - case nzExtend_Finite: - return cube.GetSize(); - - case nzExtend_Infinite: - // Il est possible de renvoyer un vecteur avec des flottants infinis - // Bien que ça soit plus juste mathématiquement, je ne vois pas l'intérêt... - NazaraError("Infinite AABB has no size"); - return NzVector3(); - - case nzExtend_Null: - return NzVector3::Zero(); - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (0x" + NzString::Number(extend, 16) + ')'); - return NzVector3(); -} - -template -bool NzAxisAlignedBox::Intersect(const NzAxisAlignedBox& box, NzAxisAlignedBox* intersection) const -{ - switch (extend) - { - case nzExtend_Finite: - { - switch (box.extend) - { - case nzExtend_Finite: - { - if (cube.Intersect(box.cube, &intersection->cube)) - { - intersection->extend = nzExtend_Finite; - return true; - } - else - return false; - } - - case nzExtend_Infinite: - intersection->Set(*this); - return true; - - case nzExtend_Null: - return false; - } - - NazaraError("Invalid extend type (0x" + NzString::Number(box.extend, 16) + ')'); - return false; - } - - case nzExtend_Infinite: - if (!box.IsNull()) // Si l'AABB n'est pas nulle, c'est qu'elle est finie ou infinie - { - // Et dans ce cas, il y a toujous intersection équivalente à la seconde AABB - intersection->Set(box); - return true; - } - else - return false; - - case nzExtend_Null: - return false; // N'a jamais de collision avec quoi que ce soit - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (0x" + NzString::Number(extend, 16) + ')'); - return false; -} - -template -bool NzAxisAlignedBox::IsFinite() const -{ - return extend == nzExtend_Finite; -} - -template -bool NzAxisAlignedBox::IsInfinite() const -{ - return extend == nzExtend_Infinite; -} - -template -bool NzAxisAlignedBox::IsNull() const -{ - return extend == nzExtend_Null; -} - -template -NzAxisAlignedBox& NzAxisAlignedBox::MakeInfinite() -{ - extend = nzExtend_Infinite; - - return *this; -} - -template -NzAxisAlignedBox& NzAxisAlignedBox::MakeNull() -{ - extend = nzExtend_Null; - - return *this; -} - -template -NzAxisAlignedBox& NzAxisAlignedBox::Set(nzExtend Extend) -{ - extend = Extend; - - return *this; -} - -template -NzAxisAlignedBox& NzAxisAlignedBox::Set(T X, T Y, T Z, T Width, T Height, T Depth) -{ - cube.Set(X, Y, Z, Width, Height, Depth); - extend = nzExtend_Finite; - - return *this; -} - -template -NzAxisAlignedBox& NzAxisAlignedBox::Set(const NzAxisAlignedBox& box) -{ - std::memcpy(this, &box, sizeof(NzAxisAlignedBox)); - - return *this; -} - -template -NzAxisAlignedBox& NzAxisAlignedBox::Set(const NzCube& Cube) -{ - cube.Set(Cube); - extend = nzExtend_Finite; - - return *this; -} - -template -NzAxisAlignedBox& NzAxisAlignedBox::Set(const NzVector3& vec1, const NzVector3& vec2) -{ - cube.Set(vec1, vec2); - extend = nzExtend_Finite; - - return *this; -} - -template -template -NzAxisAlignedBox& NzAxisAlignedBox::Set(const NzAxisAlignedBox& box) -{ - cube.Set(box); - extend = nzExtend_Finite; - - return *this; -} - -template -NzString NzAxisAlignedBox::ToString() const -{ - switch (extend) - { - case nzExtend_Finite: - return "NzAxisAlignedBox(min=" + cube.GetPosition().ToString() + ", max=" + (cube.GetPosition()+cube.GetSize()).ToString() + ')'; - - case nzExtend_Infinite: - return "NzAxisAlignedBox(Infinite)"; - - case nzExtend_Null: - return "NzAxisAlignedBox(Null)"; - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (0x" + NzString::Number(extend, 16) + ')'); - return "NzAxisAlignedBox(ERROR)"; -} - -template -NzAxisAlignedBox& NzAxisAlignedBox::Transform(const NzMatrix4& matrix, bool applyTranslation) -{ - if (extend != nzExtend_Finite) - return *this; // Toute transformation d'une AABox autre que finie résultera en la même AABox - - NzVector3 center = matrix.Transform(cube.GetCenter(), (applyTranslation) ? F(1.0) : F(0.0)); // Valeur multipliant la translation - NzVector3 halfSize = cube.GetSize() * F(0.5); - - 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, - std::fabs(matrix(0,2))*halfSize.x + std::fabs(matrix(1,2))*halfSize.y + std::fabs(matrix(2,2))*halfSize.z); - - cube.Set(center - halfSize, center + halfSize); - - return *this; -} - -template -NzAxisAlignedBox NzAxisAlignedBox::operator*(T scalar) const -{ - NzAxisAlignedBox box(*this); - box *= scalar; - - return box; -} - -template -NzAxisAlignedBox& NzAxisAlignedBox::operator*=(T scalar) -{ - switch (extend) - { - case nzExtend_Finite: - cube *= scalar; - return *this; - - case nzExtend_Infinite: - // L'infini multiplié par quoi que ce soit d'autre que zéro reste l'infini - // (On ne se préoccupe pas de l'infini de signe négatif, car ça finirait par être équivalent) - if (NzNumberEquals(scalar, F(0.0))) - MakeNull(); - - return *this; - - case nzExtend_Null: - return *this; // - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (0x" + NzString::Number(extend, 16) + ')'); - return NzVector3(); -} - -template -bool NzAxisAlignedBox::operator==(const NzAxisAlignedBox& box) const -{ - if (extend == box.extend) - return cube == box.cube; - else - return false; -} - -template -bool NzAxisAlignedBox::operator!=(const NzAxisAlignedBox& box) const -{ - return !operator==(box); -} - -template -NzAxisAlignedBox NzAxisAlignedBox::Infinite() -{ - NzAxisAlignedBox box; - box.MakeInfinite(); - - return box; -} - -template -NzAxisAlignedBox NzAxisAlignedBox::Lerp(const NzAxisAlignedBox& from, const NzAxisAlignedBox& to, T interpolation) -{ - #ifdef NAZARA_DEBUG - if (interpolation < 0.f || interpolation > 1.f) - { - NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')'); - return Null(); - } - #endif - - if (NzNumberEquals(interpolation, 0.f)) - return from; - - if (NzNumberEquals(interpolation, 1.f)) - return to; - - switch (to.extend) - { - case nzExtend_Finite: - { - switch (from.extend) - { - case nzExtend_Finite: - return NzCube::Lerp(from.cube, to.cube, interpolation); - - case nzExtend_Infinite: - return Infinite(); - - case nzExtend_Null: - return from.cube * interpolation; - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (From AABB) (0x" + NzString::Number(from.extend, 16) + ')'); - return Null(); - } - - case nzExtend_Infinite: - return Infinite(); // Un petit peu d'infini est infini quand même ;) - - case nzExtend_Null: - { - switch (from.extend) - { - case nzExtend_Finite: - return from.cube * (F(1.0) - interpolation); - - case nzExtend_Infinite: - return Infinite(); - - case nzExtend_Null: - return Null(); - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (From AABB) (0x" + NzString::Number(from.extend, 16) + ')'); - return Null(); - } - } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (To AABB) (0x" + NzString::Number(from.extend, 16) + ')'); - return Null(); -} - -template -NzAxisAlignedBox NzAxisAlignedBox::Null() -{ - NzAxisAlignedBox box; - box.MakeNull(); - - return box; -} - -template -std::ostream& operator<<(std::ostream& out, const NzAxisAlignedBox& box) -{ - out << box.ToString(); - return out; -} - -#undef F - -#include diff --git a/include/Nazara/Math/BoundingBox.hpp b/include/Nazara/Math/BoundingBox.hpp new file mode 100644 index 000000000..6164f413b --- /dev/null +++ b/include/Nazara/Math/BoundingBox.hpp @@ -0,0 +1,70 @@ +// Copyright (C) 2012 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 + +#ifndef NAZARA_BOUNDINGBOX_HPP +#define NAZARA_BOUNDINGBOX_HPP + +#include +#include +#include +#include +#include +#include + +template +class NzBoundingBox +{ + public: + NzBoundingBox(); + NzBoundingBox(nzExtend Extend); + NzBoundingBox(T X, T Y, T Z, T Width, T Height, T Depth); + NzBoundingBox(const NzCube& Cube); + NzBoundingBox(const NzVector3& vec1, const NzVector3& vec2); + template explicit NzBoundingBox(const NzBoundingBox& box); + NzBoundingBox(const NzBoundingBox& box) = default; + ~NzBoundingBox() = default; + + bool IsFinite() const; + bool IsInfinite() const; + bool IsNull() const; + + NzBoundingBox& MakeInfinite(); + NzBoundingBox& MakeNull(); + + NzBoundingBox& Set(nzExtend Extend); + NzBoundingBox& Set(T X, T Y, T Z, T Width, T Height, T Depth); + NzBoundingBox& Set(const NzBoundingBox& box); + NzBoundingBox& Set(const NzCube& Cube); + NzBoundingBox& Set(const NzVector3& vec1, const NzVector3& vec2); + template NzBoundingBox& Set(const NzBoundingBox& box); + + NzString ToString() const; + + void Update(const NzMatrix4& transformMatrix); + + NzBoundingBox operator*(T scalar) const; + + NzBoundingBox& operator*=(T scalar); + + bool operator==(const NzBoundingBox& box) const; + bool operator!=(const NzBoundingBox& box) const; + + static NzBoundingBox Infinite(); + static NzBoundingBox Lerp(const NzBoundingBox& from, const NzBoundingBox& to, T interpolation); + static NzBoundingBox Null(); + + nzExtend extend; + NzCube aabb; + NzOrientedCube obb; +}; + +template +std::ostream& operator<<(std::ostream& out, const NzBoundingBox& box); + +typedef NzBoundingBox NzBoundingBoxd; +typedef NzBoundingBox NzBoundingBoxf; + +#include + +#endif // NAZARA_BOUNDINGBOX_HPP diff --git a/include/Nazara/Math/BoundingBox.inl b/include/Nazara/Math/BoundingBox.inl new file mode 100644 index 000000000..5f4e6e39e --- /dev/null +++ b/include/Nazara/Math/BoundingBox.inl @@ -0,0 +1,295 @@ +// Copyright (C) 2012 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 +#include +#include +#include +#include + +#define F(a) static_cast(a) + +template +NzBoundingBox::NzBoundingBox() : +extend(nzExtend_Null) +{ +} + +template +NzBoundingBox::NzBoundingBox(nzExtend Extend) +{ + Set(Extend); +} + +template +NzBoundingBox::NzBoundingBox(T X, T Y, T Z, T Width, T Height, T Depth) +{ + Set(X, Y, Z, Width, Height, Depth); +} + +template +NzBoundingBox::NzBoundingBox(const NzCube& Cube) +{ + Set(Cube); +} + +template +NzBoundingBox::NzBoundingBox(const NzVector3& vec1, const NzVector3& vec2) +{ + Set(vec1, vec2); +} + +template +template +NzBoundingBox::NzBoundingBox(const NzBoundingBox& box) +{ + Set(box); +} + +template +bool NzBoundingBox::IsFinite() const +{ + return extend == nzExtend_Finite; +} + +template +bool NzBoundingBox::IsInfinite() const +{ + return extend == nzExtend_Infinite; +} + +template +bool NzBoundingBox::IsNull() const +{ + return extend == nzExtend_Null; +} + +template +NzBoundingBox& NzBoundingBox::MakeInfinite() +{ + extend = nzExtend_Infinite; + + return *this; +} + +template +NzBoundingBox& NzBoundingBox::MakeNull() +{ + extend = nzExtend_Null; + + return *this; +} + +template +NzBoundingBox& NzBoundingBox::Set(nzExtend Extend) +{ + extend = Extend; + + return *this; +} + +template +NzBoundingBox& NzBoundingBox::Set(T X, T Y, T Z, T Width, T Height, T Depth) +{ + obb.Set(X, Y, Z, Width, Height, Depth); + extend = nzExtend_Finite; + + return *this; +} + +template +NzBoundingBox& NzBoundingBox::Set(const NzBoundingBox& box) +{ + obb.Set(box.obb); // Seul l'OBB est importante pour la suite + + return *this; +} + +template +NzBoundingBox& NzBoundingBox::Set(const NzCube& Cube) +{ + obb.Set(Cube); + extend = nzExtend_Finite; + + return *this; +} + +template +NzBoundingBox& NzBoundingBox::Set(const NzVector3& vec1, const NzVector3& vec2) +{ + obb.Set(vec1, vec2); + extend = nzExtend_Finite; + + return *this; +} + +template +template +NzBoundingBox& NzBoundingBox::Set(const NzBoundingBox& box) +{ + obb.Set(box.obb); + extend = box.extend; + + return *this; +} + +template +NzString NzBoundingBox::ToString() const +{ + switch (extend) + { + case nzExtend_Finite: + return "BoundingBox(localCube=" + obb.localCube.ToString() + ')'; + + case nzExtend_Infinite: + return "BoundingBox(Infinite)"; + + case nzExtend_Null: + return "BoundingBox(Null)"; + } + + // Si nous arrivons ici c'est que l'extend est invalide + NazaraError("Invalid extend type (0x" + NzString::Number(extend, 16) + ')'); + return "BoundingBox(ERROR)"; +} + +template +void NzBoundingBox::Update(const NzMatrix4& transformMatrix) +{ + aabb.Set(obb.localCube); + aabb.Transform(transformMatrix); + obb.Update(transformMatrix); +} + +template +NzBoundingBox NzBoundingBox::operator*(T scalar) const +{ + NzBoundingBox box(*this); + box *= scalar; + + return box; +} + +template +NzBoundingBox& NzBoundingBox::operator*=(T scalar) +{ + aabb *= scalar; + obb *= scalar; +} + +template +bool NzBoundingBox::operator==(const NzBoundingBox& box) const +{ + if (extend == box.extend) + return obb == box.obb; + else + return false; +} + +template +bool NzBoundingBox::operator!=(const NzBoundingBox& box) const +{ + return !operator==(box); +} + +template +NzBoundingBox NzBoundingBox::Infinite() +{ + NzBoundingBox box; + box.MakeInfinite(); + + return box; +} + +template +NzBoundingBox NzBoundingBox::Lerp(const NzBoundingBox& from, const NzBoundingBox& to, T interpolation) +{ + #ifdef NAZARA_DEBUG + if (interpolation < 0.f || interpolation > 1.f) + { + NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')'); + return Null(); + } + #endif + + if (NzNumberEquals(interpolation, 0.f)) + return from; + + if (NzNumberEquals(interpolation, 1.f)) + return to; + + switch (to.extend) + { + case nzExtend_Finite: + { + switch (from.extend) + { + case nzExtend_Finite: + { + NzBoundingBox box; + box.Set(NzOrientedCube::Lerp(from.obb, to.obb, interpolation)); + + return box; + } + + case nzExtend_Infinite: + return Infinite(); + + case nzExtend_Null: + return from.obb * interpolation; + } + + // Si nous arrivons ici c'est que l'extend est invalide + NazaraError("Invalid extend type (From) (0x" + NzString::Number(from.extend, 16) + ')'); + return Null(); + } + + case nzExtend_Infinite: + return Infinite(); // Un petit peu d'infini est infini quand même ;) + + case nzExtend_Null: + { + switch (from.extend) + { + case nzExtend_Finite: + return from.obb * (F(1.0) - interpolation); + + case nzExtend_Infinite: + return Infinite(); + + case nzExtend_Null: + return Null(); + } + + // Si nous arrivons ici c'est que l'extend est invalide + NazaraError("Invalid extend type (From) (0x" + NzString::Number(from.extend, 16) + ')'); + return Null(); + } + } + + // Si nous arrivons ici c'est que l'extend est invalide + NazaraError("Invalid extend type (To) (0x" + NzString::Number(from.extend, 16) + ')'); + return Null(); +} + +template +NzBoundingBox NzBoundingBox::Null() +{ + NzBoundingBox box; + box.MakeNull(); + + return box; +} + +template +std::ostream& operator<<(std::ostream& out, const NzBoundingBox& box) +{ + out << box.ToString(); + return out; +} + +#undef F + +#include diff --git a/include/Nazara/Math/Frustum.hpp b/include/Nazara/Math/Frustum.hpp index 5c147f789..3124aa52f 100644 --- a/include/Nazara/Math/Frustum.hpp +++ b/include/Nazara/Math/Frustum.hpp @@ -8,9 +8,10 @@ #define NAZARA_FRUSTUM_HPP #include -#include +#include #include #include +#include #include #include #include @@ -26,8 +27,9 @@ class NzFrustum NzFrustum& Build(T angle, T ratio, T zNear, T zFar, const NzVector3& eye, const NzVector3& target, const NzVector3& up = NzVector3::Up()); - bool Contains(const NzAxisAlignedBox& box) const; + bool Contains(const NzBoundingBox& box) const; bool Contains(const NzCube& cube) const; + bool Contains(const NzOrientedCube& orientedCube) const; bool Contains(const NzSphere& sphere) const; bool Contains(const NzVector3& point) const; bool Contains(const NzVector3* points, unsigned int pointCount) const; @@ -38,8 +40,9 @@ class NzFrustum const NzVector3& GetCorner(nzCorner corner) const; const NzPlane& GetPlane(nzFrustumPlane plane) const; - nzIntersectionSide Intersect(const NzAxisAlignedBox& box) const; + nzIntersectionSide Intersect(const NzBoundingBox& box) const; nzIntersectionSide Intersect(const NzCube& cube) const; + nzIntersectionSide Intersect(const NzOrientedCube& orientedCube) const; nzIntersectionSide Intersect(const NzSphere& sphere) const; nzIntersectionSide Intersect(const NzVector3* points, unsigned int pointCount) const; diff --git a/include/Nazara/Math/Frustum.inl b/include/Nazara/Math/Frustum.inl index e840ec018..6c5b6325b 100644 --- a/include/Nazara/Math/Frustum.inl +++ b/include/Nazara/Math/Frustum.inl @@ -66,12 +66,12 @@ NzFrustum& NzFrustum::Build(T angle, T ratio, T zNear, T zFar, const NzVec } template -bool NzFrustum::Contains(const NzAxisAlignedBox& box) const +bool NzFrustum::Contains(const NzBoundingBox& box) const { switch (box.extend) { case nzExtend_Finite: - return Contains(box.cube); + return Contains(box.aabb) && Contains(box.obb); case nzExtend_Infinite: return true; @@ -97,6 +97,12 @@ bool NzFrustum::Contains(const NzCube& cube) const return true; } +template +bool NzFrustum::Contains(const NzOrientedCube& orientedCube) const +{ + return Contains(&orientedCube[0], 8); +} + template bool NzFrustum::Contains(const NzSphere& sphere) const { @@ -347,12 +353,12 @@ const NzPlane& NzFrustum::GetPlane(nzFrustumPlane plane) const } template -nzIntersectionSide NzFrustum::Intersect(const NzAxisAlignedBox& box) const +nzIntersectionSide NzFrustum::Intersect(const NzBoundingBox& box) const { switch (box.extend) { case nzExtend_Finite: - return Intersect(box.cube); + return Intersect(box.aabb) && Intersect(box.obb); // Test de l'AABB et puis de l'OBB case nzExtend_Infinite: return nzIntersectionSide_Intersecting; @@ -382,6 +388,12 @@ nzIntersectionSide NzFrustum::Intersect(const NzCube& cube) const return side; } +template +nzIntersectionSide NzFrustum::Intersect(const NzOrientedCube& orientedCube) const +{ + return Intersect(&orientedCube[0], 8); +} + template nzIntersectionSide NzFrustum::Intersect(const NzSphere& sphere) const { diff --git a/include/Nazara/Math/Matrix4.hpp b/include/Nazara/Math/Matrix4.hpp index c3c8f7f07..cf9eeaaaf 100644 --- a/include/Nazara/Math/Matrix4.hpp +++ b/include/Nazara/Math/Matrix4.hpp @@ -88,7 +88,7 @@ class NzMatrix4 operator const T*() const; T& operator()(unsigned int x, unsigned int y); - const T& operator()(unsigned int x, unsigned int y) const; + T operator()(unsigned int x, unsigned int y) const; NzMatrix4& operator=(const NzMatrix4& matrix) = default; diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index 742b44f0b..0f1f01288 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -769,7 +769,7 @@ T& NzMatrix4::operator()(unsigned int x, unsigned int y) } template -const T& NzMatrix4::operator()(unsigned int x, unsigned int y) const +T NzMatrix4::operator()(unsigned int x, unsigned int y) const { #if NAZARA_MATH_SAFE if (x > 3 || y > 3) diff --git a/include/Nazara/Renderer/DebugDrawer.hpp b/include/Nazara/Renderer/DebugDrawer.hpp index 5afa5cdf2..44e72bcc0 100644 --- a/include/Nazara/Renderer/DebugDrawer.hpp +++ b/include/Nazara/Renderer/DebugDrawer.hpp @@ -9,9 +9,10 @@ #include #include -#include +#include #include #include +#include #include class NzSkeleton; @@ -19,11 +20,12 @@ class NzSkeleton; class NAZARA_API NzDebugDrawer { public: - static void Draw(const NzAxisAlignedBoxf& aabb); + static void Draw(const NzBoundingBoxf& box); static void Draw(const NzCubef& cube); static void Draw(const NzCubei& cube); static void Draw(const NzCubeui& cube); static void Draw(const NzFrustumf& frustum); + static void Draw(const NzOrientedCubef& orientedCube); static void Draw(const NzSkeleton* skeleton); static void DrawNormals(const NzSubMesh* subMesh); static void DrawTangents(const NzSubMesh* subMesh); diff --git a/include/Nazara/Utility/KeyframeMesh.hpp b/include/Nazara/Utility/KeyframeMesh.hpp index e95f3d8b5..43c6090e9 100644 --- a/include/Nazara/Utility/KeyframeMesh.hpp +++ b/include/Nazara/Utility/KeyframeMesh.hpp @@ -28,7 +28,7 @@ class NAZARA_API NzKeyframeMesh final : public NzSubMesh void GenerateAABBs(); - const NzAxisAlignedBoxf& GetAABB() const override; + const NzCubef& GetAABB() const override; nzAnimationType GetAnimationType() const override; unsigned int GetFrameCount() const; const NzIndexBuffer* GetIndexBuffer() const override; @@ -46,7 +46,7 @@ class NAZARA_API NzKeyframeMesh final : public NzSubMesh bool IsAnimated() const override; bool IsValid(); - void SetAABB(unsigned int frameIndex, const NzAxisAlignedBoxf& aabb); + void SetAABB(unsigned int frameIndex, const NzCubef& aabb); void SetIndexBuffer(const NzIndexBuffer* indexBuffer); void SetNormal(unsigned int frameIndex, unsigned int vertexIndex, const NzVector3f& normal); void SetPosition(unsigned int frameIndex, unsigned int vertexIndex, const NzVector3f& position); diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index b8f713064..ed6acc700 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -59,7 +59,7 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener void GenerateNormalsAndTangents(); void GenerateTangents(); - const NzAxisAlignedBoxf& GetAABB() const; + const NzCubef& GetAABB() const; NzString GetAnimation() const; nzAnimationType GetAnimationType() const; unsigned int GetJointCount() const; diff --git a/include/Nazara/Utility/SkeletalMesh.hpp b/include/Nazara/Utility/SkeletalMesh.hpp index 2421e7909..efcb9703b 100644 --- a/include/Nazara/Utility/SkeletalMesh.hpp +++ b/include/Nazara/Utility/SkeletalMesh.hpp @@ -37,7 +37,7 @@ class NAZARA_API NzSkeletalMesh final : public NzSubMesh void Finish(); - const NzAxisAlignedBoxf& GetAABB() const; + const NzCubef& GetAABB() const; nzAnimationType GetAnimationType() const final; void* GetBindPoseBuffer(); const void* GetBindPoseBuffer() const; diff --git a/include/Nazara/Utility/Skeleton.hpp b/include/Nazara/Utility/Skeleton.hpp index 7cca01817..7bee05618 100644 --- a/include/Nazara/Utility/Skeleton.hpp +++ b/include/Nazara/Utility/Skeleton.hpp @@ -8,7 +8,7 @@ #define NAZARA_SKELETON_HPP #include -#include +#include #include #include @@ -26,7 +26,7 @@ class NAZARA_API NzSkeleton bool Create(unsigned int jointCount); void Destroy(); - const NzAxisAlignedBoxf& GetAABB() const; + const NzCubef& GetAABB() const; NzJoint* GetJoint(const NzString& jointName); NzJoint* GetJoint(unsigned int index); const NzJoint* GetJoint(const NzString& jointName) const; diff --git a/include/Nazara/Utility/StaticMesh.hpp b/include/Nazara/Utility/StaticMesh.hpp index cfbf25fbe..78c69b4c7 100644 --- a/include/Nazara/Utility/StaticMesh.hpp +++ b/include/Nazara/Utility/StaticMesh.hpp @@ -24,7 +24,7 @@ class NAZARA_API NzStaticMesh final : public NzSubMesh, NzResourceListener bool GenerateAABB(); - const NzAxisAlignedBoxf& GetAABB() const override; + const NzCubef& GetAABB() const override; nzAnimationType GetAnimationType() const final; const NzIndexBuffer* GetIndexBuffer() const override; NzVertexBuffer* GetVertexBuffer() override; @@ -33,13 +33,13 @@ class NAZARA_API NzStaticMesh final : public NzSubMesh, NzResourceListener bool IsAnimated() const final; bool IsValid() const; - void SetAABB(const NzAxisAlignedBoxf& aabb); + void SetAABB(const NzCubef& aabb); void SetIndexBuffer(const NzIndexBuffer* indexBuffer); private: void OnResourceReleased(const NzResource* resource, int index) override; - NzAxisAlignedBoxf m_aabb; + NzCubef m_aabb; const NzIndexBuffer* m_indexBuffer = nullptr; NzVertexBuffer* m_vertexBuffer = nullptr; }; diff --git a/include/Nazara/Utility/SubMesh.hpp b/include/Nazara/Utility/SubMesh.hpp index ff0c8b6a7..16ea89c64 100644 --- a/include/Nazara/Utility/SubMesh.hpp +++ b/include/Nazara/Utility/SubMesh.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -27,7 +27,7 @@ class NAZARA_API NzSubMesh : public NzResource virtual void Finish() = 0; ///DOC: Mets le mesh dans sa position d'origine et calcule son AABB - virtual const NzAxisAlignedBoxf& GetAABB() const = 0; + virtual const NzCubef& GetAABB() const = 0; virtual nzAnimationType GetAnimationType() const = 0; virtual const NzIndexBuffer* GetIndexBuffer() const = 0; unsigned int GetMaterialIndex() const; diff --git a/src/Nazara/Renderer/DebugDrawer.cpp b/src/Nazara/Renderer/DebugDrawer.cpp index 58019912f..45c8b2e85 100644 --- a/src/Nazara/Renderer/DebugDrawer.cpp +++ b/src/Nazara/Renderer/DebugDrawer.cpp @@ -31,12 +31,19 @@ namespace static int colorLocation = -1; } -void NzDebugDrawer::Draw(const NzAxisAlignedBoxf& aabb) +void NzDebugDrawer::Draw(const NzBoundingBoxf& box) { - if (!aabb.IsFinite()) + if (!box.IsFinite()) return; - Draw(aabb.GetCube()); + NzColor oldPrimaryColor = primaryColor; + + Draw(box.aabb); + + primaryColor = secondaryColor; + Draw(box.obb); + + primaryColor = oldPrimaryColor; } void NzDebugDrawer::Draw(const NzCubei& cube) @@ -259,6 +266,109 @@ void NzDebugDrawer::Draw(const NzFrustumf& frustum) NazaraWarning("Failed to reset shader"); } +void NzDebugDrawer::Draw(const NzOrientedCubef& orientedCube) +{ + if (!initialized) + { + NazaraError("Debug drawer is not initialized"); + return; + } + + NzBufferMapper mapper(vertexBuffer, nzBufferAccess_DiscardAndWrite, 0, 24); + NzVertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); + + vertex->position.Set(orientedCube.GetCorner(nzCorner_NearLeftBottom)); + vertex++; + vertex->position.Set(orientedCube.GetCorner(nzCorner_NearRightBottom)); + vertex++; + + vertex->position.Set(orientedCube.GetCorner(nzCorner_NearLeftBottom)); + vertex++; + vertex->position.Set(orientedCube.GetCorner(nzCorner_NearLeftTop)); + vertex++; + + vertex->position.Set(orientedCube.GetCorner(nzCorner_NearLeftBottom)); + vertex++; + vertex->position.Set(orientedCube.GetCorner(nzCorner_FarLeftBottom)); + vertex++; + + vertex->position.Set(orientedCube.GetCorner(nzCorner_FarRightTop)); + vertex++; + vertex->position.Set(orientedCube.GetCorner(nzCorner_FarLeftTop)); + vertex++; + + vertex->position.Set(orientedCube.GetCorner(nzCorner_FarRightTop)); + vertex++; + vertex->position.Set(orientedCube.GetCorner(nzCorner_FarRightBottom)); + vertex++; + + vertex->position.Set(orientedCube.GetCorner(nzCorner_FarRightTop)); + vertex++; + vertex->position.Set(orientedCube.GetCorner(nzCorner_NearRightTop)); + vertex++; + + vertex->position.Set(orientedCube.GetCorner(nzCorner_FarLeftBottom)); + vertex++; + vertex->position.Set(orientedCube.GetCorner(nzCorner_FarRightBottom)); + vertex++; + + vertex->position.Set(orientedCube.GetCorner(nzCorner_FarLeftBottom)); + vertex++; + vertex->position.Set(orientedCube.GetCorner(nzCorner_FarLeftTop)); + vertex++; + + vertex->position.Set(orientedCube.GetCorner(nzCorner_NearLeftTop)); + vertex++; + vertex->position.Set(orientedCube.GetCorner(nzCorner_NearRightTop)); + vertex++; + + vertex->position.Set(orientedCube.GetCorner(nzCorner_NearLeftTop)); + vertex++; + vertex->position.Set(orientedCube.GetCorner(nzCorner_FarLeftTop)); + vertex++; + + vertex->position.Set(orientedCube.GetCorner(nzCorner_NearRightBottom)); + vertex++; + vertex->position.Set(orientedCube.GetCorner(nzCorner_NearRightTop)); + vertex++; + + vertex->position.Set(orientedCube.GetCorner(nzCorner_NearRightBottom)); + vertex++; + vertex->position.Set(orientedCube.GetCorner(nzCorner_FarRightBottom)); + vertex++; + + mapper.Unmap(); + + const NzShader* oldShader = NzRenderer::GetShader(); + + if (!NzRenderer::SetShader(shader)) + { + NazaraError("Failed to set debug shader"); + return; + } + + bool depthTestActive = NzRenderer::IsEnabled(nzRendererParameter_DepthTest); + if (depthTestActive != depthTest) + NzRenderer::Enable(nzRendererParameter_DepthTest, depthTest); + + float oldLineWidth = NzRenderer::GetLineWidth(); + NzRenderer::SetLineWidth(lineWidth); + + NzRenderer::SetVertexBuffer(vertexBuffer); + + shader->SendColor(colorLocation, primaryColor); + + NzRenderer::DrawPrimitives(nzPrimitiveType_LineList, 0, 24); + + NzRenderer::SetLineWidth(oldLineWidth); + + if (depthTestActive != depthTest) + NzRenderer::Enable(nzRendererParameter_DepthTest, depthTestActive); + + if (!NzRenderer::SetShader(oldShader)) + NazaraWarning("Failed to reset shader"); +} + void NzDebugDrawer::Draw(const NzSkeleton* skeleton) { if (!initialized) diff --git a/src/Nazara/Utility/KeyframeMesh.cpp b/src/Nazara/Utility/KeyframeMesh.cpp index 0d44ae7b1..c80c4cff8 100644 --- a/src/Nazara/Utility/KeyframeMesh.cpp +++ b/src/Nazara/Utility/KeyframeMesh.cpp @@ -12,7 +12,7 @@ struct NzKeyframeMeshImpl { - NzAxisAlignedBoxf* aabb; + NzCubef* aabb; NzVector2f* uv; NzVector3f* normals; NzVector3f* positions; @@ -59,7 +59,7 @@ bool NzKeyframeMesh::Create(NzVertexBuffer* vertexBuffer, unsigned int frameCoun vertexBuffer->AddResourceReference(); m_impl = new NzKeyframeMeshImpl; - m_impl->aabb = new NzAxisAlignedBoxf[frameCount+1]; // La première case représente l'AABB interpolée + m_impl->aabb = new NzCubef[frameCount+1]; // La première case représente l'AABB interpolée m_impl->frameCount = frameCount; m_impl->vertexBuffer = vertexBuffer; @@ -123,25 +123,23 @@ void NzKeyframeMesh::GenerateAABBs() unsigned int vertexCount = m_impl->vertexBuffer->GetVertexCount(); for (unsigned int i = 0; i < m_impl->frameCount; ++i) { - NzAxisAlignedBoxf& aabb = m_impl->aabb[i+1]; // l'AABB 0 est celle qui est interpolée - if (aabb.IsNull()) - { - // Génération de l'AABB selon la position - unsigned int index = i*vertexCount; - for (unsigned int j = 0; j < vertexCount; ++j) - aabb.ExtendTo(m_impl->positions[index+j]); - } + NzCubef& aabb = m_impl->aabb[i+1]; // l'AABB 0 est celle qui est interpolée + + // Génération de l'AABB selon la position + unsigned int index = i*vertexCount; + for (unsigned int j = 0; j < vertexCount; ++j) + aabb.ExtendTo(m_impl->positions[index+j]); } } -const NzAxisAlignedBoxf& NzKeyframeMesh::GetAABB() const +const NzCubef& NzKeyframeMesh::GetAABB() const { #if NAZARA_UTILITY_SAFE if (!m_impl) { NazaraError("Keyframe mesh not created"); - static NzAxisAlignedBoxf dummy(nzExtend_Null); + static NzCubef dummy; return dummy; } #endif @@ -404,7 +402,7 @@ bool NzKeyframeMesh::IsValid() return m_impl != nullptr; } -void NzKeyframeMesh::SetAABB(unsigned int frameIndex, const NzAxisAlignedBoxf& aabb) +void NzKeyframeMesh::SetAABB(unsigned int frameIndex, const NzCubef& aabb) { #if NAZARA_UTILITY_SAFE if (!m_impl) @@ -502,7 +500,6 @@ void NzKeyframeMesh::SetPosition(unsigned int frameIndex, unsigned int vertexInd unsigned int index = frameIndex*vertexCount + vertexIndex; m_impl->positions[index] = position; - m_impl->aabb[frameIndex+1].MakeNull(); // Invalidation de l'AABB } void NzKeyframeMesh::SetTangent(unsigned int frameIndex, unsigned int vertexIndex, const NzVector3f& tangent) @@ -566,7 +563,7 @@ void NzKeyframeMesh::InterpolateImpl(unsigned int frameA, unsigned int frameB, f #endif // Interpolation de l'AABB - m_impl->aabb[0] = NzAxisAlignedBoxf::Lerp(m_impl->aabb[frameA+1], m_impl->aabb[frameB+1], interpolation); + m_impl->aabb[0] = NzCubef::Lerp(m_impl->aabb[frameA+1], m_impl->aabb[frameB+1], interpolation); NzMeshVertex* vertex = reinterpret_cast(m_impl->vertexBuffer->Map(nzBufferAccess_DiscardAndWrite)); if (!vertex) diff --git a/src/Nazara/Utility/Loaders/MD5Anim/Parser.hpp b/src/Nazara/Utility/Loaders/MD5Anim/Parser.hpp index 0d3a1ef85..39cef84e4 100644 --- a/src/Nazara/Utility/Loaders/MD5Anim/Parser.hpp +++ b/src/Nazara/Utility/Loaders/MD5Anim/Parser.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -34,7 +34,7 @@ class NzMD5AnimParser }; std::vector joints; - NzAxisAlignedBoxf aabb; + NzCubef aabb; }; struct Joint diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index 882d00c1e..b3d263371 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -41,9 +41,10 @@ struct NzMeshImpl std::vector materials; std::vector subMeshes; nzAnimationType animationType; - NzAxisAlignedBoxf aabb; + NzCubef aabb; NzSkeleton skeleton; // Uniquement pour les meshs squelettiques NzString animationPath; + bool aabbUpdated = false; unsigned int jointCount; // Uniquement pour les meshs squelettiques }; @@ -77,7 +78,7 @@ bool NzMesh::AddSubMesh(NzSubMesh* subMesh) subMesh->AddResourceListener(this, m_impl->subMeshes.size()); subMesh->Finish(); - m_impl->aabb.MakeNull(); // On invalide l'AABB + m_impl->aabbUpdated = false; // On invalide l'AABB m_impl->subMeshes.push_back(subMesh); return true; @@ -123,7 +124,7 @@ bool NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh) subMesh->AddResourceListener(this, index); subMesh->Finish(); - m_impl->aabb.MakeNull(); // On invalide l'AABB + m_impl->aabbUpdated = false; // On invalide l'AABB m_impl->subMeshes.push_back(subMesh); m_impl->subMeshMap[identifier] = index; @@ -206,7 +207,7 @@ void NzMesh::Animate(const NzAnimation* animation, unsigned int frameA, unsigned break; } - m_impl->aabb.MakeNull(); // On invalide l'AABB + m_impl->aabbUpdated = false; // On invalide l'AABB } bool NzMesh::CreateKeyframe() @@ -417,22 +418,24 @@ void NzMesh::GenerateTangents() } } -const NzAxisAlignedBoxf& NzMesh::GetAABB() const +const NzCubef& NzMesh::GetAABB() const { #if NAZARA_UTILITY_SAFE if (!m_impl) { NazaraError("Mesh not created"); - static NzAxisAlignedBoxf dummy(nzExtend_Null); + static NzCubef dummy; return dummy; } #endif - if (m_impl->aabb.IsNull()) + if (!m_impl->aabbUpdated) { for (NzSubMesh* subMesh : m_impl->subMeshes) m_impl->aabb.ExtendTo(subMesh->GetAABB()); + + m_impl->aabbUpdated = true; } return m_impl->aabb; @@ -700,7 +703,7 @@ void NzMesh::InvalidateAABB() const } #endif - m_impl->aabb.MakeNull(); + m_impl->aabbUpdated = false; } bool NzMesh::HasSubMesh(const NzString& identifier) const @@ -791,7 +794,7 @@ void NzMesh::RemoveSubMesh(const NzString& identifier) (*it2)->RemoveResourceListener(this); m_impl->subMeshes.erase(it2); - m_impl->aabb.MakeNull(); // On invalide l'AABB + m_impl->aabbUpdated = false; // On invalide l'AABB } void NzMesh::RemoveSubMesh(unsigned int index) @@ -818,7 +821,7 @@ void NzMesh::RemoveSubMesh(unsigned int index) (*it)->RemoveResourceListener(this); m_impl->subMeshes.erase(it); - m_impl->aabb.MakeNull(); // On invalide l'AABB + m_impl->aabbUpdated = false; // On invalide l'AABB } void NzMesh::SetAnimation(const NzString& animationPath) diff --git a/src/Nazara/Utility/SkeletalMesh.cpp b/src/Nazara/Utility/SkeletalMesh.cpp index b77e3018c..ebb749584 100644 --- a/src/Nazara/Utility/SkeletalMesh.cpp +++ b/src/Nazara/Utility/SkeletalMesh.cpp @@ -132,7 +132,7 @@ struct NzSkeletalMeshImpl { std::vector vertexWeights; std::vector weights; - NzAxisAlignedBoxf aabb; + NzCubef aabb; nzUInt8* bindPoseBuffer; const NzIndexBuffer* indexBuffer = nullptr; NzVertexBuffer* vertexBuffer; @@ -208,14 +208,14 @@ void NzSkeletalMesh::Finish() Skin(); } -const NzAxisAlignedBoxf& NzSkeletalMesh::GetAABB() const +const NzCubef& NzSkeletalMesh::GetAABB() const { #if NAZARA_UTILITY_SAFE if (!m_impl) { NazaraError("Skeletal mesh not created"); - static NzAxisAlignedBoxf dummy(nzExtend_Null); + static NzCubef dummy; return dummy; } #endif diff --git a/src/Nazara/Utility/Skeleton.cpp b/src/Nazara/Utility/Skeleton.cpp index 85465bb9b..a9b89052e 100644 --- a/src/Nazara/Utility/Skeleton.cpp +++ b/src/Nazara/Utility/Skeleton.cpp @@ -10,7 +10,8 @@ struct NzSkeletonImpl { std::map jointMap; ///FIXME: unordered_map std::vector joints; - NzAxisAlignedBoxf aabb; + NzCubef aabb; + bool aabbUpdated = false; bool jointMapUpdated = false; }; @@ -50,22 +51,24 @@ void NzSkeleton::Destroy() } } -const NzAxisAlignedBoxf& NzSkeleton::GetAABB() const +const NzCubef& NzSkeleton::GetAABB() const { #if NAZARA_UTILITY_SAFE if (!m_impl) { NazaraError("Skeleton not created"); - static NzAxisAlignedBoxf dummy(nzExtend_Null); + static NzCubef dummy; return dummy; } #endif - if (m_impl->aabb.IsNull()) + if (!m_impl->aabbUpdated) { for (unsigned int i = 0; i < m_impl->joints.size(); ++i) m_impl->aabb.ExtendTo(m_impl->joints[i].GetPosition()); + + m_impl->aabbUpdated = true; } return m_impl->aabb; @@ -95,7 +98,7 @@ NzJoint* NzSkeleton::GetJoint(const NzString& jointName) #endif // Invalidation de l'AABB - m_impl->aabb.MakeNull(); + m_impl->aabbUpdated = false; return &m_impl->joints[it->second]; } @@ -117,7 +120,7 @@ NzJoint* NzSkeleton::GetJoint(unsigned int index) #endif // Invalidation de l'AABB - m_impl->aabb.MakeNull(); + m_impl->aabbUpdated = false; return &m_impl->joints[index]; } @@ -265,7 +268,7 @@ void NzSkeleton::Interpolate(const NzSkeleton& skeletonA, const NzSkeleton& skel for (unsigned int i = 0; i < m_impl->joints.size(); ++i) m_impl->joints[i].Interpolate(jointsA[i], jointsB[i], interpolation); - m_impl->aabb.MakeNull(); + m_impl->aabbUpdated = false; } void NzSkeleton::Interpolate(const NzSkeleton& skeletonA, const NzSkeleton& skeletonB, float interpolation, unsigned int* indices, unsigned int indiceCount) @@ -313,7 +316,7 @@ void NzSkeleton::Interpolate(const NzSkeleton& skeletonA, const NzSkeleton& skel m_impl->joints[index].Interpolate(jointsA[index], jointsB[index], interpolation); } - m_impl->aabb.MakeNull(); + m_impl->aabbUpdated = false; } bool NzSkeleton::IsValid() const diff --git a/src/Nazara/Utility/StaticMesh.cpp b/src/Nazara/Utility/StaticMesh.cpp index 2634e21b6..740633f73 100644 --- a/src/Nazara/Utility/StaticMesh.cpp +++ b/src/Nazara/Utility/StaticMesh.cpp @@ -39,8 +39,6 @@ bool NzStaticMesh::Create(NzVertexBuffer* vertexBuffer) void NzStaticMesh::Destroy() { - m_aabb.MakeNull(); - if (m_indexBuffer) { m_indexBuffer->RemoveResourceListener(this); @@ -62,9 +60,6 @@ void NzStaticMesh::Finish() bool NzStaticMesh::GenerateAABB() { - if (!m_aabb.IsNull()) - return true; - // On lock le buffer pour itérer sur toutes les positions et composer notre AABB NzBufferMapper mapper(m_vertexBuffer, nzBufferAccess_ReadOnly); @@ -79,7 +74,7 @@ bool NzStaticMesh::GenerateAABB() return true; } -const NzAxisAlignedBoxf& NzStaticMesh::GetAABB() const +const NzCubef& NzStaticMesh::GetAABB() const { return m_aabb; } @@ -114,7 +109,7 @@ bool NzStaticMesh::IsValid() const return m_vertexBuffer != nullptr; } -void NzStaticMesh::SetAABB(const NzAxisAlignedBoxf& aabb) +void NzStaticMesh::SetAABB(const NzCubef& aabb) { m_aabb = aabb; }