SIMD improvements

This commit is contained in:
THoehne 2024-08-28 14:26:12 +02:00
parent e54455ee31
commit 245f1d87c5
6 changed files with 683 additions and 488 deletions

View File

@ -31,9 +31,35 @@ namespace Phanes::Core::Math::Detail
template<RealType T, bool S>
struct compute_vec3_dec {};
// Cross product
template<RealType T, bool S>
struct compute_vec3_cross_p {};
// Magnitude
template<RealType T, bool S>
struct compute_vec3_mag {};
// dot product
template<RealType T, bool S>
struct compute_vec3_dotp {};
// set
template<RealType T, bool S>
struct compute_vec3_set {};
// clamp to cube
template<RealType T, bool S>
struct compute_vec3_clamp {};
// max
template<RealType T, bool S>
struct compute_vec3_max {};
// min
template<RealType T, bool S>
struct compute_vec3_min {};
template<RealType T>
@ -117,6 +143,13 @@ namespace Phanes::Core::Math::Detail
r.y = v1.y - s;
r.z = v1.z - s;
}
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, T s, const Phanes::Core::Math::TVector3<T, false>& v1)
{
r.x = s - v1.x;
r.y = s - v1.y;
r.z = s - v1.z;
}
};
@ -157,6 +190,13 @@ namespace Phanes::Core::Math::Detail
r.y = v1.y * s;
r.z = v1.z * s;
}
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, T s, const Phanes::Core::Math::TVector3<T, false>& v1)
{
r.x = s / v1.x;
r.y = s / v1.y;
r.z = s / v1.z;
}
};
template<RealType T>
@ -215,5 +255,69 @@ namespace Phanes::Core::Math::Detail
r.z = (v1.x * v2.y) - (v1.y * v2.x);
}
};
template<RealType T>
struct compute_vec3_mag<T, false>
{
static constexpr T map(const Phanes::Core::Math::TVector3<T, false>& v1)
{
return sqrt(v1.x * v1.x + v1.y * v1.y + v1.z * v1.z);
}
};
template<RealType T>
struct compute_vec3_dotp<T, false>
{
static constexpr T map(const Phanes::Core::Math::TVector3<T, false>& v1, const Phanes::Core::Math::TVector3<T, false>& v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
};
template<RealType T>
struct compute_vec3_set<T, false>
{
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& v1, T x, T y, T z)
{
v1.x = x;
v1.y = y;
v1.z = z;
}
};
template<RealType T>
struct compute_vec3_clamp<T, false>
{
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1, T radius)
{
r.x = Clamp(v1.x, -radius, radius);
r.y = Clamp(v1.y, -radius, radius);
r.z = Clamp(v1.z, -radius, radius);
}
};
template<RealType T>
struct compute_vec3_max<T, false>
{
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1, const Phanes::Core::Math::TVector3<T, false>& v2)
{
r.x = (v1.x > v2.x) ? v1.x : v2.x;
r.y = (v1.y > v2.y) ? v1.y : v2.y;
r.z = (v1.z > v2.z) ? v1.z : v2.z;
}
};
template<RealType T>
struct compute_vec3_min<T, false>
{
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1, const Phanes::Core::Math::TVector3<T, false>& v2)
{
r.x = (v1.x < v2.x) ? v1.x : v2.x;
r.y = (v1.y < v2.y) ? v1.y : v2.y;
r.z = (v1.z < v2.z) ? v1.z : v2.z;
}
};
}

View File

@ -32,6 +32,30 @@ namespace Phanes::Core::Math::Detail
struct compute_vec4_dec {};
// Magnitude
template<RealType T, bool S>
struct compute_vec4_mag {};
// dot product
template<RealType T, bool S>
struct compute_vec4_dotp {};
// set
template<RealType T, bool S>
struct compute_vec4_set {};
// max
template<RealType T, bool S>
struct compute_vec4_max {};
// min
template<RealType T, bool S>
struct compute_vec4_min {};
// perspective divide
template<RealType T, bool S>
struct compute_vec4_pdiv {};
template<RealType T>
struct construct_vec4<T, false>
@ -116,6 +140,14 @@ namespace Phanes::Core::Math::Detail
r.z = v1.z - s;
r.w = v1.w - s;
}
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, T s, const Phanes::Core::Math::TVector4<T, false>& v1)
{
r.x = s - v1.x;
r.y = s - v1.y;
r.z = s - v1.z;
r.w = s - v1.w;
}
};
@ -160,6 +192,14 @@ namespace Phanes::Core::Math::Detail
r.z = v1.z * s;
r.w = v1.w * s;
}
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, T s, const Phanes::Core::Math::TVector4<T, false>& v1)
{
r.x = s / v1.x;
r.y = s / v1.y;
r.z = s / v1.z;
r.w = s / v1.w;
}
};
template<RealType T>
@ -209,5 +249,74 @@ namespace Phanes::Core::Math::Detail
r.w = v1.w - 1;
}
};
template<RealType T>
struct compute_vec4_mag<T, false>
{
static constexpr T map(const Phanes::Core::Math::TVector4<T, false>& v1)
{
return sqrt(v1.x * v1.x + v1.y * v1.y + v1.z * v1.z + v1.w * v1.w);
}
};
template<RealType T>
struct compute_vec4_dotp<T, false>
{
static constexpr T map(const Phanes::Core::Math::TVector4<T, false>& v1, const Phanes::Core::Math::TVector4<T, false>& v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
}
};
template<RealType T>
struct compute_vec4_set<T, false>
{
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& v1, T x, T y, T z, T w)
{
v1.x = x;
v1.y = y;
v1.z = z;
v1.w = w;
}
};
template<RealType T>
struct compute_vec4_max<T, false>
{
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1, const Phanes::Core::Math::TVector4<T, false>& v2)
{
r.x = (v1.x > v2.x) ? v1.x : v2.x;
r.y = (v1.y > v2.y) ? v1.y : v2.y;
r.z = (v1.z > v2.z) ? v1.z : v2.z;
r.w = (v1.w > v2.w) ? v1.w : v2.w;
}
};
template<RealType T>
struct compute_vec4_min<T, false>
{
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1, const Phanes::Core::Math::TVector4<T, false>& v2)
{
r.x = (v1.x < v2.x) ? v1.x : v2.x;
r.y = (v1.y < v2.y) ? v1.y : v2.y;
r.z = (v1.z < v2.z) ? v1.z : v2.z;
r.w = (v1.w < v2.w) ? v1.w : v2.w;
}
};
template<RealType T>
struct compute_vec4_pdiv<T, false>
{
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1)
{
T _1_w = (T)1.0 / v1.w;
r.x = v1.x * _1_w;
r.y = v1.y * _1_w;
r.z = v1.z * _1_w;
r.w = (T)0.0;
}
};
}

View File

@ -91,7 +91,7 @@ namespace Phanes::Core::Math {
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool S>
inline TVector3<T, S> operator+= (TVector3<T, S>& v1, const TVector3<T, S>& v2);
inline TVector3<T, S>& operator+= (TVector3<T, S>& v1, const TVector3<T, S>& v2);
/// <summary>
/// Vector - scalar addition.
@ -102,7 +102,7 @@ namespace Phanes::Core::Math {
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool S>
inline TVector3<T, S> operator+= (TVector3<T, S>& v1, T s);
inline TVector3<T, S>& operator+= (TVector3<T, S>& v1, T s);
/// <summary>
/// Vector - scalar substraction
@ -113,7 +113,7 @@ namespace Phanes::Core::Math {
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool S>
inline TVector3<T, S> operator-= (TVector3<T, S>& v1, const TVector3<T, S>& v2);
inline TVector3<T, S>& operator-= (TVector3<T, S>& v1, const TVector3<T, S>& v2);
/// <summary>
/// Vector substraction.
@ -124,7 +124,7 @@ namespace Phanes::Core::Math {
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool S>
inline TVector3<T, S> operator-= (TVector3<T, S>& v1, T s);
inline TVector3<T, S>& operator-= (TVector3<T, S>& v1, T s);
/// <summary>
/// Componentwise multiplication
@ -135,7 +135,7 @@ namespace Phanes::Core::Math {
/// <param name="v2"></param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool S>
inline TVector3<T, S> operator*=(TVector3<T, S>& v1, const TVector3<T, S>& v2);
inline TVector3<T, S>& operator*=(TVector3<T, S>& v1, const TVector3<T, S>& v2);
/**
* Componentwise multiplication
@ -145,7 +145,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T, bool S>
inline TVector3<T, S> operator*= (TVector3<T, S>& v1, T s);
inline TVector3<T, S>& operator*= (TVector3<T, S>& v1, T s);
/// <summary>
/// Componentwise division
@ -156,7 +156,7 @@ namespace Phanes::Core::Math {
/// <param name="v2"></param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool S>
inline TVector3<T, S> operator/=(TVector3<T, S>& v1, const TVector3<T, S>& v2);
inline TVector3<T, S>& operator/=(TVector3<T, S>& v1, const TVector3<T, S>& v2);
/**
* Coponentwise division of 3D vector with floating point
@ -166,7 +166,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T, bool S>
inline TVector3<T, S> operator/= (TVector3<T, S>& v1, T s);
inline TVector3<T, S>& operator/= (TVector3<T, S>& v1, T s);
@ -194,6 +194,7 @@ namespace Phanes::Core::Math {
template<RealType T, bool S>
TVector3<T, S> operator* (const TVector3<T, S>& v1, T s);
/**
* Componentwise division
*
@ -206,6 +207,9 @@ namespace Phanes::Core::Math {
template<RealType T, bool S>
TVector3<T, S> operator/ (const TVector3<T, S>& v1, const TVector3<T, S>& v2);
template<RealType T, bool S>
TVector3<T, S> operator/ (T s, const TVector3<T, S>& v1);
/**
* Coponentwise division of 3D Vectors with floating point
@ -225,7 +229,7 @@ namespace Phanes::Core::Math {
* @param(s) floating point
* @param(v2) vector
*
* @return Resultion vector
* @return Resulting vector
*/
template<RealType T, bool S>
@ -234,21 +238,6 @@ namespace Phanes::Core::Math {
return v1 * s;
};
/**
* Coponentwise multiplication of 3D Vectors with floating point
*
* @param(s) floating point
* @param(v1) vector
*
* @return Resultion vector
*/
template<RealType T, bool S>
FORCEINLINE TVector3<T, S> operator/ (T s, const TVector3<T, S>& v1)
{
return v1 / s;
};
/**
* Coponentwise addition of floating point to 3D vector
*
@ -285,6 +274,9 @@ namespace Phanes::Core::Math {
template<RealType T, bool S>
TVector3<T, S> operator- (const TVector3<T, S>& v1, T s);
template<RealType T, bool S>
TVector3<T, S> operator- (T s, const TVector3<T, S>& v1);
/**
* Coponentwise substraction of floating point of 3D vector
*
@ -326,16 +318,16 @@ namespace Phanes::Core::Math {
inline bool operator!= (const TVector3<T, S>& v1, const TVector3<T, S>& v2);
template<RealType T, bool S>
TVector3<T, S>& operator++(TVector3<T, S>& v1);
TVector3<T, S> operator++(TVector3<T, S>& v1);
template<RealType T, bool S>
TVector3<T, S>& operator--(TVector3<T, S>& v1);
TVector3<T, S> operator--(TVector3<T, S>& v1);
template<RealType T, bool S>
TVector3<T, S>& operator++(TVector3<T, S>& v1, int);
TVector3<T, S> operator++(TVector3<T, S>& v1, int);
template<RealType T, bool S>
TVector3<T, S>& operator--(TVector3<T, S>& v1, int);
TVector3<T, S> operator--(TVector3<T, S>& v1, int);
// ==================================== //
// TVector3 function implementation //
@ -349,18 +341,15 @@ namespace Phanes::Core::Math {
* @return Magnitude of vector
*/
template<RealType T>
inline T Magnitude(const TVector3<T, false>& v1)
{
return sqrt(DotP(v1, v1));
}
template<RealType T, bool S>
inline T Magnitude(const TVector3<T, S>& v1);
/**
* @see [FUNC]Magnitude
*/
template<RealType T>
FORCEINLINE T Length(const TVector3<T, false>& v1) { return Magnitude(v1); };
template<RealType T, bool S>
FORCEINLINE T Length(const TVector3<T, S>& v1) { return Magnitude(v1); };
/**
* Gets square magnitude of vector
@ -370,18 +359,15 @@ namespace Phanes::Core::Math {
* @return Square magnitude of vector
*/
template<RealType T>
inline T SqrMagnitude(const TVector3<T, false>& v1)
{
return DotP(v1, v1);
}
template<RealType T, bool S>
inline T SqrMagnitude(const TVector3<T, S>& v1);
/**
* @see SqrMagnitude
*/
template<RealType T>
FORCEINLINE T SqrLength(const TVector3<T, false>& v1)
template<RealType T, bool S>
FORCEINLINE T SqrLength(const TVector3<T, S>& v1)
{
return SqrMagnitude(v1);
}
@ -394,8 +380,8 @@ namespace Phanes::Core::Math {
* @note Result is stored in v1
*/
template<RealType T>
TVector3<T, false> NormalizeV(TVector3<T, false>& v1)
template<RealType T, bool S>
TVector3<T, S>& NormalizeV(TVector3<T, S>& v1)
{
float vecNorm = Magnitude(v1);
v1 /= (vecNorm < P_FLT_INAC) ? (T)1.0 : vecNorm;
@ -411,8 +397,8 @@ namespace Phanes::Core::Math {
* @note Does not test for zero vector
*/
template<RealType T>
TVector3<T, false> UnsafeNormalizeV(TVector3<T, false>& v1)
template<RealType T, bool S>
TVector3<T, S>& UnsafeNormalizeV(TVector3<T, S>& v1)
{
v1 /= Magnitude(v1);
@ -426,8 +412,8 @@ namespace Phanes::Core::Math {
* @param(normal) Normal of surface
*/
template<RealType T>
TVector3<T, false> ReflectV(TVector3<T, false>& v1, const TVector3<T, false>& normal)
template<RealType T, bool S>
TVector3<T, S>& ReflectV(TVector3<T, S>& v1, const TVector3<T, S>& normal)
{
v1 = ((T)2.0 * DotP(v1, normal) * normal) - v1;
@ -443,8 +429,8 @@ namespace Phanes::Core::Math {
* @return Angle between vectors
*/
template<RealType T>
T Angle(const TVector3<T, false>& v1, const TVector3<T, false>& v2)
template<RealType T, bool S>
T Angle(const TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
return acos(DotP(v1, v2) / (Magnitude(v1) * Magnitude(v2)));
}
@ -458,11 +444,8 @@ namespace Phanes::Core::Math {
* @return Dot product of vectors
*/
template<RealType T>
inline T DotP(const TVector3<T, false>& v1, const TVector3<T, false>& v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
template<RealType T, bool S>
inline T DotP(const TVector3<T, S>& v1, const TVector3<T, S>& v2);
/**
* Orthogonalizes three vectors.
@ -472,8 +455,8 @@ namespace Phanes::Core::Math {
* @param(v3) Vector two
*/
template<RealType T>
void Orthogonalize(TVector3<T, false>& v1, TVector3<T, false>& v2, TVector3<T, false>& v3)
template<RealType T, bool S>
void Orthogonalize(TVector3<T, S>& v1, TVector3<T, S>& v2, TVector3<T, S>& v3)
{
Set(v2, Reject(v2, v1));
Set(v3, Reject(Reject(v3, v1), v2));
@ -489,8 +472,8 @@ namespace Phanes::Core::Math {
* @note Usefull for making sure coordinate axis are still orthogonal.
*/
template<RealType T>
void OrthoNormalize(TVector3<T, false>& v1, TVector3<T, false>& v2, TVector3<T, false>& v3)
template<RealType T, bool S>
void OrthoNormalize(TVector3<T, S>& v1, TVector3<T, S>& v2, TVector3<T, S>& v3)
{
Set(v2, Reject(v2, v1));
Set(v3, Reject(Reject(v3, v1), v2));
@ -511,8 +494,8 @@ namespace Phanes::Core::Math {
* @return True if equal, false if not.
*/
template<RealType T>
inline bool Equals(const TVector3<T, false>& v1, const TVector3<T, false>& v2, T threshold = P_FLT_INAC)
template<RealType T, bool S>
inline bool Equals(const TVector3<T, S>& v1, const TVector3<T, S>& v2, T threshold = P_FLT_INAC)
{
return (abs(v1.x - v2.x) < threshold && abs(v1.y - v2.y) < threshold && abs(v1.z - v2.z) < threshold);
}
@ -523,8 +506,8 @@ namespace Phanes::Core::Math {
* @param(v1) Vector
*/
template<RealType T>
TVector3<T, false> PerspectiveDivideV(TVector3<T, false>& v1)
template<RealType T, bool S>
TVector3<T, S>& PerspectiveDivideV(TVector3<T, S>& v1)
{
float _z = (T)1.0 / v1.z;
v1.x *= _z;
@ -544,7 +527,7 @@ namespace Phanes::Core::Math {
/// <returns>Copy of v1.</returns>
template<RealType T, bool S>
TVector3<T, S> CrossPV(TVector3<T, S>& v1, const TVector3<T, S>& v2);
TVector3<T, S>& CrossPV(TVector3<T, S>& v1, const TVector3<T, S>& v2);
/**
* Gets the componentwise max of both vectors.
@ -555,15 +538,8 @@ namespace Phanes::Core::Math {
* @note result is stored in v1.
*/
template<RealType T>
TVector3<T, false> MaxV(TVector3<T, false>& v1, const TVector3<T, false>& v2)
{
v1.x = Max(v1.x, v2.x);
v1.y = Max(v1.y, v2.y);
v1.z = Max(v1.z, v2.z);
return v1;
}
template<RealType T, bool S>
TVector3<T, S>& MaxV(TVector3<T, S>& v1, const TVector3<T, S>& v2);
/**
* Gets the componentwise min of both vectors.
@ -574,15 +550,8 @@ namespace Phanes::Core::Math {
* @note result is stored in v1.
*/
template<RealType T>
TVector3<T, false> MinV(TVector3<T, false>& v1, const TVector3<T, false>& v2)
{
v1.x = Min(v1.x, v2.x);
v1.y = Min(v1.y, v2.y);
v1.z = Min(v1.z, v2.z);
return v1;
}
template<RealType T, bool S>
TVector3<T, S>& MinV(TVector3<T, S>& v1, const TVector3<T, S>& v2);
/**
* Gets reversed vector.
@ -592,33 +561,10 @@ namespace Phanes::Core::Math {
* @note result is stored in v1.
*/
template<RealType T>
TVector3<T, false> NegateV(TVector3<T, false>& v1)
template<RealType T, bool S>
TVector3<T, S>& NegateV(TVector3<T, S>& v1)
{
v1.x = -v1.x;
v1.y = -v1.y;
v1.z = -v1.z;
return v1;
}
/**
* Performes componentwise multiplication of two vectors.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @note result is stored in v1.
*/
template<RealType T>
TVector3<T, false> ScaleV(TVector3<T, false>& v1, const TVector3<T, false>& v2)
{
v1.x *= v2.x;
v1.y *= v2.y;
v1.z *= v2.z;
return v1;
return (v1 = (T)0.0 - v1);
}
@ -631,8 +577,8 @@ namespace Phanes::Core::Math {
* @note result is stored in v1.
*/
template<RealType T>
TVector3<T, false> ProjectV(TVector3<T, false>& v1, const TVector3<T, false>& v2)
template<RealType T, bool S>
TVector3<T, S>& ProjectV(TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
float x = DotP(v1, v2) / DotP(v2, v2);
v1 = x * v2;
@ -649,8 +595,8 @@ namespace Phanes::Core::Math {
* @note result is stored in v1.
*/
template<RealType T>
TVector3<T, false> RejectV(TVector3<T, false>& v1, const TVector3<T, false>& v2)
template<RealType T, bool S>
TVector3<T, S>& RejectV(TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
float x = DotP(v1, v2) / DotP(v2, v2);
v1 -= x * v2;
@ -665,8 +611,8 @@ namespace Phanes::Core::Math {
* @param(v2) Vector to copy
*/
template<RealType T>
TVector3<T, false> Set(TVector3<T, false>& v1, const TVector3<T, false>& v2)
template<RealType T, bool S>
TVector3<T, S>& Set(TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
v1 = v2;
@ -682,15 +628,8 @@ namespace Phanes::Core::Math {
* @param(z) Z component
*/
template<RealType T>
TVector3<T, false> Set(TVector3<T, false>& v1, T x, T y, T z)
{
v1.x = x;
v1.y = y;
v1.z = z;
return v1;
}
template<RealType T, bool S>
TVector3<T, S>& Set(TVector3<T, S>& v1, T x, T y, T z);
/**
* Clamps vector to a range of magnitudes.
@ -702,8 +641,8 @@ namespace Phanes::Core::Math {
* @note Result is stored in v1
*/
template<RealType T>
TVector3<T, false> ClampToMagnitudeV(TVector3<T, false>& v1, T min, T max)
template<RealType T, bool S>
TVector3<T, S>& ClampToMagnitudeV(TVector3<T, S>& v1, T min, T max)
{
T magnitude = Magnitude(v1);
@ -722,14 +661,10 @@ namespace Phanes::Core::Math {
* @note Result is stored in v1
*/
template<RealType T>
TVector3<T, false> CompInverseV(TVector3<T, false>& v1)
template<RealType T, bool S>
TVector3<T, S>& CompInverseV(TVector3<T, S>& v1)
{
v1.x = 1.0f / v1.x;
v1.y = 1.0f / v1.y;
v1.z = 1.0f / v1.z;
return v1;
return (v1 = (T)1.0 / v1);
}
@ -742,15 +677,8 @@ namespace Phanes::Core::Math {
* @note result is stored in v1.
*/
template<RealType T>
TVector3<T, false> ClampToCubeV(TVector3<T, false> v1, T cubeRadius)
{
v1.x = Clamp(v1.x, -cubeRadius, cubeRadius);
v1.y = Clamp(v1.y, -cubeRadius, cubeRadius);
v1.z = Clamp(v1.z, -cubeRadius, cubeRadius);
return v1;
};
template<RealType T, bool S>
TVector3<T, S>& ClampToCubeV(TVector3<T, S> v1, T cubeRadius);
/**
* Rotates vector around axis
@ -761,8 +689,8 @@ namespace Phanes::Core::Math {
* @note result is stored in v1.
*/
template<RealType T>
TVector3<T, false> RotateAroundAxisV(TVector3<T, false>& v1, const TVector3<T, false>& axisNormal, T angle)
template<RealType T, bool S>
TVector3<T, S>& RotateAroundAxisV(TVector3<T, S>& v1, const TVector3<T, S>& axisNormal, T angle)
{
T sinAngle = sin(angle);
T cosAngle = cos(angle);
@ -779,8 +707,8 @@ namespace Phanes::Core::Math {
* @note It's faster to use operator* or operator*= for naturaly normalized vectors.
*/
template<RealType T>
TVector3<T, false> ScaleToMagnitudeV(TVector3<T, false>& v1, T magnitude)
template<RealType T, bool S>
TVector3<T, S>& ScaleToMagnitudeV(TVector3<T, S>& v1, T magnitude)
{
NormalizeV(v1);
v1 *= magnitude;
@ -793,8 +721,8 @@ namespace Phanes::Core::Math {
* @param(v1) Vector one
*/
template<RealType T>
TVector3<T, false> SignVectorV(TVector3<T, false>& v1)
template<RealType T, bool S>
TVector3<T, S>& SignVectorV(TVector3<T, S>& v1)
{
v1.x = (v1.x >= (T)0.0) ? (T)1.0 : (T)-1;
v1.y = (v1.y >= (T)0.0) ? (T)1.0 : (T)-1;
@ -814,8 +742,8 @@ namespace Phanes::Core::Math {
* @return Vector triple product
*/
template<RealType T>
T ScalarTriple(const TVector3<T, false>& v1, const TVector3<T, false>& v2, const TVector3<T, false>& v3)
template<RealType T, bool S>
T ScalarTriple(const TVector3<T, S>& v1, const TVector3<T, S>& v2, const TVector3<T, S>& v3)
{
return DotP(CrossP(v1, v2), v3);
}
@ -830,8 +758,8 @@ namespace Phanes::Core::Math {
* @note Simply omits acos of angle.
*/
template<RealType T>
T CosineAngle(const TVector3<T, false>& v1, const TVector3<T, false>& v2)
template<RealType T, bool S>
T CosineAngle(const TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
return DotP(v1, v2) / ((Magnitude(v1) * Magnitude(v2)));
}
@ -846,8 +774,8 @@ namespace Phanes::Core::Math {
* @note result is stored in v1
*/
template<RealType T>
TVector3<T, false> VectorTripleV(TVector3<T, false>& v1, const TVector3<T, false>& v2, const TVector3<T, false>& v3)
template<RealType T, bool S>
TVector3<T, S>& VectorTripleV(TVector3<T, S>& v1, const TVector3<T, S>& v2, const TVector3<T, S>& v3)
{
CrossPV(CrossPV(v1, v2), v3);
@ -864,8 +792,8 @@ namespace Phanes::Core::Math {
* @return True if perpendicular, false if not.
*/
template<RealType T>
inline bool IsPerpendicular(const TVector3<T, false>& v1, const TVector3<T, false>& v2, T threshold = P_FLT_INAC)
template<RealType T, bool S>
inline bool IsPerpendicular(const TVector3<T, S>& v1, const TVector3<T, S>& v2, T threshold = P_FLT_INAC)
{
return (abs(DotP(v1, v2)) < threshold);
}
@ -880,8 +808,8 @@ namespace Phanes::Core::Math {
* @return True if parallel, false if not.
*/
template<RealType T>
inline bool IsParallel(const TVector3<T, false>& v1, const TVector3<T, false>& v2, T threshold = 1.0f - P_FLT_INAC)
template<RealType T, bool S>
inline bool IsParallel(const TVector3<T, S>& v1, const TVector3<T, S>& v2, T threshold = 1.0f - P_FLT_INAC)
{
return (abs(DotP(v1, v2)) > threshold);
}
@ -896,8 +824,8 @@ namespace Phanes::Core::Math {
* @return True if coincident, false if not.
*/
template<RealType T>
inline bool IsCoincident(const TVector3<T, false>& v1, const TVector3<T, false>& v2, T threshold = 1.0f - P_FLT_INAC)
template<RealType T, bool S>
inline bool IsCoincident(const TVector3<T, S>& v1, const TVector3<T, S>& v2, T threshold = 1.0f - P_FLT_INAC)
{
return (DotP(v1, v2) > threshold);
}
@ -911,8 +839,8 @@ namespace Phanes::Core::Math {
* @return True if unit vector, false if not.
*/
template<RealType T>
inline bool IsNormalized(const TVector3<T, false>& v1, T threshold = P_FLT_INAC)
template<RealType T, bool S>
inline bool IsNormalized(const TVector3<T, S>& v1, T threshold = P_FLT_INAC)
{
return (SqrMagnitude(v1) - 1 < threshold);
}
@ -928,24 +856,12 @@ namespace Phanes::Core::Math {
* @return True if coplanar, false if not.
*/
template<RealType T>
inline bool IsCoplanar(const TVector3<T, false>& v1, const TVector3<T, false>& v2, const TVector3<T, false>& v3, T threshold = P_FLT_INAC)
template<RealType T, bool S>
inline bool IsCoplanar(const TVector3<T, S>& v1, const TVector3<T, S>& v2, const TVector3<T, S>& v3, T threshold = P_FLT_INAC)
{
return (ScalarTriple(v1, v2, v3) < threshold);
}
/**
* Gets outer product of to vectors.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Resulting matrix
*/
//
//Matrix3<T> OuterProduct(const TVector3<T, false>& v1, const TVector3<T, false>& v2);
// ============ //
// WITH RETURN: //
// ============ //
@ -958,8 +874,8 @@ namespace Phanes::Core::Math {
* @return Normalized vector
*/
template<RealType T>
TVector3<T, false> Normalize(const TVector3<T, false>& v1)
template<RealType T, bool S>
TVector3<T, S> Normalize(const TVector3<T, S>& v1)
{
float vecNorm = Magnitude(v1);
return (vecNorm < P_FLT_INAC) ? v1 : v1 / vecNorm;
@ -973,8 +889,8 @@ namespace Phanes::Core::Math {
* @note Does not test for zero vector
*/
template<RealType T>
TVector3<T, false> UnsafeNormalize(const TVector3<T, false>& v1)
template<RealType T, bool S>
TVector3<T, S> UnsafeNormalize(const TVector3<T, S>& v1)
{
return v1 / Magnitude(v1);
}
@ -988,8 +904,8 @@ namespace Phanes::Core::Math {
* @return Vector with signs a components.
*/
template<RealType T>
TVector3<T, false> SignVector(const TVector3<T, false>& v1)
template<RealType T, bool S>
TVector3<T, S> SignVector(const TVector3<T, S>& v1)
{
return TVector3<T, false>((v1.x >= (T)0) ? (T)1 : (T)-1,
(v1.y >= (T)0) ? (T)1 : (T)-1,
@ -1005,8 +921,8 @@ namespace Phanes::Core::Math {
* @return Reflected vector
*/
template<RealType T>
TVector3<T, false> Reflect(const TVector3<T, false>& v1, const TVector3<T, false>& normal)
template<RealType T, bool S>
TVector3<T, S> Reflect(const TVector3<T, S>& v1, const TVector3<T, S>& normal)
{
return (2 * DotP(v1, normal) * normal) - v1;
}
@ -1020,8 +936,8 @@ namespace Phanes::Core::Math {
* @return Perspective divided vector
*/
template<RealType T>
TVector3<T, false> PerspectiveDivide(const TVector3<T, false>& v1)
template<RealType T, bool S>
TVector3<T, S> PerspectiveDivide(const TVector3<T, S>& v1)
{
float _z = (T)1.0 / v1.z;
return TVector3<T, false>(v1.x * _z, v1.y * _z, (T)0.0);
@ -1049,8 +965,8 @@ namespace Phanes::Core::Math {
* @return Cross product of v1 and v2
*/
template<RealType T>
TVector3<T, false> Lerp(const TVector3<T, false>& start, const TVector3<T, false>& dest, T t)
template<RealType T, bool S>
TVector3<T, S> Lerp(const TVector3<T, S>& start, const TVector3<T, S>& dest, T t)
{
t = Clamp(t, (T)0.0, (T)1.0);
return ((1 - t) * start) + (t * dest);
@ -1067,10 +983,10 @@ namespace Phanes::Core::Math {
* @note Does not clamp t between 0.0 and 1.0.
*/
template<RealType T>
TVector3<T, false> LerpUnclamped(const TVector3<T, false>& start, const TVector3<T, false>& dest, T t)
template<RealType T, bool S>
TVector3<T, S> LerpUnclamped(const TVector3<T, S>& start, const TVector3<T, S>& dest, T t)
{
return (1 - t) * start + t * dest;
return (((T)1.0 - t) * start) + (t * dest);
}
/**
@ -1082,13 +998,8 @@ namespace Phanes::Core::Math {
* @return Vector of componentwise max
*/
template<RealType T>
TVector3<T, false> Max(const TVector3<T, false>& v1, const TVector3<T, false>& v2)
{
return TVector3<T, false>((v1.x > v2.x) ? v1.x : v2.x,
(v1.y > v2.y) ? v1.y : v2.y,
(v1.z > v2.z) ? v1.z : v2.z);
}
template<RealType T, bool S>
TVector3<T, S> Max(const TVector3<T, S>& v1, const TVector3<T, S>& v2);
/**
* Creates a new Vector by the componentwise min of both vectors
@ -1099,13 +1010,8 @@ namespace Phanes::Core::Math {
* @return Vector of componentwise min
*/
template<RealType T>
TVector3<T, false> Min(const TVector3<T, false>& v1, const TVector3<T, false>& v2)
{
return TVector3<T, false>((v1.x < v2.x) ? v1.x : v2.x,
(v1.y < v2.y) ? v1.y : v2.y,
(v1.z < v2.z) ? v1.z : v2.z);
}
template<RealType T, bool S>
TVector3<T, S> Min(const TVector3<T, S>& v1, const TVector3<T, S>& v2);
/**
* Gets reversed vector.
@ -1115,25 +1021,10 @@ namespace Phanes::Core::Math {
* @note result is stored in v1.
*/
template<RealType T>
TVector3<T, false> Negate(const TVector3<T, false>& v1)
template<RealType T, bool S>
TVector3<T, S> Negate(const TVector3<T, S>& v1)
{
return TVector3<T, false>(-v1.x, -v1.y, -v1.z);
}
/**
* Multiplies vector componentwise.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Vector with componentwise products
*/
template<RealType T>
TVector3<T, false> Scale(const TVector3<T, false>& v1, const TVector3<T, false>& v2)
{
return TVector3<T, false>(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
return (T)0.0 - v1;
}
/**
@ -1146,8 +1037,8 @@ namespace Phanes::Core::Math {
* @return Clamped vector
*/
template<RealType T>
TVector3<T, false> ClampToMagnitude(const TVector3<T, false>& v1, T min, T max)
template<RealType T, bool S>
TVector3<T, S> ClampToMagnitude(const TVector3<T, S>& v1, T min, T max)
{
T magnitude = Magnitude(v1);
@ -1167,15 +1058,8 @@ namespace Phanes::Core::Math {
* @result Vector clamped in cube.
*/
template<RealType T>
TVector3<T, false> ClampToCube(const TVector3<T, false>& v1, T cubeRadius)
{
return TVector3<T, false>(
Clamp(v1.x, -cubeRadius, cubeRadius),
Clamp(v1.y, -cubeRadius, cubeRadius),
Clamp(v1.z, -cubeRadius, cubeRadius)
);
};
template<RealType T, bool S>
TVector3<T, S> ClampToCube(const TVector3<T, S>& v1, T cubeRadius);
/**
* Scales vector two specific magnitude.
@ -1185,8 +1069,8 @@ namespace Phanes::Core::Math {
* @note It's faster to use operator* or operator*= for naturaly normalized vectors.
*/
template<RealType T>
TVector3<T, false> ScaleToMagnitude(const TVector3<T, false>& v1, T magnitude)
template<RealType T, bool S>
TVector3<T, S> ScaleToMagnitude(const TVector3<T, S>& v1, T magnitude)
{
return Normalize(v1) * magnitude;
}
@ -1199,10 +1083,10 @@ namespace Phanes::Core::Math {
* @result Vector with inverted components.
*/
template<RealType T>
TVector3<T, false> CompInverse(const TVector3<T, false>& v1)
template<RealType T, bool S>
TVector3<T, S> CompInverse(const TVector3<T, S>& v1)
{
return TVector3<T, false>((T)1.0f / v1.x, (T)1.0f / v1.y, (T)1.0f / v1.z);
return (T)1.0 / v1;
}
/**
@ -1215,8 +1099,8 @@ namespace Phanes::Core::Math {
* @note Calculates vector rotation with Rodrigues-Rotation
*/
template<RealType T>
TVector3<T, false> RotateAroundAxis(const TVector3<T, false>& v1, const TVector3<T, false>& axisNormal, T angle)
template<RealType T, bool S>
TVector3<T, S> RotateAroundAxis(const TVector3<T, S>& v1, const TVector3<T, S>& axisNormal, T angle)
{
T sinAngle = sin(angle);
T cosAngle = cos(angle);
@ -1234,8 +1118,8 @@ namespace Phanes::Core::Math {
* @return Vector triple product
*/
template<RealType T>
TVector3<T, false> VectorTriple(const TVector3<T, false>& v1, const TVector3<T, false>& v2, const TVector3<T, false>& v3)
template<RealType T, bool S>
TVector3<T, S> VectorTriple(const TVector3<T, S>& v1, const TVector3<T, S>& v2, const TVector3<T, S>& v3)
{
return CrossP(CrossP(v1, v2), v3);
}
@ -1249,8 +1133,8 @@ namespace Phanes::Core::Math {
* @return Projected vector
*/
template<RealType T>
TVector3<T, false> Project(const TVector3<T, false>& v1, const TVector3<T, false>& v2)
template<RealType T, bool S>
TVector3<T, S> Project(const TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
return (DotP(v1, v2) / DotP(v2, v2)) * v2;
}
@ -1264,8 +1148,8 @@ namespace Phanes::Core::Math {
* @return Rejected vector
*/
template<RealType T>
TVector3<T, false> Reject(const TVector3<T, false>& v1, const TVector3<T, false>& v2)
template<RealType T, bool S>
TVector3<T, S> Reject(const TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
return v1 - (DotP(v1, v2) / DotP(v2, v2)) * v2;
}
@ -1280,8 +1164,8 @@ namespace Phanes::Core::Math {
* @return Interpolated unit vector
*/
template<RealType T>
TVector3<T, false> Slerp(const TVector3<T, false>& v1, const TVector3<T, false>& v2, T t) {};
template<RealType T, bool S>
TVector3<T, S> Slerp(const TVector3<T, S>& v1, const TVector3<T, S>& v2, T t) {};
/**
* Interpolate vector v1 to desitnation v2 using v1 constant s. The magnitude of the vector stays the same throughout the interpolation.
@ -1294,8 +1178,8 @@ namespace Phanes::Core::Math {
* @note Does not clamp s between 0.0 and 1.0.
*/
template<RealType T>
TVector3<T, false> SlerpUnclamped(const TVector3<T, false>& v1, const TVector3<T, false>& v2, T t) {};
template<RealType T, bool S>
TVector3<T, S> SlerpUnclamped(const TVector3<T, S>& v1, const TVector3<T, S>& v2, T t) {};
} // phanes

View File

@ -45,56 +45,56 @@ namespace Phanes::Core::Math
template<RealType T, bool S>
TVector3<T, S> operator+=(TVector3<T, S>& v1, const TVector3<T, S>& v2)
TVector3<T, S>& operator+=(TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
Detail::compute_vec3_add<T, S>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool S>
TVector3<T, S> operator+=(TVector3<T, S>& v1, T s)
TVector3<T, S>& operator+=(TVector3<T, S>& v1, T s)
{
Detail::compute_vec3_add<T, S>::map(v1, v1, s);
return v1;
}
template<RealType T, bool S>
TVector3<T, S> operator-=(TVector3<T, S>& v1, const TVector3<T, S>& v2)
TVector3<T, S>& operator-=(TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
Detail::compute_vec3_sub<T, S>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool S>
TVector3<T, S> operator-=(TVector3<T, S>& v1, T s)
TVector3<T, S>& operator-=(TVector3<T, S>& v1, T s)
{
Detail::compute_vec3_sub<T, S>::map(v1, v1, s);
return v1;
}
template<RealType T, bool S>
TVector3<T, S> operator*=(TVector3<T, S>& v1, const TVector3<T, S>& v2)
TVector3<T, S>& operator*=(TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
Detail::compute_vec3_mul<T, S>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool S>
TVector3<T, S> operator*=(TVector3<T, S>& v1, T s)
TVector3<T, S>& operator*=(TVector3<T, S>& v1, T s)
{
Detail::compute_vec3_mul<T, S>::map(v1, v1, s);
return v1;
}
template<RealType T, bool S>
TVector3<T, S> operator/=(TVector3<T, S>& v1, const TVector3<T, S>& v2)
TVector3<T, S>& operator/=(TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
Detail::compute_vec3_div<T, S>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool S>
TVector3<T, S> operator/=(TVector3<T, S>& v1, T s)
TVector3<T, S>& operator/=(TVector3<T, S>& v1, T s)
{
Detail::compute_vec3_div<T, S>::map(v1, v1, s);
return v1;
@ -132,6 +132,14 @@ namespace Phanes::Core::Math
return r;
}
template<RealType T, bool S>
TVector3<T, S> operator-(T s, const TVector3<T, S>& v1)
{
TVector3<T, S> r;
Detail::compute_vec3_sub<T, S>::map(r, s, v1);
return r;
}
template<RealType T, bool S>
TVector3<T, S> operator*(const TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
@ -164,6 +172,14 @@ namespace Phanes::Core::Math
return r;
}
template<RealType T, bool S>
TVector3<T, S> operator/(T s, const TVector3<T, S>& v1)
{
TVector3<T, S> r;
Detail::compute_vec3_div<T, S>::map(r, s, v1);
return r;
}
// Comparision
template<RealType T, bool S>
@ -221,10 +237,78 @@ namespace Phanes::Core::Math
}
template<RealType T, bool S>
TVector3<T, S> CrossPV(TVector3<T, S>& v1, const TVector3<T, S>& v2)
TVector3<T, S>& CrossPV(TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
Detail::compute_vec3_cross_p<T, S>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool S>
inline T Magnitude(const TVector3<T, S>& v1)
{
return Detail::compute_vec3_mag<T, S>::map(v1);
}
template<RealType T, bool S>
inline T SqrMagnitude(const TVector3<T, S>& v1)
{
return Detail::compute_vec3_dotp<T, S>::map(v1, v1);
}
template<RealType T, bool S>
inline T DotP(const TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
return Detail::compute_vec3_dotp<T, S>::map(v1, v2);
}
template<RealType T, bool S>
TVector3<T, S>& MaxV(TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
Detail::compute_vec3_max<T, S>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool S>
TVector3<T, S> Max(TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
TVector3<T, S> r;
Detail::compute_vec3_max<T, S>::map(r, v1, v2);
return r;
}
template<RealType T, bool S>
TVector3<T, S>& MinV(TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
Detail::compute_vec3_min<T, S>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool S>
TVector3<T, S> Min(TVector3<T, S>& v1, const TVector3<T, S>& v2)
{
TVector3<T, S> r;
Detail::compute_vec3_min<T, S>::map(r, v1, v2);
return r;
}
template<RealType T, bool S>
TVector3<T, S>& Set(TVector3<T, S>& v1, T x, T y, T z)
{
Detail::compute_vec3_set<T, S>::map(v1, x, y, z);
}
template<RealType T, bool S>
TVector3<T, S>& ClampToCubeV(TVector3<T, S> v1, T cubeRadius)
{
Detail::compute_vec3_clamp<T, S>::map(v1, v1, cubeRadius);
return v1;
}
template<RealType T, bool S>
TVector3<T, S> ClampToCube(const TVector3<T, S>& v1, T cubeRadius)
{
TVector3<T, S> r;
Detail::compute_vec3_clamp<T, S>::map(r, v1, cubeRadius);
return r;
}
}

View File

@ -17,7 +17,7 @@ namespace Phanes::Core::Math
/// 4D Vector defined with x, y, z, w.
/// Alignment allows for possible simd optimization.
template<RealType T, bool IsAligned = false>
template<RealType T, bool S = false>
struct TVector4
{
public:
@ -51,8 +51,8 @@ namespace Phanes::Core::Math
/// </summary>
union
{
typename SIMD::Storage<4, Real, SIMD::use_simd<T, 4, IsAligned>::value>::type comp;
typename SIMD::Storage<4, Real, SIMD::use_simd<T, 4, IsAligned>::value>::type data;
typename SIMD::Storage<4, Real, SIMD::use_simd<T, 4, S>::value>::type comp;
typename SIMD::Storage<4, Real, SIMD::use_simd<T, 4, S>::value>::type data;
};
};
@ -61,7 +61,7 @@ namespace Phanes::Core::Math
TVector4() = default;
/// Copy constructor
TVector4(const TVector4<Real, IsAligned>& v);
TVector4(const TVector4<Real, S>& v);
/// <summary>
/// Construct vector from one scalar.
@ -86,7 +86,7 @@ namespace Phanes::Core::Math
/// </summary>
/// <param name="v1">TVector2 one</param>
/// <param name="v2">TVector2 two</param>
TVector4(const TVector2<Real, IsAligned>& v1, const TVector2<Real, IsAligned>& v2);
TVector4(const TVector2<Real, S>& v1, const TVector2<Real, S>& v2);
/// <summary>
/// Construct vector from array of components
@ -110,8 +110,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator+= (TVector4<T, A>& v1, const TVector4<T, A>& v2);
template<RealType T, bool S>
TVector4<T, S>& operator+= (TVector4<T, S>& v1, const TVector4<T, S>& v2);
/// <summary>
/// Vector - scalar addition.
@ -121,8 +121,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator+= (TVector4<T, A>& v1, T s);
template<RealType T, bool S>
TVector4<T, S>& operator+= (TVector4<T, S>& v1, T s);
/// <summary>
/// Vector substraction.
@ -132,8 +132,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator-= (TVector4<T, A>& v1, const TVector4<T, A>& v2);
template<RealType T, bool S>
TVector4<T, S>& operator-= (TVector4<T, S>& v1, const TVector4<T, S>& v2);
/// <summary>
/// Vector - scalar substraction.
@ -143,8 +143,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator-= (TVector4<T, A>& v1, T s);
template<RealType T, bool S>
TVector4<T, S>& operator-= (TVector4<T, S>& v1, T s);
/// <summary>
/// Vector - scalar multiplication.
@ -154,8 +154,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator*= (TVector4<T, A>& v1, T s);
template<RealType T, bool S>
TVector4<T, S>& operator*= (TVector4<T, S>& v1, T s);
/// <summary>
/// Scale vector by another vector componentwise.
@ -165,8 +165,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator*= (TVector4<T, A>& v1, const TVector4<T, A>& v2);
template<RealType T, bool S>
TVector4<T, S>& operator*= (TVector4<T, S>& v1, const TVector4<T, S>& v2);
/// <summary>
/// Vector - scalar division.
@ -176,8 +176,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator/= (TVector4<T, A>& v1, T s);
template<RealType T, bool S>
TVector4<T, S>& operator/= (TVector4<T, S>& v1, T s);
/// <summary>
/// Coponentwise vector division.
@ -187,8 +187,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator/= (TVector4<T, A>& v1, const TVector4<T, A>& v2);
template<RealType T, bool S>
TVector4<T, S>& operator/= (TVector4<T, S>& v1, const TVector4<T, S>& v2);
@ -202,8 +202,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator+ (const TVector4<T, A>& v1, const TVector4<T, A>& v2);
template<RealType T, bool S>
TVector4<T, S> operator+ (const TVector4<T, S>& v1, const TVector4<T, S>& v2);
/// <summary>
/// Vector - scalar addition.
@ -213,8 +213,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator+ (const TVector4<T, A>& v1, T s);
template<RealType T, bool S>
TVector4<T, S> operator+ (const TVector4<T, S>& v1, T s);
/// <summary>
/// Vector substraction.
@ -224,8 +224,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator- (const TVector4<T, A>& v1, const TVector4<T, A>& v2);
template<RealType T, bool S>
TVector4<T, S> operator- (const TVector4<T, S>& v1, const TVector4<T, S>& v2);
/// <summary>
/// Vector - scalar substraction.
@ -235,8 +235,11 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator- (const TVector4<T, A>& v1, T s);
template<RealType T, bool S>
TVector4<T, S> operator- (const TVector4<T, S>& v1, T s);
template<RealType T, bool S>
TVector4<T, S> operator- (T s, const TVector4<T, S>& v1);
/// <summary>
/// Vector - scalar multiplication.
@ -246,11 +249,11 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator* (const TVector4<T, A>& v1, T s);
template<RealType T, bool S>
TVector4<T, S> operator* (const TVector4<T, S>& v1, T s);
template<RealType T, bool A>
FORCEINLINE TVector4<T, A> operator* (T s, const TVector4<T, A>& v1) { return v1 * s; };
template<RealType T, bool S>
FORCEINLINE TVector4<T, S> operator* (T s, const TVector4<T, S>& v1) { return v1 * s; };
/// <summary>
/// Scale vector by another vector componentwise.
@ -260,8 +263,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator* (const TVector4<T, A>& v1, const TVector4<T, A>& v2);
template<RealType T, bool S>
TVector4<T, S> operator* (const TVector4<T, S>& v1, const TVector4<T, S>& v2);
/// <summary>
/// Vector - scalar division.
@ -271,11 +274,11 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator/ (const TVector4<T, A>& v1, T s);
template<RealType T, bool S>
TVector4<T, S> operator/ (const TVector4<T, S>& v1, T s);
template<RealType T, bool A>
FORCEINLINE TVector4<T, A> operator/ (T s, const TVector4<T, A>& v1) { return v1 / s; };
template<RealType T, bool S>
FORCEINLINE TVector4<T, S> operator/ (T s, const TVector4<T, S>& v1);
/// <summary>
/// Componentwise vector division.
@ -285,8 +288,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator/ (const TVector4<T, A>& v1, const TVector4<T, A>& v2);
template<RealType T, bool S>
TVector4<T, S> operator/ (const TVector4<T, S>& v1, const TVector4<T, S>& v2);
@ -300,8 +303,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns><code>True</code>, if equal and <code>false</code> if not.</returns>
template<RealType T, bool A>
bool operator==(const TVector4<T, A>& v1, const TVector4<T, A>& v2);
template<RealType T, bool S>
bool operator==(const TVector4<T, S>& v1, const TVector4<T, S>& v2);
/// <summary>
@ -312,8 +315,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns><code>True</code>, if inequal and <code>false</code> if equal.</returns>
template<RealType T, bool A>
bool operator!=(const TVector4<T, A>& v1, const TVector4<T, A>& v2);
template<RealType T, bool S>
bool operator!=(const TVector4<T, S>& v1, const TVector4<T, S>& v2);
@ -328,8 +331,8 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A>& operator++(TVector4<T, A>& v1);
template<RealType T, bool S>
TVector4<T, S>& operator++(TVector4<T, S>& v1);
/// <summary>
/// Decrement vector by one
@ -338,8 +341,8 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>v1</returns>
template<RealType T, bool A>
TVector4<T, A>& operator--(TVector4<T, A>& v1);
template<RealType T, bool S>
TVector4<T, S>& operator--(TVector4<T, S>& v1);
/// <summary>
/// Increment vector by one
@ -348,8 +351,8 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>v1</returns>
template<RealType T, bool A>
TVector4<T, A> operator++(TVector4<T, A>& v1, int);
template<RealType T, bool S>
TVector4<T, S> operator++(TVector4<T, S>& v1, int);
/// <summary>
/// Decrement vector by one
@ -358,8 +361,8 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator--(TVector4<T, A>& v1, int);
template<RealType T, bool S>
TVector4<T, S> operator--(TVector4<T, S>& v1, int);
@ -371,15 +374,27 @@ namespace Phanes::Core::Math
// TVector4 functions //
// ====================== //
template<RealType T>
void Set(TVector4<T, false>& v1, TVector4<T, false>& v2)
template<RealType T, bool S>
TVector4<T, S>& Set(TVector4<T, S>& v1, const TVector4<T, S>& v2)
{
v1.x = v2.x;
v1.y = v2.y;
v1.z = v2.z;
v1.w = v2.w;
v1 = v2;
return v1;
}
/// <summary>
/// Set vector to values.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <param name="x">X Component</param>
/// <param name="y">Y Component</param>
/// <param name="z">Z Component</param>
/// <param name="w">W Component</param>
/// <returns></returns>
template<RealType T, bool S>
TVector4<T, S>& Set(TVector4<T, S>& v1, T x, T y, T z, T w);
/// <summary>
/// Get magnitude of vector.
/// </summary>
@ -387,11 +402,8 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v">Vector</param>
/// <returns>Magnitude of vector.</returns>
template<RealType T>
T Magnitude(const TVector4<T, false>& v)
{
return sqrt(DotP(v, v));
}
template<RealType T, bool S>
T Magnitude(const TVector4<T, S>& v);
/// <summary>
/// Get square of magnitude of vector.
@ -400,11 +412,8 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v">Vector</param>
/// <returns>Square of magnitude of vector.</returns>
template<RealType T>
T SqrMagnitude(const TVector4<T, false>& v)
{
return DotP(v, v);
}
template<RealType T, bool S>
T SqrMagnitude(const TVector4<T, S>& v);
/// <summary>
/// Get magnitude of vector.
@ -413,8 +422,8 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v">Vector</param>
/// <returns>Magnitude of vector.</returns>
template<RealType T>
constexpr T Length(const TVector4<T, false>& v) { return Magnitude(v); }
template<RealType T, bool S>
constexpr T Length(const TVector4<T, S>& v) { return Magnitude(v); }
/// <summary>
/// Get square of magnitude of vector.
@ -423,8 +432,8 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v">Vector</param>
/// <returns>Square of magnitude of vector.</returns>
template<RealType T>
constexpr T SqrLength(const TVector4<T, false>& v) { return SqrMagnitude(v); }
template<RealType T, bool S>
constexpr T SqrLength(const TVector4<T, S>& v) { return SqrMagnitude(v); }
/// <summary>
/// Angle between two vectors.
@ -434,8 +443,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns></returns>
template<RealType T>
T Angle(const TVector4<T, false>& v1, const TVector4<T, false>& v2)
template<RealType T, bool S>
T Angle(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
{
return acos(DotP(v1, v2) / (Magnitude(v1) * Magnitude(v2)));
}
@ -448,8 +457,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns></returns>
template<RealType T>
T CosineAngle(const TVector4<T, false>& v1, const TVector4<T, false>& v2)
template<RealType T, bool S>
T CosineAngle(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
{
return DotP(v1, v2) / (Magnitude(v1) * Magnitude(v2));
}
@ -461,8 +470,8 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Normalized vector</returns>
template<RealType T>
TVector4<T, false> Normalize(const TVector4<T, false>& v1)
template<RealType T, bool S>
TVector4<T, S> Normalize(const TVector4<T, S>& v1)
{
T vecNorm = Magnitude(v1);
@ -478,8 +487,8 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Copy of v1.</returns>
template<RealType T>
TVector4<T, false> NormalizeV(TVector4<T, false>& v1)
template<RealType T, bool S>
TVector4<T, S>& NormalizeV(TVector4<T, S>& v1)
{
T vecNorm = Magnitude(v1);
@ -498,8 +507,8 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Normalized vector</returns>
template<RealType T>
TVector4<T, false> UnsafeNormalize(const TVector4<T, false>& v1)
template<RealType T, bool S>
TVector4<T, S> UnsafeNormalize(const TVector4<T, S>& v1)
{
return v1 / Magnitude(v1);
}
@ -512,8 +521,8 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Copy of v1.</returns>
template<RealType T>
TVector4<T, false> UnsafeNormalizeV(TVector4<T, false>& v1)
template<RealType T, bool S>
TVector4<T, S>& UnsafeNormalizeV(TVector4<T, S>& v1)
{
v1 /= Magnitude(v1);
return v1;
@ -527,11 +536,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Dot product between vectors.</returns>
template<RealType T>
T DotP(const TVector4<T, false>& v1, const TVector4<T, false>& v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
}
template<RealType T, bool S>
T DotP(const TVector4<T, S>& v1, const TVector4<T, S>& v2);
/// <summary>
/// Gets componentwise max of both vectors.
@ -541,16 +547,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Vector with componentwise max of both vectors.</returns>
template<RealType T>
TVector4<T, false> Max(const TVector4<T, false>& v1, const TVector4<T, false>& v2)
{
return TVector4<T, false>(
(v1.x > v2.x) ? v1.x : v2.x,
(v1.y > v2.y) ? v1.y : v2.y,
(v1.z > v2.z) ? v1.z : v2.z,
(v1.w > v2.w) ? v1.w : v2.w
);
}
template<RealType T, bool S>
TVector4<T, S> Max(const TVector4<T, S>& v1, const TVector4<T, S>& v2);
/// <summary>
/// Gets componentwise max of both vectors.
@ -560,16 +558,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T>
TVector4<T, false> MaxV(TVector4<T, false>& v1, const TVector4<T, false>& v2)
{
v1.x = (v1.x > v2.x) ? v1.x : v2.x;
v1.y = (v1.y > v2.y) ? v1.y : v2.y;
v1.z = (v1.z > v2.z) ? v1.z : v2.z;
v1.w = (v1.w > v2.w) ? v1.w : v2.w;
return v1;
}
template<RealType T, bool S>
TVector4<T, S>& MaxV(TVector4<T, S>& v1, const TVector4<T, S>& v2);
/// <summary>
/// Gets componentwise min of both vectors.
@ -579,16 +569,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Vector with componentwise max of both vectors.</returns>
template<RealType T>
TVector4<T, false> Min(const TVector4<T, false>& v1, const TVector4<T, false>& v2)
{
return TVector4<T, false>(
(v1.x < v2.x) ? v1.x : v2.x,
(v1.y < v2.y) ? v1.y : v2.y,
(v1.z < v2.z) ? v1.z : v2.z,
(v1.w < v2.w) ? v1.w : v2.w
);
}
template<RealType T, bool S>
TVector4<T, S> Min(const TVector4<T, S>& v1, const TVector4<T, S>& v2);
/// <summary>
/// Gets componentwise min of both vectors.
@ -598,16 +580,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T>
TVector4<T, false> MinV(TVector4<T, false>& v1, const TVector4<T, false>& v2)
{
v1.x = (v1.x < v2.x) ? v1.x : v2.x;
v1.y = (v1.y < v2.y) ? v1.y : v2.y;
v1.z = (v1.z < v2.z) ? v1.z : v2.z;
v1.w = (v1.w < v2.w) ? v1.w : v2.w;
return v1;
}
template<RealType T, bool S>
TVector4<T, S>& MinV(TVector4<T, S>& v1, const TVector4<T, S>& v2);
/// <summary>
/// Inverses vector.
@ -616,15 +590,10 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Inverted vector</returns>
template<RealType T>
TVector4<T, false> Negate(const TVector4<T, false>& v1)
template<RealType T, bool S>
TVector4<T, S> Negate(const TVector4<T, S>& v1)
{
return TVector4<T, false>(
-v1.x,
-v1.y,
-v1.z,
-v1.w
);
return (T)0.0 - v1;
}
/// <summary>
@ -634,15 +603,10 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Copy of v1.</returns>
template<RealType T>
TVector4<T, false> NegateV(TVector4<T, false>& v1)
template<RealType T, bool S>
TVector4<T, S>& NegateV(TVector4<T, S>& v1)
{
v1.x = -v1.x;
v1.y = -v1.y;
v1.z = -v1.z;
v1.w = -v1.w;
return v1;
return (v1 = (T)0.0 - v1);
}
/// <summary>
@ -652,15 +616,10 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Vector with reciprocal of components.</returns>
template<RealType T>
TVector4<T, false> CompInverse(const TVector4<T, false>& v1)
template<RealType T, bool S>
TVector4<T, S> CompInverse(const TVector4<T, S>& v1)
{
return TVector4<T, false>(
(T)1.0 / v1.x,
(T)1.0 / v1.y,
(T)1.0 / v1.z,
(T)1.0 / v1.w
);
return (T)1.0 / v1;
}
/// <summary>
@ -670,15 +629,10 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Copy of v1.</returns>
template<RealType T>
TVector4<T, false> CompInverseV(TVector4<T, false>& v1)
template<RealType T, bool S>
TVector4<T, S>& CompInverseV(TVector4<T, S>& v1)
{
v1.x = (T)1.0 / v1.x;
v1.y = (T)1.0 / v1.y;
v1.z = (T)1.0 / v1.z;
v1.w = (T)1.0 / v1.w;
return v1;
return (v1 = (T)1.0 / v1);
}
/// <summary>
@ -689,12 +643,12 @@ namespace Phanes::Core::Math
/// <param name="v1"></param>
/// <param name="s"></param>
/// <returns>Vector with magnitude clamped to s.</returns>
template<RealType T>
TVector4<T, false> ClampToMagnitude(const TVector4<T, false>& v1, T min, T max)
template<RealType T, bool S>
TVector4<T, S> ClampToMagnitude(const TVector4<T, S>& v1, T min, T max)
{
T magnitude = Magnitude(v1);
TVector4<T, false> unitVec;
TVector4<T, S> unitVec;
unitVec = (magnitude > P_FLT_INAC) ? v1 / magnitude : PZeroVector4(T, false);
magnitude = Clamp(magnitude, min, max);
@ -710,8 +664,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector</param>
/// <param name="s">Magnitude</param>
/// <returns>Copy of v1.</returns>
template<RealType T>
TVector4<T, false> ClampToMagnitudeV(TVector4<T, false>& v1, T min, T max)
template<RealType T, bool S>
TVector4<T, S>& ClampToMagnitudeV(TVector4<T, S>& v1, T min, T max)
{
T magnitude = Magnitude(v1);
@ -730,8 +684,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector</param>
/// <param name="s">Magnitude</param>
/// <returns>Vector with scaled magnitude.</returns>
template<RealType T>
TVector4<T, false> ScaleToMagnitude(const TVector4<T, false>& v1, T s)
template<RealType T, bool S>
TVector4<T, S> ScaleToMagnitude(const TVector4<T, S>& v1, T s)
{
return Normalize(v1) * s;
}
@ -744,8 +698,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector</param>
/// <param name="s">Magnitude</param>
/// <returns>Copy of v1.</returns>
template<RealType T>
TVector4<T, false> ScaleToMagnitudeV(TVector4<T, false>& v1, T s)
template<RealType T, bool S>
TVector4<T, S>& ScaleToMagnitudeV(TVector4<T, S>& v1, T s)
{
NormalizeV(v1);
v1 *= s;
@ -760,10 +714,10 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector</param>
/// <param name="normal">Planes normal</param>
/// <returns>Reflected vector</returns>
template<RealType T>
TVector4<T, false> Reflect(const TVector4<T, false>& v1, const TVector4<T, false> normal)
template<RealType T, bool S>
TVector4<T, S> Reflect(const TVector4<T, S>& v1, const TVector4<T, S> normal)
{
return (2 * DotP(v1, normal) * normal) - v1;
return ((T)2.0 * DotP(v1, normal) * normal) - v1;
}
/// <summary>
@ -774,10 +728,10 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector</param>
/// <param name="normal">Planes normal</param>
/// <returns>Copy of v1.</returns>
template<RealType T>
TVector4<T, false> ReflectV(TVector4<T, false>& v1, const TVector4<T, false> normal)
template<RealType T, bool S>
TVector4<T, S>& ReflectV(TVector4<T, S>& v1, const TVector4<T, S> normal)
{
v1 = (2 * DotP(v1, normal) * normal) - v1;
v1 = ((T)2.0 * DotP(v1, normal) * normal) - v1;
return v1;
}
@ -789,8 +743,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector to project</param>
/// <param name="v2">Vector to project on</param>
/// <returns>Projected vector.</returns>
template<RealType T>
TVector4<T, false> Project(const TVector4<T, false>& v1, const TVector4<T, false> v2)
template<RealType T, bool S>
TVector4<T, S> Project(const TVector4<T, S>& v1, const TVector4<T, S> v2)
{
return (DotP(v1, v2) / DotP(v2, v2)) * v2;
}
@ -803,8 +757,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector to project</param>
/// <param name="v2">Vector to project on</param>
/// <returns>Copy of v1.</returns>
template<RealType T>
TVector4<T, false> ProjectV(TVector4<T, false>& v1, const TVector4<T, false> v2)
template<RealType T, bool S>
TVector4<T, S>& ProjectV(TVector4<T, S>& v1, const TVector4<T, S> v2)
{
v1 = (DotP(v1, v2) / DotP(v2, v2)) * v2;
@ -819,8 +773,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector to reject</param>
/// <param name="v2">Vector to reject from</param>
/// <returns>Rejected vector.</returns>
template<RealType T>
TVector4<T, false> Reject(const TVector4<T, false>& v1, const TVector4<T, false> v2)
template<RealType T, bool S>
TVector4<T, S> Reject(const TVector4<T, S>& v1, const TVector4<T, S> v2)
{
return v1 - (DotP(v1, v2) / DotP(v2, v2)) * v2;
}
@ -833,8 +787,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector to reject</param>
/// <param name="v2">Vector to reject from</param>
/// <returns>Copy of v1.</returns>
template<RealType T>
TVector4<T, false> RejectV(TVector4<T, false>& v1, const TVector4<T, false> v2)
template<RealType T, bool S>
TVector4<T, S>& RejectV(TVector4<T, S>& v1, const TVector4<T, S> v2)
{
v1 = v1 - (DotP(v1, v2) / DotP(v2, v2)) * v2;
@ -848,17 +802,8 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Perspective divided vector.</returns>
template<RealType T>
TVector4<T, false> PerspectiveDivide(const TVector4<T, false>& v1)
{
float _1_w = (T)1.0 / v1.w;
return TVector4<T, false>(
v1.x * _1_w,
v1.y * _1_w,
v1.z * _1_w,
(T)0.0
);
}
template<RealType T, bool S>
TVector4<T, S> PerspectiveDivide(const TVector4<T, S>& v1);
/// <summary>
/// Perspective divide vector.
@ -867,18 +812,8 @@ namespace Phanes::Core::Math
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Copy of v1.</returns>
template<RealType T>
TVector4<T, false> PerspectiveDivideV(TVector4<T, false>& v1)
{
float _1_w = (T)1.0 / v1.w;
v1.x *= _1_w;
v1.y *= _1_w;
v1.z *= _1_w;
v1.w = (T)0.0;
return v1;
}
template<RealType T, bool S>
TVector4<T, S>& PerspectiveDivideV(TVector4<T, S>& v1);
/// <summary>
/// Tests if vector is normalized.
@ -887,8 +822,8 @@ namespace Phanes::Core::Math
/// <param name="v1">Vector</param>
/// <param name="threshold">Threshold to vector magnitude of 1.0</param>
/// <returns>True if vector is normalized, false if not.</returns>
template<RealType T>
FORCEINLINE bool IsNormalized(const TVector4<T, false>& v1, T threshold = P_FLT_INAC)
template<RealType T, bool S>
FORCEINLINE bool IsNormalized(const TVector4<T, S>& v1, T threshold = P_FLT_INAC)
{
return (SqrMagnitude(v1) - (T)1.0) < threshold;
}
@ -901,8 +836,8 @@ namespace Phanes::Core::Math
/// <param name="v2">Vector</param>
/// <param name="threshold">Allowed T inaccuracy from one (e.g. 0.98f)</param>
/// <returns>True if parallel, false if not.</returns>
template<RealType T>
FORCEINLINE bool IsParallel(const TVector4<T, false>& v1, const TVector4<T, false>& v2, T threshold = 1.0f - P_FLT_INAC)
template<RealType T, bool S>
FORCEINLINE bool IsParallel(const TVector4<T, S>& v1, const TVector4<T, S>& v2, T threshold = 1.0f - P_FLT_INAC)
{
return (abs(DotP(v1, v2)) > threshold);
}
@ -915,8 +850,8 @@ namespace Phanes::Core::Math
/// <param name="v2">Vector</param>
/// <param name="threshold">Allowed T inaccuracy from one (e.g. 0.98f)</param>
/// <returns>True if coincident, false if not.</returns>
template<RealType T>
FORCEINLINE bool IsCoincident(const TVector4<T, false>& v1, const TVector4<T, false>& v2, T threshold = 1.0f - P_FLT_INAC)
template<RealType T, bool S>
FORCEINLINE bool IsCoincident(const TVector4<T, S>& v1, const TVector4<T, S>& v2, T threshold = 1.0f - P_FLT_INAC)
{
return (DotP(v1, v2) > threshold);
}

View File

@ -17,7 +17,7 @@ namespace Phanes::Core::Math
}
template<RealType T, bool S>
TVector4<T, S>::TVector4(Real _x, Real _y, Real _z, Real _w)
TVector4<T, S>::TVector4(Real _x, Real _y, Real _z, Real _w)
{
Detail::construct_vec4<T, S>::map(*this, _x, _y, _z, _w);
}
@ -42,56 +42,56 @@ namespace Phanes::Core::Math
template<RealType T, bool S>
TVector4<T, S> operator+=(TVector4<T, S>& v1, const TVector4<T, S>& v2)
TVector4<T, S>& operator+=(TVector4<T, S>& v1, const TVector4<T, S>& v2)
{
Detail::compute_vec4_add<T, S>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool S>
TVector4<T, S> operator+=(TVector4<T, S>& v1, T s)
TVector4<T, S>& operator+=(TVector4<T, S>& v1, T s)
{
Detail::compute_vec4_add<T, S>::map(v1, v1, s);
return v1;
}
template<RealType T, bool S>
TVector4<T, S> operator-=(TVector4<T, S>& v1, const TVector4<T, S>& v2)
TVector4<T, S>& operator-=(TVector4<T, S>& v1, const TVector4<T, S>& v2)
{
Detail::compute_vec4_sub<T, S>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool S>
TVector4<T, S> operator-=(TVector4<T, S>& v1, T s)
TVector4<T, S>& operator-=(TVector4<T, S>& v1, T s)
{
Detail::compute_vec4_sub<T, S>::map(v1, v1, s);
return v1;
}
template<RealType T, bool S>
TVector4<T, S> operator*=(TVector4<T, S>& v1, const TVector4<T, S>& v2)
TVector4<T, S>& operator*=(TVector4<T, S>& v1, const TVector4<T, S>& v2)
{
Detail::compute_vec4_mul<T, S>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool S>
TVector4<T, S> operator*=(TVector4<T, S>& v1, T s)
TVector4<T, S>& operator*=(TVector4<T, S>& v1, T s)
{
Detail::compute_vec4_mul<T, S>::map(v1, v1, s);
return v1;
}
template<RealType T, bool S>
TVector4<T, S> operator/=(TVector4<T, S>& v1, const TVector4<T, S>& v2)
TVector4<T, S>& operator/=(TVector4<T, S>& v1, const TVector4<T, S>& v2)
{
Detail::compute_vec4_div<T, S>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool S>
TVector4<T, S> operator/=(TVector4<T, S>& v1, T s)
TVector4<T, S>& operator/=(TVector4<T, S>& v1, T s)
{
Detail::compute_vec4_div<T, S>::map(v1, v1, s);
return v1;
@ -100,7 +100,7 @@ namespace Phanes::Core::Math
template<RealType T, bool S>
TVector4<T, S> operator+(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
{
TVector4<T, S> r;
TVector4<T, S> r;
Detail::compute_vec4_add<T, S>::map(r, v1, v2);
return r;
}
@ -129,6 +129,14 @@ namespace Phanes::Core::Math
return r;
}
template<RealType T, bool S>
TVector4<T, S> operator-(T s, const TVector4<T, S>& v1)
{
TVector4<T, S> r;
Detail::compute_vec4_sub<T, S>::map(r, s, v1);
return r;
}
template<RealType T, bool S>
TVector4<T, S> operator*(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
{
@ -161,6 +169,14 @@ namespace Phanes::Core::Math
return r;
}
template<RealType T, bool S>
TVector4<T, S> operator/(T s, const TVector4<T, S>& v1)
{
TVector4<T, S> r;
Detail::compute_vec4_div<T, S>::map(r, s, v1);
return r;
}
// Comparision
template<RealType T, bool S>
@ -175,8 +191,8 @@ namespace Phanes::Core::Math
return Detail::compute_vec4_ieq<T, S>::map(v1, v2);
}
// Inc- / Decrement
@ -206,9 +222,72 @@ namespace Phanes::Core::Math
return --v1;
}
template<RealType T>
T DotP(const TVector4<T, true>& v1, const TVector4<T, true>& v2)
template<RealType T, bool S>
T DotP(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
{
return vec4_dot_cvtf32(v1.data, v2.data);
return Detail::compute_vec4_dotp<T, S> ::map(v1, v2);
}
template<RealType T, bool S>
TVector4<T, S>& Set(TVector4<T, S>& v1, T x, T y, T z, T w)
{
Detail::compute_vec4_set<T, S>::map(v1, x, y, z, w);
}
template<RealType T, bool S>
T Magnitude(const TVector4<T, S>& v)
{
return Detail::compute_vec4_mag<T, S>::map(v);
}
template<RealType T, bool S>
T SqrMagnitude(const TVector4<T, S>& v)
{
return Detail::compute_vec4_dotp<T, S>::map(v, v);
}
template<RealType T, bool S>
TVector4<T, S> Max(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
{
TVector4<T, S> r;
Detail::compute_vec4_max<T, S>::map(r, v1, v2);
return r;
}
template<RealType T, bool S>
TVector4<T, S>& MaxV(TVector4<T, S>& v1, const TVector4<T, S>& v2)
{
Detail::compute_vec4_max<T, S>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool S>
TVector4<T, S> Min(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
{
TVector4<T, S> r;
Detail::compute_vec4_min<T, S>::map(r, v1, v2);
return r;
}
template<RealType T, bool S>
TVector4<T, S>& MinV(TVector4<T, S>& v1, const TVector4<T, S>& v2)
{
Detail::compute_vec4_min<T, S>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool S>
TVector4<T, S> PerspectiveDivide(const TVector4<T, S>& v1)
{
TVector4<T, S> r;
Detail::compute_vec4_pdiv<T, S>::map(r, v1);
return r;
}
template<RealType T, bool S>
TVector4<T, S>& PerspectiveDivideV(TVector4<T, S>& v1)
{
Detail::compute_vec4_pdiv<T, S>::map(v1, v1);
return v1;
}
}