Merge pull request #51 from Gawaboumga/Documentation-Update
Documentation update Former-commit-id: f0921d7927aeb09f19523757ad2ef071140cd5b3
This commit is contained in:
commit
0a9e6fcda3
|
|
@ -20,6 +20,6 @@ namespace Ndk
|
|||
template<typename SystemType, typename S> bool IsSystem(S& system);
|
||||
}
|
||||
|
||||
#include <Ndk/Algorithm.inl>
|
||||
#include <NDK/Algorithm.inl>
|
||||
|
||||
#endif // NDK_ALGORITHM_HPP
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// This file is part of the "Nazara Development Kit"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
|
||||
|
||||
#include <Ndk/Algorithm.hpp>
|
||||
#include <NDK/Algorithm.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Ndk
|
||||
|
|
|
|||
|
|
@ -33,20 +33,20 @@ namespace Ndk
|
|||
inline void EnsureViewMatrixUpdate() const;
|
||||
inline void EnsureViewportUpdate() const;
|
||||
|
||||
inline float GetAspectRatio() const;
|
||||
inline Nz::Vector3f GetEyePosition() const;
|
||||
inline Nz::Vector3f GetForward() const;
|
||||
inline float GetAspectRatio() const override;
|
||||
inline Nz::Vector3f GetEyePosition() const override;
|
||||
inline Nz::Vector3f GetForward() const override;
|
||||
inline float GetFOV() const;
|
||||
inline const Nz::Frustumf& GetFrustum() const;
|
||||
inline const Nz::Frustumf& GetFrustum() const override;
|
||||
inline unsigned int GetLayer() const;
|
||||
inline const Nz::Matrix4f& GetProjectionMatrix() const;
|
||||
inline const Nz::Matrix4f& GetProjectionMatrix() const override;
|
||||
inline Nz::ProjectionType GetProjectionType() const;
|
||||
inline const Nz::RenderTarget* GetTarget() const;
|
||||
inline const Nz::RenderTarget* GetTarget() const override;
|
||||
inline const Nz::Rectf& GetTargetRegion() const;
|
||||
inline const Nz::Matrix4f& GetViewMatrix() const;
|
||||
inline const Nz::Recti& GetViewport() const;
|
||||
inline float GetZFar() const;
|
||||
inline float GetZNear() const;
|
||||
inline const Nz::Matrix4f& GetViewMatrix() const override;
|
||||
inline const Nz::Recti& GetViewport() const override;
|
||||
inline float GetZFar() const override;
|
||||
inline float GetZNear() const override;
|
||||
|
||||
inline void SetFOV(float fov);
|
||||
inline void SetLayer(unsigned int layer);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// This file is part of the "Nazara Development Kit"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
|
||||
|
||||
#include <Ndk/Algorithm.hpp>
|
||||
#include <NDK/Algorithm.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Ndk
|
||||
|
|
|
|||
|
|
@ -13,12 +13,13 @@
|
|||
#include <Nazara/Core/Thread.hpp> // Thread::Sleep
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <Nazara/Utility/Keyboard.hpp>
|
||||
#include <Nazara/Utility/Utility.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
// NzKeyboard ne nécessite pas l'initialisation du module Utilitaire
|
||||
Nz::Initializer<Nz::Audio> audio;
|
||||
// NzKeyboard nécessite l'initialisation du module Utilitaire
|
||||
Nz::Initializer<Nz::Audio, Nz::Utility> audio;
|
||||
if (!audio)
|
||||
{
|
||||
std::cout << "Failed to initialize audio module" << std::endl;
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ namespace Nz
|
|||
void Begin() override;
|
||||
ByteArray End() override;
|
||||
|
||||
std::size_t GetDigestLength() const;
|
||||
const char* GetHashName() const;
|
||||
std::size_t GetDigestLength() const override;
|
||||
const char* GetHashName() const override;
|
||||
|
||||
private:
|
||||
HashWhirlpool_state* m_state;
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ namespace Nz
|
|||
void AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override;
|
||||
void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override;
|
||||
|
||||
void Clear(bool fully = false);
|
||||
void Clear(bool fully = false) override;
|
||||
|
||||
struct MeshDataComparator
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace Nz
|
|||
void AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override;
|
||||
void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override;
|
||||
|
||||
void Clear(bool fully = false);
|
||||
void Clear(bool fully = false) override;
|
||||
|
||||
void Sort(const AbstractViewer* viewer);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Nz
|
|||
GuillotineTextureAtlas() = default;
|
||||
~GuillotineTextureAtlas() = default;
|
||||
|
||||
UInt32 GetStorage() const;
|
||||
UInt32 GetStorage() const override;
|
||||
|
||||
private:
|
||||
AbstractImage* ResizeImage(AbstractImage* oldImage, const Vector2ui& size) const override;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace Nz
|
|||
void AddController(ParticleControllerRef controller);
|
||||
void AddEmitter(ParticleEmitter* emitter);
|
||||
void AddGenerator(ParticleGeneratorRef generator);
|
||||
void AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const;
|
||||
void AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const override;
|
||||
|
||||
void ApplyControllers(ParticleMapper& mapper, unsigned int particleCount, float elapsedTime);
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ namespace Nz
|
|||
|
||||
bool HasAnimation() const;
|
||||
|
||||
bool IsAnimated() const;
|
||||
bool IsAnimated() const override;
|
||||
bool IsAnimationEnabled() const;
|
||||
|
||||
bool LoadFromFile(const String& filePath, const SkeletalModelParameters& params = SkeletalModelParameters());
|
||||
|
|
|
|||
|
|
@ -30,32 +30,32 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
template<typename T> T Approach(T value, T objective, T increment);
|
||||
template<typename T> constexpr T Approach(T value, T objective, T increment);
|
||||
template<typename T> constexpr T Clamp(T value, T min, T max);
|
||||
template<typename T> T CountBits(T value);
|
||||
template<typename T> constexpr T CountBits(T value);
|
||||
template<typename T> constexpr T FromDegrees(T degrees);
|
||||
template<typename T> constexpr T FromRadians(T radians);
|
||||
template<typename T> constexpr T DegreeToRadian(T degrees);
|
||||
template<typename T> T GetNearestPowerOfTwo(T number);
|
||||
unsigned int GetNumberLength(signed char number);
|
||||
unsigned int GetNumberLength(unsigned char number);
|
||||
template<typename T> constexpr T GetNearestPowerOfTwo(T number);
|
||||
constexpr unsigned int GetNumberLength(signed char number);
|
||||
constexpr unsigned int GetNumberLength(unsigned char number);
|
||||
unsigned int GetNumberLength(int number);
|
||||
unsigned int GetNumberLength(unsigned int number);
|
||||
constexpr unsigned int GetNumberLength(unsigned int number);
|
||||
unsigned int GetNumberLength(long long number);
|
||||
unsigned int GetNumberLength(unsigned long long number);
|
||||
constexpr unsigned int GetNumberLength(unsigned long long number);
|
||||
unsigned int GetNumberLength(float number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS);
|
||||
unsigned int GetNumberLength(double number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS);
|
||||
unsigned int GetNumberLength(long double number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS);
|
||||
template<typename T> unsigned int IntegralLog2(T number);
|
||||
template<typename T> unsigned int IntegralLog2Pot(T pot);
|
||||
unsigned int IntegralPow(unsigned int base, unsigned int exponent);
|
||||
template<typename T, typename T2> T Lerp(T from, T to, T2 interpolation);
|
||||
template<typename T> T MultiplyAdd(T x, T y, T z);
|
||||
template<typename T> T NormalizeAngle(T angle);
|
||||
template<typename T> bool NumberEquals(T a, T b);
|
||||
template<typename T> bool NumberEquals(T a, T b, T maxDifference);
|
||||
template<typename T> constexpr unsigned int IntegralLog2(T number);
|
||||
template<typename T> constexpr unsigned int IntegralLog2Pot(T pot);
|
||||
constexpr unsigned int IntegralPow(unsigned int base, unsigned int exponent);
|
||||
template<typename T, typename T2> constexpr T Lerp(const T& from, const T& to, const T2& interpolation);
|
||||
template<typename T> constexpr T MultiplyAdd(T x, T y, T z);
|
||||
template<typename T> constexpr T NormalizeAngle(T angle);
|
||||
template<typename T> constexpr bool NumberEquals(T a, T b);
|
||||
template<typename T> constexpr bool NumberEquals(T a, T b, T maxDifference);
|
||||
String NumberToString(long long number, UInt8 radix = 10);
|
||||
template<typename T> T RadianToDegree(T radians);
|
||||
template<typename T> constexpr T RadianToDegree(T radians);
|
||||
long long StringToNumber(String str, UInt8 radix = 10, bool* ok = nullptr);
|
||||
template<typename T> constexpr T ToDegrees(T angle);
|
||||
template<typename T> constexpr T ToRadians(T angle);
|
||||
|
|
|
|||
|
|
@ -98,10 +98,18 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Approaches the objective, beginning with value and with increment
|
||||
* \return The nearest value of the objective you can get with the value and the increment for one step
|
||||
*
|
||||
* \param value Initial value
|
||||
* \param objective Target value
|
||||
* \parma increment One step value
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Approach(T value, T objective, T increment)
|
||||
constexpr T Approach(T value, T objective, T increment)
|
||||
{
|
||||
///TODO: Marquer comme constexpr en C++14
|
||||
if (value < objective)
|
||||
return std::min(value + increment, objective);
|
||||
else if (value > objective)
|
||||
|
|
@ -110,14 +118,30 @@ namespace Nz
|
|||
return value;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Clamps value between min and max and returns the expected value
|
||||
* \return If value is not in the interval of min..max, value obtained is the nearest limit of this interval
|
||||
*
|
||||
* \param value Value to clamp
|
||||
* \param min Minimum of the interval
|
||||
* \param max Maximum of the interval
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
constexpr T Clamp(T value, T min, T max)
|
||||
{
|
||||
return std::max(std::min(value, max), min);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets number of bits set in the number
|
||||
* \return The number of bits set to 1
|
||||
*
|
||||
* \param value The value to count bits
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T CountBits(T value)
|
||||
constexpr T CountBits(T value)
|
||||
{
|
||||
// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
|
||||
unsigned int count = 0;
|
||||
|
|
@ -130,12 +154,26 @@ namespace Nz
|
|||
return count;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts degree to radian
|
||||
* \return The representation in radian of the angle in degree (0..2*pi)
|
||||
*
|
||||
* \param degrees Angle in degree (this is expected between 0..360)
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
constexpr T DegreeToRadian(T degrees)
|
||||
{
|
||||
return degrees * T(M_PI/180.0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the unit from degree and convert it according to NAZARA_MATH_ANGLE_RADIAN
|
||||
* \return Express the degrees
|
||||
*
|
||||
* \param degrees Convert degree to NAZARA_MATH_ANGLE_RADIAN unit
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
constexpr T FromDegrees(T degrees)
|
||||
{
|
||||
|
|
@ -146,6 +184,13 @@ namespace Nz
|
|||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the unit from radian and convert it according to NAZARA_MATH_ANGLE_RADIAN
|
||||
* \return Express the radians
|
||||
*
|
||||
* \param radians Convert radian to NAZARA_MATH_ANGLE_RADIAN unit
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
constexpr T FromRadians(T radians)
|
||||
{
|
||||
|
|
@ -156,22 +201,33 @@ namespace Nz
|
|||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the nearest power of two for the number
|
||||
* \return First power of two containing the number
|
||||
*
|
||||
* \param number Number to get nearest power
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T GetNearestPowerOfTwo(T number)
|
||||
constexpr T GetNearestPowerOfTwo(T number)
|
||||
{
|
||||
///TODO: Marquer comme constexpr en C++14
|
||||
T x = 1;
|
||||
// Tant que x est plus petit que n, on décale ses bits vers la gauche, ce qui revient à multiplier par deux
|
||||
while (x < number)
|
||||
x <<= 1;
|
||||
x <<= 1; // We multiply by 2
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
inline unsigned int GetNumberLength(signed char number)
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
*/
|
||||
|
||||
constexpr unsigned int GetNumberLength(signed char number)
|
||||
{
|
||||
///TODO: Marquer comme constexpr en C++14
|
||||
// Le standard définit le char comme étant codé sur un octet
|
||||
// Char is expected to be 1 byte
|
||||
static_assert(sizeof(number) == 1, "Signed char must be one byte-sized");
|
||||
|
||||
if (number >= 100)
|
||||
|
|
@ -188,10 +244,16 @@ namespace Nz
|
|||
return 4;
|
||||
}
|
||||
|
||||
inline unsigned int GetNumberLength(unsigned char number)
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
*/
|
||||
|
||||
constexpr unsigned int GetNumberLength(unsigned char number)
|
||||
{
|
||||
///TODO: Marquer comme constexpr en C++14
|
||||
// Le standard définit le char comme étant codé sur un octet
|
||||
// Char is expected to be 1 byte
|
||||
static_assert(sizeof(number) == 1, "Unsigned char must be one byte-sized");
|
||||
|
||||
if (number >= 100)
|
||||
|
|
@ -202,6 +264,13 @@ namespace Nz
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
*/
|
||||
|
||||
inline unsigned int GetNumberLength(int number)
|
||||
{
|
||||
if (number == 0)
|
||||
|
|
@ -210,7 +279,14 @@ namespace Nz
|
|||
return static_cast<unsigned int>(std::log10(std::abs(number))) + (number < 0 ? 2 : 1);
|
||||
}
|
||||
|
||||
inline unsigned int GetNumberLength(unsigned int number)
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
*/
|
||||
|
||||
constexpr unsigned int GetNumberLength(unsigned int number)
|
||||
{
|
||||
if (number == 0)
|
||||
return 1;
|
||||
|
|
@ -218,6 +294,13 @@ namespace Nz
|
|||
return static_cast<unsigned int>(std::log10(number))+1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
*/
|
||||
|
||||
inline unsigned int GetNumberLength(long long number)
|
||||
{
|
||||
if (number == 0)
|
||||
|
|
@ -226,7 +309,14 @@ namespace Nz
|
|||
return static_cast<unsigned int>(std::log10(std::abs(number))) + (number < 0 ? 2 : 1);
|
||||
}
|
||||
|
||||
inline unsigned int GetNumberLength(unsigned long long number)
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
*/
|
||||
|
||||
constexpr unsigned int GetNumberLength(unsigned long long number)
|
||||
{
|
||||
if (number == 0)
|
||||
return 1;
|
||||
|
|
@ -234,40 +324,90 @@ namespace Nz
|
|||
return static_cast<unsigned int>(std::log10(number)) + 1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits + 1 for the dot
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
* \param precision Number of digit after the dot
|
||||
*/
|
||||
|
||||
inline unsigned int GetNumberLength(float number, UInt8 precision)
|
||||
{
|
||||
// L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999)
|
||||
return GetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus un pour le point
|
||||
// The imprecision of floats need a cast (log10(9.99999) = 0.99999)
|
||||
return GetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus one for the dot
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits + 1 for the dot
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
* \param precision Number of digit after the dot
|
||||
*/
|
||||
|
||||
inline unsigned int GetNumberLength(double number, UInt8 precision)
|
||||
{
|
||||
// L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999)
|
||||
return GetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus un pour le point
|
||||
// The imprecision of floats need a cast (log10(9.99999) = 0.99999)
|
||||
return GetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus one for the dot
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits + 1 for the dot
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
* \param precision Number of digit after the dot
|
||||
*/
|
||||
|
||||
inline unsigned int GetNumberLength(long double number, UInt8 precision)
|
||||
{
|
||||
// L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999)
|
||||
return GetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus un pour le point
|
||||
// The imprecision of floats need a cast (log10(9.99999) = 0.99999)
|
||||
return GetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus one for the dot
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the log in base 2 of integral number
|
||||
* \return Log of the number (floor)
|
||||
*
|
||||
* \param number To get log in base 2
|
||||
*
|
||||
* \remark If number is 0, 0 is returned
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
unsigned int IntegralLog2(T number)
|
||||
constexpr unsigned int IntegralLog2(T number)
|
||||
{
|
||||
// Proxy nécessaire pour éviter un problème de surcharge
|
||||
// Proxy needed to avoid an overload problem
|
||||
return Detail::IntegralLog2<T>(number);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the log in base 2 of integral number, only works for power of two !
|
||||
* \return Log of the number
|
||||
*
|
||||
* \param number To get log in base 2
|
||||
*
|
||||
* \remark Only works for power of two
|
||||
* \remark If number is 0, 0 is returned
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
unsigned int IntegralLog2Pot(T pot)
|
||||
constexpr unsigned int IntegralLog2Pot(T pot)
|
||||
{
|
||||
return Detail::IntegralLog2Pot<T>(pot);
|
||||
}
|
||||
|
||||
inline unsigned int IntegralPow(unsigned int base, unsigned int exponent)
|
||||
/*!
|
||||
* \brief Gets the power of integrals
|
||||
* \return base^exponent for integral
|
||||
*
|
||||
* \param base Base of the exponentation
|
||||
* \parma exponent Power for the base
|
||||
*/
|
||||
|
||||
constexpr unsigned int IntegralPow(unsigned int base, unsigned int exponent)
|
||||
{
|
||||
///TODO: Marquer comme constexpr en C++14
|
||||
unsigned int r = 1;
|
||||
for (unsigned int i = 0; i < exponent; ++i)
|
||||
r *= base;
|
||||
|
|
@ -275,8 +415,22 @@ namespace Nz
|
|||
return r;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Interpolates the value to other one with a factor of interpolation
|
||||
* \return A new value which is the interpolation of two values
|
||||
*
|
||||
* \param from Initial value
|
||||
* \param to Target value
|
||||
* \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 NazaraWarning is produced
|
||||
*
|
||||
* \see Lerp
|
||||
*/
|
||||
|
||||
template<typename T, typename T2>
|
||||
T Lerp(T from, T to, T2 interpolation)
|
||||
constexpr T Lerp(const T& from, const T& to, const T2& interpolation)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (interpolation < T2(0.0) || interpolation > T2(1.0))
|
||||
|
|
@ -286,15 +440,26 @@ namespace Nz
|
|||
return from + interpolation * (to - from);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies X and Y, then add Z
|
||||
* \return The result of X * Y + Z
|
||||
*
|
||||
* \param x is X
|
||||
* \param y is Y
|
||||
* \param z is Z
|
||||
*
|
||||
* \remark This function is meant to use a special instruction in CPU
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T MultiplyAdd(T x, T y, T z)
|
||||
constexpr T MultiplyAdd(T x, T y, T z)
|
||||
{
|
||||
return x * y + z;
|
||||
}
|
||||
|
||||
#ifdef FP_FAST_FMAF
|
||||
template<>
|
||||
inline float MultiplyAdd(float x, float y, float z)
|
||||
constexpr float MultiplyAdd(float x, float y, float z)
|
||||
{
|
||||
return std::fmaf(x, y, z);
|
||||
}
|
||||
|
|
@ -302,7 +467,7 @@ namespace Nz
|
|||
|
||||
#ifdef FP_FAST_FMA
|
||||
template<>
|
||||
inline double MultiplyAdd(double x, double y, double z)
|
||||
constexpr double MultiplyAdd(double x, double y, double z)
|
||||
{
|
||||
return std::fma(x, y, z);
|
||||
}
|
||||
|
|
@ -310,14 +475,21 @@ namespace Nz
|
|||
|
||||
#ifdef FP_FAST_FMAL
|
||||
template<>
|
||||
inline long double MultiplyAdd(long double x, long double y, long double z)
|
||||
constexpr long double MultiplyAdd(long double x, long double y, long double z)
|
||||
{
|
||||
return std::fmal(x, y, z);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \brief Normalizes the angle
|
||||
* \return Normalized value between 0..2*(pi if radian or 180 if degrees)
|
||||
*
|
||||
* \param angle Angle to normalize
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T NormalizeAngle(T angle)
|
||||
constexpr T NormalizeAngle(T angle)
|
||||
{
|
||||
#if NAZARA_MATH_ANGLE_RADIAN
|
||||
const T limit = T(M_PI);
|
||||
|
|
@ -333,14 +505,31 @@ namespace Nz
|
|||
return angle - limit;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether two numbers are equal
|
||||
* \return true if they are equal within a certain epsilon
|
||||
*
|
||||
* \param a First value
|
||||
* \param b Second value
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool NumberEquals(T a, T b)
|
||||
constexpr bool NumberEquals(T a, T b)
|
||||
{
|
||||
return NumberEquals(a, b, std::numeric_limits<T>::epsilon());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether two numbers are equal
|
||||
* \return true if they are equal within the max difference
|
||||
*
|
||||
* \param a First value
|
||||
* \param b Second value
|
||||
* \param maxDifference Epsilon of comparison (expected to be positive)
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool NumberEquals(T a, T b, T maxDifference)
|
||||
constexpr bool NumberEquals(T a, T b, T maxDifference)
|
||||
{
|
||||
if (b > a)
|
||||
std::swap(a, b);
|
||||
|
|
@ -349,6 +538,17 @@ namespace Nz
|
|||
return diff <= maxDifference;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts the number to String
|
||||
* \return String representation of the number
|
||||
*
|
||||
* \param number Number to represent
|
||||
* \param radix Base of the number
|
||||
*
|
||||
* \remark radix is meant to be between 2 and 36, other values are potentially undefined behavior
|
||||
* \remark With NAZARA_MATH_SAFE, a NazaraError is produced and String() is returned
|
||||
*/
|
||||
|
||||
inline String NumberToString(long long number, UInt8 radix)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
|
|
@ -389,12 +589,31 @@ namespace Nz
|
|||
return str.Reverse();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts radian to degree
|
||||
* \return The representation in degree of the angle in radian (0..360)
|
||||
*
|
||||
* \param radians Angle in radian (this is expected between 0..2*pi)
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T RadianToDegree(T radians)
|
||||
constexpr T RadianToDegree(T radians)
|
||||
{
|
||||
return radians * T(180.0/M_PI);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts the string to number
|
||||
* \return Number which is represented by the string
|
||||
*
|
||||
* \param str String representation
|
||||
* \param radix Base of the number
|
||||
* \param ok Optional argument to know if convertion is correct
|
||||
*
|
||||
* \remark radix is meant to be between 2 and 36, other values are potentially undefined behavior
|
||||
* \remark With NAZARA_MATH_SAFE, a NazaraError is produced and 0 is returned
|
||||
*/
|
||||
|
||||
inline long long StringToNumber(String str, UInt8 radix, bool* ok)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
|
|
@ -444,6 +663,13 @@ namespace Nz
|
|||
return (negative) ? -static_cast<long long>(total) : total;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the degree from unit and convert it according to NAZARA_MATH_ANGLE_RADIAN
|
||||
* \return Express in degrees
|
||||
*
|
||||
* \param angle Convert degree from NAZARA_MATH_ANGLE_RADIAN unit to degrees
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
constexpr T ToDegrees(T angle)
|
||||
{
|
||||
|
|
@ -454,6 +680,13 @@ namespace Nz
|
|||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the radian from unit and convert it according to NAZARA_MATH_ANGLE_RADIAN
|
||||
* \return Express in radians
|
||||
*
|
||||
* \param angle Convert degree from NAZARA_MATH_ANGLE_RADIAN unit to radians
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
constexpr T ToRadians(T angle)
|
||||
{
|
||||
|
|
@ -461,8 +694,8 @@ namespace Nz
|
|||
return angle;
|
||||
#else
|
||||
return DegreeToRadian(angle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
|
|
|||
|
|
@ -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,14 +544,22 @@ namespace Nz
|
|||
|
||||
return volume;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \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 BoundingVolume<T>& volume)
|
||||
std::ostream& operator<<(std::ostream& out, const Nz::BoundingVolume<T>& volume)
|
||||
{
|
||||
out << volume.ToString();
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
#undef F
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -12,35 +12,49 @@
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Box<T>::Box(const Rect<T>& rect)
|
||||
{
|
||||
Set(rect);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Box<T>::Box(const Vector3<T>& lengths)
|
||||
{
|
||||
Set(lengths);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Box<T>::Box(const Vector3<T>& vec1, const Vector3<T>& vec2)
|
||||
{
|
||||
Set(vec1, vec2);
|
||||
}
|
||||
/*!
|
||||
* \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])
|
||||
|
|
@ -48,6 +62,54 @@ namespace Nz
|
|||
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);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \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>
|
||||
Box<T>::Box(const Box<U>& box)
|
||||
|
|
@ -55,6 +117,17 @@ 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
|
||||
{
|
||||
|
|
@ -63,6 +136,15 @@ namespace Nz
|
|||
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
|
||||
{
|
||||
|
|
@ -70,12 +152,32 @@ namespace Nz
|
|||
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,12 +620,30 @@ 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)
|
||||
{
|
||||
|
|
@ -373,6 +657,13 @@ namespace Nz
|
|||
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,10 +691,18 @@ 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> 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,
|
||||
|
|
@ -408,6 +712,13 @@ namespace Nz
|
|||
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);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \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);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \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,6 +841,13 @@ 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
|
||||
{
|
||||
|
|
@ -491,12 +855,33 @@ namespace Nz
|
|||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,15 +28,15 @@
|
|||
#ifndef NAZARA_CONFIG_MATH_HPP
|
||||
#define NAZARA_CONFIG_MATH_HPP
|
||||
|
||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
||||
/// Each modification of a paramater of the module needs a recompilation of the unit
|
||||
|
||||
// Définit le radian comme l'unité utilisée pour les angles
|
||||
// Define the radian as unit for angles
|
||||
#define NAZARA_MATH_ANGLE_RADIAN 0
|
||||
|
||||
// Optimise automatiquement les opérations entre matrices affines (Demande plusieurs comparaisons pour déterminer si une matrice est affine)
|
||||
// Optimize automatically the operation on affine matrices (Ask several comparisons to determine if the matrix is affine)
|
||||
#define NAZARA_MATH_MATRIX4_CHECK_AFFINE 0
|
||||
|
||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||
// Enable tests of security based on the code (Advised for the developpement)
|
||||
#define NAZARA_MATH_SAFE 1
|
||||
|
||||
#endif // NAZARA_CONFIG_MATH_HPP
|
||||
|
|
|
|||
|
|
@ -28,14 +28,14 @@ namespace Nz
|
|||
|
||||
void MakeZero();
|
||||
|
||||
void Normalize();
|
||||
EulerAngles& Normalize();
|
||||
|
||||
void Set(T P, T Y, T R);
|
||||
void Set(const T angles[3]);
|
||||
void Set(const EulerAngles<T>& angles);
|
||||
//void Set(const Matrix3<T>& mat);
|
||||
void Set(const Quaternion<T>& quat);
|
||||
template<typename U> void Set(const EulerAngles<U>& angles);
|
||||
EulerAngles& Set(T P, T Y, T R);
|
||||
EulerAngles& Set(const T angles[3]);
|
||||
EulerAngles& Set(const EulerAngles<T>& angles);
|
||||
//EulerAngles& Set(const Matrix3<T>& mat);
|
||||
EulerAngles& Set(const Quaternion<T>& quat);
|
||||
template<typename U> EulerAngles& Set(const EulerAngles<U>& angles);
|
||||
|
||||
//Matrix3<T> ToRotationMatrix() const;
|
||||
Quaternion<T> ToQuaternion() const;
|
||||
|
|
|
|||
|
|
@ -14,24 +14,58 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
|
||||
/*!
|
||||
* \class Nz::Vector4<T>
|
||||
* \brief Math class that represents an Euler angle. Those describe a rotation transformation by rotating an object on its various axes in specified amounts per axis, and a specified axis order
|
||||
*
|
||||
* \remark Rotation are "left-handed", it means that you take your left hand, put your thumb finger in the direction you want and you other fingers represent the way of rotating
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a EulerAngles<T> object from its components
|
||||
*
|
||||
* \param P Pitch component = X axis
|
||||
* \param Y Yaw component = Y axis
|
||||
* \param R Roll component = Z axis
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
EulerAngles<T>::EulerAngles(T P, T Y, T R)
|
||||
{
|
||||
Set(P, Y, R);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a EulerAngles<T> object from an array of three elements
|
||||
*
|
||||
* \param angles[3] angles[0] is pitch component, angles[1] is yaw component and angles[2] is roll component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
EulerAngles<T>::EulerAngles(const T angles[3])
|
||||
{
|
||||
Set(angles);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a EulerAngles<T> object from a quaternion
|
||||
*
|
||||
* \param quat Quaternion representing a rotation of space
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
EulerAngles<T>::EulerAngles(const Quaternion<T>& quat)
|
||||
{
|
||||
Set(quat);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a EulerAngles<T> object from another type of EulerAngles
|
||||
*
|
||||
* \param angles EulerAngles of type U to convert to type T
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
EulerAngles<T>::EulerAngles(const EulerAngles<U>& angles)
|
||||
|
|
@ -39,57 +73,125 @@ namespace Nz
|
|||
Set(angles);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the euler angle (0, 0, 0)
|
||||
* \return A reference to this euler angle with components (0, 0, 0)
|
||||
*
|
||||
* \see Zero
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
void EulerAngles<T>::MakeZero()
|
||||
{
|
||||
Set(F(0.0), F(0.0), F(0.0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Normalizes the euler angle
|
||||
* \return A reference to this euler angle with has been normalized
|
||||
*
|
||||
* \remark Normalization depends on NAZARA_MATH_ANGLE_RADIAN, between 0..2*pi
|
||||
*
|
||||
* \see NormalizeAngle
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
void EulerAngles<T>::Normalize()
|
||||
EulerAngles<T>& EulerAngles<T>::Normalize()
|
||||
{
|
||||
pitch = NormalizeAngle(pitch);
|
||||
yaw = NormalizeAngle(yaw);
|
||||
roll = NormalizeAngle(roll);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the euler angle
|
||||
* \return A reference to this euler angle
|
||||
*
|
||||
* \param P Pitch component = X axis
|
||||
* \param Y Yaw component = Y axis
|
||||
* \param R Roll component = Z axis
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
void EulerAngles<T>::Set(T P, T Y, T R)
|
||||
EulerAngles<T>& EulerAngles<T>::Set(T P, T Y, T R)
|
||||
{
|
||||
pitch = P;
|
||||
yaw = Y;
|
||||
roll = R;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the euler angle from an array of three elements
|
||||
* \return A reference to this euler angle
|
||||
*
|
||||
* \param angles[3] angles[0] is pitch component, angles[1] is yaw component and angles[2] is roll component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
void EulerAngles<T>::Set(const T angles[3])
|
||||
EulerAngles<T>& EulerAngles<T>::Set(const T angles[3])
|
||||
{
|
||||
pitch = angles[0];
|
||||
yaw = angles[1];
|
||||
roll = angles[2];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the euler angle from another euler angle
|
||||
* \return A reference to this euler angle
|
||||
*
|
||||
* \param angles The other euler angle
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
void EulerAngles<T>::Set(const EulerAngles& angles)
|
||||
EulerAngles<T>& EulerAngles<T>::Set(const EulerAngles& angles)
|
||||
{
|
||||
std::memcpy(this, &angles, sizeof(EulerAngles));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the euler angle from a quaternion
|
||||
* \return A reference to this euler angle
|
||||
*
|
||||
* \param quat Quaternion representing a rotation of space
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
void EulerAngles<T>::Set(const Quaternion<T>& quat)
|
||||
EulerAngles<T>& EulerAngles<T>::Set(const Quaternion<T>& quat)
|
||||
{
|
||||
Set(quat.ToEulerAngles());
|
||||
return Set(quat.ToEulerAngles());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the euler angle from another type of EulerAngles
|
||||
* \return A reference to this euler angle
|
||||
*
|
||||
* \param angles EulerAngles of type U to convert its components
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
void EulerAngles<T>::Set(const EulerAngles<U>& angles)
|
||||
EulerAngles<T>& EulerAngles<T>::Set(const EulerAngles<U>& angles)
|
||||
{
|
||||
pitch = F(angles.pitch);
|
||||
yaw = F(angles.yaw);
|
||||
roll = F(angles.roll);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts the euler angle to quaternion
|
||||
* \return A Quaternion which represents the rotation of this euler angle
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> EulerAngles<T>::ToQuaternion() const
|
||||
{
|
||||
|
|
@ -107,6 +209,11 @@ namespace Nz
|
|||
c1 * s2 * c3 - s1 * c2 * s3);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gives a string representation
|
||||
* \return A string representation of the object: "EulerAngles(pitch, yaw, roll)"
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
String EulerAngles<T>::ToString() const
|
||||
{
|
||||
|
|
@ -115,6 +222,13 @@ namespace Nz
|
|||
return ss << "EulerAngles(" << pitch << ", " << yaw << ", " << roll << ')';
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds the components of the euler angle with other euler angle
|
||||
* \return A euler angle where components are the sum of this euler angle and the other one
|
||||
*
|
||||
* \param angles The other euler angle to add components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
EulerAngles<T> EulerAngles<T>::operator+(const EulerAngles& angles) const
|
||||
{
|
||||
|
|
@ -123,6 +237,13 @@ namespace Nz
|
|||
roll + angles.roll);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Substracts the components of the euler angle with other euler angle
|
||||
* \return A euler angle where components are the difference of this euler angle and the other one
|
||||
*
|
||||
* \param angles The other euler angle to substract components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
EulerAngles<T> EulerAngles<T>::operator-(const EulerAngles& angles) const
|
||||
{
|
||||
|
|
@ -131,6 +252,13 @@ namespace Nz
|
|||
roll - angles.roll);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds the components of other euler angle to this euler angle
|
||||
* \return A reference to this euler angle where components are the sum of this euler angle and the other one
|
||||
*
|
||||
* \param angles The other euler angle to add components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
EulerAngles<T>& EulerAngles<T>::operator+=(const EulerAngles& angles)
|
||||
{
|
||||
|
|
@ -141,6 +269,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Substracts the components of other euler angle to this euler angle
|
||||
* \return A reference to this euler angle where components are the difference of this euler angle and the other one
|
||||
*
|
||||
* \param angle The other euler angle to substract components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
EulerAngles<T>& EulerAngles<T>::operator-=(const EulerAngles& angles)
|
||||
{
|
||||
|
|
@ -151,6 +286,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the euler angle to other one
|
||||
* \return true if the euler angles are the same
|
||||
*
|
||||
* \param angles Other euler angle to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool EulerAngles<T>::operator==(const EulerAngles& angles) const
|
||||
{
|
||||
|
|
@ -159,12 +301,26 @@ namespace Nz
|
|||
NumberEquals(roll, angles.roll);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the euler angle to other one
|
||||
* \return false if the euler angles are the same
|
||||
*
|
||||
* \param angles Other euler angle to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool EulerAngles<T>::operator!=(const EulerAngles& angles) const
|
||||
{
|
||||
return !operator==(angles);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the euler angle (0, 0, 0)
|
||||
* \return A euler angle with components (0, 0, 0)
|
||||
*
|
||||
* \see MakeZero
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
EulerAngles<T> EulerAngles<T>::Zero()
|
||||
{
|
||||
|
|
@ -175,6 +331,14 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Output operator
|
||||
* \return The stream
|
||||
*
|
||||
* \param out The stream
|
||||
* \param angles The euler angle to output
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const Nz::EulerAngles<T>& angles)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,6 +15,20 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
|
||||
/*!
|
||||
* \class Nz::Frustum<T>
|
||||
* \brief Math class that represents a frustum in the three dimensional vector space
|
||||
*
|
||||
* Frustums are used to determine what is inside the camera's field of view. They help speed up the rendering process
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Frustum<T> object from another type of Frustum
|
||||
*
|
||||
* \param frustum Frustum of type U to convert to type T
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Frustum<T>::Frustum(const Frustum<U>& frustum)
|
||||
|
|
@ -22,6 +36,19 @@ namespace Nz
|
|||
Set(frustum);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Builds the frustum object
|
||||
* \return A reference to this frustum which is the build up camera's field of view
|
||||
*
|
||||
* \param angle Unit depends on NAZARA_MATH_ANGLE_RADIAN
|
||||
* \param ratio Rendering ratio (typically 16/9 or 4/3)
|
||||
* \param zNear Distance where 'vision' begins
|
||||
* \param zFar Distance where 'vision' ends
|
||||
* \param eye Position of the camera
|
||||
* \param target Position of the target of the camera
|
||||
* \param up Direction of up vector according to the orientation of camera
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Frustum<T>& Frustum<T>::Build(T angle, T ratio, T zNear, T zFar, const Vector3<T>& eye, const Vector3<T>& target, const Vector3<T>& up)
|
||||
{
|
||||
|
|
@ -45,7 +72,7 @@ namespace Nz
|
|||
Vector3<T> nc = eye + f * zNear;
|
||||
Vector3<T> fc = eye + f * zFar;
|
||||
|
||||
// Calcul du frustum
|
||||
// Computing the frustum
|
||||
m_corners[BoxCorner_FarLeftBottom] = fc - u * farH - s * farW;
|
||||
m_corners[BoxCorner_FarLeftTop] = fc + u * farH - s * farW;
|
||||
m_corners[BoxCorner_FarRightTop] = fc + u * farH + s * farW;
|
||||
|
|
@ -56,7 +83,7 @@ namespace Nz
|
|||
m_corners[BoxCorner_NearRightTop] = nc + u * nearH + s * nearW;
|
||||
m_corners[BoxCorner_NearRightBottom] = nc - u * nearH + s * nearW;
|
||||
|
||||
// Construction des plans du frustum
|
||||
// Construction of frustum's planes
|
||||
m_planes[FrustumPlane_Bottom].Set(m_corners[BoxCorner_NearLeftBottom], m_corners[BoxCorner_NearRightBottom], m_corners[BoxCorner_FarRightBottom]);
|
||||
m_planes[FrustumPlane_Far].Set(m_corners[BoxCorner_FarRightTop], m_corners[BoxCorner_FarLeftTop], m_corners[BoxCorner_FarLeftBottom]);
|
||||
m_planes[FrustumPlane_Left].Set(m_corners[BoxCorner_NearLeftTop], m_corners[BoxCorner_NearLeftBottom], m_corners[BoxCorner_FarLeftBottom]);
|
||||
|
|
@ -67,6 +94,18 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not a bounding volume is contained in the frustum
|
||||
* \return true if the bounding volume is entirely in the frustum
|
||||
*
|
||||
* \param volume Volume to check
|
||||
*
|
||||
* \remark If volume is infinite, true is returned
|
||||
* \remark If volume is null, false is returned
|
||||
* \remark If enumeration of the volume is not defined in Extend, a NazaraError is thrown and false is returned
|
||||
* \remark If enumeration of the intersection is not defined in IntersectionSide, a NazaraError is thrown and false is returned. This should not never happen for a user of the library
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Frustum<T>::Contains(const BoundingVolume<T>& volume) const
|
||||
{
|
||||
|
|
@ -102,6 +141,13 @@ namespace Nz
|
|||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not a box is contained in the frustum
|
||||
* \return true if the box is entirely in the frustum
|
||||
*
|
||||
* \param box Box to check
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Frustum<T>::Contains(const Box<T>& box) const
|
||||
{
|
||||
|
|
@ -115,12 +161,26 @@ namespace Nz
|
|||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not an oriented box is contained in the frustum
|
||||
* \return true if the oriented box is entirely in the frustum
|
||||
*
|
||||
* \param orientedbox Oriented box to check
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Frustum<T>::Contains(const OrientedBox<T>& orientedbox) const
|
||||
{
|
||||
return Contains(&orientedbox[0], 8);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not a sphere is contained in the frustum
|
||||
* \return true if the sphere is entirely in the frustum
|
||||
*
|
||||
* \param sphere Sphere to check
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Frustum<T>::Contains(const Sphere<T>& sphere) const
|
||||
{
|
||||
|
|
@ -133,6 +193,13 @@ namespace Nz
|
|||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not a Vector3 is contained in the frustum
|
||||
* \return true if the Vector3 is in the frustum
|
||||
*
|
||||
* \param point Vector3 which represents a point in the space
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Frustum<T>::Contains(const Vector3<T>& point) const
|
||||
{
|
||||
|
|
@ -145,6 +212,14 @@ namespace Nz
|
|||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not a set of Vector3 is contained in the frustum
|
||||
* \return true if the set of Vector3 is in the frustum
|
||||
*
|
||||
* \param points Pointer to Vector3 which represents a set of points in the space
|
||||
* \param pointCount Number of points to check
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Frustum<T>::Contains(const Vector3<T>* points, unsigned int pointCount) const
|
||||
{
|
||||
|
|
@ -164,6 +239,15 @@ namespace Nz
|
|||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs the frustum from a Matrix4
|
||||
* \return A reference to this frustum which is the build up of projective matrix
|
||||
*
|
||||
* \param clipMatrix Matrix which represents the transformation of the frustum
|
||||
*
|
||||
* \remark A NazaraWarning is produced if clipMatrix is not inversible and corners are unchanged
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Frustum<T>& Frustum<T>::Extract(const Matrix4<T>& clipMatrix)
|
||||
{
|
||||
|
|
@ -261,8 +345,8 @@ namespace Nz
|
|||
|
||||
m_planes[FrustumPlane_Near].Set(plane);
|
||||
|
||||
// Une fois les plans extraits, il faut extraire les points du frustum
|
||||
// Je me base sur cette page: http://www.gamedev.net/topic/393309-calculating-the-view-frustums-vertices/
|
||||
// Once planes have been extracted, we must extract points of the frustum
|
||||
// Based on: http://www.gamedev.net/topic/393309-calculating-the-view-frustums-vertices/
|
||||
|
||||
Matrix4<T> invClipMatrix;
|
||||
if (clipMatrix.GetInverse(&invClipMatrix))
|
||||
|
|
@ -331,12 +415,31 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs the frustum from the view matrix and the projection matrix
|
||||
* \return A reference to this frustum which is the build up of projective matrix
|
||||
*
|
||||
* \param view Matrix which represents the view
|
||||
* \param projection Matrix which represents the projection (the perspective)
|
||||
*
|
||||
* \remark A NazaraWarning is produced if the product of these matrices is not inversible and corners are unchanged
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Frustum<T>& Frustum<T>::Extract(const Matrix4<T>& view, const Matrix4<T>& projection)
|
||||
{
|
||||
return Extract(Matrix4<T>::Concatenate(view, projection));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the Vector3 for the corner
|
||||
* \return The position of the corner of the frustum according to enum BoxCorner
|
||||
*
|
||||
* \param corner Enumeration of type BoxCorner
|
||||
*
|
||||
* \remark If enumeration is not defined in BoxCorner and NAZARA_DEBUG defined, a NazaraError is thrown and a Vector3 uninitialised is returned
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
const Vector3<T>& Frustum<T>::GetCorner(BoxCorner corner) const
|
||||
{
|
||||
|
|
@ -353,6 +456,15 @@ namespace Nz
|
|||
return m_corners[corner];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the Plane for the face
|
||||
* \return The face of the frustum according to enum FrustumPlane
|
||||
*
|
||||
* \param plane Enumeration of type FrustumPlane
|
||||
*
|
||||
* \remark If enumeration is not defined in FrustumPlane and NAZARA_DEBUG defined, a NazaraError is thrown and a Plane uninitialised is returned
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
const Plane<T>& Frustum<T>::GetPlane(FrustumPlane plane) const
|
||||
{
|
||||
|
|
@ -369,6 +481,18 @@ namespace Nz
|
|||
return m_planes[plane];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not a bounding volume intersects with the frustum
|
||||
* \return IntersectionSide How the bounding volume is intersecting with the frustum
|
||||
*
|
||||
* \param volume Volume to check
|
||||
*
|
||||
* \remark If volume is infinite, IntersectionSide_Intersecting is returned
|
||||
* \remark If volume is null, IntersectionSide_Outside is returned
|
||||
* \remark If enumeration of the volume is not defined in Extend, a NazaraError is thrown and false is returned
|
||||
* \remark If enumeration of the intersection is not defined in IntersectionSide, a NazaraError is thrown and false is returned. This should not never happen for a user of the library
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
IntersectionSide Frustum<T>::Intersect(const BoundingVolume<T>& volume) const
|
||||
{
|
||||
|
|
@ -394,7 +518,7 @@ namespace Nz
|
|||
}
|
||||
|
||||
case Extend_Infinite:
|
||||
return IntersectionSide_Intersecting; // On ne peut pas contenir l'infini
|
||||
return IntersectionSide_Intersecting; // We can not contain infinity
|
||||
|
||||
case Extend_Null:
|
||||
return IntersectionSide_Outside;
|
||||
|
|
@ -404,6 +528,13 @@ namespace Nz
|
|||
return IntersectionSide_Outside;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not a box intersects with the frustum
|
||||
* \return IntersectionSide How the box is intersecting with the frustum
|
||||
*
|
||||
* \param box Box to check
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
IntersectionSide Frustum<T>::Intersect(const Box<T>& box) const
|
||||
{
|
||||
|
|
@ -421,12 +552,26 @@ namespace Nz
|
|||
return side;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not an oriented box intersects with the frustum
|
||||
* \return IntersectionSide How the oriented box is intersecting with the frustum
|
||||
*
|
||||
* \param oriented box OrientedBox to check
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
IntersectionSide Frustum<T>::Intersect(const OrientedBox<T>& orientedbox) const
|
||||
{
|
||||
return Intersect(&orientedbox[0], 8);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not a sphere intersects with the frustum
|
||||
* \return IntersectionSide How the sphere is intersecting with the frustum
|
||||
*
|
||||
* \param sphere Sphere to check
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
IntersectionSide Frustum<T>::Intersect(const Sphere<T>& sphere) const
|
||||
{
|
||||
|
|
@ -445,6 +590,14 @@ namespace Nz
|
|||
return side;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not a set of Vector3 intersects with the frustum
|
||||
* \return IntersectionSide How the set of Vector3 is intersecting with the frustum
|
||||
*
|
||||
* \param points Pointer to Vector3 which represents a set of points in the space
|
||||
* \param pointCount Number of points to check
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
IntersectionSide Frustum<T>::Intersect(const Vector3<T>* points, unsigned int pointCount) const
|
||||
{
|
||||
|
|
@ -468,6 +621,13 @@ namespace Nz
|
|||
return (c == 6) ? IntersectionSide_Inside : IntersectionSide_Intersecting;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the frustum from another frustum
|
||||
* \return A reference to this frustum
|
||||
*
|
||||
* \param frustum The other frustum
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Frustum<T>& Frustum<T>::Set(const Frustum& frustum)
|
||||
{
|
||||
|
|
@ -476,6 +636,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the frustum from another type of Frustum
|
||||
* \return A reference to this frustum
|
||||
*
|
||||
* \param frustum Frustum of type U to convert its components
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Frustum<T>& Frustum<T>::Set(const Frustum<U>& frustum)
|
||||
|
|
@ -489,6 +656,11 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gives a string representation
|
||||
* \return A string representation of the object: "Frustum(Plane ...)"
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
String Frustum<T>::ToString() const
|
||||
{
|
||||
|
|
@ -503,6 +675,14 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Output operator
|
||||
* \return The stream
|
||||
*
|
||||
* \param out The stream
|
||||
* \param frustum The frustum to output
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const Nz::Frustum<T>& frustum)
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -13,24 +13,62 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \class Nz::OrientedBox<T>
|
||||
* \brief Math class that represents an oriented three dimensional box
|
||||
*
|
||||
* \remark You need to call Update not to have undefined behaviour
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a OrientedBox<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>
|
||||
OrientedBox<T>::OrientedBox(T X, T Y, T Z, T Width, T Height, T Depth)
|
||||
{
|
||||
Set(X, Y, Z, Width, Height, Depth);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a OrientedBox<T> object from a box
|
||||
*
|
||||
* \param box Box<T> object
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
OrientedBox<T>::OrientedBox(const Box<T>& box)
|
||||
{
|
||||
Set(box);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a OrientedBox<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>
|
||||
OrientedBox<T>::OrientedBox(const Vector3<T>& vec1, const Vector3<T>& vec2)
|
||||
{
|
||||
Set(vec1, vec2);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a OrientedBox<T> object from another type of OrientedBox
|
||||
*
|
||||
* \param orientedBox OrientedBox of type U to convert to type T
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
OrientedBox<T>::OrientedBox(const OrientedBox<U>& orientedBox)
|
||||
|
|
@ -38,6 +76,15 @@ namespace Nz
|
|||
Set(orientedBox);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the Vector3 for the corner
|
||||
* \return The position of the corner of the oriented 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>
|
||||
const Vector3<T>& OrientedBox<T>::GetCorner(BoxCorner corner) const
|
||||
{
|
||||
|
|
@ -54,12 +101,24 @@ namespace Nz
|
|||
return m_corners[corner];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether this oriented box is valid
|
||||
* \return true if the oriented box has a strictly positive width, height and depth
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool OrientedBox<T>::IsValid() const
|
||||
{
|
||||
return localBox.IsValid();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the oriented box position (0, 0, 0) and lengths (0, 0, 0)
|
||||
* \return A reference to this oriented box with position (0, 0, 0) and lengths (0, 0, 0)
|
||||
*
|
||||
* \see Zero
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
OrientedBox<T>& OrientedBox<T>::MakeZero()
|
||||
{
|
||||
|
|
@ -68,6 +127,18 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the oriented box
|
||||
* \return A reference to this oriented box
|
||||
*
|
||||
* \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>
|
||||
OrientedBox<T>& OrientedBox<T>::Set(T X, T Y, T Z, T Width, T Height, T Depth)
|
||||
{
|
||||
|
|
@ -76,6 +147,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the oriented box from a box
|
||||
* \return A reference to this oriented box
|
||||
*
|
||||
* \param box Box<T> object
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
OrientedBox<T>& OrientedBox<T>::Set(const Box<T>& box)
|
||||
{
|
||||
|
|
@ -84,6 +162,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the oriented box with components from another
|
||||
* \return A reference to this oriented box
|
||||
*
|
||||
* \param orientedBox The other OrientedBox
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
OrientedBox<T>& OrientedBox<T>::Set(const OrientedBox& orientedBox)
|
||||
{
|
||||
|
|
@ -92,6 +177,14 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets a OrientedBox<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>
|
||||
OrientedBox<T>& OrientedBox<T>::Set(const Vector3<T>& vec1, const Vector3<T>& vec2)
|
||||
{
|
||||
|
|
@ -100,6 +193,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the orientedBox from another type of OrientedBox
|
||||
* \return A reference to this orientedBox
|
||||
*
|
||||
* \param orientedBox OrientedBox of type U to convert its components
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
OrientedBox<T>& OrientedBox<T>::Set(const OrientedBox<U>& orientedBox)
|
||||
|
|
@ -112,6 +212,11 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gives a string representation
|
||||
* \return A string representation of the object: "OrientedBox(...)"
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
String OrientedBox<T>::ToString() const
|
||||
{
|
||||
|
|
@ -127,6 +232,12 @@ namespace Nz
|
|||
<< " NRT: " << m_corners[BoxCorner_NearRightTop].ToString() << ")\n";
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Updates the corners of the box
|
||||
*
|
||||
* \param transformMatrix Matrix4 which represents the transformation to apply on the local box
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
void OrientedBox<T>::Update(const Matrix4<T>& transformMatrix)
|
||||
{
|
||||
|
|
@ -134,6 +245,12 @@ namespace Nz
|
|||
m_corners[i] = transformMatrix.Transform(localBox.GetCorner(static_cast<BoxCorner>(i)));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Updates the corners of the box
|
||||
*
|
||||
* \param translation Vector3 which represents the translation to apply on the local box
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
void OrientedBox<T>::Update(const Vector3<T>& translation)
|
||||
{
|
||||
|
|
@ -141,18 +258,40 @@ namespace Nz
|
|||
m_corners[i] = localBox.GetCorner(static_cast<BoxCorner>(i)) + translation;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts oriented box to pointer of Vector3 to its own corners
|
||||
* \return A pointer to the own corners
|
||||
*
|
||||
* \remark Access to index greather than BoxCorner_Max is undefined behavior
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
OrientedBox<T>::operator Vector3<T>* ()
|
||||
{
|
||||
return &m_corners[0];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts oriented box to pointer of Vector3 to its own corners
|
||||
* \return A const pointer to the own corners
|
||||
*
|
||||
* \remark Access to index greather than BoxCorner_Max is undefined behavior
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
OrientedBox<T>::operator const Vector3<T>* () const
|
||||
{
|
||||
return &m_corners[0];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the ith corner of the oriented box
|
||||
* \return A reference to this corner
|
||||
*
|
||||
* \remark Produce a NazaraError if you try to access to index greather than BoxCorner_Max with NAZARA_MATH_SAFE defined. If not, it is undefined behaviour
|
||||
* \throw std::out_of_range if NAZARA_MATH_SAFE is defined and you try to acces to index greather than BoxCorner_Max
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector3<T>& OrientedBox<T>::operator()(unsigned int i)
|
||||
{
|
||||
|
|
@ -170,6 +309,14 @@ namespace Nz
|
|||
return m_corners[i];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the ith corner of the oriented box
|
||||
* \return A reference to this corner
|
||||
*
|
||||
* \remark Produce a NazaraError if you try to access to index greather than BoxCorner_Max with NAZARA_MATH_SAFE defined. If not, it is undefined behaviour
|
||||
* \throw std::out_of_range if NAZARA_MATH_SAFE is defined and you try to acces to index greather than BoxCorner_Max
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector3<T> OrientedBox<T>::operator()(unsigned int i) const
|
||||
{
|
||||
|
|
@ -187,6 +334,13 @@ namespace Nz
|
|||
return m_corners[i];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the lengths with the scalar
|
||||
* \return A OrientedBox 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>
|
||||
OrientedBox<T> OrientedBox<T>::operator*(T scalar) const
|
||||
{
|
||||
|
|
@ -196,6 +350,13 @@ namespace Nz
|
|||
return box;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the lengths of this oriented box with the scalar
|
||||
* \return A reference to this oriented 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>
|
||||
OrientedBox<T>& OrientedBox<T>::operator*=(T scalar)
|
||||
{
|
||||
|
|
@ -204,18 +365,46 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the oriented box to other one
|
||||
* \return true if the two oriented boxes are the same
|
||||
*
|
||||
* \param box Other oriented box to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool OrientedBox<T>::operator==(const OrientedBox& box) const
|
||||
{
|
||||
return localBox == box.localBox;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the oriented box to other one
|
||||
* \return false if the two oriented boxes are the same
|
||||
*
|
||||
* \param box Other oriented box to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool OrientedBox<T>::operator!=(const OrientedBox& box) const
|
||||
{
|
||||
return !operator==(box);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Interpolates the oriented box to other one with a factor of interpolation
|
||||
* \return A new oriented box which is the interpolation of two oriented boxes
|
||||
*
|
||||
* \param from Initial oriented box
|
||||
* \param to Target oriented 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>
|
||||
OrientedBox<T> OrientedBox<T>::Lerp(const OrientedBox& from, const OrientedBox& to, T interpolation)
|
||||
{
|
||||
|
|
@ -225,6 +414,13 @@ namespace Nz
|
|||
return orientedBox;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the oriented box (0, 0, 0, 0, 0, 0)
|
||||
* \return A oriented box with position (0, 0, 0) and lengths (0, 0, 0)
|
||||
*
|
||||
* \see MakeZero
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
OrientedBox<T> OrientedBox<T>::Zero()
|
||||
{
|
||||
|
|
@ -235,6 +431,14 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Output operator
|
||||
* \return The stream
|
||||
*
|
||||
* \param out The stream
|
||||
* \param orientedBox The orientedBox to output
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const Nz::OrientedBox<T>& orientedBox)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -26,8 +26,12 @@ namespace Nz
|
|||
Plane(const Plane& plane) = default;
|
||||
~Plane() = default;
|
||||
|
||||
T Distance(const Vector3<T>& point) const;
|
||||
T Distance(T x, T y, T z) const;
|
||||
T Distance(const Vector3<T>& point) const;
|
||||
|
||||
Plane& MakeXY();
|
||||
Plane& MakeXZ();
|
||||
Plane& MakeYZ();
|
||||
|
||||
Plane& Set(T normalX, T normalY, T normalZ, T Distance);
|
||||
Plane& Set(const T plane[4]);
|
||||
|
|
|
|||
|
|
@ -11,36 +11,88 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \class Nz::Vector4<T>
|
||||
* \brief Math class that represents a plane in 3D
|
||||
*
|
||||
* \remark The convention used in this class is: If you ask for plane with normal (0, 1, 0) and distance 1, you will get 0 * X + 1 * Y + 0 * Z - 1 = 0 or Y = 1. Notice the sign minus before the distance on the left side of the equation
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Plane<T> object from its components
|
||||
*
|
||||
* \param normalX X component of the normal
|
||||
* \param normalY Y component of the normal
|
||||
* \param normalZ Z component of the normal
|
||||
* \param D Distance to origin
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T>::Plane(T normalX, T normalY, T normalZ, T D)
|
||||
{
|
||||
Set(normalX, normalY, normalZ, D);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Plane<T> object from an array of four elements
|
||||
*
|
||||
* \param plane[4] plane[0] is X component, plane[1] is Y component, plane[2] is Z component and plane[3] is D
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T>::Plane(const T plane[4])
|
||||
{
|
||||
Set(plane);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Plane<T> object from a normal and a distance
|
||||
*
|
||||
* \param Normal normal of the vector
|
||||
* \param D Distance to origin
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T>::Plane(const Vector3<T>& Normal, T D)
|
||||
{
|
||||
Set(Normal, D);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Plane<T> object from a normal and a point
|
||||
*
|
||||
* \param Normal Normal of the plane
|
||||
* \param point Point which verifies the equation of the plane
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T>::Plane(const Vector3<T>& Normal, const Vector3<T>& point)
|
||||
{
|
||||
Set(Normal, point);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Plane<T> object from three points
|
||||
*
|
||||
* \param point1 First point
|
||||
* \param point2 Second point
|
||||
* \param point3 Third point
|
||||
*
|
||||
* \remark They are expected not to be colinear
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T>::Plane(const Vector3<T>& point1, const Vector3<T>& point2, const Vector3<T>& point3)
|
||||
{
|
||||
Set(point1, point2, point3);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Plane<T> object from another type of Plane
|
||||
*
|
||||
* \param plane Plane of type U to convert to type T
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Plane<T>::Plane(const Plane<U>& plane)
|
||||
|
|
@ -48,11 +100,18 @@ namespace Nz
|
|||
Set(plane);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T Plane<T>::Distance(const Vector3<T>& point) const
|
||||
{
|
||||
return normal.DotProduct(point) - distance; // ax + by + cd - d = 0.
|
||||
}
|
||||
/*!
|
||||
* \brief Returns the distance from the plane to the point
|
||||
* \return Distance to the point
|
||||
*
|
||||
* \param X X position of the point
|
||||
* \param Y Y position of the point
|
||||
* \param Z Z position of the point
|
||||
*
|
||||
* \remark If T is negative, it means that the point is in the opposite direction of the normal
|
||||
*
|
||||
* \see Distance
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Plane<T>::Distance(T x, T y, T z) const
|
||||
|
|
@ -60,6 +119,72 @@ namespace Nz
|
|||
return Distance(Vector3<T>(x, y, z));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the distance from the plane to the point
|
||||
* \return Distance to the point
|
||||
*
|
||||
* \param point Position of the point
|
||||
*
|
||||
* \remark If T is negative, it means that the point is in the opposite direction of the normal
|
||||
*
|
||||
* \see Distance
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Plane<T>::Distance(const Vector3<T>& point) const
|
||||
{
|
||||
return normal.DotProduct(point) - distance; // ax + by + cd - d = 0.
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the plane (0, 0, 1, 0)
|
||||
* \return A reference to this plane with components (0, 0, 1, 0)
|
||||
*
|
||||
* \see XY
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T>& Plane<T>::MakeXY()
|
||||
{
|
||||
return Set(F(0.0), F(0.0), F(1.0), F(0.0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the plane (0, 1, 0, 0)
|
||||
* \return A reference to this plane with components (0, 1, 0, 0)
|
||||
*
|
||||
* \see XZ
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T>& Plane<T>::MakeXZ()
|
||||
{
|
||||
return Set(F(0.0), F(1.0), F(0.0), F(0.0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the plane (1, 0, 0, 0)
|
||||
* \return A reference to this plane with components (1, 0, 0, 0)
|
||||
*
|
||||
* \see YZ
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T>& Plane<T>::MakeYZ()
|
||||
{
|
||||
return Set(F(1.0), F(0.0), F(0.0), F(0.0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the plane
|
||||
* \return A reference to this plane
|
||||
*
|
||||
* \param normalX X component of the normal
|
||||
* \param normalY Y component of the normal
|
||||
* \param normalZ Z component of the normal
|
||||
* \param D Distance to origin
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T>& Plane<T>::Set(T normalX, T normalY, T normalZ, T D)
|
||||
{
|
||||
|
|
@ -69,6 +194,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the plane from an array of four elements
|
||||
* \return A reference to this plane
|
||||
*
|
||||
* \param plane[4] plane[0] is X component, plane[1] is Y component, plane[2] is Z component and plane[3] is D
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T>& Plane<T>::Set(const T plane[4])
|
||||
{
|
||||
|
|
@ -78,6 +210,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the plane from another plane
|
||||
* \return A reference to this plane
|
||||
*
|
||||
* \param plane The other plane
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T>& Plane<T>::Set(const Plane& plane)
|
||||
{
|
||||
|
|
@ -86,6 +225,14 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the plane from a normal and a distance
|
||||
* \return A reference to this plane
|
||||
*
|
||||
* \param Normal Normal of the vector
|
||||
* \param D Distance to origin
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T>& Plane<T>::Set(const Vector3<T>& Normal, T D)
|
||||
{
|
||||
|
|
@ -95,6 +242,14 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the plane from a normal and a point
|
||||
* \return A reference to this plane
|
||||
*
|
||||
* \param Normal Normal of the plane
|
||||
* \param point Point which verifies the equation of the plane
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T>& Plane<T>::Set(const Vector3<T>& Normal, const Vector3<T>& point)
|
||||
{
|
||||
|
|
@ -104,6 +259,17 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the plane from three points
|
||||
* \return A reference to this plane
|
||||
*
|
||||
* \param point1 First point
|
||||
* \param point2 Second point
|
||||
* \param point3 Third point
|
||||
*
|
||||
* \remark They are expected not to be colinear
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T>& Plane<T>::Set(const Vector3<T>& point1, const Vector3<T>& point2, const Vector3<T>& point3)
|
||||
{
|
||||
|
|
@ -117,6 +283,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the plane from another type of Plane
|
||||
* \return A reference to this plane
|
||||
*
|
||||
* \param plane Plane of type U to convert its components
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Plane<T>& Plane<T>::Set(const Plane<U>& plane)
|
||||
|
|
@ -127,6 +300,11 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gives a string representation
|
||||
* \return A string representation of the object: "Plane(Normal: Vector3(x, y, z); Distance: w)"
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
String Plane<T>::ToString() const
|
||||
{
|
||||
|
|
@ -135,18 +313,50 @@ namespace Nz
|
|||
return ss << "Plane(Normal: " << normal.ToString() << "; Distance: " << distance << ')';
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the plane to other one
|
||||
* \return true if the planes are the same
|
||||
*
|
||||
* \param vec Other vector to compare with
|
||||
*
|
||||
* \remark Plane with normal N and distance D is the same than with normal -N et distance -D
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Plane<T>::operator==(const Plane& plane) const
|
||||
{
|
||||
return (normal == plane.normal && NumberEquals(distance, plane.distance)) || (normal == -plane.normal && NumberEquals(distance, -plane.distance));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the plane to other one
|
||||
* \return false if the planes are the same
|
||||
*
|
||||
* \param plane Other plane to compare with
|
||||
*
|
||||
* \remark Plane with normal N and distance D is the same than with normal -N et distance -D
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Plane<T>::operator!=(const Plane& plane) const
|
||||
{
|
||||
return !operator==(plane);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Interpolates the plane to other one with a factor of interpolation
|
||||
* \return A new plane which is the interpolation of two planes
|
||||
*
|
||||
* \param from Initial plane
|
||||
* \param to Target plane
|
||||
* \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 Plane() is returned
|
||||
*
|
||||
* \see Lerp
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T> Plane<T>::Lerp(const Plane& from, const Plane& to, T interpolation)
|
||||
{
|
||||
|
|
@ -159,32 +369,70 @@ namespace Nz
|
|||
#endif
|
||||
|
||||
Plane plane;
|
||||
plane.distance = Lerp(from.distance, to.distance, interpolation);
|
||||
plane.distance = Nz::Lerp(from.distance, to.distance, interpolation);
|
||||
plane.normal = Vector3<T>::Lerp(from.normal, to.normal, interpolation);
|
||||
plane.normal.Normalize();
|
||||
|
||||
return plane;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the plane (0, 0, 1, 0)
|
||||
* \return A plane with components (0, 0, 1, 0)
|
||||
*
|
||||
* \see MakeXY
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T> Plane<T>::XY()
|
||||
{
|
||||
return Plane<T>(F(0.0), F(0.0), F(1.0), F(0.0));
|
||||
Plane plane;
|
||||
plane.MakeXY();
|
||||
|
||||
return plane;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the plane (0, 1, 0, 0)
|
||||
* \return A plane with components (0, 1, 0, 0)
|
||||
*
|
||||
* \see MakeXZ
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T> Plane<T>::XZ()
|
||||
{
|
||||
return Plane<T>(F(0.0), F(1.0), F(0.0), F(0.0));
|
||||
Plane plane;
|
||||
plane.MakeXZ();
|
||||
|
||||
return plane;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the plane (1, 0, 0, 0)
|
||||
* \return A plane with components (1, 0, 0, 0)
|
||||
*
|
||||
* \see MakeYZ
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T> Plane<T>::YZ()
|
||||
{
|
||||
return Plane<T>(F(1.0), F(0.0), F(0.0), F(0.0));
|
||||
Plane plane;
|
||||
plane.MakeYZ();
|
||||
|
||||
return plane;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Output operator
|
||||
* \return The stream
|
||||
*
|
||||
* \param out The stream
|
||||
* \param plane The plane to output
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const Nz::Plane<T>& plane)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ namespace Nz
|
|||
public:
|
||||
Quaternion() = default;
|
||||
Quaternion(T W, T X, T Y, T Z);
|
||||
Quaternion(const T quat[4]);
|
||||
Quaternion(T angle, const Vector3<T>& axis);
|
||||
Quaternion(const EulerAngles<T>& angles);
|
||||
Quaternion(T angle, const Vector3<T>& axis);
|
||||
Quaternion(const T quat[4]);
|
||||
//Quaternion(const Matrix3<T>& mat);
|
||||
template<typename U> explicit Quaternion(const Quaternion<U>& quat);
|
||||
Quaternion(const Quaternion& quat) = default;
|
||||
|
|
@ -47,9 +47,9 @@ namespace Nz
|
|||
Quaternion& Normalize(T* length = nullptr);
|
||||
|
||||
Quaternion& Set(T W, T X, T Y, T Z);
|
||||
Quaternion& Set(const T quat[4]);
|
||||
Quaternion& Set(T angle, const Vector3<T>& normalizedAxis);
|
||||
Quaternion& Set(const EulerAngles<T>& angles);
|
||||
Quaternion& Set(T angle, const Vector3<T>& normalizedAxis);
|
||||
Quaternion& Set(const T quat[4]);
|
||||
//Quaternion& Set(const Matrix3<T>& mat);
|
||||
Quaternion& Set(const Quaternion& quat);
|
||||
template<typename U> Quaternion& Set(const Quaternion<U>& quat);
|
||||
|
|
@ -60,7 +60,7 @@ namespace Nz
|
|||
//Matrix3<T> ToRotationMatrix() const;
|
||||
String ToString() const;
|
||||
|
||||
Quaternion& operator=(const Quaternion& quat);
|
||||
Quaternion& operator=(const Quaternion& quat) = default;
|
||||
|
||||
Quaternion operator+(const Quaternion& quat) const;
|
||||
Quaternion operator*(const Quaternion& quat) const;
|
||||
|
|
|
|||
|
|
@ -15,29 +15,67 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \class Nz::Quaternion<T>
|
||||
* \brief Math class that represents an element of the quaternions
|
||||
*
|
||||
* \remark The quaternion is meant to be 'unit' to represent rotations in a three dimensional space
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Quaternion<T> object from its components
|
||||
*
|
||||
* \param W W component
|
||||
* \param X X component
|
||||
* \param Y Y component
|
||||
* \param Z Z component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>::Quaternion(T W, T X, T Y, T Z)
|
||||
{
|
||||
Set(W, X, Y, Z);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Quaternion<T> object from a EulerAngles
|
||||
*
|
||||
* \param angles Easier representation of rotation of space
|
||||
*
|
||||
* \see EulerAngles
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>::Quaternion(const T quat[4])
|
||||
Quaternion<T>::Quaternion(const EulerAngles<T>& angles)
|
||||
{
|
||||
Set(quat);
|
||||
Set(angles);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Quaternion<T> object from an angle and a direction
|
||||
*
|
||||
* \param angle Unit depends of NAZARA_MATH_ANGLE_RADIAN
|
||||
* \param axis Vector3 which represents a direction, no need to be normalized
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>::Quaternion(T angle, const Vector3<T>& axis)
|
||||
{
|
||||
Set(angle, axis);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Quaternion<T> object from an array of four elements
|
||||
*
|
||||
* \param quat[4] quat[0] is W component, quat[1] is X component, quat[2] is Y component and quat[3] is Z component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>::Quaternion(const EulerAngles<T>& angles)
|
||||
Quaternion<T>::Quaternion(const T quat[4])
|
||||
{
|
||||
Set(angles);
|
||||
Set(quat);
|
||||
}
|
||||
|
||||
/*
|
||||
template<typename T>
|
||||
Quaternion<T>::Quaternion(const Matrix3<T>& mat)
|
||||
|
|
@ -45,6 +83,13 @@ namespace Nz
|
|||
Set(mat);
|
||||
}
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Quaternion<T> object from another type of Quaternion
|
||||
*
|
||||
* \param quat Quaternion of type U to convert to type T
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Quaternion<T>::Quaternion(const Quaternion<U>& quat)
|
||||
|
|
@ -52,6 +97,11 @@ namespace Nz
|
|||
Set(quat);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Computes the w component of the quaternion to make it unit
|
||||
* \return A reference to this quaternion
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::ComputeW()
|
||||
{
|
||||
|
|
@ -65,6 +115,15 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the rotational conjugate of this quaternion
|
||||
* \return A reference to this quaternion
|
||||
*
|
||||
* The conjugate of a quaternion represents the same rotation in the opposite direction about the rotational axis
|
||||
*
|
||||
* \see GetConjugate
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::Conjugate()
|
||||
{
|
||||
|
|
@ -75,12 +134,28 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the dot (scalar) product with two quaternions
|
||||
* \return The value of the dot product
|
||||
*
|
||||
* \param quat The other quaternion to calculate the dot product with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Quaternion<T>::DotProduct(const Quaternion& quat) const
|
||||
{
|
||||
return w * quat.w + x * quat.x + y * quat.y + z * quat.z;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the rotational conjugate of this quaternion
|
||||
* \return A new quaternion which is the conjugate of this quaternion
|
||||
*
|
||||
* The conjugate of a quaternion represents the same rotation in the opposite direction about the rotational axis
|
||||
*
|
||||
* \see Conjugate
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::GetConjugate() const
|
||||
{
|
||||
|
|
@ -90,6 +165,15 @@ namespace Nz
|
|||
return quat;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the inverse of this quaternion
|
||||
* \return A new quaternion which is the inverse of this quaternion
|
||||
*
|
||||
* \remark If this quaternion is (0, 0, 0, 0), then it returns (0, 0, 0, 0)
|
||||
*
|
||||
* \see Inverse
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::GetInverse() const
|
||||
{
|
||||
|
|
@ -99,6 +183,17 @@ namespace Nz
|
|||
return quat;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the normalization of this quaternion
|
||||
* \return A new quaternion which is the normalization of this quaternion
|
||||
*
|
||||
* \param length Optional argument to obtain the length's ratio of the quaternion and the unit-length
|
||||
*
|
||||
* \remark If this quaternion is (0, 0, 0, 0), then it returns (0, 0, 0, 0) and length is 0
|
||||
*
|
||||
* \see Normalize
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::GetNormal(T* length) const
|
||||
{
|
||||
|
|
@ -108,6 +203,15 @@ namespace Nz
|
|||
return quat;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Inverts this quaternion
|
||||
* \return A reference to this quaternion which is now inverted
|
||||
*
|
||||
* \remark If this quaternion is (0, 0, 0, 0), then it returns (0, 0, 0, 0)
|
||||
*
|
||||
* \see GetInverse
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::Inverse()
|
||||
{
|
||||
|
|
@ -125,15 +229,34 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the quaternion (1, 0, 0, 0)
|
||||
* \return A reference to this vector with components (1, 0, 0, 0)
|
||||
*
|
||||
* \see Unit
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::MakeIdentity()
|
||||
{
|
||||
return Set(F(1.0), F(0.0), F(0.0), F(0.0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes this quaternion to the rotation required to rotate direction Vector3 from to direction Vector3 to
|
||||
* \return A reference to this vector which is the rotation needed
|
||||
*
|
||||
* \param from Initial vector
|
||||
* \param to Target vector
|
||||
*
|
||||
* \see RotationBetween
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::MakeRotationBetween(const Vector3<T>& from, const Vector3<T>& to)
|
||||
{
|
||||
// TODO (Gawaboumga): Replace by http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors ?
|
||||
|
||||
T dot = from.DotProduct(to);
|
||||
if (NumberEquals(dot, F(-1.0)))
|
||||
{
|
||||
|
|
@ -157,28 +280,55 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the quaternion (0, 0, 0, 0)
|
||||
* \return A reference to this vector with components (0, 0, 0, 0)
|
||||
*
|
||||
* \see Zero
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::MakeZero()
|
||||
{
|
||||
return Set(F(0.0), F(0.0), F(0.0), F(0.0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the magnitude (length) of the quaternion
|
||||
* \return The magnitude
|
||||
*
|
||||
* \see SquaredMagnitude
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Quaternion<T>::Magnitude() const
|
||||
{
|
||||
return std::sqrt(SquaredMagnitude());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Normalizes the current quaternion
|
||||
* \return A reference to this quaternion which is now normalized
|
||||
*
|
||||
* \param length Optional argument to obtain the length's ratio of the quaternion and the unit-length
|
||||
*
|
||||
* \remark If the quaternion is (0, 0, 0, 0), then it returns (0, 0, 0, 0) and length is 0
|
||||
*
|
||||
* \see GetNormal
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::Normalize(T* length)
|
||||
{
|
||||
T norm = std::sqrt(SquaredMagnitude());
|
||||
if (norm > F(0.0))
|
||||
{
|
||||
T invNorm = F(1.0) / norm;
|
||||
|
||||
w *= invNorm;
|
||||
x *= invNorm;
|
||||
y *= invNorm;
|
||||
z *= invNorm;
|
||||
}
|
||||
|
||||
if (length)
|
||||
*length = norm;
|
||||
|
|
@ -186,6 +336,16 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the quaternion
|
||||
* \return A reference to this quaternion
|
||||
*
|
||||
* \param W W component
|
||||
* \param X X component
|
||||
* \param Y Y component
|
||||
* \param Z Z component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::Set(T W, T X, T Y, T Z)
|
||||
{
|
||||
|
|
@ -197,17 +357,29 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::Set(const T quat[4])
|
||||
{
|
||||
w = quat[0];
|
||||
x = quat[1];
|
||||
y = quat[2];
|
||||
z = quat[3];
|
||||
/*!
|
||||
* \brief Sets this quaternion from rotation specified by Euler angle
|
||||
* \return A reference to this quaternion
|
||||
*
|
||||
* \param angles Easier representation of rotation of space
|
||||
*
|
||||
* \see EulerAngles
|
||||
*/
|
||||
|
||||
return *this;
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::Set(const EulerAngles<T>& angles)
|
||||
{
|
||||
return Set(angles.ToQuaternion());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets this quaternion from rotation specified by axis and angle
|
||||
* \return A reference to this quaternion
|
||||
*
|
||||
* \param angle Unit depends of NAZARA_MATH_ANGLE_RADIAN
|
||||
* \param axis Vector3 which represents a direction, no need to be normalized
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::Set(T angle, const Vector3<T>& axis)
|
||||
{
|
||||
|
|
@ -229,12 +401,46 @@ namespace Nz
|
|||
return Normalize();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the quaternion from an array of four elements
|
||||
* \return A reference to this quaternion
|
||||
*
|
||||
* \param quat[4] quat[0] is W component, quat[1] is X component, quat[2] is Y component and quat[3] is Z component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::Set(const EulerAngles<T>& angles)
|
||||
Quaternion<T>& Quaternion<T>::Set(const T quat[4])
|
||||
{
|
||||
return Set(angles.ToQuaternion());
|
||||
w = quat[0];
|
||||
x = quat[1];
|
||||
y = quat[2];
|
||||
z = quat[3];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the quaternion from another quaternion
|
||||
* \return A reference to this quaternion
|
||||
*
|
||||
* \param vec The other quaternion
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::Set(const Quaternion& quat)
|
||||
{
|
||||
std::memcpy(this, &quat, sizeof(Quaternion));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the quaternion from another type of Quaternion
|
||||
* \return A reference to this quaternion
|
||||
*
|
||||
* \param quat Quaternion of type U to convert its components
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Quaternion<T>& Quaternion<T>::Set(const Quaternion<U>& quat)
|
||||
|
|
@ -247,13 +453,12 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::Set(const Quaternion& quat)
|
||||
{
|
||||
std::memcpy(this, &quat, sizeof(Quaternion));
|
||||
|
||||
return *this;
|
||||
}
|
||||
/*!
|
||||
* \brief Calculates the squared magnitude (length) of the quaternion
|
||||
* \return The squared magnitude
|
||||
*
|
||||
* \see Magnitude
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Quaternion<T>::SquaredMagnitude() const
|
||||
|
|
@ -261,6 +466,13 @@ namespace Nz
|
|||
return w * w + x * x + y * y + z * z;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts this quaternion to Euler angles representation
|
||||
* \return EulerAngles which is the representation of this rotation
|
||||
*
|
||||
* \remark Rotation are "left-handed"
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
EulerAngles<T> Quaternion<T>::ToEulerAngles() const
|
||||
{
|
||||
|
|
@ -270,6 +482,7 @@ namespace Nz
|
|||
return EulerAngles<T>(FromDegrees(F(90.0)), FromRadians(F(2.0) * std::atan2(x, w)), F(0.0));
|
||||
|
||||
if (test < F(-0.499))
|
||||
// singularity at south pole
|
||||
return EulerAngles<T>(FromDegrees(F(-90.0)), FromRadians(F(-2.0) * std::atan2(x, w)), F(0.0));
|
||||
|
||||
return EulerAngles<T>(FromRadians(std::atan2(F(2.0) * x * w - F(2.0) * y * z, F(1.0) - F(2.0) * x * x - F(2.0) * z * z)),
|
||||
|
|
@ -277,6 +490,11 @@ namespace Nz
|
|||
FromRadians(std::asin(F(2.0) * test)));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gives a string representation
|
||||
* \return A string representation of the object: "Quaternion(w | x, y, z)"
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
String Quaternion<T>::ToString() const
|
||||
{
|
||||
|
|
@ -285,11 +503,12 @@ namespace Nz
|
|||
return ss << "Quaternion(" << w << " | " << x << ", " << y << ", " << z << ')';
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::operator=(const Quaternion& quat)
|
||||
{
|
||||
return Set(quat);
|
||||
}
|
||||
/*!
|
||||
* \brief Adds the components of the quaternion with other quaternion
|
||||
* \return A quaternion where components are the sum of this quaternion and the other one
|
||||
*
|
||||
* \param quat The other quaternion to add components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::operator+(const Quaternion& quat) const
|
||||
|
|
@ -303,6 +522,13 @@ namespace Nz
|
|||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies of the quaternion with other quaternion
|
||||
* \return A quaternion which is the product of those two according to operator* in quaternions
|
||||
*
|
||||
* \param quat The other quaternion to multiply with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::operator*(const Quaternion& quat) const
|
||||
{
|
||||
|
|
@ -315,6 +541,13 @@ namespace Nz
|
|||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Apply the quaternion to the Vector3
|
||||
* \return A Vector3f which is the vector rotated by this quaternion
|
||||
*
|
||||
* \param vec The vector to multiply with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector3<T> Quaternion<T>::operator*(const Vector3<T>& vec) const
|
||||
{
|
||||
|
|
@ -327,6 +560,13 @@ namespace Nz
|
|||
return vec + uv + uuv;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the components of the quaternion with a scalar
|
||||
* \return A quaternion where components are the product of this quaternion and the scalar
|
||||
*
|
||||
* \param scale The scalar to multiply components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::operator*(T scale) const
|
||||
{
|
||||
|
|
@ -336,36 +576,78 @@ namespace Nz
|
|||
z * scale);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divides the quaternion with other quaternion
|
||||
* \return A quaternion which is the quotient of those two according to operator* in quaternions
|
||||
*
|
||||
* \param quat The other quaternion to divide with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::operator/(const Quaternion& quat) const
|
||||
{
|
||||
return quat.GetConjugate() * (*this);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds the components of the quaternion with other quaternion
|
||||
* \return A reference to this quaternion where components are the sum of this quaternion and the other one
|
||||
*
|
||||
* \param quat The other quaternion to add components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::operator+=(const Quaternion& quat)
|
||||
{
|
||||
return operator=(operator+(quat));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies of the quaternion with other quaternion
|
||||
* \return A reference to this quaternion which is the product of those two according to operator* in quaternions
|
||||
*
|
||||
* \param quat The other quaternion to multiply with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::operator*=(const Quaternion& quat)
|
||||
{
|
||||
return operator=(operator*(quat));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the components of the quaternion with a scalar
|
||||
* \return A reference to this quaternion where components are the product of this quaternion and the scalar
|
||||
*
|
||||
* \param scale The scalar to multiply components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::operator*=(T scale)
|
||||
{
|
||||
return operator=(operator*(scale));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divides the quaternion with other quaternion
|
||||
* \return A reference to this quaternion which is the quotient of those two according to operator* in quaternions
|
||||
*
|
||||
* \param quat The other quaternion to divide with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::operator/=(const Quaternion& quat)
|
||||
{
|
||||
return operator=(operator/(quat));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the quaternion to other one
|
||||
* \return true if the quaternions are the same
|
||||
*
|
||||
* \param vec Other quaternion to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Quaternion<T>::operator==(const Quaternion& quat) const
|
||||
{
|
||||
|
|
@ -375,12 +657,26 @@ namespace Nz
|
|||
NumberEquals(z, quat.z);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the quaternion to other one
|
||||
* \return false if the quaternions are the same
|
||||
*
|
||||
* \param vec Other quaternion to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Quaternion<T>::operator!=(const Quaternion& quat) const
|
||||
{
|
||||
return !operator==(quat);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the quaternion (1, 0, 0, 0)
|
||||
* \return A quaternion with components (1, 0, 0, 0)
|
||||
*
|
||||
* \see MakeIdentity
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::Identity()
|
||||
{
|
||||
|
|
@ -390,6 +686,20 @@ namespace Nz
|
|||
return quaternion;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Interpolates the quaternion to other one with a factor of interpolation
|
||||
* \return A new quaternion which is the interpolation of two quaternions
|
||||
*
|
||||
* \param from Initial quaternion
|
||||
* \param to Target quaternion
|
||||
* \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, Slerp
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::Lerp(const Quaternion& from, const Quaternion& to, T interpolation)
|
||||
{
|
||||
|
|
@ -410,12 +720,32 @@ namespace Nz
|
|||
return interpolated;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gives the normalized quaternion
|
||||
* \return A normalized quaternion from the quat
|
||||
*
|
||||
* \param quat Quaternion to normalize
|
||||
* \param length Optional argument to obtain the length's ratio of the vector and the unit-length
|
||||
*
|
||||
* \see GetNormal
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::Normalize(const Quaternion& quat, T* length)
|
||||
{
|
||||
return quat.GetNormal(length);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the rotation required to rotate direction Vector3 from to direction Vector3 to
|
||||
* \return A quaternion which is the rotation needed between those two Vector3
|
||||
*
|
||||
* \param from Initial vector
|
||||
* \param to Target vector
|
||||
*
|
||||
* \see MakeRotationBetween
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::RotationBetween(const Vector3<T>& from, const Vector3<T>& to)
|
||||
{
|
||||
|
|
@ -425,6 +755,20 @@ namespace Nz
|
|||
return quaternion;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Interpolates spherically the quaternion to other one with a factor of interpolation
|
||||
* \return A new quaternion which is the interpolation of two quaternions
|
||||
*
|
||||
* \param from Initial quaternion
|
||||
* \param to Target quaternion
|
||||
* \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>
|
||||
Quaternion<T> Quaternion<T>::Slerp(const Quaternion& from, const Quaternion& to, T interpolation)
|
||||
{
|
||||
|
|
@ -441,7 +785,7 @@ namespace Nz
|
|||
T cosOmega = from.DotProduct(to);
|
||||
if (cosOmega < F(0.0))
|
||||
{
|
||||
// On inverse tout
|
||||
// We invert everything
|
||||
q.Set(-to.w, -to.x, -to.y, -to.z);
|
||||
cosOmega = -cosOmega;
|
||||
}
|
||||
|
|
@ -451,7 +795,7 @@ namespace Nz
|
|||
T k0, k1;
|
||||
if (cosOmega > F(0.9999))
|
||||
{
|
||||
// Interpolation linéaire pour éviter une division par zéro
|
||||
// Linear interpolation to avoid division by zero
|
||||
k0 = F(1.0) - interpolation;
|
||||
k1 = interpolation;
|
||||
}
|
||||
|
|
@ -460,7 +804,7 @@ namespace Nz
|
|||
T sinOmega = std::sqrt(F(1.0) - cosOmega*cosOmega);
|
||||
T omega = std::atan2(sinOmega, cosOmega);
|
||||
|
||||
// Pour éviter deux divisions
|
||||
// To avoid two divisions
|
||||
sinOmega = F(1.0)/sinOmega;
|
||||
|
||||
k0 = std::sin((F(1.0) - interpolation) * omega) * sinOmega;
|
||||
|
|
@ -471,6 +815,13 @@ namespace Nz
|
|||
return result += q * k1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the quaternion (0, 0, 0, 0)
|
||||
* \return A quaternion with components (0, 0, 0, 0)
|
||||
*
|
||||
* \see MakeZero
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::Zero()
|
||||
{
|
||||
|
|
@ -481,6 +832,14 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Output operator
|
||||
* \return The stream
|
||||
*
|
||||
* \param out The stream
|
||||
* \param quat The quaternion to output
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const Nz::Quaternion<T>& quat)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ namespace Nz
|
|||
public:
|
||||
Ray() = default;
|
||||
Ray(T X, T Y, T Z, T directionX, T directionY, T directionZ);
|
||||
Ray(const Vector3<T>& origin, const Vector3<T>& direction);
|
||||
Ray(const T origin[3], const T direction[3]);
|
||||
Ray(const Plane<T>& planeOne, const Plane<T>& planeTwo);
|
||||
Ray(const Vector3<T>& origin, const Vector3<T>& direction);
|
||||
template<typename U> explicit Ray(const Ray<U>& ray);
|
||||
template<typename U> explicit Ray(const Vector3<U>& origin, const Vector3<U>& direction);
|
||||
Ray(const Ray<T>& ray) = default;
|
||||
|
|
@ -42,16 +42,17 @@ namespace Nz
|
|||
bool Intersect(const OrientedBox<T>& orientedBox, T* closestHit = nullptr, T* furthestHit = nullptr) const;
|
||||
bool Intersect(const Plane<T>& plane, T* hit = nullptr) const;
|
||||
bool Intersect(const Sphere<T>& sphere, T* closestHit = nullptr, T* furthestHit = nullptr) const;
|
||||
bool Intersect(const Vector3<T>& firstPoint, const Vector3<T>& secondPoint, const Vector3<T>& thirdPoint, T* hit = nullptr) const;
|
||||
|
||||
Ray& MakeAxisX();
|
||||
Ray& MakeAxisY();
|
||||
Ray& MakeAxisZ();
|
||||
|
||||
Ray& Set(T X, T Y, T Z, T directionX, T directionY, T directionZ);
|
||||
Ray& Set(const Vector3<T>& origin, const Vector3<T>& direction);
|
||||
Ray& Set(const T origin[3], const T direction[3]);
|
||||
Ray& Set(const Plane<T>& planeOne, const Plane<T>& planeTwo);
|
||||
Ray& Set(const Ray& ray);
|
||||
Ray& Set(const Vector3<T>& origin, const Vector3<T>& direction);
|
||||
template<typename U> Ray& Set(const Ray<U>& ray);
|
||||
template<typename U> Ray& Set(const Vector3<U>& origin, const Vector3<U>& direction);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,29 +10,77 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \class Nz::Ray<T>
|
||||
* \brief Math class that represents a ray or a straight line in 3D space
|
||||
*
|
||||
* This ray is meant to be understood like origin + lambda * direction, where lambda is a real positive parameter
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Ray<T> object from its position and direction
|
||||
*
|
||||
* \param X X position
|
||||
* \param Y Y position
|
||||
* \param Z Z position
|
||||
* \param DirectionX X component of the vector direction
|
||||
* \param DirectionY Y component of the vector direction
|
||||
* \param DirectionY Y component of the vector direction
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T>::Ray(T X, T Y, T Z, T DirectionX, T DirectionY, T DirectionZ)
|
||||
{
|
||||
Set(X, Y, Z, DirectionX, DirectionY, DirectionZ);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Ray<T> object from two Vector3
|
||||
*
|
||||
* \param Origin Vector which represents the origin of the ray
|
||||
* \param Direction Vector which represents the direction of the ray
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T>::Ray(const Vector3<T>& Origin, const Vector3<T>& Direction)
|
||||
{
|
||||
Set(Origin, Direction);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Ray<T> object from two arrays of three elements
|
||||
*
|
||||
* \param Origin[3] Origin[0] is X position, Origin[1] is Y position and Origin[2] is Z position
|
||||
* \param Direction[3] Direction[0] is X direction, Direction[1] is Y direction and Direction[2] is Z direction
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T>::Ray(const T Origin[3], const T Direction[3])
|
||||
{
|
||||
Set(Origin, Direction);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Ray<T> object from the intersection of two planes
|
||||
*
|
||||
* \param planeOne First plane
|
||||
* \param planeTwo Second secant plane
|
||||
*
|
||||
* \remark Produce a NazaraError if planes are parallel with NAZARA_MATH_SAFE defined
|
||||
* \throw std::domain_error if NAZARA_MATH_SAFE is defined and planes are parallel
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T>::Ray(const Plane<T>& planeOne, const Plane<T>& planeTwo)
|
||||
{
|
||||
Set(planeOne, planeTwo);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Ray<T>::Ray(const Vector3<T>& Origin, const Vector3<T>& Direction)
|
||||
{
|
||||
Set(Origin, Direction);
|
||||
}
|
||||
/*!
|
||||
* \brief Constructs a Ray<T> object from another type of Ray
|
||||
*
|
||||
* \param ray Ray of type U to convert to type T
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
|
|
@ -41,6 +89,13 @@ namespace Nz
|
|||
Set(ray);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Ray<T> object from two Vector3 from another type of Ray
|
||||
*
|
||||
* \param Origin Origin of type U to convert to type T
|
||||
* \param Direction Direction of type U to convert to type T
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Ray<T>::Ray(const Vector3<U>& Origin, const Vector3<U>& Direction)
|
||||
|
|
@ -48,6 +103,13 @@ namespace Nz
|
|||
Set(Origin, Direction);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Finds the closest point of the ray from point
|
||||
* \return The parameter where the point along this ray that is closest to the point provided
|
||||
*
|
||||
* \param point The point to get the closest approach to
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Ray<T>::ClosestPoint(const Vector3<T>& point) const
|
||||
{
|
||||
|
|
@ -58,12 +120,34 @@ namespace Nz
|
|||
return proj / vsq;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the point along the ray for this parameter
|
||||
* \return The point on the ray
|
||||
*
|
||||
* \param lambda Parameter to obtain a particular point on the ray
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector3<T> Ray<T>::GetPoint(T lambda) const
|
||||
{
|
||||
return origin + lambda * direction;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not this ray intersects with the BoundingVolume
|
||||
* \return true if it intersects
|
||||
*
|
||||
* \param volume BoundingVolume to check
|
||||
* \param closestHit Optional argument to get the closest parameter where the intersection is only if it happened
|
||||
* \param furthestHit Optional argument to get the furthest parameter where the intersection is only if it happened
|
||||
*
|
||||
* \remark If BoundingVolume is Extend_Infinite, then closestHit and furthestHit are equal to 0 et infinity
|
||||
* \remark If BoundingVolume is Extend_Null, then closestHit and furthestHit are unchanged
|
||||
* \remark If enumeration of BoundingVolume is not defined in Extend, a NazaraError is thrown and closestHit and furthestHit are unchanged
|
||||
*
|
||||
* \see Intersect
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Ray<T>::Intersect(const BoundingVolume<T>& volume, T* closestHit, T* furthestHit) const
|
||||
{
|
||||
|
|
@ -96,6 +180,17 @@ namespace Nz
|
|||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not this ray intersects with the Box
|
||||
* \return true if it intersects
|
||||
*
|
||||
* \param box Box to check
|
||||
* \param closestHit Optional argument to get the closest parameter where the intersection is only if it happened
|
||||
* \param furthestHit Optional argument to get the furthest parameter where the intersection is only if it happened
|
||||
*
|
||||
* \see Intersect
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Ray<T>::Intersect(const Box<T>& box, T* closestHit, T* furthestHit) const
|
||||
{
|
||||
|
|
@ -142,6 +237,18 @@ namespace Nz
|
|||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not this ray intersects with the transform Matrix4 applied to the Box
|
||||
* \return true if it intersects
|
||||
*
|
||||
* \param box Box to check
|
||||
* \param transform Matrix4 which represents the transformation of the box
|
||||
* \param closestHit Optional argument to get the closest parameter where the intersection is only if it happened
|
||||
* \param furthestHit Optional argument to get the furthest parameter where the intersection is only if it happened
|
||||
*
|
||||
* \see Intersect
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Ray<T>::Intersect(const Box<T>& box, const Matrix4<T>& transform, T* closestHit, T* furthestHit) const
|
||||
{
|
||||
|
|
@ -200,6 +307,17 @@ namespace Nz
|
|||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not this ray intersects with the OrientedBox
|
||||
* \return true if it intersects
|
||||
*
|
||||
* \param orientedBox OrientedBox to check
|
||||
* \param closestHit Optional argument to get the closest parameter where the intersection is only if it happened
|
||||
* \param furthestHit Optional argument to get the furthest parameter where the intersection is only if it happened
|
||||
*
|
||||
* \see Intersect
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Ray<T>::Intersect(const OrientedBox<T>& orientedBox, T* closestHit, T* furthestHit) const
|
||||
{
|
||||
|
|
@ -227,12 +345,22 @@ namespace Nz
|
|||
return tmpRay.Intersect(tmpBox, closestHit, furthestHit);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not this ray intersects with the plane
|
||||
* \return true if it intersects
|
||||
*
|
||||
* \param plane Plane to check
|
||||
* \param hit Optional argument to get the parameter where the intersection is only if it happened
|
||||
*
|
||||
* \see Intersect
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Ray<T>::Intersect(const Plane<T>& plane, T* hit) const
|
||||
{
|
||||
T divisor = plane.normal.DotProduct(direction);
|
||||
if (NumberEquals(divisor, F(0.0)))
|
||||
return false; // perpendicular
|
||||
return false; // Perpendicular
|
||||
|
||||
T lambda = -(plane.normal.DotProduct(origin) - plane.distance) / divisor; // The plane is ax + by + cz = d
|
||||
if (lambda < F(0.0))
|
||||
|
|
@ -244,6 +372,17 @@ namespace Nz
|
|||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not this ray intersects with the sphere
|
||||
* \return true if it intersects
|
||||
*
|
||||
* \param sphere Sphere to check
|
||||
* \param closestHit Optional argument to get the closest parameter where the intersection is only if it happened
|
||||
* \param furthestHit Optional argument to get the furthest parameter where the intersection is only if it happened
|
||||
*
|
||||
* \see Intersect
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Ray<T>::Intersect(const Sphere<T>& sphere, T* closestHit, T* furthestHit) const
|
||||
{
|
||||
|
|
@ -274,24 +413,102 @@ namespace Nz
|
|||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not this ray intersects with the triangle
|
||||
* \return true if it intersects
|
||||
*
|
||||
* \param firstPoint First vertex of the triangle
|
||||
* \param secondPoint Second vertex of the triangle
|
||||
* \param thirdPoint Third vertex of the triangle
|
||||
* \param hit Optional argument to get the parameter where the intersection is only if it happened
|
||||
*
|
||||
* \see Intersect
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Ray<T>::Intersect(const Vector3<T>& firstPoint, const Vector3<T>& secondPoint, const Vector3<T>& thirdPoint, T* hit) const
|
||||
{
|
||||
// https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
|
||||
Vector3<T> firstEdge = secondPoint - firstPoint;
|
||||
Vector3<T> secondEdge = thirdPoint - firstPoint;
|
||||
|
||||
Vector3<T> P = Vector3<T>::CrossProduct(direction, secondEdge);
|
||||
const T divisor = firstEdge.DotProduct(P);
|
||||
if (NumberEquals(divisor, F(0.0)))
|
||||
return false; // Ray lies in plane of triangle
|
||||
|
||||
Vector3<T> directionToPoint = origin - firstPoint;
|
||||
T u = directionToPoint.DotProduct(P) / divisor;
|
||||
if (u < F(0.0) || u > F(1.0))
|
||||
return 0; // The intersection lies outside of the triangle
|
||||
|
||||
Vector3<T> Q = Vector3<T>::CrossProduct(directionToPoint, firstEdge);
|
||||
T v = directionToPoint.DotProduct(Q) / divisor;
|
||||
if (v < F(0.0) || u + v > F(1.0))
|
||||
return 0; // The intersection lies outside of the triangle
|
||||
|
||||
T t = secondEdge.DotProduct(Q) / divisor;
|
||||
if (t > F(0.0))
|
||||
{
|
||||
if (hit)
|
||||
*hit = t;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the ray with position (0, 0, 0) and direction (1, 0, 0)
|
||||
* \return A reference to this ray with position (0, 0, 0) and direction (1, 0, 0)
|
||||
*
|
||||
* \see AxisX
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T>& Ray<T>::MakeAxisX()
|
||||
{
|
||||
return Set(Vector3<T>::Zero(), Vector3<T>::UnitX());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the ray with position (0, 0, 0) and direction (0, 1, 0)
|
||||
* \return A reference to this ray with position (0, 0, 0) and direction (0, 1, 0)
|
||||
*
|
||||
* \see AxisY
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T>& Ray<T>::MakeAxisY()
|
||||
{
|
||||
return Set(Vector3<T>::Zero(), Vector3<T>::UnitY());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the ray with position (0, 0, 0) and direction (0, 0, 1)
|
||||
* \return A reference to this ray with position (0, 0, 0) and direction (0, 0, 1)
|
||||
*
|
||||
* \see AxisZ
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T>& Ray<T>::MakeAxisZ()
|
||||
{
|
||||
return Set(Vector3<T>::Zero(), Vector3<T>::UnitZ());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the ray with position and direction
|
||||
* \return A reference to this ray
|
||||
*
|
||||
* \param X X position
|
||||
* \param Y Y position
|
||||
* \param Z Z position
|
||||
* \param DirectionX X component of the vector direction
|
||||
* \param DirectionY Y component of the vector direction
|
||||
* \param DirectionY Y component of the vector direction
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T>& Ray<T>::Set(T X, T Y, T Z, T directionX, T directionY, T directionZ)
|
||||
{
|
||||
|
|
@ -301,6 +518,31 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the ray with position and direction
|
||||
* \return A reference to this ray
|
||||
*
|
||||
* \param Origin Vector which represents the origin of the ray
|
||||
* \param Direction Vector which represents the direction of the ray
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T>& Ray<T>::Set(const Vector3<T>& Origin, const Vector3<T>& Direction)
|
||||
{
|
||||
direction = Direction;
|
||||
origin = Origin;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of this ray from two arrays of three elements
|
||||
* \return A reference to this ray
|
||||
*
|
||||
* \param Origin[3] Origin[0] is X position, Origin[1] is Y position and Origin[2] is Z position
|
||||
* \param Direction[3] Direction[0] is X direction, Direction[1] is Y direction and Direction[2] is Z direction
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T>& Ray<T>::Set(const T Origin[3], const T Direction[3])
|
||||
{
|
||||
|
|
@ -310,6 +552,17 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of this ray from the intersection of two planes
|
||||
* \return A reference to this ray
|
||||
*
|
||||
* \param planeOne First plane
|
||||
* \param planeTwo Second secant plane
|
||||
*
|
||||
* \remark Produce a NazaraError if planes are parallel with NAZARA_MATH_SAFE defined
|
||||
* \throw std::domain_error if NAZARA_MATH_SAFE is defined and planes are parallel
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T>& Ray<T>::Set(const Plane<T>& planeOne, const Plane<T>& planeTwo)
|
||||
{
|
||||
|
|
@ -321,7 +574,7 @@ namespace Nz
|
|||
#if NAZARA_MATH_SAFE
|
||||
if (NumberEquals(det, F(0.0)))
|
||||
{
|
||||
String error("Planes are parallel.");
|
||||
String error("Planes are parallel");
|
||||
|
||||
NazaraError(error);
|
||||
throw std::domain_error(error);
|
||||
|
|
@ -338,6 +591,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the ray with components from another
|
||||
* \return A reference to this ray
|
||||
*
|
||||
* \param ray The other ray
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T>& Ray<T>::Set(const Ray& ray)
|
||||
{
|
||||
|
|
@ -346,14 +606,12 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Ray<T>& Ray<T>::Set(const Vector3<T>& Origin, const Vector3<T>& Direction)
|
||||
{
|
||||
direction = Direction;
|
||||
origin = Origin;
|
||||
|
||||
return *this;
|
||||
}
|
||||
/*!
|
||||
* \brief Sets the components of the ray from another type of Ray
|
||||
* \return A reference to this ray
|
||||
*
|
||||
* \param ray Ray of type U to convert its components
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
|
|
@ -365,6 +623,14 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the ray from another type of Ray
|
||||
* \return A reference to this ray
|
||||
*
|
||||
* \param Origin Origin of type U to convert to type T
|
||||
* \param Direction Direction of type U to convert to type T
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Ray<T>& Ray<T>::Set(const Vector3<U>& Origin, const Vector3<U>& Direction)
|
||||
|
|
@ -375,6 +641,11 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gives a string representation
|
||||
* \return A string representation of the object: "Ray(origin: Vector3(origin.x, origin.y, origin.z), direction: Vector3(direction.x, direction.y, direction.z))"
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
String Ray<T>::ToString() const
|
||||
{
|
||||
|
|
@ -383,24 +654,54 @@ namespace Nz
|
|||
return ss << "Ray(origin: " << origin.ToString() << ", direction: " << direction.ToString() << ")";
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the direction ray with the lambda to get the point along the ray for this parameter
|
||||
* \return The point on the ray
|
||||
*
|
||||
* \param lambda Parameter to obtain a particular point on the ray
|
||||
*
|
||||
* \see GetPoint
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector3<T> Ray<T>::operator*(T lambda) const
|
||||
{
|
||||
return GetPoint(lambda);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the ray to other one
|
||||
* \return true if the ray are the same
|
||||
*
|
||||
* \param rec Other ray to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Ray<T>::operator==(const Ray& ray) const
|
||||
{
|
||||
return direction == ray.direction && origin == ray.origin;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the ray to other one
|
||||
* \return false if the ray are the same
|
||||
*
|
||||
* \param rec Other ray to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Ray<T>::operator!=(const Ray& ray) const
|
||||
{
|
||||
return !operator==(ray);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the ray (0, 0, 0), (1, 0, 0)
|
||||
* \return A ray with position (0, 0, 0) and direction (1, 0, 0)
|
||||
*
|
||||
* \see MakeAxisX
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T> Ray<T>::AxisX()
|
||||
{
|
||||
|
|
@ -410,6 +711,13 @@ namespace Nz
|
|||
return axis;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the ray (0, 0, 0), (0, 1, 0)
|
||||
* \return A ray with position (0, 0, 0) and direction (0, 1, 0)
|
||||
*
|
||||
* \see MakeAxisY
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T> Ray<T>::AxisY()
|
||||
{
|
||||
|
|
@ -419,6 +727,13 @@ namespace Nz
|
|||
return axis;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the ray (0, 0, 0), (0, 0, 1)
|
||||
* \return A ray with position (0, 0, 0) and direction (0, 0, 1)
|
||||
*
|
||||
* \see MakeAxisZ
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T> Ray<T>::AxisZ()
|
||||
{
|
||||
|
|
@ -428,13 +743,34 @@ namespace Nz
|
|||
return axis;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Interpolates the ray to other one with a factor of interpolation
|
||||
* \return A new ray which is the interpolation of two rectangles
|
||||
*
|
||||
* \param from Initial ray
|
||||
* \param to Target ray
|
||||
* \param interpolation Factor of interpolation
|
||||
*
|
||||
* \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior
|
||||
*
|
||||
* \see Lerp
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Ray<T> Ray<T>::Lerp(const Ray& from, const Ray& to, T interpolation)
|
||||
{
|
||||
return Ray<T>(from.origin.Lerp(to.origin, interpolation), from.direction.Lerp(to.direction, interpolation));
|
||||
return Ray<T>(Nz::Vector3<T>::Lerp(from.origin, to.origin, interpolation), Nz::Vector3<T>::Lerp(from.direction, to.direction, interpolation));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Output operator
|
||||
* \return The stream
|
||||
*
|
||||
* \param out The stream
|
||||
* \param ray The ray to output
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const Nz::Ray<T>& ray)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@ namespace Nz
|
|||
~Rect() = default;
|
||||
|
||||
bool Contains(T X, T Y) const;
|
||||
bool Contains(const Vector2<T>& point) const;
|
||||
bool Contains(const Rect& rect) const;
|
||||
bool Contains(const Vector2<T>& point) const;
|
||||
|
||||
Rect& ExtendTo(T X, T Y);
|
||||
Rect& ExtendTo(const Vector2<T>& point);
|
||||
Rect& ExtendTo(const Rect& rect);
|
||||
Rect& ExtendTo(const Vector2<T>& point);
|
||||
|
||||
Vector2<T> GetCenter() const;
|
||||
Vector2<T> GetCorner(RectCorner corner) const;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -12,36 +12,89 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \class Nz::Rect<T>
|
||||
* \brief Math class that represents an axis-aligned rectangle in two dimensions
|
||||
*
|
||||
* \remark The basis is said to be "left-hand". It means that with your left hand, the thumb is X positive, the index finger Y positive pointing to the bottom
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Rect<T> object from its width and height
|
||||
*
|
||||
* \param Width Width of the rectangle (following X)
|
||||
* \param Height Height of the rectangle (following Y)
|
||||
*
|
||||
* \remark Position will be (0, 0)
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>::Rect(T Width, T Height)
|
||||
{
|
||||
Set(Width, Height);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Rect<T> object from its position, width and height
|
||||
*
|
||||
* \param X X position
|
||||
* \param Y Y position
|
||||
* \param Width Width of the rectangle (following X)
|
||||
* \param Height Height of the rectangle (following Y)
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>::Rect(T X, T Y, T Width, T Height)
|
||||
{
|
||||
Set(X, Y, Width, Height);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Rect<T> object from an array of four elements
|
||||
*
|
||||
* \param vec[4] vec[0] is X position, vec[1] is Y position, vec[2] is width and vec[3] is height
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>::Rect(const T vec[4])
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Rect<T> object from a vector representing width and height
|
||||
*
|
||||
* \param lengths (Width, Height) of the rectangle
|
||||
*
|
||||
* \remark X and Y will be (0, 0)
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>::Rect(const Vector2<T>& lengths)
|
||||
{
|
||||
Set(lengths);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Rect<T> object from two vectors representing point of the space
|
||||
* (X, Y) will be the components minimum of the two vectors and the width and height will be the components maximum - minimum
|
||||
*
|
||||
* \param vec1 First point
|
||||
* \param vec2 Second point
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>::Rect(const Vector2<T>& vec1, const Vector2<T>& vec2)
|
||||
{
|
||||
Set(vec1, vec2);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Rect<T> object from another type of Rect
|
||||
*
|
||||
* \param rect Rect of type U to convert to type T
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Rect<T>::Rect(const Rect<U>& rect)
|
||||
|
|
@ -49,18 +102,31 @@ namespace Nz
|
|||
Set(rect);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Tests whether the rectangle contains the provided point inclusive of the edge of the rectangle
|
||||
* \return true if inclusive
|
||||
*
|
||||
* \param X X position of the point
|
||||
* \param Y Y position of the point
|
||||
*
|
||||
* \see Contains
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Rect<T>::Contains(T X, T Y) const
|
||||
{
|
||||
return X >= x && X <= x+width &&
|
||||
Y >= y && Y <= y+height;
|
||||
return X >= x && X <= (x + width) &&
|
||||
Y >= y && Y <= (y + height);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Rect<T>::Contains(const Vector2<T>& point) const
|
||||
{
|
||||
return Contains(point.x, point.y);
|
||||
}
|
||||
/*!
|
||||
* \brief Tests whether the rectangle contains the provided rectangle inclusive of the edge of the rectangle
|
||||
* \return true if inclusive
|
||||
*
|
||||
* \param rect Other rectangle to test
|
||||
*
|
||||
* \see Contains
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Rect<T>::Contains(const Rect<T>& rect) const
|
||||
|
|
@ -69,6 +135,31 @@ namespace Nz
|
|||
Contains(rect.x + rect.width, rect.y + rect.height);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Tests whether the rectangle contains the provided point inclusive of the edge of the rectangle
|
||||
* \return true if inclusive
|
||||
*
|
||||
* \param point Position of the point
|
||||
*
|
||||
* \see Contains
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Rect<T>::Contains(const Vector2<T>& point) const
|
||||
{
|
||||
return Contains(point.x, point.y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Extends the rectangle to contain the point in the boundary
|
||||
* \return A reference to this rectangle extended
|
||||
*
|
||||
* \param X X position of the point
|
||||
* \param Y Y position of the point
|
||||
*
|
||||
* \see ExtendTo
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::ExtendTo(T X, T Y)
|
||||
{
|
||||
|
|
@ -84,11 +175,14 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::ExtendTo(const Vector2<T>& point)
|
||||
{
|
||||
return ExtendTo(point.x, point.y);
|
||||
}
|
||||
/*!
|
||||
* \brief Extends the rectangle to contain the rectangle
|
||||
* \return A reference to this rectangle extended
|
||||
*
|
||||
* \param rect Other rectangle to contain
|
||||
*
|
||||
* \see ExtendTo
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::ExtendTo(const Rect& rect)
|
||||
|
|
@ -105,12 +199,41 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Extends the rectangle to contain the point in the boundary
|
||||
* \return A reference to this rectangle extended
|
||||
*
|
||||
* \param point Position of the point
|
||||
*
|
||||
* \see ExtendTo
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::ExtendTo(const Vector2<T>& point)
|
||||
{
|
||||
return ExtendTo(point.x, point.y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets a Vector2 for the center
|
||||
* \return The position of the center of the rectangle
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Rect<T>::GetCenter() const
|
||||
{
|
||||
return GetPosition() + GetLengths() / F(2.0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the Vector2 for the corner
|
||||
* \return The position of the corner of the rectangle according to enum RectCorner
|
||||
*
|
||||
* \param corner Enumeration of type RectCorner
|
||||
*
|
||||
* \remark If enumeration is not defined in RectCorner, a NazaraError is thrown and a Vector2 uninitialised is returned
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Rect<T>::GetCorner(RectCorner corner) const
|
||||
{
|
||||
|
|
@ -133,25 +256,52 @@ namespace Nz
|
|||
return Vector2<T>();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets a Vector2 for the lengths
|
||||
* \return The lengths of the rectangle (width, height)
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Rect<T>::GetLengths() const
|
||||
{
|
||||
return Vector2<T>(width, height);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets a Vector2 for the maximum point
|
||||
* \return The RectCorner_RightBottom of the rectangle
|
||||
*
|
||||
* \see GetCorner
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Rect<T>::GetMaximum() const
|
||||
{
|
||||
return GetPosition() + GetLengths();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets a Vector2 for the minimum point
|
||||
* \return The RectCorner_LeftTop of the rectangle
|
||||
*
|
||||
* \see GetCorner, GetPosition
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Rect<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 rectangle 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 or height corresponding to the sign
|
||||
*
|
||||
* \param normal Vector indicating a direction
|
||||
*
|
||||
* \see GetPositiveVertex
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Rect<T>::GetNegativeVertex(const Vector2<T>& normal) const
|
||||
{
|
||||
|
|
@ -166,12 +316,28 @@ namespace Nz
|
|||
return neg;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets a Vector2 for the position
|
||||
* \return The RectCorner_LeftTop of the rectangle
|
||||
*
|
||||
* \see GetCorner, GetMinimum
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Rect<T>::GetPosition() const
|
||||
{
|
||||
return Vector2<T>(x, y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Computes the positive vertex of one direction
|
||||
* \return The position of the vertex on the rectangle 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>
|
||||
Vector2<T> Rect<T>::GetPositiveVertex(const Vector2<T>& normal) const
|
||||
{
|
||||
|
|
@ -186,6 +352,14 @@ namespace Nz
|
|||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not this rectangle intersects another one
|
||||
* \return true if the rectangle intersects
|
||||
*
|
||||
* \param rect Rectangle to check
|
||||
* \param intersection Optional argument for the rectangle which represent the intersection
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Rect<T>::Intersect(const Rect& rect, Rect* intersection) const
|
||||
{
|
||||
|
|
@ -210,12 +384,24 @@ namespace Nz
|
|||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether this rectangle is valid
|
||||
* \return true if the rectangle has a strictly positive width and height
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Rect<T>::IsValid() const
|
||||
{
|
||||
return width > F(0.0) && height > F(0.0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the rectangle position (0, 0) and lengths (0, 0)
|
||||
* \return A reference to this box with position (0, 0) and lengths (0, 0)
|
||||
*
|
||||
* \see Zero
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::MakeZero()
|
||||
{
|
||||
|
|
@ -227,6 +413,16 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the rectangle with width and height
|
||||
* \return A reference to this rectangle
|
||||
*
|
||||
* \param Width Width of the rectangle (following X)
|
||||
* \param Height Height of the rectangle (following Y)
|
||||
*
|
||||
* \remark Position will be (0, 0)
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::Set(T Width, T Height)
|
||||
{
|
||||
|
|
@ -238,6 +434,16 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the rectangle
|
||||
* \return A reference to this rectangle
|
||||
*
|
||||
* \param X X position
|
||||
* \param Y Y position
|
||||
* \param Width Width of the rectangle (following X)
|
||||
* \param Height Height of the rectangle (following Y)
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::Set(T X, T Y, T Width, T Height)
|
||||
{
|
||||
|
|
@ -249,6 +455,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the rectangle from an array of four elements
|
||||
* \return A reference to this rectangle
|
||||
*
|
||||
* \param rect[4] rect[0] is X position, rect[1] is Y position, rect[2] is width and rect[3] is height
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::Set(const T rect[4])
|
||||
{
|
||||
|
|
@ -260,6 +473,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the rectangle with components from another
|
||||
* \return A reference to this rectangle
|
||||
*
|
||||
* \param rect The other Rect
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::Set(const Rect<T>& rect)
|
||||
{
|
||||
|
|
@ -268,12 +488,30 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the rectange from a vector representing width and height
|
||||
* \return A reference to this rectangle
|
||||
*
|
||||
* \param lengths (Width, Height) of the rectangle
|
||||
*
|
||||
* \remark Position will be (0, 0)
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::Set(const Vector2<T>& lengths)
|
||||
{
|
||||
return Set(lengths.x, lengths.y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets a Rect<T> object from two vectors representing point of the space
|
||||
* (X, Y) will be the components minimum of the two vectors and the width and height will be the components maximum - minimum
|
||||
* \return A reference to this rectangle
|
||||
*
|
||||
* \param vec1 First point
|
||||
* \param vec2 Second point
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::Set(const Vector2<T>& vec1, const Vector2<T>& vec2)
|
||||
{
|
||||
|
|
@ -285,6 +523,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the rectangle from another type of Rect
|
||||
* \return A reference to this rectangle
|
||||
*
|
||||
* \param rect Rectangle of type U to convert its components
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Rect<T>& Rect<T>::Set(const Rect<U>& rect)
|
||||
|
|
@ -297,6 +542,11 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gives a string representation
|
||||
* \return A string representation of the object: "Rect(x, y, width, height)"
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
String Rect<T>::ToString() const
|
||||
{
|
||||
|
|
@ -305,6 +555,13 @@ namespace Nz
|
|||
return ss << "Rect(" << x << ", " << y << ", " << width << ", " << height << ')';
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Translates the rectangle
|
||||
* \return A reference to this rectangle translated
|
||||
*
|
||||
* \param translation Vector2 which is the translation for the position
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::Translate(const Vector2<T>& translation)
|
||||
{
|
||||
|
|
@ -314,6 +571,15 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the ith element of the rectangle
|
||||
* \return A reference to the ith element of the rectangle
|
||||
*
|
||||
* \remark Access to index greather than 4 is undefined behavior
|
||||
* \remark Produce a NazaraError if you try to acces to index greather than 4 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 4
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T& Rect<T>::operator[](unsigned int i)
|
||||
{
|
||||
|
|
@ -331,6 +597,15 @@ namespace Nz
|
|||
return *(&x+i);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the ith element of the rectangle
|
||||
* \return A value to the ith element of the rectangle
|
||||
*
|
||||
* \remark Access to index greather than 4 is undefined behavior
|
||||
* \remark Produce a NazaraError if you try to acces to index greather than 4 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 4
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Rect<T>::operator[](unsigned int i) const
|
||||
{
|
||||
|
|
@ -348,30 +623,65 @@ namespace Nz
|
|||
return *(&x+i);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the lengths with the scalar
|
||||
* \return A rectangle where the position is the same and width and height are the product of the old width and height and the scalar
|
||||
*
|
||||
* \param scale The scalar to multiply width and height with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T> Rect<T>::operator*(T scalar) const
|
||||
{
|
||||
return Rect(x, y, width * scalar, height * scalar);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the lengths with the vector
|
||||
* \return A rectangle where the position is the same and width and height are the product of the old width and height with the vec
|
||||
*
|
||||
* \param vec The vector where component one multiply width and two height
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T> Rect<T>::operator*(const Vector2<T>& vec) const
|
||||
{
|
||||
return Rect(x, y, width*vec.x, height*vec.y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divides the lengths with the scalar
|
||||
* \return A rectangle where the position is the same and width and height are the quotient of the old width and height and the scalar
|
||||
*
|
||||
* \param scale The scalar to divide width and height with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T> Rect<T>::operator/(T scalar) const
|
||||
{
|
||||
return Rect(x, y, width/scalar, height/scalar);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divides the lengths with the vector
|
||||
* \return A rectangle where the position is the same and width and height are the quotient of the old width and height with the vec
|
||||
*
|
||||
* \param vec The vector where component one divide width and two height
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T> Rect<T>::operator/(const Vector2<T>& vec) const
|
||||
{
|
||||
return Rect(x, y, width/vec.x, height/vec.y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the lengths of this rectangle with the scalar
|
||||
* \return A reference to this rectangle where lengths are the product of these lengths and the scalar
|
||||
*
|
||||
* \param scalar The scalar to multiply width and height with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::operator*=(T scalar)
|
||||
{
|
||||
|
|
@ -381,6 +691,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the lengths of this rectangle with the vector
|
||||
* \return A reference to this rectangle where width and height are the product of the old width and height with the vec
|
||||
*
|
||||
* \param vec The vector where component one multiply width and two height
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::operator*=(const Vector2<T>& vec)
|
||||
{
|
||||
|
|
@ -390,6 +707,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divides the lengths of this rectangle with the scalar
|
||||
* \return A reference to this rectangle where lengths are the quotient of these lengths and the scalar
|
||||
*
|
||||
* \param scalar The scalar to divide width and height with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::operator/=(T scalar)
|
||||
{
|
||||
|
|
@ -399,6 +723,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divives the lengths of this rectangle with the vector
|
||||
* \return A reference to this rectangle where width and height are the quotient of the old width and height with the vec
|
||||
*
|
||||
* \param vec The vector where component one divide width and two height
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::operator/=(const Vector2<T>& vec)
|
||||
{
|
||||
|
|
@ -408,6 +739,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the rectangle to other one
|
||||
* \return true if the rectangles are the same
|
||||
*
|
||||
* \param rec Other rectangle to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Rect<T>::operator==(const Rect& rect) const
|
||||
{
|
||||
|
|
@ -415,12 +753,33 @@ namespace Nz
|
|||
NumberEquals(width, rect.width) && NumberEquals(height, rect.height);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the rectangle to other one
|
||||
* \return false if the rectangles are the same
|
||||
*
|
||||
* \param rec Other rectangle to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Rect<T>::operator!=(const Rect& rect) const
|
||||
{
|
||||
return !operator==(rect);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Interpolates the rectangle to other one with a factor of interpolation
|
||||
* \return A new rectangle which is the interpolation of two rectangles
|
||||
*
|
||||
* \param from Initial rectangle
|
||||
* \param to Target rectangle
|
||||
* \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>
|
||||
Rect<T> Rect<T>::Lerp(const Rect& from, const Rect& to, T interpolation)
|
||||
{
|
||||
|
|
@ -433,14 +792,21 @@ namespace Nz
|
|||
#endif
|
||||
|
||||
Rect rect;
|
||||
rect.x = Lerp(from.x, to.x, interpolation);
|
||||
rect.y = Lerp(from.y, to.y, interpolation);
|
||||
rect.width = Lerp(from.width, to.width, interpolation);
|
||||
rect.height = Lerp(from.height, to.height, interpolation);
|
||||
rect.x = Nz::Lerp(from.x, to.x, interpolation);
|
||||
rect.y = Nz::Lerp(from.y, to.y, interpolation);
|
||||
rect.width = Nz::Lerp(from.width, to.width, interpolation);
|
||||
rect.height = Nz::Lerp(from.height, to.height, interpolation);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the rectangle (0, 0, 0, 0)
|
||||
* \return A rectangle with position (0, 0) and lengths (0, 0)
|
||||
*
|
||||
* \see MakeZero
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Rect<T> Rect<T>::Zero()
|
||||
{
|
||||
|
|
@ -451,6 +817,14 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Output operator
|
||||
* \return The stream
|
||||
*
|
||||
* \param out The stream
|
||||
* \param rect The rectangle to output
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const Nz::Rect<T>& rect)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ namespace Nz
|
|||
|
||||
bool IsValid() const;
|
||||
|
||||
Sphere& MakeUnit();
|
||||
Sphere& MakeZero();
|
||||
|
||||
Sphere& Set(T X, T Y, T Z, T Radius);
|
||||
|
|
@ -71,6 +72,7 @@ namespace Nz
|
|||
bool operator!=(const Sphere& sphere) const;
|
||||
|
||||
static Sphere Lerp(const Sphere& from, const Sphere& to, T interpolation);
|
||||
static Sphere Unit();
|
||||
static Sphere Zero();
|
||||
|
||||
T x, y, z, radius;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,20 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \class Nz::Sphere<T>
|
||||
* \brief Math class that represents a sphere "S2" in a three dimensional euclidean space
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Sphere<T> object from its center position and radius
|
||||
*
|
||||
* \param X X position
|
||||
* \param Y Y position
|
||||
* \param Z Z position
|
||||
* \param Radius half of the diameter
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Sphere<T>::Sphere(T X, T Y, T Z, T Radius)
|
||||
{
|
||||
|
|
@ -25,18 +39,38 @@ namespace Nz
|
|||
Set(rect);
|
||||
}
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Sphere<T> object from its position and radius
|
||||
*
|
||||
* \param center Center of the sphere
|
||||
* \param Radius Half of the diameter
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Sphere<T>::Sphere(const Vector3<T>& center, T Radius)
|
||||
{
|
||||
Set(center, Radius);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Sphere<T> object from an array of four elements
|
||||
*
|
||||
* \param sphere[4] sphere[0] is X component, sphere[1] is Y component, sphere[2] is Z component and sphere[3] is radius
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Sphere<T>::Sphere(const T sphere[4])
|
||||
{
|
||||
Set(sphere);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Sphere<T> object from another type of Sphere
|
||||
*
|
||||
* \param sphere Sphere of type U to convert to type T
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Sphere<T>::Sphere(const Sphere<U>& sphere)
|
||||
|
|
@ -44,12 +78,32 @@ namespace Nz
|
|||
Set(sphere);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Tests whether the sphere contains the provided point inclusive of the edge of the sphere
|
||||
* \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 Sphere<T>::Contains(T X, T Y, T Z) const
|
||||
{
|
||||
return SquaredDistance(X, Y, Z) <= radius * radius;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Tests whether the sphere contains the provided box inclusive of the edge of the sphere
|
||||
* \return true if all inclusive
|
||||
*
|
||||
* \param box Three dimensional box
|
||||
*
|
||||
* \see Contains
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Sphere<T>::Contains(const Box<T>& box) const
|
||||
{
|
||||
|
|
@ -61,12 +115,31 @@ namespace Nz
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Tests whether the sphere contains the provided point inclusive of the edge of the sphere
|
||||
* \return true if inclusive
|
||||
*
|
||||
* \param point Position of the point
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Sphere<T>::Contains(const Vector3<T>& point) const
|
||||
{
|
||||
return Contains(point.x, point.y, point.z);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the distance from the center of the sphere to the point
|
||||
* \return Distance to the point
|
||||
*
|
||||
* \param X X position of the point
|
||||
* \param Y Y position of the point
|
||||
* \param Z Z position of the point
|
||||
*
|
||||
* \see SquaredDistance
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Sphere<T>::Distance(T X, T Y, T Z) const
|
||||
{
|
||||
|
|
@ -74,12 +147,32 @@ namespace Nz
|
|||
return distance.GetLength();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the distance from the center of the sphere to the point
|
||||
* \return Distance to the point
|
||||
*
|
||||
* \param point Position of the point
|
||||
*
|
||||
* \see SquaredDistance
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Sphere<T>::Distance(const Vector3<T>& point) const
|
||||
{
|
||||
return Distance(point.x, point.y, point.z);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Extends the sphere to contain the point in the boundary
|
||||
* \return A reference to this sphere 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>
|
||||
Sphere<T>& Sphere<T>::ExtendTo(T X, T Y, T Z)
|
||||
{
|
||||
|
|
@ -90,12 +183,30 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Extends the sphere to contain the point in the boundary
|
||||
* \return A reference to this sphere extended
|
||||
*
|
||||
* \param point Position of the point
|
||||
*
|
||||
* \see ExtendTo
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Sphere<T>& Sphere<T>::ExtendTo(const Vector3<T>& point)
|
||||
{
|
||||
return ExtendTo(point.x, point.y, point.z);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Computes the negative vertex of one direction
|
||||
* \return The position of the vertex on the sphere in the opposite way of the normal while considering the center
|
||||
*
|
||||
* \param normal Vector normalized indicating a direction
|
||||
*
|
||||
* \see GetPositiveVertex
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector3<T> Sphere<T>::GetNegativeVertex(const Vector3<T>& normal) const
|
||||
{
|
||||
|
|
@ -105,12 +216,26 @@ namespace Nz
|
|||
return neg;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets a Vector3 of the position
|
||||
* \return The position of the center of the sphere
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector3<T> Sphere<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 sphere in the same way of the normal while considering the center
|
||||
*
|
||||
* \param normal Vector normalized indicating a direction
|
||||
*
|
||||
* \see GetNegativeVertex
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector3<T> Sphere<T>::GetPositiveVertex(const Vector3<T>& normal) const
|
||||
{
|
||||
|
|
@ -120,6 +245,13 @@ namespace Nz
|
|||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not this sphere intersects a box
|
||||
* \return true if the box intersects
|
||||
*
|
||||
* \param box Box to check
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Sphere<T>::Intersect(const Box<T>& box) const
|
||||
{
|
||||
|
|
@ -161,18 +293,55 @@ namespace Nz
|
|||
return squaredDistance <= radius * radius;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not this sphere intersects another sphere
|
||||
* \return true if the spheres intersect or if one is in the other
|
||||
*
|
||||
* \param sphere Sphere to check
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Sphere<T>::Intersect(const Sphere& sphere) const
|
||||
{
|
||||
return SquaredDistance(sphere.x, sphere.y, sphere.z) - radius * radius <= sphere.radius * sphere.radius;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether this sphere is valid
|
||||
* \return true if the sphere has a strictly positive radius
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Sphere<T>::IsValid() const
|
||||
{
|
||||
return radius > F(0.0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the sphere position (0, 0, 0) and radius 1
|
||||
* \return A reference to this vector with position (0, 0, 0) and radius 1
|
||||
*
|
||||
* \see Unit
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Sphere<T>& Sphere<T>::MakeUnit()
|
||||
{
|
||||
x = F(0.0);
|
||||
y = F(0.0);
|
||||
z = F(0.0);
|
||||
radius = F(1.0);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the sphere position (0, 0, 0) and radius 0
|
||||
* \return A reference to this vector with position (0, 0, 0) and radius 0
|
||||
*
|
||||
* \see Zero
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Sphere<T>& Sphere<T>::MakeZero()
|
||||
{
|
||||
|
|
@ -184,6 +353,16 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the sphere with center and radius
|
||||
* \return A reference to this sphere
|
||||
*
|
||||
* \param X X position
|
||||
* \param Y Y position
|
||||
* \param Z Z position
|
||||
* \param Radius half of the diameter
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Sphere<T>& Sphere<T>::Set(T X, T Y, T Z, T Radius)
|
||||
{
|
||||
|
|
@ -195,6 +374,14 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the sphere with center and radius
|
||||
* \return A reference to this sphere
|
||||
*
|
||||
* \param center Center of the sphere
|
||||
* \param Radius Half of the diameter
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Sphere<T>& Sphere<T>::Set(const Vector3<T>& center, T Radius)
|
||||
{
|
||||
|
|
@ -217,6 +404,14 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the sphere with center and radius from another
|
||||
* \return A reference to this sphere
|
||||
*
|
||||
* \param sphere The other sphere
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Sphere<T>& Sphere<T>::Set(const Sphere& sphere)
|
||||
{
|
||||
|
|
@ -225,6 +420,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the sphere from an array of four elements
|
||||
* \return A reference to this sphere
|
||||
*
|
||||
* \param sphere[4] sphere[0] is X position, sphere[1] is Y position, sphere[2] is Z position and sphere[3] is radius
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Sphere<T>& Sphere<T>::Set(const T sphere[4])
|
||||
{
|
||||
|
|
@ -236,6 +438,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the sphere from another type of Sphere
|
||||
* \return A reference to this sphere
|
||||
*
|
||||
* \param sphere Sphere of type U to convert its components
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Sphere<T>& Sphere<T>::Set(const Sphere<U>& sphere)
|
||||
|
|
@ -248,6 +457,17 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the squared distance from the center of the sphere to the point
|
||||
* \return Squared distance to the point
|
||||
*
|
||||
* \param X X position of the point
|
||||
* \param Y Y position of the point
|
||||
* \param Z Z position of the point
|
||||
*
|
||||
* \see Distance
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Sphere<T>::SquaredDistance(T X, T Y, T Z) const
|
||||
{
|
||||
|
|
@ -255,12 +475,26 @@ namespace Nz
|
|||
return distance.GetSquaredLength();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the squared distance from the center of the sphere to the point
|
||||
* \return Squared distance to the point
|
||||
*
|
||||
* \param point Position of the point
|
||||
*
|
||||
* \see Distance
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Sphere<T>::SquaredDistance(const Vector3<T>& point) const
|
||||
{
|
||||
return SquaredDistance(point.x, point.y, point.z);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gives a string representation
|
||||
* \return A string representation of the object: "Sphere(x, y, z; radius)"
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
String Sphere<T>::ToString() const
|
||||
{
|
||||
|
|
@ -269,6 +503,15 @@ namespace Nz
|
|||
return ss << "Sphere(" << x << ", " << y << ", " << z << "; " << radius << ')';
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the ith element of the sphere
|
||||
* \return A reference to the ith element of the sphere
|
||||
*
|
||||
* \remark Access to index greather than 4 is undefined behavior
|
||||
* \remark Produce a NazaraError if you try to acces to index greather than 4 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 4
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T& Sphere<T>::operator[](unsigned int i)
|
||||
{
|
||||
|
|
@ -286,6 +529,15 @@ namespace Nz
|
|||
return *(&x+i);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the ith element of the sphere
|
||||
* \return A value to the ith element of the sphere
|
||||
*
|
||||
* \remark Access to index greather than 4 is undefined behavior
|
||||
* \remark Produce a NazaraError if you try to acces to index greather than 4 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 4
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Sphere<T>::operator[](unsigned int i) const
|
||||
{
|
||||
|
|
@ -303,18 +555,39 @@ namespace Nz
|
|||
return *(&x+i);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the radius of the sphere with a scalar
|
||||
* \return A sphere where the center is the same and radius is the product of this radius and the scalar
|
||||
*
|
||||
* \param scale The scalar to multiply radius with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Sphere<T> Sphere<T>::operator*(T scalar) const
|
||||
{
|
||||
return Sphere(x, y, z, radius * scalar);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the radius of other sphere with a scalar
|
||||
* \return A reference to this sphere where the center is the same and radius is the product of this radius and the scalar
|
||||
*
|
||||
* \param scale The scalar to multiply radius with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Sphere<T>& Sphere<T>::operator*=(T scalar)
|
||||
{
|
||||
radius *= scalar;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the sphere to other one
|
||||
* \return true if the spheres are the same
|
||||
*
|
||||
* \param sphere Other sphere to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Sphere<T>::operator==(const Sphere& sphere) const
|
||||
{
|
||||
|
|
@ -322,12 +595,49 @@ namespace Nz
|
|||
NumberEquals(radius, sphere.radius);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the sphere to other one
|
||||
* \return false if the spheres are the same
|
||||
*
|
||||
* \param sphere Other sphere to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Sphere<T>::operator!=(const Sphere& sphere) const
|
||||
{
|
||||
return !operator==(sphere);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the sphere (0, 0, 0, 1)
|
||||
* \return A sphere with center (0, 0, 0) and radius 1
|
||||
*
|
||||
* \see MakeUnit
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Sphere<T> Sphere<T>::Unit()
|
||||
{
|
||||
Sphere sphere;
|
||||
sphere.MakeUnit();
|
||||
|
||||
return sphere;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Interpolates the sphere to other one with a factor of interpolation
|
||||
* \return A new sphere which is the interpolation of two spheres
|
||||
*
|
||||
* \param from Initial sphere
|
||||
* \param to Target sphere
|
||||
* \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>
|
||||
Sphere<T> Sphere<T>::Lerp(const Sphere& from, const Sphere& to, T interpolation)
|
||||
{
|
||||
|
|
@ -340,14 +650,21 @@ namespace Nz
|
|||
#endif
|
||||
|
||||
Sphere sphere;
|
||||
sphere.x = Lerp(from.x, to.x, interpolation);
|
||||
sphere.y = Lerp(from.y, to.y, interpolation);
|
||||
sphere.z = Lerp(from.z, to.z, interpolation);
|
||||
sphere.radius = Lerp(from.radius, to.radius, interpolation);
|
||||
sphere.x = Nz::Lerp(from.x, to.x, interpolation);
|
||||
sphere.y = Nz::Lerp(from.y, to.y, interpolation);
|
||||
sphere.z = Nz::Lerp(from.z, to.z, interpolation);
|
||||
sphere.radius = Nz::Lerp(from.radius, to.radius, interpolation);
|
||||
|
||||
return sphere;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the sphere (0, 0, 0, 0)
|
||||
* \return A sphere with center (0, 0, 0) and radius 0
|
||||
*
|
||||
* \see MakeZero
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Sphere<T> Sphere<T>::Zero()
|
||||
{
|
||||
|
|
@ -358,6 +675,14 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Output operator
|
||||
* \return The stream
|
||||
*
|
||||
* \param out The stream
|
||||
* \param sphere The sphere to output
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const Nz::Sphere<T>& sphere)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -89,7 +89,9 @@ namespace Nz
|
|||
bool operator>(const Vector2& vec) const;
|
||||
bool operator>=(const Vector2& vec) const;
|
||||
|
||||
static T DotProduct(const Vector2& vec1, const Vector2& vec2);
|
||||
static Vector2 Lerp(const Vector2& from, const Vector2& to, T interpolation);
|
||||
static Vector2 Normalize(const Vector2& vec);
|
||||
static Vector2 Unit();
|
||||
static Vector2 UnitX();
|
||||
static Vector2 UnitY();
|
||||
|
|
|
|||
|
|
@ -13,24 +13,54 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \class Nz::Vector2<T>
|
||||
* \brief Math class that represents an element of the two dimensional vector space
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Vector2<T> object from its coordinates
|
||||
*
|
||||
* \param X X component
|
||||
* \param Y Y component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>::Vector2(T X, T Y)
|
||||
{
|
||||
Set(X, Y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs explicitely a Vector2<T> object from its "scale"
|
||||
*
|
||||
* \param scale X component = Y component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>::Vector2(T scale)
|
||||
{
|
||||
Set(scale);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Vector2<T> object from an array of two elements
|
||||
*
|
||||
* \param vec[2] vec[0] is X component and vec[1] is Y component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>::Vector2(const T vec[2])
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Vector2<T> object from another type of Vector2
|
||||
*
|
||||
* \param vec Vector of type U to convert to type T
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Vector2<T>::Vector2(const Vector2<U>& vec)
|
||||
|
|
@ -38,60 +68,140 @@ namespace Nz
|
|||
Set(vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Vector2<T> object from a Vector3
|
||||
*
|
||||
* \param vec Vector3 where only the first two components are taken
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>::Vector2(const Vector3<T>& vec)
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Vector2<T> object from a Vector4
|
||||
*
|
||||
* \param vec Vector4 where only the first two components are taken
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>::Vector2(const Vector4<T>& vec)
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the absolute dot (scalar) product with two vectors
|
||||
* \return The dot product with absolutes values on each component
|
||||
*
|
||||
* \param vec The other vector to calculate the absolute dot product with
|
||||
*
|
||||
* \see DotProduct
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Vector2<T>::AbsDotProduct(const Vector2& vec) const
|
||||
{
|
||||
return std::abs(x * vec.x) + std::abs(y * vec.y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the angle between two vectors in orthonormal basis
|
||||
* \return The angle unit depends of NAZARA_MATH_ANGLE_RADIAN, you may want to normalize it to the range 0..2*pi with NormalizeAngle
|
||||
*
|
||||
* \param vec The other vector to measure the angle with
|
||||
*
|
||||
* \remark The vectors do not need to be normalised and if the angle is normalised, it represents the rotation from *this to vec in anti-clockwise direction
|
||||
*
|
||||
* \see NormalizeAngle
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Vector2<T>::AngleBetween(const Vector2& vec) const
|
||||
{
|
||||
return FromRadians(std::atan2(vec.y, vec.x) - std::atan2(y, x));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the distance between two vectors
|
||||
* \return The metric distance between two vectors with euclidean norm
|
||||
*
|
||||
* \param vec The other vector to measure the distance with
|
||||
*
|
||||
* \see SquaredDistance
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Vector2<T>::Distance(const Vector2& vec) const
|
||||
{
|
||||
return std::sqrt(SquaredDistance(vec));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the distance between two vectors
|
||||
* \return The metric distance in float between two vectors with euclidean norm
|
||||
*
|
||||
* \param vec The other vector to measure the distance with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
float Vector2<T>::Distancef(const Vector2& vec) const
|
||||
{
|
||||
return std::sqrt(static_cast<float>(SquaredDistance(vec)));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the dot (scalar) product with two vectors
|
||||
* \return The value of the dot product
|
||||
*
|
||||
* \param vec The other vector to calculate the dot product with
|
||||
*
|
||||
* \see AbsDotProduct, DotProduct
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Vector2<T>::DotProduct(const Vector2& vec) const
|
||||
{
|
||||
return x*vec.x + y*vec.y;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the length (magnitude) of the vector
|
||||
* \return The length of the vector
|
||||
*
|
||||
* \see GetSquaredLength
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Vector2<T>::GetLength() const
|
||||
{
|
||||
return std::sqrt(GetSquaredLength());
|
||||
return static_cast<T>(std::sqrt(GetSquaredLength()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the length (magnitude) of the vector
|
||||
* \return The length in float of the vector
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
float Vector2<T>::GetLengthf() const
|
||||
{
|
||||
return std::sqrt(static_cast<float>(GetSquaredLength()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets a copy normalized of the vector
|
||||
* \return A new vector which is the vector normalized
|
||||
*
|
||||
* \param length Optional argument to obtain the length's ratio of the vector and the unit-length
|
||||
*
|
||||
* \remark If this vector is (0, 0), then it returns (0, 0) and length is 0
|
||||
*
|
||||
* \see Normalize
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Vector2<T>::GetNormal(T* length) const
|
||||
{
|
||||
|
|
@ -101,36 +211,80 @@ namespace Nz
|
|||
return vec;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the squared length (magnitude) of the vector
|
||||
* \return The squared length of the vector
|
||||
*
|
||||
* \see GetLength
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Vector2<T>::GetSquaredLength() const
|
||||
{
|
||||
return x*x + y*y;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the vector (1, 1)
|
||||
* \return A reference to this vector with components (1, 1)
|
||||
*
|
||||
* \see Unit
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::MakeUnit()
|
||||
{
|
||||
return Set(F(1.0), F(1.0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the vector (1, 0)
|
||||
* \return A reference to this vector with components (1, 0)
|
||||
*
|
||||
* \see UnitX
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::MakeUnitX()
|
||||
{
|
||||
return Set(F(1.0), F(0.0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the vector (0, 1)
|
||||
* \return A reference to this vector with components (0, 1)
|
||||
*
|
||||
* \see UnitY
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::MakeUnitY()
|
||||
{
|
||||
return Set(F(0.0), F(1.0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the vector (0, 0)
|
||||
* \return A reference to this vector with components (0, 0)
|
||||
*
|
||||
* \see Zero
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::MakeZero()
|
||||
{
|
||||
return Set(F(0.0), F(0.0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets this vector's components to the maximum of its own and other components
|
||||
* \return A reference to this vector with replaced values with the corresponding max value
|
||||
*
|
||||
* \param vec Other vector to compare the components with
|
||||
*
|
||||
* \see Minimize
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::Maximize(const Vector2& vec)
|
||||
{
|
||||
|
|
@ -143,6 +297,15 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets this vector's components to the minimum of its own and other components
|
||||
* \return A reference to this vector with replaced values with the corresponding min value
|
||||
*
|
||||
* \param vec Other vector to compare the components with
|
||||
*
|
||||
* \see Maximize
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::Minimize(const Vector2& vec)
|
||||
{
|
||||
|
|
@ -155,6 +318,17 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Normalizes the current vector
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param length Optional argument to obtain the length's ratio of the vector and the unit-length
|
||||
*
|
||||
* \remark If the vector is (0, 0), then it returns (0, 0) and length is 0
|
||||
*
|
||||
* \see GetNormal
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::Normalize(T* length)
|
||||
{
|
||||
|
|
@ -172,6 +346,14 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param X X component
|
||||
* \param Y Y component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::Set(T X, T Y)
|
||||
{
|
||||
|
|
@ -181,6 +363,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector from a "scale"
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param scale X component = Y component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::Set(T scale)
|
||||
{
|
||||
|
|
@ -190,6 +379,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector from an array of two elements
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param vec[2] vec[0] is X component and vec[1] is Y component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::Set(const T vec[2])
|
||||
{
|
||||
|
|
@ -198,6 +394,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector from another vector
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param vec The other vector
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::Set(const Vector2& vec)
|
||||
{
|
||||
|
|
@ -206,6 +409,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector from another type of Vector2
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param vec Vector of type U to convert its components
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Vector2<T>& Vector2<T>::Set(const Vector2<U>& vec)
|
||||
|
|
@ -216,6 +426,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector from a Vector3
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param vec Vector3 where only the first two components are taken
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::Set(const Vector3<T>& vec)
|
||||
{
|
||||
|
|
@ -225,6 +442,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector from a Vector4
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param vec Vector4 where only the first two components are taken
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::Set(const Vector4<T>& vec)
|
||||
{
|
||||
|
|
@ -234,12 +458,26 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the squared distance between two vectors
|
||||
* \return The metric distance between two vectors with the squared euclidean norm
|
||||
*
|
||||
* \param vec The other vector to measure the distance with
|
||||
*
|
||||
* \see Distance
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Vector2<T>::SquaredDistance(const Vector2& vec) const
|
||||
{
|
||||
return (*this - vec).GetSquaredLength();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gives a string representation
|
||||
* \return A string representation of the object: "Vector2(x, y)"
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
String Vector2<T>::ToString() const
|
||||
{
|
||||
|
|
@ -248,54 +486,116 @@ namespace Nz
|
|||
return ss << "Vector2(" << x << ", " << y << ')';
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts vector to pointer to its own data
|
||||
* \return A pointer to the own data
|
||||
*
|
||||
* \remark Access to index greather than 1 is undefined behavior
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>::operator T* ()
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts vector to const pointer to its own data
|
||||
* \return A constant pointer to the own data
|
||||
*
|
||||
* \remark Access to index greather than 1 is undefined behavior
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>::operator const T* () const
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Helps to represent the sign of the vector
|
||||
* \return A constant reference to this vector
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
const Vector2<T>& Vector2<T>::operator+() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Negates the components of the vector
|
||||
* \return A constant reference to this vector with negate components
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Vector2<T>::operator-() const
|
||||
{
|
||||
return Vector2(-x, -y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds the components of the vector with other vector
|
||||
* \return A vector where components are the sum of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to add components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Vector2<T>::operator+(const Vector2& vec) const
|
||||
{
|
||||
return Vector2(x + vec.x, y + vec.y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Substracts the components of the vector with other vector
|
||||
* \return A vector where components are the difference of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to substract components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Vector2<T>::operator-(const Vector2& vec) const
|
||||
{
|
||||
return Vector2(x - vec.x, y - vec.y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the components of the vector with other vector
|
||||
* \return A vector where components are the product of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to multiply components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Vector2<T>::operator*(const Vector2& vec) const
|
||||
{
|
||||
return Vector2(x * vec.x, y * vec.y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the components of the vector with a scalar
|
||||
* \return A vector where components are the product of this vector and the scalar
|
||||
*
|
||||
* \param scale The scalar to multiply components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Vector2<T>::operator*(T scale) const
|
||||
{
|
||||
return Vector2(x * scale, y * scale);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divides the components of the vector with other vector
|
||||
* \return A vector where components are the quotient of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to divide components with
|
||||
*
|
||||
* \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined
|
||||
* \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Vector2<T>::operator/(const Vector2& vec) const
|
||||
{
|
||||
|
|
@ -312,6 +612,16 @@ namespace Nz
|
|||
return Vector2(x / vec.x, y / vec.y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divides the components of the vector with a scalar
|
||||
* \return A vector where components are the quotient of this vector and the scalar
|
||||
*
|
||||
* \param scale The scalar to divide components with
|
||||
*
|
||||
* \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined
|
||||
* \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Vector2<T>::operator/(T scale) const
|
||||
{
|
||||
|
|
@ -328,6 +638,13 @@ namespace Nz
|
|||
return Vector2(x / scale, y / scale);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds the components of other vector to this vector
|
||||
* \return A reference to this vector where components are the sum of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to add components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::operator+=(const Vector2& vec)
|
||||
{
|
||||
|
|
@ -337,6 +654,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Substracts the components of other vector to this vector
|
||||
* \return A reference to this vector where components are the difference of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to substract components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::operator-=(const Vector2& vec)
|
||||
{
|
||||
|
|
@ -346,6 +670,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the components of other vector to this vector
|
||||
* \return A reference to this vector where components are the product of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to multiply components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::operator*=(const Vector2& vec)
|
||||
{
|
||||
|
|
@ -355,6 +686,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the components of other vector with a scalar
|
||||
* \return A reference to this vector where components are the product of this vector and the scalar
|
||||
*
|
||||
* \param vec The other vector to multiply components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::operator*=(T scale)
|
||||
{
|
||||
|
|
@ -364,6 +702,16 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the components of other vector to this vector
|
||||
* \return A reference to this vector where components are the quotient of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to multiply components with
|
||||
*
|
||||
* \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined
|
||||
* \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::operator/=(const Vector2& vec)
|
||||
{
|
||||
|
|
@ -383,6 +731,16 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divides the components of other vector with a scalar
|
||||
* \return A reference to this vector where components are the quotient of this vector and the scalar
|
||||
*
|
||||
* \param vec The other vector to divide components with
|
||||
*
|
||||
* \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined
|
||||
* \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T>& Vector2<T>::operator/=(T scale)
|
||||
{
|
||||
|
|
@ -402,6 +760,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the vector to other one
|
||||
* \return true if the vectors are the same
|
||||
*
|
||||
* \param vec Other vector to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Vector2<T>::operator==(const Vector2& vec) const
|
||||
{
|
||||
|
|
@ -409,12 +774,26 @@ namespace Nz
|
|||
NumberEquals(y, vec.y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the vector to other one
|
||||
* \return false if the vectors are the same
|
||||
*
|
||||
* \param vec Other vector to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Vector2<T>::operator!=(const Vector2& vec) const
|
||||
{
|
||||
return !operator==(vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the vector to other one
|
||||
* \return true if this vector has its first components inferior to the other ones
|
||||
*
|
||||
* \param vec Other vector to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Vector2<T>::operator<(const Vector2& vec) const
|
||||
{
|
||||
|
|
@ -424,6 +803,13 @@ namespace Nz
|
|||
return x < vec.x;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the vector to other one
|
||||
* \return true if this vector has its first components inferior or equal to the other ones
|
||||
*
|
||||
* \param vec Other vector to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Vector2<T>::operator<=(const Vector2& vec) const
|
||||
{
|
||||
|
|
@ -433,24 +819,95 @@ namespace Nz
|
|||
return x < vec.x;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the vector to other one
|
||||
* \return true if this vector has its first components superior to the other ones
|
||||
*
|
||||
* \param vec Other vector to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Vector2<T>::operator>(const Vector2& vec) const
|
||||
{
|
||||
return !operator<=(vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the vector to other one
|
||||
* \return true if this vector has its first components superior or equal to the other ones
|
||||
*
|
||||
* \param vec Other vector to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Vector2<T>::operator>=(const Vector2& vec) const
|
||||
{
|
||||
return !operator<(vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the dot (scalar) product with two vectors
|
||||
* \return The value of the dot product
|
||||
*
|
||||
* \param vec1 The first vector to calculate the dot product with
|
||||
* \param vec2 The second vector to calculate the dot product with
|
||||
*
|
||||
* \see AbsDotProduct, DotProduct
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Vector2<T>::DotProduct(const Vector2& vec1, const Vector2& vec2)
|
||||
{
|
||||
return vec1.DotProduct(vec2);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Interpolates the vector to other one with a factor of interpolation
|
||||
* \return A new vector which is the interpolation of two vectors
|
||||
*
|
||||
* \param from Initial vector
|
||||
* \param to Target vector
|
||||
* \param interpolation Factor of interpolation
|
||||
*
|
||||
* \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior
|
||||
*
|
||||
* \see Lerp
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Vector2<T>::Lerp(const Vector2& from, const Vector2& to, T interpolation)
|
||||
{
|
||||
return Lerp(from, to, interpolation);
|
||||
Vector2 dummy;
|
||||
dummy.x = Nz::Lerp(from.x, to.x, interpolation);
|
||||
dummy.y = Nz::Lerp(from.y, to.y, interpolation);
|
||||
|
||||
return dummy;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gives the normalized vector
|
||||
* \return A normalized vector from the vec
|
||||
*
|
||||
* \param vec Vector to normalize
|
||||
*
|
||||
* \remark If the vector is (0, 0), then it returns (0, 0)
|
||||
*
|
||||
* \see GetNormal
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Vector2<T>::Normalize(const Vector2& vec)
|
||||
{
|
||||
return vec.GetNormal();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the vector (1, 1)
|
||||
* \return A vector with components (1, 1)
|
||||
*
|
||||
* \see MakeUnit
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Vector2<T>::Unit()
|
||||
{
|
||||
|
|
@ -460,6 +917,13 @@ namespace Nz
|
|||
return vector;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the vector (1, 0)
|
||||
* \return A vector with components (1, 0)
|
||||
*
|
||||
* \see MakeUnitX
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Vector2<T>::UnitX()
|
||||
{
|
||||
|
|
@ -469,6 +933,13 @@ namespace Nz
|
|||
return vector;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the vector (0, 1)
|
||||
* \return A vector with components (0, 1)
|
||||
*
|
||||
* \see MakeUnitY
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Vector2<T>::UnitY()
|
||||
{
|
||||
|
|
@ -478,6 +949,13 @@ namespace Nz
|
|||
return vector;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the vector (0, 0)
|
||||
* \return A vector with components (0, 0)
|
||||
*
|
||||
* \see MakeZero
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector2<T> Vector2<T>::Zero()
|
||||
{
|
||||
|
|
@ -488,18 +966,43 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Output operator
|
||||
* \return The stream
|
||||
*
|
||||
* \param out The stream
|
||||
* \param vec The vector to output
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const Nz::Vector2<T>& vec)
|
||||
{
|
||||
return out << vec.ToString();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the components of the vector with a scalar
|
||||
* \return A vector where components are the product of this vector and the scalar
|
||||
*
|
||||
* \param scale The scalar to multiply components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Nz::Vector2<T> operator*(T scale, const Nz::Vector2<T>& vec)
|
||||
{
|
||||
return Nz::Vector2<T>(scale * vec.x, scale * vec.y);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divides the components of the vector with a scalar
|
||||
* \return A vector where components are the quotient of this vector and the scalar
|
||||
*
|
||||
* \param scale The scalar to divide components with
|
||||
*
|
||||
* \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined
|
||||
* \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Nz::Vector2<T> operator/(T scale, const Nz::Vector2<T>& vec)
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -87,6 +87,9 @@ namespace Nz
|
|||
bool operator>(const Vector4& vec) const;
|
||||
bool operator>=(const Vector4& vec) const;
|
||||
|
||||
static T DotProduct(const Vector4& vec1, const Vector4& vec2);
|
||||
static Vector4 Lerp(const Vector4& from, const Vector4& to, T interpolation);
|
||||
static Vector4 Normalize(const Vector4& vec);
|
||||
static Vector4 UnitX();
|
||||
static Vector4 UnitY();
|
||||
static Vector4 UnitZ();
|
||||
|
|
|
|||
|
|
@ -14,54 +14,125 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
|
||||
/*!
|
||||
* \class Nz::Vector4<T>
|
||||
* \brief Math class that represents an element of the three dimensional vector space with the notion of projectivity. When the fourth component is 1, it describes an 'usual' point and when it is 0, it represents the point at infinity
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Vector4<T> object from its coordinates
|
||||
*
|
||||
* \param X X component
|
||||
* \param Y Y component
|
||||
* \param Z Z component
|
||||
* \param W W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>::Vector4(T X, T Y, T Z, T W)
|
||||
{
|
||||
Set(X, Y, Z, W);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Vector4<T> object from two components and a Vector2<T>
|
||||
*
|
||||
* \param X X component
|
||||
* \param Y Y component
|
||||
* \param vec vec.X = Z component and vec.y = W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>::Vector4(T X, T Y, const Vector2<T>& vec)
|
||||
{
|
||||
Set(X, Y, vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Vector4<T> object from one component, a Vector2<T> and one component
|
||||
*
|
||||
* \param X X component
|
||||
* \param vec vec.X = Y component and vec.y = Z component
|
||||
* \param W W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>::Vector4(T X, const Vector2<T>& vec, T W)
|
||||
{
|
||||
Set(X, vec, W);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Vector4<T> object from one component and a Vector3<T>
|
||||
*
|
||||
* \param X X component
|
||||
* \param vec vec.X = Y component, vec.y = Z component and vec.z = W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>::Vector4(T X, const Vector3<T>& vec)
|
||||
{
|
||||
Set(X, vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs explicitely a Vector4<T> object from its "scale"
|
||||
*
|
||||
* \param scale X component = Y component = Z component = W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>::Vector4(T scale)
|
||||
{
|
||||
Set(scale);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Vector4<T> object from an array of four elements
|
||||
*
|
||||
* \param vec[4] vec[0] is X component, vec[1] is Y component, vec[2] is Z component and vec[3] is W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>::Vector4(const T vec[4])
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Vector4<T> object from a Vector2<T> and two components
|
||||
*
|
||||
* \param vec vec.X = X component and vec.y = Y component
|
||||
* \param Z Z component
|
||||
* \param W W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>::Vector4(const Vector2<T>& vec, T Z, T W)
|
||||
{
|
||||
Set(vec, Z, W);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Vector4<T> object from one component and a Vector3<T>
|
||||
*
|
||||
* \param vec vec.X = X component, vec.y = Y component and vec.z = Z component
|
||||
* \param W W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>::Vector4(const Vector3<T>& vec, T W)
|
||||
{
|
||||
Set(vec, W);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Vector4<T> object from another type of Vector4
|
||||
*
|
||||
* \param vec Vector of type U to convert to type T
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Vector4<T>::Vector4(const Vector4<U>& vec)
|
||||
|
|
@ -69,18 +140,45 @@ namespace Nz
|
|||
Set(vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the absolute dot (scalar) product with two vectors
|
||||
* \return The dot product with absolutes values on each component
|
||||
*
|
||||
* \param vec The other vector to calculate the absolute dot product with
|
||||
*
|
||||
* \see DotProduct
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Vector4<T>::AbsDotProduct(const Vector4& vec) const
|
||||
{
|
||||
return std::abs(x * vec.x) + std::abs(y * vec.y) + std::abs(z * vec.z) + std::abs(w * vec.w);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the dot (scalar) product with two vectors
|
||||
* \return The value of the dot product
|
||||
*
|
||||
* \param vec The other vector to calculate the dot product with
|
||||
*
|
||||
* \see AbsDotProduct, DotProduct
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Vector4<T>::DotProduct(const Vector4& vec) const
|
||||
{
|
||||
return x*vec.x + y*vec.y + z*vec.z + w*vec.w;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets a copy normalized of the vector
|
||||
* \return A new vector which is the vector normalized
|
||||
*
|
||||
* \param length Optional argument to obtain the length's ratio of the vector and the unit-length in this case w
|
||||
*
|
||||
* \see Normalize
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T> Vector4<T>::GetNormal(T* length) const
|
||||
{
|
||||
|
|
@ -90,30 +188,67 @@ namespace Nz
|
|||
return vec;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the vector (1, 0, 0, 1)
|
||||
* \return A reference to this vector with components (1, 0, 0, 1)
|
||||
*
|
||||
* \see UnitX
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::MakeUnitX()
|
||||
{
|
||||
return Set(F(1.0), F(0.0), F(0.0), F(1.0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the vector (0, 1, 0, 1)
|
||||
* \return A reference to this vector with components (0, 1, 0, 1)
|
||||
*
|
||||
* \see UnitY
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::MakeUnitY()
|
||||
{
|
||||
return Set(F(0.0), F(1.0), F(0.0), F(1.0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the vector (0, 0, 1, 1)
|
||||
* \return A reference to this vector with components (0, 0, 1, 1)
|
||||
*
|
||||
* \see UnitZ
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::MakeUnitZ()
|
||||
{
|
||||
return Set(F(0.0), F(0.0), F(1.0), F(1.0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes the vector (0, 0, 0, 1)
|
||||
* \return A reference to this vector with components (0, 0, 0, 1)
|
||||
*
|
||||
* \see Zero
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::MakeZero()
|
||||
{
|
||||
return Set(F(0.0), F(0.0), F(0.0), F(0.0));
|
||||
return Set(F(0.0), F(0.0), F(0.0), F(1.0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets this vector's components to the maximum of its own and other components
|
||||
* \return A reference to this vector with replaced values with the corresponding max value
|
||||
*
|
||||
* \param vec Other vector to compare the components with
|
||||
*
|
||||
* \see Minimize
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::Maximize(const Vector4& vec)
|
||||
{
|
||||
|
|
@ -132,6 +267,15 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets this vector's components to the minimum of its own and other components
|
||||
* \return A reference to this vector with replaced values with the corresponding min value
|
||||
*
|
||||
* \param vec Other vector to compare the components with
|
||||
*
|
||||
* \see Maximize
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::Minimize(const Vector4& vec)
|
||||
{
|
||||
|
|
@ -150,11 +294,20 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gives the normalized vector
|
||||
* \return A normalized vector from the vec with w = 1
|
||||
*
|
||||
* \param length Optional argument to obtain the length's ratio of the vector in this case w
|
||||
*
|
||||
* \see GetNormal
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::Normalize(T* length)
|
||||
{
|
||||
T invLength = F(1.0)/w;
|
||||
x *= invLength; // Attention, briser cette logique casserait Frustum::Extract
|
||||
x *= invLength; // Warning, change this logic will break Frustum::Extract
|
||||
y *= invLength;
|
||||
z *= invLength;
|
||||
|
||||
|
|
@ -166,6 +319,16 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param X X component
|
||||
* \param Y Y component
|
||||
* \param Z Z component
|
||||
* \param W W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::Set(T X, T Y, T Z, T W)
|
||||
{
|
||||
|
|
@ -177,6 +340,15 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector from two components and a Vector2
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param X X component
|
||||
* \param Y Y component
|
||||
* \param vec vec.X = Z component and vec.y = W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::Set(T X, T Y, const Vector2<T>& vec)
|
||||
{
|
||||
|
|
@ -188,6 +360,15 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector from one component, a Vector2 and one component
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param X X component
|
||||
* \param vec vec.X = Y component and vec.y = Z component
|
||||
* \param W W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::Set(T X, const Vector2<T>& vec, T W)
|
||||
{
|
||||
|
|
@ -199,6 +380,14 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector from one component and a Vector3
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param X X component
|
||||
* \param vec vec.X = Y component, vec.y = Z component and vec.z = W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::Set(T X, const Vector3<T>& vec)
|
||||
{
|
||||
|
|
@ -210,6 +399,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector from a "scale"
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param scale X component = Y component = Z component = W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::Set(T scale)
|
||||
{
|
||||
|
|
@ -221,6 +417,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector from an array of four elements
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param vec[4] vec[0] is X component, vec[1] is Y component, vec[2] is Z component and vec[3] is W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::Set(const T vec[4])
|
||||
{
|
||||
|
|
@ -229,6 +432,14 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector from a Vector2 and two components
|
||||
*
|
||||
* \param vec vec.X = X component and vec.y = Y component
|
||||
* \param Z Z component
|
||||
* \param W W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::Set(const Vector2<T>& vec, T Z, T W)
|
||||
{
|
||||
|
|
@ -240,6 +451,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector from a Vector3 and one components
|
||||
*
|
||||
* \param vec vec.X = X component, vec.y = Y component and vec.z = Z component
|
||||
* \param W W component
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::Set(const Vector3<T>& vec, T W)
|
||||
{
|
||||
|
|
@ -251,6 +469,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector from another vector
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param vec The other vector
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::Set(const Vector4& vec)
|
||||
{
|
||||
|
|
@ -259,6 +484,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the components of the vector from another type of Vector4
|
||||
* \return A reference to this vector
|
||||
*
|
||||
* \param vec Vector of type U to convert its components
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Vector4<T>& Vector4<T>::Set(const Vector4<U>& vec)
|
||||
|
|
@ -271,6 +503,11 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gives a string representation
|
||||
* \return A string representation of the object: "Vector4(x, y, z, w)"
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
String Vector4<T>::ToString() const
|
||||
{
|
||||
|
|
@ -279,54 +516,116 @@ namespace Nz
|
|||
return ss << "Vector4(" << x << ", " << y << ", " << z << ", " << w << ')';
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts vector to pointer to its own data
|
||||
* \return A pointer to the own data
|
||||
*
|
||||
* \remark Access to index greather than 3 is undefined behavior
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>::operator T* ()
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts vector to const pointer to its own data
|
||||
* \return A constant pointer to the own data
|
||||
*
|
||||
* \remark Access to index greather than 3 is undefined behavior
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>::operator const T* () const
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Helps to represent the sign of the vector
|
||||
* \return A constant reference to this vector
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
const Vector4<T>& Vector4<T>::operator+() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Negates the components of the vector
|
||||
* \return A constant reference to this vector with negate components
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T> Vector4<T>::operator-() const
|
||||
{
|
||||
return Vector4(-x, -y, -z, -w);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds the components of the vector with other vector
|
||||
* \return A vector where components are the sum of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to add components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T> Vector4<T>::operator+(const Vector4& vec) const
|
||||
{
|
||||
return Vector4(x + vec.x, y + vec.y, z + vec.z, w + vec.w);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Substracts the components of the vector with other vector
|
||||
* \return A vector where components are the difference of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to substract components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T> Vector4<T>::operator-(const Vector4& vec) const
|
||||
{
|
||||
return Vector4(x - vec.x, y - vec.y, z - vec.z, w - vec.w);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the components of the vector with other vector
|
||||
* \return A vector where components are the product of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to multiply components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T> Vector4<T>::operator*(const Vector4& vec) const
|
||||
{
|
||||
return Vector4(x * vec.x, y * vec.y, z * vec.z, w * vec.w);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the components of the vector with a scalar
|
||||
* \return A vector where components are the product of this vector and the scalar
|
||||
*
|
||||
* \param scale The scalar to multiply components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T> Vector4<T>::operator*(T scale) const
|
||||
{
|
||||
return Vector4(x * scale, y * scale, z * scale, w * scale);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divides the components of the vector with other vector
|
||||
* \return A vector where components are the quotient of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to divide components with
|
||||
*
|
||||
* \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined
|
||||
* \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T> Vector4<T>::operator/(const Vector4& vec) const
|
||||
{
|
||||
|
|
@ -343,6 +642,16 @@ namespace Nz
|
|||
return Vector4(x / vec.x, y / vec.y, z / vec.z, w / vec.w);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divides the components of the vector with a scalar
|
||||
* \return A vector where components are the quotient of this vector and the scalar
|
||||
*
|
||||
* \param scale The scalar to divide components with
|
||||
*
|
||||
* \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined
|
||||
* \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T> Vector4<T>::operator/(T scale) const
|
||||
{
|
||||
|
|
@ -359,6 +668,13 @@ namespace Nz
|
|||
return Vector4(x / scale, y / scale, z / scale, w / scale);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds the components of other vector to this vector
|
||||
* \return A reference to this vector where components are the sum of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to add components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::operator+=(const Vector4& vec)
|
||||
{
|
||||
|
|
@ -370,6 +686,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Substracts the components of other vector to this vector
|
||||
* \return A reference to this vector where components are the difference of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to substract components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::operator-=(const Vector4& vec)
|
||||
{
|
||||
|
|
@ -381,6 +704,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the components of other vector to this vector
|
||||
* \return A reference to this vector where components are the product of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to multiply components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::operator*=(const Vector4& vec)
|
||||
{
|
||||
|
|
@ -392,6 +722,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the components of other vector with a scalar
|
||||
* \return A reference to this vector where components are the product of this vector and the scalar
|
||||
*
|
||||
* \param vec The other vector to multiply components with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::operator*=(T scale)
|
||||
{
|
||||
|
|
@ -403,6 +740,16 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the components of other vector to this vector
|
||||
* \return A reference to this vector where components are the quotient of this vector and the other one
|
||||
*
|
||||
* \param vec The other vector to multiply components with
|
||||
*
|
||||
* \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined
|
||||
* \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::operator/=(const Vector4& vec)
|
||||
{
|
||||
|
|
@ -424,6 +771,16 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divides the components of other vector with a scalar
|
||||
* \return A reference to this vector where components are the quotient of this vector and the scalar
|
||||
*
|
||||
* \param vec The other vector to divide components with
|
||||
*
|
||||
* \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined
|
||||
* \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T>& Vector4<T>::operator/=(T scale)
|
||||
{
|
||||
|
|
@ -445,6 +802,13 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the vector to other one
|
||||
* \return true if the vectors are the same
|
||||
*
|
||||
* \param vec Other vector to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Vector4<T>::operator==(const Vector4& vec) const
|
||||
{
|
||||
|
|
@ -454,12 +818,26 @@ namespace Nz
|
|||
NumberEquals(w, vec.w);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the vector to other one
|
||||
* \return false if the vectors are the same
|
||||
*
|
||||
* \param vec Other vector to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Vector4<T>::operator!=(const Vector4& vec) const
|
||||
{
|
||||
return !operator==(vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the vector to other one
|
||||
* \return true if this vector has its first components inferior to the other ones
|
||||
*
|
||||
* \param vec Other vector to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Vector4<T>::operator<(const Vector4& vec) const
|
||||
{
|
||||
|
|
@ -479,6 +857,13 @@ namespace Nz
|
|||
return x < vec.x;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the vector to other one
|
||||
* \return true if this vector has its first components inferior or equal to the other ones
|
||||
*
|
||||
* \param vec Other vector to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Vector4<T>::operator<=(const Vector4& vec) const
|
||||
{
|
||||
|
|
@ -498,18 +883,79 @@ namespace Nz
|
|||
return x < vec.x;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the vector to other one
|
||||
* \return true if this vector has its first components superior to the other ones
|
||||
*
|
||||
* \param vec Other vector to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Vector4<T>::operator>(const Vector4& vec) const
|
||||
{
|
||||
return !operator<=(vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Compares the vector to other one
|
||||
* \return true if this vector has its first components superior or equal to the other ones
|
||||
*
|
||||
* \param vec Other vector to compare with
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool Vector4<T>::operator>=(const Vector4& vec) const
|
||||
{
|
||||
return !operator<(vec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Interpolates the vector to other one with a factor of interpolation
|
||||
* \return A new vector which is the interpolation of two vectors
|
||||
*
|
||||
* \param from Initial vector
|
||||
* \param to Target vector
|
||||
* \param interpolation Factor of interpolation
|
||||
*
|
||||
* \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior
|
||||
*
|
||||
* \see Lerp
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T> Vector4<T>::Lerp(const Vector4& from, const Vector4& to, T interpolation)
|
||||
{
|
||||
Vector4 dummy;
|
||||
dummy.x = Nz::Lerp(from.x, to.x, interpolation);
|
||||
dummy.y = Nz::Lerp(from.y, to.y, interpolation);
|
||||
dummy.z = Nz::Lerp(from.z, to.z, interpolation);
|
||||
dummy.w = Nz::Lerp(from.w, to.w, interpolation);
|
||||
|
||||
return dummy;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gives the normalized vector
|
||||
* \return A normalized vector from the vec with w = 1
|
||||
*
|
||||
* \param vec Vector to normalize
|
||||
*
|
||||
* \see GetNormal
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T> Vector4<T>::Normalize(const Vector4& vec)
|
||||
{
|
||||
return vec.GetNormal();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the vector (1, 0, 0, 1)
|
||||
* \return A vector with components (1, 0, 0, 1)
|
||||
*
|
||||
* \see MakeUnitX
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T> Vector4<T>::UnitX()
|
||||
{
|
||||
|
|
@ -519,6 +965,13 @@ namespace Nz
|
|||
return vector;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the vector (0, 1, 0, 1)
|
||||
* \return A vector with components (0, 1, 0, 1)
|
||||
*
|
||||
* \see MakeUnitY
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T> Vector4<T>::UnitY()
|
||||
{
|
||||
|
|
@ -528,6 +981,13 @@ namespace Nz
|
|||
return vector;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the vector (0, 0, 1, 1)
|
||||
* \return A vector with components (0, 0, 1, 1)
|
||||
*
|
||||
* \see MakeUnitZ
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T> Vector4<T>::UnitZ()
|
||||
{
|
||||
|
|
@ -537,6 +997,13 @@ namespace Nz
|
|||
return vector;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Shorthand for the vector (0, 0, 0, 1)
|
||||
* \return A vector with components (0, 0, 0, 1)
|
||||
*
|
||||
* \see MakeZero
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Vector4<T> Vector4<T>::Zero()
|
||||
{
|
||||
|
|
@ -547,18 +1014,44 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Output operator
|
||||
* \return The stream
|
||||
*
|
||||
* \param out The stream
|
||||
* \param vec The vector to output
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const Nz::Vector4<T>& vec)
|
||||
{
|
||||
return out << vec.ToString();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies the components of the vector with a scalar
|
||||
* \return A vector where components are the product of this vector and the scalar
|
||||
*
|
||||
* \param scale The scalar to multiply components with
|
||||
*/
|
||||
|
||||
|
||||
template<typename T>
|
||||
Nz::Vector4<T> operator*(T scale, const Nz::Vector4<T>& vec)
|
||||
{
|
||||
return Nz::Vector4<T>(scale * vec.x, scale * vec.y, scale * vec.z, scale * vec.w);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Divides the components of the vector with a scalar
|
||||
* \return A vector where components are the quotient of this vector and the scalar
|
||||
*
|
||||
* \param scale The scalar to divide components with
|
||||
*
|
||||
* \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined
|
||||
* \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Nz::Vector4<T> operator/(T scale, const Nz::Vector4<T>& vec)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ namespace Nz
|
|||
public:
|
||||
NullGeom();
|
||||
|
||||
void ComputeInertialMatrix(Vector3f* inertia, Vector3f* center) const;
|
||||
void ComputeInertialMatrix(Vector3f* inertia, Vector3f* center) const override;
|
||||
|
||||
GeomType GetType() const override;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,12 +43,12 @@ namespace Nz
|
|||
void Detach(AttachmentPoint attachmentPoint, UInt8 index);
|
||||
|
||||
unsigned int GetHeight() const override;
|
||||
RenderTargetParameters GetParameters() const;
|
||||
RenderTargetParameters GetParameters() const override;
|
||||
Vector2ui GetSize() const;
|
||||
unsigned int GetWidth() const override;
|
||||
|
||||
bool IsComplete() const;
|
||||
bool IsRenderable() const;
|
||||
bool IsRenderable() const override;
|
||||
inline bool IsValid() const;
|
||||
|
||||
bool Lock() const;
|
||||
|
|
|
|||
|
|
@ -46,11 +46,11 @@ namespace Nz
|
|||
|
||||
void EnableVerticalSync(bool enabled);
|
||||
|
||||
unsigned int GetHeight() const;
|
||||
RenderTargetParameters GetParameters() const;
|
||||
unsigned int GetWidth() const;
|
||||
unsigned int GetHeight() const override;
|
||||
RenderTargetParameters GetParameters() const override;
|
||||
unsigned int GetWidth() const override;
|
||||
|
||||
bool IsRenderable() const;
|
||||
bool IsRenderable() const override;
|
||||
bool IsValid() const;
|
||||
|
||||
void SetFramerateLimit(unsigned int limit);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Nz
|
|||
SimpleTextDrawer(SimpleTextDrawer&& drawer);
|
||||
virtual ~SimpleTextDrawer();
|
||||
|
||||
const Rectui& GetBounds() const;
|
||||
const Rectui& GetBounds() const override;
|
||||
unsigned int GetCharacterSize() const;
|
||||
const Color& GetColor() const;
|
||||
Font* GetFont() const;
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ namespace Nz
|
|||
return true;
|
||||
}
|
||||
|
||||
unsigned int Read(void* buffer, unsigned int sampleCount)
|
||||
unsigned int Read(void* buffer, unsigned int sampleCount) override
|
||||
{
|
||||
// Si la musique a été demandée en mono, nous devons la convertir à la volée lors de la lecture
|
||||
if (m_mixToMono)
|
||||
|
|
|
|||
|
|
@ -70,9 +70,8 @@ namespace Nz
|
|||
|
||||
bool DirectoryImpl::Create(const String& dirPath)
|
||||
{
|
||||
mode_t permissions; // TODO: check permissions
|
||||
|
||||
return mkdir(dirPath.GetConstBuffer(), permissions) != -1;;
|
||||
mode_t permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; // TODO: check permissions, no right to execute but read and write for every others.
|
||||
return mkdir(dirPath.GetConstBuffer(), permissions) != -1;
|
||||
}
|
||||
|
||||
bool DirectoryImpl::Exists(const String& dirPath)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Network/Win32/SocketImpl.hpp>
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
#include <Nazara/Network/Posix/SocketImpl.hpp>
|
||||
#else
|
||||
#error Missing implementation: Socket
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Network/Win32/IpAddressImpl.hpp>
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
#include <Nazara/Network/Posix/IpAddressImpl.hpp>
|
||||
#else
|
||||
#error Missing implementation: Network
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Network/Win32/SocketImpl.hpp>
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
#include <Nazara/Network/Posix/SocketImpl.hpp>
|
||||
#else
|
||||
#error Missing implementation: Network
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,309 @@
|
|||
// Copyright (C) 2015 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Network/Posix/IpAddressImpl.hpp>
|
||||
#include <Nazara/Core/CallOnExit.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Network/Posix/SocketImpl.hpp>
|
||||
#include <cstring>
|
||||
#include <Nazara/Network/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
namespace Detail
|
||||
{
|
||||
using addrinfoImpl = addrinfo;
|
||||
|
||||
int GetAddressInfo(const String& hostname, const String& service, const addrinfoImpl* hints, addrinfoImpl** results)
|
||||
{
|
||||
return getaddrinfo(hostname.GetConstBuffer(), service.GetConstBuffer(), hints, results);
|
||||
}
|
||||
|
||||
int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, String* hostname, String* service, int flags)
|
||||
{
|
||||
std::array<char, NI_MAXHOST> hostnameBuffer;
|
||||
std::array<char, NI_MAXSERV> serviceBuffer;
|
||||
|
||||
int result = getnameinfo(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), flags);
|
||||
if (result == 0)
|
||||
{
|
||||
if (hostname)
|
||||
hostname->Set(hostnameBuffer.data());
|
||||
|
||||
if (service)
|
||||
service->Set(serviceBuffer.data());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FreeAddressInfo(addrinfoImpl* results)
|
||||
{
|
||||
freeaddrinfo(results);
|
||||
}
|
||||
|
||||
IpAddress::IPv4 convertSockaddrToIPv4(const in_addr& addr)
|
||||
{
|
||||
union byteToInt
|
||||
{
|
||||
UInt8 b[sizeof(uint32_t)];
|
||||
uint32_t i;
|
||||
};
|
||||
|
||||
byteToInt hostOrder;
|
||||
hostOrder.i = ntohl(addr.s_addr);
|
||||
|
||||
return { hostOrder.b[3], hostOrder.b[2], hostOrder.b[1], hostOrder.b[0] };
|
||||
}
|
||||
|
||||
IpAddress::IPv6 convertSockaddr6ToIPv6(const in6_addr& addr)
|
||||
{
|
||||
union byteToInt
|
||||
{
|
||||
UInt8 b[sizeof(uint32_t)];
|
||||
uint32_t i;
|
||||
};
|
||||
|
||||
IpAddress::IPv6 ipv6Addr;
|
||||
|
||||
for (auto i = 0; i < 4; ++i)
|
||||
{
|
||||
byteToInt hostOrder;
|
||||
hostOrder.i = 0;
|
||||
std::copy(addr.s6_addr + 4 * i, addr.s6_addr + 4 * (i + 1), hostOrder.b);
|
||||
ipv6Addr[2 * i] = (hostOrder.b[3] << 8) + hostOrder.b[2];
|
||||
ipv6Addr[2 * i + 1] = (hostOrder.b[1] << 8) + hostOrder.b[0];
|
||||
}
|
||||
|
||||
return ipv6Addr;
|
||||
}
|
||||
}
|
||||
|
||||
IpAddress IpAddressImpl::FromAddrinfo(const addrinfo* info)
|
||||
{
|
||||
switch (info->ai_family)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
sockaddr_in* ipv4 = reinterpret_cast<sockaddr_in*>(info->ai_addr);
|
||||
|
||||
return FromSockAddr(ipv4);
|
||||
}
|
||||
|
||||
case AF_INET6:
|
||||
{
|
||||
sockaddr_in6* ipv6 = reinterpret_cast<sockaddr_in6*>(info->ai_addr);
|
||||
|
||||
return FromSockAddr(ipv6);
|
||||
}
|
||||
}
|
||||
|
||||
return IpAddress::Invalid;
|
||||
}
|
||||
|
||||
IpAddress IpAddressImpl::FromSockAddr(const sockaddr* address)
|
||||
{
|
||||
switch (address->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
return FromSockAddr(reinterpret_cast<const sockaddr_in*>(address));
|
||||
|
||||
case AF_INET6:
|
||||
return FromSockAddr(reinterpret_cast<const sockaddr_in6*>(address));
|
||||
}
|
||||
|
||||
return IpAddress::Invalid;
|
||||
}
|
||||
|
||||
IpAddress IpAddressImpl::FromSockAddr(const sockaddr_in* addressv4)
|
||||
{
|
||||
IpAddress::IPv4 ip4Address = Detail::convertSockaddrToIPv4(addressv4->sin_addr);
|
||||
return IpAddress(ip4Address, ntohs(addressv4->sin_port));
|
||||
}
|
||||
|
||||
IpAddress IpAddressImpl::FromSockAddr(const sockaddr_in6* addressv6)
|
||||
{
|
||||
IpAddress::IPv6 ip6Address = Detail::convertSockaddr6ToIPv6(addressv6->sin6_addr);
|
||||
return IpAddress(ip6Address, ntohs(addressv6->sin6_port));
|
||||
}
|
||||
|
||||
bool IpAddressImpl::ResolveAddress(const IpAddress& ipAddress, String* hostname, String* service, ResolveError* error)
|
||||
{
|
||||
SockAddrBuffer socketAddress;
|
||||
socklen_t socketAddressLen = ToSockAddr(ipAddress, socketAddress.data());
|
||||
|
||||
if (Detail::GetHostnameInfo(reinterpret_cast<sockaddr*>(socketAddress.data()), socketAddressLen, hostname, service, NI_NUMERICSERV) != 0)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateEAIErrorToResolveError(errno);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = ResolveError_NoError;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<HostnameInfo> IpAddressImpl::ResolveHostname(NetProtocol procol, const String& hostname, const String& service, ResolveError* error)
|
||||
{
|
||||
std::vector<HostnameInfo> results;
|
||||
|
||||
Detail::addrinfoImpl hints;
|
||||
std::memset(&hints, 0, sizeof(Detail::addrinfoImpl));
|
||||
hints.ai_family = SocketImpl::TranslateNetProtocolToAF(procol);
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
Detail::addrinfoImpl* servinfo;
|
||||
if (Detail::GetAddressInfo(hostname, service, &hints, &servinfo) != 0)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateEAIErrorToResolveError(errno);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
CallOnExit onExit([servinfo]()
|
||||
{
|
||||
Detail::FreeAddressInfo(servinfo);
|
||||
});
|
||||
|
||||
// loop through all the results and connect to the first we can
|
||||
for (Detail::addrinfoImpl* p = servinfo; p != nullptr; p = p->ai_next)
|
||||
{
|
||||
HostnameInfo result;
|
||||
result.address = FromAddrinfo(p);
|
||||
result.canonicalName = String::Unicode(p->ai_canonname);
|
||||
result.protocol = TranslatePFToNetProtocol(p->ai_family);
|
||||
result.socketType = TranslateSockToNetProtocol(p->ai_socktype);
|
||||
|
||||
results.push_back(result);
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = ResolveError_NoError;
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
socklen_t IpAddressImpl::ToSockAddr(const IpAddress& ipAddress, void* buffer)
|
||||
{
|
||||
if (ipAddress.IsValid())
|
||||
{
|
||||
switch (ipAddress.GetProtocol())
|
||||
{
|
||||
case NetProtocol_IPv4:
|
||||
{
|
||||
sockaddr_in* socketAddress = reinterpret_cast<sockaddr_in*>(buffer);
|
||||
|
||||
std::memset(socketAddress, 0, sizeof(sockaddr_in));
|
||||
socketAddress->sin_family = AF_INET;
|
||||
socketAddress->sin_port = htons(ipAddress.GetPort());
|
||||
socketAddress->sin_addr.s_addr = htonl(ipAddress.ToUInt32());
|
||||
|
||||
return sizeof(sockaddr_in);
|
||||
}
|
||||
|
||||
case NetProtocol_IPv6:
|
||||
{
|
||||
sockaddr_in6* socketAddress = reinterpret_cast<sockaddr_in6*>(buffer);
|
||||
|
||||
std::memset(socketAddress, 0, sizeof(sockaddr_in6));
|
||||
socketAddress->sin6_family = AF_INET6;
|
||||
socketAddress->sin6_port = htons(ipAddress.GetPort());
|
||||
|
||||
IpAddress::IPv6 address = ipAddress.ToIPv6();
|
||||
for (unsigned int i = 0; i < 8; ++i)
|
||||
{
|
||||
UInt16 networkOrder = htons(address[i]);
|
||||
socketAddress->sin6_addr.s6_addr[2 * i] = networkOrder / 256;
|
||||
socketAddress->sin6_addr.s6_addr[2 * i + 1] = networkOrder % 256;
|
||||
}
|
||||
|
||||
return sizeof(sockaddr_in6);
|
||||
}
|
||||
|
||||
default:
|
||||
NazaraInternalError("Unhandled ip protocol (0x" + String::Number(ipAddress.GetProtocol()) + ')');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NazaraError("Invalid ip address");
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetProtocol IpAddressImpl::TranslatePFToNetProtocol(int family)
|
||||
{
|
||||
switch (family)
|
||||
{
|
||||
case PF_INET:
|
||||
return NetProtocol_IPv4;
|
||||
|
||||
case PF_INET6:
|
||||
return NetProtocol_IPv6;
|
||||
|
||||
default:
|
||||
return NetProtocol_Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
SocketType IpAddressImpl::TranslateSockToNetProtocol(int socketType)
|
||||
{
|
||||
switch (socketType)
|
||||
{
|
||||
case SOCK_STREAM:
|
||||
return SocketType_TCP;
|
||||
|
||||
case SOCK_DGRAM:
|
||||
return SocketType_UDP;
|
||||
|
||||
case SOCK_RAW:
|
||||
return SocketType_Raw;
|
||||
|
||||
default:
|
||||
return SocketType_Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
ResolveError IpAddressImpl::TranslateEAIErrorToResolveError(int error)
|
||||
{
|
||||
// http://man7.org/linux/man-pages/man3/gai_strerror.3.html
|
||||
switch (error)
|
||||
{
|
||||
case 0:
|
||||
return ResolveError_NoError;
|
||||
|
||||
// Engine error
|
||||
case EAI_BADFLAGS:
|
||||
case EAI_SYSTEM:
|
||||
return ResolveError_Internal;
|
||||
|
||||
case EAI_FAMILY:
|
||||
case EAI_SERVICE:
|
||||
case EAI_SOCKTYPE:
|
||||
return ResolveError_ProtocolNotSupported;
|
||||
|
||||
case EAI_NONAME:
|
||||
return ResolveError_NotFound;
|
||||
|
||||
case EAI_FAIL:
|
||||
return ResolveError_NonRecoverable;
|
||||
|
||||
case EAI_NODATA:
|
||||
return ResolveError_NotInitialized;
|
||||
|
||||
case EAI_MEMORY:
|
||||
return ResolveError_ResourceError;
|
||||
|
||||
case EAI_AGAIN:
|
||||
return ResolveError_TemporaryFailure;
|
||||
}
|
||||
|
||||
NazaraWarning("Unhandled EAI error: " + Error::GetLastSystemError(error) + " (" + String::Number(error) + ") as " + gai_strerror(error));
|
||||
return ResolveError_Unknown;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (C) 2015 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Network/IpAddress.hpp>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class IpAddressImpl
|
||||
{
|
||||
public:
|
||||
using SockAddrBuffer = std::array<UInt8, sizeof(sockaddr_in6)>;
|
||||
|
||||
IpAddressImpl() = delete;
|
||||
~IpAddressImpl() = delete;
|
||||
|
||||
static IpAddress FromAddrinfo(const addrinfo* info);
|
||||
static IpAddress FromSockAddr(const sockaddr* address);
|
||||
static IpAddress FromSockAddr(const sockaddr_in* addressv4);
|
||||
static IpAddress FromSockAddr(const sockaddr_in6* addressv6);
|
||||
|
||||
static bool ResolveAddress(const IpAddress& ipAddress, String* hostname, String* service, ResolveError* error);
|
||||
static std::vector<HostnameInfo> ResolveHostname(NetProtocol procol, const String& hostname, const String& service, ResolveError* error);
|
||||
|
||||
static socklen_t ToSockAddr(const IpAddress& ipAddress, void* buffer);
|
||||
static NetProtocol TranslatePFToNetProtocol(int family);
|
||||
static SocketType TranslateSockToNetProtocol(int socketType);
|
||||
static ResolveError TranslateEAIErrorToResolveError(int error);
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,746 @@
|
|||
// Copyright (C) 2015 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Network/Posix/SocketImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Network/Posix/IpAddressImpl.hpp>
|
||||
#include <netinet/tcp.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <Nazara/Network/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
constexpr int SOCKET_ERROR = -1;
|
||||
|
||||
SocketHandle SocketImpl::Accept(SocketHandle handle, IpAddress* address, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
|
||||
IpAddressImpl::SockAddrBuffer nameBuffer;
|
||||
socklen_t bufferLength = sizeof(sockaddr_in);
|
||||
|
||||
SocketHandle newClient = accept(handle, reinterpret_cast<sockaddr*>(&nameBuffer), &bufferLength);
|
||||
if (newClient != InvalidHandle)
|
||||
{
|
||||
if (address)
|
||||
*address = IpAddressImpl::FromSockAddr(reinterpret_cast<const sockaddr*>(&nameBuffer));
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
}
|
||||
|
||||
return newClient;
|
||||
}
|
||||
|
||||
SocketState SocketImpl::Bind(SocketHandle handle, const IpAddress& address, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
NazaraAssert(address.IsValid(), "Invalid address");
|
||||
|
||||
IpAddressImpl::SockAddrBuffer nameBuffer;
|
||||
int bufferLength = IpAddressImpl::ToSockAddr(address, nameBuffer.data());
|
||||
|
||||
if (bind(handle, reinterpret_cast<const sockaddr*>(&nameBuffer), bufferLength) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return SocketState_Bound;
|
||||
}
|
||||
|
||||
SocketHandle SocketImpl::Create(NetProtocol protocol, SocketType type, SocketError* error)
|
||||
{
|
||||
NazaraAssert(protocol != NetProtocol_Any, "Any protocol is not supported for socket creation");
|
||||
NazaraAssert(type <= SocketType_Max, "Type has value out of enum");
|
||||
|
||||
SocketHandle handle = socket(TranslateNetProtocolToAF(protocol), TranslateSocketTypeToSock(type), 0);
|
||||
if (handle == InvalidHandle && error != nullptr)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void SocketImpl::Close(SocketHandle handle)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
|
||||
if (close(handle) == SOCKET_ERROR)
|
||||
NazaraWarning("Failed to close socket: " + Error::GetLastSystemError(GetLastErrorCode()));
|
||||
}
|
||||
|
||||
void SocketImpl::ClearErrorCode(SocketHandle handle)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
|
||||
if (GetLastError(handle, nullptr) < 0)
|
||||
NazaraWarning("Failed to clear socket error code: " + Error::GetLastSystemError(GetLastErrorCode()));
|
||||
}
|
||||
|
||||
SocketState SocketImpl::Connect(SocketHandle handle, const IpAddress& address, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
NazaraAssert(address.IsValid(), "Invalid address");
|
||||
|
||||
IpAddressImpl::SockAddrBuffer nameBuffer;
|
||||
int bufferLength = IpAddressImpl::ToSockAddr(address, nameBuffer.data());
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
// Clear socket error status
|
||||
ClearErrorCode(handle);
|
||||
|
||||
if (connect(handle, reinterpret_cast<const sockaddr*>(nameBuffer.data()), bufferLength) == SOCKET_ERROR)
|
||||
{
|
||||
int errorCode = GetLastErrorCode();
|
||||
switch (errorCode) //< Check for "normal errors" first
|
||||
{
|
||||
case EALREADY:
|
||||
case EINPROGRESS:
|
||||
return SocketState_Connecting;
|
||||
|
||||
case EISCONN:
|
||||
return SocketState_Connected;
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (errorCode == EADDRNOTAVAIL)
|
||||
*error = SocketError_ConnectionRefused; //< ConnectionRefused seems more legit than AddressNotAvailable in connect case
|
||||
else
|
||||
*error = TranslateErrnoToResolveError(errorCode);
|
||||
}
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
|
||||
return SocketState_Connected;
|
||||
}
|
||||
|
||||
SocketState SocketImpl::Connect(SocketHandle handle, const IpAddress& address, UInt64 msTimeout, SocketError* error)
|
||||
{
|
||||
SocketState state = Connect(handle, address, error);
|
||||
if (state == SocketState_Connecting)
|
||||
{
|
||||
// http://developerweb.net/viewtopic.php?id=3196
|
||||
fd_set localSet;
|
||||
FD_ZERO(&localSet);
|
||||
FD_SET(handle, &localSet);
|
||||
|
||||
timeval tv;
|
||||
tv.tv_sec = static_cast<long>(msTimeout / 1000ULL);
|
||||
tv.tv_usec = static_cast<long>((msTimeout % 1000ULL) * 1000ULL);
|
||||
|
||||
int ret = select(0, nullptr, &localSet, &localSet, (msTimeout > 0) ? &tv : nullptr);
|
||||
if (ret == SOCKET_ERROR)
|
||||
{
|
||||
int code = GetLastErrorCode(handle, error);
|
||||
if (code < 0) //< GetLastErrorCode() failed
|
||||
return SocketState_NotConnected;
|
||||
|
||||
if (code)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(code);
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
if (error)
|
||||
*error = SocketError_TimedOut;
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
state = SocketState_Connected;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
bool SocketImpl::Initialize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
SocketError SocketImpl::GetLastError(SocketHandle handle, SocketError* error)
|
||||
{
|
||||
int code = GetLastErrorCode(handle, error);
|
||||
if (code < 0)
|
||||
return SocketError_Internal;
|
||||
|
||||
return TranslateErrnoToResolveError(code);
|
||||
}
|
||||
|
||||
int SocketImpl::GetLastErrorCode()
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
|
||||
int SocketImpl::GetLastErrorCode(SocketHandle handle, SocketError* error)
|
||||
{
|
||||
int code;
|
||||
unsigned int codeLength = sizeof(code);
|
||||
|
||||
if (getsockopt(handle, SOL_SOCKET, SO_ERROR, &code, &codeLength) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
SocketState SocketImpl::Listen(SocketHandle handle, const IpAddress& address, unsigned queueSize, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
NazaraAssert(address.IsValid(), "Invalid address");
|
||||
|
||||
IpAddressImpl::SockAddrBuffer nameBuffer;
|
||||
int bufferLength = IpAddressImpl::ToSockAddr(address, nameBuffer.data());
|
||||
|
||||
if (bind(handle, reinterpret_cast<const sockaddr*>(&nameBuffer), bufferLength) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
|
||||
if (listen(handle, queueSize) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return SocketState_Bound;
|
||||
}
|
||||
|
||||
unsigned int SocketImpl::QueryAvailableBytes(SocketHandle handle, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
|
||||
u_long availableBytes;
|
||||
if (ioctl(handle, FIONREAD, &availableBytes) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return availableBytes;
|
||||
}
|
||||
|
||||
bool SocketImpl::QueryBroadcasting(SocketHandle handle, SocketError* error)
|
||||
{
|
||||
bool code;
|
||||
unsigned int codeLength = sizeof(code);
|
||||
|
||||
if (getsockopt(handle, SOL_SOCKET, SO_BROADCAST, &code, &codeLength) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
bool SocketImpl::QueryKeepAlive(SocketHandle handle, SocketError* error)
|
||||
{
|
||||
bool code;
|
||||
unsigned int codeLength = sizeof(code);
|
||||
|
||||
if (getsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &code, &codeLength) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
unsigned int SocketImpl::QueryMaxDatagramSize(SocketHandle handle, SocketError* error)
|
||||
{
|
||||
unsigned int code;
|
||||
unsigned int codeLength = sizeof(code);
|
||||
|
||||
if (getsockopt(handle, IPPROTO_IP, IP_MTU, &code, &codeLength) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
bool SocketImpl::QueryNoDelay(SocketHandle handle, SocketError* error)
|
||||
{
|
||||
bool code;
|
||||
unsigned int codeLength = sizeof(code);
|
||||
|
||||
if (getsockopt(handle, IPPROTO_TCP, TCP_NODELAY, &code, &codeLength) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
IpAddress SocketImpl::QueryPeerAddress(SocketHandle handle, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
|
||||
IpAddressImpl::SockAddrBuffer nameBuffer;
|
||||
socklen_t bufferLength = sizeof(sockaddr_in);
|
||||
|
||||
if (getpeername(handle, reinterpret_cast<sockaddr*>(nameBuffer.data()), &bufferLength) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return IpAddress();
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return IpAddressImpl::FromSockAddr(reinterpret_cast<sockaddr*>(nameBuffer.data()));
|
||||
}
|
||||
|
||||
IpAddress SocketImpl::QuerySocketAddress(SocketHandle handle, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
|
||||
IpAddressImpl::SockAddrBuffer nameBuffer;
|
||||
socklen_t bufferLength = sizeof(sockaddr_in);
|
||||
|
||||
if (getsockname(handle, reinterpret_cast<sockaddr*>(nameBuffer.data()), &bufferLength) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
int errorCode = GetLastErrorCode();
|
||||
if (errorCode == EINVAL)
|
||||
*error = SocketError_NoError;
|
||||
else
|
||||
*error = TranslateErrnoToResolveError(errorCode);
|
||||
}
|
||||
|
||||
return IpAddress();
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return IpAddressImpl::FromSockAddr(reinterpret_cast<sockaddr*>(nameBuffer.data()));
|
||||
}
|
||||
|
||||
|
||||
bool SocketImpl::Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
NazaraAssert(buffer && length > 0, "Invalid buffer");
|
||||
|
||||
int byteRead = recv(handle, reinterpret_cast<char*>(buffer), length, 0);
|
||||
if (byteRead == SOCKET_ERROR)
|
||||
{
|
||||
int errorCode = GetLastErrorCode();
|
||||
switch (errorCode)
|
||||
{
|
||||
case EWOULDBLOCK:
|
||||
{
|
||||
// If we have no data and are not blocking, return true with 0 byte read
|
||||
byteRead = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(errorCode);
|
||||
|
||||
return false; //< Error
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (byteRead == 0)
|
||||
{
|
||||
if (error)
|
||||
*error = SocketError_ConnectionClosed;
|
||||
|
||||
return false; //< Connection has been closed
|
||||
}
|
||||
|
||||
if (read)
|
||||
*read = byteRead;
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SocketImpl::ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
NazaraAssert(buffer && length > 0, "Invalid buffer");
|
||||
|
||||
IpAddressImpl::SockAddrBuffer nameBuffer;
|
||||
socklen_t bufferLength = sizeof(sockaddr_in);
|
||||
|
||||
IpAddress senderIp;
|
||||
|
||||
int byteRead = recvfrom(handle, buffer, length, 0, reinterpret_cast<sockaddr*>(&nameBuffer), &bufferLength);
|
||||
if (byteRead == SOCKET_ERROR)
|
||||
{
|
||||
int errorCode = GetLastErrorCode();
|
||||
switch (errorCode)
|
||||
{
|
||||
case EWOULDBLOCK:
|
||||
{
|
||||
// If we have no data and are not blocking, return true with 0 byte read
|
||||
byteRead = 0;
|
||||
senderIp = IpAddress::Invalid;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(errorCode);
|
||||
|
||||
return false; //< Error
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (byteRead == 0)
|
||||
{
|
||||
if (error)
|
||||
*error = SocketError_ConnectionClosed;
|
||||
|
||||
return false; //< Connection closed
|
||||
}
|
||||
else // else we received something
|
||||
senderIp = IpAddressImpl::FromSockAddr(reinterpret_cast<const sockaddr*>(&nameBuffer));
|
||||
|
||||
if (from)
|
||||
*from = senderIp;
|
||||
|
||||
if (read)
|
||||
*read = byteRead;
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SocketImpl::Send(SocketHandle handle, const void* buffer, int length, int* sent, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
NazaraAssert(buffer && length > 0, "Invalid buffer");
|
||||
|
||||
int byteSent = send(handle, reinterpret_cast<const char*>(buffer), length, 0);
|
||||
if (byteSent == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return false; //< Error
|
||||
}
|
||||
|
||||
if (sent)
|
||||
*sent = byteSent;
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SocketImpl::SendTo(SocketHandle handle, const void* buffer, int length, const IpAddress& to, int* sent, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
NazaraAssert(buffer && length > 0, "Invalid buffer");
|
||||
|
||||
IpAddressImpl::SockAddrBuffer nameBuffer;
|
||||
int bufferLength = IpAddressImpl::ToSockAddr(to, nameBuffer.data());
|
||||
|
||||
int byteSent = sendto(handle, reinterpret_cast<const char*>(buffer), length, 0, reinterpret_cast<const sockaddr*>(nameBuffer.data()), bufferLength);
|
||||
if (byteSent == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return false; //< Error
|
||||
}
|
||||
|
||||
if (sent)
|
||||
*sent = byteSent;
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SocketImpl::SetBlocking(SocketHandle handle, bool blocking, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
|
||||
u_long block = (blocking) ? 0 : 1;
|
||||
if (ioctl(handle, FIONBIO, &block) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return false; //< Error
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SocketImpl::SetBroadcasting(SocketHandle handle, bool broadcasting, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
|
||||
bool option = broadcasting;
|
||||
if (setsockopt(handle, SOL_SOCKET, SO_BROADCAST, reinterpret_cast<const char*>(&option), sizeof(option)) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return false; //< Error
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SocketImpl::SetKeepAlive(SocketHandle handle, bool enabled, UInt64 msTime, UInt64 msInterval, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
|
||||
int keepAlive = enabled ? 1 : 0;
|
||||
int keepIdle = msTime / 1000; // Linux works with seconds.
|
||||
int keepInterval = msInterval / 1000; // Linux works with seconds.
|
||||
|
||||
if (setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &keepAlive , sizeof(keepAlive)) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return false; //< Error
|
||||
}
|
||||
|
||||
if (setsockopt(handle, IPPROTO_TCP, TCP_KEEPIDLE, &keepIdle, sizeof(keepIdle)) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return false; //< Error
|
||||
}
|
||||
|
||||
if (setsockopt(handle, IPPROTO_TCP, TCP_KEEPINTVL, &keepInterval, sizeof(keepInterval)) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return false; //< Error
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SocketImpl::SetNoDelay(SocketHandle handle, bool nodelay, SocketError* error)
|
||||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
|
||||
int option = nodelay ? 1 : 0;
|
||||
if (setsockopt(handle, IPPROTO_TCP, TCP_NODELAY, &option, sizeof(option)) == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToResolveError(GetLastErrorCode());
|
||||
|
||||
return false; //< Error
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SocketError SocketImpl::TranslateErrnoToResolveError(int error)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case 0:
|
||||
return SocketError_NoError;
|
||||
|
||||
// Engine error
|
||||
case EACCES:
|
||||
case EBADF:
|
||||
case EINVAL:
|
||||
case EFAULT:
|
||||
case ENOTSOCK:
|
||||
case EPROTOTYPE:
|
||||
return SocketError_Internal;
|
||||
|
||||
case EADDRNOTAVAIL:
|
||||
case EADDRINUSE:
|
||||
return SocketError_AddressNotAvailable;
|
||||
|
||||
case EAFNOSUPPORT:
|
||||
case EPFNOSUPPORT:
|
||||
case EOPNOTSUPP:
|
||||
case EPROTONOSUPPORT:
|
||||
case ESOCKTNOSUPPORT:
|
||||
return SocketError_NotSupported;
|
||||
|
||||
// Those are not errors and should have been handled before the call
|
||||
case EALREADY:
|
||||
case EISCONN:
|
||||
case EWOULDBLOCK:
|
||||
return SocketError_Internal;
|
||||
|
||||
case ECONNREFUSED:
|
||||
return SocketError_ConnectionRefused;
|
||||
|
||||
case EMSGSIZE:
|
||||
return SocketError_DatagramSize;
|
||||
|
||||
case EMFILE:
|
||||
case ENOBUFS:
|
||||
case ENOMEM:
|
||||
return SocketError_ResourceError;
|
||||
|
||||
case ENOTCONN:
|
||||
case ESHUTDOWN:
|
||||
return SocketError_ConnectionClosed;
|
||||
|
||||
case EHOSTUNREACH:
|
||||
return SocketError_UnreachableHost;
|
||||
|
||||
case ENETDOWN:
|
||||
case ENETUNREACH:
|
||||
return SocketError_NetworkError;
|
||||
|
||||
case ENODATA:
|
||||
return SocketError_NotInitialized;
|
||||
|
||||
case ETIMEDOUT:
|
||||
return SocketError_TimedOut;
|
||||
}
|
||||
|
||||
NazaraWarning("Unhandled POSIX error: " + Error::GetLastSystemError(error) + " (" + String::Number(error) + ')');
|
||||
return SocketError_Unknown;
|
||||
}
|
||||
|
||||
int SocketImpl::TranslateNetProtocolToAF(NetProtocol protocol)
|
||||
{
|
||||
NazaraAssert(protocol <= NetProtocol_Max, "Protocol has value out of enum");
|
||||
|
||||
static int addressFamily[] = {
|
||||
AF_UNSPEC, //< NetProtocol_Any
|
||||
AF_INET, //< NetProtocol_IPv4
|
||||
AF_INET6, //< NetProtocol_IPv6
|
||||
-1 //< NetProtocol_Unknown
|
||||
};
|
||||
static_assert(sizeof(addressFamily) / sizeof(int) == NetProtocol_Max + 1, "Address family array is incomplete");
|
||||
|
||||
return addressFamily[protocol];
|
||||
}
|
||||
|
||||
int SocketImpl::TranslateSocketTypeToSock(SocketType type)
|
||||
{
|
||||
NazaraAssert(type <= SocketType_Max, "Socket type has value out of enum");
|
||||
|
||||
static int socketType[] = {
|
||||
SOCK_RAW, //< SocketType_Raw
|
||||
SOCK_STREAM, //< SocketType_TCP
|
||||
SOCK_DGRAM, //< SocketType_UDP
|
||||
-1 //< SocketType_Unknown
|
||||
};
|
||||
static_assert(sizeof(socketType) / sizeof(int) == SocketType_Max + 1, "Socket type array is incomplete");
|
||||
|
||||
return socketType[type];
|
||||
}
|
||||
|
||||
void SocketImpl::Uninitialize()
|
||||
{
|
||||
}
|
||||
|
||||
SocketHandle SocketImpl::InvalidHandle = -1;
|
||||
SocketImpl::socketID SocketImpl::s_socket;
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright (C) 2015 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Network/SocketHandle.hpp>
|
||||
#include <Nazara/Network/Enums.hpp>
|
||||
#include <Nazara/Network/IpAddress.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class SocketImpl
|
||||
{
|
||||
public:
|
||||
SocketImpl() = delete;
|
||||
~SocketImpl() = delete;
|
||||
|
||||
static SocketHandle Accept(SocketHandle handle, IpAddress* address, SocketError* error);
|
||||
|
||||
static SocketState Bind(SocketHandle handle, const IpAddress& address, SocketError* error);
|
||||
|
||||
static SocketHandle Create(NetProtocol protocol, SocketType type, SocketError* error);
|
||||
|
||||
static void ClearErrorCode(SocketHandle handle);
|
||||
static void Close(SocketHandle handle);
|
||||
|
||||
static SocketState Connect(SocketHandle handle, const IpAddress& address, SocketError* error);
|
||||
static SocketState Connect(SocketHandle handle, const IpAddress& address, UInt64 msTimeout, SocketError* error);
|
||||
|
||||
static bool Initialize();
|
||||
|
||||
static SocketError GetLastError(SocketHandle handle, SocketError* error = nullptr);
|
||||
static int GetLastErrorCode();
|
||||
static int GetLastErrorCode(SocketHandle handle, SocketError* error = nullptr);
|
||||
|
||||
static SocketState Listen(SocketHandle handle, const IpAddress& address, unsigned queueSize, SocketError* error);
|
||||
|
||||
static unsigned int QueryAvailableBytes(SocketHandle handle, SocketError* error = nullptr);
|
||||
static bool QueryBroadcasting(SocketHandle handle, SocketError* error = nullptr);
|
||||
static bool QueryKeepAlive(SocketHandle handle, SocketError* error = nullptr);
|
||||
static unsigned int QueryMaxDatagramSize(SocketHandle handle, SocketError* error = nullptr);
|
||||
static bool QueryNoDelay(SocketHandle handle, SocketError* error = nullptr);
|
||||
static IpAddress QueryPeerAddress(SocketHandle handle, SocketError* error = nullptr);
|
||||
static IpAddress QuerySocketAddress(SocketHandle handle, SocketError* error = nullptr);
|
||||
|
||||
static bool Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error);
|
||||
static bool ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error);
|
||||
|
||||
static bool Send(SocketHandle handle, const void* buffer, int length, int* sent, SocketError* error);
|
||||
static bool SendTo(SocketHandle handle, const void* buffer, int length, const IpAddress& to, int* sent, SocketError* error);
|
||||
|
||||
static bool SetBlocking(SocketHandle handle, bool blocking, SocketError* error = nullptr);
|
||||
static bool SetBroadcasting(SocketHandle handle, bool broadcasting, SocketError* error = nullptr);
|
||||
static bool SetKeepAlive(SocketHandle handle, bool enabled, UInt64 msTime, UInt64 msInterval, SocketError* error = nullptr);
|
||||
static bool SetNoDelay(SocketHandle handle, bool nodelay, SocketError* error = nullptr);
|
||||
|
||||
static SocketError TranslateErrnoToResolveError(int error);
|
||||
static int TranslateNetProtocolToAF(NetProtocol protocol);
|
||||
static int TranslateSocketTypeToSock(SocketType type);
|
||||
|
||||
static void Uninitialize();
|
||||
|
||||
static SocketHandle InvalidHandle;
|
||||
|
||||
private:
|
||||
using socketID = int;
|
||||
static socketID s_socket;
|
||||
};
|
||||
}
|
||||
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Network/Win32/SocketImpl.hpp>
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
#include <Nazara/Network/Posix/SocketImpl.hpp>
|
||||
#else
|
||||
#error Missing implementation: Socket
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Network/Win32/SocketImpl.hpp>
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
#include <Nazara/Network/Posix/SocketImpl.hpp>
|
||||
#else
|
||||
#error Missing implementation: Socket
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Network/Win32/SocketImpl.hpp>
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
#include <Nazara/Network/Posix/SocketImpl.hpp>
|
||||
#else
|
||||
#error Missing implementation: Socket
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ namespace Nz
|
|||
OpenEWMHConnection(sharedConnection);
|
||||
}
|
||||
|
||||
NazaraNotice("Initialized: Utility module");
|
||||
NazaraNotice("Initialized: Display module");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Nz
|
|||
{
|
||||
class String;
|
||||
|
||||
class X11
|
||||
class NAZARA_UTILITY_API X11
|
||||
{
|
||||
public:
|
||||
X11() = delete;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,19 @@ TEST_CASE("Clamp", "[ALGORITHM]" )
|
|||
}
|
||||
}
|
||||
|
||||
TEST_CASE("CountBits", "[ALGORITHM]")
|
||||
{
|
||||
SECTION("Number 10 has 2 bits set to 1")
|
||||
{
|
||||
REQUIRE(Nz::CountBits(10) == 2);
|
||||
}
|
||||
|
||||
SECTION("Number 0 has 0 bit set to 1")
|
||||
{
|
||||
REQUIRE(Nz::CountBits(0) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("DegreeToRadian", "[ALGORITHM]")
|
||||
{
|
||||
SECTION("Convert 45.f degree to radian")
|
||||
|
|
@ -47,6 +60,11 @@ TEST_CASE("DegreeToRadian", "[ALGORITHM]" )
|
|||
|
||||
TEST_CASE("GetNearestPowerOfTwo", "[ALGORITHM]")
|
||||
{
|
||||
SECTION("Nearest power of two of 0 = 1")
|
||||
{
|
||||
REQUIRE(Nz::GetNearestPowerOfTwo(0) == 1);
|
||||
}
|
||||
|
||||
SECTION("Nearest power of two of 16 = 16")
|
||||
{
|
||||
REQUIRE(Nz::GetNearestPowerOfTwo(16) == 16);
|
||||
|
|
@ -115,6 +133,47 @@ TEST_CASE("GetNumberLength", "[ALGORITHM]" )
|
|||
}
|
||||
}
|
||||
|
||||
TEST_CASE("IntegralLog2", "[ALGORITHM]")
|
||||
{
|
||||
SECTION("According to implementation, log in base 2 of 0 = 0")
|
||||
{
|
||||
REQUIRE(Nz::IntegralLog2(0) == 0);
|
||||
}
|
||||
|
||||
SECTION("Log in base 2 of 1 = 0")
|
||||
{
|
||||
REQUIRE(Nz::IntegralLog2(1) == 0);
|
||||
}
|
||||
|
||||
SECTION("Log in base 2 of 4 = 2")
|
||||
{
|
||||
REQUIRE(Nz::IntegralLog2(4) == 2);
|
||||
}
|
||||
|
||||
SECTION("Log in base 2 of 5 = 2")
|
||||
{
|
||||
REQUIRE(Nz::IntegralLog2(5) == 2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("IntegralLog2Pot", "[ALGORITHM]")
|
||||
{
|
||||
SECTION("According to implementation, log in base 2 of 0 = 0")
|
||||
{
|
||||
REQUIRE(Nz::IntegralLog2Pot(0) == 0);
|
||||
}
|
||||
|
||||
SECTION("Log in base 2 of 1 = 0")
|
||||
{
|
||||
REQUIRE(Nz::IntegralLog2Pot(1) == 0);
|
||||
}
|
||||
|
||||
SECTION("Log in base 2 of 4 = 2")
|
||||
{
|
||||
REQUIRE(Nz::IntegralLog2Pot(4) == 2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("IntegralPow", "[ALGORITHM]")
|
||||
{
|
||||
SECTION("2 to power 4")
|
||||
|
|
|
|||
|
|
@ -99,5 +99,20 @@ SCENARIO("BoundingVolume", "[MATH][BOUNDINGVOLUME]")
|
|||
REQUIRE(firstCenterAndUnit.aabb != secondCenterAndUnit.aabb);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We try to lerp")
|
||||
{
|
||||
THEN("Compilation should be fine")
|
||||
{
|
||||
Nz::BoundingVolumef nullBoundingVolume = Nz::BoundingVolumef(Nz::Vector3f::Zero(), Nz::Vector3f::Zero());
|
||||
Nz::BoundingVolumef centerAndUnit = firstCenterAndUnit;
|
||||
nullBoundingVolume.Update(Nz::Matrix4f::Identity());
|
||||
centerAndUnit.Update(Nz::Matrix4f::Identity());
|
||||
Nz::BoundingVolumef result(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.5f);
|
||||
result.Update(Nz::Matrix4f::Identity());
|
||||
|
||||
REQUIRE(Nz::BoundingVolumef::Lerp(nullBoundingVolume, centerAndUnit, 0.5f) == result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,18 @@ SCENARIO("Box", "[MATH][BOX]")
|
|||
REQUIRE(tmp == firstCenterAndUnit);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We try to lerp")
|
||||
{
|
||||
THEN("Compilation should be fine")
|
||||
{
|
||||
Nz::Boxf nullBox = Nz::Boxf::Zero();
|
||||
Nz::Boxf centerAndUnit = firstCenterAndUnit;
|
||||
Nz::Boxf result(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.5f);
|
||||
|
||||
REQUIRE(Nz::Boxf::Lerp(nullBox, centerAndUnit, 0.5f) == result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("Two wrong box (negative width, height and depth")
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ SCENARIO("EulerAngles", "[MATH][EULERANGLES]")
|
|||
|
||||
WHEN("We do some operations")
|
||||
{
|
||||
Nz::EulerAnglesf euler90(90.f, 90.f, 90.f);
|
||||
Nz::EulerAnglesf euler270(270.f, 270.f, 270.f);
|
||||
Nz::EulerAnglesf euler90(Nz::FromDegrees(90.f), Nz::FromDegrees(90.f), Nz::FromDegrees(90.f));
|
||||
Nz::EulerAnglesf euler270(Nz::FromDegrees(270.f), Nz::FromDegrees(270.f), Nz::FromDegrees(270.f));
|
||||
|
||||
Nz::EulerAnglesf euler360 = euler90 + euler270;
|
||||
euler360.Normalize();
|
||||
|
|
@ -42,6 +42,27 @@ SCENARIO("EulerAngles", "[MATH][EULERANGLES]")
|
|||
}
|
||||
}
|
||||
|
||||
GIVEN("Three rotation of 90 on each axis")
|
||||
{
|
||||
Nz::EulerAnglesf euler90P(Nz::FromDegrees(90.f), 0.f, 0.f);
|
||||
Nz::EulerAnglesf euler90Y(0.f, Nz::FromDegrees(90.f), 0.f);
|
||||
Nz::EulerAnglesf euler90R(0.f, 0.f, Nz::FromDegrees(90.f));
|
||||
|
||||
WHEN("We transform the axis")
|
||||
{
|
||||
THEN("This is supposed to be left-handed")
|
||||
{
|
||||
Nz::Vector3f rotation90P = euler90P.ToQuaternion() * Nz::Vector3f::UnitY();
|
||||
Nz::Vector3f rotation90Y = euler90Y.ToQuaternion() * Nz::Vector3f::UnitZ();
|
||||
Nz::Vector3f rotation90R = euler90R.ToQuaternion() * Nz::Vector3f::UnitX();
|
||||
|
||||
REQUIRE(rotation90P == Nz::Vector3f::UnitZ());
|
||||
REQUIRE(rotation90Y == Nz::Vector3f::UnitX());
|
||||
REQUIRE(rotation90R == Nz::Vector3f::UnitY());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("Euler angles with rotation 45 on each axis")
|
||||
{
|
||||
WHEN("We convert to quaternion")
|
||||
|
|
|
|||
|
|
@ -78,5 +78,18 @@ SCENARIO("Frustum", "[MATH][FRUSTUM]")
|
|||
CHECK(frustum.Contains(&tmp, 1));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We test for edge cases")
|
||||
{
|
||||
THEN("Implementation defined these")
|
||||
{
|
||||
Nz::BoundingVolumef nullVolume = Nz::BoundingVolumef::Null();
|
||||
CHECK(!frustum.Contains(nullVolume));
|
||||
Nz::BoundingVolumef infiniteVolume = Nz::BoundingVolumef::Infinite();
|
||||
CHECK(frustum.Contains(infiniteVolume));
|
||||
REQUIRE(frustum.Intersect(nullVolume) == Nz::IntersectionSide_Outside);
|
||||
REQUIRE(frustum.Intersect(infiniteVolume) == Nz::IntersectionSide_Intersecting);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,16 @@ SCENARIO("Matrix4", "[MATH][Matrix4]")
|
|||
REQUIRE(firstIdentity.Inverse() == secondIdentity.InverseAffine());
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We transpose one of this matrix")
|
||||
{
|
||||
THEN("Identity transposed is the same than identity")
|
||||
{
|
||||
Nz::Matrix4f transposedIdentity;
|
||||
firstIdentity.GetTransposed(&transposedIdentity);
|
||||
REQUIRE(firstIdentity == transposedIdentity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("Two different matrix")
|
||||
|
|
|
|||
|
|
@ -43,5 +43,20 @@ SCENARIO("OrientedBox", "[MATH][ORIENTEDBOX]")
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We try to lerp")
|
||||
{
|
||||
THEN("Compilation should be fine")
|
||||
{
|
||||
Nz::OrientedBoxf nullOrientedBox = Nz::OrientedBoxf::Zero();
|
||||
Nz::OrientedBoxf centerAndUnit = firstCenterAndUnit;
|
||||
nullOrientedBox.Update(Nz::Matrix4f::Identity());
|
||||
centerAndUnit.Update(Nz::Matrix4f::Identity());
|
||||
Nz::OrientedBoxf result(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.5f);
|
||||
result.Update(Nz::Matrix4f::Identity());
|
||||
|
||||
REQUIRE(Nz::OrientedBoxf::Lerp(nullOrientedBox, centerAndUnit, 0.5f) == result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,18 @@ SCENARIO("Plane", "[MATH][PLANE]")
|
|||
REQUIRE(Nz::Planef(-Nz::Vector3f::UnitY(), -1000.f).Distance(Nz::Vector3f::UnitY() * 1500.f) == Approx(-500.f));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We try to lerp")
|
||||
{
|
||||
THEN("Compilation should be fine")
|
||||
{
|
||||
Nz::Planef planeXY = Nz::Planef::XY();
|
||||
Nz::Planef planeXZ = Nz::Planef::XZ();
|
||||
Nz::Vector3f result = Nz::Vector3f(0.f, 1.f, 1.f) * 0.5f;
|
||||
result.Normalize();
|
||||
REQUIRE(Nz::Planef::Lerp(planeXY, planeXZ, 0.5f) == Nz::Planef(result, 0.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("The plane XZ, distance 1 with 3 points (0, 1, 0), (1, 1, 1), (-1, 1, 0)")
|
||||
|
|
|
|||
|
|
@ -32,6 +32,22 @@ SCENARIO("Quaternion", "[MATH][QUATERNION]")
|
|||
REQUIRE((firstQuaternion * Nz::Vector3f::UnitZ()) == -Nz::Vector3f::UnitZ());
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We invert or normalize Zero quaternion")
|
||||
{
|
||||
Nz::Quaternionf zero = Nz::Quaternionf::Zero();
|
||||
|
||||
THEN("It's meant not to be changed")
|
||||
{
|
||||
Nz::Quaternionf inverted = zero.GetInverse();
|
||||
float tmp = -1.f;
|
||||
Nz::Quaternionf normalized = zero.GetNormal(&tmp);
|
||||
|
||||
REQUIRE(inverted == zero);
|
||||
REQUIRE(normalized == zero);
|
||||
REQUIRE(tmp == Approx(0.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("The four unit quaternions")
|
||||
|
|
@ -154,5 +170,18 @@ SCENARIO("Quaternion", "[MATH][QUATERNION]")
|
|||
REQUIRE(quaternionC.z == Approx(unitZ225.z));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We get the rotation between two vectors")
|
||||
{
|
||||
/*TODO
|
||||
* Nz::Quaternionf rotationBetweenXY = Nz::Quaternionf::RotationBetween(Nz::Vector3f::UnitX(), Nz::Vector3f::UnitY());
|
||||
|
||||
THEN("The rotation in left-handed is 270 degree on z")
|
||||
{
|
||||
Nz::Quaternionf rotation270Z(Nz::FromDegrees(270.f), Nz::Vector3f::UnitZ());
|
||||
Nz::Quaternionf rotation90Z(Nz::FromDegrees(90.f), Nz::Vector3f::UnitZ());
|
||||
REQUIRE(rotation90Z == rotationBetweenXY);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,10 +86,37 @@ SCENARIO("Ray", "[MATH][RAY]")
|
|||
Nz::BoundingVolumef nullVolume(Nz::Extend_Null);
|
||||
CHECK(!ray.Intersect(nullVolume));
|
||||
|
||||
float tmpClosest = -1.f;
|
||||
float tmpFurthest = -1.f;
|
||||
Nz::BoundingVolumef infiniteVolume(Nz::Extend_Infinite);
|
||||
CHECK(ray.Intersect(infiniteVolume));
|
||||
CHECK(ray.Intersect(infiniteVolume, &tmpClosest, &tmpFurthest));
|
||||
CHECK(tmpClosest == Approx(0.f));
|
||||
CHECK(tmpFurthest == std::numeric_limits<float>::infinity());
|
||||
}
|
||||
|
||||
THEN("For the triangle collision's")
|
||||
{
|
||||
Nz::Vector3f firstPoint(0.f, 1.f, 1.f);
|
||||
Nz::Vector3f secondPoint(-1.f, 1.f, -1.f);
|
||||
Nz::Vector3f thidPoint(1.f, 1.f, -1.f);
|
||||
float tmpHit = -1.f;
|
||||
|
||||
CHECK(ray.Intersect(firstPoint, secondPoint, thidPoint, &tmpHit));
|
||||
REQUIRE(ray.GetPoint(tmpHit) == Nz::Vector3f::UnitY());
|
||||
|
||||
Nz::Vector3f offset = Nz::Vector3f(10.f, 0.f, 10.f);
|
||||
CHECK(!ray.Intersect(firstPoint + offset, secondPoint + offset, thidPoint + offset, &tmpHit));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We try to lerp")
|
||||
{
|
||||
THEN("Compilation should be fine")
|
||||
{
|
||||
Nz::Rayf AxisX = Nz::Rayf::AxisX();
|
||||
Nz::Rayf AxisY = Nz::Rayf::AxisY();
|
||||
REQUIRE(Nz::Rayf::Lerp(AxisX, AxisY, 0.5f) == (Nz::Rayf(Nz::Vector3f::Zero(), Nz::Vector3f(0.5f, 0.5f, 0.f))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,5 +52,17 @@ SCENARIO("Rect", "[MATH][RECT]")
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We try to lerp")
|
||||
{
|
||||
THEN("Compilation should be fine")
|
||||
{
|
||||
Nz::Rectf nullRect = Nz::Rectf::Zero();
|
||||
Nz::Rectf centerAndUnit = firstCenterAndUnit;
|
||||
Nz::Rectf result(Nz::Vector2f::Zero(), Nz::Vector2f::Unit() * 0.5f);
|
||||
|
||||
REQUIRE(Nz::Rectf::Lerp(nullRect, centerAndUnit, 0.5f) == result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,5 +59,45 @@ SCENARIO("Sphere", "[MATH][SPHERE]")
|
|||
REQUIRE(centerUnitBox.GetSquaredBoundingSphere() == Nz::Spheref(Nz::Vector3f::Zero(), 0.75f));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We ask for positive and negative vertex")
|
||||
{
|
||||
Nz::Vector3f positiveVector = Nz::Vector3f::UnitY();
|
||||
|
||||
THEN("Positive vertex should be the same with centered and unit sphere")
|
||||
{
|
||||
REQUIRE(positiveVector == firstCenterAndUnit.GetPositiveVertex(positiveVector));
|
||||
}
|
||||
|
||||
AND_THEN("Negative vertex should be the opposite")
|
||||
{
|
||||
REQUIRE(-positiveVector == firstCenterAndUnit.GetNegativeVertex(positiveVector));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We extend the unit sphere to one point")
|
||||
{
|
||||
Nz::Vector3f point = Nz::Vector3f::UnitY() * 2.f;
|
||||
|
||||
firstCenterAndUnit.ExtendTo(point);
|
||||
|
||||
THEN("Sphere must contain it and distance should be good")
|
||||
{
|
||||
CHECK(firstCenterAndUnit.Contains(point));
|
||||
REQUIRE(firstCenterAndUnit.Distance(point) == 2.f);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We try to lerp")
|
||||
{
|
||||
THEN("Compilation should be fine")
|
||||
{
|
||||
Nz::Spheref nullRect = Nz::Spheref::Zero();
|
||||
Nz::Spheref centerAndUnit = firstCenterAndUnit;
|
||||
Nz::Spheref result(Nz::Vector3f::Zero(), 0.5f);
|
||||
|
||||
REQUIRE(Nz::Spheref::Lerp(nullRect, centerAndUnit, 0.5f) == result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ SCENARIO("Vector2", "[MATH][VECTOR2]")
|
|||
THEN("They are the same")
|
||||
{
|
||||
REQUIRE(firstUnit == secondUnit);
|
||||
REQUIRE(firstUnit <= secondUnit);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -22,11 +23,13 @@ SCENARIO("Vector2", "[MATH][VECTOR2]")
|
|||
{
|
||||
Nz::Vector2f tmp(-1.f, 1.f);
|
||||
|
||||
THEN("These results are expected")
|
||||
THEN("These are perpendicular")
|
||||
{
|
||||
REQUIRE(firstUnit.AbsDotProduct(tmp) == Approx(2.f));
|
||||
REQUIRE(firstUnit.DotProduct(tmp) == Approx(0.f));
|
||||
REQUIRE(firstUnit.AngleBetween(tmp) == Approx(90.f));
|
||||
REQUIRE(firstUnit.AngleBetween(tmp) == Approx(Nz::FromDegrees(90.f)));
|
||||
Nz::Vector2f negativeUnitX = -Nz::Vector2f::UnitX();
|
||||
REQUIRE(negativeUnitX.AngleBetween(negativeUnitX + Nz::Vector2f(0, 0.0000001f)) == Approx(Nz::FromDegrees(360.f)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -45,5 +48,49 @@ SCENARIO("Vector2", "[MATH][VECTOR2]")
|
|||
REQUIRE(firstUnit.GetLength() == Approx(std::sqrt(2.f)));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We nomalize the vectors")
|
||||
{
|
||||
float ratio = 0.f;
|
||||
THEN("For normal cases should be normal")
|
||||
{
|
||||
Nz::Vector2f normalized = firstUnit.GetNormal(&ratio);
|
||||
REQUIRE(normalized == (Nz::Vector2f::Unit() / std::sqrt(2.f)));
|
||||
REQUIRE(ratio == Approx(std::sqrt(2.f)));
|
||||
}
|
||||
|
||||
THEN("For null vector")
|
||||
{
|
||||
Nz::Vector2f zero = Nz::Vector2f::Zero();
|
||||
REQUIRE(zero.GetNormal(&ratio) == Nz::Vector2f::Zero());
|
||||
REQUIRE(ratio == Approx(0.f));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We try to maximize and minimize")
|
||||
{
|
||||
Nz::Vector2f maximize(2.f, 1.f);
|
||||
Nz::Vector2f minimize(1.f, 2.f);
|
||||
|
||||
THEN("The minimised and maximised should be (1, 1) and (2, 2)")
|
||||
{
|
||||
Nz::Vector2f maximized = maximize;
|
||||
Nz::Vector2f minimized = minimize;
|
||||
REQUIRE(minimized.Minimize(maximized) == Nz::Vector2f::Unit());
|
||||
REQUIRE(maximize.Maximize(minimize) == (2.f * Nz::Vector2f::Unit()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WHEN("We try to lerp")
|
||||
{
|
||||
THEN("Compilation should be fine")
|
||||
{
|
||||
Nz::Vector2f zero = Nz::Vector2f::Zero();
|
||||
Nz::Vector2f unit = Nz::Vector2f::Unit();
|
||||
REQUIRE(Nz::Vector2f::Lerp(zero, unit, 0.5f) == (Nz::Vector2f::Unit() * 0.5f));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@ SCENARIO("Vector3", "[MATH][VECTOR3]")
|
|||
{
|
||||
REQUIRE(firstUnit.AbsDotProduct(tmp) == Approx(2.f));
|
||||
REQUIRE(firstUnit.DotProduct(tmp) == Approx(0.f));
|
||||
REQUIRE(firstUnit.AngleBetween(tmp) == Approx(90.f));
|
||||
REQUIRE(firstUnit.AngleBetween(tmp) == Approx(Nz::FromDegrees(90.f)));
|
||||
REQUIRE(firstUnit.AngleBetween(-firstUnit) == Approx(Nz::FromDegrees(180.f)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -52,5 +53,48 @@ SCENARIO("Vector3", "[MATH][VECTOR3]")
|
|||
REQUIRE(firstUnit.GetLength() == Approx(std::sqrt(3.f)));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We nomalize the vectors")
|
||||
{
|
||||
float ratio = 0.f;
|
||||
THEN("For normal cases should be normal")
|
||||
{
|
||||
Nz::Vector3f normalized = firstUnit.GetNormal(&ratio);
|
||||
REQUIRE(normalized == (Nz::Vector3f::Unit() / std::sqrt(3.f)));
|
||||
REQUIRE(ratio == Approx(std::sqrt(3.f)));
|
||||
}
|
||||
|
||||
THEN("For null vector")
|
||||
{
|
||||
Nz::Vector3f zero = Nz::Vector3f::Zero();
|
||||
REQUIRE(zero.GetNormal(&ratio) == Nz::Vector3f::Zero());
|
||||
REQUIRE(ratio == Approx(0.f));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We try to maximize and minimize")
|
||||
{
|
||||
Nz::Vector3f maximize(2.f, 1.f, 2.f);
|
||||
Nz::Vector3f minimize(1.f, 2.f, 1.f);
|
||||
|
||||
THEN("The minimised and maximised should be (1, 1, 1) and (2, 2, 2)")
|
||||
{
|
||||
Nz::Vector3f maximized = maximize;
|
||||
Nz::Vector3f minimized = minimize;
|
||||
REQUIRE(minimized.Minimize(maximized) == Nz::Vector3f::Unit());
|
||||
REQUIRE(maximize.Maximize(minimize) == (2.f * Nz::Vector3f::Unit()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WHEN("We try to lerp")
|
||||
{
|
||||
THEN("Compilation should be fine")
|
||||
{
|
||||
Nz::Vector3f zero = Nz::Vector3f::Zero();
|
||||
Nz::Vector3f unit = Nz::Vector3f::Unit();
|
||||
REQUIRE(Nz::Vector3f::Lerp(zero, unit, 0.5f) == (Nz::Vector3f::Unit() * 0.5f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,5 +39,15 @@ SCENARIO("Vector4", "[MATH][VECTOR4]")
|
|||
REQUIRE(tmp.Normalize() == Nz::Vector4f(Nz::Vector3f::Unit() * (1.f / 3.f), 1.f));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We try to lerp")
|
||||
{
|
||||
THEN("Compilation should be fine")
|
||||
{
|
||||
Nz::Vector4f zero = Nz::Vector4f::Zero();
|
||||
Nz::Vector4f unitX = Nz::Vector4f::UnitX();
|
||||
REQUIRE(Nz::Vector4f::Lerp(zero, unitX, 0.5f) == Nz::Vector4f(Nz::Vector3f::UnitX() * 0.5f, 1.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue