Merge branch 'master' into NDK

Conflicts:
	include/Nazara/Core/Algorithm.inl
	include/Nazara/Core/ByteArray.hpp
	include/Nazara/Math/Algorithm.inl
	src/Nazara/Graphics/SkyboxBackground.cpp

Former-commit-id: 42f52f71989fa805f69527fd07edb8405df06566
This commit is contained in:
Lynix
2015-08-21 18:55:58 +02:00
76 changed files with 2358 additions and 833 deletions

View File

@@ -16,6 +16,10 @@
#define M_PI 3.141592653589793238462643
#endif
#ifndef M_PI_2
#define M_PI_2 1.5707963267948966192313217
#endif
#ifndef M_SQRT2
#define M_SQRT2 1.4142135623730950488016887
#endif

View File

@@ -337,9 +337,10 @@ bool NzNumberEquals(T a, T b)
template<typename T>
bool NzNumberEquals(T a, T b, T maxDifference)
{
std::pair<const T&, const T&> minmax = std::minmax(a, b);
T diff = minmax.second - minmax.first;
if (b > a)
std::swap(a, b);
T diff = a - b;
return diff <= maxDifference;
}

View File

@@ -212,7 +212,10 @@ template<typename T>
bool NzBoundingVolume<T>::operator==(const NzBoundingVolume& volume) const
{
if (extend == volume.extend)
return obb == volume.obb;
if (extend == nzExtend_Finite)
return obb == volume.obb;
else
return true;
else
return false;
}

View File

@@ -65,7 +65,7 @@ template<typename T>
bool NzBox<T>::Contains(const NzBox<T>& box) const
{
return Contains(box.x, box.y, box.z) &&
Contains(box.x + box.width, box.y + box.height, box.z + box.depth);
Contains(box.x + box.width, box.y + box.height, box.z + box.depth);
}
template<typename T>
@@ -399,9 +399,9 @@ NzBox<T>& NzBox<T>::Transform(const NzMatrix4<T>& matrix, bool applyTranslation)
NzVector3<T> center = matrix.Transform(GetCenter(), (applyTranslation) ? F(1.0) : F(0.0)); // Valeur multipliant la translation
NzVector3<T> halfSize = GetLengths()/F(2.0);
halfSize.Set(std::fabs(matrix(0,0))*halfSize.x + std::fabs(matrix(1,0))*halfSize.y + std::fabs(matrix(2,0))*halfSize.z,
std::fabs(matrix(0,1))*halfSize.x + std::fabs(matrix(1,1))*halfSize.y + std::fabs(matrix(2,1))*halfSize.z,
std::fabs(matrix(0,2))*halfSize.x + std::fabs(matrix(1,2))*halfSize.y + std::fabs(matrix(2,2))*halfSize.z);
halfSize.Set(std::abs(matrix(0,0))*halfSize.x + std::abs(matrix(1,0))*halfSize.y + std::abs(matrix(2,0))*halfSize.z,
std::abs(matrix(0,1))*halfSize.x + std::abs(matrix(1,1))*halfSize.y + std::abs(matrix(2,1))*halfSize.z,
std::abs(matrix(0,2))*halfSize.x + std::abs(matrix(1,2))*halfSize.y + std::abs(matrix(2,2))*halfSize.z);
return Set(center - halfSize, center + halfSize);
}
@@ -486,7 +486,7 @@ template<typename T>
bool NzBox<T>::operator==(const NzBox& box) const
{
return NzNumberEquals(x, box.x) && NzNumberEquals(y, box.y) && NzNumberEquals(z, box.z) &&
NzNumberEquals(width, box.width) && NzNumberEquals(height, box.height) && NzNumberEquals(depth, box.depth);
NzNumberEquals(width, box.width) && NzNumberEquals(height, box.height) && NzNumberEquals(depth, box.depth);
}
template<typename T>

View File

@@ -91,11 +91,18 @@ void NzEulerAngles<T>::Set(const NzEulerAngles<U>& angles)
template<typename T>
NzQuaternion<T> NzEulerAngles<T>::ToQuaternion() const
{
NzQuaternion<T> rotX(pitch, NzVector3<T>::UnitX());
NzQuaternion<T> rotY(yaw, NzVector3<T>::UnitY());
NzQuaternion<T> rotZ(roll, NzVector3<T>::UnitZ());
T c1 = std::cos(NzToRadians(yaw) / F(2.0));
T c2 = std::cos(NzToRadians(roll) / F(2.0));
T c3 = std::cos(NzToRadians(pitch) / F(2.0));
return rotY * rotX * rotZ;
T s1 = std::sin(NzToRadians(yaw) / F(2.0));
T s2 = std::sin(NzToRadians(roll) / F(2.0));
T s3 = std::sin(NzToRadians(pitch) / F(2.0));
return NzQuaternion<T>(c1 * c2 * c3 - s1 * s2 * s3,
s1 * s2 * c3 + c1 * c2 * s3,
s1 * c2 * c3 + c1 * s2 * s3,
c1 * s2 * c3 - s1 * c2 * s3);
}
template<typename T>

View File

@@ -180,7 +180,7 @@ NzFrustum<T>& NzFrustum<T>::Extract(const NzMatrix4<T>& clipMatrix)
plane[0] *= invLength;
plane[1] *= invLength;
plane[2] *= invLength;
plane[3] *= invLength;
plane[3] *= -invLength;
m_planes[nzFrustumPlane_Right].Set(plane);
@@ -195,7 +195,7 @@ NzFrustum<T>& NzFrustum<T>::Extract(const NzMatrix4<T>& clipMatrix)
plane[0] *= invLength;
plane[1] *= invLength;
plane[2] *= invLength;
plane[3] *= invLength;
plane[3] *= -invLength;
m_planes[nzFrustumPlane_Left].Set(plane);
@@ -210,7 +210,7 @@ NzFrustum<T>& NzFrustum<T>::Extract(const NzMatrix4<T>& clipMatrix)
plane[0] *= invLength;
plane[1] *= invLength;
plane[2] *= invLength;
plane[3] *= invLength;
plane[3] *= -invLength;
m_planes[nzFrustumPlane_Bottom].Set(plane);
@@ -225,7 +225,7 @@ NzFrustum<T>& NzFrustum<T>::Extract(const NzMatrix4<T>& clipMatrix)
plane[0] *= invLength;
plane[1] *= invLength;
plane[2] *= invLength;
plane[3] *= invLength;
plane[3] *= -invLength;
m_planes[nzFrustumPlane_Top].Set(plane);
@@ -240,7 +240,7 @@ NzFrustum<T>& NzFrustum<T>::Extract(const NzMatrix4<T>& clipMatrix)
plane[0] *= invLength;
plane[1] *= invLength;
plane[2] *= invLength;
plane[3] *= invLength;
plane[3] *= -invLength;
m_planes[nzFrustumPlane_Far].Set(plane);
@@ -255,7 +255,7 @@ NzFrustum<T>& NzFrustum<T>::Extract(const NzMatrix4<T>& clipMatrix)
plane[0] *= invLength;
plane[1] *= invLength;
plane[2] *= invLength;
plane[3] *= invLength;
plane[3] *= -invLength;
m_planes[nzFrustumPlane_Near].Set(plane);
@@ -332,10 +332,7 @@ NzFrustum<T>& NzFrustum<T>::Extract(const NzMatrix4<T>& clipMatrix)
template<typename T>
NzFrustum<T>& NzFrustum<T>::Extract(const NzMatrix4<T>& view, const NzMatrix4<T>& projection)
{
NzMatrix4<T> clipMatrix(view);
clipMatrix *= projection;
return Extract(clipMatrix);
return Extract(NzMatrix4<T>::Concatenate(view, projection));
}
template<typename T>

View File

@@ -81,7 +81,6 @@ class NzMatrix4
NzMatrix4& Set(const T matrix[16]);
//NzMatrix4(const NzMatrix3<T>& matrix);
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);

View File

@@ -585,6 +585,21 @@ NzMatrix4<T>& NzMatrix4<T>::MakeIdentity()
return *this;
}
template<typename T>
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> s = NzVector3<T>::Normalize(f.CrossProduct(up));
NzVector3<T> u = s.CrossProduct(f);
Set(s.x, u.x, -f.x, T(0.0),
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>
NzMatrix4<T>& NzMatrix4<T>::MakeOrtho(T left, T right, T top, T bottom, T zNear, T zFar)
{
@@ -597,22 +612,6 @@ NzMatrix4<T>& NzMatrix4<T>::MakeOrtho(T left, T right, T top, T bottom, T zNear,
return *this;
}
template<typename T>
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());
NzVector3<T> s = NzVector3<T>::Normalize(f.CrossProduct(u));
u = s.CrossProduct(f);
Set(s.x, u.x, -f.x, T(0.0),
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>
NzMatrix4<T>& NzMatrix4<T>::MakePerspective(T angle, T ratio, T zNear, T zFar)
{
@@ -623,12 +622,12 @@ NzMatrix4<T>& NzMatrix4<T>::MakePerspective(T angle, T ratio, T zNear, T zFar)
angle = NzDegreeToRadian(angle/F(2.0));
#endif
T yScale = F(1.0) / std::tan(angle);
T yScale = std::tan(M_PI_2 - angle);
Set(yScale / ratio, F(0.0), F(0.0), F(0.0),
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));
F(0.0), F(0.0), - (zFar + zNear) / (zFar - zNear), F(-1.0),
F(0.0), F(0.0), F(-2.0) * (zNear * zFar) / (zFar - zNear), F(0.0));
return *this;
}
@@ -703,7 +702,7 @@ NzMatrix4<T>& NzMatrix4<T>::MakeViewMatrix(const NzVector3<T>& translation, cons
// Une matrice de vue doit appliquer une transformation opposée à la matrice "monde"
NzQuaternion<T> invRot = rotation.GetConjugate(); // Inverse de la rotation
return MakeTransform(-(invRot*translation), invRot);
return MakeTransform(-(invRot * translation), invRot);
}
template<typename T>
@@ -828,9 +827,9 @@ 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 << ')';
<< " " << m21 << ", " << m22 << ", " << m23 << ", " << m24 << ",\n"
<< " " << m31 << ", " << m32 << ", " << m33 << ", " << m34 << ",\n"
<< " " << m41 << ", " << m42 << ", " << m43 << ", " << m44 << ')';
}
template<typename T>

View File

@@ -103,9 +103,9 @@ template<typename U>
NzOrientedBox<T>& NzOrientedBox<T>::Set(const NzOrientedBox<U>& orientedBox)
{
for (unsigned int i = 0; i <= nzBoxCorner_Max; ++i)
m_corners[i].Set(orientedBox.m_corners[i]);
m_corners[i].Set(orientedBox(i));
localBox = orientedBox.localBox;
localBox.Set(orientedBox.localBox);
return *this;
}
@@ -158,7 +158,7 @@ NzVector3<T>& NzOrientedBox<T>::operator()(unsigned int i)
if (i > nzBoxCorner_Max)
{
NzStringStream ss;
ss << "Index out of range: (" << i << " >= 3)";
ss << "Index out of range: (" << i << " >= " << nzBoxCorner_Max << ")";
NazaraError(ss);
throw std::out_of_range(ss.ToString());
@@ -175,7 +175,7 @@ NzVector3<T> NzOrientedBox<T>::operator()(unsigned int i) const
if (i > nzBoxCorner_Max)
{
NzStringStream ss;
ss << "Index out of range: (" << i << " >= 3)";
ss << "Index out of range: (" << i << " >= " << nzBoxCorner_Max << ")";
NazaraError(ss);
throw std::out_of_range(ss.ToString());

View File

@@ -37,6 +37,9 @@ class NzPlane
NzString ToString() const;
bool operator==(const NzPlane& plane) const;
bool operator!=(const NzPlane& plane) const;
static NzPlane Lerp(const NzPlane& from, const NzPlane& to, T interpolation);
static NzPlane XY();
static NzPlane XZ();

View File

@@ -49,7 +49,7 @@ NzPlane<T>::NzPlane(const NzPlane<U>& plane)
template<typename T>
T NzPlane<T>::Distance(const NzVector3<T>& point) const
{
return normal.DotProduct(point) + distance;
return normal.DotProduct(point) - distance; // ax + by + cd - d = 0.
}
template<typename T>
@@ -110,7 +110,7 @@ NzPlane<T>& NzPlane<T>::Set(const NzVector3<T>& point1, const NzVector3<T>& poin
normal = edge1.CrossProduct(edge2);
normal.Normalize();
distance = -normal.DotProduct(point3);
distance = normal.DotProduct(point3);
return *this;
}
@@ -133,6 +133,18 @@ NzString NzPlane<T>::ToString() const
return ss << "Plane(Normal: " << normal.ToString() << "; Distance: " << distance << ')';
}
template<typename T>
bool NzPlane<T>::operator==(const NzPlane& plane) const
{
return (normal == plane.normal && NzNumberEquals(distance, plane.distance)) || (normal == -plane.normal && NzNumberEquals(distance, -plane.distance));
}
template<typename T>
bool NzPlane<T>::operator!=(const NzPlane& plane) const
{
return !operator==(plane);
}
template<typename T>
NzPlane<T> NzPlane<T>::Lerp(const NzPlane& from, const NzPlane& to, T interpolation)
{
@@ -155,19 +167,19 @@ NzPlane<T> NzPlane<T>::Lerp(const NzPlane& from, const NzPlane& to, T interpolat
template<typename T>
NzPlane<T> NzPlane<T>::XY()
{
return NzPlane<T>(F(0.0), F(0.0), F(1.0), F(0.0));
return NzPlane<T>(F(0.0), F(0.0), F(1.0), F(0.0));
}
template<typename T>
NzPlane<T> NzPlane<T>::XZ()
{
return NzPlane<T>(F(0.0), F(1.0), F(0.0), F(0.0));
return NzPlane<T>(F(0.0), F(1.0), F(0.0), F(0.0));
}
template<typename T>
NzPlane<T> NzPlane<T>::YZ()
{
return NzPlane<T>(F(1.0), F(0.0), F(0.0), F(0.0));
return NzPlane<T>(F(1.0), F(0.0), F(0.0), F(0.0));
}
template<typename T>

View File

@@ -237,10 +237,10 @@ template<typename T>
template<typename U>
NzQuaternion<T>& 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);
w = F(quat.w);
x = F(quat.x);
y = F(quat.y);
z = F(quat.z);
return *this;
}
@@ -270,9 +270,9 @@ NzEulerAngles<T> NzQuaternion<T>::ToEulerAngles() const
if (test < F(-0.499))
return NzEulerAngles<T>(NzFromDegrees(F(-90.0)), NzFromRadians(F(-2.0) * std::atan2(x, w)), F(0.0));
return NzEulerAngles<T>(NzFromRadians(std::atan2(F(2.0)*x*w - F(2.0)*y*z, F(1.0) - F(2.0)*x* - F(2.0)*z*z)),
NzFromRadians(std::atan2(F(2.0)*y*w - F(2.0)*x*z, F(1.0) - F(2.0)*y*y - F(2.0)*z*z)),
NzFromRadians(std::asin(F(2.0)*test)));
return NzEulerAngles<T>(NzFromRadians(std::atan2(F(2.0)*x*w - F(2.0)*y*z, F(1.0) - F(2.0)*x*x - F(2.0)*z*z)),
NzFromRadians(std::atan2(F(2.0)*y*w - F(2.0)*x*z, F(1.0) - F(2.0)*y*y - F(2.0)*z*z)),
NzFromRadians(std::asin(F(2.0)*test)));
}
template<typename T>
@@ -329,9 +329,9 @@ template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator*(T scale) const
{
return NzQuaternion(w * scale,
x * scale,
y * scale,
z * scale);
x * scale,
y * scale,
z * scale);
}
template<typename T>
@@ -368,9 +368,9 @@ 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);
NzNumberEquals(x, quat.x) &&
NzNumberEquals(y, quat.y) &&
NzNumberEquals(z, quat.z);
}
template<typename T>
@@ -450,23 +450,23 @@ NzQuaternion<T> NzQuaternion<T>::Slerp(const NzQuaternion& from, const NzQuatern
if (cosOmega > F(0.9999))
{
// Interpolation linéaire pour éviter une division par zéro
k0 = F(1.0) - interpolation;
k1 = interpolation;
}
else
{
T sinOmega = std::sqrt(F(1.0) - cosOmega*cosOmega);
T omega = std::atan2(sinOmega, cosOmega);
k0 = F(1.0) - interpolation;
k1 = interpolation;
}
else
{
T sinOmega = std::sqrt(F(1.0) - cosOmega*cosOmega);
T omega = std::atan2(sinOmega, cosOmega);
// Pour éviter deux divisions
sinOmega = F(1.0)/sinOmega;
k0 = std::sin((F(1.0) - interpolation) * omega) * sinOmega;
k1 = std::sin(interpolation*omega) * sinOmega;
}
k0 = std::sin((F(1.0) - interpolation) * omega) * sinOmega;
k1 = std::sin(interpolation*omega) * sinOmega;
}
NzQuaternion result(k0 * from.w, k0 * from.x, k0 * from.y, k0 * from.z);
return result += q*k1;
NzQuaternion result(k0 * from.w, k0 * from.x, k0 * from.y, k0 * from.z);
return result += q*k1;
}
template<typename T>

View File

@@ -34,12 +34,12 @@ class NzRay
NzVector3<T> GetPoint(T lambda) const;
//bool Intersect(const NzBoundingVolume<T>& volume, T* closestHit = nullptr, T* farthestHit = nullptr) const;
bool Intersect(const NzBox<T>& box, T* closestHit = nullptr, T* farthestHit = nullptr) const;
bool Intersect(const NzBox<T>& box, const NzMatrix4<T>& transform, T* closestHit = nullptr, T* farthestHit = nullptr) const;
//bool Intersect(const NzOrientedBox<T>& orientedBox, T* closestHit = nullptr, T* farthestHit = nullptr) const;
bool Intersect(const NzBoundingVolume<T>& volume, T* closestHit = nullptr, T* furthestHit = nullptr) const;
bool Intersect(const NzBox<T>& box, T* closestHit = nullptr, T* furthestHit = nullptr) const;
bool Intersect(const NzBox<T>& box, const NzMatrix4<T>& transform, T* closestHit = nullptr, T* furthestHit = nullptr) const;
bool Intersect(const NzOrientedBox<T>& orientedBox, T* closestHit = nullptr, T* furthestHit = nullptr) const;
bool Intersect(const NzPlane<T>& plane, T* hit = nullptr) const;
bool Intersect(const NzSphere<T>& sphere, T* closestHit = nullptr, T* farthestHit = nullptr) const;
bool Intersect(const NzSphere<T>& sphere, T* closestHit = nullptr, T* furthestHit = nullptr) const;
NzRay& MakeAxisX();
NzRay& MakeAxisY();
@@ -57,6 +57,9 @@ class NzRay
NzVector3<T> operator*(T lambda) const;
bool operator==(const NzRay& ray) const;
bool operator!=(const NzRay& ray) const;
static NzRay AxisX();
static NzRay AxisY();
static NzRay AxisZ();

View File

@@ -59,18 +59,18 @@ T NzRay<T>::ClosestPoint(const NzVector3<T>& point) const
template<typename T>
NzVector3<T> NzRay<T>::GetPoint(T lambda) const
{
return origin + lambda*direction;
return origin + lambda * direction;
}
/*
template<typename T>
bool NzRay<T>::Intersect(const NzBoundingVolume<T>& volume, T* closestHit, T* farthestHit) const
bool NzRay<T>::Intersect(const NzBoundingVolume<T>& volume, T* closestHit, T* furthestHit) const
{
switch (volume.extend)
{
case nzExtend_Finite:
{
if (Intersect(volume.aabb))
return Intersect(volume.obb, closestHit, farthestHit);
return Intersect(volume.obb, closestHit, furthestHit);
return false;
}
@@ -80,8 +80,8 @@ bool NzRay<T>::Intersect(const NzBoundingVolume<T>& volume, T* closestHit, T* fa
if (closestHit)
*closestHit = F(0.0);
if (farthestHit)
*farthestHit = std::numeric_limits<T>::infinity();
if (furthestHit)
*furthestHit = std::numeric_limits<T>::infinity();
return true;
}
@@ -93,9 +93,9 @@ bool NzRay<T>::Intersect(const NzBoundingVolume<T>& volume, T* closestHit, T* fa
NazaraError("Invalid extend type (0x" + NzString::Number(volume.extend, 16) + ')');
return false;
}
*/
template<typename T>
bool NzRay<T>::Intersect(const NzBox<T>& box, T* closestHit, T* farthestHit) const
bool NzRay<T>::Intersect(const NzBox<T>& box, T* closestHit, T* furthestHit) const
{
// http://www.gamedev.net/topic/429443-obb-ray-and-obb-plane-intersection/
T tfirst = F(0.0);
@@ -134,14 +134,14 @@ bool NzRay<T>::Intersect(const NzBox<T>& box, T* closestHit, T* farthestHit) con
if (closestHit)
*closestHit = tfirst;
if (farthestHit)
*farthestHit = tlast;
if (furthestHit)
*furthestHit = tlast;
return true;
}
template<typename T>
bool NzRay<T>::Intersect(const NzBox<T>& box, const NzMatrix4<T>& transform, T* closestHit, T* farthestHit) const
bool NzRay<T>::Intersect(const NzBox<T>& box, const NzMatrix4<T>& transform, T* closestHit, T* furthestHit) const
{
// http://www.opengl-tutorial.org/miscellaneous/clicking-on-objects/picking-with-custom-ray-obb-function/
// Intersection method from Real-Time Rendering and Essential Mathematics for Games
@@ -192,32 +192,39 @@ bool NzRay<T>::Intersect(const NzBox<T>& box, const NzMatrix4<T>& transform, T*
if (closestHit)
*closestHit = tMin;
if (farthestHit)
*farthestHit = tMax;
if (furthestHit)
*furthestHit = tMax;
return true;
}
///FIXME: Le test ci-dessous est beaucoup trop approximatif pour être vraiment utile
/// Mais le vrai problème vient certainement des OrientedBox en elles-mêmes, peut-être faut-il envisager de les refaire ?
/*
template<typename T>
bool NzRay<T>::Intersect(const NzOrientedBox<T>& orientedBox, T* closestHit, T* farthestHit) const
bool NzRay<T>::Intersect(const NzOrientedBox<T>& orientedBox, T* closestHit, T* furthestHit) const
{
NzVector3<T> width = (orientedBox.GetCorner(nzBoxCorner_NearLeftBottom) - orientedBox.GetCorner(nzBoxCorner_FarLeftBottom)).Normalize();
NzVector3<T> height = (orientedBox.GetCorner(nzBoxCorner_FarLeftTop) - orientedBox.GetCorner(nzBoxCorner_FarLeftBottom)).Normalize();
NzVector3<T> depth = (orientedBox.GetCorner(nzBoxCorner_FarRightBottom) - orientedBox.GetCorner(nzBoxCorner_FarLeftBottom)).Normalize();
NzVector3<T> corner = orientedBox.GetCorner(nzBoxCorner_FarLeftBottom);
NzVector3<T> oppositeCorner = orientedBox.GetCorner(nzBoxCorner_NearRightTop);
NzVector3<T> width = (orientedBox.GetCorner(nzBoxCorner_NearLeftBottom) - corner);
NzVector3<T> height = (orientedBox.GetCorner(nzBoxCorner_FarLeftTop) - corner);
NzVector3<T> depth = (orientedBox.GetCorner(nzBoxCorner_FarRightBottom) - corner);
// Construction de la matrice de transformation de l'OBB
NzMatrix4<T> matrix(width.x, height.x, depth.x, F(0.0),
width.y, height.y, depth.y, F(0.0),
width.z, height.z, depth.z, F(0.0),
NzMatrix4<T> matrix(width.x, height.x, depth.x, corner.x,
width.y, height.y, depth.y, corner.y,
width.z, height.z, depth.z, corner.z,
F(0.0), F(0.0), F(0.0), F(1.0));
// Test en tant qu'AABB avec une matrice de rotation
return Intersect(orientedBox.localBox, matrix, closestHit, farthestHit);
matrix.InverseAffine();
corner = matrix.Transform(corner);
oppositeCorner = matrix.Transform(oppositeCorner);
NzBox<T> tmpBox(corner, oppositeCorner);
NzRay<T> tmpRay(matrix.Transform(origin), matrix.Transform(direction));
return tmpRay.Intersect(tmpBox, closestHit, furthestHit);
}
*/
template<typename T>
bool NzRay<T>::Intersect(const NzPlane<T>& plane, T* hit) const
{
@@ -225,9 +232,9 @@ bool NzRay<T>::Intersect(const NzPlane<T>& plane, T* hit) const
if (NzNumberEquals(divisor, F(0.0)))
return false; // perpendicular
T lambda = -(plane.normal.DotProduct(origin) + plane.distance) / divisor; // The plane is ax+by+cz=d
T lambda = -(plane.normal.DotProduct(origin) - plane.distance) / divisor; // The plane is ax + by + cz = d
if (lambda < F(0.0))
return false; // Le plan est derrière le rayon
return false; // The plane is 'behind' the ray.
if (hit)
*hit = lambda;
@@ -236,7 +243,7 @@ bool NzRay<T>::Intersect(const NzPlane<T>& plane, T* hit) const
}
template<typename T>
bool NzRay<T>::Intersect(const NzSphere<T>& sphere, T* closestHit, T* farthestHit) const
bool NzRay<T>::Intersect(const NzSphere<T>& sphere, T* closestHit, T* furthestHit) const
{
NzVector3<T> sphereRay = sphere.GetPosition() - origin;
T length = sphereRay.DotProduct(direction);
@@ -251,15 +258,15 @@ bool NzRay<T>::Intersect(const NzSphere<T>& sphere, T* closestHit, T* farthestHi
return false; // if the ray is further than the radius
// Calcul des points d'intersection si besoin
if (closestHit || farthestHit)
if (closestHit || furthestHit)
{
T deltaLambda = std::sqrt(squaredRadius - squaredDistance);
if (closestHit)
*closestHit = length - deltaLambda;
if (farthestHit)
*farthestHit = length + deltaLambda;
if (furthestHit)
*furthestHit = length + deltaLambda;
}
return true;
@@ -380,6 +387,18 @@ NzVector3<T> NzRay<T>::operator*(T lambda) const
return GetPoint(lambda);
}
template<typename T>
bool NzRay<T>::operator==(const NzRay& ray) const
{
return direction == ray.direction && origin == ray.origin;
}
template<typename T>
bool NzRay<T>::operator!=(const NzRay& ray) const
{
return !operator==(ray);
}
template<typename T>
NzRay<T> NzRay<T>::AxisX()
{

View File

@@ -64,7 +64,7 @@ template<typename T>
bool NzRect<T>::Contains(const NzRect<T>& rect) const
{
return Contains(rect.x, rect.y) &&
Contains(rect.x + rect.width, rect.y + rect.height);
Contains(rect.x + rect.width, rect.y + rect.height);
}
template<typename T>
@@ -410,7 +410,7 @@ 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);
NzNumberEquals(width, rect.width) && NzNumberEquals(height, rect.height);
}
template<typename T>

View File

@@ -51,13 +51,13 @@ bool NzSphere<T>::Contains(T X, T Y, T Z) const
template<typename T>
bool NzSphere<T>::Contains(const NzBox<T>& box) const
{
if (box.GetMinimum().SquaredDistance(GetPosition()) <= radius * radius)
{
if (box.GetMaximum().SquaredDistance(GetPosition()) <= radius * radius)
return true;
}
if (box.GetMinimum().SquaredDistance(GetPosition()) <= radius * radius)
{
if (box.GetMaximum().SquaredDistance(GetPosition()) <= radius * radius)
return true;
}
return false;
return false;
}
template<typename T>
bool NzSphere<T>::Contains(const NzVector3<T>& point) const
@@ -156,7 +156,7 @@ bool NzSphere<T>::Intersect(const NzBox<T>& box) const
squaredDistance += diff*diff;
}
return squaredDistance <= radius * radius;
return squaredDistance <= radius * radius;
}
template<typename T>

View File

@@ -27,12 +27,10 @@ class NzVector2
~NzVector2() = default;
T AbsDotProduct(const NzVector2& vec) const;
T AngleBetween(const NzVector2& vec) const;
T Distance(const NzVector2& vec) const;
float Distancef(const NzVector2& vec) const;
T DotProduct(const NzVector2& vec) const;
T GetLength() const;
@@ -40,6 +38,7 @@ class NzVector2
NzVector2 GetNormal(T* length = nullptr) const;
T GetSquaredLength() const;
NzVector2& MakeUnit();
NzVector2& MakeUnitX();
NzVector2& MakeUnitY();
NzVector2& MakeZero();
@@ -89,6 +88,7 @@ class NzVector2
bool operator>=(const NzVector2& vec) const;
static NzVector2 Lerp(const NzVector2& from, const NzVector2& to, T interpolation);
static NzVector2 Unit();
static NzVector2 UnitX();
static NzVector2 UnitY();
static NzVector2 Zero();

View File

@@ -105,6 +105,12 @@ T NzVector2<T>::GetSquaredLength() const
return x*x + y*y;
}
template<typename T>
NzVector2<T>& NzVector2<T>::MakeUnit()
{
return Set(F(1.0), F(1.0));
}
template<typename T>
NzVector2<T>& NzVector2<T>::MakeUnitX()
{
@@ -129,7 +135,7 @@ NzVector2<T>& NzVector2<T>::Maximize(const NzVector2& vec)
if (vec.x > x)
x = vec.x;
if (vec.y > y)
if (vec.y > y)
y = vec.y;
return *this;
@@ -141,7 +147,7 @@ NzVector2<T>& NzVector2<T>::Minimize(const NzVector2& vec)
if (vec.x < x)
x = vec.x;
if (vec.y < y)
if (vec.y < y)
y = vec.y;
return *this;
@@ -229,7 +235,7 @@ NzVector2<T>& NzVector2<T>::Set(const NzVector4<T>& vec)
template<typename T>
T NzVector2<T>::SquaredDistance(const NzVector2& vec) const
{
return operator-(vec).GetSquaredLength();
return (*this - vec).GetSquaredLength();
}
template<typename T>
@@ -398,7 +404,7 @@ template<typename T>
bool NzVector2<T>::operator==(const NzVector2& vec) const
{
return NzNumberEquals(x, vec.x) &&
NzNumberEquals(y, vec.y);
NzNumberEquals(y, vec.y);
}
template<typename T>
@@ -443,6 +449,15 @@ NzVector2<T> NzVector2<T>::Lerp(const NzVector2& from, const NzVector2& to, T in
return NzLerp(from, to, interpolation);
}
template<typename T>
NzVector2<T> NzVector2<T>::Unit()
{
NzVector2 vector;
vector.MakeUnit();
return vector;
}
template<typename T>
NzVector2<T> NzVector2<T>::UnitX()
{

View File

@@ -28,14 +28,12 @@ class NzVector3
~NzVector3() = default;
T AbsDotProduct(const NzVector3& vec) const;
T AngleBetween(const NzVector3& vec) const;
NzVector3 CrossProduct(const NzVector3& vec) const;
T Distance(const NzVector3& vec) const;
float Distancef(const NzVector3& vec) const;
T DotProduct(const NzVector3& vec) const;
T GetLength() const;

View File

@@ -64,9 +64,9 @@ template<typename T>
T NzVector3<T>::AngleBetween(const NzVector3& vec) const
{
// sqrt(a) * sqrt(b) = sqrt(a*b)
T divisor = std::sqrt(GetSquaredLength() * vec.GetSquaredLength());
T divisor = std::sqrt(GetSquaredLength() * vec.GetSquaredLength());
#if NAZARA_MATH_SAFE
#if NAZARA_MATH_SAFE
if (NzNumberEquals(divisor, F(0.0)))
{
NzString error("Division by zero");
@@ -325,7 +325,7 @@ NzVector3<T>& NzVector3<T>::Set(const NzVector4<T>& vec)
template<typename T>
T NzVector3<T>::SquaredDistance(const NzVector3& vec) const
{
return operator-(vec).GetSquaredLength();
return (*this - vec).GetSquaredLength();
}
template<typename T>

View File

@@ -121,11 +121,11 @@ NzVector4<T>& NzVector4<T>::Maximize(const NzVector4& vec)
if (vec.y > y)
y = vec.y;
if (vec.z > z)
z = vec.z;
if (vec.z > z)
z = vec.z;
if (vec.w > w)
w = vec.w;
if (vec.w > w)
w = vec.w;
return *this;
}
@@ -139,11 +139,11 @@ NzVector4<T>& NzVector4<T>::Minimize(const NzVector4& vec)
if (vec.y < y)
y = vec.y;
if (vec.z < z)
z = vec.z;
if (vec.z < z)
z = vec.z;
if (vec.w < w)
w = vec.w;
if (vec.w < w)
w = vec.w;
return *this;
}
@@ -447,9 +447,9 @@ 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);
NzNumberEquals(y, vec.y) &&
NzNumberEquals(z, vec.z) &&
NzNumberEquals(w, vec.w);
}
template<typename T>