SIMD improvement.
This commit is contained in:
parent
202baf29f5
commit
45a167564d
192
Engine/Source/Runtime/Core/public/Math/Detail/Vector2Decl.inl
Normal file
192
Engine/Source/Runtime/Core/public/Math/Detail/Vector2Decl.inl
Normal 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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
@ -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;
|
||||
|
@ -1 +1,497 @@
|
||||
#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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
template<>
|
||||
struct compute_vec3_dec<float, true>
|
||||
{
|
||||
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));
|
||||
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_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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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,7 +1123,7 @@ 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);
|
||||
}
|
||||
@ -1160,3 +1131,7 @@ namespace Phanes::Core::Math {
|
||||
} // phanes::core::math::coretypes
|
||||
|
||||
#endif // !VECTOR2_H
|
||||
|
||||
|
||||
|
||||
#include "Core/public/Math/Vector2.inl"
|
205
Engine/Source/Runtime/Core/public/Math/Vector2.inl
Normal file
205
Engine/Source/Runtime/Core/public/Math/Vector2.inl
Normal 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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user