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

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "Core/public/Math/Vector3.hpp" // --- Vectors ------------------------
#include "Core/public/Math/Vector4.hpp"
#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 TColor;
template<RealType T> struct TLinearColor; template<RealType T> struct TLinearColor;
template<RealType T> struct TVector2;
template<RealType T> struct TRay; template<RealType T> struct TRay;
template<RealType T> struct TLine; template<RealType T> struct TLine;
template<RealType T> struct TPlane; template<RealType T> struct TPlane;
@ -44,6 +43,7 @@ namespace Phanes::Core::Math {
template<IntType T> struct TIntPoint2; template<IntType T> struct TIntPoint2;
template<IntType T> struct TIntPoint3; template<IntType T> struct TIntPoint3;
template<IntType T> struct TIntPoint4; 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 TVector3;
template<RealType T, bool A> struct TVector4; template<RealType T, bool A> struct TVector4;
@ -51,15 +51,6 @@ namespace Phanes::Core::Math {
* Specific instantiation of forward declarations. * 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 // TIntVector2
typedef TIntVector2<int> IntVector2; typedef TIntVector2<int> IntVector2;
typedef TIntVector2<long> IntVector2l; 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/SIMD/PhanesSIMDTypes.h"
#include "Core/public/Math/Boilerplate.h" #include "Core/public/Math/Boilerplate.h"
#include "Core/public/Math/MathCommon.hpp" #include "Core/public/Math/MathCommon.hpp"
// -> For IntelliSense
// Required includes
#include "Core/public/Math/Vector3.hpp" #include "Core/public/Math/Vector3.hpp"
#include "Core/public/Math/Vector4.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); 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); 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) static FORCEINLINE void map(Phanes::Core::Math::TVector4<float, true>& v1, const float* s)
{ {
v1.comp = _mm_loadu_ps(s); v1.comp = _mm_loadu_ps(s);
@ -228,9 +220,9 @@ namespace Phanes::Core::Math::Detail
}; };
//// ============ // // ============ //
//// TVector3 // // TVector3 //
//// ============ // // ============ //
template<> template<>
@ -252,10 +244,10 @@ namespace Phanes::Core::Math::Detail
v1.comp = _mm_setr_ps(x, y, z, 0.0f); 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) 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);
template<> float r;
struct compute_vec3_dec<float, true> _mm_store_ps1(&r, _mm_cmpneq_ps(v1.comp, v2.comp));
{ return (r == 0xffffffff) ? true : false;
static FORCEINLINE void map(Phanes::Core::Math::TVector3<float, true>& r, const Phanes::Core::Math::TVector3<float, true>& v1)
{
r.comp = _mm_sub_ps(v1.comp, _mm_set_ps(1.0f, 1.0f, 1.0f, 0.0f));
} }
}; };
template<> struct compute_vec3_add<float, true> : public compute_vec4_add<float, true> {}; 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_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.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_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. # error P_INTRINSICS must be defined by the user, when P_FORCE_INTRINSICS is used.
# endif # endif
#else #elif !defined(P_FORCE_FPU)
# ifdef __AVX2__ # ifdef __AVX2__
# define P_AVX2__ 1 # define P_AVX2__ 1
# elif defined(__AVX__) # elif defined(__AVX__)
@ -274,7 +273,6 @@
# define P_SSE__ 1 # define P_SSE__ 1
# endif # endif
#endif // !P_FORCE_INTRINSICS #endif // !P_FORCE_INTRINSICS
#ifdef P_AVX2__ #ifdef P_AVX2__
@ -312,10 +310,10 @@
#if defined(P_FORCE_FPU) // Force, that no intrinsics may be used. #if defined(P_FORCE_FPU) // Force, that no intrinsics may be used.
# define P_INTRINSICS P_INTRINSICS_FPU # define P_INTRINSICS P_INTRINSICS_FPU
# undef P_AVX2__ # define P_AVX2__ 0
# undef P_AVX__ # define P_AVX__ 0
# undef P_SSE__ # define P_SSE__ 0
# undef P_SSE__ # define P_SSE__ 0
#else #else
# if (P_AVX__ == 1) && (P_AVX2__ == 0) # if (P_AVX__ == 1) && (P_AVX2__ == 0)
# define P_INTRINSICS P_INTRINSICS_AVX # define P_INTRINSICS P_INTRINSICS_AVX

View File

@ -3,9 +3,10 @@
#include "Core/public/Math/Boilerplate.h" #include "Core/public/Math/Boilerplate.h"
#include "Core/public/Math/MathCommon.hpp" #include "Core/public/Math/MathCommon.hpp"
#include "Core/public/Math/MathAbstractTypes.h"
#include "Core/public/Math/MathFwd.h" #include "Core/public/Math/MathFwd.h"
#include "Core/public/Math/SIMD/Storage.h"
#ifndef P_DEBUG #ifndef P_DEBUG
#pragma warning(disable : 4244) #pragma warning(disable : 4244)
#endif #endif
@ -29,7 +30,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> template<RealType T, bool A>
struct TVector2 { struct TVector2 {
public: 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. * @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 * Copy constructor
*/ */
TVector2(const TVector2<Real>& v) TVector2(const TVector2<Real, A>& 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) {};
/** /**
* Construct Vector from xy components. * Construct Vector from xy components.
@ -115,33 +100,19 @@ namespace Phanes::Core::Math {
* @param(y) Y component * @param(y) Y component
*/ */
TVector2(const Real x, const Real y) : x(x), y(y) {}; TVector2(const Real x, const Real y);
/** /// <summary>
* Construct Vector from two component array. /// Construct vector from array.
* /// </summary>
* @param(comp) Array of components /// <param name="comp">Array of at least 2 items.</param>
*/ TVector2(const Real* comp);
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 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(v1) Vector to add to
* @param(s) Floating point to add * @param(s) Floating point to add
*/ */
template<RealType T> 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.x += s;
v1.y += 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(v1) Vector to add to
* @param(v2) Vector to add * @param(v2) Vector to add
*/ */
template<RealType T> 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.x += v2.x;
v1.y += v2.y; 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(v1) Vector to substract from
* @param(v2) Floating point to substract * @param(v2) Floating point to substract
*/ */
template<RealType T> 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.x -= s;
v1.y -= 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(v1) Vector to substract from
* @param(v2) Vector to substract * @param(v2) Vector to substract
*/ */
template<RealType T> 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.x -= v2.x;
v1.y -= v2.y; 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(v1) Vector to multiply with
* @param(s Floating point to multiply with * @param(s Floating point to multiply with
*/ */
template<RealType T> 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.x *= s;
v1.y *= s; v1.y *= s;
@ -236,7 +207,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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; s = 1.0f / s;
v1.x *= 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(v1) Vector to multiply with
* @param(s Floating point to multiply with * @param(s Floating point to multiply with
@ -255,13 +226,13 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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(v1) Vector to multiply with
* @param(s Floating point to divide with * @param(s Floating point to divide with
@ -270,14 +241,14 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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; 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(v1) Vector to multiply with
* @param(s Floating point to multiply with * @param(s Floating point to multiply with
@ -286,7 +257,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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; return v1 * s;
} }
@ -301,7 +272,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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; s = 1.0f / s;
return v1 * s; return v1 * s;
@ -319,7 +290,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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; return v1.x * v2.x + v1.y * v2.y;
} }
@ -334,9 +305,9 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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> 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> 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> 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> 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> 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); 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> 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); 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> 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); return sqrtf(v1.x * v1.x + v1.y * v1.y);
} }
@ -453,7 +424,7 @@ namespace Phanes::Core::Math {
* @see [FUNC]Magnitude * @see [FUNC]Magnitude
*/ */
template<RealType T> 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 * Square of magnitude of Vector
@ -464,7 +435,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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; return v1.x * v1.x + v1.y * v1.y;
} }
@ -473,7 +444,7 @@ namespace Phanes::Core::Math {
* @see [FUNC]SqrMagnitude * @see [FUNC]SqrMagnitude
*/ */
template<RealType T> 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 * Normalize Vector
@ -482,7 +453,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> template<RealType T>
TVector2<T> NormalizeV(TVector2<T>& v1) TVector2<T, false> NormalizeV(TVector2<T, false>& v1)
{ {
float vecNorm = Magnitude(v1); float vecNorm = Magnitude(v1);
v1 /= (vecNorm < P_FLT_INAC) ? 1 : vecNorm; v1 /= (vecNorm < P_FLT_INAC) ? 1 : vecNorm;
@ -498,7 +469,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> template<RealType T>
TVector2<T> UnsafeNormalizeV(TVector2<T>& v1) TVector2<T, false> UnsafeNormalizeV(TVector2<T, false>& v1)
{ {
v1 /= Magnitude(v1); v1 /= Magnitude(v1);
@ -513,7 +484,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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)); return acos((v1 * v2) / Magnitude(v1) * Magnitude(v2));
} }
@ -526,7 +497,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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); return (v1 * v2) / Magnitude(v1) * Magnitude(v2);
} }
@ -538,7 +509,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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.x = (v1.x >= 0) ? 1 : -1;
v1.y = (v1.y >= 0) ? 1 : -1; v1.y = (v1.y >= 0) ? 1 : -1;
@ -554,7 +525,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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); float k = (abs(v1.x) > abs(v1.y)) ? abs(radius / v1.x) : abs(radius / v1.y);
v1 *= k; v1 *= k;
@ -570,7 +541,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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 prime = (abs(v1.x) > abs(v1.y)) ? v1.x : v1.y;
float k = (prime > radius) ? abs(radius / prime) : 1.0f; float k = (prime > radius) ? abs(radius / prime) : 1.0f;
@ -587,7 +558,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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; return v1.x * v2.x + v1.y * v2.y;
} }
@ -602,7 +573,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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.x = Phanes::Core::Math::Max(v1.x, v2.x);
v1.y = Phanes::Core::Math::Max(v1.y, v2.y); v1.y = Phanes::Core::Math::Max(v1.y, v2.y);
@ -620,7 +591,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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.x = Phanes::Core::Math::Min(v1.x, v2.x);
v1.y = Phanes::Core::Math::Min(v1.y, v2.y); v1.y = Phanes::Core::Math::Min(v1.y, v2.y);
@ -637,7 +608,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> template<RealType T>
TVector2<T> GetPerpendicularV(TVector2<T>& v1) TVector2<T, false> GetPerpendicularV(TVector2<T, false>& v1)
{ {
T x = v1.x; T x = v1.x;
v1.x = v1.y; v1.x = v1.y;
@ -657,7 +628,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> template<RealType T>
TVector2<T> GetReversePerpendicularV(TVector2<T>& v1) TVector2<T, false> GetReversePerpendicularV(TVector2<T, false>& v1)
{ {
T x = v1.x; T x = v1.x;
v1.x = -v1.y; v1.x = -v1.y;
@ -676,7 +647,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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.x *= v2.x;
v1.y *= v2.y; v1.y *= v2.y;
@ -693,7 +664,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> template<RealType T>
TVector2<T> CompInverseV(TVector2<T>& v1) TVector2<T, false> CompInverseV(TVector2<T, false>& v1)
{ {
v1.x = 1.0f / v1.x; v1.x = 1.0f / v1.x;
v1.y = 1.0f / v1.y; v1.y = 1.0f / v1.y;
@ -711,7 +682,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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)); Set(v1, v1 - (2 * (v1 * normal) * normal));
@ -726,7 +697,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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; v1 = v2;
@ -741,7 +712,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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.x = x;
v1.y = y; v1.y = y;
@ -758,7 +729,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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 sinAngle = sin(angle);
float cosAngle = cos(angle); float cosAngle = cos(angle);
@ -781,7 +752,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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); RotateV(v1, -angle);
@ -795,7 +766,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> template<RealType T>
TVector2<T> NegateV(TVector2<T>& v1) TVector2<T, false> NegateV(TVector2<T, false>& v1)
{ {
v1.x = -v1.x; v1.x = -v1.x;
v1.y = -v1.y; v1.y = -v1.y;
@ -811,7 +782,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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); return (SqrMagnitude(v1) < threshold);
} }
@ -829,7 +800,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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); return (abs(DotP(v1, v2)) < threshold);
} }
@ -847,7 +818,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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); return (abs(DotP(v1, v2)) > threshold);
} }
@ -865,7 +836,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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); 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> 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> 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> 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> 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> 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> 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> 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> 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> template<RealType T>
TVector2<T> Normalize(const TVector2<T>& v1) TVector2<T, false> Normalize(const TVector2<T, false>& v1)
{ {
float vecNorm = Magnitude(v1); float vecNorm = Magnitude(v1);
return (vecNorm < P_FLT_INAC) ? PZeroVector2(T) : (v1 / vecNorm); return (vecNorm < P_FLT_INAC) ? PZeroVector2(T) : (v1 / vecNorm);
@ -1029,7 +1000,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> template<RealType T>
TVector2<T> UnsafeNormalize(const TVector2<T>& v1) TVector2<T, false> UnsafeNormalize(const TVector2<T, false>& v1)
{ {
return (v1 / Magnitude(v1)); return (v1 / Magnitude(v1));
} }
@ -1043,9 +1014,9 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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> 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); float k = (abs(v1.x) > abs(v1.y)) ? abs(radius / v1.x) : abs(radius / v1.y);
return v1 * k; return v1 * k;
@ -1074,7 +1045,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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 prime = (abs(v1.x) > abs(v1.y)) ? v1.x : v1.y;
float k = (prime > radius) ? abs(radius / prime) : 1.0f; float k = (prime > radius) ? abs(radius / prime) : 1.0f;
@ -1095,7 +1066,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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); t = Phanes::Core::Math::Clamp(t, (T)0.0, (T)1.0);
@ -1115,7 +1086,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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); return (t * destVec) + ((1 - t) * startVec);
} }
@ -1132,12 +1103,12 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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 sinAngle = sin(angle);
float cosAngle = cos(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); v1.y * cosAngle + v1.x * sinAngle);
} }
@ -1152,7 +1123,7 @@ namespace Phanes::Core::Math {
*/ */
template<RealType T> 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); return Rotate(v1, -angle);
} }
@ -1160,3 +1131,7 @@ namespace Phanes::Core::Math {
} // phanes::core::math::coretypes } // 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> template<RealType T, bool A>
struct TVector3 : public TVector4<T, A> { struct TVector3 : public TVector4<T, A> {
public: 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; using Real = T;
@ -107,7 +73,7 @@ namespace Phanes::Core::Math {
/// </summary> /// </summary>
/// <param name="v">Vector</param> /// <param name="v">Vector</param>
/// <param name="s">Scalar</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> 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> template<RealType T, bool A>

View File

@ -84,7 +84,7 @@ namespace Phanes::Core::Math
/// </summary> /// </summary>
/// <param name="v1">TVector2 one</param> /// <param name="v1">TVector2 one</param>
/// <param name="v2">TVector2 two</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> /// <summary>
/// Construct vector from array of components /// Construct vector from array of components

View File

@ -29,7 +29,7 @@ namespace Phanes::Core::Math
} }
template<RealType T, bool A> 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); Detail::construct_vec4<T, SIMD::use_simd<T, 4, A>::value>::map(*this, v1, v2);
} }