Merge remote-tracking branch 'upstream/master'

Former-commit-id: 8fe411f0146d6cc64cf8d32cc4896f7f417f62a5
This commit is contained in:
Remi Beges
2012-11-04 18:51:23 +01:00
47 changed files with 1028 additions and 265 deletions

View File

@@ -31,6 +31,7 @@ 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, typename T2> T NzLerp(T from, T to, T2 interpolation);
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);

View File

@@ -11,6 +11,7 @@
#include <Nazara/Core/Debug.hpp>
#define F(a) static_cast<T>(a)
#define F2(a) static_cast<T2>(a)
template<typename T>
T NzApproach(T value, T objective, T increment)
@@ -132,11 +133,25 @@ unsigned int NzGetNumberLength(long double number, nzUInt8 precision)
return NzGetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus un pour le point
}
template<typename T, typename T2>
T NzLerp(T from, T to, T2 interpolation)
{
#ifdef NAZARA_DEBUG
if (interpolation < F2(0.0) || interpolation > F2(1.0))
{
NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')');
return F(0.0);
}
#endif
return from + interpolation*(to - from);
}
template<typename T>
T NzNormalizeAngle(T angle)
{
#if NAZARA_MATH_ANGLE_RADIAN
const T limit = M_PI;
const T limit = F(M_PI);
#else
const T limit = F(180.0);
#endif
@@ -145,13 +160,13 @@ T NzNormalizeAngle(T angle)
if (angle > F(0.0))
{
angle += limit;
angle -= static_cast<int>(angle/(F(2.0)*limit))*(F(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/(F(2.0)*limit))*(F(2.0)*limit);
angle -= static_cast<int>(angle / (F(2.0)*limit)) * (F(2.0)*limit);
angle += limit;
}
@@ -270,6 +285,7 @@ long long NzStringToNumber(NzString str, nzUInt8 radix, bool* ok)
return (negative) ? -static_cast<long long>(total) : total;
}
#undef F2
#undef F
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -20,28 +20,30 @@ class NzCube
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;
template<typename U> explicit NzCube(const NzCube<U>& cube);
NzCube(const NzCube& cube) = default;
~NzCube() = default;
bool Contains(T X, T Y, T Z) const;
bool Contains(const NzVector3<T>& point) const;
bool Contains(const NzCube& rect) const;
bool Contains(const NzCube& cube) const;
void ExtendTo(const NzVector3<T>& point);
void ExtendTo(const NzCube& rect);
void ExtendTo(const NzCube& cube);
NzVector3<T> GetCenter() const;
bool Intersect(const NzCube& rect, NzCube* intersection = nullptr) const;
bool Intersect(const NzCube& cube, NzCube* intersection = nullptr) const;
bool IsValid() const;
void MakeZero();
void Set(T X, T Y, T Z, T Width, T Height, T Depth);
void Set(const T rect[6]);
void Set(const T cube[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);
template<typename U> void Set(const NzCube<U>& cube);
NzString ToString() const;
@@ -50,6 +52,16 @@ class NzCube
T& operator[](unsigned int i);
T operator[](unsigned int i) const;
NzCube operator*(T scalar) const;
NzCube& operator*=(T scalar);
bool operator==(const NzCube& cube) const;
bool operator!=(const NzCube& cube) const;
static NzCube Lerp(const NzCube& from, const NzCube& to, T interpolation);
static NzCube Zero();
T x, y, z, width, height, depth;
};

View File

@@ -39,9 +39,9 @@ NzCube<T>::NzCube(const NzVector3<T>& vec1, const NzVector3<T>& vec2)
template<typename T>
template<typename U>
NzCube<T>::NzCube(const NzCube<U>& rect)
NzCube<T>::NzCube(const NzCube<U>& cube)
{
Set(rect);
Set(cube);
}
template<typename T>
@@ -59,10 +59,10 @@ bool NzCube<T>::Contains(const NzVector3<T>& point) const
}
template<typename T>
bool NzCube<T>::Contains(const NzCube<T>& rect) const
bool NzCube<T>::Contains(const NzCube<T>& cube) const
{
return Contains(rect.x, rect.y, rect.z) &&
Contains(rect.x + rect.width, rect.y + rect.height, rect.z + rect.depth);
return Contains(cube.x, cube.y, cube.z) &&
Contains(cube.x + cube.width, cube.y + cube.height, cube.z + cube.depth);
}
template<typename T>
@@ -77,14 +77,14 @@ void NzCube<T>::ExtendTo(const NzVector3<T>& point)
}
template<typename T>
void NzCube<T>::ExtendTo(const NzCube& rect)
void NzCube<T>::ExtendTo(const NzCube& cube)
{
x = std::min(x, rect.x);
y = std::min(y, rect.y);
z = std::min(y, rect.z);
width = std::max(x+width, rect.x+rect.width)-x;
height = std::max(x+height, rect.y+rect.height)-y;
depth = std::max(x+depth, rect.z+rect.depth)-z;
x = std::min(x, cube.x);
y = std::min(y, cube.y);
z = std::min(y, cube.z);
width = std::max(x+width, cube.x+cube.width)-x;
height = std::max(x+height, cube.y+cube.height)-y;
depth = std::max(x+depth, cube.z+cube.depth)-z;
}
template<typename T>
@@ -94,14 +94,14 @@ NzVector3<T> NzCube<T>::GetCenter() const
}
template<typename T>
bool NzCube<T>::Intersect(const NzCube& rect, NzCube* intersection) const
bool NzCube<T>::Intersect(const NzCube& cube, NzCube* intersection) const
{
T left = std::max(x, rect.x);
T right = std::min(x+width, rect.x+rect.width);
T top = std::max(y, rect.y);
T bottom = std::min(y+height, rect.y+rect.height);
T up = std::max(z, rect.z);
T down = std::min(z+depth, rect.z+rect.depth);
T left = std::max(x, cube.x);
T right = std::min(x+width, cube.x+cube.width);
T top = std::max(y, cube.y);
T bottom = std::min(y+height, cube.y+cube.height);
T up = std::max(z, cube.z);
T down = std::min(z+depth, cube.z+cube.depth);
if (left < right && top < bottom && up < down)
{
@@ -127,6 +127,17 @@ bool NzCube<T>::IsValid() const
return width > F(0.0) && height > F(0.0) && depth > F(0.0);
}
template<typename T>
void NzCube<T>::MakeZero()
{
x = F(0.0);
y = F(0.0);
z = F(0.0);
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)
{
@@ -139,14 +150,14 @@ void NzCube<T>::Set(T X, T Y, T Z, T Width, T Height, T Depth)
}
template<typename T>
void NzCube<T>::Set(const T rect[6])
void NzCube<T>::Set(const T cube[6])
{
x = rect[0];
y = rect[1];
z = rect[2];
width = rect[3];
height = rect[4];
depth = rect[5];
x = cube[0];
y = cube[1];
z = cube[2];
width = cube[3];
height = cube[4];
depth = cube[5];
}
template<typename T>
@@ -230,9 +241,67 @@ T NzCube<T>::operator[](unsigned int i) const
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const NzCube<T>& rect)
NzCube<T> NzCube<T>::operator*(T scalar) const
{
return out << rect.ToString();
return NzCube(x, y, z, width*scalar, height*scalar, depth*scalar);
}
template<typename T>
NzCube<T>& NzCube<T>::operator*=(T scalar)
{
width *= scalar;
height *= scalar;
depth *= scalar;
}
template<typename T>
bool NzCube<T>::operator==(const NzCube& cube) const
{
return NzNumberEquals(x, cube.x) && NzNumberEquals(y, cube.y) && NzNumberEquals(z, cube.z) &&
NzNumberEquals(width, cube.width) && NzNumberEquals(height, cube.height) && NzNumberEquals(depth, cube.depth);
}
template<typename T>
bool NzCube<T>::operator!=(const NzCube& cube) const
{
return !operator==(cube);
}
template<typename T>
NzCube<T> NzCube<T>::Lerp(const NzCube& from, const NzCube& to, T interpolation)
{
#ifdef NAZARA_DEBUG
if (interpolation < F(0.0) || interpolation > F(1.0))
{
NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')');
return Zero();
}
#endif
NzCube cube;
cube.x = NzLerp(from.x, to.x, interpolation);
cube.y = NzLerp(from.y, to.y, interpolation);
cube.z = NzLerp(from.z, to.z, interpolation);
cube.width = NzLerp(from.width, to.width, interpolation);
cube.height = NzLerp(from.height, to.height, interpolation);
cube.depth = NzLerp(from.depth, to.depth, interpolation);
return cube;
}
template<typename T>
NzCube<T> NzCube<T>::Zero()
{
NzCube cube;
cube.MakeZero();
return cube;
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const NzCube<T>& cube)
{
return out << cube.ToString();
}
#undef F

View File

@@ -38,11 +38,14 @@ class NzMatrix4
NzMatrix4(NzMatrix4&& matrix) noexcept;
~NzMatrix4();
NzMatrix4& ApplyScale(const NzVector3<T>& scale);
NzMatrix4 Concatenate(const NzMatrix4& matrix) const;
NzMatrix4 ConcatenateAffine(const NzMatrix4& matrix) const;
T GetDeterminant() const;
NzMatrix4 GetInverse() const;
NzMatrix4 GetInverse(bool* succeeded = nullptr) const;
NzMatrix4 GetInverseAffine(bool* succeeded = nullptr) const;
NzQuaternion<T> GetRotation() const;
//NzMatrix3 GetRotationMatrix() const;
NzVector3<T> GetScale() const;
@@ -52,30 +55,34 @@ class NzMatrix4
bool HasNegativeScale() const;
bool HasScale() const;
NzMatrix4& Inverse(bool* succeeded = nullptr);
NzMatrix4& InverseAffine(bool* succeeded = nullptr);
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();
NzMatrix4& MakeIdentity();
NzMatrix4& MakeLookAt(const NzVector3<T>& eye, const NzVector3<T>& target, const NzVector3<T>& up = NzVector3<T>::Up());
NzMatrix4& MakeOrtho(T left, T top, T width, T height, T zNear = -1.0, T zFar = 1.0);
NzMatrix4& MakePerspective(T angle, T ratio, T zNear, T zFar);
NzMatrix4& MakeRotation(const NzQuaternion<T>& rotation);
NzMatrix4& MakeScale(const NzVector3<T>& scale);
NzMatrix4& MakeTranslation(const NzVector3<T>& translation);
NzMatrix4& MakeTransform(const NzVector3<T>& translation, const NzVector3<T>& scale, const NzQuaternion<T>& rotation);
NzMatrix4& MakeZero();
void Set(T r11, T r12, T r13, T r14,
NzMatrix4& 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(const T matrix[16]);
NzMatrix4& 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 SetRotation(const NzQuaternion<T>& rotation);
void SetScale(const NzVector3<T>& scale);
void SetTranslation(const NzVector3<T>& translation);
NzMatrix4& Set(const NzMatrix4& matrix);
NzMatrix4& Set(NzMatrix4&& matrix);
template<typename U> NzMatrix4& Set(const NzMatrix4<U>& matrix);
NzMatrix4& SetRotation(const NzQuaternion<T>& rotation);
NzMatrix4& SetScale(const NzVector3<T>& scale);
NzMatrix4& SetTranslation(const NzVector3<T>& translation);
NzString ToString() const;
@@ -85,6 +92,8 @@ class NzMatrix4
NzMatrix4& Transpose();
NzMatrix4& Undefine();
operator NzString() const;
operator T*();
@@ -117,6 +126,7 @@ class NzMatrix4
static NzMatrix4 Rotate(const NzQuaternion<T>& rotation);
static NzMatrix4 Scale(const NzVector3<T>& scale);
static NzMatrix4 Translate(const NzVector3<T>& translation);
static NzMatrix4 Transform(const NzVector3<T>& translation, const NzVector3<T>& scale, const NzQuaternion<T>& rotation);
static NzMatrix4 Zero();
struct SharedMatrix

View File

@@ -16,7 +16,7 @@
#include <limits>
#include <stdexcept>
//#include <Nazara/Core/Debug.hpp>
///FIXME: Le MLT détecte de faux-leaks ici (Problème lié aux inline ?)
///FIXME: Le MLT détecte des leaks ici, mais dont la véracité n'a pu être prouvée (Problème lié aux classes inlines ?)
#define F(a) static_cast<T>(a)
@@ -68,6 +68,24 @@ NzMatrix4<T>::~NzMatrix4()
ReleaseMatrix();
}
template<typename T>
NzMatrix4<T>& NzMatrix4<T>::ApplyScale(const NzVector3<T>& scale)
{
m_sharedMatrix->m11 *= scale.x;
m_sharedMatrix->m12 *= scale.x;
m_sharedMatrix->m13 *= scale.x;
m_sharedMatrix->m21 *= scale.y;
m_sharedMatrix->m22 *= scale.y;
m_sharedMatrix->m23 *= scale.y;
m_sharedMatrix->m31 *= scale.z;
m_sharedMatrix->m32 *= scale.z;
m_sharedMatrix->m33 *= scale.z;
return *this;
}
template<typename T>
NzMatrix4<T> NzMatrix4<T>::Concatenate(const NzMatrix4& matrix) const
{
@@ -100,45 +118,17 @@ T NzMatrix4<T>::GetDeterminant() const
}
template<typename T>
NzMatrix4<T> NzMatrix4<T>::GetInverse() const
NzMatrix4<T> NzMatrix4<T>::GetInverse(bool* succeeded) const
{
#if NAZARA_MATH_SAFE
if (!IsDefined())
{
NazaraError("Matrix not defined");
return NzMatrix4();
}
#endif
NzMatrix4f matInv(*this);
return matInv.Inverse(succeeded);
}
T det = GetDeterminant();
if (!NzNumberEquals(det, F(0.0)))
{
return NzMatrix4((m_sharedMatrix->m22*(m_sharedMatrix->m33*m_sharedMatrix->m44 - m_sharedMatrix->m34*m_sharedMatrix->m43) - m_sharedMatrix->m32*(m_sharedMatrix->m23*m_sharedMatrix->m44 - m_sharedMatrix->m43*m_sharedMatrix->m24) + m_sharedMatrix->m42*(m_sharedMatrix->m23*m_sharedMatrix->m34 - m_sharedMatrix->m33*m_sharedMatrix->m24)) / det,
-(m_sharedMatrix->m12*(m_sharedMatrix->m33*m_sharedMatrix->m44 - m_sharedMatrix->m43*m_sharedMatrix->m34) - m_sharedMatrix->m32*(m_sharedMatrix->m13*m_sharedMatrix->m44 - m_sharedMatrix->m43*m_sharedMatrix->m14) + m_sharedMatrix->m42*(m_sharedMatrix->m13*m_sharedMatrix->m34 - m_sharedMatrix->m33*m_sharedMatrix->m14)) / det,
(m_sharedMatrix->m12*(m_sharedMatrix->m23*m_sharedMatrix->m44 - m_sharedMatrix->m43*m_sharedMatrix->m24) - m_sharedMatrix->m22*(m_sharedMatrix->m13*m_sharedMatrix->m44 - m_sharedMatrix->m43*m_sharedMatrix->m14) + m_sharedMatrix->m42*(m_sharedMatrix->m13*m_sharedMatrix->m24 - m_sharedMatrix->m23*m_sharedMatrix->m14)) / det,
-(m_sharedMatrix->m12*(m_sharedMatrix->m23*m_sharedMatrix->m34 - m_sharedMatrix->m33*m_sharedMatrix->m24) - m_sharedMatrix->m22*(m_sharedMatrix->m13*m_sharedMatrix->m34 - m_sharedMatrix->m33*m_sharedMatrix->m14) + m_sharedMatrix->m32*(m_sharedMatrix->m13*m_sharedMatrix->m24 - m_sharedMatrix->m23*m_sharedMatrix->m14)) / det,
-(m_sharedMatrix->m21*(m_sharedMatrix->m33*m_sharedMatrix->m44 - m_sharedMatrix->m34*m_sharedMatrix->m43) - m_sharedMatrix->m23*(m_sharedMatrix->m31*m_sharedMatrix->m44 - m_sharedMatrix->m34*m_sharedMatrix->m41) + m_sharedMatrix->m24*(m_sharedMatrix->m31*m_sharedMatrix->m43 - m_sharedMatrix->m33*m_sharedMatrix->m41)) / det,
(m_sharedMatrix->m11*(m_sharedMatrix->m33*m_sharedMatrix->m44 - m_sharedMatrix->m34*m_sharedMatrix->m43) - m_sharedMatrix->m13*(m_sharedMatrix->m31*m_sharedMatrix->m44 - m_sharedMatrix->m34*m_sharedMatrix->m41) + m_sharedMatrix->m14*(m_sharedMatrix->m31*m_sharedMatrix->m43 - m_sharedMatrix->m33*m_sharedMatrix->m41)) / det,
-(m_sharedMatrix->m11*(m_sharedMatrix->m23*m_sharedMatrix->m44 - m_sharedMatrix->m24*m_sharedMatrix->m43) - m_sharedMatrix->m13*(m_sharedMatrix->m21*m_sharedMatrix->m44 - m_sharedMatrix->m24*m_sharedMatrix->m41) + m_sharedMatrix->m14*(m_sharedMatrix->m21*m_sharedMatrix->m43 - m_sharedMatrix->m23*m_sharedMatrix->m41)) / det,
(m_sharedMatrix->m11*(m_sharedMatrix->m23*m_sharedMatrix->m34 - m_sharedMatrix->m24*m_sharedMatrix->m33) - m_sharedMatrix->m13*(m_sharedMatrix->m21*m_sharedMatrix->m34 - m_sharedMatrix->m24*m_sharedMatrix->m31) + m_sharedMatrix->m14*(m_sharedMatrix->m21*m_sharedMatrix->m33 - m_sharedMatrix->m23*m_sharedMatrix->m31)) / det,
(m_sharedMatrix->m21*(m_sharedMatrix->m32*m_sharedMatrix->m44 - m_sharedMatrix->m34*m_sharedMatrix->m42) - m_sharedMatrix->m22*(m_sharedMatrix->m31*m_sharedMatrix->m44 - m_sharedMatrix->m34*m_sharedMatrix->m41) + m_sharedMatrix->m24*(m_sharedMatrix->m31*m_sharedMatrix->m42 - m_sharedMatrix->m32*m_sharedMatrix->m41)) / det,
-(m_sharedMatrix->m11*(m_sharedMatrix->m32*m_sharedMatrix->m44 - m_sharedMatrix->m34*m_sharedMatrix->m42) - m_sharedMatrix->m12*(m_sharedMatrix->m31*m_sharedMatrix->m44 - m_sharedMatrix->m34*m_sharedMatrix->m41) + m_sharedMatrix->m14*(m_sharedMatrix->m31*m_sharedMatrix->m42 - m_sharedMatrix->m32*m_sharedMatrix->m41)) / det,
(m_sharedMatrix->m11*(m_sharedMatrix->m22*m_sharedMatrix->m44 - m_sharedMatrix->m24*m_sharedMatrix->m42) - m_sharedMatrix->m12*(m_sharedMatrix->m21*m_sharedMatrix->m44 - m_sharedMatrix->m24*m_sharedMatrix->m41) + m_sharedMatrix->m14*(m_sharedMatrix->m21*m_sharedMatrix->m42 - m_sharedMatrix->m22*m_sharedMatrix->m41)) / det,
-(m_sharedMatrix->m11*(m_sharedMatrix->m22*m_sharedMatrix->m34 - m_sharedMatrix->m24*m_sharedMatrix->m32) - m_sharedMatrix->m12*(m_sharedMatrix->m21*m_sharedMatrix->m34 - m_sharedMatrix->m24*m_sharedMatrix->m31) + m_sharedMatrix->m14*(m_sharedMatrix->m21*m_sharedMatrix->m32 - m_sharedMatrix->m22*m_sharedMatrix->m31)) / det,
-(m_sharedMatrix->m21*(m_sharedMatrix->m32*m_sharedMatrix->m43 - m_sharedMatrix->m33*m_sharedMatrix->m42) - m_sharedMatrix->m22*(m_sharedMatrix->m31*m_sharedMatrix->m43 - m_sharedMatrix->m33*m_sharedMatrix->m41) + m_sharedMatrix->m23*(m_sharedMatrix->m31*m_sharedMatrix->m42 - m_sharedMatrix->m32*m_sharedMatrix->m41)) / det,
(m_sharedMatrix->m11*(m_sharedMatrix->m32*m_sharedMatrix->m43 - m_sharedMatrix->m33*m_sharedMatrix->m42) - m_sharedMatrix->m12*(m_sharedMatrix->m31*m_sharedMatrix->m43 - m_sharedMatrix->m33*m_sharedMatrix->m41) + m_sharedMatrix->m13*(m_sharedMatrix->m31*m_sharedMatrix->m42 - m_sharedMatrix->m32*m_sharedMatrix->m41)) / det,
-(m_sharedMatrix->m11*(m_sharedMatrix->m22*m_sharedMatrix->m43 - m_sharedMatrix->m23*m_sharedMatrix->m42) - m_sharedMatrix->m12*(m_sharedMatrix->m21*m_sharedMatrix->m43 - m_sharedMatrix->m23*m_sharedMatrix->m41) + m_sharedMatrix->m13*(m_sharedMatrix->m21*m_sharedMatrix->m42 - m_sharedMatrix->m22*m_sharedMatrix->m41)) / det,
(m_sharedMatrix->m11*(m_sharedMatrix->m22*m_sharedMatrix->m33 - m_sharedMatrix->m23*m_sharedMatrix->m32) - m_sharedMatrix->m12*(m_sharedMatrix->m21*m_sharedMatrix->m33 - m_sharedMatrix->m23*m_sharedMatrix->m31) + m_sharedMatrix->m13*(m_sharedMatrix->m21*m_sharedMatrix->m32 - m_sharedMatrix->m22*m_sharedMatrix->m31)) / det);
}
else
{
NazaraError("Matrix has no inverse");
return Identity();
}
template<typename T>
NzMatrix4<T> NzMatrix4<T>::GetInverseAffine(bool* succeeded) const
{
NzMatrix4f matInv(*this);
return matInv.InverseAffine(succeeded);
}
template<typename T>
@@ -220,6 +210,259 @@ bool NzMatrix4<T>::HasScale() const
return false;
}
template<typename T>
NzMatrix4<T>& NzMatrix4<T>::Inverse(bool* succeeded)
{
#if NAZARA_MATH_SAFE
if (!IsDefined())
{
NazaraError("Matrix not defined");
if (succeeded)
*succeeded = false;
return *this;
}
#endif
T det = GetDeterminant();
if (!NzNumberEquals(det, F(0.0)))
{
// http://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix
T inv[16];
inv[0] = m_sharedMatrix->m22 * m_sharedMatrix->m33 * m_sharedMatrix->m44 -
m_sharedMatrix->m22 * m_sharedMatrix->m34 * m_sharedMatrix->m43 -
m_sharedMatrix->m32 * m_sharedMatrix->m23 * m_sharedMatrix->m44 +
m_sharedMatrix->m32 * m_sharedMatrix->m24 * m_sharedMatrix->m43 +
m_sharedMatrix->m42 * m_sharedMatrix->m23 * m_sharedMatrix->m34 -
m_sharedMatrix->m42 * m_sharedMatrix->m24 * m_sharedMatrix->m33;
inv[1] = -m_sharedMatrix->m12 * m_sharedMatrix->m33 * m_sharedMatrix->m44 +
m_sharedMatrix->m12 * m_sharedMatrix->m34 * m_sharedMatrix->m43 +
m_sharedMatrix->m32 * m_sharedMatrix->m13 * m_sharedMatrix->m44 -
m_sharedMatrix->m32 * m_sharedMatrix->m14 * m_sharedMatrix->m43 -
m_sharedMatrix->m42 * m_sharedMatrix->m13 * m_sharedMatrix->m34 +
m_sharedMatrix->m42 * m_sharedMatrix->m14 * m_sharedMatrix->m33;
inv[2] = m_sharedMatrix->m12 * m_sharedMatrix->m23 * m_sharedMatrix->m44 -
m_sharedMatrix->m12 * m_sharedMatrix->m24 * m_sharedMatrix->m43 -
m_sharedMatrix->m22 * m_sharedMatrix->m13 * m_sharedMatrix->m44 +
m_sharedMatrix->m22 * m_sharedMatrix->m14 * m_sharedMatrix->m43 +
m_sharedMatrix->m42 * m_sharedMatrix->m13 * m_sharedMatrix->m24 -
m_sharedMatrix->m42 * m_sharedMatrix->m14 * m_sharedMatrix->m23;
inv[3] = -m_sharedMatrix->m12 * m_sharedMatrix->m23 * m_sharedMatrix->m34 +
m_sharedMatrix->m12 * m_sharedMatrix->m24 * m_sharedMatrix->m33 +
m_sharedMatrix->m22 * m_sharedMatrix->m13 * m_sharedMatrix->m34 -
m_sharedMatrix->m22 * m_sharedMatrix->m14 * m_sharedMatrix->m33 -
m_sharedMatrix->m32 * m_sharedMatrix->m13 * m_sharedMatrix->m24 +
m_sharedMatrix->m32 * m_sharedMatrix->m14 * m_sharedMatrix->m23;
inv[4] = -m_sharedMatrix->m21 * m_sharedMatrix->m33 * m_sharedMatrix->m44 +
m_sharedMatrix->m21 * m_sharedMatrix->m34 * m_sharedMatrix->m43 +
m_sharedMatrix->m31 * m_sharedMatrix->m23 * m_sharedMatrix->m44 -
m_sharedMatrix->m31 * m_sharedMatrix->m24 * m_sharedMatrix->m43 -
m_sharedMatrix->m41 * m_sharedMatrix->m23 * m_sharedMatrix->m34 +
m_sharedMatrix->m41 * m_sharedMatrix->m24 * m_sharedMatrix->m33;
inv[5] = m_sharedMatrix->m11 * m_sharedMatrix->m33 * m_sharedMatrix->m44 -
m_sharedMatrix->m11 * m_sharedMatrix->m34 * m_sharedMatrix->m43 -
m_sharedMatrix->m31 * m_sharedMatrix->m13 * m_sharedMatrix->m44 +
m_sharedMatrix->m31 * m_sharedMatrix->m14 * m_sharedMatrix->m43 +
m_sharedMatrix->m41 * m_sharedMatrix->m13 * m_sharedMatrix->m34 -
m_sharedMatrix->m41 * m_sharedMatrix->m14 * m_sharedMatrix->m33;
inv[6] = -m_sharedMatrix->m11 * m_sharedMatrix->m23 * m_sharedMatrix->m44 +
m_sharedMatrix->m11 * m_sharedMatrix->m24 * m_sharedMatrix->m43 +
m_sharedMatrix->m21 * m_sharedMatrix->m13 * m_sharedMatrix->m44 -
m_sharedMatrix->m21 * m_sharedMatrix->m14 * m_sharedMatrix->m43 -
m_sharedMatrix->m41 * m_sharedMatrix->m13 * m_sharedMatrix->m24 +
m_sharedMatrix->m41 * m_sharedMatrix->m14 * m_sharedMatrix->m23;
inv[7] = m_sharedMatrix->m11 * m_sharedMatrix->m23 * m_sharedMatrix->m34 -
m_sharedMatrix->m11 * m_sharedMatrix->m24 * m_sharedMatrix->m33 -
m_sharedMatrix->m21 * m_sharedMatrix->m13 * m_sharedMatrix->m34 +
m_sharedMatrix->m21 * m_sharedMatrix->m14 * m_sharedMatrix->m33 +
m_sharedMatrix->m31 * m_sharedMatrix->m13 * m_sharedMatrix->m24 -
m_sharedMatrix->m31 * m_sharedMatrix->m14 * m_sharedMatrix->m23;
inv[8] = m_sharedMatrix->m21 * m_sharedMatrix->m32 * m_sharedMatrix->m44 -
m_sharedMatrix->m21 * m_sharedMatrix->m34 * m_sharedMatrix->m42 -
m_sharedMatrix->m31 * m_sharedMatrix->m22 * m_sharedMatrix->m44 +
m_sharedMatrix->m31 * m_sharedMatrix->m24 * m_sharedMatrix->m42 +
m_sharedMatrix->m41 * m_sharedMatrix->m22 * m_sharedMatrix->m34 -
m_sharedMatrix->m41 * m_sharedMatrix->m24 * m_sharedMatrix->m32;
inv[9] = -m_sharedMatrix->m11 * m_sharedMatrix->m32 * m_sharedMatrix->m44 +
m_sharedMatrix->m11 * m_sharedMatrix->m34 * m_sharedMatrix->m42 +
m_sharedMatrix->m31 * m_sharedMatrix->m12 * m_sharedMatrix->m44 -
m_sharedMatrix->m31 * m_sharedMatrix->m14 * m_sharedMatrix->m42 -
m_sharedMatrix->m41 * m_sharedMatrix->m12 * m_sharedMatrix->m34 +
m_sharedMatrix->m41 * m_sharedMatrix->m14 * m_sharedMatrix->m32;
inv[10] = m_sharedMatrix->m11 * m_sharedMatrix->m22 * m_sharedMatrix->m44 -
m_sharedMatrix->m11 * m_sharedMatrix->m24 * m_sharedMatrix->m42 -
m_sharedMatrix->m21 * m_sharedMatrix->m12 * m_sharedMatrix->m44 +
m_sharedMatrix->m21 * m_sharedMatrix->m14 * m_sharedMatrix->m42 +
m_sharedMatrix->m41 * m_sharedMatrix->m12 * m_sharedMatrix->m24 -
m_sharedMatrix->m41 * m_sharedMatrix->m14 * m_sharedMatrix->m22;
inv[11] = -m_sharedMatrix->m11 * m_sharedMatrix->m22 * m_sharedMatrix->m34 +
m_sharedMatrix->m11 * m_sharedMatrix->m24 * m_sharedMatrix->m32 +
m_sharedMatrix->m21 * m_sharedMatrix->m12 * m_sharedMatrix->m34 -
m_sharedMatrix->m21 * m_sharedMatrix->m14 * m_sharedMatrix->m32 -
m_sharedMatrix->m31 * m_sharedMatrix->m12 * m_sharedMatrix->m24 +
m_sharedMatrix->m31 * m_sharedMatrix->m14 * m_sharedMatrix->m22;
inv[12] = -m_sharedMatrix->m21 * m_sharedMatrix->m32 * m_sharedMatrix->m43 +
m_sharedMatrix->m21 * m_sharedMatrix->m33 * m_sharedMatrix->m42 +
m_sharedMatrix->m31 * m_sharedMatrix->m22 * m_sharedMatrix->m43 -
m_sharedMatrix->m31 * m_sharedMatrix->m23 * m_sharedMatrix->m42 -
m_sharedMatrix->m41 * m_sharedMatrix->m22 * m_sharedMatrix->m33 +
m_sharedMatrix->m41 * m_sharedMatrix->m23 * m_sharedMatrix->m32;
inv[13] = m_sharedMatrix->m11 * m_sharedMatrix->m32 * m_sharedMatrix->m43 -
m_sharedMatrix->m11 * m_sharedMatrix->m33 * m_sharedMatrix->m42 -
m_sharedMatrix->m31 * m_sharedMatrix->m12 * m_sharedMatrix->m43 +
m_sharedMatrix->m31 * m_sharedMatrix->m13 * m_sharedMatrix->m42 +
m_sharedMatrix->m41 * m_sharedMatrix->m12 * m_sharedMatrix->m33 -
m_sharedMatrix->m41 * m_sharedMatrix->m13 * m_sharedMatrix->m32;
inv[14] = -m_sharedMatrix->m11 * m_sharedMatrix->m22 * m_sharedMatrix->m43 +
m_sharedMatrix->m11 * m_sharedMatrix->m23 * m_sharedMatrix->m42 +
m_sharedMatrix->m21 * m_sharedMatrix->m12 * m_sharedMatrix->m43 -
m_sharedMatrix->m21 * m_sharedMatrix->m13 * m_sharedMatrix->m42 -
m_sharedMatrix->m41 * m_sharedMatrix->m12 * m_sharedMatrix->m23 +
m_sharedMatrix->m41 * m_sharedMatrix->m13 * m_sharedMatrix->m22;
inv[15] = m_sharedMatrix->m11 * m_sharedMatrix->m22 * m_sharedMatrix->m33 -
m_sharedMatrix->m11 * m_sharedMatrix->m23 * m_sharedMatrix->m32 -
m_sharedMatrix->m21 * m_sharedMatrix->m12 * m_sharedMatrix->m33 +
m_sharedMatrix->m21 * m_sharedMatrix->m13 * m_sharedMatrix->m32 +
m_sharedMatrix->m31 * m_sharedMatrix->m12 * m_sharedMatrix->m23 -
m_sharedMatrix->m31 * m_sharedMatrix->m13 * m_sharedMatrix->m22;
T invDet = F(1.0) / det;
for (unsigned int i = 0; i < 16; ++i)
inv[i] *= invDet;
Set(inv);
if (succeeded)
*succeeded = true;
}
else
{
NazaraError("Matrix has no inverse");
if (succeeded)
*succeeded = false;
}
return *this;
}
template<typename T>
NzMatrix4<T>& NzMatrix4<T>::InverseAffine(bool* succeeded)
{
#if NAZARA_MATH_SAFE
if (!IsDefined())
{
NazaraError("Matrix not defined");
if (succeeded)
*succeeded = false;
return *this;
}
if (!IsAffine())
{
NazaraError("Matrix not affine");
if (succeeded)
*succeeded = false;
return *this;
}
#endif
T det = GetDeterminant();
if (!NzNumberEquals(det, F(0.0)))
{
// http://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix
T inv[16];
inv[0] = m_sharedMatrix->m22 * m_sharedMatrix->m33 -
m_sharedMatrix->m32 * m_sharedMatrix->m23;
inv[1] = -m_sharedMatrix->m12 * m_sharedMatrix->m33 +
m_sharedMatrix->m32 * m_sharedMatrix->m13;
inv[2] = m_sharedMatrix->m12 * m_sharedMatrix->m23 -
m_sharedMatrix->m22 * m_sharedMatrix->m13;
inv[3] = F(0.0);
inv[4] = -m_sharedMatrix->m21 * m_sharedMatrix->m33 +
m_sharedMatrix->m31 * m_sharedMatrix->m23;
inv[5] = m_sharedMatrix->m11 * m_sharedMatrix->m33 -
m_sharedMatrix->m31 * m_sharedMatrix->m13;
inv[6] = -m_sharedMatrix->m11 * m_sharedMatrix->m23 +
m_sharedMatrix->m21 * m_sharedMatrix->m13;
inv[7] = F(0.0);
inv[8] = m_sharedMatrix->m21 * m_sharedMatrix->m32 -
m_sharedMatrix->m31 * m_sharedMatrix->m22;
inv[9] = -m_sharedMatrix->m11 * m_sharedMatrix->m32 +
m_sharedMatrix->m31 * m_sharedMatrix->m12;
inv[10] = m_sharedMatrix->m11 * m_sharedMatrix->m22 -
m_sharedMatrix->m21 * m_sharedMatrix->m12;
inv[11] = F(0.0);
inv[12] = -m_sharedMatrix->m21 * m_sharedMatrix->m32 * m_sharedMatrix->m43 +
m_sharedMatrix->m21 * m_sharedMatrix->m33 * m_sharedMatrix->m42 +
m_sharedMatrix->m31 * m_sharedMatrix->m22 * m_sharedMatrix->m43 -
m_sharedMatrix->m31 * m_sharedMatrix->m23 * m_sharedMatrix->m42 -
m_sharedMatrix->m41 * m_sharedMatrix->m22 * m_sharedMatrix->m33 +
m_sharedMatrix->m41 * m_sharedMatrix->m23 * m_sharedMatrix->m32;
inv[13] = m_sharedMatrix->m11 * m_sharedMatrix->m32 * m_sharedMatrix->m43 -
m_sharedMatrix->m11 * m_sharedMatrix->m33 * m_sharedMatrix->m42 -
m_sharedMatrix->m31 * m_sharedMatrix->m12 * m_sharedMatrix->m43 +
m_sharedMatrix->m31 * m_sharedMatrix->m13 * m_sharedMatrix->m42 +
m_sharedMatrix->m41 * m_sharedMatrix->m12 * m_sharedMatrix->m33 -
m_sharedMatrix->m41 * m_sharedMatrix->m13 * m_sharedMatrix->m32;
inv[14] = -m_sharedMatrix->m11 * m_sharedMatrix->m22 * m_sharedMatrix->m43 +
m_sharedMatrix->m11 * m_sharedMatrix->m23 * m_sharedMatrix->m42 +
m_sharedMatrix->m21 * m_sharedMatrix->m12 * m_sharedMatrix->m43 -
m_sharedMatrix->m21 * m_sharedMatrix->m13 * m_sharedMatrix->m42 -
m_sharedMatrix->m41 * m_sharedMatrix->m12 * m_sharedMatrix->m23 +
m_sharedMatrix->m41 * m_sharedMatrix->m13 * m_sharedMatrix->m22;
inv[15] = F(0.0);
T invDet = F(1.0) / det;
for (unsigned int i = 0; i < 16; ++i)
inv[i] *= invDet;
inv[15] = F(1.0);
Set(inv);
if (succeeded)
*succeeded = true;
}
else
{
NazaraError("Matrix has no inverse");
if (succeeded)
*succeeded = false;
}
return *this;
}
template<typename T>
bool NzMatrix4<T>::IsAffine() const
{
@@ -244,26 +487,30 @@ bool NzMatrix4<T>::IsDefined() const
}
template<typename T>
void NzMatrix4<T>::MakeIdentity()
NzMatrix4<T>& NzMatrix4<T>::MakeIdentity()
{
Set(F(1.0), F(0.0), F(0.0), F(0.0),
F(0.0), F(1.0), F(0.0), F(0.0),
F(0.0), F(0.0), F(1.0), F(0.0),
F(0.0), F(0.0), F(0.0), F(1.0));
return *this;
}
template<typename T>
void NzMatrix4<T>::MakeOrtho(T left, T top, T width, T height, T zNear, T zFar)
NzMatrix4<T>& NzMatrix4<T>::MakeOrtho(T left, T top, T width, T height, T zNear, T zFar)
{
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb204941(v=vs.85).aspx
Set(F(2.0)/(width-left), F(0.0), F(0.0), -(width+left)/(width-left),
F(0.0), F(2.0)/(top-height), F(0.0), -(top+height)/(top-height),
F(0.0), F(0.0), F(-2.0)/(zFar-zNear), -(zFar+zNear)/(zFar-zNear),
F(0.0), F(0.0), F(0.0), F(1.0));
return *this;
}
template<typename T>
void NzMatrix4<T>::MakeLookAt(const NzVector3<T>& eye, const NzVector3<T>& target, const NzVector3<T>& up)
NzMatrix4<T>& NzMatrix4<T>::MakeLookAt(const NzVector3<T>& eye, const NzVector3<T>& target, const NzVector3<T>& up)
{
NzVector3<T> f = NzVector3<T>::Normalize(target - eye);
NzVector3<T> u(up.GetNormal());
@@ -274,10 +521,12 @@ void NzMatrix4<T>::MakeLookAt(const NzVector3<T>& eye, const NzVector3<T>& targe
s.y, u.y, -f.y, T(0.0),
s.z, u.z, -f.z, T(0.0),
-s.DotProduct(eye), -u.DotProduct(eye), f.DotProduct(eye), T(1.0));
return *this;
}
template<typename T>
void NzMatrix4<T>::MakePerspective(T angle, T ratio, T zNear, T zFar)
NzMatrix4<T>& NzMatrix4<T>::MakePerspective(T angle, T ratio, T zNear, T zFar)
{
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb204944(v=vs.85).aspx
#if NAZARA_MATH_ANGLE_RADIAN
@@ -292,10 +541,12 @@ void NzMatrix4<T>::MakePerspective(T angle, T ratio, T zNear, T zFar)
F(0.0), yScale, F(0.0), F(0.0),
F(0.0), F(0.0), zFar / (zNear-zFar), F(-1.0),
F(0.0), F(0.0), (zNear*zFar) / (zNear-zFar), F(0.0));
return *this;
}
template<typename T>
void NzMatrix4<T>::MakeRotation(const NzQuaternion<T>& rotation)
NzMatrix4<T>& NzMatrix4<T>::MakeRotation(const NzQuaternion<T>& rotation)
{
// http://www.flipcode.com/documents/matrfaq.html#Q54
/*
@@ -309,7 +560,7 @@ void NzMatrix4<T>::MakeRotation(const NzQuaternion<T>& rotation)
| 2XZ + 2YW 2YZ - 2XW 1 - 2X - 2Y |
| |
*/
///FIXME: À corriger (Rotation quaternino != rotation matricielle)
///FIXME: À corriger (Rotation quaternion != rotation matricielle)
Set(F(1.0) - F(2.0)*rotation.y*rotation.y - F(2.0)*rotation.z*rotation.z,
F(2.0)*rotation.x*rotation.y + F(2.0)*rotation.z*rotation.w,
F(2.0)*rotation.x*rotation.z - F(2.0)*rotation.y*rotation.w,
@@ -329,43 +580,71 @@ void NzMatrix4<T>::MakeRotation(const NzQuaternion<T>& rotation)
F(0.0),
F(0.0),
F(1.0));
return *this;
}
template<typename T>
void NzMatrix4<T>::MakeScale(const NzVector3<T>& scale)
NzMatrix4<T>& NzMatrix4<T>::MakeScale(const NzVector3<T>& scale)
{
Set(scale.x, F(0.0), F(0.0), F(0.0),
F(0.0), scale.y, F(0.0), F(0.0),
F(0.0), F(0.0), scale.z, F(0.0),
F(0.0), F(0.0), F(0.0), F(1.0));
return *this;
}
template<typename T>
void NzMatrix4<T>::MakeTranslation(const NzVector3<T>& translation)
NzMatrix4<T>& NzMatrix4<T>::MakeTranslation(const NzVector3<T>& translation)
{
Set(F(1.0), F(0.0), F(0.0), F(0.0),
F(0.0), F(1.0), F(0.0), F(0.0),
F(0.0), F(0.0), F(1.0), F(0.0),
translation.x, translation.y, translation.z, F(1.0));
return *this;
}
template<typename T>
void NzMatrix4<T>::MakeZero()
NzMatrix4<T>& NzMatrix4<T>::MakeTransform(const NzVector3<T>& translation, const NzVector3<T>& scale, const NzQuaternion<T>& rotation)
{
// La rotation et la translation peuvent être appliquées directement
SetRotation(rotation);
SetTranslation(translation);
// On complète la matrice (les transformations sont affines)
m_sharedMatrix->m14 = F(0.0);
m_sharedMatrix->m24 = F(0.0);
m_sharedMatrix->m34 = F(0.0);
m_sharedMatrix->m44 = F(1.0);
// Ensuite on fait une mise à l'échelle des valeurs déjà présentes
ApplyScale(scale);
return *this;
}
template<typename T>
NzMatrix4<T>& NzMatrix4<T>::MakeZero()
{
Set(F(0.0), F(0.0), F(0.0), F(0.0),
F(0.0), F(0.0), F(0.0), F(0.0),
F(0.0), F(0.0), F(0.0), F(0.0),
F(0.0), F(0.0), F(0.0), F(0.0));
return *this;
}
template<typename T>
void NzMatrix4<T>::Set(T r11, T r12, T r13, T r14,
NzMatrix4<T>& 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)
{
EnsureOwnership();
ReleaseMatrix();
m_sharedMatrix = new SharedMatrix;
m_sharedMatrix->m11 = r11;
m_sharedMatrix->m12 = r12;
m_sharedMatrix->m13 = r13;
@@ -382,19 +661,24 @@ void NzMatrix4<T>::Set(T r11, T r12, T r13, T r14,
m_sharedMatrix->m42 = r42;
m_sharedMatrix->m43 = r43;
m_sharedMatrix->m44 = r44;
return *this;
}
template<typename T>
void NzMatrix4<T>::Set(const T matrix[16])
NzMatrix4<T>& NzMatrix4<T>::Set(const T matrix[16])
{
EnsureOwnership();
ReleaseMatrix();
m_sharedMatrix = new SharedMatrix;
// Ici nous sommes certains de la continuité des éléments en mémoire
std::memcpy(&m_sharedMatrix->m11, matrix, 16*sizeof(T));
return *this;
}
template<typename T>
void NzMatrix4<T>::Set(const NzMatrix4& matrix)
NzMatrix4<T>& NzMatrix4<T>::Set(const NzMatrix4& matrix)
{
ReleaseMatrix();
@@ -405,26 +689,32 @@ void NzMatrix4<T>::Set(const NzMatrix4& matrix)
m_sharedMatrix->refCount++;
NazaraMutexUnlock(m_sharedMatrix->mutex);
}
return *this;
}
template<typename T>
void NzMatrix4<T>::Set(NzMatrix4&& matrix)
NzMatrix4<T>& NzMatrix4<T>::Set(NzMatrix4&& matrix)
{
std::swap(m_sharedMatrix, matrix.m_sharedMatrix);
return *this;
}
template<typename T>
template<typename U>
void NzMatrix4<T>::Set(const NzMatrix4<U>& matrix)
NzMatrix4<T>& NzMatrix4<T>::Set(const NzMatrix4<U>& matrix)
{
Set(F(matrix.m_sharedMatrix->m11), F(matrix.m_sharedMatrix->m12), F(matrix.m_sharedMatrix->m13), F(matrix.m_sharedMatrix->m14),
F(matrix.m_sharedMatrix->m21), F(matrix.m_sharedMatrix->m22), F(matrix.m_sharedMatrix->m23), F(matrix.m_sharedMatrix->m24),
F(matrix.m_sharedMatrix->m31), F(matrix.m_sharedMatrix->m32), F(matrix.m_sharedMatrix->m33), F(matrix.m_sharedMatrix->m34),
F(matrix.m_sharedMatrix->m41), F(matrix.m_sharedMatrix->m42), F(matrix.m_sharedMatrix->m43), F(matrix.m_sharedMatrix->m44));
return *this;
}
template<typename T>
void NzMatrix4<T>::SetRotation(const NzQuaternion<T>& rotation)
NzMatrix4<T>& NzMatrix4<T>::SetRotation(const NzQuaternion<T>& rotation)
{
// http://www.flipcode.com/documents/matrfaq.html#Q54
EnsureOwnership();
@@ -439,20 +729,24 @@ void NzMatrix4<T>::SetRotation(const NzQuaternion<T>& rotation)
m_sharedMatrix->m23 = F(2.0)*rotation.y*rotation.z - F(2.0)*rotation.x*rotation.w;
m_sharedMatrix->m31 = F(2.0)*rotation.x*rotation.z - F(2.0)*rotation.y*rotation.w;
m_sharedMatrix->m32 = F(2.0)*rotation.y*rotation.z + F(2.0)*rotation.x*rotation.w;
return *this;
}
template<typename T>
void NzMatrix4<T>::SetScale(const NzVector3<T>& scale)
NzMatrix4<T>& NzMatrix4<T>::SetScale(const NzVector3<T>& scale)
{
EnsureOwnership();
m_sharedMatrix->m11 = scale.x;
m_sharedMatrix->m22 = scale.y;
m_sharedMatrix->m33 = scale.z;
return *this;
}
template<typename T>
void NzMatrix4<T>::SetTranslation(const NzVector3<T>& translation)
NzMatrix4<T>& NzMatrix4<T>::SetTranslation(const NzVector3<T>& translation)
{
EnsureOwnership();
@@ -460,6 +754,8 @@ void NzMatrix4<T>::SetTranslation(const NzVector3<T>& translation)
m_sharedMatrix->m42 = translation.y;
m_sharedMatrix->m43 = translation.z;
m_sharedMatrix->m44 = F(1.0);
return *this;
}
template<typename T>
@@ -534,6 +830,8 @@ NzMatrix4<T>& NzMatrix4<T>::Transpose()
}
#endif
EnsureOwnership();
std::swap(m_sharedMatrix->m12, m_sharedMatrix->m21);
std::swap(m_sharedMatrix->m13, m_sharedMatrix->m31);
std::swap(m_sharedMatrix->m14, m_sharedMatrix->m41);
@@ -544,6 +842,14 @@ NzMatrix4<T>& NzMatrix4<T>::Transpose()
return *this;
}
template<typename T>
NzMatrix4<T>& NzMatrix4<T>::Undefine()
{
ReleaseMatrix();
return *this;
}
template<typename T>
NzMatrix4<T>::operator NzString() const
{
@@ -734,7 +1040,7 @@ bool NzMatrix4<T>::operator==(const NzMatrix4& mat) const
return false;
for (unsigned int i = 0; i < 16; ++i)
if (!NzNumberEquals((&m_sharedMatrix->m11)[i]))
if (!NzNumberEquals((&m_sharedMatrix->m11)[i], (&mat.m_sharedMatrix->m11)[i]))
return false;
return true;
@@ -904,6 +1210,15 @@ NzMatrix4<T> NzMatrix4<T>::Translate(const NzVector3<T>& translation)
return mat;
}
template<typename T>
NzMatrix4<T> NzMatrix4<T>::Transform(const NzVector3<T>& translation, const NzVector3<T>& scale, const NzQuaternion<T>& rotation)
{
NzMatrix4 mat;
mat.MakeTransform(translation, scale, rotation);
return mat;
}
template<typename T>
NzMatrix4<T> NzMatrix4<T>::Zero()
{
@@ -937,6 +1252,8 @@ void NzMatrix4<T>::EnsureOwnership()
SharedMatrix* sharedMatrix = new SharedMatrix;
std::memcpy(&sharedMatrix->m11, &m_sharedMatrix->m11, 16*sizeof(T));
m_sharedMatrix = sharedMatrix;
}
}
else

View File

@@ -77,7 +77,8 @@ template<typename T> class NzQuaternion
bool operator>=(const NzQuaternion& quat) const;
static NzQuaternion Identity();
static NzQuaternion Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp);
static NzQuaternion Lerp(const NzQuaternion& from, const NzQuaternion& to, T interpolation);
static NzQuaternion Slerp(const NzQuaternion& from, const NzQuaternion& to, T interpolation);
static NzQuaternion Zero();
T w, x, y, z;

View File

@@ -365,32 +365,54 @@ NzQuaternion<T> NzQuaternion<T>::Identity()
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp)
NzQuaternion<T> NzQuaternion<T>::Lerp(const NzQuaternion& from, const NzQuaternion& to, T interpolation)
{
if (interp <= F(0.0))
return quatA;
#ifdef NAZARA_DEBUG
if (interpolation < F(0.0) || interpolation > F(1.0))
{
NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')');
return Zero();
}
#endif
if (interp >= F(1.0))
return quatB;
NzQuaternion interpolated;
interpolated.w = NzLerp(from.w, to.w, interpolation);
interpolated.x = NzLerp(from.x, to.x, interpolation);
interpolated.y = NzLerp(from.y, to.y, interpolation);
interpolated.z = NzLerp(from.z, to.z, interpolation);
return interpolated;
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::Slerp(const NzQuaternion& from, const NzQuaternion& to, T interpolation)
{
#ifdef NAZARA_DEBUG
if (interpolation < F(0.0) || interpolation > F(1.0))
{
NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')');
return Zero();
}
#endif
NzQuaternion q;
T cosOmega = quatA.DotProduct(quatB);
T cosOmega = from.DotProduct(to);
if (cosOmega < F(0.0))
{
// On inverse tout
q.Set(-quatB.w, -quatB.x, -quatB.y, -quatB.z);
q.Set(-to.w, -to.x, -to.y, -to.z);
cosOmega = -cosOmega;
}
else
q.Set(quatB);
q.Set(to);
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;
k0 = F(1.0) - interpolation;
k1 = interpolation;
}
else
{
@@ -400,11 +422,11 @@ NzQuaternion<T> NzQuaternion<T>::Slerp(const NzQuaternion& quatA, const NzQuater
// Pour éviter deux divisions
sinOmega = F(1.0)/sinOmega;
k0 = std::sin((F(1.0) - interp) * omega) * sinOmega;
k1 = std::sin(interp*omega) * sinOmega;
k0 = std::sin((F(1.0) - interpolation) * omega) * sinOmega;
k1 = std::sin(interpolation*omega) * sinOmega;
}
NzQuaternion result(k0 * quatA.w, k0 * quatA.x, k0 * quatA.y, k0 * quatA.z);
NzQuaternion result(k0 * from.w, k0 * from.x, k0 * from.y, k0 * from.z);
return result += q*k1;
}

View File

@@ -35,6 +35,8 @@ class NzRect
bool IsValid() const;
void MakeZero();
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);
@@ -47,6 +49,16 @@ class NzRect
T& operator[](unsigned int i);
T operator[](unsigned int i) const;
NzRect operator*(T scalar) const;
NzRect& operator*=(T scalar);
bool operator==(const NzRect& rect) const;
bool operator!=(const NzRect& rect) const;
static NzRect Lerp(const NzRect& from, const NzRect& to, T interpolation);
static NzRect Zero();
T x, y, width, height;
};

View File

@@ -112,6 +112,15 @@ bool NzRect<T>::IsValid() const
return width > F(0.0) && height > F(0.0);
}
template<typename T>
void NzRect<T>::MakeZero()
{
x = F(0.0);
y = F(0.0);
width = F(0.0);
height = F(0.0);
}
template<typename T>
void NzRect<T>::Set(T X, T Y, T Width, T Height)
{
@@ -195,6 +204,61 @@ T NzRect<T>::operator[](unsigned int i) const
return *(&x+i);
}
template<typename T>
NzRect<T> NzRect<T>::operator*(T scalar) const
{
return NzRect(x, y, width*scalar, height*scalar);
}
template<typename T>
NzRect<T>& NzRect<T>::operator*=(T scalar)
{
width *= scalar;
height *= scalar;
}
template<typename T>
bool NzRect<T>::operator==(const NzRect& rect) const
{
return NzNumberEquals(x, rect.x) && NzNumberEquals(y, rect.y) &&
NzNumberEquals(width, rect.width) && NzNumberEquals(height, rect.height);
}
template<typename T>
bool NzRect<T>::operator!=(const NzRect& rect) const
{
return !operator==(rect);
}
template<typename T>
NzRect<T> NzRect<T>::Lerp(const NzRect& from, const NzRect& to, T interpolation)
{
#ifdef NAZARA_DEBUG
if (interpolation < F(0.0) || interpolation > F(1.0))
{
NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')');
return Zero();
}
#endif
NzRect rect;
rect.x = NzLerp(from.x, to.x, interpolation);
rect.y = NzLerp(from.y, to.y, interpolation);
rect.width = NzLerp(from.width, to.width, interpolation);
rect.height = NzLerp(from.height, to.height, interpolation);
return rect;
}
template<typename T>
NzRect<T> NzRect<T>::Zero()
{
NzRect rect;
rect.MakeZero();
return rect;
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const NzRect<T>& rect)
{

View File

@@ -83,6 +83,7 @@ template<typename T> class NzVector2
bool operator>(const NzVector2& vec) const;
bool operator>=(const NzVector2& vec) const;
static NzVector2 Lerp(const NzVector2& from, const NzVector2& to, T interpolation);
static NzVector2 UnitX();
static NzVector2 UnitY();
static NzVector2 Zero();

View File

@@ -428,6 +428,12 @@ bool NzVector2<T>::operator>=(const NzVector2& vec) const
return !operator<(vec);
}
template<typename T>
NzVector2<T> NzVector2<T>::Lerp(const NzVector2& from, const NzVector2& to, T interpolation)
{
return NzLerp(from, to, interpolation);
}
template<typename T>
NzVector2<T> NzVector2<T>::UnitX()
{

View File

@@ -96,6 +96,7 @@ template<typename T> class NzVector3
static T DotProduct(const NzVector3& vec1, const NzVector3& vec2);
static NzVector3 Forward();
static NzVector3 Left();
static NzVector3 Lerp(const NzVector3& from, const NzVector3& to, T interpolation);
static NzVector3 Normalize(const NzVector3& vec);
static NzVector3 UnitX();
static NzVector3 UnitY();

View File

@@ -515,6 +515,12 @@ NzVector3<T> NzVector3<T>::Left()
return vector;
}
template<typename T>
NzVector3<T> NzVector3<T>::Lerp(const NzVector3& from, const NzVector3& to, T interpolation)
{
return NzLerp(from, to, interpolation);
}
template<typename T>
NzVector3<T> NzVector3<T>::Normalize(const NzVector3& vec)
{

View File

@@ -37,20 +37,32 @@
///TODO: Rajouter des tests d'identification de compilateurs
// NAZARA_THREADLOCAL n'existe qu'en attendant le support complet de thread_local
#if defined(_MSC_VER)
#define NAZARA_COMPILER_MSVC
#define NAZARA_DEPRECATED(txt) __declspec(deprecated(txt))
#define NAZARA_FUNCTION __FUNCSIG__
#if defined(__BORLANDC__)
#define NAZARA_COMPILER_BORDLAND
#define NAZARA_DEPRECATED(txt)
#define NAZARA_FUNCTION __FUNC__
#define NAZARA_THREADLOCAL __declspec(thread)
#elif defined(__GNUC__)
#elif defined(__clang__)
#define NAZARA_COMPILER_CLANG
#define NAZARA_DEPRECATED(txt) __attribute__((__deprecated__(txt)))
#define NAZARA_FUNCTION __PRETTY_FUNCTION__
#define NAZARA_THREADLOCAL __declspec(thread)
#elif defined(__GNUC__) || defined(__MINGW32__)
#define NAZARA_COMPILER_GCC
#define NAZARA_DEPRECATED(txt) __attribute__((__deprecated__(txt)))
#define NAZARA_FUNCTION __PRETTY_FUNCTION__
#define NAZARA_THREADLOCAL __thread
#elif defined(__BORLANDC__)
#define NAZARA_COMPILER_BORDLAND
#define NAZARA_DEPRECATED(txt)
#define NAZARA_FUNCTION __FUNC__
#ifdef __MINGW32__
#define NAZARA_COMPILER_MINGW
#ifdef __MINGW64_VERSION_MAJOR
#define NAZARA_COMPILER_MINGW_W64
#endif
#endif
#elif defined(_MSC_VER)
#define NAZARA_COMPILER_MSVC
#define NAZARA_DEPRECATED(txt) __declspec(deprecated(txt))
#define NAZARA_FUNCTION __FUNCSIG__
#define NAZARA_THREADLOCAL __declspec(thread)
#else
#define NAZARA_COMPILER_UNKNOWN

View File

@@ -9,6 +9,7 @@
#ifdef NAZARA_RENDERER_OPENGL
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Resource.hpp>
#include <Nazara/Renderer/ContextParameters.hpp>
@@ -19,7 +20,7 @@ class NAZARA_API NzContext : public NzResource
friend NzContextImpl;
public:
NzContext();
NzContext() = default;
~NzContext();
bool Create(const NzContextParameters& parameters = NzContextParameters());

View File

@@ -151,6 +151,7 @@ NAZARA_API extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
NAZARA_API extern PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv;
NAZARA_API extern PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog;
NAZARA_API extern PFNGLGETERRORPROC glGetError;
NAZARA_API extern PFNGLGETFLOATVPROC glGetFloatv;
NAZARA_API extern PFNGLGETINTEGERVPROC glGetIntegerv;
NAZARA_API extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
NAZARA_API extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
@@ -168,10 +169,12 @@ NAZARA_API extern PFNGLGETTEXLEVELPARAMETERIVPROC glGetTexLevelParameteriv;
NAZARA_API extern PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv;
NAZARA_API extern PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv;
NAZARA_API extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
NAZARA_API extern PFNGLLINEWIDTHPROC glLineWidth;
NAZARA_API extern PFNGLLINKPROGRAMPROC glLinkProgram;
NAZARA_API extern PFNGLMAPBUFFERPROC glMapBuffer;
NAZARA_API extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
NAZARA_API extern PFNGLPIXELSTOREIPROC glPixelStorei;
NAZARA_API extern PFNGLPOINTSIZEPROC glPointSize;
NAZARA_API extern PFNGLPOLYGONMODEPROC glPolygonMode;
NAZARA_API extern PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d;
NAZARA_API extern PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f;

View File

@@ -36,11 +36,13 @@ class NAZARA_API NzRenderer
static void Enable(nzRendererParameter parameter, bool enable);
float GetLineWidth();
//static NzMatrix4f GetMatrix(nzMatrixCombination combination);
static NzMatrix4f GetMatrix(nzMatrixType type);
static unsigned int GetMaxAnisotropyLevel();
static unsigned int GetMaxRenderTargets();
static unsigned int GetMaxTextureUnits();
static float GetPointSize();
static NzShader* GetShader();
static NzRenderTarget* GetTarget();
static NzRectui GetViewport();
@@ -59,7 +61,9 @@ class NAZARA_API NzRenderer
static void SetFaceCulling(nzFaceCulling cullingMode);
static void SetFaceFilling(nzFaceFilling fillingMode);
static bool SetIndexBuffer(const NzIndexBuffer* indexBuffer);
static void SetLineWidth(float size);
static void SetMatrix(nzMatrixType type, const NzMatrix4f& matrix);
static void SetPointSize(float size);
static bool SetShader(NzShader* shader);
static void SetStencilCompareFunction(nzRendererComparison compareFunc);
static void SetStencilFailOperation(nzStencilOperation failOperation);

View File

@@ -43,6 +43,7 @@ class NAZARA_API NzShader : public NzResource, NzNonCopyable
bool IsCompiled() const;
bool IsLoaded(nzShaderType type) const;
bool IsValid() const;
bool Load(nzShaderType type, const NzString& source);
bool LoadFromFile(nzShaderType type, const NzString& source);

View File

@@ -15,6 +15,7 @@ class NAZARA_API NzAxisAlignedBox
{
public:
NzAxisAlignedBox();
NzAxisAlignedBox(const NzCubef& cube);
NzAxisAlignedBox(const NzVector3f& vec1, const NzVector3f& vec2);
NzAxisAlignedBox(nzExtend extend);
@@ -37,6 +38,10 @@ class NAZARA_API NzAxisAlignedBox
NzString ToString() const;
operator NzString() const;
static NzAxisAlignedBox Lerp(const NzAxisAlignedBox& from, const NzAxisAlignedBox& to, float interpolation);
static const NzAxisAlignedBox Infinite;
static const NzAxisAlignedBox Null;

View File

@@ -10,6 +10,7 @@
#define NAZARA_KEYBOARD_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/String.hpp>
class NAZARA_API NzKeyboard
{
@@ -159,6 +160,7 @@ class NAZARA_API NzKeyboard
Count
};
static NzString GetKeyName(Key key);
static bool IsKeyPressed(Key key);
};