SIMD improvements

This commit is contained in:
THoehne 2024-08-27 14:32:55 +02:00
parent 7ff9493708
commit e54455ee31
3 changed files with 264 additions and 185 deletions

View File

@ -28,6 +28,26 @@ namespace Phanes::Core::Math::Detail
struct compute_vec2_dec {};
// Magnitude
template<RealType T, bool S>
struct compute_vec2_mag {};
// Dot product
template<RealType T, bool S>
struct compute_vec2_dotp {};
// Max
template<RealType T, bool S>
struct compute_vec2_max {};
// Min
template<RealType T, bool S>
struct compute_vec2_min {};
// Set
template<RealType T, bool S>
struct compute_vec2_set {};
template<RealType T>
struct construct_vec2<T, false>
@ -97,6 +117,12 @@ namespace Phanes::Core::Math::Detail
r.x = v1.x - s;
r.y = v1.y - s;
}
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, T s, const Phanes::Core::Math::TVector2<T, false>& v1)
{
r.x = s - v1.x;
r.y = s - v1.y;
}
};
@ -137,6 +163,12 @@ namespace Phanes::Core::Math::Detail
r.x = v1.x * s;
r.y = v1.y * s;
}
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, T s, const Phanes::Core::Math::TVector2<T, false>& v1)
{
r.x = s / v1.x;
r.y = s / v1.y;
}
};
template<RealType T, bool S>
@ -182,5 +214,53 @@ namespace Phanes::Core::Math::Detail
r.y = v1.y - 1;
}
};
}
template<RealType T>
struct compute_vec2_mag<T, false>
{
static constexpr T map(const Phanes::Core::Math::TVector2<T, false>& v1)
{
return sqrt(v1.x * v1.x + v1.y * v1.y);
}
};
template<RealType T>
struct compute_vec2_dotp<T, false>
{
static constexpr T map(const Phanes::Core::Math::TVector2<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2)
{
return v1.x * v2.x + v1.y * v2.y;
}
};
template<RealType T>
struct compute_vec2_max<T, false>
{
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2)
{
r.x = (v1.x > v2.x) ? v1.x : v2.x;
r.y = (v1.y > v2.y) ? v1.y : v2.y;
}
};
template<RealType T>
struct compute_vec2_min<T, false>
{
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2)
{
r.x = (v1.x < v2.x) ? v1.x : v2.x;
r.y = (v1.y < v2.y) ? v1.y : v2.y;
}
};
template<RealType T>
struct compute_vec2_set<T, false>
{
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& v1, T x, T y)
{
v1.x = x;
v1.y = y;
}
};
}

View File

@ -273,10 +273,12 @@ namespace Phanes::Core::Math {
template<RealType T, bool S>
inline TVector2<T, S> operator/ (T s, const TVector2<T, S>& v1)
{
return v1 / s;
}
inline TVector2<T, S> operator/ (T s, const TVector2<T, S>& v1);
template<RealType T, bool S>
inline TVector2<T, S> operator- (T s, const TVector2<T, S>& v1);
/**
* Componentwise addition of Vector with floating point.
@ -378,11 +380,8 @@ namespace Phanes::Core::Math {
* @return Size of Vector
*/
template<RealType T>
T Magnitude(const TVector2<T, false>& v1)
{
return sqrtf(v1.x * v1.x + v1.y * v1.y);
}
template<RealType T, bool S>
T Magnitude(const TVector2<T, S>& v1);
/**
* @see [FUNC]Magnitude
@ -398,11 +397,8 @@ namespace Phanes::Core::Math {
* @return Magnitude without calculating square root
*/
template<RealType T>
T SqrMagnitude(const TVector2<T, false>& v1)
{
return v1.x * v1.x + v1.y * v1.y;
}
template<RealType T, bool S>
T SqrMagnitude(const TVector2<T, S>& v1);
/**
* @see [FUNC]SqrMagnitude
@ -416,10 +412,10 @@ namespace Phanes::Core::Math {
* @param(v1) Vector
*/
template<RealType T>
TVector2<T, false> NormalizeV(TVector2<T, false>& v1)
template<RealType T, bool S>
TVector2<T, S>& NormalizeV(TVector2<T, S>& v1)
{
float vecNorm = Magnitude(v1);
T vecNorm = Magnitude(v1);
v1 /= (vecNorm < P_FLT_INAC) ? (T)1.0 : vecNorm;
return v1;
}
@ -432,12 +428,10 @@ namespace Phanes::Core::Math {
* @note Does not look for zero vector.
*/
template<RealType T>
TVector2<T, false> UnsafeNormalizeV(TVector2<T, false>& v1)
template<RealType T, bool S>
TVector2<T, S>& UnsafeNormalizeV(TVector2<T, S>& v1)
{
v1 /= Magnitude(v1);
return v1;
return (v1 /= Magnitude(v1));
}
/**
@ -447,8 +441,8 @@ namespace Phanes::Core::Math {
* @param(v2) Vector two
*/
template<RealType T>
T Angle(const TVector2<T, false>& v1, const TVector2<T, false>& v2)
template<RealType T, bool S>
T Angle(const TVector2<T, S>& v1, const TVector2<T, S>& v2)
{
return acos(DotP(v1, v2) / (Magnitude(v1) * Magnitude(v2)));
}
@ -460,8 +454,8 @@ namespace Phanes::Core::Math {
* @param(v2) Vector two
*/
template<RealType T>
T CosineAngle(const TVector2<T, false>& v1, const TVector2<T, false>& v2)
template<RealType T, bool S>
T CosineAngle(const TVector2<T, S>& v1, const TVector2<T, S>& v2)
{
return DotP(v1, v2) / (Magnitude(v1) * Magnitude(v2));
}
@ -472,8 +466,8 @@ namespace Phanes::Core::Math {
* @param(v1) Vector one
*/
template<RealType T>
TVector2<T, false> SignVectorV(TVector2<T, false>& v1)
template<RealType T, bool S>
TVector2<T, S>& SignVectorV(TVector2<T, S>& v1)
{
v1.x = (v1.x >= (T)0.0) ? (T)1.0 : -(T)1.0;
v1.y = (v1.y >= (T)0.0) ? (T)1.0 : -(T)1.0;
@ -488,10 +482,10 @@ namespace Phanes::Core::Math {
* @param(radius) Radius of square (=> Distance from middle to center of each site.)
*/
template<RealType T>
TVector2<T, false> BindToSquareV(TVector2<T, false>& v1, T radius)
template<RealType T, bool S>
TVector2<T, S>& BindToSquareV(TVector2<T, S>& v1, T radius)
{
float k = (abs(v1.x) > abs(v1.y)) ? abs(radius / v1.x) : abs(radius / v1.y);
T k = (Abs(v1.x) > Abs(v1.y)) ? Abs(radius / v1.x) : Abs(radius / v1.y);
v1 *= k;
return v1;
@ -504,11 +498,11 @@ namespace Phanes::Core::Math {
* @param(radius) Radius of square (=> Distance from middle to center of each site.)
*/
template<RealType T>
TVector2<T, false> ClampToSquareV(TVector2<T, false>& v1, T radius)
template<RealType T, bool S>
TVector2<T, S>& ClampToSquareV(TVector2<T, S>& v1, T radius)
{
float prime = (abs(v1.x) > abs(v1.y)) ? v1.x : v1.y;
float k = (prime > radius) ? abs(radius / prime) : 1.0f;
T prime = (Abs(v1.x) > Abs(v1.y)) ? v1.x : v1.y;
T k = (prime > radius) ? Abs(radius / prime) : (T)1.0;
v1 *= k;
return v1;
@ -521,11 +515,8 @@ namespace Phanes::Core::Math {
* @param(v2) Vector two
*/
template<RealType T>
inline T DotP(const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
return v1.x * v2.x + v1.y * v2.y;
}
template<RealType T, bool S>
inline T DotP(const TVector2<T, S>& v1, const TVector2<T, S>& v2);
/**
* Creates Vector, with component wise largest values.
@ -536,14 +527,8 @@ namespace Phanes::Core::Math {
* @note Stores new Vector to v1
*/
template<RealType T>
TVector2<T, false> MaxV(TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
v1.x = Phanes::Core::Math::Max(v1.x, v2.x);
v1.y = Phanes::Core::Math::Max(v1.y, v2.y);
return v1;
}
template<RealType T, bool S>
TVector2<T, S>& MaxV(TVector2<T, S>& v1, const TVector2<T, S>& v2);
/**
* Creates Vector, with component wise smallest values.
@ -554,14 +539,8 @@ namespace Phanes::Core::Math {
* @note Stores new Vector to v1
*/
template<RealType T>
TVector2<T, false> MinV(TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
v1.x = Phanes::Core::Math::Min(v1.x, v2.x);
v1.y = Phanes::Core::Math::Min(v1.y, v2.y);
return v1;
}
template<RealType T, bool S>
TVector2<T, S>& MinV(TVector2<T, S>& v1, const TVector2<T, S>& v2);
/**
* Gets perpendicular Vector to v1.
@ -572,13 +551,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T, false> GetPerpendicularV(TVector2<T, false>& v1)
TVector2<T, false>& GetPerpendicularV(TVector2<T, false>& v1)
{
T x = -v1.x;
v1.x = v1.y;
v1.y = x;
return v1;
return Set(v1, v1.y, -v1.x);
}
/**
@ -592,7 +567,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T, false> GetReversePerpendicularV(TVector2<T, false>& v1)
TVector2<T, false>& GetReversePerpendicularV(TVector2<T, false>& v1)
{
T x = v1.x;
v1.x = -v1.y;
@ -601,24 +576,6 @@ namespace Phanes::Core::Math {
return v1;
}
/**
* Component wise multiplication of Vector
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @note Stores new Vector to v1
*/
template<RealType T>
TVector2<T, false> ScaleV(TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
v1.x *= v2.x;
v1.y *= v2.y;
return v1;
}
/**
* Componentwise inverse of Vector
*
@ -627,13 +584,10 @@ namespace Phanes::Core::Math {
* @note Stores new Vector to v1
*/
template<RealType T>
TVector2<T, false> CompInverseV(TVector2<T, false>& v1)
template<RealType T, bool S>
TVector2<T, S>& CompInverseV(TVector2<T, S>& v1)
{
v1.x = 1.0f / v1.x;
v1.y = 1.0f / v1.y;
return v1;
return (v1 = (T)1.0 / v1);
}
/**
@ -645,8 +599,8 @@ namespace Phanes::Core::Math {
* @note Stores new Vector to v1
*/
template<RealType T>
TVector2<T, false> ReflectV(TVector2<T, false>& v1, const TVector2<T, false>& normal)
template<RealType T, bool S>
TVector2<T, S>& ReflectV(TVector2<T, S>& v1, const TVector2<T, S>& normal)
{
v1 = ((T)2.0 * DotP(v1, normal) * normal) - v1;
@ -660,8 +614,8 @@ namespace Phanes::Core::Math {
* @param(v2) Vector to copy
*/
template<RealType T>
TVector2<T, false> Set(TVector2<T, false>& v1, const TVector2<T, false>& v2)
template<RealType T, bool S>
TVector2<T, S>& Set(TVector2<T, S>& v1, const TVector2<T, S>& v2)
{
v1 = v2;
@ -670,19 +624,15 @@ namespace Phanes::Core::Math {
/**
* Sets components of a vector.
*
* Automatically used _mm_setr_ps, if vector is xmm register.
*
* @param(v1) Vector to copy to
* @param(v2) Vector to copy
*/
template<RealType T>
TVector2<T, false> Set(TVector2<T, false>& v1, T x, T y)
{
v1.x = x;
v1.y = y;
return v1;
}
template<RealType T, bool S>
TVector2<T, S>& Set(TVector2<T, S>& v1, T x, T y);
/**
* Anti-clockwise vector rotation.
@ -692,11 +642,11 @@ namespace Phanes::Core::Math {
* @note Angle is not clamped
*/
template<RealType T>
TVector2<T, false> RotateV(TVector2<T, false>& v1, T angle)
template<RealType T, bool S>
TVector2<T, S>& RotateV(TVector2<T, S>& v1, T angle)
{
float sinAngle = sin(angle);
float cosAngle = cos(angle);
T sinAngle = sin(angle);
T cosAngle = cos(angle);
Set(v1,
v1.x * cosAngle - v1.y * sinAngle,
@ -715,8 +665,8 @@ namespace Phanes::Core::Math {
* @note Angle is not clamped
*/
template<RealType T>
FORCEINLINE TVector2<T, false> ClockwiseRotateV(TVector2<T, false>& v1, T angle)
template<RealType T, bool S>
FORCEINLINE TVector2<T, S>& ClockwiseRotateV(TVector2<T, S>& v1, T angle)
{
RotateV(v1, -angle);
@ -730,12 +680,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T, false> NegateV(TVector2<T, false>& v1)
TVector2<T, false>& NegateV(TVector2<T, false>& v1)
{
v1.x = -v1.x;
v1.y = -v1.y;
return v1;
return Set(v1, -v1.x, -v1.y);
}
/**
@ -747,10 +694,10 @@ namespace Phanes::Core::Math {
* @return true if unit vector, false if not
*/
template<RealType T>
inline bool IsNormalized(const TVector2<T, false>& v1, T threshold = P_FLT_INAC)
template<RealType T, bool S>
inline bool IsNormalized(const TVector2<T, S>& v1, T threshold = P_FLT_INAC)
{
return (abs(SqrMagnitude(v1) - 1) < threshold);
return (Abs(SqrMagnitude(v1) - 1) < threshold);
}
/**
@ -765,10 +712,10 @@ namespace Phanes::Core::Math {
* @note Requires v1 and v2 to be normal vectors.
*/
template<RealType T>
inline bool IsPerpendicular(const TVector2<T, false>& v1, const TVector2<T, false>& v2, T threshold = P_FLT_INAC)
template<RealType T, bool S>
inline bool IsPerpendicular(const TVector2<T, S>& v1, const TVector2<T, S>& v2, T threshold = P_FLT_INAC)
{
return (abs(DotP(v1, v2)) < threshold);
return (Abs(DotP(v1, v2)) < threshold);
}
/**
@ -783,10 +730,10 @@ namespace Phanes::Core::Math {
* @note Requires v1 and v2 to be normal vectors.
*/
template<RealType T>
inline bool IsParallel(const TVector2<T, false>& v1, const TVector2<T, false>& v2, T threshold = 1.0f - P_FLT_INAC)
template<RealType T, bool S>
inline bool IsParallel(const TVector2<T, S>& v1, const TVector2<T, S>& v2, T threshold = 1.0f - P_FLT_INAC)
{
return (abs(DotP(v1, v2)) > threshold);
return (Abs(DotP(v1, v2)) > threshold);
}
/**
@ -801,8 +748,8 @@ namespace Phanes::Core::Math {
* @note Requires v1 and v2 to be normal vectors.
*/
template<RealType T>
inline bool IsCoincident(const TVector2<T, false>& v1, const TVector2<T, false>& v2, T threshold = 1.0f - P_FLT_INAC)
template<RealType T, bool S>
inline bool IsCoincident(const TVector2<T, S>& v1, const TVector2<T, S>& v2, T threshold = 1.0f - P_FLT_INAC)
{
return (DotP(v1, v2) > threshold);
}
@ -834,27 +781,12 @@ namespace Phanes::Core::Math {
* @return Reflected vector
*/
template<RealType T>
TVector2<T, false> Reflect(const TVector2<T, false>& v1, const TVector2<T, false>& normal)
template<RealType T, bool S>
TVector2<T, S> Reflect(const TVector2<T, S>& v1, const TVector2<T, S>& normal)
{
return (((T)2.0 * DotP(v1, normal) * normal) - v1);
}
/**
* Scales a vector component wise
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Reflected vector
*/
template<RealType T>
TVector2<T, false> Scale(const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
return TVector2<T, false>(v1.x * v2.x, v1.y * v2.y);
}
/**
* Componentwise inverse of a vector
*
@ -863,10 +795,10 @@ namespace Phanes::Core::Math {
* @return Componentwise inverted vector
*/
template<RealType T>
TVector2<T, false> CompInverse(const TVector2<T, false>& v1)
template<RealType T, bool S>
TVector2<T, S> CompInverse(const TVector2<T, S>& v1)
{
return TVector2<T, false>(1.0f / v1.x, 1.0f / v1.y);
return ((T)1.0 / v1);
}
/**
@ -877,10 +809,10 @@ namespace Phanes::Core::Math {
* @return Componentwise inverted vector
*/
template<RealType T>
TVector2<T, false> Negate(const TVector2<T, false>& v1)
template<RealType T, bool S>
TVector2<T, S> Negate(const TVector2<T, S>& v1)
{
return TVector2<T, false>(-v1.x, -v1.y);
return ((T)1.0 - v1);
}
/**
@ -891,10 +823,10 @@ namespace Phanes::Core::Math {
* @return Perpendicular vector
*/
template<RealType T>
TVector2<T, false> GetPerpendicular(const TVector2<T, false>& v1)
template<RealType T, bool S>
TVector2<T, S> GetPerpendicular(const TVector2<T, S>& v1)
{
return TVector2<T, false>(v1.y, -v1.x);
return TVector2<T, S>(v1.y, -v1.x);
}
/**
@ -905,10 +837,10 @@ namespace Phanes::Core::Math {
* @return Reversed perpendicular vector
*/
template<RealType T>
TVector2<T, false> GetReversePerpendicular(const TVector2<T, false>& v1)
template<RealType T, bool S>
TVector2<T, S> GetReversePerpendicular(const TVector2<T, S>& v1)
{
return TVector2<T, false>(-v1.y, v1.x);
return TVector2<T, S>(-v1.y, v1.x);
}
/**
@ -920,11 +852,8 @@ namespace Phanes::Core::Math {
* @return Minimal vector
*/
template<RealType T>
TVector2<T, false> Min(const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
return TVector2<T, false>(Phanes::Core::Math::Min(v1.x, v2.x), Phanes::Core::Math::Min(v1.y, v2.y));
}
template<RealType T, bool S>
TVector2<T, S> Min(const TVector2<T, S>& v1, const TVector2<T, S>& v2);
/**
* Creates a new Vector by the component wise maxima of both vectors
@ -935,11 +864,8 @@ namespace Phanes::Core::Math {
* @return Maximal vector
*/
template<RealType T>
TVector2<T, false> Max(const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
return TVector2<T, false>(Phanes::Core::Math::Max(v1.x, v2.x), Phanes::Core::Math::Max(v1.y, v2.y));
}
template<RealType T, bool S>
TVector2<T, S> Max(const TVector2<T, S>& v1, const TVector2<T, S>& v2);
/**
* Creates a normalized instance of the vector
@ -949,10 +875,10 @@ namespace Phanes::Core::Math {
* @return Unit vector
*/
template<RealType T>
TVector2<T, false> Normalize(const TVector2<T, false>& v1)
template<RealType T, bool S>
TVector2<T, S> Normalize(const TVector2<T, S>& v1)
{
float vecNorm = Magnitude(v1);
T vecNorm = Magnitude(v1);
return (vecNorm < P_FLT_INAC) ? v1 : (v1 / vecNorm);
}
@ -965,8 +891,8 @@ namespace Phanes::Core::Math {
* @note Does not test for zero vector
*/
template<RealType T>
TVector2<T, false> UnsafeNormalize(const TVector2<T, false>& v1)
template<RealType T, bool S>
TVector2<T, S> UnsafeNormalize(const TVector2<T, S>& v1)
{
return (v1 / Magnitude(v1));
}
@ -979,10 +905,10 @@ namespace Phanes::Core::Math {
* @return Vector with signs as components
*/
template<RealType T>
TVector2<T, false> SignVector(const TVector2<T, false>& v1)
template<RealType T, bool S>
TVector2<T, S> SignVector(const TVector2<T, S>& v1)
{
return TVector2<T, false>((v1.x >= (T)0.0) ? (T)1.0 : (T)-1.0, (v1.y >= (T)0.0) ? (T)1.0 : (T)-1.0);
return TVector2<T, S>((v1.x >= (T)0.0) ? (T)1.0 : (T)-1.0, (v1.y >= (T)0.0) ? (T)1.0 : (T)-1.0);
}
/**
@ -994,10 +920,10 @@ namespace Phanes::Core::Math {
* @return Bound vector
*/
template<RealType T>
TVector2<T, false> BindToSquare(const TVector2<T, false>& v1, T radius)
template<RealType T, bool S>
TVector2<T, S> BindToSquare(const TVector2<T, S>& v1, T radius)
{
float k = (abs(v1.x) > abs(v1.y)) ? abs(radius / v1.x) : abs(radius / v1.y);
T k = (Abs(v1.x) > Abs(v1.y)) ? Abs(radius / v1.x) : Abs(radius / v1.y);
return v1 * k;
}
@ -1010,11 +936,11 @@ namespace Phanes::Core::Math {
* @return Clamped vector. If the length of the vector fits the square, then the vector is returned.
*/
template<RealType T>
TVector2<T, false> ClampToSquare(const TVector2<T, false>& v1, T radius)
template<RealType T, bool S>
TVector2<T, S> ClampToSquare(const TVector2<T, S>& v1, T radius)
{
float prime = (abs(v1.x) > abs(v1.y)) ? v1.x : v1.y;
float k = (prime > radius) ? abs(radius / prime) : 1.0f;
T prime = (Abs(v1.x) > Abs(v1.y)) ? v1.x : v1.y;
T k = (prime > radius) ? Abs(radius / prime) : 1.0f;
return v1 * k;
}
@ -1031,8 +957,8 @@ namespace Phanes::Core::Math {
* @note Interpolation is clamped between 0 - 1.
*/
template<RealType T>
TVector2<T, false> Lerp(const TVector2<T, false>& startVec, const TVector2<T, false>& destVec, T t)
template<RealType T, bool S>
TVector2<T, S> Lerp(const TVector2<T, S>& startVec, const TVector2<T, S>& destVec, T t)
{
t = Phanes::Core::Math::Clamp(t, (T)0.0, (T)1.0);
@ -1051,8 +977,8 @@ namespace Phanes::Core::Math {
* @note Interpolation is not clamped. Make shure t is between 0.0f and 1.0f
*/
template<RealType T>
TVector2<T, false> LerpUnclamped(const TVector2<T, false>& startVec, const TVector2<T, false>& destVec, T t)
template<RealType T, bool S>
TVector2<T, S> LerpUnclamped(const TVector2<T, S>& startVec, const TVector2<T, S>& destVec, T t)
{
return (t * destVec) + ((1 - t) * startVec);
}
@ -1068,13 +994,13 @@ namespace Phanes::Core::Math {
* @note Angle is not clamped
*/
template<RealType T>
TVector2<T, false> Rotate(const TVector2<T, false>& v1, T angle)
template<RealType T, bool S>
TVector2<T, S> Rotate(const TVector2<T, S>& v1, T angle)
{
float sinAngle = sin(angle);
float cosAngle = cos(angle);
return TVector2<T, false>(v1.x * cosAngle - v1.y * sinAngle,
return TVector2<T, S>(v1.x * cosAngle - v1.y * sinAngle,
v1.y * cosAngle + v1.x * sinAngle);
}
@ -1088,8 +1014,8 @@ namespace Phanes::Core::Math {
* @note Angle is not clamped
*/
template<RealType T>
TVector2<T, false> ClockwiseRotate(const TVector2<T, false>& v1, T angle)
template<RealType T, bool S>
TVector2<T, S> ClockwiseRotate(const TVector2<T, S>& v1, T angle)
{
return Rotate(v1, -angle);
}

View File

@ -1,3 +1,7 @@
/**
* Contains functions, that have separate simd equivalents.
*/
#pragma once
#include "Core/public/Math/Boilerplate.h"
@ -158,6 +162,22 @@ namespace Phanes::Core::Math
return r;
}
template<RealType T, bool S>
TVector2<T, S> operator/(T s, const TVector2<T, S>& v1)
{
TVector2<T, S> r;
Detail::compute_vec2_div<T, S>::map(r, s, v1);
return r;
}
template<RealType T, bool S>
TVector2<T, S> operator-(T s, const TVector2<T, S>& v1)
{
TVector2<T, S> r;
Detail::compute_vec2_sub<T, S>::map(r, s, v1);
return r;
}
// Comparision
template<RealType T, bool S>
@ -204,5 +224,58 @@ namespace Phanes::Core::Math
}
template<RealType T, bool S>
T Magnitude(const TVector2<T, S>& v1)
{
return Detail::compute_vec2_mag<T, S>::map(v1);
}
template<RealType T, bool S>
T SqrMagnitude(const TVector2<T, S>& v1)
{
return Detail::compute_vec2_dotp<T, S>::map(v1, v1);
}
template<RealType T, bool S>
inline T DotP(const TVector2<T, S>& v1, const TVector2<T, S>& v2)
{
return Detail::compute_vec2_dotp<T, S>::map(v1, v2);
}
template<RealType T, bool S>
TVector2<T, S>& MaxV(TVector2<T, S>& v1, const TVector2<T, S>& v2)
{
Detail::compute_vec2_max<T, S>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool S>
TVector2<T, S> Max(const TVector2<T, S>& v1, const TVector2<T, S>& v2)
{
TVector2<T, S> r;
Detail::compute_vec2_max<T, S>::map(r, v1, v2);
return r;
}
template<RealType T, bool S>
TVector2<T, S>& MinV(TVector2<T, S>& v1, const TVector2<T, S>& v2)
{
Detail::compute_vec2_min<T, S>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool S>
TVector2<T, S> Min(const TVector2<T, S>& v1, const TVector2<T, S>& v2)
{
TVector2<T, S> r;
Detail::compute_vec2_min<T, S>::map(r, v1, v2);
return r;
}
template<RealType T, bool S>
TVector2<T, S>& Set(TVector2<T, S>& v1, T x, T y)
{
Detail::compute_vec2_set<T, S>::map(v1, x, y);
return v1;
}
}