First commit

This commit is contained in:
Lynix
2012-05-01 16:43:48 +02:00
commit 71b4262c51
208 changed files with 46084 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
// 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_BASIC_HPP
#define NAZARA_BASIC_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/String.hpp>
#ifndef M_PI
#define M_PI 3.141592653589793238462643
#endif
#ifndef M_SQRT2
#define M_SQRT2 1.4142135623730950488016887
#endif
template<typename T> T NzApproach(T value, T objective, T increment);
template<typename T> T NzClamp(T value, T min, T max);
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);
inline unsigned int NzGetNumberLength(double number, nzUInt8 precision = NAZARA_CORE_REAL_PRECISION);
inline unsigned int NzGetNumberLength(long double number, nzUInt8 precision = NAZARA_CORE_REAL_PRECISION);
template<typename T> T NzNormalizeAngle(T angle);
template<typename T> bool NzNumberEquals(T a, T b);
inline NzString NzNumberToString(long long number, nzUInt8 radix = 10);
template<typename T> T NzRadians(T radians);
template<typename T> T NzRadianToDegree(T radians);
inline long long NzStringToNumber(NzString str, nzUInt8 radix = 10);
#include <Nazara/Math/Basic.inl>
#endif // NAZARA_BASIC_HPP

View File

@@ -0,0 +1,279 @@
// 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/Error.hpp>
#include <Nazara/Math/Config.hpp>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <Nazara/Core/Debug.hpp>
template<typename T>
T NzApproach(T value, T objective, T increment)
{
if (value < objective)
return std::min(value + increment, objective);
else if (value > objective)
return std::max(value - increment, objective);
else
return value;
}
template<typename T>
T NzClamp(T value, T min, T max)
{
if (value < min)
return min;
else if (value > max)
return max;
else
return value;
}
template<typename T>
T NzDegrees(T degrees)
{
#if NAZARA_MATH_ANGLE_RADIAN
return NzDegreeToRadian(degrees);
#else
return degrees;
#endif
}
template<typename T>
T NzDegreeToRadian(T degrees)
{
return degrees * (M_PI/180.0);
}
unsigned int NzGetNumberLength(signed char number)
{
if (number == 0)
return 1;
return static_cast<unsigned int>(std::log10(std::abs(number)))+(number < 0 ? 2 : 1);
}
unsigned int NzGetNumberLength(unsigned char number)
{
if (number == 0)
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)
{
if (number == 0)
return 1;
return static_cast<unsigned int>(std::log10(std::abs(number)))+(number < 0 ? 2 : 1);
}
unsigned int NzGetNumberLength(unsigned int number)
{
if (number == 0)
return 1;
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)
return 1;
return static_cast<unsigned int>(std::log10(std::abs(number)))+(number < 0 ? 2 : 1);
}
unsigned int NzGetNumberLength(unsigned long long number)
{
if (number == 0)
return 1;
return static_cast<unsigned int>(std::log10(number))+1;
}
unsigned int NzGetNumberLength(float number, nzUInt8 precision)
{
// 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)
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)
return NzGetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus un pour le point
}
template<typename T>
T NzNormalizeAngle(T angle)
{
#if NAZARA_MATH_ANGLE_RADIAN
const T limit = M_PI;
#else
const T limit = 180.0;
#endif
///TODO: Trouver une solution sans duplication
if (angle > 0.0)
{
angle += limit;
angle -= static_cast<int>(angle/(2.0*limit))*(2.0*limit);
angle -= limit;
}
else
{
angle -= limit;
angle -= static_cast<int>(angle/(2.0*limit))*(2.0*limit);
angle += limit;
}
return 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();
}
NzString NzNumberToString(long long number, nzUInt8 radix)
{
#if NAZARA_MATH_SAFE
if (radix < 2 || radix > 36)
{
NazaraError("Base must be between 2 and 36");
return NzString();
}
#endif
if (number == 0)
return '0';
static const char* symbols("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
bool negative;
if (number < 0)
{
negative = true;
number = -number;
}
else
negative = false;
NzString str;
str.Reserve(NzGetNumberLength(number));
do
{
str += symbols[number % radix];
number /= radix;
}
while (number > 0);
if (negative)
str += '-';
return str.Reversed();
}
template<typename T>
T NzRadians(T radians)
{
#if NAZARA_MATH_ANGLE_RADIAN
return radians;
#else
return NzRadianToDegree(radians);
#endif
}
template<typename T>
T NzRadianToDegree(T radians)
{
return radians * (180.0/M_PI);
}
long long NzStringToNumber(NzString str, nzUInt8 radix)
{
#if NAZARA_MATH_SAFE
if (radix < 2 || radix > 36)
{
NazaraError("Radix must be between 2 and 36");
return 0;
}
#endif
str.Simplify();
if (radix > 10)
str.ToUpper();
bool negative = str.StartsWith('-');
static const char* symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char* digit = &str[(negative) ? 1 : 0];
unsigned long long total = 0;
do
{
if (*digit == ' ')
continue;
total *= radix;
const char* c = std::strchr(symbols, *digit);
if (c && c-symbols < radix)
total += c-symbols;
else
{
NazaraError("str is not a valid number");
return 0;
}
}
while (*++digit);
return (negative) ? -static_cast<long long>(total) : total;
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -0,0 +1,42 @@
/*
Nazara Engine
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
Rémi "overdrivr" Begues (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
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma once
#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
// 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
#define NAZARA_MATH_MATRIX_COLUMN_MAJOR 1
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
#define NAZARA_MATH_SAFE 1
#endif // NAZARA_CONFIG_MATH_HPP

View File

@@ -0,0 +1,70 @@
// Copyright (C) 2012 Rémi Begues
// 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_EULERANGLES_HPP
#define NAZARA_EULERANGLES_HPP
#include <Nazara/Core/String.hpp>
template<typename T> class NzQuaternion;
template<typename T> class NzVector3;
template<typename T> class NzEulerAngles
{
public:
NzEulerAngles();
NzEulerAngles(T P, T Y, T R);
NzEulerAngles(T angles[3]);
//NzEulerAngles(const NzMatrix3<T>& mat);
NzEulerAngles(const NzQuaternion<T>& quat);
template<typename U> explicit NzEulerAngles(const NzEulerAngles<U>& angles);
NzEulerAngles(const NzEulerAngles& angles) = default;
~NzEulerAngles() = default;
NzVector3<T> GetForward() const;
NzVector3<T> GetRight() const;
NzVector3<T> GetUp() const;
void Normalize();
void Set(T P, T Y, T R);
void Set(T angles[3]);
void Set(const NzEulerAngles<T>& angles);
//void Set(const NzMatrix3<T>& mat);
void Set(const NzQuaternion<T>& quat);
template<typename U> void Set(const NzEulerAngles<U>& angles);
void SetZero();
//NzEulerAngles<T> ToEulerAngles() const;
//NzMatrix3<T> ToRotationMatrix() const;
NzQuaternion<T> ToQuaternion() const;
NzString ToString() 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);
bool operator==(const NzEulerAngles& angles) const;
bool operator!=(const NzEulerAngles& angles) const;
T pitch, yaw, roll;
};
template<typename T> std::ostream& operator<<(std::ostream& out, const NzEulerAngles<T>& angles);
typedef NzEulerAngles<double> NzEulerAnglesd;
typedef NzEulerAngles<float> NzEulerAnglesf;
#include <Nazara/Math/EulerAngles.inl>
#endif // NAZARA_EULERANGLES_HPP

View File

@@ -0,0 +1,199 @@
// 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 <Nazara/Math/Basic.hpp>
#include <Nazara/Math/Quaternion.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <cmath>
#include <Nazara/Core/Debug.hpp>
template<typename T>
NzEulerAngles<T>::NzEulerAngles()
{
}
template<typename T>
NzEulerAngles<T>::NzEulerAngles(T P, T Y, T R)
{
Set(P, Y, R);
}
template<typename T>
NzEulerAngles<T>::NzEulerAngles(T angles[3])
{
Set(angles);
}
template<typename T>
NzEulerAngles<T>::NzEulerAngles(const NzQuaternion<T>& quat)
{
Set(quat);
}
template<typename T>
template<typename U>
NzEulerAngles<T>::NzEulerAngles(const NzEulerAngles<U>& angles)
{
Set(angles);
}
template<typename T>
NzVector3<T> NzEulerAngles<T>::GetForward() const
{
#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
}
template<typename T>
void NzEulerAngles<T>::Normalize()
{
pitch = NzNormalizeAngle(pitch);
yaw = NzNormalizeAngle(yaw);
roll = NzNormalizeAngle(roll);
}
template<typename T>
void NzEulerAngles<T>::Set(T P, T Y, T R)
{
pitch = P;
yaw = Y;
roll = R;
}
template<typename T>
void NzEulerAngles<T>::Set(T angles[3])
{
pitch = angles[0];
yaw = angles[1];
roll = angles[2];
}
template<typename T>
void NzEulerAngles<T>::Set(const NzEulerAngles& angles)
{
pitch = angles.pitch;
yaw = angles.yaw;
roll = angles.roll;
}
template<typename T>
void NzEulerAngles<T>::Set(const NzQuaternion<T>& quat)
{
Set(quat.ToEulerAngles());
}
template<typename T>
template<typename U>
void NzEulerAngles<T>::Set(const NzEulerAngles<U>& angles)
{
pitch = static_cast<T>(angles.pitch);
yaw = static_cast<T>(angles.yaw);
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));
return Qx * Qy * Qz;
}
template<typename T>
NzString NzEulerAngles<T>::ToString() const
{
NzStringStream ss;
return ss << "EulerAngles(" << pitch << ", " << yaw << ", " << roll << ')';
}
template<typename T>
NzEulerAngles<T> NzEulerAngles<T>::operator+(const NzEulerAngles& angles) const
{
return NzEulerAngles(pitch + angles.pitch,
yaw + angles.yaw,
roll + angles.roll);
}
template<typename T>
NzEulerAngles<T> NzEulerAngles<T>::operator-(const NzEulerAngles& angles) const
{
return NzEulerAngles(pitch - angles.pitch,
yaw - angles.yaw,
roll - angles.roll);
}
template<typename T>
NzEulerAngles<T> NzEulerAngles<T>::operator+=(const NzEulerAngles& angles)
{
pitch += angles.pitch;
yaw += angles.yaw;
roll += angles.roll;
return *this;
}
template<typename T>
NzEulerAngles<T> NzEulerAngles<T>::operator-=(const NzEulerAngles& angles)
{
pitch -= angles.pitch;
yaw -= angles.yaw;
roll -= angles.roll;
return *this;
}
template<typename T>
bool NzEulerAngles<T>::operator==(const NzEulerAngles& angles) const
{
return NzNumberEquals(pitch, angles.pitch) &&
NzNumberEquals(yaw, angles.yaw) &&
NzNumberEquals(roll, angles.roll);
}
template<typename T>
bool NzEulerAngles<T>::operator!=(const NzEulerAngles& angles) const
{
return !operator==(angles);
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const NzEulerAngles<T>& angles)
{
return out << angles.ToString();
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -0,0 +1,100 @@
// 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_MATRIX4_HPP
#define NAZARA_MATRIX4_HPP
#include <Nazara/Core/String.hpp>
template<typename T> class NzEulerAngles;
template<typename T> class NzQuaternion;
template<typename T> class NzVector2;
template<typename T> class NzVector3;
template<typename T> class NzVector4;
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);
NzMatrix4(T matrix[16]);
//NzMatrix4(const NzMatrix3<T>& mat);
template<typename U> explicit NzMatrix4(const NzMatrix4<U>& mat);
NzMatrix4(const NzMatrix4& mat) = default;
~NzMatrix4() = default;
T GetDeterminant() const;
NzMatrix4 GetInverse() const;
//NzMatrix3 GetRotationMatrix() const;
NzVector3<T> GetScale() const;
NzVector3<T> GetTranslation() const;
NzMatrix4 GetTransposed() const;
bool HasNegativeScale() const;
bool HasScale() const;
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);
void Set(T matrix[16]);
//NzMatrix4(const NzMatrix3<T>& mat);
void Set(const NzMatrix4& mat);
template<typename U> void Set(const NzMatrix4<U>& mat);
void SetIdentity();
void SetLookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up);
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;
NzVector2<T> Transform(const NzVector2<T>& vector, T z = 0.0, T w = 1.0) const;
NzVector3<T> Transform(const NzVector3<T>& vector, T w = 1.0) const;
NzVector4<T> Transform(const NzVector4<T>& vector) const;
NzMatrix4& Transpose();
operator T*();
operator const T*() const;
T& operator()(unsigned int x, unsigned int y);
const T& operator()(unsigned int x, unsigned int y) const;
NzMatrix4 operator*(const NzMatrix4& mat) const;
NzVector2<T> operator*(const NzVector2<T>& vector) const;
NzVector3<T> operator*(const NzVector3<T>& vector) const;
NzVector4<T> operator*(const NzVector4<T>& vector) const;
NzMatrix4 operator*(T scalar) const;
NzMatrix4& operator*=(const NzMatrix4& mat);
NzMatrix4& operator*=(T scalar);
static NzMatrix4 LookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up);
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);
T m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44;
};
template<typename T> std::ostream& operator<<(std::ostream& out, const NzMatrix4<T>& mat);
typedef NzMatrix4<double> NzMatrix4d;
typedef NzMatrix4<float> NzMatrix4f;
#include <Nazara/Math/Matrix4.inl>
#endif // NAZARA_MATRIX4_HPP

View File

@@ -0,0 +1,576 @@
// 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 <Nazara/Math/Basic.hpp>
#include <Nazara/Math/EulerAngles.hpp>
#include <Nazara/Math/Quaternion.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Math/Vector4.hpp>
#include <cmath>
#include <cstring>
#include <limits>
#include <stdexcept>
#include <Nazara/Core/Debug.hpp>
template<typename T>
NzMatrix4<T>::NzMatrix4()
{
}
template<typename T>
NzMatrix4<T>::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)
{
Set(r11, r12, r13, r14,
r21, r22, r23, r24,
r31, r32, r33, r34,
r41, r42, r43, r44);
}
template<typename T>
NzMatrix4<T>::NzMatrix4(T matrix[16])
{
Set(matrix);
}
template<typename T>
template<typename U>
NzMatrix4<T>::NzMatrix4(const NzMatrix4<U>& mat)
{
Set(mat);
}
template<typename T>
T NzMatrix4<T>::GetDeterminant() const
{
T A = m22 * (m33 * m44 - m43 * m34) - m32 * (m23 * m44 - m43 * m24) + m42 * (m23 * m34 - m33 * m24);
T B = m12 * (m33 * m44 - m43 * m34) - m32 * (m13 * m44 - m43 * m14) + m42 * (m13 * m34 - m33 * m14);
T C = m12 * (m23 * m44 - m43 * m24) - m22 * (m13 * m44 - m43 * m14) + m42 * (m13 * m24 - m23 * m14);
T D = m12 * (m23 * m34 - m33 * m24) - m22 * (m13 * m34 - m33 * m14) + m32 * (m13 * m24 - m23 * m14);
return m11 * A - m21 * B + m31 * C - m41 * D;
}
template<typename T>
NzMatrix4<T> NzMatrix4<T>::GetInverse() const
{
NzMatrix4 mat;
T det = GetDeterminant();
if (det != 0.0)
{
mat.m11 = (m22 * (m33 * m44 - m34 * m43) - m32 * (m23 * m44 - m43 * m24) + m42 * (m23 * m34 - m33 * m24)) / det;
mat.m12 = -(m12 * (m33 * m44 - m43 * m34) - m32 * (m13 * m44 - m43 * m14) + m42 * (m13 * m34 - m33 * m14)) / det;
mat.m13 = (m12 * (m23 * m44 - m43 * m24) - m22 * (m13 * m44 - m43 * m14) + m42 * (m13 * m24 - m23 * m14)) / det;
mat.m14 = -(m12 * (m23 * m34 - m33 * m24) - m22 * (m13 * m34 - m33 * m14) + m32 * (m13 * m24 - m23 * m14)) / det;
mat.m21 = -(m21 * (m33 * m44 - m34 * m43) - m23 * (m31 * m44 - m34 * m41) + m24 * (m31 * m43 - m33 * m41)) / det;
mat.m22 = (m11 * (m33 * m44 - m34 * m43) - m13 * (m31 * m44 - m34 * m41) + m14 * (m31 * m43 - m33 * m41)) / det;
mat.m23 = -(m11 * (m23 * m44 - m24 * m43) - m13 * (m21 * m44 - m24 * m41) + m14 * (m21 * m43 - m23 * m41)) / det;
mat.m24 = (m11 * (m23 * m34 - m24 * m33) - m13 * (m21 * m34 - m24 * m31) + m14 * (m21 * m33 - m23 * m31)) / det;
mat.m31 = (m21 * (m32 * m44 - m34 * m42) - m22 * (m31 * m44 - m34 * m41) + m24 * (m31 * m42 - m32 * m41)) / det;
mat.m32 = -(m11 * (m32 * m44 - m34 * m42) - m12 * (m31 * m44 - m34 * m41) + m14 * (m31 * m42 - m32 * m41)) / det;
mat.m33 = (m11 * (m22 * m44 - m24 * m42) - m12 * (m21 * m44 - m24 * m41) + m14 * (m21 * m42 - m22 * m41)) / det;
mat.m34 = -(m11 * (m22 * m34 - m24 * m32) - m12 * (m21 * m34 - m24 * m31) + m14 * (m21 * m32 - m22 * m31)) / det;
mat.m41 = -(m21 * (m32 * m43 - m33 * m42) - m22 * (m31 * m43 - m33 * m41) + m23 * (m31 * m42 - m32 * m41)) / det;
mat.m42 = (m11 * (m32 * m43 - m33 * m42) - m12 * (m31 * m43 - m33 * m41) + m13 * (m31 * m42 - m32 * m41)) / det;
mat.m43 = -(m11 * (m22 * m43 - m23 * m42) - m12 * (m21 * m43 - m23 * m41) + m13 * (m21 * m42 - m22 * m41)) / det;
mat.m44 = (m11 * (m22 * m33 - m23 * m32) - m12 * (m21 * m33 - m23 * m31) + m13 * (m21 * m32 - m22 * m31)) / det;
}
return mat;
}
template<typename T>
NzVector3<T> NzMatrix4<T>::GetScale() const
{
return NzVector3<T>(std::sqrt(m11 * m11 + m21 * m21 + m31 * m31),
std::sqrt(m12 * m12 + m22 * m22 + m32 * m32),
std::sqrt(m13 * m13 + m23 * m23 + m33 * m33));
}
template<typename T>
NzVector3<T> NzMatrix4<T>::GetTranslation() const
{
#if NAZARA_MATH_MATRIX_COLUMN_MAJOR
return NzVector3<T>(m41, m42, m43);
#else
return NzVector3<T>(m14, m24, m34);
#endif
}
template<typename T>
NzMatrix4<T> NzMatrix4<T>::GetTransposed() const
{
return NzMatrix4(m11, m21, m31, m41,
m12, m22, m32, m42,
m13, m23, m33, m43,
m14, m24, m34, m44);
}
template<typename T>
bool NzMatrix4<T>::HasNegativeScale() const
{
return GetDeterminant() < 0.f;
}
template<typename T>
bool NzMatrix4<T>::HasScale() const
{
T t = m11 * m11 + m21 * m21 + m31 * m31;
if (1.0 - t > std::numeric_limits<T>::epsilon())
return true;
t = m12 * m12 + m22 * m22 + m32 * m32;
if (1.0 - t > std::numeric_limits<T>::epsilon())
return true;
t = m13 * m13 + m23 * m23 + m33 * m33;
if (1.0 - t > std::numeric_limits<T>::epsilon())
return true;
return false;
}
template<typename T>
void NzMatrix4<T>::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)
{
m11 = r11;
m12 = r12;
m13 = r13;
m14 = r14;
m21 = r21;
m22 = r22;
m23 = r23;
m24 = r24;
m31 = r31;
m32 = r32;
m33 = r33;
m34 = r34;
m41 = r41;
m42 = r42;
m43 = r43;
m44 = r44;
}
template<typename T> void NzMatrix4<T>::Set(T matrix[16])
{
// Ici nous sommes certains de la continuité des éléments en mémoire
std::memcpy(&m41, matrix, 16*sizeof(T));
}
template<typename T> void NzMatrix4<T>::Set(const NzMatrix4& mat)
{
// Pareil
std::memcpy(&m41, &mat.m41, 16*sizeof(T));
}
template<typename T>
template<typename U>
void NzMatrix4<T>::Set(const NzMatrix4<U>& mat)
{
m11 = static_cast<T>(mat.m11);
m12 = static_cast<T>(mat.m12);
m13 = static_cast<T>(mat.m13);
m14 = static_cast<T>(mat.m14);
m21 = static_cast<T>(mat.m21);
m22 = static_cast<T>(mat.m22);
m23 = static_cast<T>(mat.m23);
m24 = static_cast<T>(mat.m24);
m31 = static_cast<T>(mat.m31);
m32 = static_cast<T>(mat.m32);
m33 = static_cast<T>(mat.m33);
m34 = static_cast<T>(mat.m34);
m41 = static_cast<T>(mat.m41);
m42 = static_cast<T>(mat.m42);
m43 = static_cast<T>(mat.m43);
m44 = static_cast<T>(mat.m44);
}
template<typename T>
void NzMatrix4<T>::SetIdentity()
{
Set(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0);
}
template<typename T>
void NzMatrix4<T>::SetLookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up)
{
NzVector3<T> f = center - eye;
f.Normalize();
NzVector3<T> u = up;
u.Normalize();
NzVector3<T> s = f.CrossProduct(u);
s.Normalize();
u = s.CrossProduct(f);
Set(s.x, u.x, -f.x, 0.0,
s.y, u.y, -f.y, 0.0,
s.z, u.z, -f.z, 0.0,
0.0, 0.0, 0.0, 1.0);
operator*=(Translate(-eye));
}
template<typename T>
void NzMatrix4<T>::SetPerspective(T angle, T ratio, T zNear, T zFar)
{
#if NAZARA_MATH_ANGLE_RADIAN
angle /= 2;
#else
angle = NzDegreeToRadian(angle/2);
#endif
T f = 1 / std::tan(angle);
#if NAZARA_MATH_MATRIX_COLUMN_MAJOR
Set(f / ratio, 0.0, 0.0, 0.0,
0.0, f, 0.0, 0.0,
0.0, 0.0, (zNear + zFar) / (zNear - zFar), -1.0,
0.0, 0.0, (2 * zNear * zFar) / (zNear - zFar), 1.0);
#else
Set(f / ratio, 0.0, 0.0, 0.0,
0.0, f, 0.0, 0.0,
0.0, 0.0, (zNear + zFar) / (zNear - zFar), (2 * zNear * zFar) / (zNear - zFar),
0.0, 0.0, -1.0, 1.0);
#endif
}
template<typename T>
void NzMatrix4<T>::SetRotation(const NzQuaternion<T>& rotation)
{
// http://www.flipcode.com/documents/matrfaq.html#Q54
T xx = rotation.x * rotation.x;
T xy = rotation.x * rotation.y;
T xz = rotation.x * rotation.z;
T xw = rotation.x * rotation.w;
T yy = rotation.y * rotation.y;
T yz = rotation.y * rotation.z;
T yw = rotation.y * rotation.w;
T zz = rotation.z * rotation.z;
T zw = rotation.z * rotation.w;
Set(1.0 - 2.0*(yy+zz), 2.0*(xy-zw), 2.0*(xz+yw), 0.0,
2.0*(xz+zw), 1.0 - 2.0*(xx+zz), 2.0*(yz-xw), 0.0,
2.0*(xz-yw), 2.0*(yz+xw), 1.0 - 2.0*(xx+yy), 0.0,
0.0, 0.0, 0.0, 1.0);
}
template<typename T>
void NzMatrix4<T>::SetScale(const NzVector3<T>& vector)
{
Set(vector.x, 0.0, 0.0, 0.0,
0.0, vector.y, 0.0, 0.0,
0.0, 0.0, vector.z, 0.0,
0.0, 0.0, 0.0, 1.0);
}
template<typename T>
void NzMatrix4<T>::SetTranslation(const NzVector3<T>& translation)
{
#if NAZARA_MATH_MATRIX_COLUMN_MAJOR
Set(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
translation.x, translation.y, translation.z, 1.0);
#else
Set(1.0, 0.0, 0.0, translation.x,
0.0, 1.0, 0.0, translation.y,
0.0, 0.0, 1.0, translation.z,
0.0, 0.0, 0.0, 1.0);
#endif
}
template<typename T>
void NzMatrix4<T>::SetZero()
{
Set(0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0);
}
template<typename T>
NzString NzMatrix4<T>::ToString() const
{
NzStringStream ss;
return ss << "Matrix4(" << m11 << ", " << m12 << ", " << m13 << ", " << m14 << ",\n"
<< " " << m21 << ", " << m22 << ", " << m23 << ", " << m24 << ",\n"
<< " " << m31 << ", " << m32 << ", " << m33 << ", " << m34 << ",\n"
<< " " << m41 << ", " << m42 << ", " << m43 << ", " << m44 << ')';
}
template<typename T>
NzVector2<T> NzMatrix4<T>::Transform(const NzVector2<T>& vector, T z, T w) const
{
return NzVector2<T>(m11 * vector.x + m12 * vector.y + m13 * z + m14 * w,
m21 * vector.x + m22 * vector.y + m23 * z + m24 * w);
}
template<typename T>
NzVector3<T> NzMatrix4<T>::Transform(const NzVector3<T>& vector, T w) const
{
return NzVector3<T>(m11 * vector.x + m12 * vector.y + m13 * vector.z + m14 * w,
m21 * vector.x + m22 * vector.y + m23 * vector.z + m24 * w,
m31 * vector.x + m32 * vector.y + m33 * vector.z + m34 * w);
}
template<typename T>
NzVector4<T> NzMatrix4<T>::Transform(const NzVector4<T>& vector) const
{
return NzVector4<T>(m11 * vector.x + m12 * vector.y + m13 * vector.z + m14 * vector.w,
m21 * vector.x + m22 * vector.y + m23 * vector.z + m24 * vector.w,
m31 * vector.x + m32 * vector.y + m33 * vector.z + m34 * vector.w,
m41 * vector.x + m42 * vector.y + m43 * vector.z + m44 * vector.w);
}
template<typename T>
NzMatrix4<T>& NzMatrix4<T>::Transpose()
{
std::swap(m12, m21);
std::swap(m13, m31);
std::swap(m14, m41);
std::swap(m23, m32);
std::swap(m24, m42);
std::swap(m34, m43);
return *this;
}
template<typename T>
NzMatrix4<T>::operator T*()
{
return &m11;
}
template<typename T>
NzMatrix4<T>::operator const T*() const
{
return &m11;
}
template<typename T>
T& NzMatrix4<T>::operator()(unsigned int x, unsigned int y)
{
#if NAZARA_MATH_SAFE
if (x > 3 || y > 3)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Index out of range: (" << x << ", " << y << ") > (3,3)";
throw std::out_of_range(ss.ToString());
}
#endif
return (&m11)[x*4+y];
}
template<typename T>
const T& NzMatrix4<T>::operator()(unsigned int x, unsigned int y) const
{
#if NAZARA_MATH_SAFE
if (x > 3 || y > 3)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Index out of range: (" << x << ", " << y << ") > (3,3)";
throw std::out_of_range(ss.ToString());
}
#endif
return (&m11)[x*4+y];
}
template<typename T>
NzMatrix4<T> NzMatrix4<T>::operator*(const NzMatrix4& mat) const
{
NzMatrix4 matrix;
for(int k = 0; k < 4; k++)
{
for(int j = 0; j < 4; j++)
{
for(int i = 0; i < 4; i++)
matrix(j, k) += (*this)(j, i) * mat(i, k);
}
}
return matrix;
/*return NzMatrix4(m11 * mat.m11 + m21 * mat.m12 + m31 * mat.m13 + m41 * mat.m14,
m12 * mat.m11 + m22 * mat.m12 + m32 * mat.m13 + m42 * mat.m14,
m13 * mat.m11 + m23 * mat.m12 + m33 * mat.m13 + m43 * mat.m14,
m14 * mat.m11 + m24 * mat.m12 + m34 * mat.m13 + m44 * mat.m14,
m11 * mat.m21 + m21 * mat.m22 + m31 * mat.m23 + m41 * mat.m24,
m12 * mat.m21 + m22 * mat.m22 + m32 * mat.m23 + m42 * mat.m24,
m13 * mat.m21 + m23 * mat.m22 + m33 * mat.m23 + m43 * mat.m24,
m14 * mat.m21 + m24 * mat.m22 + m34 * mat.m23 + m44 * mat.m24,
m11 * mat.m31 + m21 * mat.m32 + m31 * mat.m33 + m41 * mat.m34,
m12 * mat.m31 + m22 * mat.m32 + m32 * mat.m33 + m42 * mat.m34,
m13 * mat.m31 + m23 * mat.m32 + m33 * mat.m33 + m43 * mat.m34,
m14 * mat.m31 + m24 * mat.m32 + m34 * mat.m33 + m44 * mat.m34,
m11 * mat.m41 + m21 * mat.m42 + m31 * mat.m43 + m41 * mat.m44,
m12 * mat.m41 + m22 * mat.m42 + m32 * mat.m43 + m42 * mat.m44,
m13 * mat.m41 + m23 * mat.m42 + m33 * mat.m43 + m43 * mat.m44,
m14 * mat.m41 + m24 * mat.m42 + m34 * mat.m43 + m44 * mat.m44);*/
}
template<typename T>
NzVector2<T> NzMatrix4<T>::operator*(const NzVector2<T>& vector) const
{
return Transform(vector);
}
template<typename T>
NzVector3<T> NzMatrix4<T>::operator*(const NzVector3<T>& vector) const
{
return Transform(vector);
}
template<typename T>
NzVector4<T> NzMatrix4<T>::operator*(const NzVector4<T>& vector) const
{
return Transform(vector);
}
template<typename T>
NzMatrix4<T> NzMatrix4<T>::operator*(T scalar) const
{
return NzMatrix4(m11 * scalar, m12 * scalar, m13 * scalar, m14 * scalar,
m21 * scalar, m22 * scalar, m23 * scalar, m24 * scalar,
m31 * scalar, m32 * scalar, m33 * scalar, m34 * scalar,
m41 * scalar, m42 * scalar, m43 * scalar, m44 * scalar);
}
template<typename T>
NzMatrix4<T>& NzMatrix4<T>::operator*=(const NzMatrix4& mat)
{
T r11 = m11 * mat.m11 + m21 * mat.m12 + m31 * mat.m13 + m41 * mat.m14;
T r12 = m12 * mat.m11 + m22 * mat.m12 + m32 * mat.m13 + m42 * mat.m14;
T r13 = m13 * mat.m11 + m23 * mat.m12 + m33 * mat.m13 + m43 * mat.m14;
T r14 = m14 * mat.m11 + m24 * mat.m12 + m34 * mat.m13 + m44 * mat.m14;
T r21 = m11 * mat.m21 + m21 * mat.m22 + m31 * mat.m23 + m41 * mat.m24;
T r22 = m12 * mat.m21 + m22 * mat.m22 + m32 * mat.m23 + m42 * mat.m24;
T r23 = m13 * mat.m21 + m23 * mat.m22 + m33 * mat.m23 + m43 * mat.m24;
T r24 = m14 * mat.m21 + m24 * mat.m22 + m34 * mat.m23 + m44 * mat.m24;
T r31 = m11 * mat.m31 + m21 * mat.m32 + m31 * mat.m33 + m41 * mat.m34;
T r32 = m12 * mat.m31 + m22 * mat.m32 + m32 * mat.m33 + m42 * mat.m34;
T r33 = m13 * mat.m31 + m23 * mat.m32 + m33 * mat.m33 + m43 * mat.m34;
T r34 = m14 * mat.m31 + m24 * mat.m32 + m34 * mat.m33 + m44 * mat.m34;
T r41 = m11 * mat.m41 + m21 * mat.m42 + m31 * mat.m43 + m41 * mat.m44;
T r42 = m12 * mat.m41 + m22 * mat.m42 + m32 * mat.m43 + m42 * mat.m44;
T r43 = m13 * mat.m41 + m23 * mat.m42 + m33 * mat.m43 + m43 * mat.m44;
m44 = m14 * mat.m41 + m24 * mat.m42 + m34 * mat.m43 + m44 * mat.m44;
m43 = r43;
m42 = r42;
m41 = r41;
m34 = r34;
m33 = r33;
m32 = r32;
m31 = r31;
m24 = r24;
m23 = r23;
m22 = r22;
m21 = r21;
m14 = r14;
m13 = r13;
m12 = r12;
m11 = r11;
return *this;
}
template<typename T>
NzMatrix4<T>& NzMatrix4<T>::operator*=(T scalar)
{
m11 *= scalar;
m12 *= scalar;
m13 *= scalar;
m14 *= scalar;
m21 *= scalar;
m22 *= scalar;
m23 *= scalar;
m24 *= scalar;
m31 *= scalar;
m32 *= scalar;
m33 *= scalar;
m34 *= scalar;
m41 *= scalar;
m42 *= scalar;
m43 *= scalar;
m44 *= scalar;
return *this;
}
template<typename T>
NzMatrix4<T> NzMatrix4<T>::LookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up)
{
NzMatrix4 mat;
mat.SetLookAt(eye, center, up);
return mat;
}
template<typename T>
NzMatrix4<T> NzMatrix4<T>::Perspective(T angle, T ratio, T zNear, T zFar)
{
NzMatrix4 mat;
mat.SetPerspective(angle, ratio, zNear, zFar);
return mat;
}
template<typename T>
NzMatrix4<T> NzMatrix4<T>::Rotate(const NzQuaternion<T>& rotation)
{
NzMatrix4 mat;
mat.SetRotation(rotation);
return mat;
}
template<typename T>
NzMatrix4<T> NzMatrix4<T>::Scale(const NzVector3<T>& scale)
{
NzMatrix4 mat;
mat.SetScale(scale);
return mat;
}
template<typename T>
NzMatrix4<T> NzMatrix4<T>::Translate(const NzVector3<T>& translation)
{
NzMatrix4 mat;
mat.SetTranslation(translation);
return mat;
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const NzMatrix4<T>& mat)
{
return out << mat.ToString();
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -0,0 +1,78 @@
// Copyright (C) 2012 Rémi Begues
// 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_QUATERNION_HPP
#define NAZARA_QUATERNION_HPP
#include <Nazara/Core/String.hpp>
template<typename T> class NzEulerAngles;
template<typename T> class NzVector3;
template<typename T> class NzQuaternion
{
public:
NzQuaternion();
NzQuaternion(T W, T X, T Y, T Z);
NzQuaternion(T quat[4]);
NzQuaternion(T angle, const NzVector3<T>& axis);
NzQuaternion(const NzEulerAngles<T>& angles);
//NzQuaternion(const NzMatrix3<T>& mat);
template<typename U> explicit NzQuaternion(const NzQuaternion<U>& quat);
NzQuaternion(const NzQuaternion& quat) = default;
~NzQuaternion() = default;
NzQuaternion GetConjugate() const;
NzQuaternion GetNormalized() const;
double Magnitude() const;
double Normalize();
T SquaredMagnitude() const;
void Set(T W, T X, T Y, T Z);
void Set(T quat[4]);
void Set(T angle, const NzVector3<T>& normalizedAxis);
void Set(const NzEulerAngles<T>& angles);
//void Set(const NzMatrix3<T>& mat);
void Set(const NzQuaternion& quat);
template<typename U> void Set(const NzQuaternion<U>& quat);
void SetIdentity();
void SetZero();
NzEulerAngles<T> ToEulerAngles() const;
//NzMatrix3<T> ToRotationMatrix() const;
NzString ToString() const;
NzQuaternion operator+(const NzQuaternion& quat) const;
NzQuaternion operator*(const NzQuaternion& quat) const;
NzVector3<T> operator*(const NzVector3<T>& vec) const;
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);
bool operator==(const NzQuaternion& quat) const;
bool operator!=(const NzQuaternion& quat) const;
bool operator<(const NzQuaternion& quat) const;
bool operator<=(const NzQuaternion& quat) const;
bool operator>(const NzQuaternion& quat) const;
bool operator>=(const NzQuaternion& quat) const;
T w, x, y, z;
};
template<typename T> std::ostream& operator<<(std::ostream& out, const NzQuaternion<T>& quat);
typedef NzQuaternion<double> NzQuaterniond;
typedef NzQuaternion<float> NzQuaternionf;
#include <Nazara/Math/Quaternion.inl>
#endif // NAZARA_QUATERNION_HPP

View File

@@ -0,0 +1,328 @@
// Copyright (C) 2012 Rémi Begues
// 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 <Nazara/Math/Basic.hpp>
#include <Nazara/Math/EulerAngles.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Core/Debug.hpp>
template<typename T>
NzQuaternion<T>::NzQuaternion()
{
}
template<typename T>
NzQuaternion<T>::NzQuaternion(T W, T X, T Y, T Z)
{
Set(W, X, Y, Z);
}
template<typename T>
NzQuaternion<T>::NzQuaternion(T quat[4])
{
Set(quat);
}
template<typename T>
NzQuaternion<T>::NzQuaternion(T angle, const NzVector3<T>& axis)
{
Set(angle, axis);
}
template<typename T>
NzQuaternion<T>::NzQuaternion(const NzEulerAngles<T>& angles)
{
Set(angles);
}
/*
template<typename T>
NzQuaternion<T>::NzQuaternion(const NzMatrix3<T>& mat)
{
Set(mat);
}
*/
template<typename T>
template<typename U>
NzQuaternion<T>::NzQuaternion(const NzQuaternion<U>& quat)
{
Set(quat);
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::GetConjugate() const
{
return NzQuaternion(w, -x, -y, -z);
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::GetNormalized() const
{
NzQuaternion<T> quat(*this);
quat.Normalize();
return quat;
}
template<typename T>
double NzQuaternion<T>::Magnitude() const
{
return std::sqrt(SquaredMagnitude());
}
template<typename T>
double NzQuaternion<T>::Normalize()
{
double length = Magnitude();
if (length != 0.0)
{
w /= length;
x /= length;
y /= length;
z /= length;
}
return length;
}
template<typename T>
T NzQuaternion<T>::SquaredMagnitude() const
{
return w * w + x * x + y * y + z * z;
}
template<typename T>
void NzQuaternion<T>::Set(T W, T X, T Y, T Z)
{
w = W;
x = X;
y = Y;
z = Z;
}
template<typename T>
void NzQuaternion<T>::Set(T quat[4])
{
w = quat[0];
x = quat[1];
y = quat[2];
z = quat[3];
}
template<typename T>
void NzQuaternion<T>::Set(T angle, const NzVector3<T>& normalizedAxis)
{
#if !NAZARA_MATH_ANGLE_RADIAN
angle = NzDegreeToRadian(angle);
#endif
angle /= 2;
auto sinAngle = std::sin(angle);
w = std::cos(angle);
x = normalizedAxis.x * sinAngle;
y = normalizedAxis.y * sinAngle;
z = normalizedAxis.z * sinAngle;
}
template<typename T>
void NzQuaternion<T>::Set(const NzEulerAngles<T>& angles)
{
Set(angles.ToQuaternion());
}
template<typename T>
template<typename U>
void NzQuaternion<T>::Set(const NzQuaternion<U>& quat)
{
w = static_cast<T>(quat.w);
x = static_cast<T>(quat.x);
y = static_cast<T>(quat.y);
z = static_cast<T>(quat.z);
}
template<typename T>
void NzQuaternion<T>::Set(const NzQuaternion& quat)
{
w = quat.w;
x = quat.x;
y = quat.y;
z = quat.z;
}
template<typename T>
void NzQuaternion<T>::SetIdentity()
{
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>
NzEulerAngles<T> NzQuaternion<T>::ToEulerAngles() const
{
T test = x*y + z*w;
if (test > 0.499)
// singularity at north pole
return NzEulerAngles<T>(NzDegrees(90.0), NzRadians(2.0 * std::atan2(x, w)), 0.0);
if (test < -0.499)
return NzEulerAngles<T>(NzDegrees(-90.0), NzRadians(-2.0 * std::atan2(x, w)), 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)));
}
template<typename T>
NzString NzQuaternion<T>::ToString() const
{
NzStringStream ss;
return ss << "Quaternion(" << w << " | " << x << ", " << y << ", " << 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);
}
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);
}
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;
return vec + uv + uuv;
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator*(T scale) const
{
return NzQuaternion(w * scale,
x * scale,
y * scale,
z * scale);
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator/(const NzQuaternion& quat) const
{
return GetConjugate(quat) * (*this);
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator+=(const NzQuaternion& quat)
{
w += quat.w;
x += quat.x;
y += quat.y;
z += quat.z;
return *this;
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator*=(const NzQuaternion& quat)
{
NzQuaternion q(*this);
operator=(q * quat);
return *this;
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator*=(T scale)
{
w *= scale;
x *= scale;
y *= scale;
z *= scale;
return *this;
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator/=(const NzQuaternion& quat)
{
NzQuaternion q(*this);
operator=(q / quat);
return *this;
}
template<typename T>
bool NzQuaternion<T>::operator==(const NzQuaternion& quat) const
{
return NzNumberEquals(w, quat.w) &&
NzNumberEquals(x, quat.x) &&
NzNumberEquals(y, quat.y) &&
NzNumberEquals(z, quat.z);
}
template<typename T>
bool NzQuaternion<T>::operator!=(const NzQuaternion& quat) const
{
return !operator==(quat);
}
template<typename T>
bool NzQuaternion<T>::operator<(const NzQuaternion& quat) const
{
return w < quat.w && x < quat.x && y < quat.y && z < quat.z;
}
template<typename T>
bool NzQuaternion<T>::operator<=(const NzQuaternion& quat) const
{
return operator<(quat) || operator==(quat);
}
template<typename T>
bool NzQuaternion<T>::operator>(const NzQuaternion& quat) const
{
return !operator<=(quat);
}
template<typename T>
bool NzQuaternion<T>::operator>=(const NzQuaternion& quat) const
{
return !operator<(quat);
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const NzQuaternion<T>& quat)
{
return out << quat.ToString();
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -0,0 +1,80 @@
// 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_VECTOR2_HPP
#define NAZARA_VECTOR2_HPP
#include <Nazara/Core/String.hpp>
template<typename T> class NzVector2
{
public:
NzVector2();
NzVector2(T X, T Y);
explicit NzVector2(T scale);
NzVector2(T vec[2]);
template<typename U> explicit NzVector2(const NzVector2<U>& vec);
NzVector2(const NzVector2& vec) = default;
~NzVector2() = default;
T AbsDotProduct(const NzVector2& vec) const;
double Distance(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 SquaredDistance(const NzVector2& vec) const;
T SquaredLength() const;
NzString ToString() const;
operator NzString() const;
T& operator[](unsigned int i);
T operator[](unsigned int i) const;
const NzVector2& operator+() const;
NzVector2 operator-() const;
NzVector2 operator+(const NzVector2& vec) const;
NzVector2 operator-(const NzVector2& vec) const;
NzVector2 operator*(const NzVector2& vec) const;
NzVector2 operator*(T scale) const;
NzVector2 operator/(const NzVector2& vec) const;
NzVector2 operator/(T scale) const;
NzVector2& operator+=(const NzVector2& vec);
NzVector2& operator-=(const NzVector2& vec);
NzVector2& operator*=(const NzVector2& vec);
NzVector2& operator*=(T scale);
NzVector2& operator/=(const NzVector2& vec);
NzVector2& operator/=(T scale);
bool operator==(const NzVector2& vec) const;
bool operator!=(const NzVector2& vec) const;
bool operator<(const NzVector2& vec) const;
bool operator<=(const NzVector2& vec) const;
bool operator>(const NzVector2& vec) const;
bool operator>=(const NzVector2& vec) const;
T x;
T y;
};
template<typename T> std::ostream& operator<<(std::ostream& out, const NzVector2<T>& vec);
template<typename T> NzVector2<T> operator*(T scale, const NzVector2<T>& vec);
template<typename T> NzVector2<T> operator/(T scale, const NzVector2<T>& vec);
typedef NzVector2<double> NzVector2d;
typedef NzVector2<float> NzVector2f;
typedef NzVector2<int> NzVector2i;
#include <Nazara/Math/Vector2.inl>
#endif // NAZARA_VECTOR2_HPP

View File

@@ -0,0 +1,369 @@
// 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 <Nazara/Math/Basic.hpp>
#include <cmath>
#include <cstdlib>
#include <stdexcept>
#include <Nazara/Core/Debug.hpp>
template<typename T>
NzVector2<T>::NzVector2()
{
}
template<typename T>
NzVector2<T>::NzVector2(T X, T Y) :
x(X),
y(Y)
{
}
template<typename T>
NzVector2<T>::NzVector2(T scale) :
x(scale),
y(scale)
{
}
template<typename T>
NzVector2<T>::NzVector2(T vec[2]) :
x(vec[0]),
y(vec[1])
{
}
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))
{
}
template<typename T>
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
{
return std::labs(x * vec.x) + std::labs(y * vec.y);
}
template<typename T>
double NzVector2<T>::Distance(const NzVector2& vec) const
{
return std::sqrt(SquaredDistance(vec));
}
template<typename T>
T NzVector2<T>::DotProduct(const NzVector2& vec) const
{
return x * vec.x + y * vec.y;
}
template<typename T>
NzVector2<T> NzVector2<T>::GetNormal() const
{
NzVector2 vec(*this);
vec.Normalize();
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>
double NzVector2<T>::Length() const
{
return std::sqrt(SquaredLength());
}
template<typename T>
double NzVector2<T>::Normalize()
{
double length = Length();
if (length != 0.f)
{
x /= length;
y /= length;
}
return length;
}
template<typename T>
T NzVector2<T>::SquaredDistance(const NzVector2& vec) const
{
return operator-(vec).SquaredLength();
}
template<typename T>
T NzVector2<T>::SquaredLength() const
{
return x * x + y * y;
}
template<typename T>
NzString NzVector2<T>::ToString() const
{
NzStringStream ss;
return ss << "Vector2(" << x << ", " << y << ')';
}
template<typename T>
NzVector2<T>::operator NzString() const
{
return ToString();
}
template<typename T>
T& NzVector2<T>::operator[](unsigned int i)
{
if (i >= 2)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 2)";
throw std::domain_error(ss.ToString());
}
return *(&x+i);
}
template<typename T>
T NzVector2<T>::operator[](unsigned int i) const
{
if (i >= 2)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 2)";
throw std::domain_error(ss.ToString());
}
return *(&x+i);
}
template<typename T>
const NzVector2<T>& NzVector2<T>::operator+() const
{
return *this;
}
template<typename T>
NzVector2<T> NzVector2<T>::operator-() const
{
return NzVector2(-x, -y);
}
template<typename T>
NzVector2<T> NzVector2<T>::operator+(const NzVector2& vec) const
{
return NzVector2(x + vec.x, y + vec.y);
}
template<typename T>
NzVector2<T> NzVector2<T>::operator-(const NzVector2& vec) const
{
return NzVector2(x - vec.x, y - vec.y);
}
template<typename T>
NzVector2<T> NzVector2<T>::operator*(const NzVector2& vec) const
{
return NzVector2(x * vec.x, y * vec.y);
}
template<typename T>
NzVector2<T> NzVector2<T>::operator*(T scale) const
{
return NzVector2(x * scale, y * scale);
}
template<typename T>
NzVector2<T> NzVector2<T>::operator/(const NzVector2& vec) const
{
if (vec.x == 0.f || vec.y == 0.f)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
throw std::domain_error(ss.ToString());
}
return NzVector2(x / vec.x, y / vec.y);
}
template<typename T>
NzVector2<T> NzVector2<T>::operator/(T scale) const
{
if (scale == 0.f)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
throw std::domain_error(ss.ToString());
}
return NzVector2(x / scale, y / scale);
}
template<typename T>
NzVector2<T>& NzVector2<T>::operator+=(const NzVector2& vec)
{
x += vec.x;
y += vec.y;
return *this;
}
template<typename T>
NzVector2<T>& NzVector2<T>::operator-=(const NzVector2& vec)
{
x -= vec.x;
y -= vec.y;
return *this;
}
template<typename T>
NzVector2<T>& NzVector2<T>::operator*=(const NzVector2& vec)
{
x *= vec.x;
y *= vec.y;
return *this;
}
template<typename T>
NzVector2<T>& NzVector2<T>::operator*=(T scale)
{
x *= scale;
y *= scale;
return *this;
}
template<typename T>
NzVector2<T>& NzVector2<T>::operator/=(const NzVector2& vec)
{
if (vec.x == 0.f || vec.y == 0.f)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
throw std::domain_error(ss.ToString());
}
x /= vec.x;
y /= vec.y;
return *this;
}
template<typename T>
NzVector2<T>& NzVector2<T>::operator/=(T scale)
{
if (scale == 0.f)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
throw std::domain_error(ss.ToString());
}
x /= scale;
y /= scale;
return *this;
}
template<typename T>
bool NzVector2<T>::operator==(const NzVector2& vec) const
{
return NzNumberEquals(x, vec.x) &&
NzNumberEquals(y, vec.y);
}
template<typename T>
bool NzVector2<T>::operator!=(const NzVector2& vec) const
{
return !operator==(vec);
}
template<typename T>
bool NzVector2<T>::operator<(const NzVector2& vec) const
{
return x < vec.x && y < vec.y;
}
template<typename T>
bool NzVector2<T>::operator<=(const NzVector2& vec) const
{
return operator<(vec) || operator==(vec);
}
template<typename T>
bool NzVector2<T>::operator>(const NzVector2& vec) const
{
return !operator<=(vec);
}
template<typename T>
bool NzVector2<T>::operator>=(const NzVector2& vec) const
{
return !operator<(vec);
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const NzVector2<T>& vec)
{
return out << vec.ToString();
}
template<typename T>
NzVector2<T> operator*(T scale, const NzVector2<T>& vec)
{
return NzVector2<T>(scale * vec.x, scale * vec.y);
}
template<typename T>
NzVector2<T> operator/(T scale, const NzVector2<T>& vec)
{
if (vec.x == 0.f || vec.y == 0.f)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
throw std::domain_error(ss.ToString());
}
return NzVector2<T>(scale/vec.x, scale/vec.y);
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -0,0 +1,82 @@
// Copyright (C) 2012 Rémi Begues
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_VECTOR3_HPP
#define NAZARA_VECTOR3_HPP
#include <Nazara/Core/String.hpp>
template<typename T> class NzVector3
{
public:
NzVector3();
NzVector3(T X, T Y, T Z);
explicit NzVector3(T scale);
NzVector3(T vec[3]);
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 DotProduct(const NzVector3& vec) const;
NzVector3 GetNormal() const;
void MakeCeil(const NzVector3& vec);
void MakeFloor(const NzVector3& vec);
double Length() const;
double Normalize();
T SquaredDistance(const NzVector3& vec) const;
T SquaredLength() const;
NzString ToString() const;
operator NzString() const;
T& operator[](unsigned int i);
T operator[](unsigned int i) const;
const NzVector3& operator+() const;
NzVector3 operator-() const;
NzVector3 operator+(const NzVector3& vec) const;
NzVector3 operator-(const NzVector3& vec) const;
NzVector3 operator*(const NzVector3& vec) const;
NzVector3 operator*(T scale) const;
NzVector3 operator/(const NzVector3& vec) const;
NzVector3 operator/(T scale) const;
NzVector3& operator+=(const NzVector3& vec);
NzVector3& operator-=(const NzVector3& vec);
NzVector3& operator*=(const NzVector3& vec);
NzVector3& operator*=(T scale);
NzVector3& operator/=(const NzVector3& vec);
NzVector3& operator/=(T scale);
bool operator==(const NzVector3& vec) const;
bool operator!=(const NzVector3& vec) const;
bool operator<(const NzVector3& vec) const;
bool operator<=(const NzVector3& vec) const;
bool operator>(const NzVector3& vec) const;
bool operator>=(const NzVector3& vec) const;
T x;
T y;
T z;
};
template<typename T> std::ostream& operator<<(std::ostream& out, const NzVector3<T>& vec);
template<typename T> NzVector3<T> operator*(T scale, const NzVector3<T>& vec);
template<typename T> NzVector3<T> operator/(T scale, const NzVector3<T>& vec);
typedef NzVector3<double> NzVector3d;
typedef NzVector3<float> NzVector3f;
typedef NzVector3<int> NzVector3i;
#include <Nazara/Math/Vector3.inl>
#endif // NAZARA_VECTOR3_HPP

View File

@@ -0,0 +1,393 @@
// Copyright (C) 2012 Rémi Begues
// 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 <Nazara/Math/Basic.hpp>
#include <cmath>
#include <cstdlib>
#include <stdexcept>
#include <Nazara/Core/Debug.hpp>
template<typename T>
NzVector3<T>::NzVector3()
{
}
template<typename T>
NzVector3<T>::NzVector3(T X, T Y, T Z) :
x(X),
y(Y),
z(Z)
{
}
template<typename T>
NzVector3<T>::NzVector3(T scale) :
x(scale),
y(scale),
z(scale)
{
}
template<typename T>
NzVector3<T>::NzVector3(T vec[3]) :
x(vec[0]),
y(vec[1]),
z(vec[2])
{
}
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))
{
}
template<typename T>
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
{
return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z);
}
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);
}
template<typename T>
double NzVector3<T>::Distance(const NzVector3& vec) const
{
return std::sqrt(SquaredDistance(vec));
}
template<typename T>
T NzVector3<T>::DotProduct(const NzVector3& vec) const
{
return x * vec.x + y * vec.y + z * vec.z;
}
template<typename T>
NzVector3<T> NzVector3<T>::GetNormal() const
{
NzVector3 vec(*this);
vec.Normalize();
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>
double NzVector3<T>::Length() const
{
return std::sqrt(SquaredLength());
}
template<typename T>
double NzVector3<T>::Normalize()
{
double length = Length();
if (length != 0.f)
{
x /= length;
y /= length;
z /= length;
}
return length;
}
template<typename T>
T NzVector3<T>::SquaredDistance(const NzVector3& vec) const
{
return operator-(vec).SquaredLength();
}
template<typename T>
T NzVector3<T>::SquaredLength() const
{
return x * x + y * y + z * z;
}
template<typename T>
NzString NzVector3<T>::ToString() const
{
NzStringStream ss;
return ss << "Vector3(" << x << ", " << y << ", " << z <<')';
}
template<typename T>
NzVector3<T>::operator NzString() const
{
return ToString();
}
template<typename T>
T& NzVector3<T>::operator[](unsigned int i)
{
if (i >= 3)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 3)";
throw std::domain_error(ss.ToString());
}
return *(&x+i);
}
template<typename T>
T NzVector3<T>::operator[](unsigned int i) const
{
if (i >= 3)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 3)";
throw std::domain_error(ss.ToString());
}
return *(&x+i);
}
template<typename T>
const NzVector3<T>& NzVector3<T>::operator+() const
{
return *this;
}
template<typename T>
NzVector3<T> NzVector3<T>::operator-() const
{
return NzVector3(-x, -y, -z);
}
template<typename T>
NzVector3<T> NzVector3<T>::operator+(const NzVector3& vec) const
{
return NzVector3(x + vec.x, y + vec.y, z + vec.z);
}
template<typename T>
NzVector3<T> NzVector3<T>::operator-(const NzVector3& vec) const
{
return NzVector3(x - vec.x, y - vec.y, z - vec.z);
}
template<typename T>
NzVector3<T> NzVector3<T>::operator*(const NzVector3& vec) const
{
return NzVector3(x * vec.x, y * vec.y, z * vec.z);
}
template<typename T>
NzVector3<T> NzVector3<T>::operator*(T scale) const
{
return NzVector3(x * scale, y * scale, z * scale);
}
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)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
throw std::domain_error(ss.ToString());
}
return NzVector3(x / vec.x, y / vec.y, z / vec.z);
}
template<typename T>
NzVector3<T> NzVector3<T>::operator/(T scale) const
{
if (scale == 0.f)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
throw std::domain_error(ss.ToString());
}
return NzVector3(x / scale, y / scale, z / scale);
}
template<typename T>
NzVector3<T>& NzVector3<T>::operator+=(const NzVector3& vec)
{
x += vec.x;
y += vec.y;
z += vec.z;
return *this;
}
template<typename T>
NzVector3<T>& NzVector3<T>::operator-=(const NzVector3& vec)
{
x -= vec.x;
y -= vec.y;
z -= vec.z;
return *this;
}
template<typename T>
NzVector3<T>& NzVector3<T>::operator*=(const NzVector3& vec)
{
x *= vec.x;
y *= vec.y;
z *= vec.z;
return *this;
}
template<typename T>
NzVector3<T>& NzVector3<T>::operator*=(T scale)
{
x *= scale;
y *= scale;
z *= scale;
return *this;
}
template<typename T>
NzVector3<T>& NzVector3<T>::operator/=(const NzVector3& vec)
{
if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
throw std::domain_error(ss.ToString());
}
x /= vec.x;
y /= vec.y;
z /= vec.z;
return *this;
}
template<typename T>
NzVector3<T>& NzVector3<T>::operator/=(T scale)
{
if (scale == 0.f)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
throw std::domain_error(ss.ToString());
}
x /= scale;
y /= scale;
z /= scale;
return *this;
}
template<typename T>
bool NzVector3<T>::operator==(const NzVector3& vec) const
{
return NzNumberEquals(x, vec.x) &&
NzNumberEquals(y, vec.y) &&
NzNumberEquals(z, vec.z);
}
template<typename T>
bool NzVector3<T>::operator!=(const NzVector3& vec) const
{
return !operator==(vec);
}
template<typename T>
bool NzVector3<T>::operator<(const NzVector3& vec) const
{
return x < vec.x && y < vec.y && z < vec.z;
}
template<typename T>
bool NzVector3<T>::operator<=(const NzVector3& vec) const
{
return operator<(vec) || operator==(vec);
}
template<typename T>
bool NzVector3<T>::operator>(const NzVector3& vec) const
{
return !operator<=(vec);
}
template<typename T>
bool NzVector3<T>::operator>=(const NzVector3& vec) const
{
return !operator<(vec);
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const NzVector3<T>& vec)
{
return out << vec.ToString();
}
template<typename T>
NzVector3<T> operator*(T scale, const NzVector3<T>& vec)
{
return NzVector3<T>(scale * vec.x, scale * vec.y, scale * vec.z);
}
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)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
throw std::domain_error(ss.ToString());
}
return NzVector3<T>(scale / vec.x, scale / vec.y, scale / vec.z);
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -0,0 +1,77 @@
// Copyright (C) 2012 Rémi Begues
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_VECTOR4_HPP
#define NAZARA_VECTOR4_HPP
#include <Nazara/Core/String.hpp>
template<typename T> class NzVector4
{
public:
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 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 Normalize();
NzString ToString() const;
operator NzString() const;
T& operator[](unsigned int i);
T operator[](unsigned int i) const;
const NzVector4& operator+() const;
NzVector4 operator-() const;
NzVector4 operator+(const NzVector4& vec) const;
NzVector4 operator-(const NzVector4& vec) const;
NzVector4 operator*(const NzVector4& vec) const;
NzVector4 operator*(T scale) const;
NzVector4 operator/(const NzVector4& vec) const;
NzVector4 operator/(T scale) const;
NzVector4& operator+=(const NzVector4& vec);
NzVector4& operator-=(const NzVector4& vec);
NzVector4& operator*=(const NzVector4& vec);
NzVector4& operator*=(T scale);
NzVector4& operator/=(const NzVector4& vec);
NzVector4& operator/=(T scale);
bool operator==(const NzVector4& vec) const;
bool operator!=(const NzVector4& vec) const;
bool operator<(const NzVector4& vec) const;
bool operator<=(const NzVector4& vec) const;
bool operator>(const NzVector4& vec) const;
bool operator>=(const NzVector4& vec) const;
T x;
T y;
T z;
T w;
};
template<typename T> std::ostream& operator<<(std::ostream& out, const NzVector4<T>& vec);
template<typename T> NzVector4<T> operator*(T scale, const NzVector4<T>& vec);
template<typename T> NzVector4<T> operator/(T scale, const NzVector4<T>& vec);
typedef NzVector4<double> NzVector4d;
typedef NzVector4<float> NzVector4f;
typedef NzVector4<int> NzVector4i;
#include <Nazara/Math/Vector4.inl>
#endif // NAZARA_VECTOR4_HPP

View File

@@ -0,0 +1,367 @@
// 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 <Nazara/Math/Basic.hpp>
#include <cmath>
#include <cstdlib>
#include <stdexcept>
#include <Nazara/Core/Debug.hpp>
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)
{
}
template<typename T>
NzVector4<T>::NzVector4(T scale) :
x(scale),
y(scale),
z(scale),
w(scale)
{
}
template<typename T>
NzVector4<T>::NzVector4(T vec[4]) :
x(vec[0]),
y(vec[1]),
z(vec[2]),
w(vec[3])
{
}
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>
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
{
return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z) + std::labs(w * vec.w);
}
template<typename T>
T NzVector4<T>::DotProduct(const NzVector4& vec) const
{
return x * vec.x + y * vec.y + z * vec.z + w * vec.w;
}
template<typename T>
void NzVector4<T>::MakeCeil(const NzVector4& vec)
{
if (vec.x > x)
x = vec.x;
if (vec.y > y)
y = vec.y;
if (vec.z > z)
z = vec.z;
if (vec.w > w)
w = vec.w;
}
template<typename T>
void NzVector4<T>::MakeFloor(const NzVector4& vec)
{
if (vec.x < x)
x = vec.x;
if (vec.y < y)
y = vec.y;
if (vec.z < z)
z = vec.z;
if (vec.w < w)
w = vec.w;
}
template<typename T>
void NzVector4<T>::Normalize()
{
if (w != 0.f)
{
x /= w;
y /= w;
z /= w;
}
}
template<typename T>
NzString NzVector4<T>::ToString() const
{
NzStringStream ss;
return ss << "Vector4(" << x << ", " << y << ", " << z <<')';
}
template<typename T>
NzVector4<T>::operator NzString() const
{
return ToString();
}
template<typename T>
T& NzVector4<T>::operator[](unsigned int i)
{
if (i >= 4)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 4)";
throw std::domain_error(ss.ToString());
}
return *(&x+i);
}
template<typename T>
T NzVector4<T>::operator[](unsigned int i) const
{
if (i >= 4)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 4)";
throw std::domain_error(ss.ToString());
}
return *(&x+i);
}
template<typename T>
const NzVector4<T>& NzVector4<T>::operator+() const
{
return *this;
}
template<typename T>
NzVector4<T> NzVector4<T>::operator-() const
{
return NzVector4(-x, -y, -z, -w);
}
template<typename T>
NzVector4<T> NzVector4<T>::operator+(const NzVector4& vec) const
{
return NzVector4(x + vec.x, y + vec.y, z + vec.z, w + vec.w);
}
template<typename T>
NzVector4<T> NzVector4<T>::operator-(const NzVector4& vec) const
{
return NzVector4(x - vec.x, y - vec.y, z - vec.z);
}
template<typename T>
NzVector4<T> NzVector4<T>::operator*(const NzVector4& vec) const
{
return NzVector4(x * vec.x, y * vec.y, z * vec.z, w * vec.w);
}
template<typename T>
NzVector4<T> NzVector4<T>::operator*(T scale) const
{
return NzVector4(x * scale, y * scale, z * scale, w * scale);
}
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)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
throw std::domain_error(ss.ToString());
}
return NzVector4(x / vec.x, y / vec.y, z / vec.z, w / vec.w);
}
template<typename T>
NzVector4<T> NzVector4<T>::operator/(T scale) const
{
if (scale == 0.f)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
throw std::domain_error(ss.ToString());
}
return NzVector4(x / scale, y / scale, z / scale, w / scale);
}
template<typename T>
NzVector4<T>& NzVector4<T>::operator+=(const NzVector4& vec)
{
x += vec.x;
y += vec.y;
z += vec.z;
w += vec.w;
return *this;
}
template<typename T>
NzVector4<T>& NzVector4<T>::operator-=(const NzVector4& vec)
{
x -= vec.x;
y -= vec.y;
z -= vec.z;
w -= vec.w;
return *this;
}
template<typename T>
NzVector4<T>& NzVector4<T>::operator*=(const NzVector4& vec)
{
x *= vec.x;
y *= vec.y;
z *= vec.z;
w *= vec.w;
return *this;
}
template<typename T>
NzVector4<T>& NzVector4<T>::operator*=(T scale)
{
x *= scale;
y *= scale;
z *= scale;
w *= scale;
return *this;
}
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)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
throw std::domain_error(ss.ToString());
}
x /= vec.x;
y /= vec.y;
z /= vec.z;
w /= vec.w;
return *this;
}
template<typename T>
NzVector4<T>& NzVector4<T>::operator/=(T scale)
{
if (scale == 0.f)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
throw std::domain_error(ss.ToString());
}
x /= scale;
y /= scale;
z /= scale;
w /= scale;
return *this;
}
template<typename T>
bool NzVector4<T>::operator==(const NzVector4& vec) const
{
return NzNumberEquals(x, vec.x) &&
NzNumberEquals(y, vec.y) &&
NzNumberEquals(z, vec.z) &&
NzNumberEquals(w, vec.w);
}
template<typename T>
bool NzVector4<T>::operator!=(const NzVector4& vec) const
{
return !operator==(vec);
}
template<typename T>
bool NzVector4<T>::operator<(const NzVector4& vec) const
{
return x < vec.x && y < vec.y && z < vec.z && w < vec.w;
}
template<typename T>
bool NzVector4<T>::operator<=(const NzVector4& vec) const
{
return operator<(vec) || operator==(vec);
}
template<typename T>
bool NzVector4<T>::operator>(const NzVector4& vec) const
{
return !operator<=(vec);
}
template<typename T>
bool NzVector4<T>::operator>=(const NzVector4& vec) const
{
return !operator<(vec);
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const NzVector4<T>& vec)
{
return out << vec.ToString();
}
template<typename T>
NzVector4<T> operator*(T scale, const NzVector4<T>& vec)
{
return NzVector4<T>(scale * vec.x, scale * vec.y, scale * vec.z, scale * vec.w);
}
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)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
throw std::domain_error(ss.ToString());
}
return NzVector3<T>(scale / vec.x, scale / vec.y, scale / vec.z, scale / vec.w);
}
#include <Nazara/Core/DebugOff.hpp>