Documentation for BoundingVolume & Box

Former-commit-id: 0fc14422dc32677f329f95dc7a554127f1b8ba0a
This commit is contained in:
Gawaboumga 2015-12-30 15:29:07 +01:00
parent 007b40b1b3
commit e2213cac61
3 changed files with 682 additions and 46 deletions

View File

@ -1,4 +1,4 @@
// Copyright (C) 2015 Jérôme Leclercq
// Copyright (C) 2015 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
@ -13,42 +13,108 @@
namespace Nz
{
/*!
* \class Nz::BoundingVolume<T>
* \brief Math class that represents a bounding volume, a combination of a box and an oriented box
*
* \remark You need to call Update not to have undefined behaviour
*/
/*!
* \brief Constructs a BoundingVolume<T> object by default
*
* \remark extend is set to Extend_Null, aabb and obb are uninitialized
*/
template<typename T>
BoundingVolume<T>::BoundingVolume() :
extend(Extend_Null)
{
}
/*!
* \brief Constructs a BoundingVolume<T> object from Extend
* \param Extend Extend of the volume part of enumeration Extend
*
* \remark Aabb and obb are uninitialized
*/
template<typename T>
BoundingVolume<T>::BoundingVolume(Extend Extend)
{
Set(Extend);
}
/*!
* \brief Constructs a BoundingVolume<T> object from its position and sizes
*
* \param X X component of position
* \param Y Y component of position
* \param Z Z component of position
* \param Width Width of the box (following X)
* \param Height Height of the box (following Y)
* \param Depth Depth of the box (following Z)
*
* \remark Aabb is uninitialized
*/
template<typename T>
BoundingVolume<T>::BoundingVolume(T X, T Y, T Z, T Width, T Height, T Depth)
{
Set(X, Y, Z, Width, Height, Depth);
}
/*!
* \brief Constructs a BoundingVolume<T> object from a box
*
* \param box Box<T> object
*
* \remark Aabb is uninitialized
*/
template<typename T>
BoundingVolume<T>::BoundingVolume(const Box<T>& box)
{
Set(box);
}
/*!
* \brief Constructs a BoundingVolume<T> object from an oriented box
*
* \param orientedBox OrientedBox<T> object
*
* \remark Aabb is uninitialized
*/
template<typename T>
BoundingVolume<T>::BoundingVolume(const OrientedBox<T>& orientedBox)
{
Set(orientedBox);
}
/*!
* \brief Constructs a BoundingVolume<T> object from two vectors representing point of the space
* (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum
*
* \param vec1 First point
* \param vec2 Second point
*
* \remark Aabb is uninitialized
*/
template<typename T>
BoundingVolume<T>::BoundingVolume(const Vector3<T>& vec1, const Vector3<T>& vec2)
{
Set(vec1, vec2);
}
/*!
* \brief Constructs a BoundingVolume<T> object from another type of BoundingVolume
*
* \param volume BoundingVolume of type U to convert to type T
*/
template<typename T>
template<typename U>
BoundingVolume<T>::BoundingVolume(const BoundingVolume<U>& volume)
@ -56,24 +122,46 @@ namespace Nz
Set(volume);
}
/*!
* \brief Checks whether the volume is finite
* \return true if extend is Extend_Finite
*/
template<typename T>
bool BoundingVolume<T>::IsFinite() const
{
return extend == Extend_Finite;
}
/*!
* \brief Checks whether the volume is infinite
* \return true if extend is Extend_Infinite
*/
template<typename T>
bool BoundingVolume<T>::IsInfinite() const
{
return extend == Extend_Infinite;
}
/*!
* \brief Checks whether the volume is null
* \return true if extend is Extend_Null
*/
template<typename T>
bool BoundingVolume<T>::IsNull() const
{
return extend == Extend_Null;
}
/*!
* \brief Makes the bounding volume infinite
* \return A reference to this bounding volume with Extend_Infinite for extend
*
* \see Infinite
*/
template<typename T>
BoundingVolume<T>& BoundingVolume<T>::MakeInfinite()
{
@ -82,6 +170,13 @@ namespace Nz
return *this;
}
/*!
* \brief Makes the bounding volume null
* \return A reference to this bounding volume with Extend_Null for extend
*
* \see Null
*/
template<typename T>
BoundingVolume<T>& BoundingVolume<T>::MakeNull()
{
@ -90,6 +185,15 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the extend of the bounding volume from Extend
* \return A reference to this bounding volume
*
* \param Extend New extend
*
* \remark This method is meant to be called with Extend_Infinite or Extend_Null
*/
template<typename T>
BoundingVolume<T>& BoundingVolume<T>::Set(Extend Extend)
{
@ -98,6 +202,18 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the bounding volume
* \return A reference to this bounding volume
*
* \param X X position
* \param Y Y position
* \param Z Z position
* \param Width Width of the oriented box (following X)
* \param Height Height of the oriented box (following Y)
* \param Depth Depth of the oriented box (following Z)
*/
template<typename T>
BoundingVolume<T>& BoundingVolume<T>::Set(T X, T Y, T Z, T Width, T Height, T Depth)
{
@ -107,15 +223,29 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the bounding volume from another bounding volume
* \return A reference to this bounding volume
*
* \param volume The other bounding volume
*/
template<typename T>
BoundingVolume<T>& BoundingVolume<T>::Set(const BoundingVolume<T>& volume)
{
obb.Set(volume.obb); // Seul l'OBB est importante pour la suite
obb.Set(volume.obb); // Only OBB is important for the moment
extend = volume.extend;
return *this;
}
/*!
* \brief Sets the components of the bounding volume from a box
* \return A reference to this bounding volume
*
* \param box Box<T> object
*/
template<typename T>
BoundingVolume<T>& BoundingVolume<T>::Set(const Box<T>& box)
{
@ -125,6 +255,13 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the bounding volume from an oriented box
* \return A reference to this bounding volume
*
* \param orientedBox OrientedBox<T> object
*/
template<typename T>
BoundingVolume<T>& BoundingVolume<T>::Set(const OrientedBox<T>& orientedBox)
{
@ -134,6 +271,14 @@ namespace Nz
return *this;
}
/*!
* \brief Sets a BoundingVolume<T> object from two vectors representing point of the space
* (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum
*
* \param vec1 First point
* \param vec2 Second point
*/
template<typename T>
BoundingVolume<T>& BoundingVolume<T>::Set(const Vector3<T>& vec1, const Vector3<T>& vec2)
{
@ -143,6 +288,13 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the bounding volume from another type of BoundingVolume
* \return A reference to this bounding volume
*
* \param volume BoundingVolume of type U to convert its components
*/
template<typename T>
template<typename U>
BoundingVolume<T>& BoundingVolume<T>::Set(const BoundingVolume<U>& volume)
@ -153,6 +305,13 @@ namespace Nz
return *this;
}
/*!
* \brief Gives a string representation
* \return A string representation of the object: "BoundingVolume(localBox="")" if finite, or "BoundingVolume(Infinite)" or "BoundingVolume(Null)"
*
* \remark If enumeration is not defined in Extend, a NazaraError is thrown and "BoundingVolume(ERROR)" is returned
*/
template<typename T>
String BoundingVolume<T>::ToString() const
{
@ -173,6 +332,12 @@ namespace Nz
return "BoundingVolume(ERROR)";
}
/*!
* \brief Updates the obb and the aabb of the bounding volume
*
* \param transformMatrix Matrix4 which represents the transformation to apply
*/
template<typename T>
void BoundingVolume<T>::Update(const Matrix4<T>& transformMatrix)
{
@ -183,6 +348,12 @@ namespace Nz
aabb.ExtendTo(obb(i));
}
/*!
* \brief Updates the obb and the aabb of the bounding volume
*
* \param translation Vector3 which represents the translation to apply
*/
template<typename T>
void BoundingVolume<T>::Update(const Vector3<T>& translation)
{
@ -193,6 +364,13 @@ namespace Nz
aabb.ExtendTo(obb(i));
}
/*!
* \brief Multiplies the lengths of the obb with the scalar
* \return A BoundingVolume where the position is the same and width, height and depth are the product of the old width, height and depth and the scalar
*
* \param scale The scalar to multiply width, height and depth with
*/
template<typename T>
BoundingVolume<T> BoundingVolume<T>::operator*(T scalar) const
{
@ -202,6 +380,13 @@ namespace Nz
return volume;
}
/*!
* \brief Multiplies the lengths of this bounding volume with the scalar
* \return A reference to this bounding volume where lengths are the product of these lengths and the scalar
*
* \param scalar The scalar to multiply width, height and depth with
*/
template<typename T>
BoundingVolume<T>& BoundingVolume<T>::operator*=(T scalar)
{
@ -210,6 +395,13 @@ namespace Nz
return *this;
}
/*!
* \brief Compares the bounding volume to other one
* \return true if the two bounding volumes are the same
*
* \param volume Other bounding volume to compare with
*/
template<typename T>
bool BoundingVolume<T>::operator==(const BoundingVolume& volume) const
{
@ -222,12 +414,26 @@ namespace Nz
return false;
}
/*!
* \brief Compares the bounding volume to other one
* \return false if the two bounding volumes are the same
*
* \param volume Other bounding volume to compare with
*/
template<typename T>
bool BoundingVolume<T>::operator!=(const BoundingVolume& volume) const
{
return !operator==(volume);
}
/*!
* \brief Shorthand for the bounding volume (Extend_Infinite)
* \return A bounding volume with Extend_Infinite
*
* \see MakeInfinite
*/
template<typename T>
BoundingVolume<T> BoundingVolume<T>::Infinite()
{
@ -237,6 +443,21 @@ namespace Nz
return volume;
}
/*!
* \brief Interpolates the bounding volume to other one with a factor of interpolation
* \return A new bounding volume box which is the interpolation of two bounding volumes
*
* \param from Initial bounding volume
* \param to Target bounding volume
* \param interpolation Factor of interpolation
*
* \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior
* \remark With NAZARA_DEBUG, a NazaraError is thrown and Null() is returned
* \remark If enumeration is not defined in Extend, a NazaraError is thrown and Null() is returned
*
* \see Lerp
*/
template<typename T>
BoundingVolume<T> BoundingVolume<T>::Lerp(const BoundingVolume& from, const BoundingVolume& to, T interpolation)
{
@ -275,13 +496,13 @@ namespace Nz
return from.obb * interpolation;
}
// Si nous arrivons ici c'est que l'extend est invalide
// If we arrive here, the extend is invalid
NazaraError("Invalid extend type (From) (0x" + String::Number(from.extend, 16) + ')');
return Null();
}
case Extend_Infinite:
return Infinite(); // Un petit peu d'infini est infini quand même ;)
return Infinite(); // A little bit of infinity is already too much ;)
case Extend_Null:
{
@ -297,17 +518,24 @@ namespace Nz
return Null();
}
// Si nous arrivons ici c'est que l'extend est invalide
// If we arrive here, the extend is invalid
NazaraError("Invalid extend type (From) (0x" + String::Number(from.extend, 16) + ')');
return Null();
}
}
// Si nous arrivons ici c'est que l'extend est invalide
// If we arrive here, the extend is invalid
NazaraError("Invalid extend type (To) (0x" + String::Number(to.extend, 16) + ')');
return Null();
}
/*!
* \brief Shorthand for the bounding volume (Extend_Null)
* \return A bounding volume with Extend_Null
*
* \see MakeNull
*/
template<typename T>
BoundingVolume<T> BoundingVolume<T>::Null()
{
@ -316,13 +544,21 @@ namespace Nz
return volume;
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const BoundingVolume<T>& volume)
{
out << volume.ToString();
return out;
}
/*!
* \brief Output operator
* \return The stream
*
* \param out The stream
* \param volume The bounding volume to output
*/
template<typename T>
std::ostream& operator<<(std::ostream& out, const Nz::BoundingVolume<T>& volume)
{
out << volume.ToString();
return out;
}
#undef F

View File

@ -40,8 +40,8 @@ namespace Nz
Box& ExtendTo(const Vector3<T>& point);
Sphere<T> GetBoundingSphere() const;
Vector3<T> GetCorner(BoxCorner corner) const;
Vector3<T> GetCenter() const;
Vector3<T> GetCorner(BoxCorner corner) const;
Vector3<T> GetLengths() const;
Vector3<T> GetMaximum() const;
Vector3<T> GetMinimum() const;

View File

@ -12,41 +12,103 @@
namespace Nz
{
/*!
* \class Nz::Box<T>
* \brief Math class that represents a three dimensional box
*/
/*!
* \brief Constructs a Box<T> object from its width, height and depth
*
* \param Width Width of the box (following X)
* \param Height Height of the box (following Y)
* \param Depth Depth of the box (following Z)
*
* \remark Position will be (0, 0, 0)
*/
template<typename T>
Box<T>::Box(T Width, T Height, T Depth)
{
Set(Width, Height, Depth);
}
/*!
* \brief Constructs a Rect<T> object from its position, width, height and depth
*
* \param X X position
* \param Y Y position
* \param Z Z position
* \param Width Width of the box (following X)
* \param Height Height of the box (following Y)
* \param Depth Depth of the box (following Z)
*/
template<typename T>
Box<T>::Box(T X, T Y, T Z, T Width, T Height, T Depth)
{
Set(X, Y, Z, Width, Height, Depth);
}
/*!
* \brief Constructs a Box<T> object from an array of six elements
*
* \param vec[6] vec[0] is X position, vec[1] is Y position, vec[2] is Z position, vec[3] is width, vec[4] is height and vec[5] is depth
*/
template<typename T>
Box<T>::Box(const T vec[6])
{
Set(vec);
}
/*!
* \brief Constructs a Box<T> object from a Rect
*
* \param rect Rectangle which describes (X, Y) position and (width, height) lenghts
*
* \remark Z position is 0 and depth is 1
*/
template<typename T>
Box<T>::Box(const Rect<T>& rect)
{
Set(rect);
}
/*!
* \brief Constructs a Box<T> object from a vector representing width, height and depth
*
* \param lengths (Width, Height, Depth) of the box
*
* \remark Positions will be (0, 0, 0)
*/
template<typename T>
Box<T>::Box(const Vector3<T>& lengths)
{
Set(lengths);
}
/*!
* \brief Constructs a Box<T> object from two vectors representing point of the space
* (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum
*
* \param vec1 First point
* \param vec2 Second point
*/
template<typename T>
Box<T>::Box(const Vector3<T>& vec1, const Vector3<T>& vec2)
{
Set(vec1, vec2);
}
template<typename T>
Box<T>::Box(const T vec[6])
{
Set(vec);
}
/*!
* \brief Constructs a Box<T> object from another type of Box
*
* \param box Box of type U to convert to type T
*/
template<typename T>
template<typename U>
@ -55,27 +117,67 @@ namespace Nz
Set(box);
}
/*!
* \brief Tests whether the box contains the provided point inclusive of the edge of the box
* \return true if inclusive
*
* \param X X position of the point
* \param Y Y position of the point
* \param Z Z position of the point
*
* \see Contains
*/
template<typename T>
bool Box<T>::Contains(T X, T Y, T Z) const
{
return X >= x && X <= x+width &&
Y >= y && Y <= y+height &&
Z >= z && Z <= z+depth;
return X >= x && X <= x + width &&
Y >= y && Y <= y + height &&
Z >= z && Z <= z + depth;
}
/*!
* \brief Tests whether the box contains the provided box inclusive of the edge of the box
* \return true if inclusive
*
* \param box Other box to test
*
* \see Contains
*/
template<typename T>
bool Box<T>::Contains(const Box<T>& box) const
{
return Contains(box.x, box.y, box.z) &&
Contains(box.x + box.width, box.y + box.height, box.z + box.depth);
Contains(box.x + box.width, box.y + box.height, box.z + box.depth);
}
/*!
* \brief Tests whether the box contains the provided point inclusive of the edge of the box
* \return true if inclusive
*
* \param point Position of the point
*
* \see Contains
*/
template<typename T>
bool Box<T>::Contains(const Vector3<T>& point) const
{
return Contains(point.x, point.y, point.z);
}
/*!
* \brief Extends the box to contain the point in the boundary
* \return A reference to this box extended
*
* \param X X position of the point
* \param Y Y position of the point
* \param Z Z position of the point
*
* \see ExtendTo
*/
template<typename T>
Box<T>& Box<T>::ExtendTo(T X, T Y, T Z)
{
@ -94,6 +196,15 @@ namespace Nz
return *this;
}
/*!
* \brief Extends the box to contain the box
* \return A reference to this box extended
*
* \param box Other box to contain
*
* \see ExtendTo
*/
template<typename T>
Box<T>& Box<T>::ExtendTo(const Box& box)
{
@ -112,12 +223,54 @@ namespace Nz
return *this;
}
/*!
* \brief Extends the box to contain the point in the boundary
* \return A reference to this box extended
*
* \param point Position of the point
*
* \see ExtendTo
*/
template<typename T>
Box<T>& Box<T>::ExtendTo(const Vector3<T>& point)
{
return ExtendTo(point.x, point.y, point.z);
}
/*!
* \brief Gets the bounding sphere for the box
* \return A sphere containing the box
*
* \see GetSquaredBoundingSphere
*/
template<typename T>
Sphere<T> Box<T>::GetBoundingSphere() const
{
return Sphere<T>(GetCenter(), GetRadius());
}
/*!
* \brief Gets a Vector3 for the center
* \return The position of the center of the box
*/
template<typename T>
Vector3<T> Box<T>::GetCenter() const
{
return GetPosition() + GetLengths() / F(2.0);
}
/*!
* \brief Gets the Vector3 for the corner
* \return The position of the corner of the box according to enum BoxCorner
*
* \param corner Enumeration of type BoxCorner
*
* \remark If enumeration is not defined in BoxCorner, a NazaraError is thrown and a Vector3 uninitialised is returned
*/
template<typename T>
Vector3<T> Box<T>::GetCorner(BoxCorner corner) const
{
@ -152,17 +305,10 @@ namespace Nz
return Vector3<T>();
}
template<typename T>
Sphere<T> Box<T>::GetBoundingSphere() const
{
return Sphere<T>(GetCenter(), GetRadius());
}
template<typename T>
Vector3<T> Box<T>::GetCenter() const
{
return GetPosition() + GetLengths()/F(2.0);
}
/*!
* \brief Gets a Vector3 for the lengths
* \return The lengths of the box (width, height, depth)
*/
template<typename T>
Vector3<T> Box<T>::GetLengths() const
@ -170,19 +316,41 @@ namespace Nz
return Vector3<T>(width, height, depth);
}
/*!
* \brief Gets a Vector3 for the maximum point
* \return The BoxCorner_NearRightTop of the box
*
* \see GetCorner
*/
template<typename T>
Vector3<T> Box<T>::GetMaximum() const
{
return GetPosition() + GetLengths();
}
/*!
* \brief Gets a Vector3 for the minimum point
* \return The BoxCorner_FarLeftBottom of the box
*
* \see GetCorner, GetPosition
*/
template<typename T>
Vector3<T> Box<T>::GetMinimum() const
{
///DOC: Alias de GetPosition()
return GetPosition();
}
/*!
* \brief Computes the negative vertex of one direction
* \return The position of the vertex on the box in the opposite way of the normal while considering the center. It means that if the normal has one component negative, the component is set to width, height or depth corresponding to the sign
*
* \param normal Vector indicating a direction
*
* \see GetPositiveVertex
*/
template<typename T>
Vector3<T> Box<T>::GetNegativeVertex(const Vector3<T>& normal) const
{
@ -200,12 +368,28 @@ namespace Nz
return neg;
}
/*!
* \brief Gets a Vector3 for the position
* \return The BoxCorner_FarLeftBottom of the box
*
* \see GetCorner, GetMinimum
*/
template<typename T>
Vector3<T> Box<T>::GetPosition() const
{
return Vector3<T>(x, y, z);
}
/*!
* \brief Computes the positive vertex of one direction
* \return The position of the vertex on the box in the same way of the normal while considering the center. It means that if the normal has one component positive, the component is set to width or height corresponding to the sign
*
* \param normal Vector indicating a direction
*
* \see GetNegativeVertex
*/
template<typename T>
Vector3<T> Box<T>::GetPositiveVertex(const Vector3<T>& normal) const
{
@ -223,27 +407,52 @@ namespace Nz
return pos;
}
/*!
* \brief Gets the radius of the box
* \return Value of the radius which is the biggest distance between a corner and the center
*/
template<typename T>
T Box<T>::GetRadius() const
{
return std::sqrt(GetSquaredRadius());
}
/*!
* \brief Gets the squared bounding sphere for the box
* \return A sphere containing the box
*
* \see GetBoundingSphere
*/
template<typename T>
Sphere<T> Box<T>::GetSquaredBoundingSphere() const
{
return Sphere<T>(GetCenter(), GetSquaredRadius());
}
/*!
* \brief Gets the squared radius of the box
* \return Value of the squared radius which is the squared of biggest distance between a corner and the center
*/
template<typename T>
T Box<T>::GetSquaredRadius() const
{
Vector3<T> size(GetLengths());
size /= F(2.0); // La taille étant relative à la position (minimum) de la boite et non pas à son centre
size /= F(2.0); // The size only depends on the lengths and not the center
return size.GetSquaredLength();
}
/*!
* \brief Checks whether or not this box intersects another one
* \return true if the box intersects
*
* \param box Box to check
* \param intersection Optional argument for the box which represent the intersection
*/
template<typename T>
bool Box<T>::Intersect(const Box& box, Box* intersection) const
{
@ -275,12 +484,24 @@ namespace Nz
return true;
}
/*!
* \brief Checks whether this box is valid
* \return true if the box has a strictly positive width, height and depth
*/
template<typename T>
bool Box<T>::IsValid() const
{
return width > F(0.0) && height > F(0.0) && depth > F(0.0);
}
/*!
* \brief Makes the box position (0, 0, 0) and lengths (0, 0, 0)
* \return A reference to this box with position (0, 0, 0) and lengths (0, 0, 0)
*
* \see Zero
*/
template<typename T>
Box<T>& Box<T>::MakeZero()
{
@ -294,6 +515,17 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the box with width, height and depth
* \return A reference to this box
*
* \param Width Width of the box (following X)
* \param Height Height of the box (following Y)
* \param Depth Depth of the box (following Z)
*
* \remark Position will be (0, 0, 0)
*/
template<typename T>
Box<T>& Box<T>::Set(T Width, T Height, T Depth)
{
@ -307,6 +539,17 @@ namespace Nz
return *this;
}
/*!
* \brief Constructs a Box<T> object from its position and sizes
*
* \param X X component of position
* \param Y Y component of position
* \param Z Z component of position
* \param Width Width of the box (following X)
* \param Height Height of the box (following Y)
* \param Depth Depth of the box (following Z)
*/
template<typename T>
Box<T>& Box<T>::Set(T X, T Y, T Z, T Width, T Height, T Depth)
{
@ -320,6 +563,13 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the box from an array of six elements
* \return A reference to this box
*
* \param box[6] box[0] is X position, box[1] is Y position, box[2] is Z position, box[3] is width, box[4] is height and box[5] is depth
*/
template<typename T>
Box<T>& Box<T>::Set(const T box[6])
{
@ -333,6 +583,13 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the box with components from another
* \return A reference to this box
*
* \param box The other box
*/
template<typename T>
Box<T>& Box<T>::Set(const Box& box)
{
@ -341,6 +598,15 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the box with components from a Rect
* \return A reference to this box
*
* \param rect Rectangle which describes (X, Y) position and (width, height) lenghts
*
* \remark Z position is 0 and depth is 1
*/
template<typename T>
Box<T>& Box<T>::Set(const Rect<T>& rect)
{
@ -354,25 +620,50 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the components of the box from a vector representing width, height and depth
* \return A reference to this box
*
* \param lengths (Width, Height, depth) of the box
*
* \remark Position will be (0, 0, 0)
*/
template<typename T>
Box<T>& Box<T>::Set(const Vector3<T>& lengths)
{
return Set(lengths.x, lengths.y, lengths.z);
}
/*!
* \brief Sets the components of the box from two vectors representing point of the space
* (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum
* \return A reference to this box
*
* \param vec1 First point
* \param vec2 Second point
*/
template<typename T>
Box<T>& Box<T>::Set(const Vector3<T>& vec1, const Vector3<T>& vec2)
{
x = std::min(vec1.x, vec2.x);
y = std::min(vec1.y, vec2.y);
z = std::min(vec1.z, vec2.z);
width = (vec2.x > vec1.x) ? vec2.x-vec1.x : vec1.x-vec2.x;
height = (vec2.y > vec1.y) ? vec2.y-vec1.y : vec1.y-vec2.y;
depth = (vec2.z > vec1.z) ? vec2.z-vec1.z : vec1.z-vec2.z;
width = (vec2.x > vec1.x) ? vec2.x - vec1.x : vec1.x - vec2.x;
height = (vec2.y > vec1.y) ? vec2.y - vec1.y : vec1.y - vec2.y;
depth = (vec2.z > vec1.z) ? vec2.z - vec1.z : vec1.z - vec2.z;
return *this;
}
/*!
* \brief Sets the components of the box from another type of Box
* \return A reference to this box
*
* \param box Box of type U to convert its components
*/
template<typename T>
template<typename U>
Box<T>& Box<T>::Set(const Box<U>& box)
@ -387,6 +678,11 @@ namespace Nz
return *this;
}
/*!
* \brief Gives a string representation
* \return A string representation of the object: "Box(x, y, z, width, height, depth)"
*/
template<typename T>
String Box<T>::ToString() const
{
@ -395,19 +691,34 @@ namespace Nz
return ss << "Box(" << x << ", " << y << ", " << z << ", " << width << ", " << height << ", " << depth << ')';
}
/*!
* \brief Transforms the box according to the matrix
* \return A reference to this box transformed
*
* \param matrix Matrix4 representing the transformation
* \param applyTranslation Should transform the position or the direction
*/
template<typename T>
Box<T>& Box<T>::Transform(const Matrix4<T>& matrix, bool applyTranslation)
{
Vector3<T> center = matrix.Transform(GetCenter(), (applyTranslation) ? F(1.0) : F(0.0)); // Valeur multipliant la translation
Vector3<T> halfSize = GetLengths()/F(2.0);
Vector3<T> center = matrix.Transform(GetCenter(), (applyTranslation) ? F(1.0) : F(0.0)); // Value multiplying the translation
Vector3<T> halfSize = GetLengths() / F(2.0);
halfSize.Set(std::abs(matrix(0,0))*halfSize.x + std::abs(matrix(1,0))*halfSize.y + std::abs(matrix(2,0))*halfSize.z,
std::abs(matrix(0,1))*halfSize.x + std::abs(matrix(1,1))*halfSize.y + std::abs(matrix(2,1))*halfSize.z,
std::abs(matrix(0,2))*halfSize.x + std::abs(matrix(1,2))*halfSize.y + std::abs(matrix(2,2))*halfSize.z);
halfSize.Set(std::abs(matrix(0,0)) * halfSize.x + std::abs(matrix(1,0)) * halfSize.y + std::abs(matrix(2,0)) * halfSize.z,
std::abs(matrix(0,1)) * halfSize.x + std::abs(matrix(1,1)) * halfSize.y + std::abs(matrix(2,1)) * halfSize.z,
std::abs(matrix(0,2)) * halfSize.x + std::abs(matrix(1,2)) * halfSize.y + std::abs(matrix(2,2)) * halfSize.z);
return Set(center - halfSize, center + halfSize);
}
/*!
* \brief Translates the box
* \return A reference to this box translated
*
* \param translation Vector3 which is the translation for the position
*/
template<typename T>
Box<T>& Box<T>::Translate(const Vector3<T>& translation)
{
@ -418,6 +729,15 @@ namespace Nz
return *this;
}
/*!
* \brief Returns the ith element of the box
* \return A reference to the ith element of the box
*
* \remark Access to index greather than 6 is undefined behavior
* \remark Produce a NazaraError if you try to acces to index greather than 6 with NAZARA_MATH_SAFE defined
* \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of you try to acces to index greather than 6
*/
template<typename T>
T& Box<T>::operator[](unsigned int i)
{
@ -435,6 +755,15 @@ namespace Nz
return *(&x+i);
}
/*!
* \brief Returns the ith element of the box
* \return A value to the ith element of the box
*
* \remark Access to index greather than 6 is undefined behavior
* \remark Produce a NazaraError if you try to acces to index greather than 6 with NAZARA_MATH_SAFE defined
* \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of you try to acces to index greather than 6
*/
template<typename T>
T Box<T>::operator[](unsigned int i) const
{
@ -452,18 +781,39 @@ namespace Nz
return *(&x+i);
}
/*!
* \brief Multiplies the lengths with the scalar
* \return A box where the position is the same and width, height and depth are the product of the old width, height and depth and the scalar
*
* \param scale The scalar to multiply width, height and depth with
*/
template<typename T>
Box<T> Box<T>::operator*(T scalar) const
{
return Box(x, y, z, width*scalar, height*scalar, depth*scalar);
return Box(x, y, z, width * scalar, height * scalar, depth * scalar);
}
/*!
* \brief Multiplies the lengths with the vector
* \return A box where the position is the same and width, height and depth are the product of the old width, height and depth with the vec
*
* \param vec The vector where component one multiply width, two height and three depth
*/
template<typename T>
Box<T> Box<T>::operator*(const Vector3<T>& vec) const
{
return Box(x, y, z, width*vec.x, height*vec.y, depth*vec.z);
return Box(x, y, z, width * vec.x, height * vec.y, depth * vec.z);
}
/*!
* \brief Multiplies the lengths of this box with the scalar
* \return A reference to this box where lengths are the product of these lengths and the scalar
*
* \param scalar The scalar to multiply width, height and depth with
*/
template<typename T>
Box<T>& Box<T>::operator*=(T scalar)
{
@ -474,6 +824,13 @@ namespace Nz
return *this;
}
/*!
* \brief Multiplies the lengths of this box with the vector
* \return A reference to this box where width, height and depth are the product of the old width, height and depth with the vec
*
* \param vec The vector where component one multiply width, two height and three depth
*/
template<typename T>
Box<T>& Box<T>::operator*=(const Vector3<T>& vec)
{
@ -484,19 +841,47 @@ namespace Nz
return *this;
}
/*!
* \brief Compares the box to other one
* \return true if the boxes are the same
*
* \param box Other box to compare with
*/
template<typename T>
bool Box<T>::operator==(const Box& box) const
{
return NumberEquals(x, box.x) && NumberEquals(y, box.y) && NumberEquals(z, box.z) &&
NumberEquals(width, box.width) && NumberEquals(height, box.height) && NumberEquals(depth, box.depth);
NumberEquals(width, box.width) && NumberEquals(height, box.height) && NumberEquals(depth, box.depth);
}
/*!
* \brief Compares the box to other one
* \return false if the boxes are the same
*
* \param box Other box to compare with
*/
template<typename T>
bool Box<T>::operator!=(const Box& box) const
{
return !operator==(box);
}
/*!
* \brief Interpolates the box to other one with a factor of interpolation
* \return A new box which is the interpolation of two rectangles
*
* \param from Initial box
* \param to Target box
* \param interpolation Factor of interpolation
*
* \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior
* \remark With NAZARA_DEBUG, a NazaraError is thrown and Zero() is returned
*
* \see Lerp
*/
template<typename T>
Box<T> Box<T>::Lerp(const Box& from, const Box& to, T interpolation)
{
@ -519,6 +904,13 @@ namespace Nz
return box;
}
/*!
* \brief Shorthand for the box (0, 0, 0, 0, 0, 0)
* \return A box with position (0, 0, 0) and lengths (0, 0, 0)
*
* \see MakeZero
*/
template<typename T>
Box<T> Box<T>::Zero()
{
@ -529,6 +921,14 @@ namespace Nz
}
}
/*!
* \brief Output operator
* \return The stream
*
* \param out The stream
* \param box The box to output
*/
template<typename T>
std::ostream& operator<<(std::ostream& out, const Nz::Box<T>& box)
{