Refactored mathematics module
Added AABBs Added code examples Added experimental support for texture arrays (1D/2D) Added initialisers (new way of initialising modules) Added global headers (Plus a global header generator script) Added pattern support for directory Added support for spinlocks critical section on Windows Added NzRenderWindow::SetFramerateLimit Core project now includes Mathematics files Fixed color implementation using double Fixed declaration needing renderer include Fixed MLT not clearing nextFree(File/Line) after Free Fixed move operators not being noexcept Fixed thread-safety (Now working correctly - If I'm lucky) Moved Resource to core New interface for modules New interface for the renderer Put some global functions to anonymous namespace Removed empty modules Renamed ThreadCondition to ConditionVariable Replaced redirect to cerr log option by duplicate to cout Setting mouse position relative to a window will make this window ignore the event Shaders sending methods no longer takes the uniform variable name (it's using ID instead) Using new OpenGL 4.3 header
This commit is contained in:
@@ -10,6 +10,8 @@
|
||||
#include <cstring>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
#define F(a) static_cast<T>(a)
|
||||
|
||||
template<typename T>
|
||||
T NzApproach(T value, T objective, T increment)
|
||||
{
|
||||
@@ -45,7 +47,7 @@ T NzDegrees(T degrees)
|
||||
template<typename T>
|
||||
T NzDegreeToRadian(T degrees)
|
||||
{
|
||||
return degrees * (M_PI/180.0);
|
||||
return degrees * F(M_PI/180.0);
|
||||
}
|
||||
|
||||
unsigned int NzGetNumberLength(signed char number)
|
||||
@@ -53,7 +55,15 @@ unsigned int NzGetNumberLength(signed char number)
|
||||
if (number == 0)
|
||||
return 1;
|
||||
|
||||
return static_cast<unsigned int>(std::log10(std::abs(number)))+(number < 0 ? 2 : 1);
|
||||
// Le standard définit le char comme étant codé sur un octet
|
||||
static_assert(sizeof(number) == 1, "Signed char must be one byte-sized");
|
||||
|
||||
if (number >= 100)
|
||||
return 3;
|
||||
else if (number >= 10)
|
||||
return 2;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int NzGetNumberLength(unsigned char number)
|
||||
@@ -61,7 +71,15 @@ unsigned int NzGetNumberLength(unsigned char number)
|
||||
if (number == 0)
|
||||
return 1;
|
||||
|
||||
return static_cast<unsigned int>(std::log10(number))+1;
|
||||
// Le standard définit le char comme étant codé sur un octet
|
||||
static_assert(sizeof(number) == 1, "Signed char must be one byte-sized");
|
||||
|
||||
if (number >= 100)
|
||||
return 3;
|
||||
else if (number >= 10)
|
||||
return 2;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int NzGetNumberLength(short number)
|
||||
@@ -152,20 +170,20 @@ T NzNormalizeAngle(T angle)
|
||||
#if NAZARA_MATH_ANGLE_RADIAN
|
||||
const T limit = M_PI;
|
||||
#else
|
||||
const T limit = 180.0;
|
||||
const T limit = F(180.0);
|
||||
#endif
|
||||
|
||||
///TODO: Trouver une solution sans duplication
|
||||
if (angle > 0.0)
|
||||
if (angle > F(0.0))
|
||||
{
|
||||
angle += limit;
|
||||
angle -= static_cast<int>(angle/(2.0*limit))*(2.0*limit);
|
||||
angle -= static_cast<int>(angle/(F(2.0)*limit))*(F(2.0)*limit);
|
||||
angle -= limit;
|
||||
}
|
||||
else
|
||||
{
|
||||
angle -= limit;
|
||||
angle -= static_cast<int>(angle/(2.0*limit))*(2.0*limit);
|
||||
angle -= static_cast<int>(angle/(F(2.0)*limit))*(F(2.0)*limit);
|
||||
angle += limit;
|
||||
}
|
||||
|
||||
@@ -175,11 +193,7 @@ T NzNormalizeAngle(T angle)
|
||||
template<typename T>
|
||||
bool NzNumberEquals(T a, T b)
|
||||
{
|
||||
if (a > b)
|
||||
return (a-b) <= std::numeric_limits<T>::epsilon();
|
||||
else
|
||||
return (b-a) <= std::numeric_limits<T>::epsilon();
|
||||
|
||||
return std::fabs(a-b) <= std::numeric_limits<T>::epsilon();
|
||||
}
|
||||
|
||||
NzString NzNumberToString(long long number, nzUInt8 radix)
|
||||
@@ -235,7 +249,7 @@ T NzRadians(T radians)
|
||||
template<typename T>
|
||||
T NzRadianToDegree(T radians)
|
||||
{
|
||||
return radians * (180.0/M_PI);
|
||||
return radians * F(180.0/M_PI);
|
||||
}
|
||||
|
||||
long long NzStringToNumber(NzString str, nzUInt8 radix, bool* ok)
|
||||
@@ -288,4 +302,6 @@ long long NzStringToNumber(NzString str, nzUInt8 radix, bool* ok)
|
||||
return (negative) ? -static_cast<long long>(total) : total;
|
||||
}
|
||||
|
||||
#undef F
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
||||
@@ -36,15 +36,17 @@
|
||||
// Définit la disposition des matrices en colonnes (Façon OpenGL)
|
||||
#define NAZARA_MATH_MATRIX_COLUMN_MAJOR 1
|
||||
|
||||
// Optimise les opérations entre matrices affines (Demande plusieurs comparaisons pour déterminer si une matrice est affine)
|
||||
#define NAZARA_MATH_MATRIX4_CHECK_AFFINE 0
|
||||
|
||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||
#define NAZARA_MATH_SAFE 1
|
||||
|
||||
// Protège le module des accès concurrentiels
|
||||
// Protège les classes des accès concurrentiels
|
||||
#define NAZARA_MATH_THREADSAFE 1
|
||||
|
||||
#if NAZARA_MATH_THREADSAFE
|
||||
#define NAZARA_THREADSAFETY_MATRIX3 1 // NzMatrix3 (COW)
|
||||
#define NAZARA_THREADSAFETY_MATRIX4 1 // NzMatrix4 (COW)
|
||||
#endif
|
||||
// Les classes à protéger des accès concurrentiels
|
||||
#define NAZARA_THREADSAFETY_MATRIX3 1 // NzMatrix3 (COW)
|
||||
#define NAZARA_THREADSAFETY_MATRIX4 1 // NzMatrix4 (COW)
|
||||
|
||||
#endif // NAZARA_CONFIG_MATH_HPP
|
||||
|
||||
@@ -17,8 +17,9 @@ class NzCube
|
||||
public:
|
||||
NzCube();
|
||||
NzCube(T X, T Y, T Z, T Width, T Height, T Depth);
|
||||
NzCube(T cube[6]);
|
||||
NzCube(const T cube[6]);
|
||||
NzCube(const NzRect<T>& rect);
|
||||
NzCube(const NzVector3<T>& vec1, const NzVector3<T>& vec2);
|
||||
template<typename U> explicit NzCube(const NzCube<U>& rect);
|
||||
NzCube(const NzCube& rect) = default;
|
||||
~NzCube() = default;
|
||||
@@ -32,11 +33,16 @@ class NzCube
|
||||
|
||||
NzVector3<T> GetCenter() const;
|
||||
|
||||
bool Intersect(const NzCube& rect) const;
|
||||
bool Intersect(const NzCube& rect, NzCube& intersection) const;
|
||||
bool Intersect(const NzCube& rect, NzCube* intersection = nullptr) const;
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
void Set(T X, T Y, T Z, T Width, T Height, T Depth);
|
||||
void Set(const T rect[6]);
|
||||
void Set(const NzRect<T>& rect);
|
||||
void Set(const NzVector3<T>& vec1, const NzVector3<T>& vec2);
|
||||
template<typename U> void Set(const NzCube<U>& rect);
|
||||
|
||||
NzString ToString() const;
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
@@ -6,54 +6,42 @@
|
||||
#include <algorithm>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
#define F(a) static_cast<T>(a)
|
||||
|
||||
template<typename T>
|
||||
NzCube<T>::NzCube()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzCube<T>::NzCube(T X, T Y, T Z, T Width, T Height, T Depth) :
|
||||
x(X),
|
||||
y(Y),
|
||||
z(Z),
|
||||
width(Width),
|
||||
height(Height),
|
||||
depth(Depth)
|
||||
NzCube<T>::NzCube(T X, T Y, T Z, T Width, T Height, T Depth)
|
||||
{
|
||||
Set(X, Y, Z, Width, Height, Depth);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzCube<T>::NzCube(T vec[6]) :
|
||||
x(vec[0]),
|
||||
y(vec[1]),
|
||||
z(vec[2]),
|
||||
width(vec[3]),
|
||||
height(vec[4]),
|
||||
depth(vec[5])
|
||||
NzCube<T>::NzCube(const T vec[6])
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzCube<T>::NzCube(const NzRect<T>& rect) :
|
||||
x(rect.x),
|
||||
y(rect.y),
|
||||
z(0),
|
||||
width(rect.width),
|
||||
height(rect.height),
|
||||
depth(1)
|
||||
NzCube<T>::NzCube(const NzRect<T>& rect)
|
||||
{
|
||||
Set(rect);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzCube<T>::NzCube(const NzVector3<T>& vec1, const NzVector3<T>& vec2)
|
||||
{
|
||||
Set(vec1, vec2);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
NzCube<T>::NzCube(const NzCube<U>& rect) :
|
||||
x(static_cast<T>(rect.x)),
|
||||
y(static_cast<T>(rect.y)),
|
||||
z(static_cast<T>(rect.z)),
|
||||
width(static_cast<T>(rect.width)),
|
||||
height(static_cast<T>(rect.height)),
|
||||
depth(static_cast<T>(rect.depth))
|
||||
NzCube<T>::NzCube(const NzCube<U>& rect)
|
||||
{
|
||||
Set(rect);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -102,18 +90,11 @@ void NzCube<T>::ExtendTo(const NzCube& rect)
|
||||
template<typename T>
|
||||
NzVector3<T> NzCube<T>::GetCenter() const
|
||||
{
|
||||
return NzVector3<T>((x+width)/2, (y+height)/2, (z+depth)/2);
|
||||
return NzVector3<T>((x+width)/F(2.0), (y+height)/F(2.0), (z+depth)/F(2.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzCube<T>::Intersect(const NzCube& rect) const
|
||||
{
|
||||
NzCube intersection; // Optimisé par le compilateur
|
||||
return Intersect(rect, intersection);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzCube<T>::Intersect(const NzCube& rect, NzCube& intersection) const
|
||||
bool NzCube<T>::Intersect(const NzCube& rect, NzCube* intersection) const
|
||||
{
|
||||
T left = std::max(x, rect.x);
|
||||
T right = std::min(x+width, rect.x+rect.width);
|
||||
@@ -124,12 +105,15 @@ bool NzCube<T>::Intersect(const NzCube& rect, NzCube& intersection) const
|
||||
|
||||
if (left < right && top < bottom && up < down)
|
||||
{
|
||||
intersection.x = left;
|
||||
intersection.y = top;
|
||||
intersection.z = up;
|
||||
intersection.width = right-left;
|
||||
intersection.height = bottom-top;
|
||||
intersection.depth = down-up;
|
||||
if (intersection)
|
||||
{
|
||||
intersection->x = left;
|
||||
intersection->y = top;
|
||||
intersection->z = up;
|
||||
intersection->width = right-left;
|
||||
intersection->height = bottom-top;
|
||||
intersection->depth = down-up;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -140,7 +124,63 @@ bool NzCube<T>::Intersect(const NzCube& rect, NzCube& intersection) const
|
||||
template<typename T>
|
||||
bool NzCube<T>::IsValid() const
|
||||
{
|
||||
return width > 0 && height > 0 && depth > 0;
|
||||
return width > F(0.0) && height > F(0.0) && depth > F(0.0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzCube<T>::Set(T X, T Y, T Z, T Width, T Height, T Depth)
|
||||
{
|
||||
x = X;
|
||||
y = Y;
|
||||
z = Z;
|
||||
width = Width;
|
||||
height = Height;
|
||||
depth = Depth;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzCube<T>::Set(const T rect[6])
|
||||
{
|
||||
x = rect[0];
|
||||
y = rect[1];
|
||||
z = rect[2];
|
||||
width = rect[3];
|
||||
height = rect[4];
|
||||
depth = rect[5];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzCube<T>::Set(const NzRect<T>& rect)
|
||||
{
|
||||
x = rect.x;
|
||||
y = rect.y;
|
||||
z = 0;
|
||||
width = rect.width;
|
||||
height = rect.height;
|
||||
depth = 1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzCube<T>::Set(const NzVector3<T>& vec1, const NzVector3<T>& vec2)
|
||||
{
|
||||
x = std::min(vec1.x, vec2.x);
|
||||
y = std::min(vec1.y, vec2.y);
|
||||
z = std::min(vec1.z, vec2.z);
|
||||
width = (vec2.x > vec1.x) ? vec2.x-vec1.x : vec1.x-vec2.x;
|
||||
height = (vec2.y > vec1.y) ? vec2.y-vec1.y : vec1.y-vec2.y;
|
||||
depth = (vec2.z > vec1.z) ? vec2.z-vec1.z : vec1.z-vec2.z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
void NzCube<T>::Set(const NzCube<U>& cube)
|
||||
{
|
||||
x = F(cube.x);
|
||||
y = F(cube.y);
|
||||
z = F(cube.z);
|
||||
width = F(cube.width);
|
||||
height = F(cube.height);
|
||||
depth = F(cube.depth);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -160,13 +200,15 @@ NzCube<T>::operator NzString() const
|
||||
template<typename T>
|
||||
T& NzCube<T>::operator[](unsigned int i)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (i >= 6)
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 4)";
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 6)";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return *(&x+i);
|
||||
}
|
||||
@@ -174,13 +216,15 @@ T& NzCube<T>::operator[](unsigned int i)
|
||||
template<typename T>
|
||||
T NzCube<T>::operator[](unsigned int i) const
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (i >= 6)
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 4)";
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 6)";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return *(&x+i);
|
||||
}
|
||||
@@ -191,4 +235,6 @@ std::ostream& operator<<(std::ostream& out, const NzCube<T>& rect)
|
||||
return out << rect.ToString();
|
||||
}
|
||||
|
||||
#undef F
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
||||
@@ -9,9 +9,8 @@
|
||||
#define NAZARA_EULERANGLES_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
|
||||
template<typename T> class NzQuaternion;
|
||||
template<typename T> class NzVector3;
|
||||
#include <Nazara/Math/Quaternion.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
|
||||
template<typename T> class NzEulerAngles
|
||||
{
|
||||
@@ -25,9 +24,7 @@ template<typename T> class NzEulerAngles
|
||||
NzEulerAngles(const NzEulerAngles& angles) = default;
|
||||
~NzEulerAngles() = default;
|
||||
|
||||
NzVector3<T> GetForward() const;
|
||||
NzVector3<T> GetRight() const;
|
||||
NzVector3<T> GetUp() const;
|
||||
void MakeZero();
|
||||
|
||||
void Normalize();
|
||||
|
||||
@@ -37,25 +34,28 @@ template<typename T> class NzEulerAngles
|
||||
//void Set(const NzMatrix3<T>& mat);
|
||||
void Set(const NzQuaternion<T>& quat);
|
||||
template<typename U> void Set(const NzEulerAngles<U>& angles);
|
||||
void SetZero();
|
||||
|
||||
//NzMatrix3<T> ToRotationMatrix() const;
|
||||
NzQuaternion<T> ToQuaternion() const;
|
||||
NzString ToString() const;
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
NzEulerAngles operator+(const NzEulerAngles& angles) const;
|
||||
NzEulerAngles operator-(const NzEulerAngles& angles) const;
|
||||
NzEulerAngles operator*(const NzEulerAngles& angles) const;
|
||||
NzEulerAngles operator/(const NzEulerAngles& angles) const;
|
||||
/*NzEulerAngles operator*(const NzEulerAngles& angles) const;
|
||||
NzEulerAngles operator/(const NzEulerAngles& angles) const;*/
|
||||
|
||||
NzEulerAngles operator+=(const NzEulerAngles& angles);
|
||||
NzEulerAngles operator-=(const NzEulerAngles& angles);
|
||||
NzEulerAngles operator*=(const NzEulerAngles& angles);
|
||||
NzEulerAngles operator/=(const NzEulerAngles& angles);
|
||||
/*NzEulerAngles operator*=(const NzEulerAngles& angles);
|
||||
NzEulerAngles operator/=(const NzEulerAngles& angles);*/
|
||||
|
||||
bool operator==(const NzEulerAngles& angles) const;
|
||||
bool operator!=(const NzEulerAngles& angles) const;
|
||||
|
||||
static NzEulerAngles Zero();
|
||||
|
||||
T pitch, yaw, roll;
|
||||
};
|
||||
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
#include <Nazara/Math/Config.hpp>
|
||||
#include <Nazara/Math/Quaternion.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <cmath>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
#define F(a) static_cast<T>(a)
|
||||
|
||||
template<typename T>
|
||||
NzEulerAngles<T>::NzEulerAngles()
|
||||
{
|
||||
@@ -41,33 +42,9 @@ NzEulerAngles<T>::NzEulerAngles(const NzEulerAngles<U>& angles)
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T> NzEulerAngles<T>::GetForward() const
|
||||
void NzEulerAngles<T>::MakeZero()
|
||||
{
|
||||
#if NAZARA_MATH_ANGLE_RADIAN
|
||||
return NzVector3<T>(std::cos(yaw), std::sin(roll), std::sin(yaw));
|
||||
#else
|
||||
return NzVector3<T>(std::cos(NzDegreeToRadian(yaw)), std::sin(NzDegreeToRadian(roll)), std::sin(NzDegreeToRadian(yaw)));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T> NzEulerAngles<T>::GetRight() const
|
||||
{
|
||||
#if NAZARA_MATH_ANGLE_RADIAN
|
||||
return NzVector3<T>(std::sin(yaw), std::sin(pitch), std::cos(pitch));
|
||||
#else
|
||||
return NzVector3<T>(std::sin(NzDegreeToRadian(yaw)), std::sin(NzDegreeToRadian(pitch)), std::cos(NzDegreeToRadian(pitch)));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T> NzEulerAngles<T>::GetUp() const
|
||||
{
|
||||
#if NAZARA_MATH_ANGLE_RADIAN
|
||||
return NzVector3<T>(std::sin(roll), std::cos(pitch), -std::sin(pitch));
|
||||
#else
|
||||
return NzVector3<T>(std::sin(NzDegreeToRadian(roll)), std::cos(NzDegreeToRadian(pitch)), -std::sin(NzDegreeToRadian(pitch)));
|
||||
#endif
|
||||
Set(F(0.0), F(0.0), F(0.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -117,20 +94,14 @@ void NzEulerAngles<T>::Set(const NzEulerAngles<U>& angles)
|
||||
roll = static_cast<T>(angles.roll);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzEulerAngles<T>::SetZero()
|
||||
{
|
||||
Set(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzEulerAngles<T>::ToQuaternion() const
|
||||
{
|
||||
NzQuaternion<T> Qx(pitch, NzVector3<T>(1.0, 0.0, 0.0));
|
||||
NzQuaternion<T> Qy(yaw, NzVector3<T>(0.0, 1.0, 0.0));
|
||||
NzQuaternion<T> Qz(roll, NzVector3<T>(0.0, 0.0, 1.0));
|
||||
NzQuaternion<T> rotX(pitch, NzVector3<T>(F(1.0), F(0.0), F(0.0)));
|
||||
NzQuaternion<T> rotY(yaw, NzVector3<T>(F(0.0), F(1.0), F(0.0)));
|
||||
NzQuaternion<T> rotZ(roll, NzVector3<T>(F(0.0), F(0.0), F(1.0)));
|
||||
|
||||
return Qx * Qy * Qz;
|
||||
return rotY * rotX * rotZ;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -141,6 +112,12 @@ NzString NzEulerAngles<T>::ToString() const
|
||||
return ss << "EulerAngles(" << pitch << ", " << yaw << ", " << roll << ')';
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzEulerAngles<T>::operator NzString() const
|
||||
{
|
||||
return ToString();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzEulerAngles<T> NzEulerAngles<T>::operator+(const NzEulerAngles& angles) const
|
||||
{
|
||||
@@ -191,10 +168,21 @@ bool NzEulerAngles<T>::operator!=(const NzEulerAngles& angles) const
|
||||
return !operator==(angles);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzEulerAngles<T> NzEulerAngles<T>::Zero()
|
||||
{
|
||||
NzEulerAngles angles;
|
||||
angles.MakeZero();
|
||||
|
||||
return angles;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const NzEulerAngles<T>& angles)
|
||||
{
|
||||
return out << angles.ToString();
|
||||
}
|
||||
|
||||
#undef F
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
||||
23
include/Nazara/Math/Math.hpp
Normal file
23
include/Nazara/Math/Math.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Nazara Engine
|
||||
|
||||
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
@@ -8,8 +8,9 @@
|
||||
#define NAZARA_MATRIX4_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Math/Config.hpp>
|
||||
|
||||
#if NAZARA_THREADSAFETY_MATRIX4
|
||||
#if NAZARA_MATH_THREADSAFE && NAZARA_THREADSAFETY_MATRIX4
|
||||
#include <Nazara/Core/ThreadSafety.hpp>
|
||||
#else
|
||||
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
||||
@@ -26,18 +27,21 @@ template<typename T> class NzMatrix4
|
||||
public:
|
||||
NzMatrix4();
|
||||
NzMatrix4(T r11, T r12, T r13, T r14,
|
||||
T r21, T r22, T r23, T r24,
|
||||
T r31, T r32, T r33, T r34,
|
||||
T r41, T r42, T r43, T r44);
|
||||
T r21, T r22, T r23, T r24,
|
||||
T r31, T r32, T r33, T r34,
|
||||
T r41, T r42, T r43, T r44);
|
||||
NzMatrix4(const T matrix[16]);
|
||||
//NzMatrix4(const NzMatrix3<T>& matrix);
|
||||
template<typename U> explicit NzMatrix4(const NzMatrix4<U>& matrix);
|
||||
NzMatrix4(const NzMatrix4& matrix);
|
||||
NzMatrix4(NzMatrix4&& matrix);
|
||||
NzMatrix4(NzMatrix4&& matrix) noexcept;
|
||||
~NzMatrix4();
|
||||
|
||||
NzMatrix4 Concatenate(const NzMatrix4& matrix) const;
|
||||
|
||||
T GetDeterminant() const;
|
||||
NzMatrix4 GetInverse() const;
|
||||
NzQuaternion<T> GetRotation() const;
|
||||
//NzMatrix3 GetRotationMatrix() const;
|
||||
NzVector3<T> GetScale() const;
|
||||
NzVector3<T> GetTranslation() const;
|
||||
@@ -46,23 +50,30 @@ template<typename T> class NzMatrix4
|
||||
bool HasNegativeScale() const;
|
||||
bool HasScale() const;
|
||||
|
||||
bool IsAffine() const;
|
||||
bool IsDefined() const;
|
||||
|
||||
void MakeIdentity();
|
||||
void MakeLookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up);
|
||||
void MakeOrtho(T left, T top, T width, T height, T zNear = -1.0, T zFar = 1.0);
|
||||
void MakePerspective(T angle, T ratio, T zNear, T zFar);
|
||||
void MakeRotation(const NzQuaternion<T>& rotation);
|
||||
void MakeScale(const NzVector3<T>& scale);
|
||||
void MakeTranslation(const NzVector3<T>& translation);
|
||||
void MakeZero();
|
||||
|
||||
void Set(T r11, T r12, T r13, T r14,
|
||||
T r21, T r22, T r23, T r24,
|
||||
T r31, T r32, T r33, T r34,
|
||||
T r41, T r42, T r43, T r44);
|
||||
T r21, T r22, T r23, T r24,
|
||||
T r31, T r32, T r33, T r34,
|
||||
T r41, T r42, T r43, T r44);
|
||||
void Set(const T matrix[16]);
|
||||
//NzMatrix4(const NzMatrix3<T>& matrix);
|
||||
void Set(const NzMatrix4& matrix);
|
||||
void Set(NzMatrix4&& matrix);
|
||||
template<typename U> void Set(const NzMatrix4<U>& matrix);
|
||||
void SetIdentity();
|
||||
void SetLookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up);
|
||||
void SetOrtho(T left, T top, T width, T height, T zNear = -1.0, T zFar = 1.0);
|
||||
void SetPerspective(T angle, T ratio, T zNear, T zFar);
|
||||
void SetRotation(const NzQuaternion<T>& rotation);
|
||||
void SetScale(const NzVector3<T>& scale);
|
||||
void SetTranslation(const NzVector3<T>& translation);
|
||||
void SetZero();
|
||||
|
||||
NzString ToString() const;
|
||||
|
||||
@@ -72,6 +83,8 @@ template<typename T> class NzMatrix4
|
||||
|
||||
NzMatrix4& Transpose();
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
operator T*();
|
||||
operator const T*() const;
|
||||
|
||||
@@ -79,7 +92,7 @@ template<typename T> class NzMatrix4
|
||||
const T& operator()(unsigned int x, unsigned int y) const;
|
||||
|
||||
NzMatrix4& operator=(const NzMatrix4& matrix);
|
||||
NzMatrix4& operator=(NzMatrix4&& matrix);
|
||||
NzMatrix4& operator=(NzMatrix4&& matrix) noexcept;
|
||||
|
||||
NzMatrix4 operator*(const NzMatrix4& matrix) const;
|
||||
NzVector2<T> operator*(const NzVector2<T>& vector) const;
|
||||
@@ -90,12 +103,16 @@ template<typename T> class NzMatrix4
|
||||
NzMatrix4& operator*=(const NzMatrix4& matrix);
|
||||
NzMatrix4& operator*=(T scalar);
|
||||
|
||||
static NzMatrix4 Concatenate(const NzMatrix4& m1, const NzMatrix4& m2);
|
||||
static NzMatrix4 ConcatenateAffine(const NzMatrix4& m1, const NzMatrix4& m2);
|
||||
static NzMatrix4 Identity();
|
||||
static NzMatrix4 LookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up);
|
||||
static NzMatrix4 Ortho(T left, T top, T width, T height, T zNear = -1.0, T zFar = 1.0);
|
||||
static NzMatrix4 Perspective(T angle, T ratio, T zNear, T zFar);
|
||||
static NzMatrix4 Rotate(const NzQuaternion<T>& rotation);
|
||||
static NzMatrix4 Scale(const NzVector3<T>& scale);
|
||||
static NzMatrix4 Translate(const NzVector3<T>& translation);
|
||||
static NzMatrix4 Zero();
|
||||
|
||||
struct SharedMatrix
|
||||
{
|
||||
@@ -112,11 +129,13 @@ template<typename T> class NzMatrix4
|
||||
void EnsureOwnership();
|
||||
void ReleaseMatrix();
|
||||
|
||||
SharedMatrix* m_sharedMatrix;
|
||||
SharedMatrix* m_sharedMatrix = nullptr;
|
||||
};
|
||||
|
||||
template<typename T> std::ostream& operator<<(std::ostream& out, const NzMatrix4<T>& matrix);
|
||||
|
||||
template<typename T> NzMatrix4<T> operator*(T scale, const NzMatrix4<T>& matrix);
|
||||
|
||||
typedef NzMatrix4<double> NzMatrix4d;
|
||||
typedef NzMatrix4<float> NzMatrix4f;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,9 +31,12 @@ template<typename T> class NzQuaternion
|
||||
NzQuaternion GetConjugate() const;
|
||||
NzQuaternion GetNormalized() const;
|
||||
|
||||
void MakeIdentity();
|
||||
void MakeZero();
|
||||
|
||||
T Magnitude() const;
|
||||
|
||||
T Normalize();
|
||||
T SquaredMagnitude() const;
|
||||
|
||||
void Set(T W, T X, T Y, T Z);
|
||||
void Set(T quat[4]);
|
||||
@@ -42,13 +45,17 @@ template<typename T> class NzQuaternion
|
||||
//void Set(const NzMatrix3<T>& mat);
|
||||
void Set(const NzQuaternion& quat);
|
||||
template<typename U> void Set(const NzQuaternion<U>& quat);
|
||||
void SetIdentity();
|
||||
void SetZero();
|
||||
|
||||
T SquaredMagnitude() const;
|
||||
|
||||
NzEulerAngles<T> ToEulerAngles() const;
|
||||
//NzMatrix3<T> ToRotationMatrix() const;
|
||||
NzString ToString() const;
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
NzQuaternion& operator=(const NzQuaternion& quat);
|
||||
|
||||
NzQuaternion operator+(const NzQuaternion& quat) const;
|
||||
NzQuaternion operator*(const NzQuaternion& quat) const;
|
||||
NzVector3<T> operator*(const NzVector3<T>& vec) const;
|
||||
@@ -67,7 +74,9 @@ template<typename T> class NzQuaternion
|
||||
bool operator>(const NzQuaternion& quat) const;
|
||||
bool operator>=(const NzQuaternion& quat) const;
|
||||
|
||||
static NzQuaternion Identity();
|
||||
static NzQuaternion Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp);
|
||||
static NzQuaternion Zero();
|
||||
|
||||
T w, x, y, z;
|
||||
};
|
||||
|
||||
@@ -8,8 +8,11 @@
|
||||
#include <Nazara/Math/Config.hpp>
|
||||
#include <Nazara/Math/EulerAngles.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <limits>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
#define F(a) static_cast<T>(a)
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>::NzQuaternion()
|
||||
{
|
||||
@@ -53,9 +56,9 @@ NzQuaternion<T>::NzQuaternion(const NzQuaternion<U>& quat)
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzQuaternion<T>::DotProduct(const NzQuaternion& vec) const
|
||||
T NzQuaternion<T>::DotProduct(const NzQuaternion& quat) const
|
||||
{
|
||||
return w*vec.w + x*vec.x + y*vec.y + z.vec.z;
|
||||
return w*quat.w + x*quat.x + y*quat.y + z*quat.z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -73,6 +76,18 @@ NzQuaternion<T> NzQuaternion<T>::GetNormalized() const
|
||||
return quat;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::MakeIdentity()
|
||||
{
|
||||
Set(1.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::MakeZero()
|
||||
{
|
||||
Set(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzQuaternion<T>::Magnitude() const
|
||||
{
|
||||
@@ -82,27 +97,21 @@ T NzQuaternion<T>::Magnitude() const
|
||||
template<typename T>
|
||||
T NzQuaternion<T>::Normalize()
|
||||
{
|
||||
T squaredLength = SquaredMagnitude();
|
||||
T squaredMagnitude = SquaredMagnitude();
|
||||
|
||||
if (std::fabs(squaredLength) > 0.00001 && std::fabs(squaredLength - 1.0) > 0.00001)
|
||||
if (squaredMagnitude-F(1.0) > std::numeric_limits<T>::epsilon())
|
||||
{
|
||||
T length = std::sqrt(squaredLength);
|
||||
T magnitude = std::sqrt(squaredMagnitude);
|
||||
|
||||
w /= length;
|
||||
x /= length;
|
||||
y /= length;
|
||||
z /= length;
|
||||
w /= magnitude;
|
||||
x /= magnitude;
|
||||
y /= magnitude;
|
||||
z /= magnitude;
|
||||
|
||||
return length;
|
||||
return magnitude;
|
||||
}
|
||||
else
|
||||
return 1.0; // Le quaternion est déjà normalisé
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzQuaternion<T>::SquaredMagnitude() const
|
||||
{
|
||||
return w * w + x * x + y * y + z * z;
|
||||
return F(1.0); // Le quaternion est déjà normalisé
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -166,81 +175,29 @@ void NzQuaternion<T>::Set(const NzQuaternion& quat)
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::SetIdentity()
|
||||
T NzQuaternion<T>::SquaredMagnitude() const
|
||||
{
|
||||
Set(1.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::SetZero()
|
||||
{
|
||||
Set(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp)
|
||||
{
|
||||
if (interp <= 0.0)
|
||||
return quatA;
|
||||
|
||||
if (interp >= 1.0)
|
||||
return quatB;
|
||||
|
||||
NzQuaternion q;
|
||||
|
||||
T cosOmega = quatA.DotProduct(quatB);
|
||||
if (cosOmega < 0.0)
|
||||
{
|
||||
// On inverse tout
|
||||
q.Set(-quatB.w, -quatB.x, -quatB.y, -quatB.z);
|
||||
cosOmega = -cosOmega;
|
||||
}
|
||||
else
|
||||
q.Set(quatB);
|
||||
|
||||
T k0, k1;
|
||||
if (cosOmega > 0.9999)
|
||||
{
|
||||
// Interpolation linéaire pour éviter une division par zéro
|
||||
k0 = 1.0 - interp;
|
||||
k1 = interp;
|
||||
}
|
||||
else
|
||||
{
|
||||
T sinOmega = std::sqrt(1.0f - (cosOmega * cosOmega));
|
||||
T omega = std::atan2(sinOmega, cosOmega);
|
||||
|
||||
// Pour éviter deux divisions
|
||||
sinOmega = 1/sinOmega;
|
||||
|
||||
k0 = std::sin((1.0 - interp) * omega) * sinOmega;
|
||||
k1 = std::sin(interp * omega) * sinOmega;
|
||||
}
|
||||
|
||||
NzQuaternion result(k0 * quatA.w, k0 * quatA.x, k0 * quatA.y, k0 * quatA.z);
|
||||
return result += q;
|
||||
return w*w + x*x + y*y + z*z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzEulerAngles<T> NzQuaternion<T>::ToEulerAngles() const
|
||||
{
|
||||
Normalize();
|
||||
|
||||
T test = x*y + z*w;
|
||||
if (test > 0.499)
|
||||
if (test > F(0.499))
|
||||
// singularity at north pole
|
||||
return NzEulerAngles<T>(NzDegrees(90.0), NzRadians(2.0 * std::atan2(x, w)), 0.0);
|
||||
return NzEulerAngles<T>(NzDegrees(F(90.0)), NzRadians(F(2.0) * std::atan2(x, w)), F(0.0));
|
||||
|
||||
if (test < -0.499)
|
||||
return NzEulerAngles<T>(NzDegrees(-90.0), NzRadians(-2.0 * std::atan2(x, w)), 0.0);
|
||||
if (test < F(-0.499))
|
||||
return NzEulerAngles<T>(NzDegrees(F(-90.0)), NzRadians(F(-2.0) * std::atan2(x, w)), F(0.0));
|
||||
|
||||
T xx = x*x;
|
||||
T yy = y*y;
|
||||
T zz = z*z;
|
||||
|
||||
return NzEulerAngles<T>(NzRadians(std::atan2(2.0*x*w - 2.0*y*z, 1.0 - 2.0*xx - 2.0*zz)),
|
||||
NzRadians(std::atan2(2.0*y*w - 2.0*x*z, 1.f - 2.0*yy - 2.0*zz)),
|
||||
NzRadians(std::asin(2.0*test)));
|
||||
return NzEulerAngles<T>(NzRadians(std::atan2(F(2.0)*x*w - F(2.0)*y*z, F(1.0) - F(2.0)*xx - F(2.0)*zz)),
|
||||
NzRadians(std::atan2(F(2.0)*y*w - F(2.0)*x*z, F(1.0) - F(2.0)*yy - F(2.0)*zz)),
|
||||
NzRadians(std::asin(F(2.0)*test)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -251,6 +208,20 @@ NzString NzQuaternion<T>::ToString() const
|
||||
return ss << "Quaternion(" << w << " | " << x << ", " << y << ", " << z << ')';
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>::operator NzString() const
|
||||
{
|
||||
return ToString();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>& NzQuaternion<T>::operator=(const NzQuaternion& quat)
|
||||
{
|
||||
Set(quat);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::operator+(const NzQuaternion& quat) const
|
||||
{
|
||||
@@ -263,10 +234,10 @@ NzQuaternion<T> NzQuaternion<T>::operator+(const NzQuaternion& quat) const
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::operator*(const NzQuaternion& quat) const
|
||||
{
|
||||
return NzQuaternion(w * quat.w - x * quat.x - y * quat.y - z * quat.z,
|
||||
w * quat.x + x * quat.w + y * quat.z - z * quat.y,
|
||||
w * quat.y + y * quat.w + z * quat.x - x * quat.z,
|
||||
w * quat.z + z * quat.w + x * quat.y - y * quat.x);
|
||||
return NzQuaternion(w*quat.w - x*quat.x - y*quat.y - z*quat.z,
|
||||
w*quat.x + x*quat.w + y*quat.z - z*quat.y,
|
||||
w*quat.y + y*quat.w + z*quat.x - x*quat.z,
|
||||
w*quat.z + z*quat.w + x*quat.y - y*quat.x);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -276,7 +247,7 @@ NzVector3<T> NzQuaternion<T>::operator*(const NzVector3<T>& vec) const
|
||||
normal.Normalize();
|
||||
|
||||
NzQuaternion qvec(0.0, normal.x, normal.y, normal.z);
|
||||
NzQuaternion result = operator*(qvec * GetConjugate());
|
||||
NzQuaternion result(operator*(qvec * GetConjugate()));
|
||||
|
||||
return NzVector3<T>(result.x, result.y, result.z);
|
||||
|
||||
@@ -360,10 +331,74 @@ bool NzQuaternion<T>::operator>=(const NzQuaternion& quat) const
|
||||
return !operator<(quat);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::Identity()
|
||||
{
|
||||
NzQuaternion quaternion;
|
||||
quaternion.MakeIdentity();
|
||||
|
||||
return quaternion;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp)
|
||||
{
|
||||
if (interp <= F(0.0))
|
||||
return quatA;
|
||||
|
||||
if (interp >= F(1.0))
|
||||
return quatB;
|
||||
|
||||
NzQuaternion q;
|
||||
|
||||
T cosOmega = quatA.DotProduct(quatB);
|
||||
if (cosOmega < F(0.0))
|
||||
{
|
||||
// On inverse tout
|
||||
q.Set(-quatB.w, -quatB.x, -quatB.y, -quatB.z);
|
||||
cosOmega = -cosOmega;
|
||||
}
|
||||
else
|
||||
q.Set(quatB);
|
||||
|
||||
T k0, k1;
|
||||
if (cosOmega > F(0.9999))
|
||||
{
|
||||
// Interpolation linéaire pour éviter une division par zéro
|
||||
k0 = F(1.0) - interp;
|
||||
k1 = interp;
|
||||
}
|
||||
else
|
||||
{
|
||||
T sinOmega = std::sqrt(F(1.0) - cosOmega*cosOmega);
|
||||
T omega = std::atan2(sinOmega, cosOmega);
|
||||
|
||||
// Pour éviter deux divisions
|
||||
sinOmega = F(1.0)/sinOmega;
|
||||
|
||||
k0 = std::sin((F(1.0) - interp) * omega) * sinOmega;
|
||||
k1 = std::sin(interp*omega) * sinOmega;
|
||||
}
|
||||
|
||||
NzQuaternion result(k0 * quatA.w, k0 * quatA.x, k0 * quatA.y, k0 * quatA.z);
|
||||
return result += q*k1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::Zero()
|
||||
{
|
||||
NzQuaternion quaternion;
|
||||
quaternion.MakeZero();
|
||||
|
||||
return quaternion;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const NzQuaternion<T>& quat)
|
||||
{
|
||||
return out << quat.ToString();
|
||||
}
|
||||
|
||||
#undef F
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
||||
@@ -16,7 +16,8 @@ class NzRect
|
||||
public:
|
||||
NzRect();
|
||||
NzRect(T X, T Y, T Width, T Height);
|
||||
NzRect(T rect[4]);
|
||||
NzRect(const T rect[4]);
|
||||
NzRect(const NzVector2<T>& vec1, const NzVector2<T>& vec2);
|
||||
template<typename U> explicit NzRect(const NzRect<U>& rect);
|
||||
NzRect(const NzRect& rect) = default;
|
||||
~NzRect() = default;
|
||||
@@ -30,11 +31,15 @@ class NzRect
|
||||
|
||||
NzVector2<T> GetCenter() const;
|
||||
|
||||
bool Intersect(const NzRect& rect) const;
|
||||
bool Intersect(const NzRect& rect, NzRect& intersection) const;
|
||||
bool Intersect(const NzRect& rect, NzRect* intersection = nullptr) const;
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
void Set(T X, T Y, T Width, T Height);
|
||||
void Set(const T rect[4]);
|
||||
void Set(const NzVector2<T>& vec1, const NzVector2<T>& vec2);
|
||||
template<typename U> void Set(const NzRect<U>& rect);
|
||||
|
||||
NzString ToString() const;
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
@@ -6,37 +6,36 @@
|
||||
#include <algorithm>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
#define F(a) static_cast<T>(a)
|
||||
|
||||
template<typename T>
|
||||
NzRect<T>::NzRect()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzRect<T>::NzRect(T X, T Y, T Width, T Height) :
|
||||
x(X),
|
||||
y(Y),
|
||||
width(Width),
|
||||
height(Height)
|
||||
NzRect<T>::NzRect(T X, T Y, T Width, T Height)
|
||||
{
|
||||
Set(X, Y, Width, Height);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzRect<T>::NzRect(T vec[4]) :
|
||||
x(vec[0]),
|
||||
y(vec[1]),
|
||||
width(vec[2]),
|
||||
height(vec[3])
|
||||
NzRect<T>::NzRect(const T vec[4])
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzRect<T>::NzRect(const NzVector2<T>& vec1, const NzVector2<T>& vec2)
|
||||
{
|
||||
Set(vec1, vec2);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
NzRect<T>::NzRect(const NzRect<U>& rect) :
|
||||
x(static_cast<T>(rect.x)),
|
||||
y(static_cast<T>(rect.y)),
|
||||
width(static_cast<T>(rect.width)),
|
||||
height(static_cast<T>(rect.height))
|
||||
NzRect<T>::NzRect(const NzRect<U>& rect)
|
||||
{
|
||||
Set(rect);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -80,18 +79,11 @@ void NzRect<T>::ExtendTo(const NzRect& rect)
|
||||
template<typename T>
|
||||
NzVector2<T> NzRect<T>::GetCenter() const
|
||||
{
|
||||
return NzVector2<T>((x+width)/2, (y+height)/2);
|
||||
return NzVector2<T>((x+width)/F(2.0), (y+height)/F(2.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzRect<T>::Intersect(const NzRect& rect) const
|
||||
{
|
||||
NzRect intersection; // Optimisé par le compilateur
|
||||
return Intersect(rect, intersection);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzRect<T>::Intersect(const NzRect& rect, NzRect& intersection) const
|
||||
bool NzRect<T>::Intersect(const NzRect& rect, NzRect* intersection) const
|
||||
{
|
||||
T left = std::max(x, rect.x);
|
||||
T right = std::min(x+width, rect.x+rect.width);
|
||||
@@ -100,10 +92,13 @@ bool NzRect<T>::Intersect(const NzRect& rect, NzRect& intersection) const
|
||||
|
||||
if (left < right && top < bottom)
|
||||
{
|
||||
intersection.x = left;
|
||||
intersection.y = top;
|
||||
intersection.width = right-left;
|
||||
intersection.height = bottom-top;
|
||||
if (intersection)
|
||||
{
|
||||
intersection->x = left;
|
||||
intersection->y = top;
|
||||
intersection->width = right-left;
|
||||
intersection->height = bottom-top;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -114,7 +109,44 @@ bool NzRect<T>::Intersect(const NzRect& rect, NzRect& intersection) const
|
||||
template<typename T>
|
||||
bool NzRect<T>::IsValid() const
|
||||
{
|
||||
return width > 0 && height > 0;
|
||||
return width > F(0.0) && height > F(0.0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzRect<T>::Set(T X, T Y, T Width, T Height)
|
||||
{
|
||||
x = X;
|
||||
y = Y;
|
||||
width = Width;
|
||||
height = Height;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzRect<T>::Set(const T rect[4])
|
||||
{
|
||||
x = rect[0];
|
||||
y = rect[1];
|
||||
width = rect[2];
|
||||
height = rect[3];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzRect<T>::Set(const NzVector2<T>& vec1, const NzVector2<T>& vec2)
|
||||
{
|
||||
x = std::min(vec1.x, vec2.x);
|
||||
y = std::min(vec1.y, vec2.y);
|
||||
width = (vec2.x > vec1.x) ? vec2.x-vec1.x : vec1.x-vec2.x;
|
||||
height = (vec2.y > vec1.y) ? vec2.y-vec1.y : vec1.y-vec2.y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
void NzRect<T>::Set(const NzRect<U>& rect)
|
||||
{
|
||||
x = F(rect.x);
|
||||
y = F(rect.y);
|
||||
width = F(rect.width);
|
||||
height = F(rect.height);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -134,6 +166,7 @@ NzRect<T>::operator NzString() const
|
||||
template<typename T>
|
||||
T& NzRect<T>::operator[](unsigned int i)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (i >= 4)
|
||||
{
|
||||
NzStringStream ss;
|
||||
@@ -141,6 +174,7 @@ T& NzRect<T>::operator[](unsigned int i)
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return *(&x+i);
|
||||
}
|
||||
@@ -148,6 +182,7 @@ T& NzRect<T>::operator[](unsigned int i)
|
||||
template<typename T>
|
||||
T NzRect<T>::operator[](unsigned int i) const
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (i >= 4)
|
||||
{
|
||||
NzStringStream ss;
|
||||
@@ -155,6 +190,7 @@ T NzRect<T>::operator[](unsigned int i) const
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return *(&x+i);
|
||||
}
|
||||
@@ -165,4 +201,6 @@ std::ostream& operator<<(std::ostream& out, const NzRect<T>& rect)
|
||||
return out << rect.ToString();
|
||||
}
|
||||
|
||||
#undef F
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
||||
@@ -21,20 +21,37 @@ template<typename T> class NzVector2
|
||||
~NzVector2() = default;
|
||||
|
||||
T AbsDotProduct(const NzVector2& vec) const;
|
||||
|
||||
T Distance(const NzVector2& vec) const;
|
||||
float Distancef(const NzVector2& vec) const;
|
||||
|
||||
T DotProduct(const NzVector2& vec) const;
|
||||
|
||||
NzVector2 GetNormal() const;
|
||||
|
||||
void MakeCeil(const NzVector2& vec);
|
||||
void MakeFloor(const NzVector2& vec);
|
||||
void MakeUnitX();
|
||||
void MakeUnitY();
|
||||
void MakeZero();
|
||||
|
||||
T Length() const;
|
||||
float Lengthf() const;
|
||||
|
||||
void Normalize();
|
||||
|
||||
void Set(T X, T Y);
|
||||
void Set(T scale);
|
||||
void Set(T vec[2]);
|
||||
template<typename U> void Set(const NzVector2<U>& vec);
|
||||
|
||||
T SquaredDistance(const NzVector2& vec) const;
|
||||
T SquaredLength() const;
|
||||
|
||||
NzString ToString() const;
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
operator T*();
|
||||
operator const T*() const;
|
||||
|
||||
@@ -65,8 +82,11 @@ template<typename T> class NzVector2
|
||||
bool operator>(const NzVector2& vec) const;
|
||||
bool operator>=(const NzVector2& vec) const;
|
||||
|
||||
T x;
|
||||
T y;
|
||||
static NzVector2 UnitX();
|
||||
static NzVector2 UnitY();
|
||||
static NzVector2 Zero();
|
||||
|
||||
T x, y;
|
||||
};
|
||||
|
||||
template<typename T> std::ostream& operator<<(std::ostream& out, const NzVector2<T>& vec);
|
||||
|
||||
@@ -6,41 +6,40 @@
|
||||
#include <Nazara/Math/Basic.hpp>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
#define F(a) static_cast<T>(a)
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::NzVector2()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::NzVector2(T X, T Y) :
|
||||
x(X),
|
||||
y(Y)
|
||||
NzVector2<T>::NzVector2(T X, T Y)
|
||||
{
|
||||
Set(X, Y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::NzVector2(T scale) :
|
||||
x(scale),
|
||||
y(scale)
|
||||
NzVector2<T>::NzVector2(T scale)
|
||||
{
|
||||
Set(scale);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::NzVector2(T vec[2]) :
|
||||
x(vec[0]),
|
||||
y(vec[1])
|
||||
NzVector2<T>::NzVector2(T vec[2])
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
NzVector2<T>::NzVector2(const NzVector2<U>& vec) :
|
||||
x(static_cast<T>(vec.x)),
|
||||
y(static_cast<T>(vec.y))
|
||||
NzVector2<T>::NzVector2(const NzVector2<U>& vec)
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -76,7 +75,7 @@ float NzVector2<T>::Distancef(const NzVector2& vec) const
|
||||
template<typename T>
|
||||
T NzVector2<T>::DotProduct(const NzVector2& vec) const
|
||||
{
|
||||
return x * vec.x + y * vec.y;
|
||||
return x*vec.x + y*vec.y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -88,6 +87,18 @@ NzVector2<T> NzVector2<T>::GetNormal() const
|
||||
return vec;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::Length() const
|
||||
{
|
||||
return std::sqrt(SquaredLength());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
float NzVector2<T>::Lengthf() const
|
||||
{
|
||||
return std::sqrt(static_cast<float>(SquaredLength()));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::MakeCeil(const NzVector2& vec)
|
||||
{
|
||||
@@ -109,29 +120,65 @@ void NzVector2<T>::MakeFloor(const NzVector2& vec)
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::Length() const
|
||||
void NzVector2<T>::MakeUnitX()
|
||||
{
|
||||
return std::sqrt(SquaredLength());
|
||||
Set(F(1.0), F(0.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
float NzVector2<T>::Lengthf() const
|
||||
void NzVector2<T>::MakeUnitY()
|
||||
{
|
||||
return std::sqrt(static_cast<float>(SquaredLength()));
|
||||
Set(F(0.0), F(1.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::MakeZero()
|
||||
{
|
||||
Set(F(0.0), F(0.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::Normalize()
|
||||
{
|
||||
auto length = Length();
|
||||
T squaredLength = SquaredLength();
|
||||
|
||||
if (!NzNumberEquals(length, static_cast<T>(0.0)))
|
||||
if (squaredLength-F(1.0) > std::numeric_limits<T>::epsilon())
|
||||
{
|
||||
T length = std::sqrt(squaredLength);
|
||||
|
||||
x /= length;
|
||||
y /= length;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::Set(T X, T Y)
|
||||
{
|
||||
x = X;
|
||||
y = Y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::Set(T scale)
|
||||
{
|
||||
x = scale;
|
||||
y = scale;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::Set(T vec[2])
|
||||
{
|
||||
std::memcpy(&x, vec, 2*sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
void NzVector2<T>::Set(const NzVector2<U>& vec)
|
||||
{
|
||||
x = F(vec.x);
|
||||
y = F(vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::SquaredDistance(const NzVector2& vec) const
|
||||
{
|
||||
@@ -141,7 +188,7 @@ T NzVector2<T>::SquaredDistance(const NzVector2& vec) const
|
||||
template<typename T>
|
||||
T NzVector2<T>::SquaredLength() const
|
||||
{
|
||||
return x * x + y * y;
|
||||
return x*x + y*y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -152,6 +199,12 @@ NzString NzVector2<T>::ToString() const
|
||||
return ss << "Vector2(" << x << ", " << y << ')';
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::operator NzString() const
|
||||
{
|
||||
return ToString();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::operator T*()
|
||||
{
|
||||
@@ -167,6 +220,7 @@ NzVector2<T>::operator const T*() const
|
||||
template<typename T>
|
||||
T& NzVector2<T>::operator[](unsigned int i)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (i >= 2)
|
||||
{
|
||||
NzStringStream ss;
|
||||
@@ -174,6 +228,7 @@ T& NzVector2<T>::operator[](unsigned int i)
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return *(&x+i);
|
||||
}
|
||||
@@ -181,6 +236,7 @@ T& NzVector2<T>::operator[](unsigned int i)
|
||||
template<typename T>
|
||||
T NzVector2<T>::operator[](unsigned int i) const
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (i >= 2)
|
||||
{
|
||||
NzStringStream ss;
|
||||
@@ -188,6 +244,7 @@ T NzVector2<T>::operator[](unsigned int i) const
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return *(&x+i);
|
||||
}
|
||||
@@ -231,13 +288,15 @@ NzVector2<T> NzVector2<T>::operator*(T scale) const
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator/(const NzVector2& vec) const
|
||||
{
|
||||
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)))
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return NzVector2(x / vec.x, y / vec.y);
|
||||
}
|
||||
@@ -245,13 +304,15 @@ NzVector2<T> NzVector2<T>::operator/(const NzVector2& vec) const
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator/(T scale) const
|
||||
{
|
||||
if (NzNumberEquals(scale, static_cast<T>(0.0)))
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(scale, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return NzVector2(x / scale, y / scale);
|
||||
}
|
||||
@@ -295,13 +356,15 @@ NzVector2<T>& NzVector2<T>::operator*=(T scale)
|
||||
template<typename T>
|
||||
NzVector2<T>& NzVector2<T>::operator/=(const NzVector2& vec)
|
||||
{
|
||||
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)))
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
x /= vec.x;
|
||||
y /= vec.y;
|
||||
@@ -312,13 +375,15 @@ NzVector2<T>& NzVector2<T>::operator/=(const NzVector2& vec)
|
||||
template<typename T>
|
||||
NzVector2<T>& NzVector2<T>::operator/=(T scale)
|
||||
{
|
||||
if (NzNumberEquals(scale, static_cast<T>(0.0)))
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(scale, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
x /= scale;
|
||||
y /= scale;
|
||||
@@ -363,6 +428,33 @@ bool NzVector2<T>::operator>=(const NzVector2& vec) const
|
||||
return !operator<(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::UnitX()
|
||||
{
|
||||
NzVector2 vector;
|
||||
vector.MakeUnitX();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::UnitY()
|
||||
{
|
||||
NzVector2 vector;
|
||||
vector.MakeUnitY();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::Zero()
|
||||
{
|
||||
NzVector2 vector;
|
||||
vector.MakeZero();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const NzVector2<T>& vec)
|
||||
{
|
||||
@@ -378,15 +470,19 @@ NzVector2<T> operator*(T scale, const NzVector2<T>& vec)
|
||||
template<typename T>
|
||||
NzVector2<T> operator/(T scale, const NzVector2<T>& vec)
|
||||
{
|
||||
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)))
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return NzVector2<T>(scale/vec.x, scale/vec.y);
|
||||
}
|
||||
|
||||
#undef F
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
||||
@@ -23,21 +23,41 @@ template<typename T> class NzVector3
|
||||
~NzVector3() = default;
|
||||
|
||||
T AbsDotProduct(const NzVector3& vec) const;
|
||||
|
||||
NzVector3 CrossProduct(const NzVector3& vec) const;
|
||||
|
||||
T Distance(const NzVector3& vec) const;
|
||||
float Distancef(const NzVector3& vec) const;
|
||||
|
||||
T DotProduct(const NzVector3& vec) const;
|
||||
|
||||
NzVector3 GetNormal() const;
|
||||
void MakeCeil(const NzVector3& vec);
|
||||
void MakeFloor(const NzVector3& vec);
|
||||
|
||||
T Length() const;
|
||||
float Lengthf() const;
|
||||
|
||||
void MakeCeil(const NzVector3& vec);
|
||||
void MakeFloor(const NzVector3& vec);
|
||||
void MakeUnitX();
|
||||
void MakeUnitY();
|
||||
void MakeUnitZ();
|
||||
void MakeZero();
|
||||
|
||||
void Normalize();
|
||||
|
||||
void Set(T X, T Y, T Z);
|
||||
void Set(T scale);
|
||||
void Set(T vec[3]);
|
||||
void Set(const NzVector2<T>& vec, T Z = 0.0);
|
||||
template<typename U> void Set(const NzVector3<U>& vec);
|
||||
|
||||
T SquaredDistance(const NzVector3& vec) const;
|
||||
T SquaredLength() const;
|
||||
|
||||
NzString ToString() const;
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
operator T*();
|
||||
operator const T*() const;
|
||||
|
||||
@@ -68,9 +88,12 @@ template<typename T> class NzVector3
|
||||
bool operator>(const NzVector3& vec) const;
|
||||
bool operator>=(const NzVector3& vec) const;
|
||||
|
||||
T x;
|
||||
T y;
|
||||
T z;
|
||||
static NzVector3 UnitX();
|
||||
static NzVector3 UnitY();
|
||||
static NzVector3 UnitZ();
|
||||
static NzVector3 Zero();
|
||||
|
||||
T x, y, z;
|
||||
};
|
||||
|
||||
template<typename T> std::ostream& operator<<(std::ostream& out, const NzVector3<T>& vec);
|
||||
|
||||
@@ -6,53 +6,46 @@
|
||||
#include <Nazara/Math/Basic.hpp>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
#define F(a) static_cast<T>(a)
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T>::NzVector3()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T>::NzVector3(T X, T Y, T Z) :
|
||||
x(X),
|
||||
y(Y),
|
||||
z(Z)
|
||||
NzVector3<T>::NzVector3(T X, T Y, T Z)
|
||||
{
|
||||
Set(X, Y, Z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T>::NzVector3(T scale) :
|
||||
x(scale),
|
||||
y(scale),
|
||||
z(scale)
|
||||
NzVector3<T>::NzVector3(T scale)
|
||||
{
|
||||
Set(scale);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T>::NzVector3(T vec[3]) :
|
||||
x(vec[0]),
|
||||
y(vec[1]),
|
||||
z(vec[2])
|
||||
NzVector3<T>::NzVector3(T vec[3])
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T>::NzVector3(const NzVector2<T>& vec, T Z) :
|
||||
x(vec.x),
|
||||
y(vec.y),
|
||||
z(Z)
|
||||
NzVector3<T>::NzVector3(const NzVector2<T>& vec, T Z)
|
||||
{
|
||||
Set(vec, Z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
NzVector3<T>::NzVector3(const NzVector3<U>& vec) :
|
||||
x(static_cast<T>(vec.x)),
|
||||
y(static_cast<T>(vec.y)),
|
||||
z(static_cast<T>(vec.z))
|
||||
NzVector3<T>::NzVector3(const NzVector3<U>& vec)
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -94,7 +87,7 @@ float NzVector3<T>::Distancef(const NzVector3& vec) const
|
||||
template<typename T>
|
||||
T NzVector3<T>::DotProduct(const NzVector3& vec) const
|
||||
{
|
||||
return x * vec.x + y * vec.y + z * vec.z;
|
||||
return x*vec.x + y*vec.y + z*vec.z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -132,6 +125,30 @@ void NzVector3<T>::MakeFloor(const NzVector3& vec)
|
||||
z = vec.z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector3<T>::MakeUnitX()
|
||||
{
|
||||
Set(F(1.0), F(0.0), F(0.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector3<T>::MakeUnitY()
|
||||
{
|
||||
Set(F(0.0), F(1.0), F(0.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector3<T>::MakeUnitZ()
|
||||
{
|
||||
Set(F(0.0), F(0.0), F(1.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector3<T>::MakeZero()
|
||||
{
|
||||
Set(F(0.0), F(0.0), F(0.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector3<T>::Length() const
|
||||
{
|
||||
@@ -147,16 +164,57 @@ float NzVector3<T>::Lengthf() const
|
||||
template<typename T>
|
||||
void NzVector3<T>::Normalize()
|
||||
{
|
||||
T length = Length();
|
||||
T squaredLength = SquaredLength();
|
||||
|
||||
if (!NzNumberEquals(length, static_cast<T>(0.0)))
|
||||
if (squaredLength-F(1.0) > std::numeric_limits<T>::epsilon())
|
||||
{
|
||||
T length = std::sqrt(squaredLength);
|
||||
|
||||
x /= length;
|
||||
y /= length;
|
||||
z /= length;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector3<T>::Set(T X, T Y, T Z)
|
||||
{
|
||||
x = X;
|
||||
y = Y;
|
||||
z = Z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector3<T>::Set(T scale)
|
||||
{
|
||||
x = scale;
|
||||
y = scale;
|
||||
z = scale;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector3<T>::Set(T vec[3])
|
||||
{
|
||||
std::memcpy(&x, vec, 3*sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector3<T>::Set(const NzVector2<T>& vec, T Z)
|
||||
{
|
||||
x = vec.x;
|
||||
y = vec.y;
|
||||
z = Z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
void NzVector3<T>::Set(const NzVector3<U>& vec)
|
||||
{
|
||||
x = F(vec.x);
|
||||
y = F(vec.y);
|
||||
z = F(vec.z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector3<T>::SquaredDistance(const NzVector3& vec) const
|
||||
{
|
||||
@@ -166,7 +224,7 @@ T NzVector3<T>::SquaredDistance(const NzVector3& vec) const
|
||||
template<typename T>
|
||||
T NzVector3<T>::SquaredLength() const
|
||||
{
|
||||
return x * x + y * y + z * z;
|
||||
return x*x + y*y + z*z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -177,6 +235,12 @@ NzString NzVector3<T>::ToString() const
|
||||
return ss << "Vector3(" << x << ", " << y << ", " << z <<')';
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T>::operator NzString() const
|
||||
{
|
||||
return ToString();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T>::operator T*()
|
||||
{
|
||||
@@ -192,13 +256,15 @@ NzVector3<T>::operator const T*() const
|
||||
template<typename T>
|
||||
T& NzVector3<T>::operator[](unsigned int i)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (i >= 3)
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 3)";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
throw std::out_of_range(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return *(&x+i);
|
||||
}
|
||||
@@ -206,13 +272,15 @@ T& NzVector3<T>::operator[](unsigned int i)
|
||||
template<typename T>
|
||||
T NzVector3<T>::operator[](unsigned int i) const
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (i >= 3)
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 3)";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
throw std::out_of_range(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return *(&x+i);
|
||||
}
|
||||
@@ -256,13 +324,15 @@ NzVector3<T> NzVector3<T>::operator*(T scale) const
|
||||
template<typename T>
|
||||
NzVector3<T> NzVector3<T>::operator/(const NzVector3& vec) const
|
||||
{
|
||||
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)))
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return NzVector3(x / vec.x, y / vec.y, z / vec.z);
|
||||
}
|
||||
@@ -270,13 +340,15 @@ NzVector3<T> NzVector3<T>::operator/(const NzVector3& vec) const
|
||||
template<typename T>
|
||||
NzVector3<T> NzVector3<T>::operator/(T scale) const
|
||||
{
|
||||
if (NzNumberEquals(scale, static_cast<T>(0.0)))
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(scale, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return NzVector3(x / scale, y / scale, z / scale);
|
||||
}
|
||||
@@ -324,7 +396,7 @@ NzVector3<T>& NzVector3<T>::operator*=(T scale)
|
||||
template<typename T>
|
||||
NzVector3<T>& NzVector3<T>::operator/=(const NzVector3& vec)
|
||||
{
|
||||
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)))
|
||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
@@ -342,7 +414,7 @@ NzVector3<T>& NzVector3<T>::operator/=(const NzVector3& vec)
|
||||
template<typename T>
|
||||
NzVector3<T>& NzVector3<T>::operator/=(T scale)
|
||||
{
|
||||
if (NzNumberEquals(scale, static_cast<T>(0.0)))
|
||||
if (NzNumberEquals(scale, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
@@ -395,6 +467,42 @@ bool NzVector3<T>::operator>=(const NzVector3& vec) const
|
||||
return !operator<(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T> NzVector3<T>::UnitX()
|
||||
{
|
||||
NzVector3 vector;
|
||||
vector.MakeUnitX();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T> NzVector3<T>::UnitY()
|
||||
{
|
||||
NzVector3 vector;
|
||||
vector.MakeUnitY();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T> NzVector3<T>::UnitZ()
|
||||
{
|
||||
NzVector3 vector;
|
||||
vector.MakeUnitZ();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T> NzVector3<T>::Zero()
|
||||
{
|
||||
NzVector3 vector;
|
||||
vector.MakeZero();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const NzVector3<T>& vec)
|
||||
{
|
||||
@@ -410,15 +518,19 @@ NzVector3<T> operator*(T scale, const NzVector3<T>& vec)
|
||||
template<typename T>
|
||||
NzVector3<T> operator/(T scale, const NzVector3<T>& vec)
|
||||
{
|
||||
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)))
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return NzVector3<T>(scale / vec.x, scale / vec.y, scale / vec.z);
|
||||
}
|
||||
|
||||
#undef F
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
||||
@@ -17,19 +17,34 @@ template<typename T> class NzVector4
|
||||
NzVector4(T X, T Y, T Z, T W = 1.0);
|
||||
explicit NzVector4(T scale);
|
||||
NzVector4(T vec[4]);
|
||||
template<typename U> explicit NzVector4(const NzVector4<U>& vec);
|
||||
NzVector4(const NzVector3<T>& vec, T W = 1.0);
|
||||
template<typename U> explicit NzVector4(const NzVector4<U>& vec);
|
||||
NzVector4(const NzVector4& vec) = default;
|
||||
~NzVector4() = default;
|
||||
|
||||
T AbsDotProduct(const NzVector4& vec) const;
|
||||
|
||||
T DotProduct(const NzVector4& vec) const;
|
||||
|
||||
void MakeCeil(const NzVector4& vec);
|
||||
void MakeFloor(const NzVector4& vec);
|
||||
void MakeUnitX();
|
||||
void MakeUnitY();
|
||||
void MakeUnitZ();
|
||||
void MakeZero();
|
||||
|
||||
void Normalize();
|
||||
|
||||
void Set(T X, T Y, T Z, T W = 1.0);
|
||||
void Set(T scale);
|
||||
void Set(T vec[4]);
|
||||
void Set(const NzVector3<T>& vec, T W = 1.0);
|
||||
template<typename U> void Set(const NzVector4<U>& vec);
|
||||
|
||||
NzString ToString() const;
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
operator T*();
|
||||
operator const T*() const;
|
||||
|
||||
@@ -60,10 +75,12 @@ template<typename T> class NzVector4
|
||||
bool operator>(const NzVector4& vec) const;
|
||||
bool operator>=(const NzVector4& vec) const;
|
||||
|
||||
T x;
|
||||
T y;
|
||||
T z;
|
||||
T w;
|
||||
static NzVector4 UnitX();
|
||||
static NzVector4 UnitY();
|
||||
static NzVector4 UnitZ();
|
||||
static NzVector4 Zero();
|
||||
|
||||
T x, y, z, w;
|
||||
};
|
||||
|
||||
template<typename T> std::ostream& operator<<(std::ostream& out, const NzVector4<T>& vec);
|
||||
|
||||
@@ -9,55 +9,44 @@
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
///FIXME: Les calculs effectués ici sont probablements tous faux, la composante W étant spéciale dans le monde de la 3D
|
||||
|
||||
#define F(a) static_cast<T>(a)
|
||||
|
||||
template<typename T>
|
||||
NzVector4<T>::NzVector4()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector4<T>::NzVector4(T X, T Y, T Z, T W) :
|
||||
x(X),
|
||||
y(Y),
|
||||
z(Z),
|
||||
w(W)
|
||||
NzVector4<T>::NzVector4(T X, T Y, T Z, T W)
|
||||
{
|
||||
Set(X, Y, Z, W);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector4<T>::NzVector4(T scale) :
|
||||
x(scale),
|
||||
y(scale),
|
||||
z(scale),
|
||||
w(scale)
|
||||
NzVector4<T>::NzVector4(T scale)
|
||||
{
|
||||
Set(scale);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector4<T>::NzVector4(T vec[4]) :
|
||||
x(vec[0]),
|
||||
y(vec[1]),
|
||||
z(vec[2]),
|
||||
w(vec[3])
|
||||
NzVector4<T>::NzVector4(T vec[4])
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector4<T>::NzVector4(const NzVector3<T>& vec, T W)
|
||||
{
|
||||
Set(vec, W);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
NzVector4<T>::NzVector4(const NzVector4<U>& vec) :
|
||||
x(static_cast<T>(vec.x)),
|
||||
y(static_cast<T>(vec.y)),
|
||||
z(static_cast<T>(vec.z)),
|
||||
w(static_cast<T>(vec.w))
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector4<T>::NzVector4(const NzVector3<T>& vec, T W) :
|
||||
x(vec.x),
|
||||
y(vec.y),
|
||||
z(vec.z),
|
||||
w(W)
|
||||
NzVector4<T>::NzVector4(const NzVector4<U>& vec)
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -81,7 +70,7 @@ inline unsigned int NzVector4<unsigned int>::AbsDotProduct(const NzVector4<unsig
|
||||
template<typename T>
|
||||
T NzVector4<T>::DotProduct(const NzVector4& vec) const
|
||||
{
|
||||
return x * vec.x + y * vec.y + z * vec.z + w * vec.w;
|
||||
return x*vec.x + y*vec.y + z*vec.z + w*vec.w;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -116,10 +105,34 @@ void NzVector4<T>::MakeFloor(const NzVector4& vec)
|
||||
w = vec.w;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector4<T>::MakeUnitX()
|
||||
{
|
||||
Set(F(1.0), F(0.0), F(0.0), F(1.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector4<T>::MakeUnitY()
|
||||
{
|
||||
Set(F(0.0), F(1.0), F(0.0), F(1.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector4<T>::MakeUnitZ()
|
||||
{
|
||||
Set(F(0.0), F(0.0), F(1.0), F(1.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector4<T>::MakeZero()
|
||||
{
|
||||
Set(F(0.0), F(0.0), F(0.0), F(0.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector4<T>::Normalize()
|
||||
{
|
||||
if (!NzNumberEquals(w, static_cast<T>(0.0)))
|
||||
if (!NzNumberEquals(w, F(0.0)))
|
||||
{
|
||||
x /= w;
|
||||
y /= w;
|
||||
@@ -127,6 +140,49 @@ void NzVector4<T>::Normalize()
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector4<T>::Set(T X, T Y, T Z, T W)
|
||||
{
|
||||
w = W;
|
||||
x = X;
|
||||
y = Y;
|
||||
z = Z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector4<T>::Set(T scale)
|
||||
{
|
||||
w = scale;
|
||||
x = scale;
|
||||
y = scale;
|
||||
z = scale;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector4<T>::Set(T vec[4])
|
||||
{
|
||||
std::memcpy(&x, vec, 4*sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector4<T>::Set(const NzVector3<T>& vec, T W)
|
||||
{
|
||||
w = W;
|
||||
x = vec.x;
|
||||
y = vec.y;
|
||||
z = vec.z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
void NzVector4<T>::Set(const NzVector4<U>& vec)
|
||||
{
|
||||
w = F(vec.w);
|
||||
x = F(vec.x);
|
||||
y = F(vec.y);
|
||||
z = F(vec.z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzString NzVector4<T>::ToString() const
|
||||
{
|
||||
@@ -135,6 +191,12 @@ NzString NzVector4<T>::ToString() const
|
||||
return ss << "Vector4(" << x << ", " << y << ", " << z << ", " << w << ')';
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector4<T>::operator NzString() const
|
||||
{
|
||||
return ToString();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector4<T>::operator T*()
|
||||
{
|
||||
@@ -150,6 +212,7 @@ NzVector4<T>::operator const T*() const
|
||||
template<typename T>
|
||||
T& NzVector4<T>::operator[](unsigned int i)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (i >= 4)
|
||||
{
|
||||
NzStringStream ss;
|
||||
@@ -157,6 +220,7 @@ T& NzVector4<T>::operator[](unsigned int i)
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return *(&x+i);
|
||||
}
|
||||
@@ -164,6 +228,7 @@ T& NzVector4<T>::operator[](unsigned int i)
|
||||
template<typename T>
|
||||
T NzVector4<T>::operator[](unsigned int i) const
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (i >= 4)
|
||||
{
|
||||
NzStringStream ss;
|
||||
@@ -171,6 +236,7 @@ T NzVector4<T>::operator[](unsigned int i) const
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return *(&x+i);
|
||||
}
|
||||
@@ -214,13 +280,15 @@ NzVector4<T> NzVector4<T>::operator*(T scale) const
|
||||
template<typename T>
|
||||
NzVector4<T> NzVector4<T>::operator/(const NzVector4& vec) const
|
||||
{
|
||||
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)) || NzNumberEquals(vec.w, static_cast<T>(0.0)))
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)) || NzNumberEquals(vec.w, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return NzVector4(x / vec.x, y / vec.y, z / vec.z, w / vec.w);
|
||||
}
|
||||
@@ -228,13 +296,15 @@ NzVector4<T> NzVector4<T>::operator/(const NzVector4& vec) const
|
||||
template<typename T>
|
||||
NzVector4<T> NzVector4<T>::operator/(T scale) const
|
||||
{
|
||||
if (NzNumberEquals(scale, static_cast<T>(0.0)))
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(scale, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return NzVector4(x / scale, y / scale, z / scale, w / scale);
|
||||
}
|
||||
@@ -286,13 +356,15 @@ NzVector4<T>& NzVector4<T>::operator*=(T scale)
|
||||
template<typename T>
|
||||
NzVector4<T>& NzVector4<T>::operator/=(const NzVector4& vec)
|
||||
{
|
||||
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)) || NzNumberEquals(vec.w, static_cast<T>(0.0)))
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)) || NzNumberEquals(vec.w, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
x /= vec.x;
|
||||
y /= vec.y;
|
||||
@@ -305,13 +377,15 @@ NzVector4<T>& NzVector4<T>::operator/=(const NzVector4& vec)
|
||||
template<typename T>
|
||||
NzVector4<T>& NzVector4<T>::operator/=(T scale)
|
||||
{
|
||||
if (NzNumberEquals(scale, static_cast<T>(0.0)))
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(scale, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
x /= scale;
|
||||
y /= scale;
|
||||
@@ -360,6 +434,42 @@ bool NzVector4<T>::operator>=(const NzVector4& vec) const
|
||||
return !operator<(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector4<T> NzVector4<T>::UnitX()
|
||||
{
|
||||
NzVector4 vector;
|
||||
vector.MakeUnitX();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector4<T> NzVector4<T>::UnitY()
|
||||
{
|
||||
NzVector4 vector;
|
||||
vector.MakeUnitY();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector4<T> NzVector4<T>::UnitZ()
|
||||
{
|
||||
NzVector4 vector;
|
||||
vector.MakeUnitZ();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector4<T> NzVector4<T>::Zero()
|
||||
{
|
||||
NzVector4 vector;
|
||||
vector.MakeZero();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const NzVector4<T>& vec)
|
||||
{
|
||||
@@ -375,15 +485,19 @@ NzVector4<T> operator*(T scale, const NzVector4<T>& vec)
|
||||
template<typename T>
|
||||
NzVector4<T> operator/(T scale, const NzVector4<T>& vec)
|
||||
{
|
||||
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)) || NzNumberEquals(vec.w, static_cast<T>(0.0)))
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)) || NzNumberEquals(vec.w, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return NzVector4<T>(scale / vec.x, scale / vec.y, scale / vec.z, scale / vec.w);
|
||||
}
|
||||
|
||||
#undef F
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
||||
Reference in New Issue
Block a user