SIMD improvement.

This commit is contained in:
scorpioblood 2024-06-04 22:13:28 +02:00
parent 202baf29f5
commit 45a167564d
14 changed files with 1187 additions and 241 deletions

View File

@ -0,0 +1,192 @@
#pragma once
#include "Core/public/Math/Boilerplate.h"
#include <iostream>
namespace Phanes::Core::Math::Detail
{
template<RealType T, bool S>
struct construct_vec2 {};
template<RealType T, bool S>
struct compute_vec2_add {};
template<RealType T, bool S>
struct compute_vec2_sub {};
template<RealType T, bool S>
struct compute_vec2_mul {};
template<RealType T, bool S>
struct compute_vec2_div {};
template<RealType T, bool S>
struct compute_vec2_eq {};
template<RealType T, bool S>
struct compute_vec2_ieq {};
template<RealType T, bool S>
struct compute_vec2_inc {};
template<RealType T, bool S>
struct compute_vec2_dec {};
template<RealType T>
struct construct_vec2<T, false>
{
template<bool A>
static constexpr void map(Phanes::Core::Math::TVector2<T, A>& v1, const TVector2<T, A>& v2)
{
v1.x = v2.x;
v1.y = v2.y;
}
template<bool A>
static constexpr void map(Phanes::Core::Math::TVector2<T, A>& v1, T s)
{
v1.x = s;
v1.y = s;
}
template<bool A>
static constexpr void map(Phanes::Core::Math::TVector2<T, A>& v1, T x, T y)
{
v1.x = x;
v1.y = y;
}
template<bool A>
static constexpr void map(Phanes::Core::Math::TVector2<T, A>& v1, const T* comp)
{
v1.x = comp[0];
v1.y = comp[1];
}
};
template<RealType T>
struct compute_vec2_add<T, false>
{
template<bool A>
static constexpr void map(Phanes::Core::Math::TVector2<T, A>& r, const Phanes::Core::Math::TVector2<T, A>& v1, const Phanes::Core::Math::TVector2<T, A>& v2)
{
r.x = v1.x + v2.x;
r.y = v1.y + v2.y;
}
template<bool A>
static constexpr void map(Phanes::Core::Math::TVector2<T, A>& r, const Phanes::Core::Math::TVector2<T, A>& v1, T s)
{
r.x = v1.x + s;
r.y = v1.y + s;
}
};
template<RealType T>
struct compute_vec2_sub<T, false>
{
template<bool A>
static constexpr void map(Phanes::Core::Math::TVector2<T, A>& r, const Phanes::Core::Math::TVector2<T, A>& v1, const Phanes::Core::Math::TVector2<T, A>& v2)
{
r.x = v1.x - v2.x;
r.y = v1.y - v2.y;
}
template<bool A>
static constexpr void map(Phanes::Core::Math::TVector2<T, A>& r, const Phanes::Core::Math::TVector2<T, A>& v1, T s)
{
r.x = v1.x - s;
r.y = v1.y - s;
}
};
template<RealType T>
struct compute_vec2_mul<T, false>
{
template<bool A>
static constexpr void map(Phanes::Core::Math::TVector2<T, A>& r, const Phanes::Core::Math::TVector2<T, A>& v1, const Phanes::Core::Math::TVector2<T, A>& v2)
{
r.x = v1.x * v2.x;
r.y = v1.y * v2.y;
}
template<bool A>
static constexpr void map(Phanes::Core::Math::TVector2<T, A>& r, const Phanes::Core::Math::TVector2<T, A>& v1, T s)
{
r.x = v1.x * s;
r.y = v1.y * s;
}
};
template<RealType T>
struct compute_vec2_div<T, false>
{
template<bool A>
static constexpr void map(Phanes::Core::Math::TVector2<T, A>& r, const Phanes::Core::Math::TVector2<T, A>& v1, const Phanes::Core::Math::TVector2<T, A>& v2)
{
r.x = v1.x / v2.x;
r.y = v1.y / v2.y;
}
template<bool A>
static constexpr void map(Phanes::Core::Math::TVector2<T, A>& r, const Phanes::Core::Math::TVector2<T, A>& v1, T s)
{
s = (T)1.0 / s;
r.x = v1.x * s;
r.y = v1.y * s;
}
};
template<RealType T>
struct compute_vec2_eq<T, false>
{
template<bool A>
static constexpr bool map(const Phanes::Core::Math::TVector2<T, A>& v1, const Phanes::Core::Math::TVector2<T, A>& v2)
{
return (Phanes::Core::Math::Abs(v1.x - v2.x) < P_FLT_INAC &&
Phanes::Core::Math::Abs(v1.y - v2.y) < P_FLT_INAC);
}
};
template<RealType T>
struct compute_vec2_ieq<T, false>
{
template<bool A>
static constexpr bool map(const Phanes::Core::Math::TVector2<T, A>& v1, const Phanes::Core::Math::TVector2<T, A>& v2)
{
return (Phanes::Core::Math::Abs(v1.x - v2.x) > P_FLT_INAC ||
Phanes::Core::Math::Abs(v1.y - v2.y) > P_FLT_INAC);
}
};
template<RealType T>
struct compute_vec2_inc<T, false>
{
template<bool A>
static constexpr void map(Phanes::Core::Math::TVector2<T, A>& r, const Phanes::Core::Math::TVector2<T, A>& v1)
{
r.x = v1.x + 1;
r.y = v1.y + 1;
}
};
template<RealType T>
struct compute_vec2_dec<T, false>
{
template<bool A>
static constexpr void map(Phanes::Core::Math::TVector2<T, A>& r, const Phanes::Core::Math::TVector2<T, A>& v1)
{
r.x = v1.x - 1;
r.y = v1.y - 1;
}
};
}

View File

@ -61,21 +61,13 @@ namespace Phanes::Core::Math::Detail
v1.w = (T)0.0;
}
/*static constexpr void map(Phanes::Core::Math::TVector3<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2, const Phanes::Core::Math::TVector2<T, false>& v3)
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2, T s)
{
v1.x = v2.x;
v1.y = v2.y;
v1.z = v3.x;
v1.w = v3.y;
v1.z = s;
}
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2, const Phanes::Core::Math::TVector2<T, false>& v3)
{
v1.x = v2.x;
v1.y = v2.y;
v1.z = v3.x;
v1.w = v3.y;
}*/
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& v1, const T* comp)
{

View File

@ -61,7 +61,7 @@ namespace Phanes::Core::Math::Detail
v1.w = w;
}
/*static constexpr void map(Phanes::Core::Math::TVector4<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2, const Phanes::Core::Math::TVector2<T, false>& v3)
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2, const Phanes::Core::Math::TVector2<T, false>& v3)
{
v1.x = v2.x;
v1.y = v2.y;
@ -69,13 +69,6 @@ namespace Phanes::Core::Math::Detail
v1.w = v3.y;
}
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2, const Phanes::Core::Math::TVector2<T, false>& v3)
{
v1.x = v2.x;
v1.y = v2.y;
v1.z = v3.x;
v1.w = v3.y;
}*/
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& v1, const T* comp)
{

View File

@ -1,4 +1,5 @@
#pragma once
#include "Core/public/Math/Vector3.hpp"
#include "Core/public/Math/Vector4.hpp"
// --- Vectors ------------------------
#include "Core/public/Math/Vector2.hpp" // <-- Includes Vector3/4 automatically

View File

@ -26,7 +26,6 @@ namespace Phanes::Core::Math {
template<RealType T> struct TColor;
template<RealType T> struct TLinearColor;
template<RealType T> struct TVector2;
template<RealType T> struct TRay;
template<RealType T> struct TLine;
template<RealType T> struct TPlane;
@ -44,6 +43,7 @@ namespace Phanes::Core::Math {
template<IntType T> struct TIntPoint2;
template<IntType T> struct TIntPoint3;
template<IntType T> struct TIntPoint4;
template<RealType T, bool A> struct TVector2;
template<RealType T, bool A> struct TVector3;
template<RealType T, bool A> struct TVector4;
@ -51,15 +51,6 @@ namespace Phanes::Core::Math {
* Specific instantiation of forward declarations.
*/
// TVector2
typedef TVector2<float> Vector2;
typedef TVector2<double> Vector2d;
typedef std::vector<Vector2> Vector2List;
typedef std::vector<Vector2d> Vector2Listd;
// TIntVector2
typedef TIntVector2<int> IntVector2;
typedef TIntVector2<long> IntVector2l;

View File

@ -1 +1,497 @@
#pragma once
#pragma once
#include <nmmintrin.h>
#include "Core/public/Math/SIMD/PhanesSIMDTypes.h"
#include "Core/public/Math/Boilerplate.h"
#include "Core/public/Math/MathCommon.hpp"
// Required includes
#include "Core/public/Math/Vector3.hpp"
#include "Core/public/Math/Vector4.hpp"
// ========== //
// Common //
// ========== //
namespace Phanes::Core::Math::SIMD
{
/// <summary>
/// Adds all scalars of the vector.
/// </summary>
/// <param name="v">Vector</param>
/// <returns>Sum stored in v[0:31].</returns>
Phanes::Core::Types::Vec4f32Reg vec4_hadd(const Phanes::Core::Types::Vec4f32Reg v)
{
Phanes::Core::Types::Vec4f32Reg r;
r.data[0] = (v.data[0] + v.data[1] + v.data[2] + v.data[3]);
return r;
}
/// <summary>
/// Adds all scalars of the vector.
/// </summary>
/// <param name="v">Vector</param>
/// <returns>Sum of components.</returns>
float vec4_hadd_cvtf32(const Phanes::Core::Types::Vec4f32Reg v)
{
return (v.data[0] + v.data[1] + v.data[2] + v.data[3]);
}
/// <summary>
/// Gets the absolute value of each scalar in the vector.
/// </summary>
/// <param name="v">Vector</param>
/// <returns>Vector with all components positive.</returns>
Phanes::Core::Types::Vec4f32Reg vec4_abs(const Phanes::Core::Types::Vec4f32Reg v)
{
Phanes::Core::Types::Vec4f32Reg r;
r.data[0] = Phanes::Core::Math::Abs(v.data[0]);
r.data[1] = Phanes::Core::Math::Abs(v.data[1]);
r.data[2] = Phanes::Core::Math::Abs(v.data[2]);
r.data[3] = Phanes::Core::Math::Abs(v.data[3]);
return r;
}
/// <summary>
/// Gets the dot product of the
/// </summary>
/// <param name="v1"></param>
/// <param name="v2"></param>
/// <returns></returns>
Phanes::Core::Types::Vec4f32Reg vec4_dot(const Phanes::Core::Types::Vec4f32Reg v1, const Phanes::Core::Types::Vec4f32Reg v2)
{
Phanes::Core::Types::Vec4f32Reg r;
r.data[0] = (v1.data[0] * v2.data[0] + v1.data[1] * v2.data[1] + v1.data[2] * v2.data[2] + v1.data[3] * v2.data[3]);
return r;
}
/// <summary>
/// Gets the dot product of the
/// </summary>
/// <param name="v1"></param>
/// <param name="v2"></param>
/// <returns></returns>
float vec4_dot_cvtf32(const Phanes::Core::Types::Vec4f32Reg v1, const Phanes::Core::Types::Vec4f32Reg v2)
{
return (v1.data[0] * v2.data[0] + v1.data[1] * v2.data[1] + v1.data[2] * v2.data[2] + v1.data[3] * v2.data[3]);
}
}
// ============ //
// TVector4 //
// ============ //
namespace Phanes::Core::Math::Detail
{
// Template class has already been defined and is included through: Storage.h -> Vector4.hpp -> SIMDIntrinsics.h -> PhanesVectorMathSEE.hpp
template<>
struct construct_vec4<float, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& v1, const TVector4<float, true>& v2)
{
v1.x = v2.x;
v1.y = v2.y;
v1.z = v2.z;
v1.w = v2.w;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& v1, float s)
{
v1.x = s;
v1.y = s;
v1.z = s;
v1.w = s;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& v1, float x, float y, float z, float w)
{
v1.x = x;
v1.y = y;
v1.z = z;
v1.w = w;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& v1, const Phanes::Core::Math::TVector2<float, false>& v2, const Phanes::Core::Math::TVector2<float, false>& v3)
{
v1.x = v2.x;
v1.y = v2.y;
v1.x = v3.x;
v1.y = v3.y;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& v1, const float* s)
{
v1.x = s[0];
v1.y = s[1];
v1.z = s[2];
v1.w = s[3];
}
};
template<>
struct compute_vec4_add<float, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& r, const Phanes::Core::Math::TVector4<float, true>& v1, const Phanes::Core::Math::TVector4<float, true>& v2)
{
r.x = v1.x + v2.x;
r.y = v1.y + v2.y;
r.z = v1.z + v2.z;
r.w = v1.w + v2.w;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& r, const Phanes::Core::Math::TVector4<float, true>& v1, float s)
{
r.x = v1.x + s;
r.y = v1.y + s;
r.z = v1.z + s;
r.w = v1.w + s;
}
};
template<>
struct compute_vec4_sub<float, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& r, const Phanes::Core::Math::TVector4<float, true>& v1, const Phanes::Core::Math::TVector4<float, true>& v2)
{
r.x = v1.x - v2.x;
r.y = v1.y - v2.y;
r.z = v1.z - v2.z;
r.w = v1.w - v2.w;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& r, const Phanes::Core::Math::TVector4<float, true>& v1, float s)
{
r.x = v1.x - s;
r.y = v1.y - s;
r.z = v1.z - s;
r.w = v1.w - s;
}
};
template<>
struct compute_vec4_mul<float, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& r, const Phanes::Core::Math::TVector4<float, true>& v1, const Phanes::Core::Math::TVector4<float, true>& v2)
{
r.x = v1.x * v2.x;
r.y = v1.y * v2.y;
r.z = v1.z * v2.z;
r.w = v1.w * v2.w;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& r, const Phanes::Core::Math::TVector4<float, true>& v1, float s)
{
r.x = v1.x * s;
r.y = v1.y * s;
r.z = v1.z * s;
r.w = v1.w * s;
}
};
template<>
struct compute_vec4_div<float, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& r, const Phanes::Core::Math::TVector4<float, true>& v1, const Phanes::Core::Math::TVector4<float, true>& v2)
{
r.x = v1.x / v2.x;
r.y = v1.y / v2.y;
r.z = v1.z / v2.z;
r.w = v1.w / v2.w;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& r, const Phanes::Core::Math::TVector4<float, true>& v1, float s)
{
s = 1.0f / s;
r.x = v1.x * s;
r.y = v1.y * s;
r.z = v1.z * s;
r.w = v1.w * s;
}
};
template<>
struct compute_vec4_inc<float, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& r, const Phanes::Core::Math::TVector4<float, true>& v1)
{
r.x = v1.x + 1;
r.y = v1.y + 1;
r.z = v1.z + 1;
r.w = v1.w + 1;
}
};
template<>
struct compute_vec4_dec<float, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& r, const Phanes::Core::Math::TVector4<float, true>& v1)
{
r.x = v1.x - 1;
r.y = v1.y - 1;
r.z = v1.z - 1;
r.w = v1.w - 1;
}
};
template<>
struct compute_vec4_eq<float, true>
{
static FORCEINLINE bool map(const Phanes::Core::Math::TVector4<float, true>& v1, const Phanes::Core::Math::TVector4<float, true>& v2)
{
return (Phanes::Core::Math::Abs(v1.x - v2.x) < P_FLT_INAC &&
Phanes::Core::Math::Abs(v1.y - v2.y) < P_FLT_INAC &&
Phanes::Core::Math::Abs(v1.z - v2.z) < P_FLT_INAC &&
Phanes::Core::Math::Abs(v1.w - v2.w) < P_FLT_INAC);
}
};
template<>
struct compute_vec4_ieq<float, true>
{
static FORCEINLINE bool map(const Phanes::Core::Math::TVector4<float, true>& v1, const Phanes::Core::Math::TVector4<float, true>& v2)
{
return (Phanes::Core::Math::Abs(v1.x - v2.x) > P_FLT_INAC ||
Phanes::Core::Math::Abs(v1.y - v2.y) > P_FLT_INAC ||
Phanes::Core::Math::Abs(v1.z - v2.z) > P_FLT_INAC ||
Phanes::Core::Math::Abs(v1.w - v2.w) > P_FLT_INAC);
}
};
// ============ //
// TVector3 //
// ============ //
template<>
struct construct_vec3<float, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector3<float, true>& v1, const TVector3<float, true>& v2)
{
v1.x = v2.x;
v1.y = v2.y;
v1.z = v2.z;
v1.w = 0.0f;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector3<float, true>& v1, float s)
{
v1.x = s;
v1.y = s;
v1.z = s;
v1.w = 0.0f;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector3<float, true>& v1, float x, float y, float z)
{
v1.x = x;
v1.y = y;
v1.z = z;
v1.w = 0.0f;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector3<float, true>& v1, const Phanes::Core::Math::TVector2<float, true>& v2, float s)
{
v1.x = v2.x;
v1.y = v2.y;
v1.z = s;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector3<float, true>& v1, const float* comp)
{
v1.x = comp[0];
v1.y = comp[1];
v1.z = comp[2];
v1.w = 0.0f;
}
};
template<> struct compute_vec3_eq<float, true> : public compute_vec4_eq<float, true>
{
static FORCEINLINE bool map(Phanes::Core::Math::TVector3<float, true>& v1, Phanes::Core::Math::TVector3<float, true>& v2)
{
return (Phanes::Core::Math::Abs(v1.x - v2.x) < P_FLT_INAC &&
Phanes::Core::Math::Abs(v1.y - v2.y) < P_FLT_INAC &&
Phanes::Core::Math::Abs(v1.z - v2.z) < P_FLT_INAC);
}
};
template<> struct compute_vec3_ieq<float, true> : public compute_vec4_ieq<float, true>
{
static FORCEINLINE bool map(Phanes::Core::Math::TVector3<float, true>& v1, Phanes::Core::Math::TVector3<float, true>& v2)
{
return (Phanes::Core::Math::Abs(v1.x - v2.x) > P_FLT_INAC ||
Phanes::Core::Math::Abs(v1.y - v2.y) > P_FLT_INAC ||
Phanes::Core::Math::Abs(v1.z - v2.z) > P_FLT_INAC);
}
};
template<> struct compute_vec3_add<float, true> : public compute_vec4_add<float, true> {};
template<> struct compute_vec3_sub<float, true> : public compute_vec4_sub<float, true> {};
template<> struct compute_vec3_mul<float, true> : public compute_vec4_mul<float, true> {};
template<> struct compute_vec3_div<float, true> : public compute_vec4_div<float, true> {};
template<> struct compute_vec3_inc<float, true> : public compute_vec4_inc<float, true> {};
template<> struct compute_vec3_dec<float, true> : public compute_vec4_dec<float, true> {};
// ============ //
// TVector2 //
// ============ //
template<>
struct construct_vec2<double, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& v1, const Phanes::Core::Math::TVector2<double, true>& v2)
{
v1.x = v2.x;
v1.y = v2.y;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& v1, double s)
{
v1.x = s;
v1.y = s;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& v1, double x, double y)
{
v1.x = x;
v1.y = y;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& v1, const double* comp)
{
v1.x = comp[0];
v1.y = comp[1];
}
};
template<>
struct compute_vec2_add<double, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, const Phanes::Core::Math::TVector2<double, true>& v2)
{
r.x = v1.x + v2.x;
r.y = v1.y + v2.y;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, double s)
{
r.x = v1.x + s;
r.y = v1.y + s;
}
};
template<>
struct compute_vec2_sub<double, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, const Phanes::Core::Math::TVector2<double, true>& v2)
{
r.x = v1.x - v2.x;
r.y = v1.y - v2.y;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, double s)
{
r.x = v1.x - s;
r.y = v1.y - s;
}
};
template<>
struct compute_vec2_mul<double, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, const Phanes::Core::Math::TVector2<double, true>& v2)
{
r.x = v1.x * v2.x;
r.y = v1.y * v2.y;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, double s)
{
r.x = v1.x * s;
r.y = v1.y * s;
}
};
template<>
struct compute_vec2_div<double, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, const Phanes::Core::Math::TVector2<double, true>& v2)
{
r.x = v1.x / v2.x;
r.y = v1.y / v2.y;
}
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, double s)
{
s = 1.0f / s;
r.x = v1.x * s;
r.y = v1.y * s;
}
};
template<>
struct compute_vec2_inc<double, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1)
{
r.x = v1.x + 1;
r.y = v1.y + 1;
}
};
template<>
struct compute_vec2_dec<double, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1)
{
r.x = v1.x - 1;
r.y = v1.y - 1;
}
};
template<>
struct compute_vec2_eq<double, true>
{
static FORCEINLINE bool map(const Phanes::Core::Math::TVector2<double, true>& v1, const Phanes::Core::Math::TVector2<double, true>& v2)
{
return (Phanes::Core::Math::Abs(v1.x - v2.x) < P_FLT_INAC &&
Phanes::Core::Math::Abs(v1.y - v2.y) < P_FLT_INAC);
}
};
template<>
struct compute_vec2_ieq<double, true>
{
static FORCEINLINE bool map(const Phanes::Core::Math::TVector2<double, true>& v1, const Phanes::Core::Math::TVector2<double, true>& v2)
{
return (Phanes::Core::Math::Abs(v1.x - v2.x) > P_FLT_INAC ||
Phanes::Core::Math::Abs(v1.y - v2.y) > P_FLT_INAC);
}
};
}

View File

@ -5,10 +5,10 @@
#include "Core/public/Math/SIMD/PhanesSIMDTypes.h"
#include "Core/public/Math/Boilerplate.h"
#include "Core/public/Math/MathCommon.hpp"
// -> For IntelliSense
// Required includes
#include "Core/public/Math/Vector3.hpp"
#include "Core/public/Math/Vector4.hpp"
// ========== //
@ -110,19 +110,11 @@ namespace Phanes::Core::Math::Detail
v1.comp = _mm_setr_ps(x, y, z, w);
}
/*static constexpr void map(Phanes::Core::Math::TVector4<float, false>& v1, const Phanes::Core::Math::TVector2<float, false>& v2, const Phanes::Core::Math::TVector2<float, false>& v3)
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& v1, const Phanes::Core::Math::TVector2<float, false>& v2, const Phanes::Core::Math::TVector2<float, false>& v3)
{
v1.comp = _mm_set_ps(v2.x, v2.y, v3.x, v3.y);
}
static constexpr void map(Phanes::Core::Math::TVector4<float, false>& v1, const Phanes::Core::Math::TVector2<float, false>& v2, const Phanes::Core::Math::TVector2<float, false>& v3)
{
v1.x = v2.x;
v1.y = v2.y;
v1.z = v3.x;
v1.w = v3.y;
}*/
static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& v1, const float* s)
{
v1.comp = _mm_loadu_ps(s);
@ -228,9 +220,9 @@ namespace Phanes::Core::Math::Detail
};
//// ============ //
//// TVector3 //
//// ============ //
// ============ //
// TVector3 //
// ============ //
template<>
@ -252,10 +244,10 @@ namespace Phanes::Core::Math::Detail
v1.comp = _mm_setr_ps(x, y, z, 0.0f);
}
/*static FORCEINLINE void map(Phanes::Core::Math::TVector3<float, true>& v1, const Phanes::Core::Math::TVector2<float, true>& v2, float s)
static FORCEINLINE void map(Phanes::Core::Math::TVector3<float, true>& v1, const Phanes::Core::Math::TVector2<float, true>& v2, float s)
{
v1.comp = _mm_set_ps(v2.x, v2.y, v3.x, v3.y);
}*/
v1.comp = _mm_set_ps(v2.x, v2.y, s, 0.0f);
}
static FORCEINLINE void map(Phanes::Core::Math::TVector3<float, true>& v1, const float* s)
{
@ -265,24 +257,169 @@ namespace Phanes::Core::Math::Detail
};
template<>
struct compute_vec3_inc<float, true>
template<> struct compute_vec3_eq<float, true> : public compute_vec4_eq<float, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector3<float, true>& r, const Phanes::Core::Math::TVector3<float, true>& v1)
static FORCEINLINE bool map(Phanes::Core::Math::TVector3<float, true>& v1, Phanes::Core::Math::TVector3<float, true>& v2)
{
r.comp = _mm_add_ps(v1.comp, _mm_set_ps(1.0f, 1.0f, 1.0f, 0.0f));
v1.comp = _mm_setr_ps(v1.x, v1.y, v1.z, 0.0f);
v2.comp = _mm_setr_ps(v2.x, v2.y, v2.z, 0.0f);
float r;
_mm_store_ps1(&r, _mm_cmpeq_ps(v1.comp, v2.comp));
return (r == 0xffffffff) ? true : false;
}
};
template<> struct compute_vec3_ieq<float, true> : public compute_vec4_ieq<float, true>
{
static FORCEINLINE bool map(Phanes::Core::Math::TVector3<float, true>& v1, Phanes::Core::Math::TVector3<float, true>& v2)
{
v1.comp = _mm_setr_ps(v1.x, v1.y, v1.z, 0.0f);
v2.comp = _mm_setr_ps(v2.x, v2.y, v2.z, 0.0f);
float r;
_mm_store_ps1(&r, _mm_cmpneq_ps(v1.comp, v2.comp));
return (r == 0xffffffff) ? true : false;
}
};
template<> struct compute_vec3_add<float, true> : public compute_vec4_add<float, true> {};
template<> struct compute_vec3_sub<float, true> : public compute_vec4_sub<float, true> {};
template<> struct compute_vec3_mul<float, true> : public compute_vec4_mul<float, true> {};
template<> struct compute_vec3_div<float, true> : public compute_vec4_div<float, true> {};
template<> struct compute_vec3_inc<float, true> : public compute_vec4_inc<float, true> {};
template<> struct compute_vec3_dec<float, true> : public compute_vec4_dec<float, true> {};
// ============ //
// TVector2 //
// ============ //
template<>
struct construct_vec2<double, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& v1, const TVector2<double, true>& v2)
{
v1.comp = _mm_setr_pd(v2.x, v2.y);
}
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& v1, double s)
{
v1.comp = _mm_set_pd1(s);
}
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& v1, double x, double y)
{
v1.comp = _mm_setr_pd(x, y);
}
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& v1, const double* s)
{
v1.comp = _mm_loadu_pd(s);
}
};
template<>
struct compute_vec3_dec<float, true>
struct compute_vec2_add<double, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector3<float, true>& r, const Phanes::Core::Math::TVector3<float, true>& v1)
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, const Phanes::Core::Math::TVector2<double, true>& v2)
{
r.comp = _mm_sub_ps(v1.comp, _mm_set_ps(1.0f, 1.0f, 1.0f, 0.0f));
r.comp = _mm_add_pd(v1.comp, v2.comp);
}
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, double s)
{
r.comp = _mm_add_pd(v1.comp, _mm_set1_pd(s));
}
};
template<> struct compute_vec3_add<float, true> : public compute_vec4_add<float, true> {};
template<>
struct compute_vec2_sub<double, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, const Phanes::Core::Math::TVector2<double, true>& v2)
{
r.comp = _mm_sub_pd(v1.comp, v2.comp);
}
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, double s)
{
r.comp = _mm_sub_pd(v1.comp, _mm_set1_pd(s));
}
};
template<>
struct compute_vec2_mul<double, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, const Phanes::Core::Math::TVector2<double, true>& v2)
{
r.comp = _mm_mul_pd(v1.comp, v2.comp);
}
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, double s)
{
r.comp = _mm_mul_pd(v1.comp, _mm_set1_pd(s));
}
};
template<>
struct compute_vec2_div<double, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, const Phanes::Core::Math::TVector2<double, true>& v2)
{
r.comp = _mm_div_pd(v1.comp, v2.comp);
}
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1, double s)
{
r.comp = _mm_div_pd(v1.comp, _mm_set1_pd(s));
}
};
template<>
struct compute_vec2_inc<double, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1)
{
r.comp = _mm_add_pd(v1.comp, _mm_set1_pd(1.0f));
}
};
template<>
struct compute_vec2_dec<double, true>
{
static FORCEINLINE void map(Phanes::Core::Math::TVector2<double, true>& r, const Phanes::Core::Math::TVector2<double, true>& v1)
{
r.comp = _mm_sub_pd(v1.comp, _mm_set1_pd(1.0f));
}
};
template<>
struct compute_vec2_eq<double, true>
{
static FORCEINLINE bool map(const Phanes::Core::Math::TVector2<double, true>& v1, const Phanes::Core::Math::TVector2<double, true>& v2)
{
double r;
_mm_store1_pd(&r, _mm_cmpeq_pd(v1.comp, v2.comp));
return (r == 0xffffffff) ? true : false;
}
};
template<>
struct compute_vec2_ieq<double, true>
{
static FORCEINLINE bool map(const Phanes::Core::Math::TVector2<double, true>& v1, const Phanes::Core::Math::TVector2<double, true>& v2)
{
double r;
_mm_store1_pd(&r, _mm_cmpneq_pd(v1.comp, v2.comp));
return (r == 0xffffffff) ? true : false;
}
};
}

View File

@ -264,8 +264,7 @@
# error P_INTRINSICS must be defined by the user, when P_FORCE_INTRINSICS is used.
# endif
#else
#elif !defined(P_FORCE_FPU)
# ifdef __AVX2__
# define P_AVX2__ 1
# elif defined(__AVX__)
@ -274,7 +273,6 @@
# define P_SSE__ 1
# endif
#endif // !P_FORCE_INTRINSICS
#ifdef P_AVX2__
@ -312,10 +310,10 @@
#if defined(P_FORCE_FPU) // Force, that no intrinsics may be used.
# define P_INTRINSICS P_INTRINSICS_FPU
# undef P_AVX2__
# undef P_AVX__
# undef P_SSE__
# undef P_SSE__
# define P_AVX2__ 0
# define P_AVX__ 0
# define P_SSE__ 0
# define P_SSE__ 0
#else
# if (P_AVX__ == 1) && (P_AVX2__ == 0)
# define P_INTRINSICS P_INTRINSICS_AVX

View File

@ -3,9 +3,10 @@
#include "Core/public/Math/Boilerplate.h"
#include "Core/public/Math/MathCommon.hpp"
#include "Core/public/Math/MathAbstractTypes.h"
#include "Core/public/Math/MathFwd.h"
#include "Core/public/Math/SIMD/Storage.h"
#ifndef P_DEBUG
#pragma warning(disable : 4244)
#endif
@ -29,7 +30,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
template<RealType T, bool A>
struct TVector2 {
public:
@ -67,7 +68,11 @@ namespace Phanes::Core::Math {
* @note Components are split into x and y. Access and manipulation is possible by these variables.
*/
Real* comp;
union
{
typename SIMD::Storage<2, T, SIMD::use_simd<T, 2, A>::value>::type comp;
typename SIMD::Storage<2, T, SIMD::use_simd<T, 2, A>::value>::type data;
};
};
@ -86,27 +91,7 @@ namespace Phanes::Core::Math {
* Copy constructor
*/
TVector2(const TVector2<Real>& v)
{
memcpy(this->comp, comp, sizeof(T) * 2);
}
/**
* Move constructor
*/
TVector2(TVector2<Real>&& v)
{
this->comp = v.comp;
v.comp = nullptr;
}
/**
* Convert other type of vector
*/
template<RealType FloatType>
explicit TVector2(const TVector2<FloatType>& v) : x((T)v.x), y((T)v.y) {};
TVector2(const TVector2<Real, A>& v);
/**
* Construct Vector from xy components.
@ -115,33 +100,19 @@ namespace Phanes::Core::Math {
* @param(y) Y component
*/
TVector2(const Real x, const Real y) : x(x), y(y) {};
TVector2(const Real x, const Real y);
/**
* Construct Vector from two component array.
*
* @param(comp) Array of components
*/
explicit TVector2(const Real* comp)
{
memcpy(this->comp, comp, sizeof(T) * 2);
}
/**
* Constructs a vector pointing from start to end.
*
* @param(start) Startingpoint
* @param(end) Endpoint
*/
TVector2(const TPoint2<Real>& start, const TPoint2<Real>& end)
{
this->x = end.x - start.x;
this->y = end.y - start.y;
}
/// <summary>
/// Construct vector from array.
/// </summary>
/// <param name="comp">Array of at least 2 items.</param>
TVector2(const Real* comp);
/// <summary>
/// Construct vector by broadcasting one scalar into all components.
/// </summary>
/// <param name="s">Scalar</param>
TVector2(Real s);
};
// ====================== //
@ -149,14 +120,14 @@ namespace Phanes::Core::Math {
// ====================== //
/**
* Addition operation on same TVector2<T> (this) by a floating point value.
* Addition operation on same TVector2<T, false> (this) by a floating point value.
*
* @param(v1) Vector to add to
* @param(s) Floating point to add
*/
template<RealType T>
TVector2<T> operator+= (TVector2<T>& v1, T s)
TVector2<T, false> operator+= (TVector2<T, false>& v1, T s)
{
v1.x += s;
v1.y += s;
@ -165,14 +136,14 @@ namespace Phanes::Core::Math {
}
/**
* Addition operation on same TVector2<T> (this) by a another TVector2<T>.
* Addition operation on same TVector2<T, false> (this) by a another TVector2<T, false>.
*
* @param(v1) Vector to add to
* @param(v2) Vector to add
*/
template<RealType T>
TVector2<T> operator+= (TVector2<T>& v1, const TVector2<T>& v2)
TVector2<T, false> operator+= (TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
v1.x += v2.x;
v1.y += v2.y;
@ -181,14 +152,14 @@ namespace Phanes::Core::Math {
}
/**
* Substraction operation on same TVector2<T> (this) by a floating point.
* Substraction operation on same TVector2<T, false> (this) by a floating point.
*
* @param(v1) Vector to substract from
* @param(v2) Floating point to substract
*/
template<RealType T>
TVector2<T> operator-= (TVector2<T>& v1, T s)
TVector2<T, false> operator-= (TVector2<T, false>& v1, T s)
{
v1.x -= s;
v1.y -= s;
@ -197,14 +168,14 @@ namespace Phanes::Core::Math {
}
/**
* Substraction operation on same TVector2<T> (this) by a another TVector2<T>.
* Substraction operation on same TVector2<T, false> (this) by a another TVector2<T, false>.
*
* @param(v1) Vector to substract from
* @param(v2) Vector to substract
*/
template<RealType T>
TVector2<T> operator-= (TVector2<T>& v1, const TVector2<T>& v2)
TVector2<T, false> operator-= (TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
v1.x -= v2.x;
v1.y -= v2.y;
@ -213,14 +184,14 @@ namespace Phanes::Core::Math {
}
/**
* Multiplication of TVector2<T> (this) with a floating point.
* Multiplication of TVector2<T, false> (this) with a floating point.
*
* @param(v1) Vector to multiply with
* @param(s Floating point to multiply with
*/
template<RealType T>
TVector2<T> operator*= (TVector2<T>& v1, T s)
TVector2<T, false> operator*= (TVector2<T, false>& v1, T s)
{
v1.x *= s;
v1.y *= s;
@ -236,7 +207,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> operator/= (TVector2<T>& v1, T s)
TVector2<T, false> operator/= (TVector2<T, false>& v1, T s)
{
s = 1.0f / s;
v1.x *= s;
@ -246,7 +217,7 @@ namespace Phanes::Core::Math {
}
/**
* Scale of Vector by floating point. (> Creates a new TVector2<T>)
* Scale of Vector by floating point. (> Creates a new TVector2<T, false>)
*
* @param(v1) Vector to multiply with
* @param(s Floating point to multiply with
@ -255,13 +226,13 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> operator* (const TVector2<T>& v1, T s)
TVector2<T, false> operator* (const TVector2<T, false>& v1, T s)
{
return TVector2<T>(v1.x * s, v1.y * s);
return TVector2<T, false>(v1.x * s, v1.y * s);
}
/**
* Division of Vector by floating point. (> Creates another TVector2<T>)
* Division of Vector by floating point. (> Creates another TVector2<T, false>)
*
* @param(v1) Vector to multiply with
* @param(s Floating point to divide with
@ -270,14 +241,14 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> operator/ (const TVector2<T>& v1, T s)
TVector2<T, false> operator/ (const TVector2<T, false>& v1, T s)
{
s = 1.0f / s;
return TVector2<T>(v1.x * s, v1.y * s);
return TVector2<T, false>(v1.x * s, v1.y * s);
}
/**
* Scale of Vector by floating point. (> Creates a new TVector2<T>)
* Scale of Vector by floating point. (> Creates a new TVector2<T, false>)
*
* @param(v1) Vector to multiply with
* @param(s Floating point to multiply with
@ -286,7 +257,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
inline TVector2<T> operator* (T s, const TVector2<T>& v1)
inline TVector2<T, false> operator* (T s, const TVector2<T, false>& v1)
{
return v1 * s;
}
@ -301,7 +272,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
inline TVector2<T> operator/ (T s, const TVector2<T>& v1)
inline TVector2<T, false> operator/ (T s, const TVector2<T, false>& v1)
{
s = 1.0f / s;
return v1 * s;
@ -319,7 +290,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
inline T operator* (const TVector2<T>& v1, const TVector2<T>& v2)
inline T operator* (const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
return v1.x * v2.x + v1.y * v2.y;
}
@ -334,9 +305,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> operator+ (const TVector2<T>& v1, T s)
TVector2<T, false> operator+ (const TVector2<T, false>& v1, T s)
{
return TVector2<T>(v1.x + s, v1.y + s);
return TVector2<T, false>(v1.x + s, v1.y + s);
}
/**
@ -349,9 +320,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> operator+ (const TVector2<T>& v1, const TVector2<T>& v2)
TVector2<T, false> operator+ (const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
return TVector2<T>(v1.x + v2.x, v1.y + v2.y);
return TVector2<T, false>(v1.x + v2.x, v1.y + v2.y);
}
/**
@ -364,9 +335,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> operator- (const TVector2<T>& v1, T s)
TVector2<T, false> operator- (const TVector2<T, false>& v1, T s)
{
return TVector2<T>(v1.x - s, v1.y - s);
return TVector2<T, false>(v1.x - s, v1.y - s);
}
/**
@ -379,9 +350,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> operator- (const TVector2<T>& v1, const TVector2<T>& v2)
TVector2<T, false> operator- (const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
return TVector2<T>(v1.x - v2.x, v1.y - v2.y);
return TVector2<T, false>(v1.x - v2.x, v1.y - v2.y);
}
/**
@ -391,9 +362,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> operator- (const TVector2<T>& v1)
TVector2<T, false> operator- (const TVector2<T, false>& v1)
{
return TVector2<T>&(-v1.x, -v1.y);
return TVector2<T, false>&(-v1.x, -v1.y);
}
@ -408,7 +379,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
bool operator== (const TVector2<T>& v1, const TVector2<T>& v2)
bool operator== (const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
return (abs(v1.x - v1.x) < P_FLT_INAC && abs(v1.y - v1.y) < P_FLT_INAC);
}
@ -425,7 +396,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
bool operator!= (const TVector2<T>& v1, const TVector2<T>& v2)
bool operator!= (const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
return (abs(v1.x - v1.x) > P_FLT_INAC || abs(v1.y - v1.y) > P_FLT_INAC);
}
@ -444,7 +415,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
T Magnitude(const TVector2<T>& v1)
T Magnitude(const TVector2<T, false>& v1)
{
return sqrtf(v1.x * v1.x + v1.y * v1.y);
}
@ -453,7 +424,7 @@ namespace Phanes::Core::Math {
* @see [FUNC]Magnitude
*/
template<RealType T>
FORCEINLINE T Length(const TVector2<T>& v1) { return Magnitude(v1); };
FORCEINLINE T Length(const TVector2<T, false>& v1) { return Magnitude(v1); };
/**
* Square of magnitude of Vector
@ -464,7 +435,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
T SqrMagnitude(const TVector2<T>& v1)
T SqrMagnitude(const TVector2<T, false>& v1)
{
return v1.x * v1.x + v1.y * v1.y;
}
@ -473,7 +444,7 @@ namespace Phanes::Core::Math {
* @see [FUNC]SqrMagnitude
*/
template<RealType T>
FORCEINLINE T SqrLength(const TVector2<T>& v1) { return SqrMagnitude(v1); };
FORCEINLINE T SqrLength(const TVector2<T, false>& v1) { return SqrMagnitude(v1); };
/**
* Normalize Vector
@ -482,7 +453,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> NormalizeV(TVector2<T>& v1)
TVector2<T, false> NormalizeV(TVector2<T, false>& v1)
{
float vecNorm = Magnitude(v1);
v1 /= (vecNorm < P_FLT_INAC) ? 1 : vecNorm;
@ -498,7 +469,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> UnsafeNormalizeV(TVector2<T>& v1)
TVector2<T, false> UnsafeNormalizeV(TVector2<T, false>& v1)
{
v1 /= Magnitude(v1);
@ -513,7 +484,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
T Angle(const TVector2<T>& v1, const TVector2<T>& v2)
T Angle(const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
return acos((v1 * v2) / Magnitude(v1) * Magnitude(v2));
}
@ -526,7 +497,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
T CosineAngle(const TVector2<T>& v1, const TVector2<T>& v2)
T CosineAngle(const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
return (v1 * v2) / Magnitude(v1) * Magnitude(v2);
}
@ -538,7 +509,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> SignVectorV(TVector2<T>& v1)
TVector2<T, false> SignVectorV(TVector2<T, false>& v1)
{
v1.x = (v1.x >= 0) ? 1 : -1;
v1.y = (v1.y >= 0) ? 1 : -1;
@ -554,7 +525,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> BindToSquareV(TVector2<T>& v1, T radius)
TVector2<T, false> BindToSquareV(TVector2<T, false>& v1, T radius)
{
float k = (abs(v1.x) > abs(v1.y)) ? abs(radius / v1.x) : abs(radius / v1.y);
v1 *= k;
@ -570,7 +541,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> ClampToSquareV(TVector2<T>& v1, T radius)
TVector2<T, false> ClampToSquareV(TVector2<T, false>& v1, T radius)
{
float prime = (abs(v1.x) > abs(v1.y)) ? v1.x : v1.y;
float k = (prime > radius) ? abs(radius / prime) : 1.0f;
@ -587,7 +558,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
inline T DotP(const TVector2<T>& v1, const TVector2<T>& v2)
inline T DotP(const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
return v1.x * v2.x + v1.y * v2.y;
}
@ -602,7 +573,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> MaxV(TVector2<T>& v1, const TVector2<T>& v2)
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);
@ -620,7 +591,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> MinV(TVector2<T>& v1, const TVector2<T>& v2)
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);
@ -637,7 +608,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> GetPerpendicularV(TVector2<T>& v1)
TVector2<T, false> GetPerpendicularV(TVector2<T, false>& v1)
{
T x = v1.x;
v1.x = v1.y;
@ -657,7 +628,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> GetReversePerpendicularV(TVector2<T>& v1)
TVector2<T, false> GetReversePerpendicularV(TVector2<T, false>& v1)
{
T x = v1.x;
v1.x = -v1.y;
@ -676,7 +647,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> ScaleV(TVector2<T>& v1, const TVector2<T>& v2)
TVector2<T, false> ScaleV(TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
v1.x *= v2.x;
v1.y *= v2.y;
@ -693,7 +664,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> CompInverseV(TVector2<T>& v1)
TVector2<T, false> CompInverseV(TVector2<T, false>& v1)
{
v1.x = 1.0f / v1.x;
v1.y = 1.0f / v1.y;
@ -711,7 +682,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> ReflectV(TVector2<T>& v1, const TVector2<T>& normal)
TVector2<T, false> ReflectV(TVector2<T, false>& v1, const TVector2<T, false>& normal)
{
Set(v1, v1 - (2 * (v1 * normal) * normal));
@ -726,7 +697,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> Set(TVector2<T>& v1, const TVector2<T>& v2)
TVector2<T, false> Set(TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
v1 = v2;
@ -741,7 +712,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> Set(TVector2<T>& v1, T x, T y)
TVector2<T, false> Set(TVector2<T, false>& v1, T x, T y)
{
v1.x = x;
v1.y = y;
@ -758,7 +729,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> RotateV(TVector2<T>& v1, T angle)
TVector2<T, false> RotateV(TVector2<T, false>& v1, T angle)
{
float sinAngle = sin(angle);
float cosAngle = cos(angle);
@ -781,7 +752,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
FORCEINLINE TVector2<T> ClockwiseRotateV(TVector2<T>& v1, T angle)
FORCEINLINE TVector2<T, false> ClockwiseRotateV(TVector2<T, false>& v1, T angle)
{
RotateV(v1, -angle);
@ -795,7 +766,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> NegateV(TVector2<T>& v1)
TVector2<T, false> NegateV(TVector2<T, false>& v1)
{
v1.x = -v1.x;
v1.y = -v1.y;
@ -811,7 +782,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
inline bool IsNormalized(const TVector2<T>& v1, T threshold = P_FLT_INAC)
inline bool IsNormalized(const TVector2<T, false>& v1, T threshold = P_FLT_INAC)
{
return (SqrMagnitude(v1) < threshold);
}
@ -829,7 +800,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
inline bool IsPerpendicular(const TVector2<T>& v1, const TVector2<T>& v2, T threshold = P_FLT_INAC)
inline bool IsPerpendicular(const TVector2<T, false>& v1, const TVector2<T, false>& v2, T threshold = P_FLT_INAC)
{
return (abs(DotP(v1, v2)) < threshold);
}
@ -847,7 +818,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
inline bool IsParallel(const TVector2<T>& v1, const TVector2<T>& v2, T threshold = 1.0f - P_FLT_INAC)
inline bool IsParallel(const TVector2<T, false>& v1, const TVector2<T, false>& v2, T threshold = 1.0f - P_FLT_INAC)
{
return (abs(DotP(v1, v2)) > threshold);
}
@ -865,7 +836,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
inline bool IsCoincident(const TVector2<T>& v1, const TVector2<T>& v2, T threshold = 1.0f - P_FLT_INAC)
inline bool IsCoincident(const TVector2<T, false>& v1, const TVector2<T, false>& v2, T threshold = 1.0f - P_FLT_INAC)
{
return (DotP(v1, v2) > threshold);
}
@ -880,7 +851,7 @@ namespace Phanes::Core::Math {
*/
//
//Matrix2 OuterProduct(const TVector2<T>& v1, const TVector2<T>& v2);
//Matrix2 OuterProduct(const TVector2<T, false>& v1, const TVector2<T, false>& v2);
// ============================================================== //
@ -898,9 +869,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> Reflect(const TVector2<T>& v1, const TVector2<T>& normal)
TVector2<T, false> Reflect(const TVector2<T, false>& v1, const TVector2<T, false>& normal)
{
return TVector2<T>(v1 - (2 * (v1 * normal) * normal));
return TVector2<T, false>(v1 - (2 * (v1 * normal) * normal));
}
/**
@ -913,9 +884,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> Scale(const TVector2<T>& v1, const TVector2<T>& v2)
TVector2<T, false> Scale(const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
return TVector2<T>(v1.x * v2.x, v1.y * v2.y);
return TVector2<T, false>(v1.x * v2.x, v1.y * v2.y);
}
/**
@ -927,9 +898,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> CompInverse(const TVector2<T>& v1)
TVector2<T, false> CompInverse(const TVector2<T, false>& v1)
{
return TVector2<T>(1.0f / v1.x, 1.0f / v1.y);
return TVector2<T, false>(1.0f / v1.x, 1.0f / v1.y);
}
/**
@ -941,9 +912,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> Negate(const TVector2<T>& v1)
TVector2<T, false> Negate(const TVector2<T, false>& v1)
{
return TVector2<T>(-v1.x, -v1.y);
return TVector2<T, false>(-v1.x, -v1.y);
}
/**
@ -955,9 +926,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> GetPerpendicular(const TVector2<T>& v1)
TVector2<T, false> GetPerpendicular(const TVector2<T, false>& v1)
{
return TVector2<T>(v1.y, -v1.x);
return TVector2<T, false>(v1.y, -v1.x);
}
/**
@ -969,9 +940,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> GetReversePerpendicular(const TVector2<T>& v1)
TVector2<T, false> GetReversePerpendicular(const TVector2<T, false>& v1)
{
return TVector2<T>(-v1.y, v1.x);
return TVector2<T, false>(-v1.y, v1.x);
}
/**
@ -984,9 +955,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> Min(const TVector2<T>& v1, const TVector2<T>& v2)
TVector2<T, false> Min(const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
return TVector2<T>(Phanes::Core::Math::Min(v1.x, v2.x), Phanes::Core::Math::Min(v1.y, v2.y));
return TVector2<T, false>(Phanes::Core::Math::Min(v1.x, v2.x), Phanes::Core::Math::Min(v1.y, v2.y));
}
/**
@ -999,9 +970,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> Max(const TVector2<T>& v1, const TVector2<T>& v2)
TVector2<T, false> Max(const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
return TVector2<T>(Phanes::Core::Math::Max(v1.x, v2.x), Phanes::Core::Math::Max(v1.y, v2.y));
return TVector2<T, false>(Phanes::Core::Math::Max(v1.x, v2.x), Phanes::Core::Math::Max(v1.y, v2.y));
}
/**
@ -1013,7 +984,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> Normalize(const TVector2<T>& v1)
TVector2<T, false> Normalize(const TVector2<T, false>& v1)
{
float vecNorm = Magnitude(v1);
return (vecNorm < P_FLT_INAC) ? PZeroVector2(T) : (v1 / vecNorm);
@ -1029,7 +1000,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> UnsafeNormalize(const TVector2<T>& v1)
TVector2<T, false> UnsafeNormalize(const TVector2<T, false>& v1)
{
return (v1 / Magnitude(v1));
}
@ -1043,9 +1014,9 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> SignVector(const TVector2<T>& v1)
TVector2<T, false> SignVector(const TVector2<T, false>& v1)
{
return TVector2<T>((v1.x >= 0) ? 1 : -1, (v1.y >= 0) ? 1 : -1);
return TVector2<T, false>((v1.x >= 0) ? 1 : -1, (v1.y >= 0) ? 1 : -1);
}
/**
@ -1058,7 +1029,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> BindToSquare(const TVector2<T>& v1, T radius)
TVector2<T, false> BindToSquare(const TVector2<T, false>& v1, T radius)
{
float k = (abs(v1.x) > abs(v1.y)) ? abs(radius / v1.x) : abs(radius / v1.y);
return v1 * k;
@ -1074,7 +1045,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> ClampToSquare(const TVector2<T>& v1, T radius)
TVector2<T, false> ClampToSquare(const TVector2<T, false>& v1, T radius)
{
float prime = (abs(v1.x) > abs(v1.y)) ? v1.x : v1.y;
float k = (prime > radius) ? abs(radius / prime) : 1.0f;
@ -1095,7 +1066,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> Lerp(const TVector2<T>& startVec, const TVector2<T>& destVec, T t)
TVector2<T, false> Lerp(const TVector2<T, false>& startVec, const TVector2<T, false>& destVec, T t)
{
t = Phanes::Core::Math::Clamp(t, (T)0.0, (T)1.0);
@ -1115,7 +1086,7 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> LerpUnclamped(const TVector2<T>& startVec, const TVector2<T>& destVec, T t)
TVector2<T, false> LerpUnclamped(const TVector2<T, false>& startVec, const TVector2<T, false>& destVec, T t)
{
return (t * destVec) + ((1 - t) * startVec);
}
@ -1132,12 +1103,12 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> Rotate(const TVector2<T>& v1, T angle)
TVector2<T, false> Rotate(const TVector2<T, false>& v1, T angle)
{
float sinAngle = sin(angle);
float cosAngle = cos(angle);
return TVector2<T>(v1.x * cosAngle - v1.y * sinAngle,
return TVector2<T, false>(v1.x * cosAngle - v1.y * sinAngle,
v1.y * cosAngle + v1.x * sinAngle);
}
@ -1152,11 +1123,15 @@ namespace Phanes::Core::Math {
*/
template<RealType T>
TVector2<T> ClockwiseRotate(const TVector2<T>& v1, T angle)
TVector2<T, false> ClockwiseRotate(const TVector2<T, false>& v1, T angle)
{
return Rotate(v1, -angle);
}
} // phanes::core::math::coretypes
#endif // !VECTOR2_H
#endif // !VECTOR2_H
#include "Core/public/Math/Vector2.inl"

View File

@ -0,0 +1,205 @@
#pragma once
#include "Core/public/Math/Boilerplate.h"
#include "Core/public/Math/Detail/Vector2Decl.inl"
#include "Core/public/Math/SIMD/SIMDIntrinsics.h"
#include "Core/public/Math/SIMD/PhanesSIMDTypes.h"
namespace Phanes::Core::Math
{
template<RealType T, bool A>
TVector2<T, A>::TVector2(const TVector2<Real, A>& v)
{
Detail::construct_vec2<T, SIMD::use_simd<T, 2, A>::value>::map(*this, v);
}
template<RealType T, bool A>
TVector2<T, A>::TVector2(Real _x, Real _y)
{
Detail::construct_vec2<T, SIMD::use_simd<T, 2, A>::value>::map(*this, _x, _y);
}
template<RealType T, bool A>
TVector2<T, A>::TVector2(Real s)
{
Detail::construct_vec2<T, SIMD::use_simd<T, 2, A>::value>::map(*this, s);
}
template<RealType T, bool A>
TVector2<T, A>::TVector2(const Real* comp)
{
Detail::construct_vec2<T, SIMD::use_simd<T, 2, A>::value>::map(*this, comp);
}
template<RealType T, bool A>
TVector2<T, A> operator+=(TVector2<T, A>& v1, const TVector2<T, A>& v2)
{
Detail::compute_vec2_add<T, SIMD::use_simd<T, 2, A>::value>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool A>
TVector2<T, A> operator+=(TVector2<T, A>& v1, T s)
{
Detail::compute_vec2_add<T, SIMD::use_simd<T, 2, A>::value>::map(v1, v1, s);
return v1;
}
template<RealType T, bool A>
TVector2<T, A> operator-=(TVector2<T, A>& v1, const TVector2<T, A>& v2)
{
Detail::compute_vec2_sub<T, SIMD::use_simd<T, 2, A>::value>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool A>
TVector2<T, A> operator-=(TVector2<T, A>& v1, T s)
{
Detail::compute_vec2_sub<T, SIMD::use_simd<T, 2, A>::value>::map(v1, v1, s);
return v1;
}
template<RealType T, bool A>
TVector2<T, A> operator*=(TVector2<T, A>& v1, const TVector2<T, A>& v2)
{
Detail::compute_vec2_mul<T, SIMD::use_simd<T, 2, A>::value>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool A>
TVector2<T, A> operator*=(TVector2<T, A>& v1, T s)
{
Detail::compute_vec2_mul<T, SIMD::use_simd<T, 2, A>::value>::map(v1, v1, s);
return v1;
}
template<RealType T, bool A>
TVector2<T, A> operator/=(TVector2<T, A>& v1, const TVector2<T, A>& v2)
{
Detail::compute_vec2_div<T, SIMD::use_simd<T, 2, A>::value>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool A>
TVector2<T, A> operator/=(TVector2<T, A>& v1, T s)
{
Detail::compute_vec2_div<T, SIMD::use_simd<T, 2, A>::value>::map(v1, v1, s);
return v1;
}
template<RealType T, bool A>
TVector2<T, A> operator+(TVector2<T, A>& v1, const TVector2<T, A>& v2)
{
TVector2<T, A> r;
Detail::compute_vec2_add<T, SIMD::use_simd<T, 2, A>::value>::map(r, v1, v2);
return r;
}
template<RealType T, bool A>
TVector2<T, A> operator+(TVector2<T, A>& v1, T s)
{
TVector2<T, A> r;
Detail::compute_vec2_add<T, SIMD::use_simd<T, 2, A>::value>::map(r, v1, s);
return r;
}
template<RealType T, bool A>
TVector2<T, A> operator-(TVector2<T, A>& v1, const TVector2<T, A>& v2)
{
TVector2<T, A> r;
Detail::compute_vec2_sub<T, SIMD::use_simd<T, 2, A>::value>::map(r, v1, v2);
return r;
}
template<RealType T, bool A>
TVector2<T, A> operator-(TVector2<T, A>& v1, T s)
{
TVector2<T, A> r;
Detail::compute_vec2_sub<T, SIMD::use_simd<T, 2, A>::value>::map(r, v1, s);
return r;
}
template<RealType T, bool A>
TVector2<T, A> operator*(TVector2<T, A>& v1, const TVector2<T, A>& v2)
{
TVector2<T, A> r;
Detail::compute_vec2_mul<T, SIMD::use_simd<T, 2, A>::value>::map(r, v1, v2);
return r;
}
template<RealType T, bool A>
TVector2<T, A> operator*(TVector2<T, A>& v1, T s)
{
TVector2<T, A> r;
Detail::compute_vec2_mul<T, SIMD::use_simd<T, 2, A>::value>::map(r, v1, s);
return r;
}
template<RealType T, bool A>
TVector2<T, A> operator/(TVector2<T, A>& v1, const TVector2<T, A>& v2)
{
TVector2<T, A> r;
Detail::compute_vec2_div<T, SIMD::use_simd<T, 2, A>::value>::map(r, v1, v2);
return r;
}
template<RealType T, bool A>
TVector2<T, A> operator/(TVector2<T, A>& v1, T s)
{
TVector2<T, A> r;
Detail::compute_vec2_div<T, SIMD::use_simd<T, 2, A>::value>::map(r, v1, s);
return r;
}
// Comparision
template<RealType T, bool A>
bool operator==(const TVector2<T, A>& v1, const TVector2<T, A>& v2)
{
return Detail::compute_vec2_eq<T, SIMD::use_simd<T, 2, A>::value>::map(v1, v2);
}
template<RealType T, bool A>
bool operator!=(const TVector2<T, A>& v1, const TVector2<T, A>& v2)
{
return Detail::compute_vec2_ieq<T, SIMD::use_simd<T, 2, A>::value>::map(v1, v2);
}
// Inc- / Decrement
template<RealType T, bool A>
TVector2<T, A>& operator++(TVector2<T, A>& v1)
{
Detail::compute_vec2_inc<T, SIMD::use_simd<T, 2, A>::value>::map(v1);
return v1;
}
template<RealType T, bool A>
TVector2<T, A>& operator--(TVector2<T, A>& v1)
{
Detail::compute_vec2_inc<T, SIMD::use_simd<T, 2, A>::value>::map(v1);
return v1;
}
template<RealType T, bool A>
TVector2<T, A>& operator++(TVector2<T, A>& v1, int)
{
return ++v1;
}
template<RealType T, bool A>
TVector2<T, A>& operator--(TVector2<T, A>& v1, int)
{
return --v1;
}
}

View File

@ -34,40 +34,6 @@ namespace Phanes::Core::Math {
template<RealType T, bool A>
struct TVector3 : public TVector4<T, A> {
public:
//using Real = T;
//union
//{
// struct {
// /// <summary>
// /// X component of vector
// /// </summary>
// Real x;
// /// <summary>
// /// X component of vector
// /// </summary>
// Real y;
// /// <summary>
// /// Z component of vector
// /// </summary>
// Real z;
// /// <summary>
// /// W component of vector
// /// </summary>
// Real w;
// };
// /// <summary>
// /// Wraps components in one array / xmm register.
// /// </summary>
// union
// {
// typename SIMD::Storage<4, Real, SIMD::use_simd<T, 3, A>::value>::type comp;
// typename SIMD::Storage<4, Real, SIMD::use_simd<T, 3, A>::value>::type data;
// };
//};
using Real = T;
@ -107,7 +73,7 @@ namespace Phanes::Core::Math {
/// </summary>
/// <param name="v">Vector</param>
/// <param name="s">Scalar</param>
TVector3(const TVector2<Real>& v, Real s);
TVector3(const TVector2<Real, A>& v, Real s);
};

View File

@ -30,9 +30,9 @@ namespace Phanes::Core::Math
}
template<RealType T, bool A>
TVector3<T, A>::TVector3(const TVector2<Real>& v1, Real s)
TVector3<T, A>::TVector3(const TVector2<Real, A>& v1, Real s)
{
Detail::construct_vec3<T, SIMD::use_simd<T, 3, A>::value>::map(*this, v1.x, v1.y, s);
Detail::construct_vec3<T, SIMD::use_simd<T, 3, A>::value>::map(*this, v1, s);
}
template<RealType T, bool A>

View File

@ -84,7 +84,7 @@ namespace Phanes::Core::Math
/// </summary>
/// <param name="v1">TVector2 one</param>
/// <param name="v2">TVector2 two</param>
TVector4(const TVector2<Real>& v1, const TVector2<Real>& v2);
TVector4(const TVector2<Real, IsAligned>& v1, const TVector2<Real, IsAligned>& v2);
/// <summary>
/// Construct vector from array of components

View File

@ -29,7 +29,7 @@ namespace Phanes::Core::Math
}
template<RealType T, bool A>
Phanes::Core::Math::TVector4<T, A>::TVector4(const TVector2<Real>& v1, const TVector2<Real>& v2)
Phanes::Core::Math::TVector4<T, A>::TVector4(const TVector2<Real, A>& v1, const TVector2<Real, A>& v2)
{
Detail::construct_vec4<T, SIMD::use_simd<T, 4, A>::value>::map(*this, v1, v2);
}