Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Remi Beges
2012-06-16 12:45:59 +02:00
114 changed files with 7524 additions and 1031 deletions

View File

@@ -0,0 +1,60 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CUBE_HPP
#define NAZARA_CUBE_HPP
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Rect.hpp>
#include <Nazara/Math/Vector3.hpp>
template<typename T>
class NzCube
{
public:
NzCube();
NzCube(T X, T Y, T Z, T Width, T Height, T Depth);
NzCube(T cube[6]);
NzCube(const NzRect<T>& rect);
template<typename U> explicit NzCube(const NzCube<U>& rect);
NzCube(const NzCube& rect) = default;
~NzCube() = default;
bool Contains(T X, T Y, T Z) const;
bool Contains(const NzVector3<T>& point) const;
bool Contains(const NzCube& rect) const;
void ExtendTo(const NzVector3<T>& point);
void ExtendTo(const NzCube& rect);
NzVector3<T> GetCenter() const;
bool Intersect(const NzCube& rect) const;
bool Intersect(const NzCube& rect, NzCube& intersection) const;
bool IsValid() const;
NzString ToString() const;
operator NzString() const;
T& operator[](unsigned int i);
T operator[](unsigned int i) const;
T x, y, z, width, height, depth;
};
template<typename T>
std::ostream& operator<<(std::ostream& out, const NzCube<T>& vec);
typedef NzCube<double> NzCubed;
typedef NzCube<float> NzCubef;
typedef NzCube<int> NzCubei;
typedef NzCube<unsigned int> NzCubeui;
#include <Nazara/Math/Cube.inl>
#endif // NAZARA_CUBE_HPP

View File

@@ -0,0 +1,194 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/StringStream.hpp>
#include <algorithm>
#include <Nazara/Core/Debug.hpp>
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)
{
}
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])
{
}
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)
{
}
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))
{
}
template<typename T>
bool NzCube<T>::Contains(T X, T Y, T Z) const
{
return X >= x && X < x+width &&
Y >= y && Y < y+height &&
Z >= z && Z < z+depth;
}
template<typename T>
bool NzCube<T>::Contains(const NzVector3<T>& point) const
{
return Contains(point.x, point.y, point.z);
}
template<typename T>
bool NzCube<T>::Contains(const NzCube<T>& rect) const
{
return Contains(rect.x, rect.y, rect.z) &&
Contains(rect.x + rect.width, rect.y + rect.height, rect.z + rect.depth);
}
template<typename T>
void NzCube<T>::ExtendTo(const NzVector3<T>& point)
{
x = std::min(x, point.x);
y = std::min(y, point.y);
z = std::min(z, point.z);
width = std::max(x+width, point.x)-x;
height = std::max(y+height, point.x)-y;
depth = std::max(z+depth, point.x)-z;
}
template<typename T>
void NzCube<T>::ExtendTo(const NzCube& rect)
{
x = std::min(x, rect.x);
y = std::min(y, rect.y);
z = std::min(y, rect.z);
width = std::max(x+width, rect.x+rect.width)-x;
height = std::max(x+height, rect.y+rect.height)-y;
depth = std::max(x+depth, rect.z+rect.depth)-z;
}
template<typename T>
NzVector3<T> NzCube<T>::GetCenter() const
{
return NzVector3<T>((x+width)/2, (y+height)/2, (z+depth)/2);
}
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
{
T left = std::max(x, rect.x);
T right = std::min(x+width, rect.x+rect.width);
T top = std::max(y, rect.y);
T bottom = std::min(y+height, rect.y+rect.height);
T up = std::max(z, rect.z);
T down = std::min(z+depth, rect.z+rect.depth);
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;
return true;
}
else
return false;
}
template<typename T>
bool NzCube<T>::IsValid() const
{
return width > 0 && height > 0 && depth > 0;
}
template<typename T>
NzString NzCube<T>::ToString() const
{
NzStringStream ss;
return ss << "Cube(" << x << ", " << y << ", " << z << ", " << width << ", " << height << ", " << depth << ')';
}
template<typename T>
NzCube<T>::operator NzString() const
{
return ToString();
}
template<typename T>
T& NzCube<T>::operator[](unsigned int i)
{
if (i >= 6)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 4)";
throw std::domain_error(ss.ToString());
}
return *(&x+i);
}
template<typename T>
T NzCube<T>::operator[](unsigned int i) const
{
if (i >= 6)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 4)";
throw std::domain_error(ss.ToString());
}
return *(&x+i);
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const NzCube<T>& rect)
{
return out << rect.ToString();
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -96,17 +96,12 @@ template<typename T> class NzMatrix4
struct SharedMatrix
{
SharedMatrix() : // Vivement GCC 4.7 sur Windows
refCount(1)
{
}
T m11, m12, m13, m14;
T m21, m22, m23, m24;
T m31, m32, m33, m34;
T m41, m42, m43, m44;
unsigned short refCount;
unsigned short refCount = 1;
NazaraMutex(mutex)
};

View File

@@ -107,7 +107,7 @@ NzMatrix4<T> NzMatrix4<T>::GetInverse() const
NzMatrix4 matrix;
T det = GetDeterminant();
if (det != 0.0)
if (!NzNumberEquals(det, static_cast<T>(0.0)))
{
matrix(0, 0) = (m_sharedMatrix->m22 * (m_sharedMatrix->m33 * m_sharedMatrix->m44 - m_sharedMatrix->m34 * m_sharedMatrix->m43) - m_sharedMatrix->m32 * (m_sharedMatrix->m23 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m24) + m_sharedMatrix->m42 * (m_sharedMatrix->m23 * m_sharedMatrix->m34 - m_sharedMatrix->m33 * m_sharedMatrix->m24)) / det;
matrix(0, 1) = -(m_sharedMatrix->m12 * (m_sharedMatrix->m33 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m34) - m_sharedMatrix->m32 * (m_sharedMatrix->m13 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m14) + m_sharedMatrix->m42 * (m_sharedMatrix->m13 * m_sharedMatrix->m34 - m_sharedMatrix->m33 * m_sharedMatrix->m14)) / det;

View File

@@ -26,11 +26,13 @@ template<typename T> class NzQuaternion
NzQuaternion(const NzQuaternion& quat) = default;
~NzQuaternion() = default;
T DotProduct(const NzQuaternion& vec) const;
NzQuaternion GetConjugate() const;
NzQuaternion GetNormalized() const;
double Magnitude() const;
double Normalize();
T Magnitude() const;
T Normalize();
T SquaredMagnitude() const;
void Set(T W, T X, T Y, T Z);
@@ -53,10 +55,10 @@ template<typename T> class NzQuaternion
NzQuaternion operator*(T scale) const;
NzQuaternion operator/(const NzQuaternion& quat) const;
NzQuaternion operator+=(const NzQuaternion& quat);
NzQuaternion operator*=(const NzQuaternion& quat);
NzQuaternion operator*=(T scale);
NzQuaternion operator/=(const NzQuaternion& quat);
NzQuaternion& operator+=(const NzQuaternion& quat);
NzQuaternion& operator*=(const NzQuaternion& quat);
NzQuaternion& operator*=(T scale);
NzQuaternion& operator/=(const NzQuaternion& quat);
bool operator==(const NzQuaternion& quat) const;
bool operator!=(const NzQuaternion& quat) const;
@@ -65,6 +67,8 @@ template<typename T> class NzQuaternion
bool operator>(const NzQuaternion& quat) const;
bool operator>=(const NzQuaternion& quat) const;
static NzQuaternion Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp);
T w, x, y, z;
};

View File

@@ -52,6 +52,12 @@ NzQuaternion<T>::NzQuaternion(const NzQuaternion<U>& quat)
Set(quat);
}
template<typename T>
T NzQuaternion<T>::DotProduct(const NzQuaternion& vec) const
{
return w*vec.w + x*vec.x + y*vec.y + z.vec.z;
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::GetConjugate() const
{
@@ -68,25 +74,29 @@ NzQuaternion<T> NzQuaternion<T>::GetNormalized() const
}
template<typename T>
double NzQuaternion<T>::Magnitude() const
T NzQuaternion<T>::Magnitude() const
{
return std::sqrt(SquaredMagnitude());
}
template<typename T>
double NzQuaternion<T>::Normalize()
T NzQuaternion<T>::Normalize()
{
double length = Magnitude();
T squaredLength = SquaredMagnitude();
if (length != 0.0)
if (std::fabs(squaredLength) > 0.00001 && std::fabs(squaredLength - 1.0) > 0.00001)
{
T length = std::sqrt(squaredLength);
w /= length;
x /= length;
y /= length;
z /= length;
}
return length;
return length;
}
else
return 1.0; // Le quaternion est déjà normalisé
}
template<typename T>
@@ -167,9 +177,55 @@ 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;
}
template<typename T>
NzEulerAngles<T> NzQuaternion<T>::ToEulerAngles() const
{
Normalize();
T test = x*y + z*w;
if (test > 0.499)
// singularity at north pole
@@ -199,31 +255,31 @@ 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);
x + quat.x,
y + quat.y,
z + quat.z);
}
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);
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>
NzVector3<T> NzQuaternion<T>::operator*(const NzVector3<T>& vec) const
{
NzVector3<T> uv, uuv;
NzVector3<T> qvec(x, y, z);
uv = qvec.CrossProduct(vec);
uuv = qvec.CrossProduct(uv);
uv *= 2.0 * w;
uuv *= 2.0;
NzVector3<T> normal(vec);
normal.Normalise();
NzQuaternion qvec(0.0, normal.x, normal.y, normal.z);
NzQuaternion result = operator*(qvec * GetConjugate());
return NzVector3<T>(result.x, result.y, result.z);
return vec + uv + uuv;
}
template<typename T>
@@ -242,43 +298,27 @@ NzQuaternion<T> NzQuaternion<T>::operator/(const NzQuaternion& quat) const
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator+=(const NzQuaternion& quat)
NzQuaternion<T>& NzQuaternion<T>::operator+=(const NzQuaternion& quat)
{
w += quat.w;
x += quat.x;
y += quat.y;
z += quat.z;
return *this;
return operator=(operator+(quat));
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator*=(const NzQuaternion& quat)
NzQuaternion<T>& NzQuaternion<T>::operator*=(const NzQuaternion& quat)
{
NzQuaternion q(*this);
operator=(q * quat);
return *this;
return operator=(operator*(quat));
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator*=(T scale)
NzQuaternion<T>& NzQuaternion<T>::operator*=(T scale)
{
w *= scale;
x *= scale;
y *= scale;
z *= scale;
return *this;
return operator=(operator*(scale));
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator/=(const NzQuaternion& quat)
NzQuaternion<T>& NzQuaternion<T>::operator/=(const NzQuaternion& quat)
{
NzQuaternion q(*this);
operator=(q / quat);
return *this;
return operator=(operator/(quat));
}
template<typename T>

View File

@@ -28,6 +28,8 @@ class NzRect
void ExtendTo(const NzVector2<T>& point);
void ExtendTo(const NzRect& rect);
NzVector2<T> GetCenter() const;
bool Intersect(const NzRect& rect) const;
bool Intersect(const NzRect& rect, NzRect& intersection) const;

View File

@@ -65,7 +65,7 @@ void NzRect<T>::ExtendTo(const NzVector2<T>& point)
x = std::min(x, point.x);
y = std::min(y, point.y);
width = std::max(x+width, point.x)-x;
height = std::max(x+width, point.x)-y;
height = std::max(y+height, point.y)-y;
}
template<typename T>
@@ -74,7 +74,13 @@ void NzRect<T>::ExtendTo(const NzRect& rect)
x = std::min(x, rect.x);
y = std::min(y, rect.y);
width = std::max(x+width, rect.x+rect.width)-x;
height = std::max(x+width, rect.x+rect.height)-y;
height = std::max(x+height, rect.y+rect.height)-y;
}
template<typename T>
NzVector2<T> NzRect<T>::GetCenter() const
{
return NzVector2<T>((x+width)/2, (y+height)/2);
}
template<typename T>
@@ -97,7 +103,7 @@ bool NzRect<T>::Intersect(const NzRect& rect, NzRect& intersection) const
intersection.x = left;
intersection.y = top;
intersection.width = right-left;
intersection.height = top-bottom;
intersection.height = bottom-top;
return true;
}

View File

@@ -21,19 +21,22 @@ template<typename T> class NzVector2
~NzVector2() = default;
T AbsDotProduct(const NzVector2& vec) const;
double Distance(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);
double Length() const;
double Normalize();
T Length() const;
float Lengthf() const;
void Normalize();
T SquaredDistance(const NzVector2& vec) const;
T SquaredLength() const;
NzString ToString() const;
operator NzString() const;
operator T*();
operator const T*() const;
T& operator[](unsigned int i);
T operator[](unsigned int i) const;

View File

@@ -49,17 +49,30 @@ T NzVector2<T>::AbsDotProduct(const NzVector2& vec) const
return std::fabs(x * vec.x) + std::fabs(y * vec.y);
}
template<> inline int NzVector2<int>::AbsDotProduct(const NzVector2<int>& vec) const
template<>
inline int NzVector2<int>::AbsDotProduct(const NzVector2<int>& vec) const
{
return std::labs(x * vec.x) + std::labs(y * vec.y);
}
template<>
inline unsigned int NzVector2<unsigned int>::AbsDotProduct(const NzVector2<unsigned int>& vec) const
{
return std::labs(x * vec.x) + std::labs(y * vec.y);
}
template<typename T>
double NzVector2<T>::Distance(const NzVector2& vec) const
T NzVector2<T>::Distance(const NzVector2& vec) const
{
return std::sqrt(SquaredDistance(vec));
}
template<typename T>
float NzVector2<T>::Distancef(const NzVector2& vec) const
{
return std::sqrt(static_cast<float>(SquaredDistance(vec)));
}
template<typename T>
T NzVector2<T>::DotProduct(const NzVector2& vec) const
{
@@ -96,23 +109,27 @@ void NzVector2<T>::MakeFloor(const NzVector2& vec)
}
template<typename T>
double NzVector2<T>::Length() const
T NzVector2<T>::Length() const
{
return std::sqrt(SquaredLength());
}
template<typename T>
double NzVector2<T>::Normalize()
float NzVector2<T>::Lengthf() const
{
double length = Length();
return std::sqrt(static_cast<float>(SquaredLength()));
}
if (length != 0.f)
template<typename T>
void NzVector2<T>::Normalize()
{
auto length = Length();
if (!NzNumberEquals(length, static_cast<T>(0.0)))
{
x /= length;
y /= length;
}
return length;
}
template<typename T>
@@ -136,9 +153,15 @@ NzString NzVector2<T>::ToString() const
}
template<typename T>
NzVector2<T>::operator NzString() const
NzVector2<T>::operator T*()
{
return ToString();
return &x;
}
template<typename T>
NzVector2<T>::operator const T*() const
{
return &x;
}
template<typename T>
@@ -208,7 +231,7 @@ NzVector2<T> NzVector2<T>::operator*(T scale) const
template<typename T>
NzVector2<T> NzVector2<T>::operator/(const NzVector2& vec) const
{
if (vec.x == 0.f || vec.y == 0.f)
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@@ -222,7 +245,7 @@ NzVector2<T> NzVector2<T>::operator/(const NzVector2& vec) const
template<typename T>
NzVector2<T> NzVector2<T>::operator/(T scale) const
{
if (scale == 0.f)
if (NzNumberEquals(scale, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@@ -272,7 +295,7 @@ NzVector2<T>& NzVector2<T>::operator*=(T scale)
template<typename T>
NzVector2<T>& NzVector2<T>::operator/=(const NzVector2& vec)
{
if (vec.x == 0.f || vec.y == 0.f)
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)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@@ -289,7 +312,7 @@ NzVector2<T>& NzVector2<T>::operator/=(const NzVector2& vec)
template<typename T>
NzVector2<T>& NzVector2<T>::operator/=(T scale)
{
if (scale == 0.f)
if (NzNumberEquals(scale, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@@ -355,7 +378,7 @@ NzVector2<T> operator*(T scale, const NzVector2<T>& vec)
template<typename T>
NzVector2<T> operator/(T scale, const NzVector2<T>& vec)
{
if (vec.x == 0.f || vec.y == 0.f)
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)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";

View File

@@ -8,6 +8,7 @@
#define NAZARA_VECTOR3_HPP
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Vector2.hpp>
template<typename T> class NzVector3
{
@@ -16,25 +17,29 @@ template<typename T> class NzVector3
NzVector3(T X, T Y, T Z);
explicit NzVector3(T scale);
NzVector3(T vec[3]);
NzVector3(const NzVector2<T>& vec);
template<typename U> explicit NzVector3(const NzVector3<U>& vec);
NzVector3(const NzVector3& vec) = default;
~NzVector3() = default;
T AbsDotProduct(const NzVector3& vec) const;
NzVector3 CrossProduct(const NzVector3& vec) const;
double Distance(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);
double Length() const;
double Normalize();
T Length() const;
float Lengthf() const;
void Normalize();
T SquaredDistance(const NzVector3& vec) const;
T SquaredLength() const;
NzString ToString() const;
operator NzString() const;
operator T*();
operator const T*() const;
T& operator[](unsigned int i);
T operator[](unsigned int i) const;
@@ -76,6 +81,7 @@ template<typename T> NzVector3<T> operator/(T scale, const NzVector3<T>& vec);
typedef NzVector3<double> NzVector3d;
typedef NzVector3<float> NzVector3f;
typedef NzVector3<int> NzVector3i;
typedef NzVector3<unsigned int> NzVector3ui;
#include <Nazara/Math/Vector3.inl>

View File

@@ -38,6 +38,14 @@ z(vec[2])
{
}
template<typename T>
NzVector3<T>::NzVector3(const NzVector2<T>& vec) :
x(vec.x),
y(vec.y),
z(0)
{
}
template<typename T>
template<typename U>
NzVector3<T>::NzVector3(const NzVector3<U>& vec) :
@@ -53,7 +61,14 @@ T NzVector3<T>::AbsDotProduct(const NzVector3& vec) const
return std::fabs(x * vec.x) + std::fabs(y * vec.y) + std::fabs(z * vec.z);
}
template<> inline int NzVector3<int>::AbsDotProduct(const NzVector3<int>& vec) const
template<>
inline int NzVector3<int>::AbsDotProduct(const NzVector3<int>& vec) const
{
return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z);
}
template<>
inline unsigned int NzVector3<unsigned int>::AbsDotProduct(const NzVector3<unsigned int>& vec) const
{
return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z);
}
@@ -65,11 +80,17 @@ NzVector3<T> NzVector3<T>::CrossProduct(const NzVector3& vec) const
}
template<typename T>
double NzVector3<T>::Distance(const NzVector3& vec) const
T NzVector3<T>::Distance(const NzVector3& vec) const
{
return std::sqrt(SquaredDistance(vec));
}
template<typename T>
float NzVector3<T>::Distancef(const NzVector3& vec) const
{
return std::sqrt(static_cast<float>(SquaredDistance()));
}
template<typename T>
T NzVector3<T>::DotProduct(const NzVector3& vec) const
{
@@ -112,24 +133,28 @@ void NzVector3<T>::MakeFloor(const NzVector3& vec)
}
template<typename T>
double NzVector3<T>::Length() const
T NzVector3<T>::Length() const
{
return std::sqrt(SquaredLength());
}
template<typename T>
double NzVector3<T>::Normalize()
float NzVector3<T>::Lengthf() const
{
double length = Length();
return std::sqrt(static_cast<float>(SquaredLength()));
}
if (length != 0.f)
template<typename T>
void NzVector3<T>::Normalize()
{
T length = Length();
if (!NzNumberEquals(length, static_cast<T>(0.0)))
{
x /= length;
y /= length;
z /= length;
}
return length;
}
template<typename T>
@@ -153,9 +178,15 @@ NzString NzVector3<T>::ToString() const
}
template<typename T>
NzVector3<T>::operator NzString() const
NzVector3<T>::operator T*()
{
return ToString();
return &x;
}
template<typename T>
NzVector3<T>::operator const T*() const
{
return &x;
}
template<typename T>
@@ -225,7 +256,7 @@ NzVector3<T> NzVector3<T>::operator*(T scale) const
template<typename T>
NzVector3<T> NzVector3<T>::operator/(const NzVector3& vec) const
{
if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f)
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)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@@ -239,7 +270,7 @@ NzVector3<T> NzVector3<T>::operator/(const NzVector3& vec) const
template<typename T>
NzVector3<T> NzVector3<T>::operator/(T scale) const
{
if (scale == 0.f)
if (NzNumberEquals(scale, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@@ -293,7 +324,7 @@ NzVector3<T>& NzVector3<T>::operator*=(T scale)
template<typename T>
NzVector3<T>& NzVector3<T>::operator/=(const NzVector3& vec)
{
if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f)
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)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@@ -311,7 +342,7 @@ NzVector3<T>& NzVector3<T>::operator/=(const NzVector3& vec)
template<typename T>
NzVector3<T>& NzVector3<T>::operator/=(T scale)
{
if (scale == 0.f)
if (NzNumberEquals(scale, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@@ -379,7 +410,7 @@ NzVector3<T> operator*(T scale, const NzVector3<T>& vec)
template<typename T>
NzVector3<T> operator/(T scale, const NzVector3<T>& vec)
{
if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f)
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)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";

View File

@@ -8,6 +8,7 @@
#define NAZARA_VECTOR4_HPP
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Vector3.hpp>
template<typename T> class NzVector4
{
@@ -17,6 +18,7 @@ template<typename T> class NzVector4
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);
NzVector4(const NzVector4& vec) = default;
~NzVector4() = default;
@@ -28,7 +30,8 @@ template<typename T> class NzVector4
NzString ToString() const;
operator NzString() const;
operator T*();
operator const T*() const;
T& operator[](unsigned int i);
T operator[](unsigned int i) const;

View File

@@ -51,13 +51,29 @@ 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)
{
}
template<typename T>
T NzVector4<T>::AbsDotProduct(const NzVector4& vec) const
{
return std::fabs(x * vec.x) + std::fabs(y * vec.y) + std::fabs(z * vec.z) + std::fabs(w * vec.w);
}
template<> inline int NzVector4<int>::AbsDotProduct(const NzVector4<int>& vec) const
template<>
inline int NzVector4<int>::AbsDotProduct(const NzVector4<int>& vec) const
{
return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z) + std::labs(w * vec.w);
}
template<>
inline unsigned int NzVector4<unsigned int>::AbsDotProduct(const NzVector4<unsigned int>& vec) const
{
return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z) + std::labs(w * vec.w);
}
@@ -103,7 +119,7 @@ void NzVector4<T>::MakeFloor(const NzVector4& vec)
template<typename T>
void NzVector4<T>::Normalize()
{
if (w != 0.f)
if (!NzNumberEquals(w, static_cast<T>(0.0)))
{
x /= w;
y /= w;
@@ -116,13 +132,19 @@ NzString NzVector4<T>::ToString() const
{
NzStringStream ss;
return ss << "Vector4(" << x << ", " << y << ", " << z <<')';
return ss << "Vector4(" << x << ", " << y << ", " << z << ", " << w << ')';
}
template<typename T>
NzVector4<T>::operator NzString() const
NzVector4<T>::operator T*()
{
return ToString();
return &x;
}
template<typename T>
NzVector4<T>::operator const T*() const
{
return &x;
}
template<typename T>
@@ -174,7 +196,7 @@ NzVector4<T> NzVector4<T>::operator+(const NzVector4& vec) const
template<typename T>
NzVector4<T> NzVector4<T>::operator-(const NzVector4& vec) const
{
return NzVector4(x - vec.x, y - vec.y, z - vec.z);
return NzVector4(x - vec.x, y - vec.y, z - vec.z, w - vec.w);
}
template<typename T>
@@ -192,7 +214,7 @@ NzVector4<T> NzVector4<T>::operator*(T scale) const
template<typename T>
NzVector4<T> NzVector4<T>::operator/(const NzVector4& vec) const
{
if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f || vec.w == 0.f)
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)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@@ -206,7 +228,7 @@ NzVector4<T> NzVector4<T>::operator/(const NzVector4& vec) const
template<typename T>
NzVector4<T> NzVector4<T>::operator/(T scale) const
{
if (scale == 0.f)
if (NzNumberEquals(scale, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@@ -264,7 +286,7 @@ NzVector4<T>& NzVector4<T>::operator*=(T scale)
template<typename T>
NzVector4<T>& NzVector4<T>::operator/=(const NzVector4& vec)
{
if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f || vec.w == 0.f)
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)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@@ -283,7 +305,7 @@ NzVector4<T>& NzVector4<T>::operator/=(const NzVector4& vec)
template<typename T>
NzVector4<T>& NzVector4<T>::operator/=(T scale)
{
if (scale == 0.f)
if (NzNumberEquals(scale, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@@ -353,7 +375,7 @@ NzVector4<T> operator*(T scale, const NzVector4<T>& vec)
template<typename T>
NzVector4<T> operator/(T scale, const NzVector4<T>& vec)
{
if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f || vec.w == 0.f)
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)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";