Merge remote-tracking branch 'upstream/master'

Conflicts:
	include/Nazara/Noise/NoiseMachine.hpp
	src/Nazara/Noise/ComplexNoiseBase.cpp
	src/Nazara/Noise/NoiseMachine.cpp

Former-commit-id: 54af2e19e336cfacee63cabe785d7b05fa392b53
This commit is contained in:
Remi Beges
2012-10-05 17:53:41 +02:00
332 changed files with 10964 additions and 23504 deletions

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
@@ -24,12 +24,8 @@ template<typename T> T NzDegrees(T degrees);
template<typename T> T NzDegreeToRadian(T degrees);
inline unsigned int NzGetNumberLength(signed char number);
inline unsigned int NzGetNumberLength(unsigned char number);
inline unsigned int NzGetNumberLength(short number);
inline unsigned int NzGetNumberLength(unsigned short number);
inline unsigned int NzGetNumberLength(int number);
inline unsigned int NzGetNumberLength(unsigned int number);
inline unsigned int NzGetNumberLength(long number);
inline unsigned int NzGetNumberLength(unsigned long number);
inline unsigned int NzGetNumberLength(long long number);
inline unsigned int NzGetNumberLength(unsigned long long number);
inline unsigned int NzGetNumberLength(float number, nzUInt8 precision = NAZARA_CORE_REAL_PRECISION);

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Error.hpp>
@@ -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,39 +47,39 @@ 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)
{
if (number == 0)
return 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");
return static_cast<unsigned int>(std::log10(std::abs(number)))+(number < 0 ? 2 : 1);
if (number >= 100)
return 3;
else if (number >= 10)
return 2;
else if (number >= 0)
return 1;
else if (number > -10)
return 2;
else if (number > -100)
return 3;
else
return 4;
}
unsigned int NzGetNumberLength(unsigned char number)
{
if (number == 0)
// 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;
return static_cast<unsigned int>(std::log10(number))+1;
}
unsigned int NzGetNumberLength(short number)
{
if (number == 0)
return 1;
return static_cast<unsigned int>(std::log10(std::abs(number)))+(number < 0 ? 2 : 1);
}
unsigned int NzGetNumberLength(unsigned short number)
{
if (number == 0)
return 1;
return static_cast<unsigned int>(std::log10(number))+1;
}
unsigned int NzGetNumberLength(int number)
@@ -96,22 +98,6 @@ unsigned int NzGetNumberLength(unsigned int number)
return static_cast<unsigned int>(std::log10(number))+1;
}
unsigned int NzGetNumberLength(long number)
{
if (number == 0)
return 1;
return static_cast<unsigned int>(std::log10(std::abs(number)))+(number < 0 ? 2 : 1);
}
unsigned int NzGetNumberLength(unsigned long number)
{
if (number == 0)
return 1;
return static_cast<unsigned int>(std::log10(number))+1;
}
unsigned int NzGetNumberLength(long long number)
{
if (number == 0)
@@ -130,19 +116,19 @@ unsigned int NzGetNumberLength(unsigned long long number)
unsigned int NzGetNumberLength(float number, nzUInt8 precision)
{
// L'imprécision des flottants nécessite un cast (log10(9.99999) = 1)
// L'imprécision des flottants nécessite un cast (log10(9.99999) = 1)
return NzGetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus un pour le point
}
unsigned int NzGetNumberLength(double number, nzUInt8 precision)
{
// L'imprécision des flottants nécessite un cast (log10(9.99999) = 1)
// L'imprécision des flottants nécessite un cast (log10(9.99999) = 1)
return NzGetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus un pour le point
}
unsigned int NzGetNumberLength(long double number, nzUInt8 precision)
{
// L'imprécision des flottants nécessite un cast (log10(9.99999) = 1)
// L'imprécision des flottants nécessite un cast (log10(9.99999) = 1)
return NzGetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus un pour le point
}
@@ -152,20 +138,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 +161,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 +217,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 +270,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>

View File

@@ -1,8 +1,8 @@
/*
Nazara Engine
Nazara Engine - Mathematics module
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
Rémi "overdrivr" Bèges (remi.beges@laposte.net)
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
Rémi "overdrivr" Bèges (remi.beges@laposte.net)
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
@@ -28,23 +28,22 @@
#ifndef NAZARA_CONFIG_MATH_HPP
#define NAZARA_CONFIG_MATH_HPP
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
// Définit le radian comme l'unité utilisée pour les angles
// Définit le radian comme l'unité utilisée pour les angles
#define NAZARA_MATH_ANGLE_RADIAN 0
// 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)
// 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

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
@@ -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;

View File

@@ -1,59 +1,47 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/StringStream.hpp>
#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>

View File

@@ -1,6 +1,5 @@
// Copyright (C) 2012 Rémi Bèges
// Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
@@ -9,9 +8,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 +23,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 +33,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;
};

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/StringStream.hpp>
@@ -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>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
@@ -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>
@@ -21,23 +22,28 @@ template<typename T> class NzVector2;
template<typename T> class NzVector3;
template<typename T> class NzVector4;
template<typename T> class NzMatrix4
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;
NzMatrix4 ConcatenateAffine(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 +52,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>& target, const NzVector3<T>& up = 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 +85,8 @@ template<typename T> class NzMatrix4
NzMatrix4& Transpose();
operator NzString() const;
operator T*();
operator const T*() const;
@@ -79,7 +94,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 +105,19 @@ template<typename T> class NzMatrix4
NzMatrix4& operator*=(const NzMatrix4& matrix);
NzMatrix4& operator*=(T scalar);
static NzMatrix4 LookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up);
bool operator==(const NzMatrix4& mat) const;
bool operator!=(const NzMatrix4& mat) const;
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>& target, const NzVector3<T>& up = 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 +134,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

View File

@@ -1,6 +1,5 @@
// Copyright (C) 2012 Rémi Bèges
// Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
@@ -29,11 +28,17 @@ template<typename T> class NzQuaternion
T DotProduct(const NzQuaternion& vec) const;
NzQuaternion GetConjugate() const;
NzQuaternion GetNormalized() const;
NzQuaternion GetInverse() const;
NzQuaternion GetNormal() const;
void Inverse();
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 +47,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 +76,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;
};

View File

@@ -1,6 +1,5 @@
// Copyright (C) 2012 Rémi Bèges
// Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/StringStream.hpp>
@@ -8,8 +7,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 +55,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>
@@ -65,7 +67,16 @@ NzQuaternion<T> NzQuaternion<T>::GetConjugate() const
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::GetNormalized() const
NzQuaternion<T> NzQuaternion<T>::GetInverse() const
{
NzQuaternion<T> quat(*this);
quat.Inverse();
return quat;
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::GetNormal() const
{
NzQuaternion<T> quat(*this);
quat.Normalize();
@@ -73,6 +84,33 @@ NzQuaternion<T> NzQuaternion<T>::GetNormalized() const
return quat;
}
template<typename T>
void NzQuaternion<T>::Inverse()
{
T norm = SquaredMagnitude();
if (norm > F(0.0))
{
T invNorm = F(1.0) / norm;
w *= invNorm;
x *= -invNorm;
y *= -invNorm;
z *= -invNorm;
}
}
template<typename T>
void NzQuaternion<T>::MakeIdentity()
{
Set(F(1.0), F(0.0), F(0.0), F(0.0));
}
template<typename T>
void NzQuaternion<T>::MakeZero()
{
Set(F(0.0), F(0.0), F(0.0), F(0.0));
}
template<typename T>
T NzQuaternion<T>::Magnitude() const
{
@@ -82,27 +120,23 @@ 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)
// Inutile de vérifier si la magnitude au carrée est négative (Elle ne peut pas l'être)
if (!NzNumberEquals(squaredMagnitude, F(1.0)))
{
T length = std::sqrt(squaredLength);
T norm = std::sqrt(squaredMagnitude);
T invNorm = F(1.0) / norm;
w /= length;
x /= length;
y /= length;
z /= length;
w *= invNorm;
x *= invNorm;
y *= invNorm;
z *= invNorm;
return length;
return norm;
}
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>
@@ -124,20 +158,24 @@ void NzQuaternion<T>::Set(T quat[4])
}
template<typename T>
void NzQuaternion<T>::Set(T angle, const NzVector3<T>& normalizedAxis)
void NzQuaternion<T>::Set(T angle, const NzVector3<T>& axis)
{
angle /= F(2.0);
#if !NAZARA_MATH_ANGLE_RADIAN
angle = NzDegreeToRadian(angle);
#endif
angle /= 2;
NzVector3<T> normalizedAxis = axis.GetNormal();
auto sinAngle = std::sin(angle);
T sinAngle = std::sin(angle);
w = std::cos(angle);
x = normalizedAxis.x * sinAngle;
y = normalizedAxis.y * sinAngle;
z = normalizedAxis.z * sinAngle;
Normalize();
}
template<typename T>
@@ -166,81 +204,25 @@ 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)*x* - F(2.0)*z*z)),
NzRadians(std::atan2(F(2.0)*y*w - F(2.0)*x*z, F(1.0) - F(2.0)*y*y - F(2.0)*z*z)),
NzRadians(std::asin(F(2.0)*test)));
}
template<typename T>
@@ -251,6 +233,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,23 +259,22 @@ 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>
NzVector3<T> NzQuaternion<T>::operator*(const NzVector3<T>& vec) const
{
NzVector3<T> normal(vec);
normal.Normalize();
NzQuaternion qvec(0.0, normal.x, normal.y, normal.z);
NzQuaternion result = operator*(qvec * GetConjugate());
return NzVector3<T>(result.x, result.y, result.z);
NzVector3f quatVec(x, y, z);
NzVector3f uv = quatVec.CrossProduct(vec);
NzVector3f uuv = quatVec.CrossProduct(uv);
uv *= F(2.0) * w;
uuv *= F(2.0);
return vec + uv + uuv;
}
template<typename T>
@@ -360,10 +355,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>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
@@ -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;

View File

@@ -1,42 +1,41 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/StringStream.hpp>
#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>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
@@ -21,20 +21,38 @@ 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);
T Length() const;
float Lengthf() const;
void MakeUnitX();
void MakeUnitY();
void MakeZero();
void Maximize(const NzVector2& vec);
void Minimize(const NzVector2& vec);
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 +83,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);

View File

@@ -1,46 +1,45 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/StringStream.hpp>
#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,26 +87,6 @@ NzVector2<T> NzVector2<T>::GetNormal() const
return vec;
}
template<typename T>
void NzVector2<T>::MakeCeil(const NzVector2& vec)
{
if (vec.x > x)
x = vec.x;
if (vec.y > y)
y = vec.y;
}
template<typename T>
void NzVector2<T>::MakeFloor(const NzVector2& vec)
{
if (vec.x < x)
x = vec.x;
if (vec.y < y)
y = vec.y;
}
template<typename T>
T NzVector2<T>::Length() const
{
@@ -120,18 +99,86 @@ float NzVector2<T>::Lengthf() const
return std::sqrt(static_cast<float>(SquaredLength()));
}
template<typename T>
void NzVector2<T>::MakeUnitX()
{
Set(F(1.0), F(0.0));
}
template<typename T>
void NzVector2<T>::MakeUnitY()
{
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>::Maximize(const NzVector2& vec)
{
if (vec.x > x)
x = vec.x;
if (vec.y > y)
y = vec.y;
}
template<typename T>
void NzVector2<T>::Minimize(const NzVector2& vec)
{
if (vec.x < x)
x = vec.x;
if (vec.y < y)
y = vec.y;
}
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>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Rémi Bèges
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
@@ -23,21 +23,45 @@ 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 MakeForward();
void MakeLeft();
void MakeUnitX();
void MakeUnitY();
void MakeUnitZ();
void MakeUp();
void MakeZero();
void Maximize(const NzVector3& vec);
void Minimize(const NzVector3& vec);
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 +92,18 @@ 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 CrossProduct(const NzVector3& vec1, const NzVector3& vec2);
static T DotProduct(const NzVector3& vec1, const NzVector3& vec2);
static NzVector3 Forward();
static NzVector3 Left();
static NzVector3 Normalize(const NzVector3& vec);
static NzVector3 UnitX();
static NzVector3 UnitY();
static NzVector3 UnitZ();
static NzVector3 Up();
static NzVector3 Zero();
T x, y, z;
};
template<typename T> std::ostream& operator<<(std::ostream& out, const NzVector3<T>& vec);

View File

@@ -1,58 +1,51 @@
// Copyright (C) 2012 Rémi Bèges
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/StringStream.hpp>
#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>
@@ -76,7 +69,7 @@ inline unsigned int NzVector3<unsigned int>::AbsDotProduct(const NzVector3<unsig
template<typename T>
NzVector3<T> NzVector3<T>::CrossProduct(const NzVector3& vec) const
{
return NzVector3(y * vec.z - z * vec.y, z * vec.x - x * vec.y, x * vec.y - y * vec.x);
return NzVector3(y * vec.z - z * vec.y, z * vec.x - x * vec.z, x * vec.y - y * vec.x);
}
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>
@@ -106,32 +99,6 @@ NzVector3<T> NzVector3<T>::GetNormal() const
return vec;
}
template<typename T>
void NzVector3<T>::MakeCeil(const NzVector3& vec)
{
if (vec.x > x)
x = vec.x;
if (vec.y > y)
y = vec.y;
if (vec.z > z)
z = vec.z;
}
template<typename T>
void NzVector3<T>::MakeFloor(const NzVector3& vec)
{
if (vec.x < x)
x = vec.x;
if (vec.y < y)
y = vec.y;
if (vec.z < z)
z = vec.z;
}
template<typename T>
T NzVector3<T>::Length() const
{
@@ -144,19 +111,128 @@ float NzVector3<T>::Lengthf() const
return std::sqrt(static_cast<float>(SquaredLength()));
}
template<typename T>
void NzVector3<T>::MakeForward()
{
Set(F(0.0), F(0.0), F(-1.0));
}
template<typename T>
void NzVector3<T>::MakeLeft()
{
Set(F(-1.0), F(0.0), F(0.0));
}
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>::MakeUp()
{
Set(F(0.0), F(1.0), F(0.0));
}
template<typename T>
void NzVector3<T>::MakeZero()
{
Set(F(0.0), F(0.0), F(0.0));
}
template<typename T>
void NzVector3<T>::Maximize(const NzVector3& vec)
{
if (vec.x > x)
x = vec.x;
if (vec.y > y)
y = vec.y;
if (vec.z > z)
z = vec.z;
}
template<typename T>
void NzVector3<T>::Minimize(const NzVector3& vec)
{
if (vec.x < x)
x = vec.x;
if (vec.y < y)
y = vec.y;
if (vec.z < z)
z = vec.z;
}
template<typename T>
void NzVector3<T>::Normalize()
{
T length = Length();
T squaredLength = SquaredLength();
if (!NzNumberEquals(length, static_cast<T>(0.0)))
if (!NzNumberEquals(squaredLength, F(1.0)))
{
x /= length;
y /= length;
z /= length;
T invLength = F(1.0) / std::sqrt(squaredLength);
x *= invLength;
y *= invLength;
z *= invLength;
}
}
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 +242,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 +253,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 +274,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 +290,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 +342,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 +358,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 +414,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 +432,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 +485,87 @@ bool NzVector3<T>::operator>=(const NzVector3& vec) const
return !operator<(vec);
}
template<typename T>
NzVector3<T> NzVector3<T>::CrossProduct(const NzVector3& vec1, const NzVector3& vec2)
{
return vec1.CrossProduct(vec2);
}
template<typename T>
T NzVector3<T>::DotProduct(const NzVector3& vec1, const NzVector3& vec2)
{
return vec1.DotProduct(vec2);
}
template<typename T>
NzVector3<T> NzVector3<T>::Forward()
{
NzVector3 vector;
vector.MakeForward();
return vector;
}
template<typename T>
NzVector3<T> NzVector3<T>::Left()
{
NzVector3 vector;
vector.MakeLeft();
return vector;
}
template<typename T>
NzVector3<T> NzVector3<T>::Normalize(const NzVector3& vec)
{
return vec.GetNormal();
}
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>::Up()
{
NzVector3 vector;
vector.MakeUp();
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 +581,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>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Rémi Bèges
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
@@ -17,19 +17,35 @@ 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 Maximize(const NzVector4& vec);
void Minimize(const NzVector4& vec);
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 +76,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);

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
// This file is part of the "Nazara Engine - Mathematics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/StringStream.hpp>
@@ -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,11 +70,35 @@ 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>
void NzVector4<T>::MakeCeil(const NzVector4& vec)
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>::Maximize(const NzVector4& vec)
{
if (vec.x > x)
x = vec.x;
@@ -101,7 +114,7 @@ void NzVector4<T>::MakeCeil(const NzVector4& vec)
}
template<typename T>
void NzVector4<T>::MakeFloor(const NzVector4& vec)
void NzVector4<T>::Minimize(const NzVector4& vec)
{
if (vec.x < x)
x = vec.x;
@@ -119,7 +132,7 @@ void NzVector4<T>::MakeFloor(const NzVector4& vec)
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>