Migrating to Linux
This commit is contained in:
101
Engine/Source/Runtime/Core/Math/Boilerplate.h
Normal file
101
Engine/Source/Runtime/Core/Math/Boilerplate.h
Normal file
@@ -0,0 +1,101 @@
|
||||
// Math is independent from the rest of the library, to ensure seamless usage with other client.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef P_BUILD_LIB
|
||||
#include "PhanesEnginePCH.h"
|
||||
|
||||
#else
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef P_WIN_BUILD
|
||||
|
||||
#ifdef P_DEBUG
|
||||
|
||||
#define P_DEBUGBREAK DebugBreak();
|
||||
|
||||
#else
|
||||
|
||||
#define P_DEBUGBREAK
|
||||
|
||||
#endif // P_DEBUG
|
||||
|
||||
#define FORCEINLINE __forceinline
|
||||
|
||||
#elif defined(P_LINUX_BUILD)
|
||||
|
||||
#ifdef P_DEBUG
|
||||
|
||||
#define P_DEBUGBREAK __builtin_trap();
|
||||
|
||||
#else
|
||||
|
||||
#define P_DEBUGBREAK
|
||||
|
||||
#endif // P_DEBUG
|
||||
|
||||
#define FORCEINLINE inline __attribute__((always_inline))
|
||||
|
||||
#elif defined(P_ARM_BUILD)
|
||||
|
||||
#error Only Windows is supported at the moment.
|
||||
|
||||
#else
|
||||
|
||||
#error The target system must be defined. (See https://github.com/scorpioblood/PhanesEngine for more information)
|
||||
|
||||
#endif // P_WIN_BUILD
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Phanes::Core::Math
|
||||
{
|
||||
|
||||
// Typenames with RealType constrain have to be floating point numbers.
|
||||
template<typename T>
|
||||
concept RealType = std::is_floating_point_v<T>;
|
||||
|
||||
// Typenames with IntType constrain have to be integer number.
|
||||
template<typename T>
|
||||
concept IntType = std::is_integral_v<T>;
|
||||
|
||||
// Typenames with Arithmethic constrain have to be number.
|
||||
template<typename T>
|
||||
concept Arithmethic = std::is_arithmetic_v<T>;
|
||||
|
||||
|
||||
|
||||
// Alias for shared_ptr
|
||||
template<typename T>
|
||||
using Ref = std::shared_ptr<T>;
|
||||
|
||||
// Alias for make_shared
|
||||
template<typename T, typename ...Args>
|
||||
constexpr Ref<T> MakeRef(Args&& ...args)
|
||||
{
|
||||
return std::make_shared<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// Alias for unique ptr
|
||||
template<typename T>
|
||||
using Scope = std::unique_ptr<T>;
|
||||
|
||||
// Alias for make_unique
|
||||
template<typename T, typename ...Args>
|
||||
constexpr Scope<T> MakeScope(Args&& ...args)
|
||||
{
|
||||
return std::make_unique<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
301
Engine/Source/Runtime/Core/Math/Detail/IntVector2Decl.inl
Normal file
301
Engine/Source/Runtime/Core/Math/Detail/IntVector2Decl.inl
Normal file
@@ -0,0 +1,301 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
namespace Phanes::Core::Math::Detail
|
||||
{
|
||||
template<IntType T, bool S>
|
||||
struct construct_ivec2 {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec2_add {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec2_sub {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec2_mul {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec2_div {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec2_mod {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec2_eq {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec2_ieq {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec2_inc {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec2_dec {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec2_and {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec2_or {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec2_xor {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec2_left_shift {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec2_right_shift {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec2_bnot {};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct construct_ivec2<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& v1, const TIntVector2<T, false>& v2)
|
||||
{
|
||||
v1.x = v2.x;
|
||||
v1.y = v2.y;
|
||||
}
|
||||
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& v1, T s)
|
||||
{
|
||||
v1.x = s;
|
||||
v1.y = s;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& v1, T x, T y)
|
||||
{
|
||||
v1.x = x;
|
||||
v1.y = y;
|
||||
}
|
||||
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& v1, const T* comp)
|
||||
{
|
||||
v1.x = comp[0];
|
||||
v1.y = comp[1];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec2_add<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, const Phanes::Core::Math::TIntVector2<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x + v2.x;
|
||||
r.y = v1.y + v2.y;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x + s;
|
||||
r.y = v1.y + s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec2_sub<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, const Phanes::Core::Math::TIntVector2<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x - v2.x;
|
||||
r.y = v1.y - v2.y;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x - s;
|
||||
r.y = v1.y - s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec2_mul<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, const Phanes::Core::Math::TIntVector2<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x * v2.x;
|
||||
r.y = v1.y * v2.y;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x * s;
|
||||
r.y = v1.y * s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec2_div<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, const Phanes::Core::Math::TIntVector2<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x / v2.x;
|
||||
r.y = v1.y / v2.y;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x / s;
|
||||
r.y = v1.y / s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec2_mod<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, const Phanes::Core::Math::TIntVector2<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x % v2.x;
|
||||
r.y = v1.y % v2.y;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x % s;
|
||||
r.y = v1.y % s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec2_eq<T, false>
|
||||
{
|
||||
static constexpr bool map(const Phanes::Core::Math::TIntVector2<T, false>& v1, const Phanes::Core::Math::TIntVector2<T, false>& 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<IntType T>
|
||||
struct compute_ivec2_ieq<T, false>
|
||||
{
|
||||
static constexpr bool map(const Phanes::Core::Math::TIntVector2<T, false>& v1, const Phanes::Core::Math::TIntVector2<T, false>& 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<IntType T>
|
||||
struct compute_ivec2_inc<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1)
|
||||
{
|
||||
r.x = v1.x + 1;
|
||||
r.y = v1.y + 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec2_dec<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1)
|
||||
{
|
||||
r.x = v1.x - 1;
|
||||
r.y = v1.y - 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec2_and<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, const Phanes::Core::Math::TIntVector2<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x & v2.x;
|
||||
r.y = v1.y & v2.y;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x & s;
|
||||
r.y = v1.y & s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec2_or<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, const Phanes::Core::Math::TIntVector2<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x | v2.x;
|
||||
r.y = v1.y | v2.y;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, const T s)
|
||||
{
|
||||
r.x = v1.x | s;
|
||||
r.y = v1.y | s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec2_xor<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, const Phanes::Core::Math::TIntVector2<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x ^ v2.x;
|
||||
r.y = v1.y ^ v2.y;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, const T s)
|
||||
{
|
||||
r.x = v1.x ^ s;
|
||||
r.y = v1.y ^ s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec2_left_shift<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, const Phanes::Core::Math::TIntVector2<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x << v2.x;
|
||||
r.y = v1.y << v2.y;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, const T s)
|
||||
{
|
||||
r.x = v1.x << s;
|
||||
r.y = v1.y << s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec2_right_shift<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, const Phanes::Core::Math::TIntVector2<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x >> v2.x;
|
||||
r.y = v1.y >> v2.y;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1, const T s)
|
||||
{
|
||||
r.x = v1.x >> s;
|
||||
r.y = v1.y >> s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec2_bnot<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector2<T, false>& r, const Phanes::Core::Math::TIntVector2<T, false>& v1)
|
||||
{
|
||||
r.x = ~v1.x;
|
||||
r.y = ~v1.y;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
342
Engine/Source/Runtime/Core/Math/Detail/IntVector3Decl.inl
Normal file
342
Engine/Source/Runtime/Core/Math/Detail/IntVector3Decl.inl
Normal file
@@ -0,0 +1,342 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
namespace Phanes::Core::Math::Detail
|
||||
{
|
||||
template<IntType T, bool S>
|
||||
struct construct_ivec3 {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec3_add {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec3_sub {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec3_mul {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec3_div {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec3_mod {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec3_eq {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec3_ieq {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec3_inc {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec3_dec {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec3_and {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec3_or {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec3_xor {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec3_left_shift {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec3_right_shift {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec3_bnot {};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct construct_ivec3<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& v1, const TIntVector3<T, false>& v2)
|
||||
{
|
||||
v1.x = v2.x;
|
||||
v1.y = v2.y;
|
||||
v1.z = v2.z;
|
||||
v1.w = (T)0;
|
||||
}
|
||||
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& v1, T s)
|
||||
{
|
||||
v1.x = s;
|
||||
v1.y = s;
|
||||
v1.z = s;
|
||||
v1.w = (T)0;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& v1, T x, T y, T z)
|
||||
{
|
||||
v1.x = x;
|
||||
v1.y = y;
|
||||
v1.z = z;
|
||||
v1.w = (T)0;
|
||||
}
|
||||
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& v1, const T* comp)
|
||||
{
|
||||
v1.x = comp[0];
|
||||
v1.y = comp[1];
|
||||
v1.z = comp[2];
|
||||
v1.w = (T)0;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& v1, const Phanes::Core::Math::TIntVector2<T, false>& v2, const T s)
|
||||
{
|
||||
v1.x = v2.x;
|
||||
v1.y = v2.y;
|
||||
v1.z = s;
|
||||
v1.w = (T)0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec3_add<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, const Phanes::Core::Math::TIntVector3<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x + v2.x;
|
||||
r.y = v1.y + v2.y;
|
||||
r.z = v1.z + v2.z;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x + s;
|
||||
r.y = v1.y + s;
|
||||
r.z = v1.z + s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec3_sub<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, const Phanes::Core::Math::TIntVector3<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x - v2.x;
|
||||
r.y = v1.y - v2.y;
|
||||
r.z = v1.z - v2.z;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x - s;
|
||||
r.y = v1.y - s;
|
||||
r.z = v1.z - s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec3_mul<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, const Phanes::Core::Math::TIntVector3<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x * v2.x;
|
||||
r.y = v1.y * v2.y;
|
||||
r.z = v1.z * v2.z;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x * s;
|
||||
r.y = v1.y * s;
|
||||
r.z = v1.z * s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec3_div<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, const Phanes::Core::Math::TIntVector3<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x / v2.x;
|
||||
r.y = v1.y / v2.y;
|
||||
r.z = v1.z / v2.z;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x / s;
|
||||
r.y = v1.y / s;
|
||||
r.z = v1.z / s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec3_mod<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, const Phanes::Core::Math::TIntVector3<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x % v2.x;
|
||||
r.y = v1.y % v2.y;
|
||||
r.z = v1.z % v2.z;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x % s;
|
||||
r.y = v1.y % s;
|
||||
r.z = v1.z % s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec3_eq<T, false>
|
||||
{
|
||||
static constexpr bool map(const Phanes::Core::Math::TIntVector3<T, false>& v1, const Phanes::Core::Math::TIntVector3<T, false>& 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<IntType T>
|
||||
struct compute_ivec3_ieq<T, false>
|
||||
{
|
||||
static constexpr bool map(const Phanes::Core::Math::TIntVector3<T, false>& v1, const Phanes::Core::Math::TIntVector3<T, false>& 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.y - v2.y) > P_FLT_INAC);
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec3_inc<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1)
|
||||
{
|
||||
r.x = v1.x + 1;
|
||||
r.y = v1.y + 1;
|
||||
r.z = v1.z + 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec3_dec<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1)
|
||||
{
|
||||
r.x = v1.x - 1;
|
||||
r.y = v1.y - 1;
|
||||
r.z = v1.z - 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec3_and<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, const Phanes::Core::Math::TIntVector3<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x & v2.x;
|
||||
r.y = v1.y & v2.y;
|
||||
r.z = v1.z & v2.y;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x & s;
|
||||
r.y = v1.y & s;
|
||||
r.z = v1.z & s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec3_or<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, const Phanes::Core::Math::TIntVector3<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x | v2.x;
|
||||
r.y = v1.y | v2.y;
|
||||
r.z = v1.z | v2.z;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x | s;
|
||||
r.y = v1.y | s;
|
||||
r.z = v1.z | s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec3_xor<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, const Phanes::Core::Math::TIntVector3<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x ^ v2.x;
|
||||
r.y = v1.y ^ v2.y;
|
||||
r.z = v1.z ^ v2.z;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x ^ s;
|
||||
r.y = v1.y ^ s;
|
||||
r.z = v1.z ^ s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec3_left_shift<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, const Phanes::Core::Math::TIntVector3<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x << v2.x;
|
||||
r.y = v1.y << v2.y;
|
||||
r.z = v1.z << v2.z;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x << s;
|
||||
r.y = v1.y << s;
|
||||
r.z = v1.z << s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec3_right_shift<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, const Phanes::Core::Math::TIntVector3<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x >> v2.x;
|
||||
r.y = v1.y >> v2.y;
|
||||
r.z = v1.z >> v2.z;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x >> s;
|
||||
r.y = v1.y >> s;
|
||||
r.z = v1.z >> s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec3_bnot<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector3<T, false>& r, const Phanes::Core::Math::TIntVector3<T, false>& v1)
|
||||
{
|
||||
r.x = ~v1.x;
|
||||
r.y = ~v1.y;
|
||||
r.z = ~v1.z;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
365
Engine/Source/Runtime/Core/Math/Detail/IntVector4Decl.inl
Normal file
365
Engine/Source/Runtime/Core/Math/Detail/IntVector4Decl.inl
Normal file
@@ -0,0 +1,365 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
namespace Phanes::Core::Math::Detail
|
||||
{
|
||||
template<IntType T, bool S>
|
||||
struct construct_ivec4 {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec4_add {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec4_sub {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec4_mul {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec4_div {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec4_mod {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec4_eq {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec4_ieq {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec4_inc {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec4_dec {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec4_and {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec4_or {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec4_xor {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec4_left_shift {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec4_right_shift {};
|
||||
|
||||
template<IntType T, bool S>
|
||||
struct compute_ivec4_bnot {};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct construct_ivec4<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& v1, const TIntVector4<T, false>& v2)
|
||||
{
|
||||
v1.x = v2.x;
|
||||
v1.y = v2.y;
|
||||
v1.z = v2.z;
|
||||
v1.w = v2.w;
|
||||
}
|
||||
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& v1, T s)
|
||||
{
|
||||
v1.x = s;
|
||||
v1.y = s;
|
||||
v1.z = s;
|
||||
v1.w = s;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& v1, T x, T y, T z, T w)
|
||||
{
|
||||
v1.x = x;
|
||||
v1.y = y;
|
||||
v1.z = z;
|
||||
v1.w = w;
|
||||
}
|
||||
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& v1, const T* comp)
|
||||
{
|
||||
v1.x = comp[0];
|
||||
v1.y = comp[1];
|
||||
v1.z = comp[2];
|
||||
v1.w = comp[3];
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<int, false>& r, const Phanes::Core::Math::TIntVector2<int, false>& v1, const Phanes::Core::Math::TIntVector2<int, false>& v2)
|
||||
{
|
||||
r.x = v1.x;
|
||||
r.y = v1.y;
|
||||
r.x = v2.x;
|
||||
r.y = v2.y;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec4_add<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, const Phanes::Core::Math::TIntVector4<T, false>& 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 constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x + s;
|
||||
r.y = v1.y + s;
|
||||
r.z = v1.z + s;
|
||||
r.w = v1.w + s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec4_sub<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, const Phanes::Core::Math::TIntVector4<T, false>& 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 constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x - s;
|
||||
r.y = v1.y - s;
|
||||
r.z = v1.z - s;
|
||||
r.w = v1.w - s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec4_mul<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, const Phanes::Core::Math::TIntVector4<T, false>& 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 constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x * s;
|
||||
r.y = v1.y * s;
|
||||
r.z = v1.z * s;
|
||||
r.w = v1.w * s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec4_div<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, const Phanes::Core::Math::TIntVector4<T, false>& 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 constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x / s;
|
||||
r.y = v1.y / s;
|
||||
r.z = v1.z / s;
|
||||
r.w = v1.w / s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec4_mod<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, const Phanes::Core::Math::TIntVector4<T, false>& 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 constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x % s;
|
||||
r.y = v1.y % s;
|
||||
r.z = v1.z % s;
|
||||
r.w = v1.w % s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec4_eq<T, false>
|
||||
{
|
||||
static constexpr bool map(const Phanes::Core::Math::TIntVector4<T, false>& v1, const Phanes::Core::Math::TIntVector4<T, false>& v2)
|
||||
{
|
||||
return (v1.x == v2.x &&
|
||||
v1.y == v2.y &&
|
||||
v1.z == v2.z &&
|
||||
v1.w == v2.w);
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec4_ieq<T, false>
|
||||
{
|
||||
static constexpr bool map(const Phanes::Core::Math::TIntVector4<T, false>& v1, const Phanes::Core::Math::TIntVector4<T, false>& v2)
|
||||
{
|
||||
return (v1.x != v2.x ||
|
||||
v1.y != v2.y ||
|
||||
v1.z != v2.z ||
|
||||
v1.w != v2.w);
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec4_inc<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1)
|
||||
{
|
||||
r.x = v1.x + 1;
|
||||
r.y = v1.y + 1;
|
||||
r.z = v1.z + 1;
|
||||
r.w = v1.w + 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec4_dec<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1)
|
||||
{
|
||||
r.x = v1.x - 1;
|
||||
r.y = v1.y - 1;
|
||||
r.z = v1.z - 1;
|
||||
r.w = v1.w - 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec4_and<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, const Phanes::Core::Math::TIntVector4<T, false>& 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 constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x & s;
|
||||
r.y = v1.y & s;
|
||||
r.z = v1.z & s;
|
||||
r.w = v1.w & s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec4_or<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, const Phanes::Core::Math::TIntVector4<T, false>& 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 constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x | s;
|
||||
r.y = v1.y | s;
|
||||
r.z = v1.z | s;
|
||||
r.w = v1.w | s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec4_xor<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, const Phanes::Core::Math::TIntVector4<T, false>& 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 constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x ^ s;
|
||||
r.y = v1.y ^ s;
|
||||
r.z = v1.z ^ s;
|
||||
r.w = v1.w ^ s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec4_left_shift<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, const Phanes::Core::Math::TIntVector4<T, false>& 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 constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x << s;
|
||||
r.y = v1.y << s;
|
||||
r.z = v1.z << s;
|
||||
r.w = v1.w << s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec4_right_shift<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, const Phanes::Core::Math::TIntVector4<T, false>& 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 constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x >> s;
|
||||
r.y = v1.y >> s;
|
||||
r.z = v1.z >> s;
|
||||
r.w = v1.w >> s;
|
||||
}
|
||||
};
|
||||
|
||||
template<IntType T>
|
||||
struct compute_ivec4_bnot<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TIntVector4<T, false>& r, const Phanes::Core::Math::TIntVector4<T, false>& v1)
|
||||
{
|
||||
r.x = ~v1.x;
|
||||
r.y = ~v1.y;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
53
Engine/Source/Runtime/Core/Math/Detail/Matrix3Decl.inl
Normal file
53
Engine/Source/Runtime/Core/Math/Detail/Matrix3Decl.inl
Normal file
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
#include "Core/public/Math/MathCommon.hpp"
|
||||
|
||||
namespace Phanes::Core::Math::Detail
|
||||
{
|
||||
template<RealType T, bool S>
|
||||
struct compute_mat3_transpose {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_mat3_mul {};
|
||||
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_mat3_transpose<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TMatrix3<T, false>& r, const TMatrix3<T, false>& m1)
|
||||
{
|
||||
r = TMatrix3<T, false>(m1(0, 0), m1(1, 0), m1(2, 0),
|
||||
m1(0, 1), m1(1, 1), m1(2, 1),
|
||||
m1(0, 2), m1(1, 2), m1(2, 2)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_mat3_mul<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TMatrix3<T, false>& r, const TMatrix3<T, false>& m1, const TMatrix3<T, false>& m2)
|
||||
{
|
||||
r(0, 0) = m1(0, 0) * m2(0, 0) + m1(0, 1) * m2(1, 0) + m1(0, 2) * m2(2, 0);
|
||||
r(0, 1) = m1(0, 0) * m2(0, 1) + m1(0, 1) * m2(1, 1) + m1(0, 2) * m2(2, 1);
|
||||
r(0, 2) = m1(0, 0) * m2(0, 2) + m1(0, 1) * m2(1, 2) + m1(0, 2) * m2(2, 2);
|
||||
|
||||
r(1, 0) = m1(1, 0) * m2(0, 0) + m1(1, 1) * m2(1, 0) + m1(1, 2) * m2(2, 0);
|
||||
r(1, 1) = m1(1, 0) * m2(0, 1) + m1(1, 1) * m2(1, 1) + m1(1, 2) * m2(2, 1);
|
||||
r(1, 2) = m1(1, 0) * m2(0, 2) + m1(1, 1) * m2(1, 2) + m1(1, 2) * m2(2, 2);
|
||||
|
||||
r(2, 0) = m1(2, 0) * m2(0, 0) + m1(2, 1) * m2(1, 0) + m1(2, 2) * m2(2, 0);
|
||||
r(2, 1) = m1(2, 0) * m2(0, 1) + m1(2, 1) * m2(1, 1) + m1(2, 2) * m2(2, 1);
|
||||
r(2, 2) = m1(2, 0) * m2(0, 2) + m1(2, 1) * m2(1, 2) + m1(2, 2) * m2(2, 2);
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const TMatrix3<T, false>& m1, const TVector3<T, false>& v)
|
||||
{
|
||||
r.x = m1(0, 0) * v.x + m1(0, 1) * v.y + m1(0, 2) * v.z;
|
||||
r.y = m1(1, 0) * v.x + m1(1, 1) * v.y + m1(1, 2) * v.z;
|
||||
r.z = m1(2, 0) * v.x + m1(2, 1) * v.y + m1(2, 2) * v.z;
|
||||
}
|
||||
};
|
||||
}
|
136
Engine/Source/Runtime/Core/Math/Detail/Matrix4Decl.inl
Normal file
136
Engine/Source/Runtime/Core/Math/Detail/Matrix4Decl.inl
Normal file
@@ -0,0 +1,136 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
#include "Core/public/Math/MathCommon.hpp"
|
||||
|
||||
namespace Phanes::Core::Math::Detail
|
||||
{
|
||||
template<RealType T, bool S>
|
||||
struct compute_mat4_det {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_mat4_inv {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_mat4_transpose {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_mat4_mul {};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_mat4_det<T, false>
|
||||
{
|
||||
static constexpr T map(const Phanes::Core::Math::TMatrix4<T, false>& m)
|
||||
{
|
||||
const TVector3<T, false>& a = reinterpret_cast<const TVector3<T, false>&>(m[0]);
|
||||
const TVector3<T, false>& b = reinterpret_cast<const TVector3<T, false>&>(m[1]);
|
||||
const TVector3<T, false>& c = reinterpret_cast<const TVector3<T, false>&>(m[2]);
|
||||
const TVector3<T, false>& d = reinterpret_cast<const TVector3<T, false>&>(m[3]);
|
||||
|
||||
const float& x = m(3, 0);
|
||||
const float& y = m(3, 1);
|
||||
const float& z = m(3, 2);
|
||||
const float& w = m(3, 3);
|
||||
|
||||
TVector3<T, false> s = CrossP(a, b);
|
||||
TVector3<T, false> t = CrossP(c, d);
|
||||
TVector3<T, false> u = a * y - b * x;
|
||||
TVector3<T, false> v = c * w - d * z;
|
||||
return DotP(s, v) + DotP(t, u);
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_mat4_inv<T, false>
|
||||
{
|
||||
static constexpr bool map(Phanes::Core::Math::TMatrix4<T, false>& r, const Phanes::Core::Math::TMatrix4<T, false>& m)
|
||||
{
|
||||
const TVector3<T, false>& a = reinterpret_cast<const TVector3<T, false>&>(m[0]);
|
||||
const TVector3<T, false>& b = reinterpret_cast<const TVector3<T, false>&>(m[1]);
|
||||
const TVector3<T, false>& c = reinterpret_cast<const TVector3<T, false>&>(m[2]);
|
||||
const TVector3<T, false>& d = reinterpret_cast<const TVector3<T, false>&>(m[3]);
|
||||
|
||||
const float& x = m(3, 0);
|
||||
const float& y = m(3, 1);
|
||||
const float& z = m(3, 2);
|
||||
const float& w = m(3, 3);
|
||||
|
||||
TVector3<T, false> s = CrossP(a, b);
|
||||
TVector3<T, false> t = CrossP(c, d);
|
||||
TVector3<T, false> u = a * y - b * x;
|
||||
TVector3<T, false> v = c * w - d * z;
|
||||
|
||||
float _1_det = (T)1.0 / (DotP(s, v) + DotP(t, u));
|
||||
|
||||
if (_1_det == (T)0.0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
s *= _1_det;
|
||||
t *= _1_det;
|
||||
u *= _1_det;
|
||||
v *= _1_det;
|
||||
|
||||
TVector3<T, false> r0 = CrossP(b, v) + t * y;
|
||||
TVector3<T, false> r1 = CrossP(v, a) - t * x;
|
||||
TVector3<T, false> r2 = CrossP(d, u) + s * w;
|
||||
TVector3<T, false> r3 = CrossP(u, c) - s * z;
|
||||
|
||||
r = TMatrix4<T, false>(r0.x, r0.y, r0.z, -DotP(b, t),
|
||||
r1.x, r1.y, r1.z, DotP(a, t),
|
||||
r2.x, r2.y, r2.z, -DotP(d, s),
|
||||
r3.x, r3.y, r3.z, DotP(c, s));
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_mat4_transpose<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TMatrix4<T, false>& r, const Phanes::Core::Math::TMatrix4<T, false>& m)
|
||||
{
|
||||
r = Phanes::Core::Math::TMatrix4<T, false>(m(0, 0), m(1, 0), m(2, 0), m(3, 0),
|
||||
m(0, 1), m(1, 1), m(2, 1), m(3, 1),
|
||||
m(0, 2), m(1, 2), m(2, 2), m(3, 2),
|
||||
m(0, 3), m(1, 3), m(2, 3), m(3, 3));
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_mat4_mul<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TMatrix4<T, false>& r, const Phanes::Core::Math::TMatrix4<T, false>& m1, const Phanes::Core::Math::TMatrix4<T, false>& m2)
|
||||
{
|
||||
r(0, 0) = m1(0, 0) * m2(0, 0) + m1(0, 1) * m2(1, 0) + m1(0, 2) * m2(2, 0) + m1(0, 3) * m2(3, 0);
|
||||
r(0, 1) = m1(0, 0) * m2(0, 1) + m1(0, 1) * m2(1, 1) + m1(0, 2) * m2(2, 1) + m1(0, 3) * m2(3, 1);
|
||||
r(0, 2) = m1(0, 0) * m2(0, 2) + m1(0, 1) * m2(1, 2) + m1(0, 2) * m2(2, 2) + m1(0, 3) * m2(3, 2);
|
||||
r(0, 3) = m1(0, 0) * m2(0, 3) + m1(0, 1) * m2(1, 3) + m1(0, 2) * m2(2, 3) + m1(0, 3) * m2(3, 3);
|
||||
|
||||
r(1, 0) = m1(1, 0) * m2(0, 0) + m1(1, 1) * m2(1, 0) + m1(1, 2) * m2(2, 0) + m1(1, 3) * m2(3, 0);
|
||||
r(1, 1) = m1(1, 0) * m2(0, 1) + m1(1, 1) * m2(1, 1) + m1(1, 2) * m2(2, 1) + m1(1, 3) * m2(3, 1);
|
||||
r(1, 2) = m1(1, 0) * m2(0, 2) + m1(1, 1) * m2(1, 2) + m1(1, 2) * m2(2, 2) + m1(1, 3) * m2(3, 2);
|
||||
r(1, 3) = m1(1, 0) * m2(0, 3) + m1(1, 1) * m2(1, 3) + m1(1, 2) * m2(2, 3) + m1(1, 3) * m2(3, 3);
|
||||
|
||||
r(2, 0) = m1(2, 0) * m2(0, 0) + m1(2, 1) * m2(1, 0) + m1(2, 2) * m2(2, 0) + m1(2, 3) * m2(3, 0);
|
||||
r(2, 1) = m1(2, 0) * m2(0, 1) + m1(2, 1) * m2(1, 1) + m1(2, 2) * m2(2, 1) + m1(2, 3) * m2(3, 1);
|
||||
r(2, 2) = m1(2, 0) * m2(0, 2) + m1(2, 1) * m2(1, 2) + m1(2, 2) * m2(2, 2) + m1(2, 3) * m2(3, 2);
|
||||
r(2, 3) = m1(2, 0) * m2(0, 3) + m1(2, 1) * m2(1, 3) + m1(2, 2) * m2(2, 3) + m1(2, 3) * m2(3, 3);
|
||||
|
||||
r(3, 0) = m1(3, 0) * m2(0, 0) + m1(3, 1) * m2(1, 0) + m1(3, 2) * m2(2, 0) + m1(3, 3) * m2(3, 0);
|
||||
r(3, 1) = m1(3, 0) * m2(0, 1) + m1(3, 1) * m2(1, 1) + m1(3, 2) * m2(2, 1) + m1(3, 3) * m2(3, 1);
|
||||
r(3, 2) = m1(3, 0) * m2(0, 2) + m1(3, 1) * m2(1, 2) + m1(3, 2) * m2(2, 2) + m1(3, 3) * m2(3, 2);
|
||||
r(3, 3) = m1(3, 0) * m2(0, 3) + m1(3, 1) * m2(1, 3) + m1(3, 2) * m2(2, 3) + m1(3, 3) * m2(3, 3);
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TMatrix4<T, false>& m1, const Phanes::Core::Math::TVector4<T, false>& v)
|
||||
{
|
||||
r.x = m1(0, 0) * v.x + m1(0, 1) * v.y + m1(0, 2) * v.z + m1(0, 3) * v.w;
|
||||
r.y = m1(1, 0) * v.x + m1(1, 1) * v.y + m1(1, 2) * v.z + m1(1, 3) * v.w;
|
||||
r.z = m1(2, 0) * v.x + m1(2, 1) * v.y + m1(2, 2) * v.z + m1(2, 3) * v.w;
|
||||
r.w = m1(3, 0) * v.x + m1(3, 1) * v.y + m1(3, 2) * v.z + m1(3, 3) * v.w;
|
||||
}
|
||||
};
|
||||
}
|
107
Engine/Source/Runtime/Core/Math/Detail/PlaneDecl.inl
Normal file
107
Engine/Source/Runtime/Core/Math/Detail/PlaneDecl.inl
Normal file
@@ -0,0 +1,107 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
namespace Phanes::Core::Math::Detail
|
||||
{
|
||||
template<RealType T, bool S>
|
||||
struct construct_plane {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_plane_add {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_plane_sub {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_plane_mul {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_plane_div {};
|
||||
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct construct_plane<T, false>
|
||||
{
|
||||
|
||||
static constexpr void map(TPlane<T, false>& r, const TVector3<T, false>& normal, T d)
|
||||
{
|
||||
r.normal = normal;
|
||||
r.d = d;
|
||||
}
|
||||
|
||||
static constexpr void map(TPlane<T, false>& r, const TVector3<T, false>& normal, const TVector3<T, false>& base)
|
||||
{
|
||||
r.normal = std::copy(normal);
|
||||
r.d = DotP(r.normal, base);
|
||||
}
|
||||
|
||||
static constexpr void map(TPlane<T, false>& r, T x, T y, T z, T d)
|
||||
{
|
||||
r.normal = TVector3<T, false>(x, y, z);
|
||||
r.d = d;
|
||||
}
|
||||
|
||||
static constexpr void map(TPlane<T, false>& r, const TVector3<T, false>& v1, const TVector3<T, false>& v2, const TVector3<T, false>& v3)
|
||||
{
|
||||
r.normal = Normalize(CrossP(v1, v2));
|
||||
r.d = DotP(r.normal, v3);
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_plane_add<T, false>
|
||||
{
|
||||
static constexpr void map(TPlane<T, false>& r, const TPlane<T, false>& pl1, const TPlane<T, false>& pl2)
|
||||
{
|
||||
r.comp = pl1.comp + pl2.comp;
|
||||
}
|
||||
|
||||
static constexpr void map(TPlane<T, false>& r, const TPlane<T, false>& pl1, T s)
|
||||
{
|
||||
r.comp = pl1.comp + s;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_plane_sub<T, false>
|
||||
{
|
||||
static constexpr void map(TPlane<T, false>& r, const TPlane<T, false>& pl1, const TPlane<T, false>& pl2)
|
||||
{
|
||||
r.comp = pl1.comp - pl2.comp;
|
||||
}
|
||||
|
||||
static constexpr void map(TPlane<T, false>& r, const TPlane<T, false>& pl1, T s)
|
||||
{
|
||||
r.comp = pl1.comp - s;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_plane_mul<T, false>
|
||||
{
|
||||
static constexpr void map(TPlane<T, false>& r, const TPlane<T, false>& pl1, const TPlane<T, false>& pl2)
|
||||
{
|
||||
r.comp = pl1.comp * pl2.comp;
|
||||
}
|
||||
|
||||
static constexpr void map(TPlane<T, false>& r, const TPlane<T, false>& pl1, T s)
|
||||
{
|
||||
r.comp = pl1.comp * s;
|
||||
}
|
||||
};
|
||||
template<RealType T>
|
||||
struct compute_plane_div<T, false>
|
||||
{
|
||||
static constexpr void map(TPlane<T, false>& r, const TPlane<T, false>& pl1, const TPlane<T, false>& pl2)
|
||||
{
|
||||
r.comp = pl1.comp / pl2.comp;
|
||||
}
|
||||
|
||||
static constexpr void map(TPlane<T, false>& r, const TPlane<T, false>& pl1, T s)
|
||||
{
|
||||
r.comp = pl1.comp / s;
|
||||
}
|
||||
};
|
||||
}
|
266
Engine/Source/Runtime/Core/Math/Detail/Vector2Decl.inl
Normal file
266
Engine/Source/Runtime/Core/Math/Detail/Vector2Decl.inl
Normal file
@@ -0,0 +1,266 @@
|
||||
#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_inc {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec2_dec {};
|
||||
|
||||
|
||||
// Magnitude
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec2_mag {};
|
||||
|
||||
// Dot product
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec2_dotp {};
|
||||
|
||||
// Max
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec2_max {};
|
||||
|
||||
// Min
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec2_min {};
|
||||
|
||||
// Set
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec2_set {};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct construct_vec2<T, false>
|
||||
{
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& v1, const TVector2<T, false>& v2)
|
||||
{
|
||||
v1.x = v2.x;
|
||||
v1.y = v2.y;
|
||||
}
|
||||
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& v1, T s)
|
||||
{
|
||||
v1.x = s;
|
||||
v1.y = s;
|
||||
}
|
||||
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& v1, T x, T y)
|
||||
{
|
||||
v1.x = x;
|
||||
v1.y = y;
|
||||
}
|
||||
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& v1, const T* comp)
|
||||
{
|
||||
v1.x = comp[0];
|
||||
v1.y = comp[1];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec2_add<T, false>
|
||||
{
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x + v2.x;
|
||||
r.y = v1.y + v2.y;
|
||||
}
|
||||
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x + s;
|
||||
r.y = v1.y + s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec2_sub<T, false>
|
||||
{
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x - v2.x;
|
||||
r.y = v1.y - v2.y;
|
||||
}
|
||||
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x - s;
|
||||
r.y = v1.y - s;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, T s, const Phanes::Core::Math::TVector2<T, false>& v1)
|
||||
{
|
||||
r.x = s - v1.x;
|
||||
r.y = s - v1.y;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec2_mul<T, false>
|
||||
{
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x * v2.x;
|
||||
r.y = v1.y * v2.y;
|
||||
}
|
||||
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x * s;
|
||||
r.y = v1.y * s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec2_div<T, false>
|
||||
{
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x / v2.x;
|
||||
r.y = v1.y / v2.y;
|
||||
}
|
||||
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v1, T s)
|
||||
{
|
||||
s = (T)1.0 / s;
|
||||
|
||||
r.x = v1.x * s;
|
||||
r.y = v1.y * s;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, T s, const Phanes::Core::Math::TVector2<T, false>& v1)
|
||||
{
|
||||
r.x = s / v1.x;
|
||||
r.y = s / v1.y;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec2_eq
|
||||
{
|
||||
|
||||
static constexpr bool map(const Phanes::Core::Math::TVector2<T, S>& v1, const Phanes::Core::Math::TVector2<T, S>& 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, bool S>
|
||||
struct compute_vec2_ieq
|
||||
{
|
||||
|
||||
static constexpr bool map(const Phanes::Core::Math::TVector2<T, S>& v1, const Phanes::Core::Math::TVector2<T, S>& 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>
|
||||
{
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v1)
|
||||
{
|
||||
r.x = v1.x + 1;
|
||||
r.y = v1.y + 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec2_dec<T, false>
|
||||
{
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v1)
|
||||
{
|
||||
r.x = v1.x - 1;
|
||||
r.y = v1.y - 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec2_mag<T, false>
|
||||
{
|
||||
static constexpr T map(const Phanes::Core::Math::TVector2<T, false>& v1)
|
||||
{
|
||||
return sqrt(v1.x * v1.x + v1.y * v1.y);
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec2_dotp<T, false>
|
||||
{
|
||||
static constexpr T map(const Phanes::Core::Math::TVector2<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2)
|
||||
{
|
||||
return v1.x * v2.x + v1.y * v2.y;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec2_max<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2)
|
||||
{
|
||||
r.x = (v1.x > v2.x) ? v1.x : v2.x;
|
||||
r.y = (v1.y > v2.y) ? v1.y : v2.y;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec2_min<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v1, const Phanes::Core::Math::TVector2<T, false>& v2)
|
||||
{
|
||||
r.x = (v1.x < v2.x) ? v1.x : v2.x;
|
||||
r.y = (v1.y < v2.y) ? v1.y : v2.y;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec2_set<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector2<T, false>& v1, T x, T y)
|
||||
{
|
||||
v1.x = x;
|
||||
v1.y = y;
|
||||
}
|
||||
};
|
||||
}
|
320
Engine/Source/Runtime/Core/Math/Detail/Vector3Decl.inl
Normal file
320
Engine/Source/Runtime/Core/Math/Detail/Vector3Decl.inl
Normal file
@@ -0,0 +1,320 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
namespace Phanes::Core::Math::Detail
|
||||
{
|
||||
template<RealType T, bool S>
|
||||
struct construct_vec3 {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct move_vec3 {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec3_add {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec3_sub {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec3_mul {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec3_div {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec3_eq {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec3_ieq {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec3_inc {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec3_dec {};
|
||||
|
||||
|
||||
// Cross product
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec3_cross_p {};
|
||||
|
||||
// Magnitude
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec3_mag {};
|
||||
|
||||
// dot product
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec3_dotp {};
|
||||
|
||||
// set
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec3_set {};
|
||||
|
||||
// clamp to cube
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec3_clamp {};
|
||||
|
||||
// max
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec3_max {};
|
||||
|
||||
// min
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec3_min {};
|
||||
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct construct_vec3<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const TVector3<T, false>& v1)
|
||||
{
|
||||
memcpy(r.data, v1.data, 4 * sizeof(T));
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, T s)
|
||||
{
|
||||
r.x = s;
|
||||
r.y = s;
|
||||
r.z = s;
|
||||
r.w = (T)0.0;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, T x, T y, T z)
|
||||
{
|
||||
r.x = x;
|
||||
r.y = y;
|
||||
r.z = z;
|
||||
r.w = (T)0.0;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x;
|
||||
r.y = v1.y;
|
||||
r.z = s;
|
||||
r.w = (T)0.0;
|
||||
}
|
||||
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const T* comp)
|
||||
{
|
||||
memcpy(r.data, comp, 3 * sizeof(T));
|
||||
r.w = (T)0.0;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec3_add<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1, const Phanes::Core::Math::TVector3<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x + v2.x;
|
||||
r.y = v1.y + v2.y;
|
||||
r.z = v1.z + v2.z;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x + s;
|
||||
r.y = v1.y + s;
|
||||
r.z = v1.z + s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec3_sub<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1, const Phanes::Core::Math::TVector3<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x - v2.x;
|
||||
r.y = v1.y - v2.y;
|
||||
r.z = v1.z - v2.z;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x - s;
|
||||
r.y = v1.y - s;
|
||||
r.z = v1.z - s;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, T s, const Phanes::Core::Math::TVector3<T, false>& v1)
|
||||
{
|
||||
r.x = s - v1.x;
|
||||
r.y = s - v1.y;
|
||||
r.z = s - v1.z;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec3_mul<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1, const Phanes::Core::Math::TVector3<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x * v2.x;
|
||||
r.y = v1.y * v2.y;
|
||||
r.z = v1.z * v2.z;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x * s;
|
||||
r.y = v1.y * s;
|
||||
r.z = v1.z * s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec3_div<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1, const Phanes::Core::Math::TVector3<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x / v2.x;
|
||||
r.y = v1.y / v2.y;
|
||||
r.z = v1.z / v2.z;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1, T s)
|
||||
{
|
||||
s = (T)1.0 / s;
|
||||
|
||||
r.x = v1.x * s;
|
||||
r.y = v1.y * s;
|
||||
r.z = v1.z * s;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, T s, const Phanes::Core::Math::TVector3<T, false>& v1)
|
||||
{
|
||||
r.x = s / v1.x;
|
||||
r.y = s / v1.y;
|
||||
r.z = s / v1.z;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec3_eq<T, false>
|
||||
{
|
||||
static constexpr bool map(const Phanes::Core::Math::TVector3<T, false>& v1, const Phanes::Core::Math::TVector3<T, false>& 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<RealType T>
|
||||
struct compute_vec3_ieq<T, false>
|
||||
{
|
||||
static constexpr bool map(const Phanes::Core::Math::TVector3<T, false>& v1, const Phanes::Core::Math::TVector3<T, false>& 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<RealType T>
|
||||
struct compute_vec3_inc<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1)
|
||||
{
|
||||
r.x = v1.x + 1;
|
||||
r.y = v1.y + 1;
|
||||
r.z = v1.z + 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec3_dec<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1)
|
||||
{
|
||||
r.x = v1.x - 1;
|
||||
r.y = v1.y - 1;
|
||||
r.z = v1.z - 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec3_cross_p<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false> v1, const Phanes::Core::Math::TVector3<T, false>& v2)
|
||||
{
|
||||
// V1 has to be copied, as otherwise changes to r affect calculation -> r is v1.
|
||||
|
||||
r.x = (v1.y * v2.z) - (v1.z * v2.y);
|
||||
r.y = (v1.z * v2.x) - (v1.x * v2.z);
|
||||
r.z = (v1.x * v2.y) - (v1.y * v2.x);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec3_mag<T, false>
|
||||
{
|
||||
static constexpr T map(const Phanes::Core::Math::TVector3<T, false>& v1)
|
||||
{
|
||||
return sqrt(v1.x * v1.x + v1.y * v1.y + v1.z * v1.z);
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec3_dotp<T, false>
|
||||
{
|
||||
static constexpr T map(const Phanes::Core::Math::TVector3<T, false>& v1, const Phanes::Core::Math::TVector3<T, false>& v2)
|
||||
{
|
||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec3_set<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& v1, T x, T y, T z)
|
||||
{
|
||||
v1.x = x;
|
||||
v1.y = y;
|
||||
v1.z = z;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec3_clamp<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1, T radius)
|
||||
{
|
||||
r.x = Clamp(v1.x, -radius, radius);
|
||||
r.y = Clamp(v1.y, -radius, radius);
|
||||
r.z = Clamp(v1.z, -radius, radius);
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec3_max<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1, const Phanes::Core::Math::TVector3<T, false>& v2)
|
||||
{
|
||||
r.x = (v1.x > v2.x) ? v1.x : v2.x;
|
||||
r.y = (v1.y > v2.y) ? v1.y : v2.y;
|
||||
r.z = (v1.z > v2.z) ? v1.z : v2.z;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec3_min<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector3<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v1, const Phanes::Core::Math::TVector3<T, false>& v2)
|
||||
{
|
||||
r.x = (v1.x < v2.x) ? v1.x : v2.x;
|
||||
r.y = (v1.y < v2.y) ? v1.y : v2.y;
|
||||
r.z = (v1.z < v2.z) ? v1.z : v2.z;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
328
Engine/Source/Runtime/Core/Math/Detail/Vector4Decl.inl
Normal file
328
Engine/Source/Runtime/Core/Math/Detail/Vector4Decl.inl
Normal file
@@ -0,0 +1,328 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
namespace Phanes::Core::Math::Detail
|
||||
{
|
||||
template<RealType T, bool S>
|
||||
struct construct_vec4 {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct move_vec4 {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec4_add {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec4_sub {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec4_mul {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec4_div {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec4_eq {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec4_ieq {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec4_inc {};
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec4_dec {};
|
||||
|
||||
|
||||
// Magnitude
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec4_mag {};
|
||||
|
||||
// dot product
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec4_dotp {};
|
||||
|
||||
// set
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec4_set {};
|
||||
|
||||
// max
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec4_max {};
|
||||
|
||||
// min
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec4_min {};
|
||||
|
||||
// perspective divide
|
||||
template<RealType T, bool S>
|
||||
struct compute_vec4_pdiv {};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct construct_vec4<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const TVector4<T, false>& v1)
|
||||
{
|
||||
|
||||
memcpy(r.data, v1.data, 4 * sizeof(T));
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, T s)
|
||||
{
|
||||
r.x = s;
|
||||
r.y = s;
|
||||
r.z = s;
|
||||
r.w = s;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, T x, T y, T z, T w)
|
||||
{
|
||||
r.x = x;
|
||||
r.y = y;
|
||||
r.z = z;
|
||||
r.w = w;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector2<T, false>& v2, const Phanes::Core::Math::TVector2<T, false>& v3)
|
||||
{
|
||||
r.x = v2.x;
|
||||
r.y = v2.y;
|
||||
r.z = v3.x;
|
||||
r.w = v3.y;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector3<T, false>& v, T w)
|
||||
{
|
||||
r.x = v.x;
|
||||
r.y = v.y;
|
||||
r.z = v.z;
|
||||
r.w = w;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const T* comp)
|
||||
{
|
||||
memcpy(r.data, comp, 4 * sizeof(T));
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec4_add<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1, const Phanes::Core::Math::TVector4<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x + v2.x;
|
||||
r.y = v1.y + v2.y;
|
||||
r.z = v1.z + v2.z;
|
||||
r.w = v1.w + v2.w;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x + s;
|
||||
r.y = v1.y + s;
|
||||
r.z = v1.z + s;
|
||||
r.w = v1.w + s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec4_sub<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1, const Phanes::Core::Math::TVector4<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x - v2.x;
|
||||
r.y = v1.y - v2.y;
|
||||
r.z = v1.z - v2.z;
|
||||
r.w = v1.w - v2.w;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x - s;
|
||||
r.y = v1.y - s;
|
||||
r.z = v1.z - s;
|
||||
r.w = v1.w - s;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, T s, const Phanes::Core::Math::TVector4<T, false>& v1)
|
||||
{
|
||||
r.x = s - v1.x;
|
||||
r.y = s - v1.y;
|
||||
r.z = s - v1.z;
|
||||
r.w = s - v1.w;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec4_mul<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1, const Phanes::Core::Math::TVector4<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x * v2.x;
|
||||
r.y = v1.y * v2.y;
|
||||
r.z = v1.z * v2.z;
|
||||
r.w = v1.w * v2.w;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1, T s)
|
||||
{
|
||||
r.x = v1.x * s;
|
||||
r.y = v1.y * s;
|
||||
r.z = v1.z * s;
|
||||
r.w = v1.w * s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec4_div<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1, const Phanes::Core::Math::TVector4<T, false>& v2)
|
||||
{
|
||||
r.x = v1.x / v2.x;
|
||||
r.y = v1.y / v2.y;
|
||||
r.z = v1.z / v2.z;
|
||||
r.w = v1.w / v2.w;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1, T s)
|
||||
{
|
||||
s = (T)1.0 / s;
|
||||
|
||||
r.x = v1.x * s;
|
||||
r.y = v1.y * s;
|
||||
r.z = v1.z * s;
|
||||
r.w = v1.w * s;
|
||||
}
|
||||
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, T s, const Phanes::Core::Math::TVector4<T, false>& v1)
|
||||
{
|
||||
r.x = s / v1.x;
|
||||
r.y = s / v1.y;
|
||||
r.z = s / v1.z;
|
||||
r.w = s / v1.w;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec4_eq<T, false>
|
||||
{
|
||||
static constexpr bool map(const Phanes::Core::Math::TVector4<T, false>& v1, const Phanes::Core::Math::TVector4<T, false>& 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<RealType T>
|
||||
struct compute_vec4_ieq<T, false>
|
||||
{
|
||||
static constexpr bool map(const Phanes::Core::Math::TVector4<T, false>& v1, const Phanes::Core::Math::TVector4<T, false>& 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<RealType T>
|
||||
struct compute_vec4_inc<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1)
|
||||
{
|
||||
r.x = v1.x + 1;
|
||||
r.y = v1.y + 1;
|
||||
r.z = v1.z + 1;
|
||||
r.w = v1.w + 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec4_dec<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1)
|
||||
{
|
||||
r.x = v1.x - 1;
|
||||
r.y = v1.y - 1;
|
||||
r.z = v1.z - 1;
|
||||
r.w = v1.w - 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec4_mag<T, false>
|
||||
{
|
||||
static constexpr T map(const Phanes::Core::Math::TVector4<T, false>& v1)
|
||||
{
|
||||
return sqrt(v1.x * v1.x + v1.y * v1.y + v1.z * v1.z + v1.w * v1.w);
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec4_dotp<T, false>
|
||||
{
|
||||
static constexpr T map(const Phanes::Core::Math::TVector4<T, false>& v1, const Phanes::Core::Math::TVector4<T, false>& v2)
|
||||
{
|
||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec4_set<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& v1, T x, T y, T z, T w)
|
||||
{
|
||||
v1.x = x;
|
||||
v1.y = y;
|
||||
v1.z = z;
|
||||
v1.w = w;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec4_max<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1, const Phanes::Core::Math::TVector4<T, false>& v2)
|
||||
{
|
||||
r.x = (v1.x > v2.x) ? v1.x : v2.x;
|
||||
r.y = (v1.y > v2.y) ? v1.y : v2.y;
|
||||
r.z = (v1.z > v2.z) ? v1.z : v2.z;
|
||||
r.w = (v1.w > v2.w) ? v1.w : v2.w;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec4_min<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1, const Phanes::Core::Math::TVector4<T, false>& v2)
|
||||
{
|
||||
r.x = (v1.x < v2.x) ? v1.x : v2.x;
|
||||
r.y = (v1.y < v2.y) ? v1.y : v2.y;
|
||||
r.z = (v1.z < v2.z) ? v1.z : v2.z;
|
||||
r.w = (v1.w < v2.w) ? v1.w : v2.w;
|
||||
}
|
||||
};
|
||||
|
||||
template<RealType T>
|
||||
struct compute_vec4_pdiv<T, false>
|
||||
{
|
||||
static constexpr void map(Phanes::Core::Math::TVector4<T, false>& r, const Phanes::Core::Math::TVector4<T, false>& v1)
|
||||
{
|
||||
T _1_w = (T)1.0 / v1.w;
|
||||
r.x = v1.x * _1_w;
|
||||
r.y = v1.y * _1_w;
|
||||
r.z = v1.z * _1_w;
|
||||
r.w = (T)0.0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
39
Engine/Source/Runtime/Core/Math/Include.h
Normal file
39
Engine/Source/Runtime/Core/Math/Include.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef P_DEBUG
|
||||
#pragma warning(disable : 4244)
|
||||
#endif
|
||||
|
||||
#include "Core/public/Math/MathFwd.h"
|
||||
|
||||
|
||||
// --- Vectors ------------------------
|
||||
|
||||
#include "Core/public/Math/Vector2.hpp"
|
||||
#include "Core/public/Math/Vector3.hpp"
|
||||
#include "Core/public/Math/Vector4.hpp"
|
||||
|
||||
#include "Core/public/Math/IntVector2.hpp"
|
||||
#include "Core/public/Math/IntVector3.hpp"
|
||||
#include "Core/public/Math/IntVector4.hpp"
|
||||
|
||||
#include "Core/public/Math/Point.hpp"
|
||||
#include "Core/public/Math/IntPoint.hpp"
|
||||
|
||||
|
||||
// --- Matrices ------------------------
|
||||
|
||||
#include "Core/public/Math/Matrix2.hpp"
|
||||
#include "Core/public/Math/Matrix3.hpp"
|
||||
#include "Core/public/Math/Matrix4.hpp"
|
||||
|
||||
// --- Other Math ----------------------
|
||||
|
||||
#include "Core/public/Math/Plane.hpp"
|
||||
#include "Core/public/Math/Line.hpp"
|
||||
|
||||
|
||||
// --- Misc -----------------
|
||||
|
||||
#include "Core/public/Math/MathTypeConversion.hpp"
|
||||
#include "Core/public/Math/MathUnitConversion.hpp"
|
146
Engine/Source/Runtime/Core/Math/IntPoint.hpp
Normal file
146
Engine/Source/Runtime/Core/Math/IntPoint.hpp
Normal file
@@ -0,0 +1,146 @@
|
||||
#pragma once
|
||||
|
||||
#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/IntVector2.hpp"
|
||||
#include "Core/public/Math/IntVector3.hpp"
|
||||
#include "Core/public/Math/IntVector4.hpp"
|
||||
|
||||
#ifndef P_DEBUG
|
||||
#pragma warning(disable : 4244)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* General annonation: The Point is the same as a vector. The type exists, to ensure a
|
||||
* easy differentiation between the two.
|
||||
*/
|
||||
|
||||
#ifndef INTPOINT_H
|
||||
#define INTPOINT_H
|
||||
|
||||
namespace Phanes::Core::Math {
|
||||
|
||||
/**
|
||||
* A 2D Point with components x and y with integer precision.
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
struct TIntPoint2 : public TIntVector2<T, false> {
|
||||
|
||||
using TIntVector2<T, false>::TIntVector2;
|
||||
|
||||
/**
|
||||
* Creates IntPoint2 from IntPoint3's xy
|
||||
*
|
||||
* @param a IntPoint3 one
|
||||
*/
|
||||
|
||||
TIntPoint2(const TIntPoint3<T>& a)
|
||||
{
|
||||
this->x = a.x;
|
||||
this->y = a.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates IntPoint2 from IntPoint4's xy
|
||||
*
|
||||
* @param a IntPoint4 one
|
||||
*/
|
||||
|
||||
//TIntPoint2(const TIntPoint4<T>& a)
|
||||
//{
|
||||
// this->x = a.x;
|
||||
// this->y = a.y;
|
||||
|
||||
//}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* A 3D Point with components x and y with integer precision.
|
||||
*/
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct TIntPoint3 : public TIntVector3<T, false> {
|
||||
|
||||
using TIntVector3<T, false>::TIntVector3;
|
||||
|
||||
/**
|
||||
* Creates IntPoint3 from IntPoint2's xy and zero
|
||||
*
|
||||
* @param a IntPoint2 one
|
||||
*/
|
||||
|
||||
TIntPoint3(const TIntPoint2<T>& a)
|
||||
{
|
||||
this->x = a.x;
|
||||
this->y = a.y;
|
||||
this->z = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates IntPoint3 from IntPoint4's xyz
|
||||
*
|
||||
* @param a IntPoint4 one
|
||||
*/
|
||||
|
||||
//TIntPoint3(const TIntPoint4<T>& a)
|
||||
//{
|
||||
// this->components[0] = a.components[0];
|
||||
// this->components[1] = a.components[1];
|
||||
// this->components[2] = a.components[2];
|
||||
//}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* A 4D Point with components x and y with integer precision.
|
||||
*/
|
||||
|
||||
|
||||
template<IntType T>
|
||||
struct TIntPoint4 : public TIntVector4<T, false> {
|
||||
|
||||
using TIntVector4<T, false>::TIntVector4;
|
||||
|
||||
/**
|
||||
* Creates IntPoint4 from IntPoint2's xy and the last two zero
|
||||
*
|
||||
* @param a IntPoint2 one
|
||||
*/
|
||||
|
||||
TIntPoint4(const TIntPoint2<T>& a)
|
||||
{
|
||||
this->data[0] = a.data[0];
|
||||
this->data[1] = a.data[1];
|
||||
this->data[2] = 0;
|
||||
this->data[3] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates IntPoint4 from IntPoint3's xyz and zero
|
||||
*
|
||||
* @param a IntPoint3 one
|
||||
*/
|
||||
|
||||
TIntPoint4(const TIntPoint3<T>& a)
|
||||
{
|
||||
this->data[0] = a.data[0];
|
||||
this->data[1] = a.data[1];
|
||||
this->data[2] = a.data[2];
|
||||
this->data[3] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // phanes::core::math::coretypes
|
||||
|
||||
#endif // !INTPOINT_H
|
630
Engine/Source/Runtime/Core/Math/IntVector2.hpp
Normal file
630
Engine/Source/Runtime/Core/Math/IntVector2.hpp
Normal file
@@ -0,0 +1,630 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/MathCommon.hpp"
|
||||
#include "Core/public/Math/MathFwd.h"
|
||||
|
||||
#include "Core/public/Math/SIMD/Storage.h"
|
||||
|
||||
#ifndef P_DEBUG
|
||||
#pragma warning(disable : 4244)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Note: Some function are deleted, because, their unusable with int types, except very specific cases.
|
||||
* To keep the library verbose, these functions are explicitly marked as deleted.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INTVECTOR2_H
|
||||
#define INTVECTOR2_H
|
||||
|
||||
#define PIntZeroVector2(type, aligned) TIntVector2<##type, ##aligned>(0,0)
|
||||
#define PIntVectorSouth2(type, aligned) TIntVector2<##type, ##aligned>(0,-1)
|
||||
#define PIntVectorNorth2(type, aligned) TIntVector2<##type, ##aligned>(0,1)
|
||||
#define PIntVectorEast2(type, aligned) TIntVector2<##type, ##aligned>(1,0)
|
||||
#define PIntVectorWest2(type, aligned) TIntVector2<##type, ##aligned>(-1,0)
|
||||
|
||||
|
||||
namespace Phanes::Core::Math {
|
||||
|
||||
/**
|
||||
* A 2D Vector with components x and y with integer precision.
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
struct TIntVector2 {
|
||||
|
||||
public:
|
||||
|
||||
// Using in combination with a struct and an array allows us the reflect changes of the x and y variables in the comp array and vise versa.
|
||||
|
||||
union
|
||||
{
|
||||
|
||||
struct
|
||||
{
|
||||
/** X component of Vector
|
||||
*
|
||||
* @ref [FIELD]components
|
||||
* @note x does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
|
||||
*/
|
||||
T x;
|
||||
|
||||
/** Y component of Vector
|
||||
*
|
||||
* @ref [FIELD]components
|
||||
*
|
||||
* @note y does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
|
||||
*/
|
||||
T y;
|
||||
};
|
||||
|
||||
/** Components array holding the data
|
||||
*
|
||||
* @ref [FIELD]x
|
||||
* @ref [FIELD]y
|
||||
*
|
||||
* @note Components are split into x and y. Access and manipulation is possible by these variables.
|
||||
*/
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor without initialization
|
||||
*/
|
||||
|
||||
TIntVector2() = default;
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*/
|
||||
|
||||
TIntVector2(const TIntVector2<T, A>& v);
|
||||
|
||||
/**
|
||||
* Construct Vector from xy components.
|
||||
*
|
||||
* @param x X component
|
||||
* @param y Y component
|
||||
*/
|
||||
|
||||
TIntVector2(const T x, const T y);
|
||||
|
||||
/**
|
||||
* Construct Vector from two component array.
|
||||
*
|
||||
* @param comp Array of components
|
||||
*/
|
||||
|
||||
TIntVector2(const T* comp);
|
||||
|
||||
/**
|
||||
* Construct Vector from 3D integer Vector's xy.
|
||||
*
|
||||
* @param v 3D IntVector to copy from
|
||||
*/
|
||||
|
||||
TIntVector2(const T s);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// ======================== //
|
||||
// IntVector2 operators //
|
||||
// ======================== //
|
||||
|
||||
/**
|
||||
* Addition operation on same TIntVector2<T, A> (this) by a scalar value.
|
||||
*
|
||||
* @param(v1) Vector to add to
|
||||
* @param(s) Scalar to add
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A>& operator+= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Addition operation on same TIntVector2<T, A> (this) by a another TIntVector2<T, A>.
|
||||
*
|
||||
* @param(v1) Vector to add to
|
||||
* @param(v2) Vector to add
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A>& operator+= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
/**
|
||||
* Substraction operation on same TIntVector2<T, A> (this) by a scalar.
|
||||
*
|
||||
* @param(v1) Vector to substract from
|
||||
* @param(v2) Scalar to substract
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A>& operator-= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Substraction operation on same TIntVector2<T, A> (this) by a another TIntVector2<T, A>.
|
||||
*
|
||||
* @param(v1) Vector to substract from
|
||||
* @param(v2) Vector to substract
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A>& operator-= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
|
||||
/**
|
||||
* Multiplication of TIntVector2<T, A> (this) with a scalar.
|
||||
*
|
||||
* @param(v1) Vector to multiply with
|
||||
* @param(s) scalar to multiply with
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A>& operator*= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A>& operator*= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
/**
|
||||
* Devision of Vector
|
||||
*
|
||||
* @param(v1) Vector to divide with
|
||||
* @param(s) Scalar to divide with
|
||||
*
|
||||
* @note Result is rounded
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A>& operator/= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A>& operator/= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
/**
|
||||
* Stores the remainder of division by a scalar.
|
||||
*
|
||||
* @param(v1) Vector to divide with
|
||||
* @param(s) Scalar to divide with
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A>& operator%= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A>& operator%= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator&= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator&= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator|= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator|= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator^= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator^= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator<<= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator<<= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator>>= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator>>= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Scale of Vector by floating point. (> Creates a new TIntVector2<T, A>)
|
||||
*
|
||||
* @param(v1) Vector to multiply with
|
||||
* @param(s Floating point to multiply with
|
||||
*
|
||||
* @return Result Vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A> operator* (const TIntVector2<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Division of Vector by floating point. (> Creates another TIntVector2<T, A>)
|
||||
*
|
||||
* @see [FUNC]DivideFloat
|
||||
*
|
||||
* @param(v1) Vector to multiply with
|
||||
* @param(s Floating point to divide with
|
||||
*
|
||||
* @return Result Vector
|
||||
* @note Deleted, because the returntype might not implicitly be obvious, when using in code or reading.
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A> operator/ (const TIntVector2<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Scale of Vector by floating point. (> Creates a new TIntVector2<T, A>)
|
||||
*
|
||||
* @param(v1) Vector to multiply with
|
||||
* @param(s Floating point to multiply with
|
||||
*
|
||||
* @return Result Vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
FORCEINLINE TIntVector2<T, A> operator* (T s, const TIntVector2<T, A>& v1) { return v1 * s; };
|
||||
|
||||
/**
|
||||
* Division of Vector by floating point. (> For convenience not arithmethicaly correct. Works like overloaded counterpart.)
|
||||
*
|
||||
* @see [FUNC]DivideFloat
|
||||
*
|
||||
* @param(v1) Vector to multiply with
|
||||
* @param(s Floating point to divide with
|
||||
*
|
||||
* @return Result Vector
|
||||
*
|
||||
* @note Deleted, because the returntype might not implicitly be obvious, when using in code or reading.
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
FORCEINLINE TIntVector2<T, A> operator/ (T s, const TIntVector2<T, A>& v1) { return v1 / s; };
|
||||
|
||||
/**
|
||||
* Dot product between two Vectors.
|
||||
*
|
||||
* @see [FUNC]DotP
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @result Dot product
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
T operator* (const TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
/**
|
||||
* Componentwise addition of Vector with floating point.
|
||||
*
|
||||
* @param(v1) Vector to add to
|
||||
* @param(s Floating point to add
|
||||
*
|
||||
* @return Result Vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A> operator+ (const TIntVector2<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Componentwise addition of Vector with floating point.
|
||||
*
|
||||
* @param(v1) Vector to add to
|
||||
* @param(s Floating point to add
|
||||
*
|
||||
* @return Result Vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A> operator+ (const TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
/**
|
||||
* Componentwise substraction of Vector with floating point.
|
||||
*
|
||||
* @param(v1) Vector to substract from
|
||||
* @param(s Floating point to substract
|
||||
*
|
||||
* @return Result Vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A> operator- (const TIntVector2<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Componentwise substraction of Vector with Vector.
|
||||
*
|
||||
* @param(v1) Vector to substract from
|
||||
* @param(s Floating point to substract
|
||||
*
|
||||
* @return Result Vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A> operator- (const TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Scale of Vector by floating point. (> Creates a new TIntVector2<T, A>)
|
||||
*
|
||||
* @param(v1) Vector to multiply with
|
||||
* @param(s Floating point to multiply with
|
||||
*
|
||||
* @return Result Vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator% (const TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator% (const TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator& (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator& (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator| (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator| (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator^ (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator^ (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator<< (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator<< (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator>> (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator>> (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator~ (TIntVector2<T, A>& v1);
|
||||
|
||||
|
||||
/**
|
||||
* Compare Vector for equality.
|
||||
*
|
||||
* @see [FUNC]Equals
|
||||
*
|
||||
* @param(v1) Vector to negate
|
||||
*
|
||||
* @return true if equal, false if inequal
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
bool operator== (const TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
|
||||
/**
|
||||
* Compare Vector for inequality.
|
||||
*
|
||||
* @see [FUNC]Equals
|
||||
*
|
||||
* @param(v1) Vector to negate
|
||||
*
|
||||
* @return true if inequal, false if equal
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
bool operator!= (const TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
|
||||
|
||||
// ============================================== //
|
||||
// TIntVector2 static function implementation //
|
||||
// ============================================== //
|
||||
|
||||
template<IntType T>
|
||||
T DotP(const TIntVector2<T, false>& v, const TIntVector2<T, false>& v1)
|
||||
{
|
||||
return v.x * v1.x + v.y * v1.y;
|
||||
}
|
||||
|
||||
template<IntType T>
|
||||
TIntVector2<T, false>& MaxV(TIntVector2<T, false>& v1, const TIntVector2<T, false>& v2)
|
||||
{
|
||||
v1.x = Phanes::Core::Math::Max(v1.x, v2.x);
|
||||
v1.y = Phanes::Core::Math::Max(v1.y, v2.y);
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Vector, with component wise smallest values.
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @note Stores new Vector to v1
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector2<T, false>& MinV(TIntVector2<T, false>& v1, const TIntVector2<T, false>& v2)
|
||||
{
|
||||
v1.x = Phanes::Core::Math::Min(v1.x, v2.x);
|
||||
v1.y = Phanes::Core::Math::Min(v1.y, v2.y);
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns signs of numbers (1 / -1). <br>
|
||||
/// Returns 1 for zero.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="v1"></param>
|
||||
/// <returns></returns>
|
||||
template<IntType T>
|
||||
TIntVector2<T, false>& SignVectorV(TIntVector2<T, false>& v1)
|
||||
{
|
||||
v1.x = (v1.x >= 0) ? 1 : -1;
|
||||
v1.y = (v1.y >= 0) ? 1 : -1;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies one Vector two another
|
||||
*
|
||||
* @param(v1) Vector to copy to
|
||||
* @param(v2) Vector to copy
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector2<T, false>& Set(TIntVector2<T, false>& v1, const TIntVector2<T, false>& v2)
|
||||
{
|
||||
v1 = v2;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets components of a vector.
|
||||
*
|
||||
* @param(v1) Vector to copy to
|
||||
* @param(v2) Vector to copy
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector2<T, false>& Set(TIntVector2<T, false>& v1, T x, T y)
|
||||
{
|
||||
v1.x = x;
|
||||
v1.y = y;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Negates Vector
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector2<T, false>& NegateV(TIntVector2<T, false>& v1)
|
||||
{
|
||||
v1.x = -v1.x;
|
||||
v1.y = -v1.y;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if 2 vectors are perpendicular to each other.
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @return true if perpendicular, false if not
|
||||
*
|
||||
* @note Requires v1 and v2 to be normal vectors.
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
inline bool IsPerpendicular(const TIntVector2<T, false>& v1, const TIntVector2<T, false>& v2)
|
||||
{
|
||||
return (Abs(DotP(v1, v2)) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets outer product of to vectors.
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @return Resulting matrix
|
||||
*/
|
||||
|
||||
//template<IntType T>
|
||||
//Matrix2<T> OuterProduct(const TIntVector2<T, false>& v1, const TIntVector2<T, false>& v2);
|
||||
|
||||
|
||||
// ================================================================ //
|
||||
// IntVector2 static function implementation with return values //
|
||||
// ================================================================ //
|
||||
|
||||
|
||||
/**
|
||||
* Negates Vector
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
*
|
||||
* @return Componentwise inverted vector
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector2<T, false> Negate(const TIntVector2<T, false>& v1)
|
||||
{
|
||||
return TIntVector2<T, false>(-v1.x, -v1.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Vector by the component wise minimals of both vectors
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @return Minimal vector
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector2<T, false> Min(const TIntVector2<T, false>& v1, const TIntVector2<T, false>& v2)
|
||||
{
|
||||
return TIntVector2<T, false>(Phanes::Core::Math::Min(v1.x, v2.x), Phanes::Core::Math::Min(v1.y, v2.y));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Vector by the component wise maxima of both vectors
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @return Maximal vector
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector2<T, false> Max(const TIntVector2<T, false>& v1, const TIntVector2<T, false>& v2)
|
||||
{
|
||||
return TIntVector2<T, false>(Phanes::Core::Math::Max(v1.x, v2.x), Phanes::Core::Math::Max(v1.y, v2.y));
|
||||
}
|
||||
|
||||
|
||||
template<IntType T>
|
||||
TIntVector2<T, false> SignVector(const TIntVector2<T, false>& v1)
|
||||
{
|
||||
return TIntVector2<T, false>((v1.x >= 0) ? 1 : -1, (v1.y >= 0) ? 1 : -1);
|
||||
}
|
||||
|
||||
|
||||
} // phanes::core::math::coretypes
|
||||
|
||||
#endif // !INTVECTOR2_H
|
||||
|
||||
#include "Core/public/Math/IntVector2.inl"
|
401
Engine/Source/Runtime/Core/Math/IntVector2.inl
Normal file
401
Engine/Source/Runtime/Core/Math/IntVector2.inl
Normal file
@@ -0,0 +1,401 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/Detail/IntVector2Decl.inl"
|
||||
#include "Core/public/Math/SIMD/SIMDIntrinsics.h"
|
||||
|
||||
#include "Core/public/Math/SIMD/PhanesSIMDTypes.h"
|
||||
|
||||
namespace Phanes::Core::Math
|
||||
{
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>::TIntVector2(const TIntVector2<T, S>& v)
|
||||
{
|
||||
Detail::construct_ivec2<T, S>::map(*this, v);
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>::TIntVector2(const T _x, const T _y)
|
||||
{
|
||||
Detail::construct_ivec2<T, S>::map(*this, _x, _y);
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>::TIntVector2(const T s)
|
||||
{
|
||||
Detail::construct_ivec2<T, S>::map(*this, s);
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>::TIntVector2(const T* comp)
|
||||
{
|
||||
Detail::construct_ivec2<T, S>::map(*this, comp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator+=(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec2_add<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator+=(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec2_add<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator-=(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec2_sub<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator-=(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec2_sub<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator*=(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec2_mul<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator*=(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec2_mul<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator/=(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec2_div<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator/=(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec2_div<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator%=(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec2_mod<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator%=(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec2_mod<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator+(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_add<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator+(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_add<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator-(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_sub<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator-(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_sub<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator*(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_mul<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator*(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_mul<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator/(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_div<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator/(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_div<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator%(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_mod<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator%(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_mod<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Bitwise operators
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator&=(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec2_and<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator&=(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec2_and<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator|=(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec2_or<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator|=(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec2_or<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator^=(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec2_xor<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator^=(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec2_xor<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator<<=(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec2_left_shift<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator<<=(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec2_left_shift<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator>>=(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec2_right_shift<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator>>=(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec2_right_shift<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator&(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_and<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator&(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_and<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator|(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_or<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator|(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_or<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator^(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_xor<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator^(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_xor<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator<<(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_left_shift<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator<<(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_left_shift<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator>>(TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_right_shift<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator>>(TIntVector2<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_right_shift<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S> operator~(TIntVector2<T, S>& v1)
|
||||
{
|
||||
TIntVector2<T, S> r;
|
||||
Detail::compute_ivec2_bnot<T, S>::map(r, v1);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Comparision
|
||||
|
||||
template<IntType T, bool S>
|
||||
bool operator==(const TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
return Detail::compute_ivec2_eq<T, S>::map(v1, v2);
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
bool operator!=(const TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
return Detail::compute_ivec2_ieq<T, S>::map(v1, v2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Inc- / Decrement
|
||||
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator++(TIntVector2<T, S>& v1)
|
||||
{
|
||||
Detail::compute_ivec2_inc<T, S>::map(v1, v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator--(TIntVector2<T, S>& v1)
|
||||
{
|
||||
Detail::compute_ivec2_dec<T, S>::map(v1, v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator++(TIntVector2<T, S>& v1, int)
|
||||
{
|
||||
return ++v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector2<T, S>& operator--(TIntVector2<T, S>& v1, int)
|
||||
{
|
||||
return --v1;
|
||||
}
|
||||
}
|
689
Engine/Source/Runtime/Core/Math/IntVector3.hpp
Normal file
689
Engine/Source/Runtime/Core/Math/IntVector3.hpp
Normal file
@@ -0,0 +1,689 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/MathCommon.hpp"
|
||||
#include "Core/public/Math/MathFwd.h"
|
||||
|
||||
#include "Core/public/Math/SIMD/Storage.h"
|
||||
|
||||
#include "Core/public/Math/IntVector4.hpp"
|
||||
|
||||
#ifndef P_DEBUG
|
||||
#pragma warning(disable : 4244)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef INTVECTOR3_H
|
||||
#define INTVECTOR3_H
|
||||
|
||||
#define PIntZeroVector3(type) TIntVector3<##type>(0,0,0)
|
||||
#define PIntVectorForward3(type) TIntVector3<##type>(1,0,0)
|
||||
#define PIntVectorBackward3(type) TIntVector3<##type>(-1,0,0)
|
||||
#define PIntVectorEast3(type) TIntVector3<##type>(0,1,0)
|
||||
#define PIntVectorWest3(type) TIntVector3<##type>(0,-1,0)
|
||||
#define PIntVectorUp3(type) TIntVector3<##type>(0,0,1)
|
||||
#define PIntVectorDown3(type) TIntVector3<##type>(0,0,-1)
|
||||
|
||||
namespace Phanes::Core::Math {
|
||||
|
||||
/**
|
||||
* A 3D Vector with components x, y and z with integer precision.
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
struct TIntVector3 : public TIntVector4<T, A> {
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor without initialization
|
||||
*/
|
||||
|
||||
TIntVector3() = default;
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*/
|
||||
|
||||
TIntVector3(const TIntVector3<T, A>& v);
|
||||
|
||||
/**
|
||||
* Construct Vector from xyz components.
|
||||
*
|
||||
* @param(x) X component
|
||||
* @param(y) Y component
|
||||
* @param(z) Z component
|
||||
*/
|
||||
|
||||
TIntVector3(const T x, const T y, const T z);
|
||||
|
||||
/// <summary>
|
||||
/// Broadcast s into all components.
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
TIntVector3(const T s);
|
||||
|
||||
/**
|
||||
* Construct Vector from two component array.
|
||||
*
|
||||
* @param(comp) Array of components
|
||||
*/
|
||||
|
||||
TIntVector3(const T* comp);
|
||||
|
||||
TIntVector3(const TIntVector2<T, A>& v1, const T s);
|
||||
|
||||
};
|
||||
|
||||
|
||||
// ======================== //
|
||||
// IntVector3 operators //
|
||||
// ======================== //
|
||||
|
||||
|
||||
/**
|
||||
* Coponentwise addition of scalar to 3D vector
|
||||
*
|
||||
* @param(v1) vector to add to
|
||||
* @param(s) scalar to add
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector3<T, A>& operator+= (TIntVector3<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Coponentwise addition of 3D vector to 3D vector
|
||||
*
|
||||
* @param(v1) vector to add to
|
||||
* @param(v2) vector to add
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector3<T, A>& operator+= (TIntVector3<T, A>& v1, const TIntVector3<T, A>& v2);
|
||||
|
||||
/**
|
||||
* Coponentwise substraction of scalar of 3D vector
|
||||
*
|
||||
* @param(v1) vector to substract from
|
||||
* @param(s) scalar to substract
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector3<T, A>& operator-= (TIntVector3<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Coponentwise substraction of 3D vector to 3D vector
|
||||
*
|
||||
* @param(v1) vector to substract from
|
||||
* @param(v2) vector to substract with
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector3<T, A>& operator-= (TIntVector3<T, A>& v1, const TIntVector3<T, A>& v2);
|
||||
|
||||
/**
|
||||
* Dot product between two 3D Vectors
|
||||
*
|
||||
* @param(v1) vector one
|
||||
* @param(s) scalar
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector3<T, A>& operator*= (TIntVector3<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Division of vector by scalar
|
||||
*
|
||||
* @param(v1) vector one
|
||||
* @param(s) scalar
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector3<T, A>& operator/= (TIntVector3<T, A>& v1, T s);
|
||||
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A>& operator%= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector2<T, A>& operator%= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator&= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator&= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator|= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator|= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator^= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator^= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator<<= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator<<= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator>>= (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A>& operator>>= (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Coponentwise multiplication of 3D Vectors with scalar
|
||||
*
|
||||
* @param(v1) vector one
|
||||
* @param(s) scalar
|
||||
*
|
||||
* @return Resulting vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector3<T, A> operator* (const TIntVector3<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Coponentwise multiplication of 3D Vectors with scalar
|
||||
*
|
||||
* @param(s) scalar
|
||||
* @param(v2) vector
|
||||
*
|
||||
* @return Solution vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
FORCEINLINE TIntVector3<T, A> operator* (T s, const TIntVector3<T, A>& v1) { return v1 / s; };
|
||||
|
||||
/**
|
||||
* Division by scalar
|
||||
*
|
||||
* @param(s) scalar
|
||||
* @param(v2) vector
|
||||
*
|
||||
* @return Solution vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector3<T, A> operator/ (const TIntVector3<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
FORCEINLINE TIntVector3<T, A> operator/ (T s, const TIntVector3<T, A>& v1) { return v1 / s; };
|
||||
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator% (const TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator% (const TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator& (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator& (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator| (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator| (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator^ (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator^ (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator<< (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator<< (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator>> (TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator>> (TIntVector2<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector2<T, A> operator~ (TIntVector2<T, A>& v1);
|
||||
|
||||
/**
|
||||
* Dot product between two 3D Vectors
|
||||
*
|
||||
* @param(v1) vector one
|
||||
* @param(v2) vector two
|
||||
*
|
||||
* @return Dot product of Vectors
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector3<T, A> operator* (const TIntVector3<T, A>& v1, const TIntVector3<T, A>& v2);
|
||||
|
||||
/**
|
||||
* Coponentwise addition of scalar to 3D vector
|
||||
*
|
||||
* @param(v1) vector to add to
|
||||
* @param(s) scalar to add
|
||||
*
|
||||
* @return Resulting vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector3<T, A> operator+ (const TIntVector3<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Coponentwise addition of 3D vector to 3D vector
|
||||
*
|
||||
* @param(v1) vector to add to
|
||||
* @param(v2) vector to add
|
||||
*
|
||||
* @return Resulting vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector3<T, A> operator+ (const TIntVector3<T, A>& v1, const TIntVector3<T, A>& v2);
|
||||
|
||||
/**
|
||||
* Coponentwise substraction of scalar of 3D vector
|
||||
*
|
||||
* @param(v1) vector to substract from
|
||||
* @param(s) scalar to substract
|
||||
*
|
||||
* @return Resulting vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector3<T, A> operator- (const TIntVector3<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Coponentwise substraction of scalar of 3D vector
|
||||
*
|
||||
* @param(v1) vector to substract from
|
||||
* @param(v2) vector to substract with
|
||||
*
|
||||
* @return Resulting vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector3<T, A> operator- (const TIntVector3<T, A>& v1, const TIntVector3<T, A>& v2);
|
||||
|
||||
/**
|
||||
* Tests two 3D vectors for equality.
|
||||
*
|
||||
* @ref [FUNC]Equals
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @return True if equal, false if not.
|
||||
*
|
||||
* @note Uses [MACRO]P_FLT_INAC
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline bool operator== (const TIntVector3<T, A>& v1, const TIntVector3<T, A>& v2);
|
||||
|
||||
/**
|
||||
* Tests two 3D vectors for inequality.
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @return True if inequal, false if not.
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline bool operator!= (const TIntVector3<T, A>& v1, const TIntVector3<T, A>& v2);
|
||||
|
||||
|
||||
// ============================================== //
|
||||
// IntVector3 static function implementation //
|
||||
// ============================================== //
|
||||
|
||||
|
||||
/**
|
||||
* Dot product of two vectors
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @return Dot product of vectors
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
T DotP(const TIntVector3<T, false>& v1, const TIntVector3<T, false>& v2)
|
||||
{
|
||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests two vectors for equality.
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
* @param(threshold) Allowed T inaccuracy.
|
||||
*
|
||||
* @return True if equal, false if not.
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
inline bool Equals(const TIntVector3<T, false>& v1, const TIntVector3<T, false>& v2, T threshold = P_FLT_INAC)
|
||||
{
|
||||
return (abs(v1.x - v2.x) < threshold && abs(v1.y - v2.y) < threshold && abs(v1.z - v2.z) < threshold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the cross product between two vectors.
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @note result is stored in v1.
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector3<T, false>& CrossPV(TIntVector3<T, false>& v1, const TIntVector3<T, false>& v2)
|
||||
{
|
||||
T x = v1.x;
|
||||
T y = v1.y;
|
||||
T z = v1.z;
|
||||
|
||||
v1.x = (y * v2.z) - (z * v2.y);
|
||||
v1.y = (z * v2.x) - (x * v2.z);
|
||||
v1.z = (x * v2.y) - (y * v2.x);
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the componentwise max of both vectors.
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @note result is stored in v1.
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector3<T, false>& MaxV(TIntVector3<T, false>& v1, const TIntVector3<T, false>& v2)
|
||||
{
|
||||
v1.x = Phanes::Core::Math::Max(v1.x, v2.x);
|
||||
v1.y = Phanes::Core::Math::Max(v1.y, v2.y);
|
||||
v1.z = Phanes::Core::Math::Max(v1.z, v2.z);
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the componentwise min of both vectors.
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @note result is stored in v1.
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector3<T, false>& MinV(TIntVector3<T, false>& v1, const TIntVector3<T, false>& v2)
|
||||
{
|
||||
v1.x = Phanes::Core::Math::Min(v1.x, v2.x);
|
||||
v1.y = Phanes::Core::Math::Min(v1.y, v2.y);
|
||||
v1.z = Phanes::Core::Math::Min(v1.z, v2.z);
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets reversed vector.
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
*
|
||||
* @note result is stored in v1.
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector3<T, false>& NegateV(TIntVector3<T, false>& v1)
|
||||
{
|
||||
v1.x = -v1.x;
|
||||
v1.y = -v1.y;
|
||||
v1.z = -v1.z;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies v1 vector
|
||||
*
|
||||
* @param(v1) Vector to copy to
|
||||
* @param(v2) Vector to copy
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector3<T, false>& Set(TIntVector3<T, false>& v1, const TIntVector3<T, false>& v2)
|
||||
{
|
||||
v1 = v2;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets vector.
|
||||
*
|
||||
* @param(v1) Vector to copy to
|
||||
* @param(x) X component
|
||||
* @param(y) Y component
|
||||
* @param(z) Z component
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector3<T, false>& Set(TIntVector3<T, false>& v1, T x, T y, T z)
|
||||
{
|
||||
v1.x = x;
|
||||
v1.y = y;
|
||||
v1.z = z;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns signs of components in vector: -1 / +1 / 0.
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector3<T, false>& SignVectorV(TIntVector3<T, false>& v1)
|
||||
{
|
||||
v1.x = (v1.x >= 0) ? 1 : -1;
|
||||
v1.y = (v1.y >= 0) ? 1 : -1;
|
||||
v1.z = (v1.z >= 0) ? 1 : -1;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets scalar triple product ((v1 x v2) * v3). (Volume of parallelepiped.)
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
* @param(v3) Vector three
|
||||
*
|
||||
* @return Vector triple product
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
T ScalarTriple(const TIntVector3<T, false>& v1, const TIntVector3<T, false>& v2, const TIntVector3<T, false>& v3)
|
||||
{
|
||||
return DotP(CrossP(v1, v2), v3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets vector triple product ((v1 x v2) x v3).
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
* @param(v3) Vector three
|
||||
*
|
||||
* @note result is stored in v1
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector3<T, false>& VectorTripleV(TIntVector3<T, false>& v1, const TIntVector3<T, false>& v2, const TIntVector3<T, false>& v3)
|
||||
{
|
||||
CrossPV(CrossPV(v1, v2), v3);
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T>
|
||||
TIntVector3<T, false>& GetPerpendicular(TIntVector3<T, false>& v1)
|
||||
{
|
||||
T y = v1.y;
|
||||
v1.x = 0;
|
||||
v1.y = v1.z;
|
||||
v1.z = -y;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether two vectors are perpendicular.
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @return True if perpendicular, false if not.
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
inline bool IsPerpendicular(const TIntVector3<T, false>& v1, const TIntVector3<T, false>& v2)
|
||||
{
|
||||
return (DotP(v1, v2) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if three vectors are coplanar
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
* @param(v3) Vector three
|
||||
*
|
||||
* @return True if coplanar, false if not.
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
inline bool IsCoplanar(const TIntVector3<T, false>& v1, const TIntVector3<T, false>& v2, const TIntVector3<T, false>& v3)
|
||||
{
|
||||
return (ScalarTriple(v1, v2, v3) == 0);
|
||||
}
|
||||
|
||||
|
||||
// ================================================================ //
|
||||
// IntVector3 static function implementation with return values //
|
||||
// ================================================================ //
|
||||
|
||||
/**
|
||||
* Gets cross product between two vectors.
|
||||
*
|
||||
* @param(v1) vector one
|
||||
* @param(v2) vector two
|
||||
*
|
||||
* @return Cross product of v1 and v2
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector3<T, false> CrossP(const TIntVector3<T, false>& v1, const TIntVector3<T, false>& v2)
|
||||
{
|
||||
return TIntVector3<T, false>((v1.y * v2.z) - (v1.z * v2.y),
|
||||
(v1.z * v2.x) - (v1.x * v2.z),
|
||||
(v1.x * v2.y) - (v1.y * v2.x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Vector by the componentwise max of both vectors
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @return Vector of componentwise max
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector3<T, false> Max(const TIntVector3<T, false>& v1, const TIntVector3<T, false>& v2)
|
||||
{
|
||||
return TIntVector3<T, false>((v1.x > v2.x) ? v1.x : v2.x,
|
||||
(v1.y > v2.y) ? v1.y : v2.y,
|
||||
(v1.z > v2.z) ? v1.z : v2.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Vector by the componentwise min of both vectors
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @return Vector of componentwise min
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector3<T, false> Min(const TIntVector3<T, false>& v1, const TIntVector3<T, false>& v2)
|
||||
{
|
||||
return TIntVector3<T, false>((v1.x < v2.x) ? v1.x : v2.x,
|
||||
(v1.y < v2.y) ? v1.y : v2.y,
|
||||
(v1.z < v2.z) ? v1.z : v2.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets reversed vector.
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
*
|
||||
* @note result is stored in v1.
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector3<T, false> Negate(const TIntVector3<T, false>& v1)
|
||||
{
|
||||
return TIntVector3<T, false>(-v1.x, -v1.y, -v1.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets vector triple product ((v1 x v2) x v3).
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
* @param(v3) Vector three
|
||||
*
|
||||
* @return Vector triple product
|
||||
*/
|
||||
|
||||
template<IntType T>
|
||||
TIntVector3<T, false> VectorTriple(const TIntVector3<T, false>& v1, const TIntVector3<T, false>& v2, const TIntVector3<T, false>& v3)
|
||||
{
|
||||
return CrossP(CrossP(v1, v2), v3);
|
||||
}
|
||||
|
||||
template<IntType T>
|
||||
TIntVector3<T, false> SignVector(const TIntVector3<T, false>& v1)
|
||||
{
|
||||
return TIntVector3<T, false>((v1.x >= 0) ? 1 : -1, (v1.y >= 0) ? 1 : -1, (v1.z >= 0) ? 1 : -1);
|
||||
}
|
||||
|
||||
} // phanes::core::math::coretypes
|
||||
|
||||
#endif // !INTVECTOR3_H
|
||||
|
||||
#include "Core/public/Math/IntVector3.inl"
|
408
Engine/Source/Runtime/Core/Math/IntVector3.inl
Normal file
408
Engine/Source/Runtime/Core/Math/IntVector3.inl
Normal file
@@ -0,0 +1,408 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/Detail/IntVector3Decl.inl"
|
||||
#include "Core/public/Math/SIMD/SIMDIntrinsics.h"
|
||||
|
||||
#include "Core/public/Math/SIMD/PhanesSIMDTypes.h"
|
||||
|
||||
|
||||
namespace Phanes::Core::Math
|
||||
{
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>::TIntVector3(const TIntVector3<T, S>& v)
|
||||
{
|
||||
Detail::construct_ivec3<T, S>::map(*this, v);
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>::TIntVector3(const T _x, const T _y, const T _z)
|
||||
{
|
||||
Detail::construct_ivec3<T, S>::map(*this, _x, _y, _z);
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>::TIntVector3(const T s)
|
||||
{
|
||||
Detail::construct_ivec3<T, S>::map(*this, s);
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>::TIntVector3(const T* comp)
|
||||
{
|
||||
Detail::construct_ivec3<T, S>::map(*this, comp);
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>::TIntVector3(const TIntVector2<T, S>& v1, const T s)
|
||||
{
|
||||
Detail::construct_ivec3<T, S>::map(*this, v1, s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator+=(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec3_add<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator+=(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec3_add<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator-=(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec3_sub<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator-=(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec3_sub<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator*=(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec3_mul<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator*=(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec3_mul<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator/=(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec3_div<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator/=(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec3_div<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator%=(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec3_mod<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator%=(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec3_mod<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator+(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_add<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator+(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_add<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator-(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_sub<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator-(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_sub<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator*(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_mul<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator*(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_mul<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator/(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_div<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator/(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_div<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator%(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_mod<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator%(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_mod<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Bitwise operators
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator&=(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec3_and<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator&=(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec3_and<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator|=(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec3_or<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator|=(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec3_or<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator^=(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec3_xor<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator^=(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec3_xor<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator<<=(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec3_left_shift<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator<<=(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec3_left_shift<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator>>=(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec3_right_shift<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator>>=(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec3_right_shift<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator&(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_and<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator&(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_and<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator|(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_or<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator|(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_or<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator^(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_xor<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator^(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_xor<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator<<(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_left_shift<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator<<(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_left_shift<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator>>(TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_right_shift<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator>>(TIntVector3<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_right_shift<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S> operator~(TIntVector3<T, S>& v1)
|
||||
{
|
||||
TIntVector3<T, S> r;
|
||||
Detail::compute_ivec3_bnot<T, S>::map(r, v1);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Comparision
|
||||
|
||||
template<IntType T, bool S>
|
||||
bool operator==(const TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
return Detail::compute_ivec3_eq<T, S>::map(v1, v2);
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
bool operator!=(const TIntVector3<T, S>& v1, const TIntVector3<T, S>& v2)
|
||||
{
|
||||
return Detail::compute_ivec3_ieq<T, S>::map(v1, v2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Inc- / Decrement
|
||||
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator++(TIntVector3<T, S>& v1)
|
||||
{
|
||||
Detail::compute_ivec3_inc<T, S>::map(v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator--(TIntVector3<T, S>& v1)
|
||||
{
|
||||
Detail::compute_ivec3_inc<T, S>::map(v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator++(TIntVector3<T, S>& v1, int)
|
||||
{
|
||||
return ++v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector3<T, S>& operator--(TIntVector3<T, S>& v1, int)
|
||||
{
|
||||
return --v1;
|
||||
}
|
||||
}
|
643
Engine/Source/Runtime/Core/Math/IntVector4.hpp
Normal file
643
Engine/Source/Runtime/Core/Math/IntVector4.hpp
Normal file
@@ -0,0 +1,643 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/MathCommon.hpp"
|
||||
#include "Core/public/Math/MathFwd.h"
|
||||
|
||||
#include "Core/public/Math/SIMD/Storage.h"
|
||||
|
||||
#include "Core/public/Math/IntVector2.hpp"
|
||||
|
||||
#ifndef P_DEBUG
|
||||
#pragma warning(disable : 4244)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef INTVECTOR4_H
|
||||
#define INTVECTOR4_H
|
||||
|
||||
namespace Phanes::Core::Math {
|
||||
|
||||
/**
|
||||
* A 4D Vector with components x, y, z and w with integer precision.
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
struct TIntVector4 {
|
||||
|
||||
public:
|
||||
|
||||
union
|
||||
{
|
||||
|
||||
struct
|
||||
{
|
||||
|
||||
/** X component of Vector
|
||||
*
|
||||
* @ref [FIELD]components
|
||||
*
|
||||
* @note x does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
|
||||
*/
|
||||
T x;
|
||||
|
||||
/** Y component of Vector
|
||||
*
|
||||
* @ref [FIELD]components
|
||||
*
|
||||
* @note y does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
|
||||
*/
|
||||
T y;
|
||||
|
||||
/** Z component of Vector
|
||||
*
|
||||
* @ref [FIELD]components
|
||||
*
|
||||
* @note z does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
|
||||
*/
|
||||
T z;
|
||||
|
||||
/** W component of Vector
|
||||
*
|
||||
* @ref [FIELD]components
|
||||
*
|
||||
* @note w does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
|
||||
*/
|
||||
T w;
|
||||
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
typename SIMD::Storage<4, T, SIMD::use_simd<T, 4, A>::value>::type comp;
|
||||
typename SIMD::Storage<4, T, SIMD::use_simd<T, 4, A>::value>::type data;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor without initialization
|
||||
*/
|
||||
|
||||
TIntVector4() = default;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Copy constructor.
|
||||
/// </summary>
|
||||
/// <param name="v"></param>
|
||||
TIntVector4(const TIntVector4<T, A>& v);
|
||||
|
||||
/// <summary>
|
||||
/// Construct vector from x, y, z, w components.
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <param name="z"></param>
|
||||
/// <param name="w"></param>
|
||||
TIntVector4(const T x, const T y, const T z, const T w);
|
||||
|
||||
/// <summary>
|
||||
/// Broadcast s into all components.
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
TIntVector4(T s);
|
||||
|
||||
/**
|
||||
* Construct Vector from two component array.
|
||||
*
|
||||
* @param comp Array of components
|
||||
*/
|
||||
|
||||
TIntVector4(const T *comp);
|
||||
|
||||
/// <summary>
|
||||
/// Construct vector from two 2d vectors
|
||||
/// <param>
|
||||
/// x,y = v1.x, v2.y
|
||||
/// </param>
|
||||
/// z,w = v2.x, v2.y
|
||||
/// </summary>
|
||||
/// <param name="v1"></param>
|
||||
/// <param name="v2"></param>
|
||||
TIntVector4(const TIntVector2<T, A>& v1, const TIntVector2<T, A>& v2);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Addition operation on same TIntVector4<T, A> (this) by a scalar value.
|
||||
*
|
||||
* @param(v1) Vector to add to
|
||||
* @param(s) Scalar
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector4<T, A>& operator+= (TIntVector4<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Addition operation on same TIntVector4<T, A> (this) by a another TIntVector4<T, A>.
|
||||
*
|
||||
* @param(v1) Vector to add to
|
||||
* @param(v2) Vector to add
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector4<T, A>& operator+= (TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
/**
|
||||
* Substraction operation on same TIntVector4<T, A> (this) by a floating point.
|
||||
*
|
||||
* @param(v1) Vector to substract from
|
||||
* @param(v2) Floating point to substract
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector4<T, A>& operator-= (TIntVector4<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Substraction operation on same TIntVector4<T, A> (this) by a another TIntVector4<T, A>.
|
||||
*
|
||||
* @param(v1) Vector to substract from
|
||||
* @param(v2) Vector to substract
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector4<T, A>& operator-= (TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
|
||||
/**
|
||||
* Multiplication of TIntVector4<T, A> (this) with a floating point.
|
||||
*
|
||||
* @param(v1) Vector to multiply with
|
||||
* @param(s Floating point to multiply with
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector4<T, A>& operator*= (TIntVector4<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Devision of Vector
|
||||
*
|
||||
* @param(v1) Vector to divide with
|
||||
* @param(s) Scalar to divide with
|
||||
*
|
||||
* @note Result is rounded (obviously)
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector4<T, A>& operator/= (TIntVector4<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Stores the remainder of division by a scalar.
|
||||
*
|
||||
* @param(v1) Vector to divide with
|
||||
* @param(s) Scalar to divide with
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector4<T, A>& operator%= (TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector4<T, A>& operator%= (TIntVector4<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A>& operator&= (TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A>& operator&= (TIntVector4<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A>& operator|= (TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A>& operator|= (TIntVector4<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A> operator^= (TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A>& operator^= (TIntVector4<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A>& operator<<= (TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A>& operator<<= (TIntVector4<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A>& operator>>= (TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A>& operator>>= (TIntVector4<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Scale of Vector by floating point. (> Creates a new TIntVector4<T, A>)
|
||||
*
|
||||
* @param(v1) Vector to multiply with
|
||||
* @param(s Floating point to multiply with
|
||||
*
|
||||
* @return Result Vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector4<T, A> operator* (const TIntVector4<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Division of Vector by floating point. (> Creates another TIntVector4<T, A>)
|
||||
*
|
||||
* @see [FUNC]DivideFloat
|
||||
*
|
||||
* @param(v1) Vector to multiply with
|
||||
* @param(s Floating point to divide with
|
||||
*
|
||||
* @return Result Vector
|
||||
* @note Deleted, because the returntype might not implicitly be obvious, when using in code or reading.
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector4<T, A> operator/ (const TIntVector4<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Scale of Vector by floating point. (> Creates a new TIntVector4<T, A>)
|
||||
*
|
||||
* @param(v1) Vector to multiply with
|
||||
* @param(s Floating point to multiply with
|
||||
*
|
||||
* @return Result Vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
FORCEINLINE TIntVector4<T, A> operator* (T s, const TIntVector4<T, A>& v1) { return v1 * s; };
|
||||
|
||||
/**
|
||||
* Division of Vector by floating point. (> For convenience not arithmethicaly correct. Works like overloaded counterpart.)
|
||||
*
|
||||
* @see [FUNC]DivideFloat
|
||||
*
|
||||
* @param(v1) Vector to multiply with
|
||||
* @param(s Floating point to divide with
|
||||
*
|
||||
* @return Result Vector
|
||||
*
|
||||
* @note Deleted, because the returntype might not implicitly be obvious, when using in code or reading.
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
FORCEINLINE TIntVector4<T, A> operator/ (T s, const TIntVector4<T, A>& v1) { return v1 / s; };
|
||||
|
||||
/**
|
||||
* Dot product between two Vectors.
|
||||
*
|
||||
* @see [FUNC]DotP
|
||||
*
|
||||
* @param(v1) Vector one
|
||||
* @param(v2) Vector two
|
||||
*
|
||||
* @result Dot product
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
T operator* (const TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
/**
|
||||
* Componentwise addition of Vector with floating point.
|
||||
*
|
||||
* @param(v1) Vector to add to
|
||||
* @param(s Floating point to add
|
||||
*
|
||||
* @return Result Vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector4<T, A> operator+ (const TIntVector4<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Componentwise addition of Vector with floating point.
|
||||
*
|
||||
* @param(v1) Vector to add to
|
||||
* @param(s Floating point to add
|
||||
*
|
||||
* @return Result Vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector4<T, A> operator+ (const TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
/**
|
||||
* Componentwise substraction of Vector with floating point.
|
||||
*
|
||||
* @param(v1) Vector to substract from
|
||||
* @param(s Floating point to substract
|
||||
*
|
||||
* @return Result Vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector4<T, A> operator- (const TIntVector4<T, A>& v1, T s);
|
||||
|
||||
/**
|
||||
* Componentwise substraction of Vector with Vector.
|
||||
*
|
||||
* @param(v1) Vector to substract from
|
||||
* @param(s Floating point to substract
|
||||
*
|
||||
* @return Result Vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
TIntVector4<T, A> operator- (const TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Scale of Vector by floating point. (> Creates a new TIntVector4<T, A>)
|
||||
*
|
||||
* @param(v1) Vector to multiply with
|
||||
* @param(s Floating point to multiply with
|
||||
*
|
||||
* @return Result Vector
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
FORCEINLINE TIntVector4<T, A> operator% (const TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
FORCEINLINE TIntVector4<T, A> operator% (const TIntVector4<T, A>& v1, T s);
|
||||
|
||||
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A> operator& (TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A> operator& (TIntVector4<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A> operator| (TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A> operator| (TIntVector4<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A> operator^ (TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A> operator^ (TIntVector4<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A> operator<< (TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A> operator<< (TIntVector4<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A> operator>> (TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A> operator>> (TIntVector4<T, A>& v1, T s);
|
||||
|
||||
template<IntType T, bool A>
|
||||
inline TIntVector4<T, A> operator~ (TIntVector4<T, A>& v1);
|
||||
|
||||
|
||||
/**
|
||||
* Compare Vector for equality.
|
||||
*
|
||||
* @see [FUNC]Equals
|
||||
*
|
||||
* @param(v1) Vector to negate
|
||||
*
|
||||
* @return true if equal, false if inequal
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
bool operator== (const TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
|
||||
/**
|
||||
* Compare Vector for inequality.
|
||||
*
|
||||
* @see [FUNC]Equals
|
||||
*
|
||||
* @param(v1) Vector to negate
|
||||
*
|
||||
* @return true if inequal, false if equal
|
||||
*/
|
||||
|
||||
template<IntType T, bool A>
|
||||
bool operator!= (const TIntVector4<T, A>& v1, const TIntVector4<T, A>& v2);
|
||||
|
||||
|
||||
|
||||
|
||||
// ========================= //
|
||||
// TIntVector4 functions //
|
||||
// ========================= //
|
||||
|
||||
|
||||
template<IntType T>
|
||||
TIntVector4<T, false>& Set(TIntVector4<T, false>& v1, TIntVector4<T, false>& v2)
|
||||
{
|
||||
v1.x = v2.x;
|
||||
v1.y = v2.y;
|
||||
v1.z = v2.z;
|
||||
v1.w = v2.w;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the dot product between two vectors.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Dot product between vectors.</returns>
|
||||
template<IntType T>
|
||||
T DotP(const TIntVector4<T, false>& v1, const TIntVector4<T, false>& v2)
|
||||
{
|
||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets componentwise max of both vectors.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam> * @note z does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Vector with componentwise max of both vectors.</returns>
|
||||
template<IntType T>
|
||||
TIntVector4<T, false> Max(const TIntVector4<T, false>& v1, const TIntVector4<T, false>& v2)
|
||||
{
|
||||
return TIntVector4<T, false>(
|
||||
(v1.x > v2.x) ? v1.x : v2.x,
|
||||
(v1.y > v2.y) ? v1.y : v2.y,
|
||||
(v1.z > v2.z) ? v1.z : v2.z,
|
||||
(v1.w > v2.w) ? v1.w : v2.w
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets componentwise max of both vectors.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<IntType T>
|
||||
TIntVector4<T, false>& MaxV(TIntVector4<T, false>& v1, const TIntVector4<T, false>& v2)
|
||||
{
|
||||
v1.x = (v1.x > v2.x) ? v1.x : v2.x;
|
||||
v1.y = (v1.y > v2.y) ? v1.y : v2.y;
|
||||
v1.z = (v1.z > v2.z) ? v1.z : v2.z;
|
||||
v1.w = (v1.w > v2.w) ? v1.w : v2.w;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets componentwise min of both vectors.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Vector with componentwise max of both vectors.</returns>
|
||||
template<IntType T>
|
||||
TIntVector4<T, false> Min(const TIntVector4<T, false>& v1, const TIntVector4<T, false>& v2)
|
||||
{
|
||||
return TIntVector4<T, false>(
|
||||
(v1.x < v2.x) ? v1.x : v2.x,
|
||||
(v1.y < v2.y) ? v1.y : v2.y,
|
||||
(v1.z < v2.z) ? v1.z : v2.z,
|
||||
(v1.w < v2.w) ? v1.w : v2.w
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets componentwise min of both vectors.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<IntType T>
|
||||
TIntVector4<T, false>& MinV(TIntVector4<T, false>& v1, const TIntVector4<T, false>& v2)
|
||||
{
|
||||
v1.x = (v1.x < v2.x) ? v1.x : v2.x;
|
||||
v1.y = (v1.y < v2.y) ? v1.y : v2.y;
|
||||
v1.z = (v1.z < v2.z) ? v1.z : v2.z;
|
||||
v1.w = (v1.w < v2.w) ? v1.w : v2.w;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inverses vector.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>Inverted vector</returns>
|
||||
template<IntType T>
|
||||
TIntVector4<T, false> Negate(const TIntVector4<T, false>& v1)
|
||||
{
|
||||
return TIntVector4<T, false>(
|
||||
-v1.x,
|
||||
-v1.y,
|
||||
-v1.z,
|
||||
-v1.w
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inverses vector.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<IntType T>
|
||||
TIntVector4<T, false>& NegateV(TIntVector4<T, false>& v1)
|
||||
{
|
||||
v1.x = -v1.x;
|
||||
v1.y = -v1.y;
|
||||
v1.z = -v1.z;
|
||||
v1.w = -v1.w;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get signs of components.
|
||||
/// <para>
|
||||
/// + -> +1
|
||||
/// </para>
|
||||
/// x -> -1
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <returns>Vector with signs of components.</returns>
|
||||
template<IntType T>
|
||||
TIntVector4<T, false> SignVector(TIntVector4<T, false>& v1)
|
||||
{
|
||||
return TIntVector4<T, false>(
|
||||
(v1.x > 0) ? 1 : -1,
|
||||
(v1.y > 0) ? 1 : -1,
|
||||
(v1.z > 0) ? 1 : -1,
|
||||
(v1.w > 0) ? 1 : -1
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get signs of components.
|
||||
/// <param>
|
||||
/// + -> +1
|
||||
/// </param>
|
||||
/// x -> -1
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <returns></returns>
|
||||
template<IntType T>
|
||||
TIntVector4<T, false>& SignVectorV(TIntVector4<T, false>& v1)
|
||||
{
|
||||
v1.x = (v1.x > 0) ? 1 : -1;
|
||||
v1.y = (v1.y > 0) ? 1 : -1;
|
||||
v1.z = (v1.z > 0) ? 1 : -1;
|
||||
v1.w = (v1.w > 0) ? 1 : -1;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if two vectors are perpendicular.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <param name="v1"></param>
|
||||
/// <param name="v2"></param>
|
||||
/// <returns>True if perpendicular.</returns>
|
||||
template<IntType T>
|
||||
inline bool IsPerpendicular(const TIntVector4<T, false>& v1, const TIntVector4<T, false>& v2)
|
||||
{
|
||||
return (abs(DotP(v1, v2)) == 0);
|
||||
}
|
||||
|
||||
} // phanes::core::math::coretypes
|
||||
|
||||
|
||||
#endif // !INTVECTOR3_H
|
||||
|
||||
|
||||
#include "Core/public/Math/IntVector4.inl"
|
407
Engine/Source/Runtime/Core/Math/IntVector4.inl
Normal file
407
Engine/Source/Runtime/Core/Math/IntVector4.inl
Normal file
@@ -0,0 +1,407 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/Detail/IntVector4Decl.inl"
|
||||
#include "Core/public/Math/SIMD/SIMDIntrinsics.h"
|
||||
|
||||
#include "Core/public/Math/SIMD/PhanesSIMDTypes.h"
|
||||
|
||||
namespace Phanes::Core::Math
|
||||
{
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>::TIntVector4(const TIntVector4<T, S>& v)
|
||||
{
|
||||
Detail::construct_ivec4<T, S>::map(*this, v);
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>::TIntVector4(const T _x, const T _y, const T _z, const T _w)
|
||||
{
|
||||
Detail::construct_ivec4<T, S>::map(*this, _x, _y, _z, _w);
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>::TIntVector4(const T s)
|
||||
{
|
||||
Detail::construct_ivec4<T, S>::map(*this, s);
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>::TIntVector4(const T* comp)
|
||||
{
|
||||
Detail::construct_ivec4<T, S>::map(*this, comp);
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>::TIntVector4(const TIntVector2<T, S>& v1, const TIntVector2<T, S>& v2)
|
||||
{
|
||||
Detail::construct_ivec4<T, S>::map(*this, v1, v2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator+=(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec4_add<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator+=(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec4_add<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator-=(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec4_sub<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator-=(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec4_sub<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator*=(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec4_mul<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator*=(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec4_mul<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator/=(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec4_div<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator/=(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec4_div<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator%=(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec4_mod<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator%=(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec4_mod<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator+(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_add<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator+(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_add<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator-(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_sub<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator-(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_sub<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator*(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_mul<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator*(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_mul<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator/(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_div<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator/(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_div<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator%(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_mod<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator%(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_mod<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Bitwise operators
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator&=(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec4_and<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator&=(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec4_and<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator|=(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec4_or<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator|=(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec4_or<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator^=(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec4_xor<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator^=(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec4_xor<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator<<=(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec4_left_shift<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator<<=(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec4_left_shift<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator>>=(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_ivec4_right_shift<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator>>=(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_ivec4_right_shift<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator&(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_and<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator&(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_and<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator|(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_or<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator|(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_or<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator^(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_xor<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator^(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_xor<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator<<(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_left_shift<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator<<(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_left_shift<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator>>(TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_right_shift<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator>>(TIntVector4<T, S>& v1, T s)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_right_shift<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S> operator~(TIntVector4<T, S>& v1)
|
||||
{
|
||||
TIntVector4<T, S> r;
|
||||
Detail::compute_ivec4_bnot<T, S>::map(r, v1);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Comparision
|
||||
|
||||
template<IntType T, bool S>
|
||||
bool operator==(const TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
return Detail::compute_ivec4_eq<T, S>::map(v1, v2);
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
bool operator!=(const TIntVector4<T, S>& v1, const TIntVector4<T, S>& v2)
|
||||
{
|
||||
return Detail::compute_ivec4_ieq<T, S>::map(v1, v2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Inc- / Decrement
|
||||
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator++(TIntVector4<T, S>& v1)
|
||||
{
|
||||
Detail::compute_ivec4_inc<T, S>::map(v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator--(TIntVector4<T, S>& v1)
|
||||
{
|
||||
Detail::compute_ivec4_inc<T, S>::map(v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator++(TIntVector4<T, S>& v1, int)
|
||||
{
|
||||
return ++v1;
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
TIntVector4<T, S>& operator--(TIntVector4<T, S>& v1, int)
|
||||
{
|
||||
return --v1;
|
||||
}
|
||||
}
|
72
Engine/Source/Runtime/Core/Math/Line.hpp
Normal file
72
Engine/Source/Runtime/Core/Math/Line.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
#include "Core/public/Math/MathFwd.h"
|
||||
|
||||
#include "Core/public/Math/Vector3.hpp"
|
||||
|
||||
#include <any>
|
||||
|
||||
|
||||
namespace Phanes::Core::Math
|
||||
{
|
||||
|
||||
// Line with direction and moment
|
||||
|
||||
template<RealType T>
|
||||
struct TLine
|
||||
{
|
||||
public:
|
||||
using Real = T;
|
||||
|
||||
/** Direction of line */
|
||||
|
||||
TVector3<Real, false> direction;
|
||||
|
||||
/** Base point of line */
|
||||
|
||||
TVector3<Real, false> base;
|
||||
|
||||
public:
|
||||
|
||||
/** Construct line from base and direction
|
||||
*
|
||||
* @param(direction) Direction of line
|
||||
* @param(p) Base of line
|
||||
*/
|
||||
|
||||
TLine(const TVector3<T, false>& direction, const TVector3<T, false>& p) : direction(direction), base(p) {};
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Normalizes the direction of the line
|
||||
*
|
||||
* @param(l1) Line
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
TLine<T>& NormalizeV(TLine<T>& l1)
|
||||
{
|
||||
std::any
|
||||
|
||||
NormalizeV(l1.direction);
|
||||
return l1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Normalizes the direction of the line
|
||||
*
|
||||
* @param(l1) Line
|
||||
*
|
||||
* @return Line with normalized direction.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
TLine<T> NormalizeV(const TLine<T>& l1)
|
||||
{
|
||||
return TLine<T>(Normalize(l1.direction), l1.base);
|
||||
}
|
||||
}
|
29
Engine/Source/Runtime/Core/Math/MathAbstractTypes.h
Normal file
29
Engine/Source/Runtime/Core/Math/MathAbstractTypes.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef ABSTRACT_TYPES_H
|
||||
#define ABSTRACT_TYPES_H
|
||||
|
||||
namespace Phanes::Core::Math::Internal {
|
||||
|
||||
template <typename T, unsigned int D = 3>
|
||||
struct AVector {
|
||||
public:
|
||||
|
||||
/**
|
||||
* List of n components of the vector
|
||||
*/
|
||||
|
||||
T comp[D];
|
||||
|
||||
};
|
||||
|
||||
template <typename T, unsigned int n = 3, unsigned int m = 3>
|
||||
struct AMatrix {
|
||||
public:
|
||||
T fields[n][m];
|
||||
|
||||
};
|
||||
|
||||
}; // Phanes::Core::Math::abstract::coretypes
|
||||
|
||||
#endif // !ABSTRACT_TYPES_H
|
161
Engine/Source/Runtime/Core/Math/MathCommon.hpp
Normal file
161
Engine/Source/Runtime/Core/Math/MathCommon.hpp
Normal file
@@ -0,0 +1,161 @@
|
||||
#pragma once
|
||||
|
||||
#define P_FLT_INAC_LARGE 0.0001f // large float inaccuracy (1*10^-4);
|
||||
#define P_FLT_INAC 0.00001f // float inaccuracy (1*10^-5);
|
||||
#define P_FLT_INAC_SMALL 0.000001f // small float inaccuracy (1*10^-6);
|
||||
|
||||
#define P_180_PI 57.29577951308232 // (double) 180<38>/pi;
|
||||
#define P_180_PI_FLT 57.29577951308232f // (float) 180<38>/pi;
|
||||
|
||||
#define P_PI_180 0.0174532925199432 // double pi/180<38>
|
||||
#define P_PI_180_FLT 0.0174532925199432f // (float) pi/180<38>
|
||||
|
||||
#define P_PI 3.1415926535897932 // PI
|
||||
#define P_PI_FLT 3.1415926535897932f // PI
|
||||
|
||||
|
||||
#ifndef MATH_COMMON_H
|
||||
#define MATH_COMMON_H
|
||||
|
||||
namespace Phanes::Core::Math {
|
||||
|
||||
/**
|
||||
* Clamps a value between minimum and maximum
|
||||
*
|
||||
* @param value Value to clamp
|
||||
* @param low Minimum
|
||||
* @param high Maximum
|
||||
*
|
||||
* @return Minimum, if value is to small / Maximum, if value is to large / value, if value is in range.
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Clamp(T value, T low, T high)
|
||||
{
|
||||
if (value < low) value = low;
|
||||
if (value > high) value = high;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the larger of two values
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
*
|
||||
* @return Larger value
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
constexpr T Max(T x, T y)
|
||||
{
|
||||
return (x > y) ? x : y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the smaller of two values
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
*
|
||||
* @return Smaller value
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
constexpr T Min(T x, T y)
|
||||
{
|
||||
return (x < y) ? x : y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swaps the values of two variables
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
inline void Swap(T& x, T& y)
|
||||
{
|
||||
float z = x;
|
||||
x = y;
|
||||
y = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test two numbers for equality
|
||||
*
|
||||
* @param(x)
|
||||
* @param(y)
|
||||
* @param(threshold) Allowed inaccuracy
|
||||
*
|
||||
* @return True, if equal, false if not
|
||||
*/
|
||||
template<typename T>
|
||||
bool Equals(T x, T y, T threshold = P_FLT_INAC)
|
||||
{
|
||||
return (abs(x - y) < threshold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the reciprocal of the square root of n using the algorithm of A Quake III
|
||||
*
|
||||
* @param n Number to calculate
|
||||
*
|
||||
* @return Inverse square root of n
|
||||
*
|
||||
* @note a simple 1.0f / sqrtf(x) is faster than this algorithm. Use for research purpose only.
|
||||
*/
|
||||
|
||||
|
||||
template<typename T>
|
||||
float FastInvSqrt(T n)
|
||||
{
|
||||
int i = *(int*)&n;
|
||||
float x2 = n * 0.5f;
|
||||
|
||||
i = 0x5f3759df - (i >> 1);
|
||||
n = *(float*)&i;
|
||||
n = n * (1.5f - (x2 * n * n));
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
FORCEINLINE T Abs(T s)
|
||||
{
|
||||
return abs(s);
|
||||
}
|
||||
|
||||
template<>
|
||||
FORCEINLINE float Abs<float>(float s)
|
||||
{
|
||||
return (float)fabs(s);
|
||||
};
|
||||
|
||||
template<>
|
||||
FORCEINLINE long long Abs<long long>(long long s)
|
||||
{
|
||||
return llabs(s);
|
||||
};
|
||||
|
||||
template<>
|
||||
FORCEINLINE long Abs<long>(long s)
|
||||
{
|
||||
return labs(s);
|
||||
};
|
||||
|
||||
template<>
|
||||
FORCEINLINE double Abs<double>(double s)
|
||||
{
|
||||
return fabsl(s);
|
||||
};
|
||||
|
||||
|
||||
} // phanes
|
||||
|
||||
#endif // !MATH_COMMON_H
|
201
Engine/Source/Runtime/Core/Math/MathFwd.h
Normal file
201
Engine/Source/Runtime/Core/Math/MathFwd.h
Normal file
@@ -0,0 +1,201 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef P_BUILD_LIB
|
||||
#include "PhanesEnginePCH.h"
|
||||
#else
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
#ifndef MATH_FWD_H
|
||||
#define MATH_FWD_H
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
#include "Core/public/Math/SIMD/PhanesSIMDTypes.h"
|
||||
|
||||
/**
|
||||
* Includes forward declarations, as well as certain useful typedefs.
|
||||
*
|
||||
* @ref OSAL/PlatformTypes.h
|
||||
*/
|
||||
|
||||
|
||||
namespace Phanes::Core::Math {
|
||||
|
||||
/**
|
||||
* Template forward declarations.
|
||||
*/
|
||||
|
||||
template<RealType T> struct TColor;
|
||||
template<RealType T> struct TLinearColor;
|
||||
template<RealType T> struct TLine;
|
||||
template<RealType T> struct TQuaternion;
|
||||
template<RealType T> struct TTransform;
|
||||
template<RealType T> struct TPoint2;
|
||||
template<RealType T> struct TPoint3;
|
||||
template<RealType T> struct TPoint4;
|
||||
template<IntType T> struct TIntPoint2;
|
||||
template<IntType T> struct TIntPoint3;
|
||||
template<IntType T> struct TIntPoint4;
|
||||
template<RealType T> struct TMatrix2;
|
||||
template<RealType T, bool S> struct TMatrix3;
|
||||
template<RealType T, bool S> struct TMatrix4;
|
||||
template<RealType T, bool S> struct TVector2;
|
||||
template<RealType T, bool S> struct TVector3;
|
||||
template<RealType T, bool S> struct TVector4;
|
||||
template<IntType T, bool S> struct TIntVector2;
|
||||
template<IntType T, bool S> struct TIntVector3;
|
||||
template<IntType T, bool S> struct TIntVector4;
|
||||
template<RealType T, bool S> struct TPlane;
|
||||
template<RealType T, bool S> struct TRay;
|
||||
|
||||
/**
|
||||
* Specific instantiation of forward declarations.
|
||||
*/
|
||||
|
||||
// TPoint2
|
||||
|
||||
typedef TPoint2<float> Point2;
|
||||
typedef TPoint2<float> Point2f;
|
||||
typedef TPoint2<double> Point2d;
|
||||
|
||||
// TPoint3
|
||||
|
||||
typedef TPoint3<float> Point3;
|
||||
typedef TPoint3<float> Point3f;
|
||||
typedef TPoint3<double> Point3d;
|
||||
|
||||
// TPoint4
|
||||
|
||||
typedef TPoint4<float> Point4;
|
||||
typedef TPoint4<float> Point4f;
|
||||
typedef TPoint4<double> Point4d;
|
||||
|
||||
|
||||
// TIntPoint2
|
||||
|
||||
typedef TIntPoint2<int> IntPoint2;
|
||||
typedef TIntPoint2<int> IntPoint2i;
|
||||
typedef TIntPoint2<long> IntPoint2l;
|
||||
|
||||
// TIntPoint3
|
||||
|
||||
typedef TIntPoint3<int> IntPoint3;
|
||||
typedef TIntPoint3<int> IntPoint3i;
|
||||
typedef TIntPoint3<long> IntPoint3l;
|
||||
|
||||
// TIntPoint4
|
||||
|
||||
typedef TIntPoint4<int> IntPoint4;
|
||||
typedef TIntPoint4<int> IntPoint4i;
|
||||
typedef TIntPoint4<long> IntPoint4l;
|
||||
|
||||
// IntVetor2
|
||||
|
||||
typedef TIntVector2<int, false> IntVector2;
|
||||
typedef TIntVector2<int, false> Vector2i;
|
||||
typedef TIntVector2<long, false> LongVector2;
|
||||
typedef TIntVector2<long, false> Vector2l;
|
||||
|
||||
// IntVetor3
|
||||
|
||||
typedef TIntVector3<int, false> IntVector3;
|
||||
typedef TIntVector3<int, false> Vector3i;
|
||||
typedef TIntVector3<long, false> LongVector3;
|
||||
typedef TIntVector3<long, false> Vector3l;
|
||||
|
||||
|
||||
// IntVetor4
|
||||
|
||||
typedef TIntVector4<int, false> IntVector4;
|
||||
typedef TIntVector4<int, false> Vector4i;
|
||||
typedef TIntVector4<long, false> LongVector4;
|
||||
typedef TIntVector4<long, false> Vector4l;
|
||||
|
||||
// Vector2
|
||||
|
||||
typedef TVector2<float, false> Vector2;
|
||||
typedef TVector2<float, false> Vector2f;
|
||||
typedef TVector2<double, false> Vector2d;
|
||||
|
||||
typedef TVector2<double, SIMD::use_simd<double, 2, true>::value> Vector2Regf64;
|
||||
typedef TVector2<double, SIMD::use_simd<double, 2, true>::value> Vector2Reg;
|
||||
typedef TVector2<double, SIMD::use_simd<double, 2, true>::value> Vector2Regd;
|
||||
|
||||
|
||||
// Vector3
|
||||
|
||||
typedef TVector3<float, false> Vector3;
|
||||
typedef TVector3<float, false> Vector3f;
|
||||
typedef TVector3<double, false> Vector3d;
|
||||
|
||||
typedef TVector3<float, SIMD::use_simd<float, 3, true>::value> Vector3Reg;
|
||||
typedef TVector3<float, SIMD::use_simd<float, 3, true>::value> Vector3Regf32;
|
||||
typedef TVector3<double, SIMD::use_simd<double, 3, true>::value> Vector3Regd;
|
||||
typedef TVector3<double, SIMD::use_simd<double, 3, true>::value> Vector3Regf64;
|
||||
|
||||
|
||||
// Vector4
|
||||
|
||||
typedef TVector4<float, false> Vector4;
|
||||
typedef TVector4<float, false> Vector4f;
|
||||
typedef TVector4<double, false> Vector4d;
|
||||
|
||||
typedef TVector4<float, SIMD::use_simd<float, 4, true>::value> Vector4Reg;
|
||||
typedef TVector4<float, SIMD::use_simd<float, 4, true>::value> Vector4Regf32;
|
||||
typedef TVector4<double, SIMD::use_simd<double, 4, true>::value> Vector4Regd;
|
||||
typedef TVector4<double, SIMD::use_simd<double, 4, true>::value> Vector4Regf64;
|
||||
|
||||
// Matrix2
|
||||
|
||||
typedef TMatrix2<float> Matrix2;
|
||||
typedef TMatrix2<float> Matrix2f;
|
||||
typedef TMatrix2<double> Matrix2d;
|
||||
|
||||
// Matrix3
|
||||
|
||||
typedef TMatrix3<float, false> Matrix3;
|
||||
typedef TMatrix3<float, false> Matrix3f;
|
||||
typedef TMatrix3<double, false> Matrix3d;
|
||||
|
||||
typedef TMatrix3<float, SIMD::use_simd<float, 3, true>::value> Matrix3Reg;
|
||||
typedef TMatrix3<float, SIMD::use_simd<float, 3, true>::value> Matrix3Regf;
|
||||
typedef TMatrix3<double, SIMD::use_simd<double, 3, true>::value> Matrix3Regd;
|
||||
typedef TMatrix3<double, SIMD::use_simd<double, 3, true>::value> Matrix3Regf64;
|
||||
|
||||
// Matrix4
|
||||
|
||||
typedef TMatrix4<float, false> Matrix4;
|
||||
typedef TMatrix4<float, false> Matrix4f;
|
||||
typedef TMatrix4<double, false> Matrix4d;
|
||||
|
||||
typedef TMatrix3<float, SIMD::use_simd<float, 4, true>::value> Matrix4Reg;
|
||||
typedef TMatrix3<float, SIMD::use_simd<float, 4, true>::value> Matrix4Regf;
|
||||
typedef TMatrix3<double, SIMD::use_simd<double, 4, true>::value> Matrix4Regd;
|
||||
typedef TMatrix3<double, SIMD::use_simd<double, 4, true>::value> Matrix4Regf64;
|
||||
|
||||
|
||||
|
||||
// TPlane
|
||||
|
||||
typedef TPlane<float, false> Plane;
|
||||
typedef TPlane<float, false> Planef;
|
||||
typedef TPlane<double, false> Planed;
|
||||
|
||||
typedef TPlane<float, SIMD::use_simd<float, 4, true>::value> PlaneReg;
|
||||
typedef TPlane<float, SIMD::use_simd<double, 4, true>::value> PlaneRegd;
|
||||
|
||||
|
||||
} // Phanes::Core::Math::coretypes
|
||||
|
||||
namespace Phanes::Core::Math::Internal
|
||||
{
|
||||
|
||||
// Internal types
|
||||
|
||||
template <typename T, unsigned int D> struct AVector;
|
||||
|
||||
template <typename T, unsigned int n, unsigned int> struct AMatrix;
|
||||
}
|
||||
|
||||
|
||||
#endif // !MATH_FWD_H
|
27
Engine/Source/Runtime/Core/Math/MathPCH.h
Normal file
27
Engine/Source/Runtime/Core/Math/MathPCH.h
Normal file
@@ -0,0 +1,27 @@
|
||||
// Header file containing all files to be compiled to use core math.
|
||||
// Should be included in PCH file of project to use.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Point.hpp"
|
||||
#include "Core/public/Math/Plane.hpp"
|
||||
#include "Core/public/Math/Line.hpp"
|
||||
#include "Core/public/Math/Ray.hpp"
|
||||
|
||||
|
||||
#include "Core/public/Math/Vector2.hpp"
|
||||
#include "Core/public/Math/Vector3.hpp"
|
||||
#include "Core/public/Math/Vector4.hpp"
|
||||
|
||||
#include "Core/public/Math/IntPoint.hpp"
|
||||
#include "Core/public/Math/IntVector2.hpp"
|
||||
#include "Core/public/Math/IntVector3.hpp"
|
||||
#include "Core/public/Math/IntVector4.hpp"
|
||||
|
||||
#include "Core/public/Math/Matrix2.hpp"
|
||||
#include "Core/public/Math/Matrix3.hpp"
|
||||
#include "Core/public/Math/Matrix4.hpp"
|
||||
|
||||
#include "Core/public/Math/MathCommon.hpp"
|
||||
#include "Core/public/Math/MathTypeConversion.hpp"
|
||||
#include "Core/public/Math/MathUnitConversion.hpp"
|
128
Engine/Source/Runtime/Core/Math/MathTypeConversion.hpp
Normal file
128
Engine/Source/Runtime/Core/Math/MathTypeConversion.hpp
Normal file
@@ -0,0 +1,128 @@
|
||||
#pragma once
|
||||
|
||||
// ============================================= //
|
||||
// Function to convert types into each other //
|
||||
// //
|
||||
// @ref [FILE]MathUnitConversion //
|
||||
// ============================================= //
|
||||
|
||||
#ifdef P_BUILD_LIB
|
||||
#include "PhanesEnginePCH.h"
|
||||
#else
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/MathAbstractTypes.h"
|
||||
#include "Core/public/Math/Vector2.hpp"
|
||||
#include "Core/public/Math/Vector3.hpp"
|
||||
#include "Core/public/Math/Vector4.hpp"
|
||||
#include "Core/public/Math/Matrix2.hpp"
|
||||
#include "Core/public/Math/Matrix3.hpp"
|
||||
#include "Core/public/Math/Matrix4.hpp"
|
||||
#include "Core/public/Math/IntVector2.hpp"
|
||||
#include "Core/public/Math/IntVector3.hpp"
|
||||
#include "Core/public/Math/IntVector4.hpp"
|
||||
|
||||
#ifndef MATH_TYPE_CONVERSION_H
|
||||
#define MATH_TYPE_CONVERSION_H
|
||||
|
||||
|
||||
namespace Phanes::Core::Math {
|
||||
|
||||
// =================================================== //
|
||||
// std::to_string wrapper //
|
||||
// //
|
||||
// This is, to make using ToString more general //
|
||||
// and allow usage of one function instead of two, //
|
||||
// for converting a mathmatical type to a string. //
|
||||
// =================================================== //
|
||||
|
||||
FORCEINLINE std::string ToString(long long val) { return std::to_string(val); };
|
||||
|
||||
FORCEINLINE std::string ToString(double val) { return std::to_string(val); };
|
||||
|
||||
FORCEINLINE std::string ToString(float val) { return std::to_string(val); };
|
||||
|
||||
FORCEINLINE std::string ToString(int val) { return std::to_string(val); };
|
||||
|
||||
FORCEINLINE std::string ToString(long val) { return std::to_string(val); };
|
||||
|
||||
FORCEINLINE std::string ToString(long double val) { return std::to_string(val); };
|
||||
|
||||
FORCEINLINE std::string ToString(unsigned long long val) { return std::to_string(val); };
|
||||
|
||||
FORCEINLINE std::string ToString(unsigned int val) { return std::to_string(val); };
|
||||
|
||||
FORCEINLINE std::string ToString(unsigned long val) { return std::to_string(val); };
|
||||
|
||||
|
||||
// ============ //
|
||||
// ToString //
|
||||
// ============ //
|
||||
|
||||
template<RealType T, bool S>
|
||||
std::string ToString(const TVector2<T, S>& v)
|
||||
{
|
||||
return "(" + ToString(v.x) + ", " + ToString(v.y) + ")";
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
std::string ToString(const TIntVector2<T, S>& v)
|
||||
{
|
||||
return "(" + ToString(v.x) + ", " + ToString(v.y) + ")";
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
std::string ToString(const TVector3<T, S>& v)
|
||||
{
|
||||
return "(" + ToString(v.x) + ", " + ToString(v.y) + ", " + ToString(v.z) + ")";
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
std::string ToString(const TIntVector3<T, S>& v)
|
||||
{
|
||||
return "(" + ToString(v.x) + ", " + ToString(v.y) + ", " + ToString(v.z) + ")";
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
std::string ToString(const TVector4<T, S>& v)
|
||||
{
|
||||
return "(" + ToString(v.x) + ", " + ToString(v.y) + ", " + ToString(v.z) + ", " + ToString(v.w) + ")";
|
||||
}
|
||||
|
||||
template<IntType T, bool S>
|
||||
std::string ToString(const TIntVector4<T, S>& v)
|
||||
{
|
||||
return "(" + ToString(v.x) + ", " + ToString(v.y) + ", " + ToString(v.z) + ", " + ToString(v.w) + ")";
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
std::string ToString(const TMatrix2<T>& m)
|
||||
{
|
||||
return "([" + ToString(m(0, 0)) + ", " + ToString(m(0, 1)) + "], [" +
|
||||
ToString(m(1, 0)) + ", " + ToString(m(1, 1)) + "])";
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
std::string ToString(const TMatrix3<T, S>& m)
|
||||
{
|
||||
return "([" + ToString(m(0, 0)) + ", " + ToString(m(0, 1)) + ", " + ToString(m(0, 2)) + "], [" +
|
||||
ToString(m(1, 0)) + ", " + ToString(m(1, 1)) + ", " + ToString(m(1, 2)) + "], [" +
|
||||
ToString(m(2, 0)) + ", " + ToString(m(2, 1)) + ", " + ToString(m(2, 2)) + "])";
|
||||
}
|
||||
|
||||
|
||||
template<RealType T, bool S>
|
||||
std::string ToString(const TMatrix4<T, S>& m)
|
||||
{
|
||||
return "([" + ToString(m(0, 0)) + ", " + ToString(m(0, 1)) + ", " + ToString(m(0, 2)) + ", " + ToString(m(0, 3)) + "], [" +
|
||||
ToString(m(1, 0)) + ", " + ToString(m(1, 1)) + ", " + ToString(m(1, 2)) + ", " + ToString(m(1, 3)) + "], [" +
|
||||
ToString(m(2, 0)) + ", " + ToString(m(2, 1)) + ", " + ToString(m(2, 2)) + ", " + ToString(m(2, 3)) + "], [" +
|
||||
ToString(m(3, 0)) + ", " + ToString(m(3, 1)) + ", " + ToString(m(3, 2)) + ", " + ToString(m(3, 3)) + "])";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // !MATH_TYPE_CONVERSION_H
|
111
Engine/Source/Runtime/Core/Math/MathTypes.h
Normal file
111
Engine/Source/Runtime/Core/Math/MathTypes.h
Normal file
@@ -0,0 +1,111 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef P_BUILD_LIB
|
||||
# include "PhanesEnginePCH.h"
|
||||
#else
|
||||
# define NOMINMAX
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
// ============================================= //
|
||||
// Turn os specific types into global types. //
|
||||
// ============================================= //
|
||||
|
||||
|
||||
// TODO: include int128
|
||||
|
||||
namespace Phanes::Core::Types
|
||||
{
|
||||
|
||||
#ifdef P_WIN_BUILD
|
||||
|
||||
// MSVC specific types
|
||||
|
||||
typedef _FLOAT128 float128;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// Specific types size
|
||||
//
|
||||
// 8-Bit integer
|
||||
typedef int8_t int8;
|
||||
|
||||
// 16-Bit integer
|
||||
typedef int16_t int16;
|
||||
|
||||
// 32-Bit integer
|
||||
typedef int32_t int32;
|
||||
|
||||
// 64-Bit integer
|
||||
typedef int64_t int64;
|
||||
|
||||
// 8-Bit unsigned integer
|
||||
typedef uint8_t uint8;
|
||||
|
||||
// 16-Bit unsigned integer
|
||||
typedef uint16_t uint16;
|
||||
|
||||
// 32-Bit unsigned integer
|
||||
typedef uint32_t uint32;
|
||||
|
||||
// 64-Bit unsigned integer
|
||||
typedef uint64_t uint64;
|
||||
|
||||
|
||||
|
||||
// At least N bit types
|
||||
//
|
||||
// At least 8-Bit integer
|
||||
typedef int_least8_t lint8;
|
||||
|
||||
// At least 16-Bit integer
|
||||
typedef int_least16_t lint16;
|
||||
|
||||
// At least 32-Bit integer
|
||||
typedef int_least32_t lint32;
|
||||
|
||||
// At least 64-Bit integer
|
||||
typedef int_least64_t lint64;
|
||||
|
||||
// At least 8-Bit integer
|
||||
typedef uint_least8_t ulint8;
|
||||
|
||||
// At least 16-Bit integer
|
||||
typedef uint_least16_t ulint16;
|
||||
|
||||
// At least 32-Bit integer
|
||||
typedef uint_least32_t ulint32;
|
||||
|
||||
// At least 64-Bit integer
|
||||
typedef uint_least64_t ulint64;
|
||||
|
||||
|
||||
|
||||
// Fast N bit types
|
||||
//
|
||||
// Fast 8-bit integer
|
||||
typedef int_fast8_t fint8;
|
||||
|
||||
// At least 16-Bit integer
|
||||
typedef int_fast16_t fint16;
|
||||
|
||||
// At least 32-Bit integer
|
||||
typedef int_fast32_t fint32;
|
||||
|
||||
// At least 64-Bit integer
|
||||
typedef int_fast64_t fint64;
|
||||
|
||||
// At least 8-Bit integer
|
||||
typedef uint_fast8_t ufint8;
|
||||
|
||||
// At least 16-Bit integer
|
||||
typedef uint_fast16_t ufint16;
|
||||
|
||||
// At least 32-Bit integer
|
||||
typedef uint_fast32_t ufint32;
|
||||
|
||||
// At least 64-Bit integer
|
||||
typedef uint_fast64_t ufint64;
|
||||
|
||||
}
|
139
Engine/Source/Runtime/Core/Math/MathUnitConversion.hpp
Normal file
139
Engine/Source/Runtime/Core/Math/MathUnitConversion.hpp
Normal file
@@ -0,0 +1,139 @@
|
||||
#pragma once
|
||||
|
||||
// ======================================= //
|
||||
// Contains functions to convert units //
|
||||
// ======================================= //
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/MathCommon.hpp"
|
||||
|
||||
namespace Phanes::Core::Math::UnitConversion
|
||||
{
|
||||
|
||||
/**
|
||||
* Converts degrees to radians.
|
||||
*
|
||||
* @param(deg) Angle in degress (<28>)
|
||||
*
|
||||
* @return Angle in radians
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
inline T DegToRad(T deg)
|
||||
{
|
||||
return deg * P_PI_180_FLT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts radians to degrees.
|
||||
*
|
||||
* @param(rad) Angle in radians (rad)
|
||||
*
|
||||
* @return Angle in degrees
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
inline T RadToDeg(T rad)
|
||||
{
|
||||
return rad * P_180_PI_FLT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts degrees to gradian.
|
||||
*
|
||||
* @param(deg) Angle in degress (<28>)
|
||||
*
|
||||
* @return Angle in gradian
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
inline T DegToGradian(T deg)
|
||||
{
|
||||
return deg * 1.111111f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts gradian to degrees.
|
||||
*
|
||||
* @param(rad) Angle in gradians (g)
|
||||
*
|
||||
* @return Angle in degrees
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
inline T GradianToDeg(T g)
|
||||
{
|
||||
return g * 0.9f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts radians to gradians.
|
||||
*
|
||||
* @param(deg) Angle in radians (rad)
|
||||
*
|
||||
* @return Angle in gradians
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
inline T RadToGradian(T rad)
|
||||
{
|
||||
return rad * 200 / P_PI_FLT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts gradian to radians.
|
||||
*
|
||||
* @param(rad) Angle in gradians (g)
|
||||
*
|
||||
* @return Angle in radians
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
inline T GradianToRad(T g)
|
||||
{
|
||||
return g * P_PI_FLT / 200;
|
||||
}
|
||||
|
||||
} // phanes::core::math::typeconversion
|
||||
|
||||
|
||||
namespace Phanes::Core::Math::UnitLiterals
|
||||
{
|
||||
// ============================================== //
|
||||
// unit conversion with user-defined literals //
|
||||
// ============================================== //
|
||||
|
||||
/**
|
||||
* Convert deg to rad.
|
||||
*
|
||||
* @param(_x) Angle in degress
|
||||
*/
|
||||
|
||||
double operator ""_deg(long double _x)
|
||||
{
|
||||
return _x * P_PI_180_FLT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert rad to rad.
|
||||
*
|
||||
* @param(_x) Angle in degress
|
||||
*/
|
||||
|
||||
double operator ""_rad(long double _x)
|
||||
{
|
||||
return _x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert gradian to rad.
|
||||
*
|
||||
* @param(_x) Angle in degress
|
||||
*/
|
||||
|
||||
double operator ""_g(long double _x)
|
||||
{
|
||||
return _x * P_PI_FLT / 200;
|
||||
}
|
||||
}
|
358
Engine/Source/Runtime/Core/Math/Matrix2.hpp
Normal file
358
Engine/Source/Runtime/Core/Math/Matrix2.hpp
Normal file
@@ -0,0 +1,358 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/MathFwd.h"
|
||||
|
||||
#include "Core/public/Math/Vector2.hpp"
|
||||
|
||||
#ifndef MATRIX2_H
|
||||
#define MATRIX2_H
|
||||
|
||||
namespace Phanes::Core::Math {
|
||||
|
||||
// 2x2 Matrix defined in column-major order.
|
||||
// Accessed by M[Row][Col].
|
||||
|
||||
template<RealType T>
|
||||
struct TMatrix2
|
||||
{
|
||||
public:
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/// <summary>
|
||||
/// Column one.
|
||||
/// </summary>
|
||||
TVector2<T, false> c0;
|
||||
|
||||
/// <summary>
|
||||
/// Column two
|
||||
/// </summary>
|
||||
TVector2<T, false> c1;
|
||||
};
|
||||
|
||||
T data[2][2];
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
TMatrix2() = default;
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
|
||||
TMatrix2(const TMatrix2<T>& m1)
|
||||
{
|
||||
this->c0 = m1.c0;
|
||||
this->c1 = m1.c1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct Matrix from 2d array.
|
||||
*
|
||||
* @param(fields) 2D Array with column major order.
|
||||
*/
|
||||
|
||||
TMatrix2(T fields[2][2])
|
||||
{
|
||||
this->data[0][0] = fields[0][0]; this->data[1][0] = fields[1][0];
|
||||
this->data[0][1] = fields[0][1]; this->data[1][1] = fields[1][1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct Matrix from parameters.
|
||||
*
|
||||
* @param(n00) M[0][0]
|
||||
* @param(n10) M[1][0]
|
||||
* @param(n01) M[0][1]
|
||||
* @param(n11) M[1][1]
|
||||
*
|
||||
* @note nXY = n[Row][Col]
|
||||
*/
|
||||
|
||||
TMatrix2(T n00, T n01, T n10, T n11)
|
||||
{
|
||||
this->data[0][0] = n00; this->data[1][0] = n01;
|
||||
this->data[0][1] = n10; this->data[1][1] = n11;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct Matrix from two 2d vector columns.
|
||||
*
|
||||
* @param(v1) Column zero
|
||||
* @param(v2) Column one
|
||||
*/
|
||||
|
||||
TMatrix2(const TVector2<T, false>& v1, const TVector2<T, false>& v2)
|
||||
{
|
||||
this->c0 = v1;
|
||||
this->c1 = v2;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
||||
T& operator() (int n, int m)
|
||||
{
|
||||
return this->data[m][n];
|
||||
}
|
||||
|
||||
T operator() (int n, int m) const
|
||||
{
|
||||
return this->data[m][n];
|
||||
}
|
||||
|
||||
TVector2<T, false>& operator[] (int m)
|
||||
{
|
||||
switch (m)
|
||||
{
|
||||
case 0:
|
||||
return this->c0;
|
||||
case 1:
|
||||
return this->c1;
|
||||
}
|
||||
|
||||
throw std::invalid_argument("m is outside valid range.");
|
||||
}
|
||||
|
||||
TVector2<T, false> operator[] (int m) const
|
||||
{
|
||||
switch (m)
|
||||
{
|
||||
case 0:
|
||||
return this->c0;
|
||||
case 1:
|
||||
return this->c1;
|
||||
}
|
||||
|
||||
throw std::invalid_argument("m is outside valid range.");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// ====================== //
|
||||
// TMatrix2 operator //
|
||||
// ====================== //
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T>& operator+= (TMatrix2<T>& m1, T s)
|
||||
{
|
||||
m1(0, 0) += s;
|
||||
m1(0, 1) += s;
|
||||
m1(1, 0) += s;
|
||||
m1(1, 1) += s;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T>& operator+= (TMatrix2<T>& m1, const TMatrix2<T>& m2)
|
||||
{
|
||||
m1(0, 0) += m2(0, 0);
|
||||
m1(0, 1) += m2(0, 1);
|
||||
m1(1, 0) += m2(1, 0);
|
||||
m1(1, 1) += m2(1, 1);
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T>& operator-= (TMatrix2<T>& m1, T s)
|
||||
{
|
||||
m1(0, 0) -= s;
|
||||
m1(0, 1) -= s;
|
||||
m1(1, 0) -= s;
|
||||
m1(1, 1) -= s;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T>& operator-= (TMatrix2<T>& m1, const TMatrix2<T>& m2)
|
||||
{
|
||||
m1(0, 0) -= m2(0, 0);
|
||||
m1(0, 1) -= m2(0, 1);
|
||||
m1(1, 0) -= m2(1, 0);
|
||||
m1(1, 1) -= m2(1, 1);
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T>& operator*= (TMatrix2<T>& m1, T s)
|
||||
{
|
||||
m1.data[0][0] *= s;
|
||||
m1.data[0][1] *= s;
|
||||
m1.data[1][0] *= s;
|
||||
m1.data[1][1] *= s;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T>& operator*= (TMatrix2<T>& m1, const TMatrix2<T>& m2)
|
||||
{
|
||||
TMatrix2<T> c = m1;
|
||||
|
||||
m1(0, 0) = c(0, 0) * m2(0, 0) + c(0, 1) * m2(1, 0);
|
||||
m1(0, 1) = c(0, 0) * m2(0, 1) + c(0, 1) * m2(1, 1);
|
||||
|
||||
m1(1, 0) = c(1, 0) * m2(0, 0) + c(1, 1) * m2(1, 0);
|
||||
m1(1, 1) = c(1, 0) * m2(0, 1) + c(1, 1) * m2(1, 1);
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T>& operator/= (TMatrix2<T>& m1, T s)
|
||||
{
|
||||
s = (T)1.0 / s;
|
||||
m1.data[0][0] *= s;
|
||||
m1.data[0][1] *= s;
|
||||
m1.data[1][0] *= s;
|
||||
m1.data[1][1] *= s;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T> operator+ (const TMatrix2<T>& m1, T s)
|
||||
{
|
||||
return TMatrix2<T>(m1(0, 0) + s, m1(0, 1) + s,
|
||||
m1(1, 0) + s, m1(1, 1) + s);
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T> operator+ (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
|
||||
{
|
||||
return TMatrix2<T>(m1(0, 0) + m2(0, 0), m1(0, 1) + m2(0, 1),
|
||||
m1(1, 0) + m2(1, 0), m1(1, 1) + m2(1, 1));
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T> operator- (const TMatrix2<T>& m1, T s)
|
||||
{
|
||||
return TMatrix2<T>(m1(0, 0) - s, m1(0, 1) - s,
|
||||
m1(1, 0) - s, m1(1, 1) - s);
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T> operator- (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
|
||||
{
|
||||
return TMatrix2<T>(m1(0, 0) - m2(0, 0), m1(0, 1) - m2(0, 1),
|
||||
m1(1, 0) - m2(1, 0), m1(1, 1) - m2(1, 1));
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T> operator* (const TMatrix2<T>& m1, T s)
|
||||
{
|
||||
return TMatrix2<T>(m1(0, 0) * s, m1(0, 1) * s,
|
||||
m1(1, 0) * s, m1(1, 1) * s);
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T> operator/ (const TMatrix2<T>& m1, T s)
|
||||
{
|
||||
s = (T)1.0 / s;
|
||||
return TMatrix2<T>(m1(0, 0) * s, m1(0, 1) * s,
|
||||
m1(1, 0) * s, m1(1, 1) * s);
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T> operator* (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
|
||||
{
|
||||
return TMatrix2<T>(m1(0, 0) * m2(0, 0) + m1(0, 1) * m2(1, 0), m1(0, 0) * m2(0, 1) + m1(0, 1) * m2(1, 1),
|
||||
m1(1, 0) * m2(0, 0) + m1(1, 1) * m2(1, 0), m1(1, 0) * m2(0, 1) + m1(1, 1) * m2(1, 1));
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TVector2<T, false> operator* (const TMatrix2<T>& m1, const TVector2<T, false>& v)
|
||||
{
|
||||
return TVector2<T, false>(m1(0, 0) * v.x + m1(0, 1) * v.y,
|
||||
m1(1, 0) * v.x + m1(1, 1) * v.y);
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
bool operator== (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
|
||||
{
|
||||
return m1[0] == m2[0] && m1[1] == m2[1];
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
bool operator!= (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
|
||||
{
|
||||
return m1[0] != m2[0] || m1[1] != m2[1];
|
||||
}
|
||||
|
||||
|
||||
// ============================== //
|
||||
// Matrix function definition //
|
||||
// ============================== //
|
||||
|
||||
template<RealType T>
|
||||
T Determinant(const TMatrix2<T>& m1)
|
||||
{
|
||||
return m1(0, 0) * m1(1, 1) - m1(0, 1) * m1(1, 0);
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T>& InverseV(TMatrix2<T>& m1)
|
||||
{
|
||||
float _1_det = 1.0f / Determinant(m1);
|
||||
float m00 = m1(0, 0);
|
||||
|
||||
m1(0, 0) = m1(1, 1);
|
||||
m1(0, 1) = -m1(0, 1);
|
||||
m1(1, 0) = -m1(1, 0);
|
||||
m1(1, 1) = m00;
|
||||
|
||||
m1 *= _1_det;
|
||||
return m1;
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T>& TransposeV(TMatrix2<T>& m1)
|
||||
{
|
||||
Swap(m1(0, 1), m1(1, 0));
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
// =============== //
|
||||
// WITH RETURN //
|
||||
// =============== //
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T> Inverse(TMatrix2<T>& m1)
|
||||
{
|
||||
float _1_det = 1.0f / Determinant(m1);
|
||||
|
||||
return TMatrix2<T>( m1(1, 1) * _1_det, -m1(0, 1) * _1_det,
|
||||
-m1(1, 0) * _1_det, m1(0, 0) * _1_det);
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
TMatrix2<T> Transpose(const TMatrix2<T>& m1)
|
||||
{
|
||||
return TMatrix2<T>(m1(0, 0), m1(1, 0),
|
||||
m1(0, 1), m1(1, 1));
|
||||
}
|
||||
|
||||
template<RealType T>
|
||||
bool IsIdentityMatrix(const TMatrix2<T>& m1, T threshold = P_FLT_INAC)
|
||||
{
|
||||
return (abs(m1(0, 0) - (T)1.0) < P_FLT_INAC && abs(m1(0, 1)) < P_FLT_INAC &&
|
||||
abs(m1(1, 0)) < P_FLT_INAC && abs(m1(1, 1) - (T)1.0) < P_FLT_INAC);
|
||||
}
|
||||
|
||||
} // Phanes::Core::Math
|
||||
|
||||
|
||||
#endif // !MATRIX2_H
|
||||
|
||||
|
||||
#include "Core/public/Math/SIMD/SIMDIntrinsics.h"
|
550
Engine/Source/Runtime/Core/Math/Matrix3.hpp
Normal file
550
Engine/Source/Runtime/Core/Math/Matrix3.hpp
Normal file
@@ -0,0 +1,550 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/MathAbstractTypes.h"
|
||||
#include "Core/public/Math/MathFwd.h"
|
||||
#include "Core/public/Math/Vector3.hpp"
|
||||
|
||||
#ifndef MATRIX3_H
|
||||
#define MATRIX3_H
|
||||
|
||||
namespace Phanes::Core::Math {
|
||||
|
||||
|
||||
// 3x3 Matrix defined in column-major order.
|
||||
// Accessed by M[Row][Col].
|
||||
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct TMatrix3
|
||||
{
|
||||
public:
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/// <summary>
|
||||
/// Column one.
|
||||
/// </summary>
|
||||
TVector3<T, S> c0;
|
||||
|
||||
/// <summary>
|
||||
/// Column two.
|
||||
/// </summary>
|
||||
TVector3<T, S> c1;
|
||||
|
||||
/// <summary>
|
||||
/// Column three.
|
||||
/// </summary>
|
||||
TVector3<T, S> c2;
|
||||
};
|
||||
|
||||
T data[3][4];
|
||||
};
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
TMatrix3() = default;
|
||||
|
||||
TMatrix3(TMatrix3<T, S>&& m)
|
||||
: c0(std::move(m.c0)), c1(std::move(m.c1)), c2(std::move(m.c2))
|
||||
{};
|
||||
|
||||
TMatrix3(const TMatrix3<T, S>& m)
|
||||
: c0(m.c0), c1(m.c1), c2(m.c2)
|
||||
{};
|
||||
|
||||
/**
|
||||
* Construct Matrix from 2d array.
|
||||
*
|
||||
* @param(fields) 2D Array with row major order.
|
||||
*/
|
||||
|
||||
TMatrix3(T fields[3][3])
|
||||
{
|
||||
this->c0 = TVector3<T, S>(fields[0][0], fields[1][0], fields[2][0]);
|
||||
this->c1 = TVector3<T, S>(fields[0][1], fields[1][1], fields[2][1]);
|
||||
this->c2 = TVector3<T, S>(fields[0][2], fields[1][2], fields[2][2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct Matrix from parameters.
|
||||
*
|
||||
* @param(n00) M[0][0]
|
||||
* @param(n10) M[0][1]
|
||||
* @param(n20) M[0][2]
|
||||
* @param(n01) M[1][0]
|
||||
* ...
|
||||
*
|
||||
* @note nXY = n[Row][Col]
|
||||
*/
|
||||
|
||||
TMatrix3(T n00, T n01, T n02,
|
||||
T n10, T n11, T n12,
|
||||
T n20, T n21, T n22)
|
||||
{
|
||||
this->c0 = TVector3<T, S>(n00,n10,n20);
|
||||
this->c1 = TVector3<T, S>(n01,n11,n21);
|
||||
this->c2 = TVector3<T, S>(n02,n12,n22);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct Matrix from two 2d vector columns.
|
||||
*
|
||||
* @param(v1) Column zero
|
||||
* @param(v2) Column one
|
||||
*/
|
||||
|
||||
TMatrix3(const TVector3<T, S>& v1, const TVector3<T, S>& v2, const TVector3<T, S> v3)
|
||||
{
|
||||
this->c0 = v1;
|
||||
this->c1 = v2;
|
||||
this->c2 = v3;
|
||||
}
|
||||
|
||||
TMatrix3<T, S>& operator= (TMatrix3<T, S>&& m)
|
||||
{
|
||||
if (this != &m)
|
||||
{
|
||||
this->c0 = std::move(m.c0);
|
||||
this->c1 = std::move(m.c1);
|
||||
this->c2 = std::move(m.c2);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
TMatrix3<T, S>& operator= (const TMatrix3<T, S>& m)
|
||||
{
|
||||
if (this != &m)
|
||||
{
|
||||
this->c0 = m.c0;
|
||||
this->c1 = m.c1;
|
||||
this->c2 = m.c2;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
FORCEINLINE T operator() (int n, int m) const
|
||||
{
|
||||
return this->data[m][n];
|
||||
}
|
||||
|
||||
FORCEINLINE T& operator() (int n, int m)
|
||||
{
|
||||
return this->data[m][n];
|
||||
}
|
||||
|
||||
FORCEINLINE TVector3<T, S>& operator[] (int m)
|
||||
{
|
||||
return (*reinterpret_cast<TVector3<T, S>*>(this->data[m]));
|
||||
}
|
||||
|
||||
FORCEINLINE const TVector3<T, S> operator[] (int m) const
|
||||
{
|
||||
return (*reinterpret_cast<TVector3<T, S>*>(this->data[m]));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// ==================== //
|
||||
// Matrix3 operator //
|
||||
// ==================== //
|
||||
|
||||
/**
|
||||
* Adds scalar to matrix componentwise
|
||||
*
|
||||
* @param(m) Matrix
|
||||
* @param(s) Scalar
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S>& operator+= (TMatrix3<T, S>& m1, T s)
|
||||
{
|
||||
m1.c0 += s;
|
||||
m1.c1 += s;
|
||||
m1.c2 += s;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds matrix to matrix componentwise
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
* @param(m2) Matrix
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S>& operator+= (TMatrix3<T, S>& m1, const TMatrix3<T, S>& m2)
|
||||
{
|
||||
m1.c0 += m2.c0;
|
||||
m1.c1 += m2.c1;
|
||||
m1.c2 += m2.c2;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Substract scalar from matrix componentwise
|
||||
*
|
||||
* @param(m) Matrix
|
||||
* @param(s) Scalar
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S>& operator-= (TMatrix3<T, S>& m1, T s)
|
||||
{
|
||||
m1.c0 -= s;
|
||||
m1.c1 -= s;
|
||||
m1.c2 -= s;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Substract matrix from matrix componentwise
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
* @param(m2) Matrix
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S>& operator-= (TMatrix3<T, S>& m1, const TMatrix3<T, S>& m2)
|
||||
{
|
||||
m1.c0 -= m2.c0;
|
||||
m1.c1 -= m2.c1;
|
||||
m1.c2 -= m2.c2;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply matrix with scalar
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
* @param(s) Scalar
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S>& operator*= (TMatrix3<T, S>& m1, T s)
|
||||
{
|
||||
m1.c0 *= s;
|
||||
m1.c1 *= s;
|
||||
m1.c2 *= s;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matrix on matrix (componentwise)
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
* @param(m2) Matrix
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S>& operator*= (TMatrix3<T, S>& m1, const TMatrix3<T, S>& m2);
|
||||
|
||||
/**
|
||||
* Multiply matrix with scalar
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
* @param(s) Scalar
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S>& operator/= (TMatrix3<T, S>& m1, T s)
|
||||
{
|
||||
s = (T)1.0 / s;
|
||||
m1.c0 *= s;
|
||||
m1.c1 *= s;
|
||||
m1.c2 *= s;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matrix on matrix (componentwise)
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
* @param(m2) Matrix
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S>& operator/= (TMatrix3<T, S>& m1, const TMatrix3<T, S>& m2)
|
||||
{
|
||||
m1.c0 /= m2.c0;
|
||||
m1.c1 /= m2.c1;
|
||||
m1.c2 /= m2.c2;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add scalar to matrix componentwise
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
* @param(s) Scalar
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S> operator+ (const TMatrix3<T, S>& m, T s)
|
||||
{
|
||||
return TMatrix3<T, S>(m.c0 + s,
|
||||
m.c1 + s,
|
||||
m.c2 + s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add matrix to matrix componentwise
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
* @param(m2) Matrix
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S> operator+ (const TMatrix3<T, S>& m1, const TMatrix3<T, S>& m2)
|
||||
{
|
||||
return TMatrix3<T, S>(m1.c0 + m2.c0,
|
||||
m1.c1 + m2.c1,
|
||||
m1.c2 + m2.c2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add scalar to matrix componentwise
|
||||
*
|
||||
* @param(m) Matrix
|
||||
* @param(s) Scalar
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S> operator- (const TMatrix3<T, S>& m, T s)
|
||||
{
|
||||
return TMatrix3<T, S>(m.c0 - s,
|
||||
m.c1 - s,
|
||||
m.c2 - s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add scalar to matrix componentwise
|
||||
*
|
||||
* @param(m) Matrix
|
||||
* @param(s) Scalar
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S> operator- (const TMatrix3<T, S>& m1, const TMatrix3<T, S>& m2)
|
||||
{
|
||||
return TMatrix3<T, S>(m1.c0 - m2.c0,
|
||||
m1.c1 - m2.c1,
|
||||
m1.c2 - m2.c2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply scalar with matrix
|
||||
*
|
||||
* @param(m) Matrix
|
||||
* @param(s) Scalar
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S> operator* (const TMatrix3<T, S>& m, float s)
|
||||
{
|
||||
return TMatrix3<T, S>(m.c0 * s,
|
||||
m.c1 * s,
|
||||
m.c2 * s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply scalar with matrix
|
||||
*
|
||||
* @param(m) Matrix
|
||||
* @param(s) Scalar
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S> operator/ (const TMatrix3<T, S>& m, float s)
|
||||
{
|
||||
s = (T)1.0 / s;
|
||||
return TMatrix3<T, S>(m.c0 * s,
|
||||
m.c1 * s,
|
||||
m.c2 * s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplay matrix by matrix (componentwise)
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
* @param(m2) Matrix
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S> operator* (const TMatrix3<T, S>& m1, const TMatrix3<T, S>& m2);
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> operator* (const TMatrix3<T, S>& m1, const TVector3<T, S>& v);
|
||||
|
||||
/**
|
||||
* Compare matrix with other matrix.
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
* @param(m2) Matrix
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool operator== (const TMatrix3<T, S>& m1, const TMatrix3<T, S>& m2)
|
||||
{
|
||||
return (m1.c0 == m2.c0 && m1.c1 == m2.c1 && m1.c2 == m2.c2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare matrix with other matrix.
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
* @param(m2) Matrix
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool operator!= (const TMatrix3<T, S>& m1, const TMatrix3<T, S>& m2)
|
||||
{
|
||||
return (m1.c0 != m2.c0 || m1.c1 != m2.c1 || m1.c2 != m2.c2);
|
||||
}
|
||||
|
||||
|
||||
// =============================== //
|
||||
// Matrix function definition //
|
||||
// =============================== //
|
||||
|
||||
/**
|
||||
* Calculate determinant of 3x3 Matrix
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
T Determinant(const TMatrix3<T, S>& m1)
|
||||
{
|
||||
return m1(0, 0) * (m1(1, 1) * m1(2, 2) - m1(1, 2) * m1(2, 1))
|
||||
- m1(0, 1) * (m1(1, 0) * m1(2, 2) - m1(1, 2) * m1(2, 0))
|
||||
+ m1(0, 2) * (m1(1, 0) * m1(2, 1) - m1(1, 1) * m1(2, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate inverse of 3x3 Matrix
|
||||
*
|
||||
* @see [FUNC]Inverse
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
*
|
||||
* @note Stores result in m1.
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool InverseV(TMatrix3<T, S>& m1)
|
||||
{
|
||||
// Rows of inversed matrix
|
||||
TVector3<T, S> r0 = CrossP(m1.c1, m1.c2);
|
||||
TVector3<T, S> r1 = CrossP(m1.c2, m1.c0);
|
||||
TVector3<T, S> r2 = CrossP(m1.c0, m1.c1);
|
||||
|
||||
T _1_det = (T)1.0 / Determinant(m1);
|
||||
|
||||
if (_1_det == (T)0.0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Store matrix transposed
|
||||
m1 = TMatrix3<T, S>(r0.x, r0.y, r0.z,
|
||||
r1.x, r1.y, r1.z,
|
||||
r2.x, r2.y, r2.z);
|
||||
|
||||
m1 *= _1_det;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get transpose of matrix.
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
*
|
||||
* @note Result is stored in m1;
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S>& TransposeV(TMatrix3<T, S>& m1);
|
||||
|
||||
|
||||
// =============== //
|
||||
// WITH RETURN //
|
||||
// =============== //
|
||||
|
||||
/**
|
||||
* Calculate inverse of 3x3 Matrix
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool Inverse(const TMatrix3<T, S>& m1, Ref<TMatrix3<T, S>> r)
|
||||
{
|
||||
// r is a row-major matrix.
|
||||
TMatrix3<T, S> row;
|
||||
row[0] = CrossP(m1.c1, m1.c2);
|
||||
row[1] = CrossP(m1.c2, m1.c0);
|
||||
row[2] = CrossP(m1.c0, m1.c1);
|
||||
|
||||
T _1_det = (T)1.0 / Determinant(m1);
|
||||
|
||||
if (Phanes::Core::Math::Equals(_1_det, (T)0.0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
row *= _1_det;
|
||||
|
||||
// Store matrix transposed.
|
||||
(*r).data[0][0] = row.data[0][0]; (*r).data[1][0] = row.data[0][1]; (*r).data[2][0] = row.data[0][2];
|
||||
(*r).data[0][1] = row.data[1][0]; (*r).data[1][1] = row.data[1][1]; (*r).data[2][1] = row.data[1][2];
|
||||
(*r).data[0][2] = row.data[2][0]; (*r).data[1][2] = row.data[2][1]; (*r).data[2][2] = row.data[2][2];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get transpose of matrix.
|
||||
*
|
||||
* @param(m1) Matrix
|
||||
*
|
||||
* @note Result is stored in m1;
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S> Transpose(const TMatrix3<T, S>& m1);
|
||||
|
||||
/**
|
||||
* Checks if matrix is an identity matrix.
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool IsIdentityMatrix(const TMatrix3<T, S>& m1)
|
||||
{
|
||||
return (abs(m1(0, 0) - (T)1.0) < P_FLT_INAC && abs(m1(0, 1)) < P_FLT_INAC && abs(m1(0, 2)) < P_FLT_INAC &&
|
||||
abs(m1(1, 0)) < P_FLT_INAC && abs(m1(1, 1) - (T)1.0) < P_FLT_INAC && abs(m1(1, 2)) < P_FLT_INAC &&
|
||||
abs(m1(2, 0)) < P_FLT_INAC && abs(m1(2, 1)) < P_FLT_INAC && abs(m1(2, 2) - (T)1.0) < P_FLT_INAC);
|
||||
}
|
||||
|
||||
} // Phanes::Core::Math
|
||||
|
||||
|
||||
#endif // !MATRIX3_H
|
||||
|
||||
#include "Core/public/Math/Matrix3.inl"
|
51
Engine/Source/Runtime/Core/Math/Matrix3.inl
Normal file
51
Engine/Source/Runtime/Core/Math/Matrix3.inl
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/Detail/Matrix3Decl.inl"
|
||||
#include "Core/public/Math/SIMD/SIMDIntrinsics.h"
|
||||
|
||||
#include "Core/public/Math/SIMD/PhanesSIMDTypes.h"
|
||||
|
||||
namespace Phanes::Core::Math
|
||||
{
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S>& TransposeV(TMatrix3<T, S>& m)
|
||||
{
|
||||
Detail::compute_mat3_transpose<T, S>::map(m, m);
|
||||
return m;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S> Transpose(const TMatrix3<T, S>& m)
|
||||
{
|
||||
TMatrix3<T, S> r;
|
||||
Detail::compute_mat3_transpose<T, S>::map(r, m);
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S>& operator*= (TMatrix3<T, S>& m1, const TMatrix3<T, S>& m2)
|
||||
{
|
||||
TMatrix3<T, S> r;
|
||||
Detail::compute_mat3_mul<T, S>::map(r, m1, m2);
|
||||
return (m1 = r);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix3<T, S> operator* (const TMatrix3<T, S>& m1, const TMatrix3<T, S>& m2)
|
||||
{
|
||||
TMatrix3<T, S> r;
|
||||
Detail::compute_mat3_mul<T, S>::map(r, m1, m2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> operator* (const TMatrix3<T, S>& m1, const TVector3<T, S>& v)
|
||||
{
|
||||
TVector3<T, S> r;
|
||||
Detail::compute_mat3_mul<T, S>::map(r, m1, v);
|
||||
return r;
|
||||
}
|
||||
}
|
334
Engine/Source/Runtime/Core/Math/Matrix4.hpp
Normal file
334
Engine/Source/Runtime/Core/Math/Matrix4.hpp
Normal file
@@ -0,0 +1,334 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/MathAbstractTypes.h"
|
||||
#include "Core/public/Math/MathFwd.h"
|
||||
#include "Core/public/Math/Vector4.hpp"
|
||||
|
||||
#ifndef MATRIX4_H
|
||||
#define MATRIX4_H
|
||||
|
||||
namespace Phanes::Core::Math {
|
||||
|
||||
// 4x4 Matrix defined in column-major order.
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct TMatrix4
|
||||
{
|
||||
public:
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
TVector4<T, S> c0;
|
||||
TVector4<T, S> c1;
|
||||
TVector4<T, S> c2;
|
||||
TVector4<T, S> c3;
|
||||
};
|
||||
|
||||
T data[4][4];
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor.
|
||||
/// </summary>
|
||||
TMatrix4() = default;
|
||||
|
||||
/// <summary>
|
||||
/// Move constructor
|
||||
/// </summary>
|
||||
/// <param name="v"></param>
|
||||
TMatrix4(TMatrix4<T, S>&& m)
|
||||
: c0(std::move(m.c0)), c1(std::move(m.c1)), c2(std::move(m.c2)), c3(std::move(m.c3))
|
||||
{};
|
||||
|
||||
/// <summary>
|
||||
/// Copy constructor
|
||||
/// </summary>
|
||||
/// <param name="v"></param>
|
||||
TMatrix4(const TMatrix4<T, S>& m)
|
||||
: c0(m.c0), c1(m.c1), c2(m.c2), c3(m.c3)
|
||||
{};
|
||||
|
||||
/// <summary>
|
||||
/// Construct matrix with values.
|
||||
/// </summary>
|
||||
TMatrix4(float n00, float n01, float n02, float n03,
|
||||
float n10, float n11, float n12, float n13,
|
||||
float n20, float n21, float n22, float n23,
|
||||
float n30, float n31, float n32, float n33)
|
||||
{
|
||||
this->c0 = TVector4<T, S>(n00, n10, n20, n30);
|
||||
this->c1 = TVector4<T, S>(n01, n11, n21, n31);
|
||||
this->c2 = TVector4<T, S>(n02, n12, n22, n32);
|
||||
this->c3 = TVector4<T, S>(n03, n13, n23, n33);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct matrix from columns.
|
||||
/// </summary>
|
||||
TMatrix4(const TVector4<T, S>& v0, const TVector4<T, S>& v1, const TVector4<T, S>& v2, const TVector4<T, S>& v3)
|
||||
{
|
||||
this->c0 = v0;
|
||||
this->c1 = v1;
|
||||
this->c2 = v2;
|
||||
this->c3 = v3;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct matrix from field of values.
|
||||
/// </summary>
|
||||
/// <param name="field"></param>
|
||||
TMatrix4(T field[4][4])
|
||||
{
|
||||
this->c0 = TVector4(field[0]);
|
||||
this->c1 = TVector4(field[1]);
|
||||
this->c2 = TVector4(field[2]);
|
||||
this->c3 = TVector4(field[3]);
|
||||
}
|
||||
|
||||
TMatrix4<T, S>& operator= (TMatrix4<T, S>&& m)
|
||||
{
|
||||
if (this != &m)
|
||||
{
|
||||
this->c0 = std::move(m.c0);
|
||||
this->c1 = std::move(m.c1);
|
||||
this->c2 = std::move(m.c2);
|
||||
this->c3 = std::move(m.c3);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
TMatrix4<T, S>& operator= (const TMatrix4<T, S>& m)
|
||||
{
|
||||
if (this != &m)
|
||||
{
|
||||
this->c0 = m.c0;
|
||||
this->c1 = m.c1;
|
||||
this->c2 = m.c2;
|
||||
this->c3 = m.c3;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
FORCEINLINE T& operator() (int n, int m)
|
||||
{
|
||||
return this->data[m][n];
|
||||
}
|
||||
FORCEINLINE TVector4<T, S>& operator[] (int m)
|
||||
{
|
||||
return (*reinterpret_cast<TVector4<T, S>*>(this->m[m]));
|
||||
}
|
||||
|
||||
FORCEINLINE const T& operator() (int n, int m) const
|
||||
{
|
||||
return this->data[m][n];
|
||||
}
|
||||
FORCEINLINE const TVector4<T, S>& operator[] (int m) const
|
||||
{
|
||||
return (*reinterpret_cast<const TVector4<T, S>*>(this->data[m]));
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== //
|
||||
// Matrix4 operator //
|
||||
// ==================== //
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S>& operator+= (TMatrix4<T, S>& m1, T s)
|
||||
{
|
||||
m1.c0 += s;
|
||||
m1.c1 += s;
|
||||
m1.c2 += s;
|
||||
m1.c3 += s;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S>& operator+= (TMatrix4<T, S>& m1, const TMatrix4<T, S>& m2)
|
||||
{
|
||||
m1.c0 += m2.c0;
|
||||
m1.c1 += m2.c1;
|
||||
m1.c2 += m2.c2;
|
||||
m1.c3 += m2.c3;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S>& operator-= (TMatrix4<T, S>& m1, T s)
|
||||
{
|
||||
m1.c0 -= s;
|
||||
m1.c1 -= s;
|
||||
m1.c2 -= s;
|
||||
m1.c3 -= s;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S>& operator-= (TMatrix4<T, S>& m1, const TMatrix4<T, S>& m2)
|
||||
{
|
||||
m1.c0 -= m2.c0;
|
||||
m1.c1 -= m2.c1;
|
||||
m1.c2 -= m2.c2;
|
||||
m1.c3 -= m2.c3;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S>& operator*= (TMatrix4<T, S>& m1, T s)
|
||||
{
|
||||
m1.c0 *= s;
|
||||
m1.c1 *= s;
|
||||
m1.c2 *= s;
|
||||
m1.c3 *= s;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
// Matrix multiplication
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S>& operator*= (TMatrix4<T, S>& m1, const TMatrix4<T, S>& m2);
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S>& operator/= (TMatrix4<T, S>& m1, T s)
|
||||
{
|
||||
s = (T)1.0 / s;
|
||||
m1.c0 *= s;
|
||||
m1.c1 *= s;
|
||||
m1.c2 *= s;
|
||||
m1.c3 *= s;
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S> operator+ (const TMatrix4<T, S>& m1, T s)
|
||||
{
|
||||
return TMatrix4<T, S>(m1.c0 + s,
|
||||
m1.c1 + s,
|
||||
m1.c2 + s,
|
||||
m1.c3 + s
|
||||
);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S> operator+ (const TMatrix4<T, S>& m1, const TMatrix4<T, S>& m2)
|
||||
{
|
||||
return TMatrix4<T, S>(m1.c0 + m2.c0,
|
||||
m1.c1 + m2.c1,
|
||||
m1.c2 + m2.c2,
|
||||
m1.c3 + m2.c3
|
||||
);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S> operator- (const TMatrix4<T, S>& m1, T s)
|
||||
{
|
||||
return TMatrix4<T, S>(m1.c0 - s,
|
||||
m1.c1 - s,
|
||||
m1.c2 - s,
|
||||
m1.c3 - s
|
||||
);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S> operator- (const TMatrix4<T, S>& m1, const TMatrix4<T, S>& m2)
|
||||
{
|
||||
return TMatrix4<T, S>(m1.c0 - m2.c0,
|
||||
m1.c1 - m2.c1,
|
||||
m1.c2 - m2.c2,
|
||||
m1.c3 - m2.c3
|
||||
);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S> operator* (const TMatrix4<T, S>& m1, T s)
|
||||
{
|
||||
return TMatrix4<T, S>(m1.c0 * s,
|
||||
m1.c1 * s,
|
||||
m1.c2 * s,
|
||||
m1.c3 * s
|
||||
);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S> operator* (const TMatrix4<T, S>& m1, const TMatrix4<T, S>& m2);
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S> operator/ (const TMatrix4<T, S>& m1, T s)
|
||||
{
|
||||
s = (T)1.0 / s;
|
||||
return TMatrix4<T, S>(m1.c0 * s,
|
||||
m1.c1 * s,
|
||||
m1.c2 * s,
|
||||
m1.c3 * s
|
||||
);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator* (const TMatrix4<T, S>& m1, const TVector4<T, S>& v);
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool operator== (const TMatrix4<T, S>& m1, const TMatrix4<T, S>& m2)
|
||||
{
|
||||
return (m1.c0 == m2.c0 && m1.c1 == m2.c1 && m1.c2 == m2.c2 && m1.c3 == m2.c3);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool operator!= (const TMatrix4<T, S>& m1, const TMatrix4<T, S>& m2)
|
||||
{
|
||||
return (m1.c0 != m2.c0 || m1.c1 != m2.c1 || m1.c2 != m2.c2 || m1.c3 != m2.c3);
|
||||
}
|
||||
|
||||
|
||||
// ================================ //
|
||||
// Matrix4 function definition //
|
||||
// ================================ //
|
||||
|
||||
template<RealType T, bool S>
|
||||
T Determinant(const TMatrix4<T, S>& m);
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool InverseV(TMatrix4<T, S>& a);
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S>& TransposeV(TMatrix4<T, S>& a);
|
||||
|
||||
|
||||
// =============== //
|
||||
// WITH RETURN //
|
||||
// =============== //
|
||||
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool Inverse(const TMatrix4<T, S>& m, Ref<TMatrix4<T, S>> r);
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S> Transpose(const TMatrix4<T, S>& a);
|
||||
|
||||
template<RealType T, bool S>
|
||||
FORCEINLINE bool IsIdentityMatrix(const TMatrix4<T, S>& m1)
|
||||
{
|
||||
return (abs(m1(0, 0) - (T)1.0) < P_FLT_INAC && abs(m1(0, 1)) < P_FLT_INAC && abs(m1(0, 2)) < P_FLT_INAC && abs(m1(0, 3)) < P_FLT_INAC &&
|
||||
abs(m1(1, 0)) < P_FLT_INAC && abs(m1(1, 1) - (T)1.0) < P_FLT_INAC && abs(m1(1, 2)) < P_FLT_INAC && abs(m1(1, 3)) < P_FLT_INAC &&
|
||||
abs(m1(2, 0)) < P_FLT_INAC && abs(m1(2, 1)) < P_FLT_INAC && abs(m1(2, 2) - (T)1.0) < P_FLT_INAC && abs(m1(2, 3)) < P_FLT_INAC &&
|
||||
abs(m1(3, 0)) < P_FLT_INAC && abs(m1(3, 1)) < P_FLT_INAC && abs(m1(3, 2)) < P_FLT_INAC && abs(m1(3, 3) - (T)0.0) < P_FLT_INAC);
|
||||
}
|
||||
|
||||
|
||||
} // Phanes::Core::Math
|
||||
|
||||
|
||||
#endif // !MATRIX4_H
|
||||
|
||||
#include "Core/public/Math/Matrix4.inl"
|
69
Engine/Source/Runtime/Core/Math/Matrix4.inl
Normal file
69
Engine/Source/Runtime/Core/Math/Matrix4.inl
Normal file
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/Detail/Matrix4Decl.inl"
|
||||
#include "Core/public/Math/SIMD/SIMDIntrinsics.h"
|
||||
|
||||
#include "Core/public/Math/SIMD/PhanesSIMDTypes.h"
|
||||
|
||||
|
||||
namespace Phanes::Core::Math
|
||||
{
|
||||
template<RealType T, bool S>
|
||||
T Determinant(const TMatrix4<T, S>& m)
|
||||
{
|
||||
return Detail::compute_mat4_det<T, S>::map(m);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool InverseV(TMatrix4<T, S>& a)
|
||||
{
|
||||
return Detail::compute_mat4_inv<T, S>::map(a, a);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S>& TransposeV(TMatrix4<T, S>& a)
|
||||
{
|
||||
Detail::compute_mat4_transpose<T, S>::map(a, a);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool Inverse(const TMatrix4<T, S>& m, Ref<TMatrix4<T, S>> r)
|
||||
{
|
||||
return Detail::compute_mat4_inv<T, S>::map(*r, m);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S> Transpose(TMatrix4<T, S>& a)
|
||||
{
|
||||
TMatrix4<T, S> r;
|
||||
Detail::compute_mat4_transpose<T, S>::map(r, a);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S>& operator*= (TMatrix4<T, S>& m1, const TMatrix4<T, S>& m2)
|
||||
{
|
||||
TMatrix4<T, S> r;
|
||||
Detail::compute_mat4_mul<T, S>::map(r, m1, m2);
|
||||
return (m1 = r);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TMatrix4<T, S> operator* (const TMatrix4<T, S>& m1, const TMatrix4<T, S>& m2)
|
||||
{
|
||||
TMatrix4<T, S> r;
|
||||
Detail::compute_mat4_mul<T, S>::map(r, m1, m2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator* (const TMatrix4<T, S>& m1, const TVector4<T, S>& v)
|
||||
{
|
||||
TVector4<T, S> r;
|
||||
Detail::compute_mat4_mul<T, S>::map(r, m1, v);
|
||||
return r;
|
||||
}
|
||||
}
|
956
Engine/Source/Runtime/Core/Math/Plane.hpp
Normal file
956
Engine/Source/Runtime/Core/Math/Plane.hpp
Normal file
@@ -0,0 +1,956 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
// TODO: Transform
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
#include "Core/public/Math/MathFwd.h"
|
||||
|
||||
#include "Core/public/Math/Line.hpp"
|
||||
#include "Core/public/Math/Ray.hpp"
|
||||
#include "Core/public/Math/Vector3.hpp"
|
||||
|
||||
namespace Phanes::Core::Math {
|
||||
|
||||
// Plane in 3D space, defined as: P: ax + by + cz = d;
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct TPlane
|
||||
{
|
||||
public:
|
||||
using Real = T;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** X Part of the normal. */
|
||||
Real x;
|
||||
|
||||
/** Y Part of the normal. */
|
||||
Real y;
|
||||
|
||||
/** Z Part of the normal. */
|
||||
Real z;
|
||||
};
|
||||
|
||||
TVector3<Real, S> normal;
|
||||
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Scalar component of plane
|
||||
/// </summary>
|
||||
Real d;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Vector containing all components of vector (x, y, z and d).
|
||||
/// </summary>
|
||||
TVector4<Real, S> comp;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
|
||||
TPlane() = default;
|
||||
|
||||
/**
|
||||
* Construct plane from normal and d
|
||||
*
|
||||
* @param(normal) Normal of plane
|
||||
* @param(d) Scalar component
|
||||
*
|
||||
* @note Normal is NOT normalized, make sure to normalize [PARAM]normal, or use [FUNC]CreateFromVector. Otherwise unexpected results may occur using the plane.
|
||||
*/
|
||||
|
||||
TPlane(const TVector3<Real, S>& normal, Real d);
|
||||
|
||||
/**
|
||||
* Construct plane from normal and base point.
|
||||
*
|
||||
* @param(normal) Normal of plane
|
||||
* @param(base) Base point
|
||||
*/
|
||||
|
||||
TPlane(const TVector3<Real, S>& normal, const TVector3<Real, S>& base);
|
||||
|
||||
/**
|
||||
* Construct plane from coefficients. The components should be normalized.
|
||||
*
|
||||
* @param(x) X coefficient
|
||||
* @param(y) Y coefficient
|
||||
* @param(z) Z coefficient
|
||||
* @param(d) D coefficient
|
||||
*/
|
||||
|
||||
TPlane(Real x, Real y, Real z, Real d);
|
||||
|
||||
/**
|
||||
* Construct plane from 3 points
|
||||
*
|
||||
* @param(p1) Point one
|
||||
* @param(p2) Point two
|
||||
* @param(p3) Point three
|
||||
*/
|
||||
|
||||
TPlane(const TVector3<Real, S>& p1, const TVector3<Real, S>& p2, const TVector3<Real, S>& p3);
|
||||
};
|
||||
|
||||
|
||||
// ======================== //
|
||||
// Operators for TPlane //
|
||||
// ======================== //
|
||||
|
||||
|
||||
/**
|
||||
* Adds pl2 to pl1.
|
||||
*
|
||||
* @param(pl1) Plane to add to
|
||||
* @param(pl2) Plane to add
|
||||
*
|
||||
* @note This leads to the plane not being normalized anymore. Use PlaneNormalizeV to normalize again.
|
||||
* @see [FUNC] PlaneNormalizeV
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator+= (TPlane<T, S>& pl1, const TPlane<T, S>& pl2);
|
||||
|
||||
/**
|
||||
* Substracts pl2 from pl1.
|
||||
*
|
||||
* @param(pl1) Plane to substract from
|
||||
* @param(pl2) Plane to substract
|
||||
*
|
||||
* @note This leads to the plane not being normalized anymore. Use PlaneNormalizeV to normalize again.
|
||||
* @see [FUNC] PlaneNormalizeV
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator-= (TPlane<T, S>& pl1, const TPlane<T, S>& pl2);
|
||||
|
||||
/**
|
||||
* Multiplies pl1 with pl2.
|
||||
*
|
||||
* @param(pl1) Plane to multiply
|
||||
* @param(pl2) Plane to multiply with
|
||||
*
|
||||
* @note This leads to the plane not being normalized anymore. Use PlaneNormalizeV to normalize again.
|
||||
* @see [FUNC] PlaneNormalizeV
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator*= (TPlane<T, S>& pl1, const TPlane<T, S>& pl2);
|
||||
|
||||
/// <summary>
|
||||
/// Divides pl1 by pl2
|
||||
/// </summary>
|
||||
/// <param name="pl1"></param>
|
||||
/// <param name="pl2"></param>
|
||||
/// <returns></returns>
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator/= (TPlane<T, S>& pl1, const TPlane<T, S>& pl2);
|
||||
|
||||
/// <summary>
|
||||
/// Add scalar to plane
|
||||
/// </summary>
|
||||
/// <param name="pl1"></param>
|
||||
/// <param name="s"></param>
|
||||
/// <returns></returns>
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator+= (TPlane<T, S>& pl1, T s);
|
||||
|
||||
/// <summary>
|
||||
/// Substract scalar from plane
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="S"></typeparam>
|
||||
/// <param name="pl1"></param>
|
||||
/// <param name="s"></param>
|
||||
/// <returns></returns>
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator-= (TPlane<T, S>& pl1, T s);
|
||||
|
||||
/**
|
||||
* Multiplies pl1 with a scalar
|
||||
*
|
||||
* @param(pl1) Plane to multiply
|
||||
* @param(s) Scalar to multiply with
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator*= (TPlane<T, S>& pl1, T s);
|
||||
|
||||
/**
|
||||
* Divides pl1 with a scalar
|
||||
*
|
||||
* @param(pl1) Plane to divide
|
||||
* @param(s) Scalar to divide with
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator/= (TPlane<T, S>& pl1, T s);
|
||||
|
||||
|
||||
/**
|
||||
* Add two planes.
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
* @param(pl2) Plane
|
||||
*
|
||||
* @return Sum of planes
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator+ (const TPlane<T, S>& pl1, const TPlane<T, S>& pl2);
|
||||
|
||||
/**
|
||||
* Substracts two planes.
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
* @param(pl2) Plane
|
||||
*
|
||||
* @return Difference of the planes
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator- (const TPlane<T, S>& pl1, const TPlane<T, S>& pl2);
|
||||
|
||||
/**
|
||||
* Multiplies two planes.
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
* @param(pl2) Plane
|
||||
*
|
||||
* @return Product of planes
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator* (const TPlane<T, S>& pl1, const TPlane<T, S>& pl2);
|
||||
|
||||
/// <summary>
|
||||
/// Divides plane by plane
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="S"></typeparam>
|
||||
/// <param name="pl1"></param>
|
||||
/// <param name="pl2"></param>
|
||||
/// <returns></returns>
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator/ (const TPlane<T, S>& pl1, const TPlane<T, S>& pl2);
|
||||
|
||||
/// <summary>
|
||||
/// Add scalar to plane
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="S"></typeparam>
|
||||
/// <param name="pl1"></param>
|
||||
/// <param name="s"></param>
|
||||
/// <returns></returns>
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator+ (const TPlane<T, S>& pl1, T s);
|
||||
|
||||
/// <summary>
|
||||
/// Substracts scalar from plane
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="S"></typeparam>
|
||||
/// <param name="pl1"></param>
|
||||
/// <param name="s"></param>
|
||||
/// <returns></returns>
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator- (const TPlane<T, S>& pl1, T s);
|
||||
|
||||
/**
|
||||
* Multiplies pl1 with a scalar
|
||||
*
|
||||
* @param(pl1) Plane to multiply
|
||||
* @param(s) Scalar to multiply with
|
||||
*
|
||||
* @return Product of plane and scalar
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator* (const TPlane<T, S>& pl1, T s);
|
||||
|
||||
/**
|
||||
* Divides pl1 with a scalar
|
||||
*
|
||||
* @param(pl1) Plane to divide
|
||||
* @param(s) Scalar to divide with
|
||||
*
|
||||
* @return Quotient of plane and scalar
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator/ (const TPlane<T, S>& pl1, T s);
|
||||
|
||||
/**
|
||||
* Tests two planes for equality
|
||||
*
|
||||
* @see [FUNC] Equals
|
||||
*
|
||||
* @param(pl1) Plane one
|
||||
* @param(pl2) Plane two
|
||||
*
|
||||
* @return True, if planes are equal, false, if not.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE bool operator== (const TPlane<T, false>& pl1, const TPlane<T, false>& pl2)
|
||||
{
|
||||
return pl1.comp == pl2.comp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests two planes for inequality
|
||||
*
|
||||
* @see [FUNC] Equals
|
||||
*
|
||||
* @param(pl1) Plane one
|
||||
* @param(pl2) Plane two
|
||||
*
|
||||
* @return True, if planes are inequal, false, if not.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE bool operator!= (const TPlane<T, false>& pl1, const TPlane<T, false>& pl2)
|
||||
{
|
||||
return pl1.comp != pl2.comp;
|
||||
}
|
||||
|
||||
|
||||
// ======================= //
|
||||
// Functions of TPlane //
|
||||
// ======================= //
|
||||
|
||||
|
||||
/**
|
||||
* Tests whether two planes are perpendicular.
|
||||
*
|
||||
* @param(pl1) Plane one
|
||||
* @param(pl2) Plane two
|
||||
* @param(threshold) Allowed T inaccuracy
|
||||
*
|
||||
* @return True if perpendicular, false if not.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
inline bool IsPerpendicular(const TPlane<T, false>& pl1, const TPlane<T, false>& pl2, T threshold = P_FLT_INAC)
|
||||
{
|
||||
return (Abs(DotP(pl1.normal, pl2.normal)) < threshold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether two planes are parallel.
|
||||
*
|
||||
* @param(pl1) Plane one
|
||||
* @param(pl2) Plane two
|
||||
* @param(threshold) Allowed T inaccuracy from one (e.g. 0.98f)
|
||||
*
|
||||
* @return True if parallel, false if not.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
inline bool IsParallel(const TPlane<T, false>& pl1, const TPlane<T, false>& pl2, T threshold = 1.0f - P_FLT_INAC)
|
||||
{
|
||||
return (Abs(DotP(pl1.normal, pl2.normal)) > threshold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether two planes are coincident (Parallel and point in same direction).
|
||||
*
|
||||
* @param(pl1) Plane one
|
||||
* @param(pl2) Plane two
|
||||
* @param(threshold) Allowed T inaccuracy from one (e.g. 0.98f)
|
||||
*
|
||||
* @return True if coincident, false if not.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
inline bool IsCoincident(const TPlane<T, false>& pl1, const TPlane<T, false>& pl2, T threshold = 1.0f - P_FLT_INAC)
|
||||
{
|
||||
return (DotP(pl1.normal, pl2.normal) > threshold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether pl1 plane is a unit vector.
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
* @param(threshold) Allowed T inaccuracy
|
||||
*
|
||||
* @return True if unit vector, false if not.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
inline bool IsNormalized(const TPlane<T, false>& pl1, T threshold = P_FLT_INAC)
|
||||
{
|
||||
return (SqrMagnitude(pl1.normal) < threshold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether two planes are the same
|
||||
*
|
||||
* @see [FUNC]Equals
|
||||
*
|
||||
* @param(pl1) Plane one
|
||||
* @param(pl2) Plane two
|
||||
* @param(threshold) Allowed T inaccuracy
|
||||
*
|
||||
* @return True if same, false if not.
|
||||
* @note Planes must be normalized.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
inline bool IsSame(const TPlane<T, false>& pl1, const TPlane<T, false>& pl2, T threshold = P_FLT_INAC)
|
||||
{
|
||||
|
||||
return DotP(pl1.normal, pl2.normal) > threshold && abs(pl1.d - pl2.d) < P_FLT_INAC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes plane.
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
TPlane<T, false> PlaneNormalizeV(TPlane<T, false>& pl1)
|
||||
{
|
||||
T normVec = SqrMagnitude(pl1);
|
||||
|
||||
T scale = (normVec > P_FLT_INAC) ? (T)1.0 / sqrt(normVec) : 1.0f;
|
||||
|
||||
pl1.normal *= scale; pl1.d *= scale;
|
||||
|
||||
return pl1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes plane.
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
*
|
||||
* @return Normalized plane
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
TPlane<T, false> PlaneNormalize(TPlane<T, false>& pl1)
|
||||
{
|
||||
T normVec = SqrMagnitude(pl1);
|
||||
|
||||
T scale = (normVec > P_FLT_INAC) ? (T)1.0 / sqrt(normVec) : 1.0f;
|
||||
|
||||
return TPlane<T, false>(pl1.normal * scale, pl1.d * scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes plane.
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
*
|
||||
* @note Does not check for zero vector pl1.normal.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
TPlane<T, false> PlaneUnsafeNormalizeV(TPlane<T, false>& pl1)
|
||||
{
|
||||
T scale = (T)1.0 / Magnitude(pl1);
|
||||
|
||||
pl1.normal *= scale; pl1.d *= scale;
|
||||
|
||||
return pl1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes plane.
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
*
|
||||
* @return Normalized plane
|
||||
*
|
||||
* @note Does not check for zero vector pl1.normal.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
TPlane<T, false> PlaneUnsafeNormalize(TPlane<T, false>& pl1)
|
||||
{
|
||||
T scale = (T)1.0 / Magnitude(pl1);
|
||||
|
||||
return TPlane<T, false>(pl1.normal * scale, pl1.d * scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dot product between two planes
|
||||
*
|
||||
* @param(pl1) Plane one
|
||||
* @param(pl2) Plane two
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE T PlaneDotP(const TPlane<T, false>& pl1, const TPlane<T, false>& pl2)
|
||||
{
|
||||
return DotP(pl1.normal, pl2.normal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get angle between two planes
|
||||
*
|
||||
* @param(pl1) Plane one
|
||||
* @param(pl2) Plane two
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE T PlaneAngle(const TPlane<T, false>& pl1, const TPlane<T, false>& pl2)
|
||||
{
|
||||
return Angle(pl1.normal, pl2.normal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cosine of angle between two planes
|
||||
*
|
||||
* @param(pl1) Plane one
|
||||
* @param(pl2) Plane two
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE T PlaneCosAngle(const TPlane<T, false>& pl1, const TPlane<T, false>& pl2)
|
||||
{
|
||||
return CosineAngle(pl1.normal, pl2.normal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flip plane.
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
TPlane<T, false> FlipV(const TPlane<T, false>& pl1)
|
||||
{
|
||||
pl1.normal = -pl1.normal;
|
||||
pl1.d = -pl1.d;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get flipped plane.
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
*
|
||||
* @return Flipped plane
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
TPlane<T, false> Flip(const TPlane<T, false>& pl1)
|
||||
{
|
||||
return TPlane<T, false>(-pl1.normal, -pl1.d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform plane with Transform
|
||||
*
|
||||
* @param(pl) Plane
|
||||
* @param(tr) Transform
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE TPlane<T, false> TransformV(TPlane<T, false>& pl, const TTransform<T>& tr)
|
||||
{
|
||||
// TODO: Do with operator*
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transform plane with Transform
|
||||
*
|
||||
* @param(pl) Plane
|
||||
* @param(tr) Transform
|
||||
*
|
||||
* @return Transformed plane.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE TPlane<T, false> Transform(const TPlane<T, false>& pl, const TTransform<T>& tr)
|
||||
{
|
||||
// TODO: Do with operator*
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates distance bewteen point and plane.
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
* @param(p1) Point
|
||||
*
|
||||
* @return Distance from point to plane
|
||||
* @note Distance is 0 if point is on plane, >0 if it's in front and <0 if it's on the backside.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
T PointDistance(const TPlane<T, false>& pl1, const TVector3<T, false>& p1)
|
||||
{
|
||||
return (pl1.x * p1.x + pl1.y * p1.y + pl1.z * p1.z) - pl1.d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the origin point (base) of the plane
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
*
|
||||
* @return Base of plane
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
TVector3<T, false> GetOrigin(const TPlane<T, false>& pl1)
|
||||
{
|
||||
return TVector3<T, false>(pl1.normal * pl1.d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates plane by vector
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
* @param(v1) Vector
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
TPlane<T, false> TranslateV(TPlane<T, false>& pl1, const TVector3<T, false>& v1)
|
||||
{
|
||||
|
||||
pl1.d = DotP(this->normal, GetOrigin(pl1) + v1);
|
||||
|
||||
return pl1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates plane by vector
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
* @param(v1) Vector
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
TPlane<T, false> Translate(TPlane<T, false>& pl1, const TVector3<T, false>& v1)
|
||||
{
|
||||
return TPlane<T, false>(pl1.normal, GetOrigin(pl1) + v1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the side a point is on.
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
* @param(p1) Point
|
||||
*
|
||||
* @return True, if it's in the front and false, if it's on the back.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
bool GetSide(const TPlane<T, false>& pl1, const TVector3<T, false>& p1)
|
||||
{
|
||||
return (pl1.d <= DotP(pl1.normal, p1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Projects vector onto plane
|
||||
*
|
||||
* @param(v1) Vector to reject
|
||||
* @param(plane) Plane
|
||||
*
|
||||
* @note result is stored in v1.
|
||||
* @note Simply rejects v1 from normal
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE TVector3<T, false> ProjectOntoPlaneV(TVector3<T, false>& v1, const TPlane<T, false>& plane)
|
||||
{
|
||||
return RejectV(v1, plane.normal);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Projects vector onto plane
|
||||
*
|
||||
* @param(v1) Vector to reject
|
||||
* @param(normal) Normal of the plane
|
||||
*
|
||||
* @note result is stored in v1.
|
||||
* @note Simply rejects v1 from normal
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE TVector3<T, false> ProjectOntoPlaneV(TVector3<T, false>& v1, const TVector3<T, false>& normal)
|
||||
{
|
||||
return RejectV(v1, normal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reflect from plane
|
||||
*
|
||||
* @param(v1) Vector to mirror
|
||||
* @param(plane) Plane to mirror on
|
||||
*
|
||||
* @note result is stored in v1.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE TVector3<T, false> ReflectFromPlaneV(TVector3<T, false>& v1, const TPlane<T, false>& plane)
|
||||
{
|
||||
return ReflectV(v1, plane.normal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reflect from plane
|
||||
*
|
||||
* @param(v1) Vector to mirror
|
||||
* @param(normal) Normal of plane
|
||||
*
|
||||
* @note result is stored in v1.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE TVector3<T, false> ReflectFromPlaneV(TVector3<T, false>& v1, const TVector3<T, false>& normal)
|
||||
{
|
||||
return ReflectV(v1, normal);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reflect from plane
|
||||
*
|
||||
* @param(v1) Vector to mirror
|
||||
* @param(plane) Plane to mirror on
|
||||
*
|
||||
* @return Reflected vector
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE TVector3<T, false> ReflectFromPlane(const TVector3<T, false>& v1, const TPlane<T, false>& plane)
|
||||
{
|
||||
return Reflect(v1, plane.normal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reflect from plane
|
||||
*
|
||||
* @param(v1) Vector to mirror
|
||||
* @param(plane) Normal of plane
|
||||
*
|
||||
* @return Reflected vector
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE TVector3<T, false> ReflectFromPlane(const TVector3<T, false>& v1, const TVector3<T, false>& normal)
|
||||
{
|
||||
return Reflect(v1, normal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Projects vector onto plane
|
||||
*
|
||||
* @see [FUNC]PointProjectOntoPlane
|
||||
*
|
||||
* @param(v1) Vector to reject
|
||||
* @param(normal) Normal of the plane
|
||||
*
|
||||
* @return Projected vector
|
||||
* @note Simply rejects the vector from normal
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE TVector3<T, false> ProjectOntoPlane(const TVector3<T, false>& v1, const TVector3<T, false>& normal)
|
||||
{
|
||||
return Reject(v1, normal);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Projects vector onto plane
|
||||
*
|
||||
* @see [FUNC]PointProjectOntoPlane
|
||||
*
|
||||
* @param(v1) Vector to reject
|
||||
* @param(plane) Plane
|
||||
*
|
||||
* @return Projected vector
|
||||
* @note Simply rejects the vector from normal
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE TVector3<T, false> ProjectOntoPlane(const TVector3<T, false>& v1, const TPlane<T, false>& plane)
|
||||
{
|
||||
return Reject(v1, plane.normal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests planes for equality
|
||||
*
|
||||
* @param(pl1) Plane one
|
||||
* @param(pl2) Plane two
|
||||
* @param(threshold) Allowed inaccuracy
|
||||
*
|
||||
* @return True, if equal, false if not.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
inline bool Equals(const TPlane<T, false>& pl1, const TPlane<T, false>& pl2, T threshold = P_FLT_INAC)
|
||||
{
|
||||
return Equals(pl1.normal, pl2.normal, threshold) && abs(pl1.d - pl2.d) < threshold;
|
||||
}
|
||||
|
||||
|
||||
/** Tests whether a point is on a plane
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
* @param(p1) Point
|
||||
*
|
||||
* @return True, if p1 on pl1, false if not.
|
||||
*/
|
||||
template<RealType T>
|
||||
FORCEINLINE bool IsPointOnPlane(const TPlane<T, false>& pl1, const TVector3<T, false>& p1)
|
||||
{
|
||||
return (Equals(DotP(pl1.normal, p1), p1.d));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether two planes intersect. Sets line to intersection-line if true.
|
||||
*
|
||||
* @param(pl1) Plane one
|
||||
* @param(pl2) Plane two
|
||||
* @param(interLine) Line of intersection
|
||||
* @param(threshold) Threshold for parallel planes.
|
||||
*
|
||||
* @return True, if planes intersect, false, if not.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
bool PlanesIntersect2(const TPlane<T, false>& pl1, const TPlane<T, false>& pl2, Ref<TLine<T>> interLine, T threshold = P_FLT_INAC)
|
||||
{
|
||||
TVector3<T, false> dirLine = CrossP(pl1.normal, pl2.normal);
|
||||
T det = SqrMagnitude(dirLine);
|
||||
|
||||
if (abs(det) > P_FLT_INAC)
|
||||
{
|
||||
interLine = MakeRef<TLine<T>>(dirLine, (CrossP(dirLine, pl2.normal) * pl1.d + CrossP(dirLine, pl1.normal) * pl2.d) / det);
|
||||
NormalizeV(interLine);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether three planes intersect. Sets line to intersection-line if true.
|
||||
*
|
||||
* @param(pl1) Plane one
|
||||
* @param(pl2) Plane two
|
||||
* @param(pl3) Plane three
|
||||
* @param(interPoint) Point of intersection
|
||||
* @param(threshold) Threshold for parallel planes.
|
||||
*
|
||||
* @return True, if all planes intersect, false, if not.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
bool PlanesIntersect3(const TPlane<T, false>& pl1, const TPlane<T, false>& pl2, const TPlane<T, false>& pl3, Ref<TVector3<T, false>> interPoint, T threshold = P_FLT_INAC)
|
||||
{
|
||||
T det = DotP(CrossP(pl1.normal, pl2.normal), pl3.normal);
|
||||
|
||||
if (abs(det) > P_FLT_INAC)
|
||||
{
|
||||
interPoint = MakeRef<TVector3<T, false>>((CrossP(pl3.normal, pl2.normal) * pl1.d + CrossP(pl1.normal, pl3.normal) * pl2.d) / det);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mirrors a point through plane
|
||||
*
|
||||
* @param(p1) Point to mirror
|
||||
* @param(pl1) Plane
|
||||
*
|
||||
* @return Mirrored point.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
TVector3<T, false> PlaneMirrorPoint(const TVector3<T, false>& p1, const TPlane<T, false>& pl1)
|
||||
{
|
||||
return p1 - pl1.normal * ((T)2.0 * PointDistance(pl1, p1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Projects point onto plane
|
||||
*
|
||||
* @param(p1) Point to project
|
||||
* @param(pl1) Plane
|
||||
*
|
||||
* @return Projected point.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
TVector3<T, false> PointProjectOntoPlane(const TVector3<T, false>& p1, const TPlane<T, false>& pl1)
|
||||
{
|
||||
return p1 - PointDistance(pl1, p1) * pl1.normal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the intersection point, of a line with a plane, if there is one
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
* @param(l1) Line
|
||||
* @param(p1) Point
|
||||
*
|
||||
* @return True, if they intersect, false if not.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
bool LineIntersect(const TPlane<T, false>& pl1, const TLine<T>& l1, Ref<TVector3<T, false>> p1)
|
||||
{
|
||||
T dotProduct = DotP(l1.normal, pl1.normal);
|
||||
|
||||
if (abs(dotProduct) > P_FLT_INAC)
|
||||
{
|
||||
p1 = MakeRef<TVector3<T, false>>(l1.base - l1.normal * (DotP(l1.normal * p1.base) / dotProduct));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates, the intersection point, of a plane and a ray.
|
||||
*
|
||||
* @param(pl1) Plane
|
||||
* @param(r1) Ray
|
||||
* @param(p1) Intersection point
|
||||
*
|
||||
* @return True, if they intersect, false if not.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
bool RayIntersect(const TPlane<T, false>& pl1, const TRay<T, false>& r1, Ref<TVector3<T, false>> p1)
|
||||
{
|
||||
T pr = DotP(pl1.normal, Normalize(r1.direction));
|
||||
T parameter = DotP((GetOrigin(pl1) - r1.origin), pl1.normal) / pr;
|
||||
|
||||
if (p1 > P_FLT_INAC && parameter >= 0)
|
||||
{
|
||||
p1 = MakeRef<TVector3<T, false>>(PointAt(r1, parameter));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // Phanes::Core::Math
|
||||
|
||||
// Include operator impl.
|
||||
#include "Core/public/Math/Plane.inl"
|
159
Engine/Source/Runtime/Core/Math/Plane.inl
Normal file
159
Engine/Source/Runtime/Core/Math/Plane.inl
Normal file
@@ -0,0 +1,159 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/Detail/PlaneDecl.inl"
|
||||
#include "Core/public/Math/SIMD/SIMDIntrinsics.h"
|
||||
|
||||
#include "Core/public/Math/SIMD/PhanesSIMDTypes.h"
|
||||
|
||||
|
||||
|
||||
namespace Phanes::Core::Math
|
||||
{
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S>::TPlane(const TVector3<T, S>& normal, Real d)
|
||||
{
|
||||
Detail::construct_plane<T, S>::map(*this, normal, d);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S>::TPlane(const TVector3<T, S>& normal, const TVector3<T, S>& base)
|
||||
{
|
||||
Detail::construct_plane<T, S>::map(*this, normal, base);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S>::TPlane(Real x, Real y, Real z, Real d)
|
||||
{
|
||||
Detail::construct_plane<T, S>::map(*this, x, y, z, d);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S>::TPlane(const TVector3<T, S>& p1, const TVector3<T, S>& p2, const TVector3<T, S>& p3)
|
||||
{
|
||||
Detail::construct_plane<T, S>::map(*this, p1, p2, p3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator+=(TPlane<T, S>& pl1, const TPlane<T, S>& pl2)
|
||||
{
|
||||
Detail::compute_plane_add(pl1, pl1, pl2);
|
||||
return pl1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator+=(TPlane<T, S>& pl1, T s)
|
||||
{
|
||||
Detail::compute_plane_add(pl1, pl1, s);
|
||||
return pl1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator+(const TPlane<T, S>& pl1, const TPlane<T, S>& pl2)
|
||||
{
|
||||
TPlane<T, S> r;
|
||||
Detail::compute_plane_add(r, pl1, pl2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator+(const TPlane<T, S>& pl1, T s)
|
||||
{
|
||||
TPlane<T, S> r;
|
||||
Detail::compute_plane_add(r, pl1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator-=(TPlane<T, S>& pl1, const TPlane<T, S>& pl2)
|
||||
{
|
||||
Detail::compute_plane_sub(pl1, pl1, pl2);
|
||||
return pl1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator-=(TPlane<T, S>& pl1, T s)
|
||||
{
|
||||
Detail::compute_plane_sub(pl1, pl1, s);
|
||||
return pl1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator-(const TPlane<T, S>& pl1, const TPlane<T, S>& pl2)
|
||||
{
|
||||
TPlane<T, S> r;
|
||||
Detail::compute_plane_sub(r, pl1, pl2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator-(const TPlane<T, S>& pl1, T s)
|
||||
{
|
||||
TPlane<T, S> r;
|
||||
Detail::compute_plane_sub(r, pl1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator*=(TPlane<T, S>& pl1, const TPlane<T, S>& pl2)
|
||||
{
|
||||
Detail::compute_plane_mul(pl1, pl1, pl2);
|
||||
return pl1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator*=(TPlane<T, S>& pl1, T s)
|
||||
{
|
||||
Detail::compute_plane_mul(pl1, pl1, s);
|
||||
return pl1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator*(const TPlane<T, S>& pl1, const TPlane<T, S>& pl2)
|
||||
{
|
||||
TPlane<T, S> r;
|
||||
Detail::compute_plane_mul(r, pl1, pl2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator*(const TPlane<T, S>& pl1, T s)
|
||||
{
|
||||
TPlane<T, S> r;
|
||||
Detail::compute_plane_mul(r, pl1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator/=(TPlane<T, S>& pl1, const TPlane<T, S>& pl2)
|
||||
{
|
||||
Detail::compute_plane_div(pl1, pl1, pl2);
|
||||
return pl1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator/=(TPlane<T, S>& pl1, T s)
|
||||
{
|
||||
Detail::compute_plane_div(pl1, pl1, s);
|
||||
return pl1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator/(const TPlane<T, S>& pl1, const TPlane<T, S>& pl2)
|
||||
{
|
||||
TPlane<T, S> r;
|
||||
Detail::compute_plane_sub(r, pl1, pl2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TPlane<T, S> operator/(const TPlane<T, S>& pl1, T s)
|
||||
{
|
||||
TPlane<T, S> r;
|
||||
Detail::compute_plane_sub(r, pl1, s);
|
||||
return r;
|
||||
}
|
||||
}
|
112
Engine/Source/Runtime/Core/Math/PlatformTypes.h
Normal file
112
Engine/Source/Runtime/Core/Math/PlatformTypes.h
Normal file
@@ -0,0 +1,112 @@
|
||||
#pragma once
|
||||
|
||||
#include "PhanesEnginePCH.h"
|
||||
|
||||
// ============================================= //
|
||||
// Turn os specific types into global types. //
|
||||
// ============================================= //
|
||||
|
||||
|
||||
// TODO: include int128
|
||||
|
||||
namespace Phanes::Core::Types
|
||||
{
|
||||
|
||||
#ifdef P_WIN_BUILD
|
||||
|
||||
// MSCV++ specific types
|
||||
|
||||
typedef FLOAT128 float128;
|
||||
|
||||
//#elif P_UNIX_BUILD
|
||||
//
|
||||
// // GCC specific types
|
||||
//
|
||||
// typedef __float128 float128;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// Specific types size
|
||||
//
|
||||
// 8-Bit integer
|
||||
typedef int8_t int8;
|
||||
|
||||
// 16-Bit integer
|
||||
typedef int16_t int16;
|
||||
|
||||
// 32-Bit integer
|
||||
typedef int32_t int32;
|
||||
|
||||
// 64-Bit integer
|
||||
typedef int64_t int64;
|
||||
|
||||
// 8-Bit unsigned integer
|
||||
typedef uint8_t uint8;
|
||||
|
||||
// 16-Bit unsigned integer
|
||||
typedef uint16_t uint16;
|
||||
|
||||
// 32-Bit unsigned integer
|
||||
typedef uint32_t uint32;
|
||||
|
||||
// 64-Bit unsigned integer
|
||||
typedef uint64_t uint64;
|
||||
|
||||
|
||||
|
||||
// At least N bit types
|
||||
//
|
||||
// At least 8-Bit integer
|
||||
typedef int_least8_t lint8;
|
||||
|
||||
// At least 16-Bit integer
|
||||
typedef int_least16_t lint16;
|
||||
|
||||
// At least 32-Bit integer
|
||||
typedef int_least32_t lint32;
|
||||
|
||||
// At least 64-Bit integer
|
||||
typedef int_least64_t lint64;
|
||||
|
||||
// At least 8-Bit integer
|
||||
typedef uint_least8_t ulint8;
|
||||
|
||||
// At least 16-Bit integer
|
||||
typedef uint_least16_t ulint16;
|
||||
|
||||
// At least 32-Bit integer
|
||||
typedef uint_least32_t ulint32;
|
||||
|
||||
// At least 64-Bit integer
|
||||
typedef uint_least64_t ulint64;
|
||||
|
||||
|
||||
|
||||
// Fast N bit types
|
||||
//
|
||||
// Fast 8-bit integer
|
||||
typedef int_fast8_t fint8;
|
||||
|
||||
// At least 16-Bit integer
|
||||
typedef int_fast16_t fint16;
|
||||
|
||||
// At least 32-Bit integer
|
||||
typedef int_fast32_t fint32;
|
||||
|
||||
// At least 64-Bit integer
|
||||
typedef int_fast64_t fint64;
|
||||
|
||||
// At least 8-Bit integer
|
||||
typedef uint_fast8_t ufint8;
|
||||
|
||||
// At least 16-Bit integer
|
||||
typedef uint_fast16_t ufint16;
|
||||
|
||||
// At least 32-Bit integer
|
||||
typedef uint_fast32_t ufint32;
|
||||
|
||||
// At least 64-Bit integer
|
||||
typedef uint_fast64_t ufint64;
|
||||
|
||||
}
|
193
Engine/Source/Runtime/Core/Math/Point.hpp
Normal file
193
Engine/Source/Runtime/Core/Math/Point.hpp
Normal file
@@ -0,0 +1,193 @@
|
||||
#pragma once
|
||||
|
||||
#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/Vector2.hpp"
|
||||
#include "Core/public/Math/Vector3.hpp"
|
||||
|
||||
#ifndef P_DEBUG
|
||||
#pragma warning(disable : 4244)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The Point is the same as a vector. The type exists, to ensure
|
||||
* differentiation between the two types.
|
||||
*/
|
||||
|
||||
#ifndef POINT_H
|
||||
#define POINT_H
|
||||
|
||||
namespace Phanes::Core::Math {
|
||||
|
||||
/**
|
||||
* A 2D Point with components x and y with float precision.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
struct TPoint2 : public TVector2<T, false> {
|
||||
|
||||
using TVector2<T, false>::TVector2;
|
||||
|
||||
using Real = T;
|
||||
|
||||
/**
|
||||
* Creates Point2 from Point3's xy
|
||||
*
|
||||
* @param a Point3 one
|
||||
*/
|
||||
|
||||
TPoint2(const TPoint3<T>& p)
|
||||
{
|
||||
this->x = p.x;
|
||||
this->y = p.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Point2 from Point4's xy
|
||||
*
|
||||
* @param a Point4 one
|
||||
*/
|
||||
|
||||
TPoint2(const TPoint4<T>& p)
|
||||
{
|
||||
this->x = p.x;
|
||||
this->y = p.y;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates distance between two points.
|
||||
*
|
||||
* @param(p1) Point one
|
||||
* @param(p2) Point two
|
||||
*
|
||||
* @return Distance between two points.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
T Distance(const TPoint2<T>& p1, const TPoint2<T>& p2)
|
||||
{
|
||||
return Magnitude(p2 - p1);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* A 3D Point with components x and y with float precision.
|
||||
*/
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct TPoint3 : public TVector3<T, false> {
|
||||
|
||||
using TVector3<T, false>::TVector3;
|
||||
|
||||
using Real = T;
|
||||
|
||||
/**
|
||||
* Creates Point3 from Point2's xy and zero
|
||||
*
|
||||
* @param a Point2 one
|
||||
*/
|
||||
|
||||
TPoint3(const TPoint2<T>& p)
|
||||
{
|
||||
this->x = p.x;
|
||||
this->y = p.y;
|
||||
this->z = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Point3 from Point4's xyz
|
||||
*
|
||||
* @param a Point4 one
|
||||
*/
|
||||
|
||||
TPoint3(const TPoint4<T>& p)
|
||||
{
|
||||
this->x = p.x;
|
||||
this->y = p.y;
|
||||
this->z = p.z;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates distance between two points.
|
||||
*
|
||||
* @param(p1) Point one
|
||||
* @param(p2) Point two
|
||||
*
|
||||
* @return Distance between two points.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
T Distance(const TPoint3<T>& p1, const TPoint3<T>& p2)
|
||||
{
|
||||
return Magnitude(p2 - p1);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* A 4D Point with components x and y with float precision.
|
||||
*/
|
||||
|
||||
|
||||
template<RealType T>
|
||||
struct TPoint4 : public TVector4<T, false> {
|
||||
|
||||
using TVector4<T, false>::TVector4;
|
||||
|
||||
/**
|
||||
* Creates Point4 from Point2's xy and the last two zero
|
||||
*
|
||||
* @param a Point2 one
|
||||
*/
|
||||
|
||||
TPoint4(const TPoint2<T>& p)
|
||||
{
|
||||
this->x = p.x;
|
||||
this->y = p.y;
|
||||
this->z = 0;
|
||||
this->w = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Point4 from Point3's xyz and zero
|
||||
*
|
||||
* @param a Point3 one
|
||||
*/
|
||||
|
||||
TPoint4(const TPoint3<T>& p)
|
||||
{
|
||||
this->x = p.x;
|
||||
this->y = p.y;
|
||||
this->z = p.z;
|
||||
this->w = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates distance between two points.
|
||||
*
|
||||
* @param(p1) Point one
|
||||
* @param(p2) Point two
|
||||
*
|
||||
* @return Distance between two points.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
T Distance(const TPoint4<T>& p1, const TPoint4<T>& p2)
|
||||
{
|
||||
return Magnitude(p2 - p1);
|
||||
}
|
||||
|
||||
} // phanes::core::math::coretypes
|
||||
|
||||
#endif // !POINT_H
|
13
Engine/Source/Runtime/Core/Math/README.md
Normal file
13
Engine/Source/Runtime/Core/Math/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# PhanesCore
|
||||
|
||||
## Math
|
||||
|
||||
### Description
|
||||
|
||||
Math lib.
|
||||
Math is designed, to be completly independent from the rest of Phanes.
|
||||
|
||||
|
||||
### Notes
|
||||
|
||||
- Normals are called normals for a reason.
|
127
Engine/Source/Runtime/Core/Math/Ray.hpp
Normal file
127
Engine/Source/Runtime/Core/Math/Ray.hpp
Normal file
@@ -0,0 +1,127 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
#include "Core/public/Math/MathFwd.h"
|
||||
|
||||
#include "Core/public/Math/Vector3.hpp"
|
||||
|
||||
namespace Phanes::Core::Math
|
||||
{
|
||||
|
||||
// Ray with origin and direction (L = p + t * v)
|
||||
|
||||
template<RealType T, bool S>
|
||||
struct TRay
|
||||
{
|
||||
public:
|
||||
using Real = T;
|
||||
|
||||
TVector3<Real, S> origin;
|
||||
TVector3<Real, S> direction;
|
||||
|
||||
public:
|
||||
/** Default constructor */
|
||||
TRay() = default;
|
||||
|
||||
/** Copy constructor */
|
||||
TRay(const TRay<Real, S>& r) : direction(r.direction), origin(r.origin) {};
|
||||
|
||||
/** Move constructor */
|
||||
TRay(TRay<Real, S>&& r) : direction(std::move(r.direction)), origin(std::move(r.origin)) {};
|
||||
|
||||
/**
|
||||
* Construct ray from origin and direction.
|
||||
*
|
||||
* @param(direction) Direction
|
||||
* @param(origin) Origin
|
||||
*/
|
||||
|
||||
TRay(const TVector3<Real, S>& direction, const TVector3<Real, S>& origin) : direction(direction), origin(origin) {};
|
||||
|
||||
};
|
||||
|
||||
// ================== //
|
||||
// TRay operators //
|
||||
// ================== //
|
||||
|
||||
|
||||
/**
|
||||
* Tests two rays for equality
|
||||
*
|
||||
* @param(r1) Ray one
|
||||
* @param(r2) Ray two
|
||||
*
|
||||
* @return True, if same and false, if not.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE bool operator== (const TRay<T, false>& r1, const TRay<T, false>& r2)
|
||||
{
|
||||
return (r1.origin == r2.origin && r1.direction == r2.direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests two rays for inequality
|
||||
*
|
||||
* @param(r1) Ray one
|
||||
* @param(r2) Ray two
|
||||
*
|
||||
* @return True, if not same and false, if same.
|
||||
*/
|
||||
|
||||
template<RealType T>
|
||||
FORCEINLINE bool operator!= (const TRay<T, false>& r1, const TRay<T, false>& r2)
|
||||
{
|
||||
return (r1.origin != r2.origin || r1.direction != r2.direction);
|
||||
}
|
||||
|
||||
// ================== //
|
||||
// TRay functions //
|
||||
// ================== //
|
||||
|
||||
|
||||
/**
|
||||
* Gets the point of the ray at a given parameter
|
||||
*
|
||||
* @param(r1) Ray
|
||||
* @param(t) Parameter
|
||||
*
|
||||
* @return Point at t
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> PointAt(const TRay<T, S>& r1, T t)
|
||||
{
|
||||
return r1.origin + r1.direction * t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets parameter necessary to travel to query point on line.
|
||||
*
|
||||
* @param(r1) Ray
|
||||
* @param(p1) Query point
|
||||
*
|
||||
* @return parameter t
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> GetParameter(const TRay<T, S>& r1, const TVector3<T, S>& p1)
|
||||
{
|
||||
return DotP((p1 - r1.origin), r1.direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests wether two ray point in the same direction (Not if origin).
|
||||
*
|
||||
* @param(r1) Ray one
|
||||
* @param(r2) Ray two
|
||||
*
|
||||
* @return True, if both rays point in the same direction, false if not.
|
||||
*/
|
||||
|
||||
template<RealType T, bool S>
|
||||
inline bool SameDirection(const TRay<T, S>& r1, const TRay<T, S>& r2)
|
||||
{
|
||||
return (r1.direction == r1.direction);
|
||||
}
|
||||
}
|
30
Engine/Source/Runtime/Core/Math/SIMD/Alignment.h
Normal file
30
Engine/Source/Runtime/Core/Math/SIMD/Alignment.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
|
||||
namespace Phanes::Core::Math::SIMD
|
||||
{
|
||||
|
||||
// Structure to conveniently align arrays.
|
||||
template<typename T, size_t L>
|
||||
struct alignas(sizeof(T) * 4) AlignedVec
|
||||
{
|
||||
public:
|
||||
T data[L];
|
||||
|
||||
AlignedVec(const T* n_aligned_data)
|
||||
{
|
||||
for (size_t i = 0; i < L; ++i)
|
||||
{
|
||||
data[i] = n_aligned_data[i];
|
||||
}
|
||||
}
|
||||
|
||||
const T* Get()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
228
Engine/Source/Runtime/Core/Math/SIMD/PhanesSIMDTypes.h
Normal file
228
Engine/Source/Runtime/Core/Math/SIMD/PhanesSIMDTypes.h
Normal file
@@ -0,0 +1,228 @@
|
||||
#pragma once
|
||||
|
||||
// This file includes the necessary header for vectorization intrinsics. If no specifics are defined SSE4.2 is used.
|
||||
//
|
||||
// ARM is not supported.
|
||||
|
||||
#include "Core/public/Math/SIMD/Platform.h"
|
||||
#include "Core/public/Math/MathTypes.h"
|
||||
|
||||
#if P_INTRINSICS == P_INTRINSICS_AVX2
|
||||
# include <immintrin.h>
|
||||
#elif P_INTRINSICS == P_INTRINSICS_AVX
|
||||
# include <immintrin.h>
|
||||
#elif P_INTRINSICS == P_INTRINSICS_SSE
|
||||
# include <nmmintrin.h>
|
||||
#elif P_INTRINSICS == P_INTRINSICS_NEON
|
||||
# include "neon.h" // <- Not supported
|
||||
#endif
|
||||
|
||||
// use_simd for metaprogramming
|
||||
namespace Phanes::Core::Math::SIMD
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This decides, whether simd operations should be used, based on the vector type, it's size, the vector alignment and whether the right extension can be loaded during compiletime.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="L">Length of vector</typeparam>
|
||||
/// <typeparam name="IsAligned">Whether the vector is aligned for simd usage.</typeparam>
|
||||
template<typename T, size_t L, bool IsAligned>
|
||||
struct use_simd
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
|
||||
// SSE / NEON
|
||||
|
||||
template<>
|
||||
struct use_simd<float, 4, true>
|
||||
{
|
||||
static const bool value = true && (P_SSE__ || P_NEON__);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct use_simd<float, 3, true>
|
||||
{
|
||||
static const bool value = true && (P_SSE__ || P_NEON__);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct use_simd<int, 4, true>
|
||||
{
|
||||
static const bool value = true && (P_SSE__ || P_NEON__);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct use_simd<int, 3, true>
|
||||
{
|
||||
static const bool value = true && (P_SSE__ || P_NEON__);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct use_simd<unsigned int, 4, true>
|
||||
{
|
||||
static const bool value = true && (P_SSE__ || P_NEON__);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct use_simd<unsigned int, 3, true>
|
||||
{
|
||||
static const bool value = true && (P_SSE__ || P_NEON__);
|
||||
};
|
||||
|
||||
// SSE
|
||||
|
||||
template<>
|
||||
struct use_simd<double, 2, true>
|
||||
{
|
||||
static const bool value = true && P_SSE__;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct use_simd<Phanes::Core::Types::int64, 2, true>
|
||||
{
|
||||
static const bool value = true && P_SSE__;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct use_simd<Phanes::Core::Types::uint64, 2, true>
|
||||
{
|
||||
static const bool value = true && P_SSE__;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// AVX
|
||||
|
||||
template<>
|
||||
struct use_simd<double, 4, true>
|
||||
{
|
||||
static const bool value = true && P_AVX__;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct use_simd<double, 3, true>
|
||||
{
|
||||
static const bool value = true && P_AVX__;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct use_simd<float, 8, true>
|
||||
{
|
||||
static const bool value = true && P_AVX__;
|
||||
};
|
||||
|
||||
|
||||
// AVX2
|
||||
|
||||
template<>
|
||||
struct use_simd<Phanes::Core::Types::int64, 4, true>
|
||||
{
|
||||
static const bool value = true && P_AVX2__;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct use_simd<Phanes::Core::Types::int64, 3, true>
|
||||
{
|
||||
static const bool value = true && P_AVX2__;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct use_simd<Phanes::Core::Types::uint64, 4, true>
|
||||
{
|
||||
static const bool value = true && P_AVX2__;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct use_simd<Phanes::Core::Types::uint64, 3, true>
|
||||
{
|
||||
static const bool value = true && P_AVX2__;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct use_simd<int, 8, true>
|
||||
{
|
||||
static const bool value = true && P_AVX2__;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct use_simd<unsigned int, 8, true>
|
||||
{
|
||||
static const bool value = true && P_AVX2__;
|
||||
};
|
||||
}
|
||||
|
||||
// Register aliases
|
||||
namespace Phanes::Core::Types
|
||||
{
|
||||
|
||||
#if P_INTRINSICS >= 1
|
||||
|
||||
typedef __m128 Vec4f32Reg;
|
||||
typedef __m128d Vec2f64Reg;
|
||||
|
||||
typedef __m128i Vec4i32Reg;
|
||||
typedef __m128i Vec2i64Reg;
|
||||
|
||||
typedef __m128i Vec4u32Reg;
|
||||
typedef __m128i Vec2u64Reg;
|
||||
|
||||
#elif P_INTRINSICS != P_INTRINSICS_NEON
|
||||
|
||||
typedef struct alignas(16) Vec4f32Reg { float data[4]; } Vec4f32Reg;
|
||||
typedef struct alignas(16) Vec2f64Reg { double data[2]; } Vec2f64Reg;
|
||||
typedef struct alignas(16) Vec4i32Reg { int data[4]; } Vec4i32Reg;
|
||||
typedef struct alignas(16) Vec2i64Reg { Phanes::Core::Types::int64 data[2]; } Vec2i64Reg;
|
||||
typedef struct alignas(16) Vec4u32Reg { unsigned int data[4]; } Vec4u32Reg;
|
||||
typedef struct alignas(16) Vec2u64Reg { Phanes::Core::Types::uint64 data[4]; } Vec2u64Reg;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if P_INTRINSICS >= 2
|
||||
|
||||
typedef __m256 Vec4x2f32Reg;
|
||||
typedef __m256 Vec8f32Reg;
|
||||
typedef __m256d Vec2x2f64Reg;
|
||||
typedef __m256d Vec4f64Reg;
|
||||
|
||||
#elif P_INTRINSICS != P_INTRINSICS_NEON
|
||||
|
||||
typedef struct alignas(32) Vec4x2f32Reg { float data[8]; } Vec4x2f32Reg;
|
||||
typedef struct alignas(32) Vec8f32Reg { float data[8]; } Vec8f32Reg;
|
||||
typedef struct alignas(32) Vec2x2f64Reg { double data[4]; } Vec2x2f64Reg;
|
||||
typedef struct alignas(32) Vec4f64Reg { double data[4]; } Vec4f64Reg;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if P_INTRINSICS == 3
|
||||
|
||||
typedef __m256i Vec4x2i32Reg;
|
||||
typedef __m256i Vec8i32Reg;
|
||||
typedef __m256i Vec2x2i64Reg;
|
||||
typedef __m256i Vec4i64Reg;
|
||||
|
||||
typedef __m256i Vec4x2u32Reg;
|
||||
typedef __m256i Vec8u32Reg;
|
||||
typedef __m256i Vec2x2u64Reg;
|
||||
typedef __m256i Vec4u64Reg;
|
||||
|
||||
#elif P_INTRINSICS != P_INTRINSICS_NEON
|
||||
|
||||
typedef struct alignas(32) Vec4x2i32Reg { int data[8]; } Vec4x2i32Reg;
|
||||
typedef struct alignas(32) Vec8i32Reg { int data[8]; } Vec8i32Reg;
|
||||
typedef struct alignas(32) Vec2x2i64Reg { Phanes::Core::Types::int64 data[4]; } Vec2x2i64Reg;
|
||||
typedef struct alignas(32) Vec4i64Reg { Phanes::Core::Types::int64 data[4]; } Vec4i64Reg;
|
||||
|
||||
typedef struct alignas(32) Vec4x2u32Reg { unsigned int data[8]; } Vec4x2u32Reg;
|
||||
typedef struct alignas(32) Vec8u32Reg { unsigned int data[8]; } Vec8u32Reg;
|
||||
typedef struct alignas(32) Vec2x2u64Reg { Phanes::Core::Types::uint64 data[4]; } Vec2x2u64Reg;
|
||||
typedef struct alignas(32) Vec4u64Reg { Phanes::Core::Types::uint64 data[4]; } Vec4u64Reg;
|
||||
|
||||
#endif
|
||||
|
||||
// NEON ...
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "PhanesVectorMathSSE.hpp" // Include previous
|
||||
|
||||
#include <immintrin.h>
|
||||
|
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#include "PhanesVectorMathAVX.hpp" // Include previous
|
74
Engine/Source/Runtime/Core/Math/SIMD/PhanesVectorMathFPU.hpp
Normal file
74
Engine/Source/Runtime/Core/Math/SIMD/PhanesVectorMathFPU.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/SIMD/PhanesSIMDTypes.h"
|
||||
#include "Core/public/Math/MathCommon.hpp"
|
||||
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
/// <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] = Abs(v.data[0]);
|
||||
}
|
||||
|
||||
/// <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] * v1.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] * v1.data[0] + v1.data[1] * v2.data[1] + v1.data[2] * v2.data[2] + v1.data[3] * v2.data[3];
|
||||
}
|
||||
|
||||
Phanes::Core::Types::Vec2f64Reg vec2_eq(const Phanes::Core::Types::Vec2f64Reg v1, const Phanes::Core::Types::Vec2f64Reg v2)
|
||||
{
|
||||
Phanes::Core::Types::Vec4f64Reg r;
|
||||
|
||||
r.data[0] = (Phanes::Core::Math::Abs(v1.data[0] - v2.data[0]) < P_FLT_INAC) ? 0xFFFFFFFF : 0;
|
||||
r.data[1] = (Phanes::Core::Math::Abs(v1.data[1] - v2.data[1]) < P_FLT_INAC) ? 0xFFFFFFFF : 0;
|
||||
}
|
||||
}
|
@@ -0,0 +1,2 @@
|
||||
#pragma once
|
||||
#error ARM architecture is not yet supported by PhanesEngine.
|
1508
Engine/Source/Runtime/Core/Math/SIMD/PhanesVectorMathSSE.hpp
Normal file
1508
Engine/Source/Runtime/Core/Math/SIMD/PhanesVectorMathSSE.hpp
Normal file
File diff suppressed because it is too large
Load Diff
330
Engine/Source/Runtime/Core/Math/SIMD/Platform.h
Normal file
330
Engine/Source/Runtime/Core/Math/SIMD/Platform.h
Normal file
@@ -0,0 +1,330 @@
|
||||
// Platform / Compiler detection.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Architecture MACRO
|
||||
// Implicitly asumes x86 architecture
|
||||
#ifndef P_ARM_ARCH
|
||||
# define P_x86_ARCH
|
||||
#else
|
||||
# ifdef P_x86_ARCH
|
||||
# undef P_x86_ARCH
|
||||
# endif
|
||||
# error ARM architecture not supported.
|
||||
#endif
|
||||
|
||||
// Set platform MACRO depending on defined build
|
||||
|
||||
#define P_PLATFORM_WIN 0
|
||||
#define P_PLATFORM_LIN 1
|
||||
#define P_PLATFORM_MAC 2
|
||||
// #define P_PLATFORM_FBSD 3 -> Is planed for eventual PS5 support
|
||||
|
||||
// User defines build platform
|
||||
#ifdef P_WIN_BUILD
|
||||
# define P_PLATFORM P_PLATFORM_WIN
|
||||
#elif P_LINUX_BUILD
|
||||
# define P_PLATFORM P_PLATFORM_LIN
|
||||
# error Linux / Unix system is not yet supported.
|
||||
#elif P_MAC_BUILD
|
||||
# define P_PLATFORM P_PLATFORM_MAC
|
||||
# error Mac target system is not yet supported.
|
||||
#elif P_PS5_BUILD || P_FBSD_BUILD
|
||||
# define P_PLATFORM P_PLATFORM_FBSD
|
||||
# error FreeBSD is not yet supported.
|
||||
#else
|
||||
# error Your target system is either not supported, or you have yet to define it.
|
||||
#endif
|
||||
|
||||
// Set compiler depending on defined compiler
|
||||
|
||||
// Compiler macro definition
|
||||
|
||||
// ID's defined like [0-9][0-x]
|
||||
// First bracket defines compiler, second defines the version of the compiler.
|
||||
|
||||
// Visual C++
|
||||
#define P_COMPILER_VC22 001
|
||||
#define P_COMPILER_VC19 002
|
||||
#define P_COMPILER_VC17 003
|
||||
#define P_COMPILER_VC15 004
|
||||
#define P_COMPILER_VC13 005
|
||||
#define P_COMPILER_VC12 006
|
||||
#define P_COMPILER_VC10 007
|
||||
#define P_COMPILER_VC08 008
|
||||
#define P_COMPILER_VC05 009
|
||||
#define P_COMPILER_VC03 010
|
||||
#define P_COMPILER_VC02 011
|
||||
#define P_COMPILER_VCSP 012
|
||||
|
||||
// Clang
|
||||
#define P_COMPILER_CLANG34 101
|
||||
#define P_COMPILER_CLANG35 102
|
||||
#define P_COMPILER_CLANG36 103
|
||||
#define P_COMPILER_CLANG37 104
|
||||
#define P_COMPILER_CLANG38 105
|
||||
#define P_COMPILER_CLANG39 106
|
||||
#define P_COMPILER_CLANG4 107
|
||||
#define P_COMPILER_CLANG5 108
|
||||
#define P_COMPILER_CLANG6 109
|
||||
#define P_COMPILER_CLANG7 110
|
||||
#define P_COMPILER_CLANG8 111
|
||||
#define P_COMPILER_CLANG9 112
|
||||
#define P_COMPILER_CLANG10 113
|
||||
#define P_COMPILER_CLANG11 114
|
||||
#define P_COMPILER_CLANG12 115
|
||||
#define P_COMPILER_CLANG13 116
|
||||
#define P_COMPILER_CLANG14 117
|
||||
#define P_COMPILER_CLANG15 118
|
||||
#define P_COMPILER_CLANG16 119
|
||||
#define P_COMPILER_CLANG17 120
|
||||
#define P_COMPILER_CLANG18 121
|
||||
#define P_COMPILER_CLANG19 122
|
||||
|
||||
|
||||
// G++
|
||||
#define P_COMPILER_GCC46 201
|
||||
#define P_COMPILER_GCC47 202
|
||||
#define P_COMPILER_GCC48 203
|
||||
#define P_COMPILER_GCC49 204
|
||||
#define P_COMPILER_GCC5 205
|
||||
#define P_COMPILER_GCC6 206
|
||||
#define P_COMPILER_GCC61 207
|
||||
#define P_COMPILER_GCC7 208
|
||||
#define P_COMPILER_GCC8 209
|
||||
#define P_COMPILER_GCC9 210
|
||||
#define P_COMPILER_GCC10 211
|
||||
#define P_COMPILER_GCC11 212
|
||||
#define P_COMPILER_GCC12 213
|
||||
#define P_COMPILER_GCC13 214
|
||||
#define P_COMPILER_GCC14 215
|
||||
|
||||
|
||||
// Intel C++
|
||||
#define P_COMPILER_INTEL14 301
|
||||
#define P_COMPILER_INTEL15 302
|
||||
#define P_COMPILER_INTEL16 303
|
||||
#define P_COMPILER_INTEL17 304
|
||||
#define P_COMPILER_INTEL18 305
|
||||
#define P_COMPILER_INTEL19 306
|
||||
#define P_COMPILER_INTEL21 307
|
||||
|
||||
// Visual studio
|
||||
#ifdef _MSC_VER
|
||||
# if _MSC_VER >= 1930
|
||||
# define P_COMPILER P_COMPILER_VC22
|
||||
# elif _MSC_VER >= 1920
|
||||
# define P_COMPILER P_COMPILER_VC19
|
||||
# elif _MSC_VER >= 1910
|
||||
# define P_COMPILER P_COMPILER_VC17
|
||||
# elif _MSC_VER >= 1900
|
||||
# define P_COMPILER P_COMPILER_VC15
|
||||
# elif _MSC_VER >= 1800
|
||||
# define P_COMPILER P_COMPILER_VC13
|
||||
# elif _MSC_VER >= 1700
|
||||
# define P_COMPILER P_COMPILER_VC12
|
||||
# elif _MSC_VER >= 1600
|
||||
# define P_COMPILER P_COMPILER_VC10
|
||||
# elif _MSC_VER >= 1500
|
||||
# define P_COMPILER P_COMPILER_VC08
|
||||
# elif _MSC_VER >= 1400
|
||||
# define P_COMPILER P_COMPILER_VC05
|
||||
# elif _MSC_VER >= 1310
|
||||
# define P_COMPILER P_COMPILER_VC03
|
||||
# elif _MSC_VER >= 1300
|
||||
# define P_COMPILER P_COMPILER_VC02
|
||||
# elif _MSC_VER >= 1200
|
||||
# define P_COMPILER P_COMPILER_VCSP
|
||||
# endif
|
||||
|
||||
|
||||
|
||||
// Clang
|
||||
|
||||
#elif (defined(__clang__))
|
||||
# error PhanesEngine only supports MSVC -> Visual Studio
|
||||
# if defined(__apple_build_version__)
|
||||
#
|
||||
# if (__clang_major__ < 6)
|
||||
# error "GLM requires Clang 3.4 / Apple Clang 6.0 or higher"
|
||||
# elif __clang_major__ == 6 && __clang_minor__ == 0
|
||||
# define P_COMPILER P_COMPILER_CLANG35
|
||||
# elif __clang_major__ == 6 && __clang_minor__ >= 1
|
||||
# define P_COMPILER P_COMPILER_CLANG36
|
||||
# elif __clang_major__ >= 7
|
||||
# define P_COMPILER P_COMPILER_CLANG37
|
||||
# endif
|
||||
# else
|
||||
# if ((__clang_major__ == 3) && (__clang_minor__ < 4)) || (__clang_major__ < 3)
|
||||
# error "GLM requires Clang 3.4 or higher"
|
||||
# elif __clang_major__ == 3 && __clang_minor__ == 4
|
||||
# define P_COMPILER P_COMPILER_CLANG34
|
||||
# elif __clang_major__ == 3 && __clang_minor__ == 5
|
||||
# define P_COMPILER P_COMPILER_CLANG35
|
||||
# elif __clang_major__ == 3 && __clang_minor__ == 6
|
||||
# define P_COMPILER P_COMPILER_CLANG36
|
||||
# elif __clang_major__ == 3 && __clang_minor__ == 7
|
||||
# define P_COMPILER P_COMPILER_CLANG37
|
||||
# elif __clang_major__ == 3 && __clang_minor__ == 8
|
||||
# define P_COMPILER P_COMPILER_CLANG38
|
||||
# elif __clang_major__ == 3 && __clang_minor__ >= 9
|
||||
# define P_COMPILER P_COMPILER_CLANG39
|
||||
# elif __clang_major__ == 4 && __clang_minor__ == 0
|
||||
# define P_COMPILER P_COMPILER_CLANG4
|
||||
# elif __clang_major__ == 5
|
||||
# define P_COMPILER P_COMPILER_CLANG5
|
||||
# elif __clang_major__ == 6
|
||||
# define P_COMPILER P_COMPILER_CLANG6
|
||||
# elif __clang_major__ == 7
|
||||
# define P_COMPILER P_COMPILER_CLANG7
|
||||
# elif __clang_major__ == 8
|
||||
# define P_COMPILER P_COMPILER_CLANG8
|
||||
# elif __clang_major__ == 9
|
||||
# define P_COMPILER P_COMPILER_CLANG9
|
||||
# elif __clang_major__ == 10
|
||||
# define P_COMPILER P_COMPILER_CLANG10
|
||||
# elif __clang_major__ == 11
|
||||
# define P_COMPILER P_COMPILER_CLANG11
|
||||
# elif __clang_major__ == 12
|
||||
# define P_COMPILER P_COMPILER_CLANG12
|
||||
# elif __clang_major__ == 13
|
||||
# define P_COMPILER P_COMPILER_CLANG13
|
||||
# elif __clang_major__ == 14
|
||||
# define P_COMPILER P_COMPILER_CLANG14
|
||||
# elif __clang_major__ == 15
|
||||
# define P_COMPILER P_COMPILER_CLANG15
|
||||
# elif __clang_major__ == 16
|
||||
# define P_COMPILER P_COMPILER_CLANG16
|
||||
# elif __clang_major__ == 17
|
||||
# define P_COMPILER P_COMPILER_CLANG17
|
||||
# elif __clang_major__ == 18
|
||||
# define P_COMPILER P_COMPILER_CLANG18
|
||||
# elif __clang_major__ >= 19
|
||||
# define P_COMPILER P_COMPILER_CLANG19
|
||||
# endif
|
||||
# endif
|
||||
|
||||
|
||||
|
||||
// G++
|
||||
#elif defined(__GNUC__) || defined(__MINGW32__)
|
||||
# error PhanesEngine only supports MSVC -> Visual Studio
|
||||
# if __GNUC__ >= 14
|
||||
# define P_COMPILER P_COMPILER_GCC14
|
||||
# elif __GNUC__ >= 13
|
||||
# define P_COMPILER P_COMPILER_GCC13
|
||||
# elif __GNUC__ >= 12
|
||||
# define P_COMPILER P_COMPILER_GCC12
|
||||
# elif __GNUC__ >= 11
|
||||
# define P_COMPILER P_COMPILER_GCC11
|
||||
# elif __GNUC__ >= 10
|
||||
# define P_COMPILER P_COMPILER_GCC10
|
||||
# elif __GNUC__ >= 9
|
||||
# define P_COMPILER P_COMPILER_GCC9
|
||||
# elif __GNUC__ >= 8
|
||||
# define P_COMPILER P_COMPILER_GCC8
|
||||
# elif __GNUC__ >= 7
|
||||
# define P_COMPILER P_COMPILER_GCC7
|
||||
# elif __GNUC__ >= 6
|
||||
# define P_COMPILER P_COMPILER_GCC6
|
||||
# elif __GNUC__ >= 5
|
||||
# define P_COMPILER P_COMPILER_GCC5
|
||||
# elif __GNUC__ == 4 && __GNUC_MINOR__ >= 9
|
||||
# define P_COMPILER P_COMPILER_GCC49
|
||||
# elif __GNUC__ == 4 && __GNUC_MINOR__ >= 8
|
||||
# define P_COMPILER P_COMPILER_GCC48
|
||||
# elif __GNUC__ == 4 && __GNUC_MINOR__ >= 7
|
||||
# define P_COMPILER P_COMPILER_GCC47
|
||||
# elif __GNUC__ == 4 && __GNUC_MINOR__ >= 6
|
||||
# define P_COMPILER P_COMPILER_GCC46
|
||||
# elif ((__GNUC__ == 4) && (__GNUC_MINOR__ < 6)) || (__GNUC__ < 4)
|
||||
# error PhanesEngine does not support your compiler.
|
||||
# endif
|
||||
|
||||
#elif defined(__CUDACC__)
|
||||
# error CUDA C++ is not supported by PhanesEngine
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
// Vector instruction sets
|
||||
|
||||
|
||||
// Define also supported instruction sets for Visual Studio, as it only defines the latest (e.g. only __AVX__ not __SSE4__ ...).
|
||||
|
||||
#ifdef P_FORCE_INTRINSICS
|
||||
|
||||
# undef __AVX2__
|
||||
# undef __AVX__
|
||||
# undef __SSE__
|
||||
|
||||
# ifndef P_INTRINSICS
|
||||
# error P_INTRINSICS must be defined by the user, when P_FORCE_INTRINSICS is used.
|
||||
# endif
|
||||
|
||||
#elif !defined(P_FORCE_FPU)
|
||||
# ifdef __AVX2__
|
||||
# define P_AVX2__ 1
|
||||
# elif defined(__AVX__)
|
||||
# define P_AVX__ 1
|
||||
# elif defined(__SSE__)
|
||||
# define P_SSE__ 1
|
||||
# endif
|
||||
|
||||
#endif // !P_FORCE_INTRINSICS
|
||||
|
||||
#ifdef P_AVX2__
|
||||
# define P_AVX__ 1
|
||||
#endif
|
||||
|
||||
#ifdef P_AVX__
|
||||
# define P_SSE__ 1
|
||||
#endif
|
||||
|
||||
// Deactivate unset SIMD
|
||||
#ifndef P_AVX2__
|
||||
# define P_AVX2__ 0
|
||||
#endif
|
||||
|
||||
// Deactivate unset SIMD
|
||||
#ifndef P_AVX__
|
||||
# define P_AVX__ 0
|
||||
#endif
|
||||
|
||||
#ifndef P_SSE__
|
||||
# define P_SSE__ 0
|
||||
#endif
|
||||
|
||||
#ifndef P_NEON__
|
||||
# define P_NEON__ 0
|
||||
#endif
|
||||
|
||||
#define P_INTRINSICS_FPU 0
|
||||
#define P_INTRINSICS_SSE 1
|
||||
#define P_INTRINSICS_AVX 2
|
||||
#define P_INTRINSICS_AVX2 3
|
||||
#define P_INTRINSICS_NEON 4
|
||||
|
||||
|
||||
#if defined(P_FORCE_FPU) // Force, that no intrinsics may be used.
|
||||
# define P_INTRINSICS P_INTRINSICS_FPU
|
||||
# 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
|
||||
# elif P_AVX2__ == 1
|
||||
# define P_INTRINSICS P_INTRINSICS_AVX2
|
||||
# elif P_SSE__ == 1
|
||||
# define P_INTRINSICS P_INTRINSICS_SSE
|
||||
# elif defined(P_ARM_ARCH)
|
||||
# define P_INTRINSICS P_INTRINSICS_NEON
|
||||
# define P_NEON__ 1
|
||||
# elif !defined(P_FORCE_INTRINSICS)
|
||||
# error No SIMD instruction set detected. Use P_FORCE_FPU to disable SIMD extensions.
|
||||
# endif
|
||||
#endif
|
15
Engine/Source/Runtime/Core/Math/SIMD/SIMDIntrinsics.h
Normal file
15
Engine/Source/Runtime/Core/Math/SIMD/SIMDIntrinsics.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Core/public/Math/SIMD/Platform.h"
|
||||
|
||||
#if P_INTRINSICS == P_INTRINSICS_AVX2
|
||||
# include "PhanesVectorMathAVX2.hpp"
|
||||
#elif P_INTRINSICS == P_INTRINSICS_AVX
|
||||
# include "PhanesVectorMathAVX.hpp"
|
||||
#elif P_INTRINSICS == P_INTRINSICS_SSE
|
||||
# include "PhanesVectorMathSSE.hpp"
|
||||
#elif P_INTRINSICS == P_INTRINSICS_NEON
|
||||
# include "PhanesVectorMathNeon.hpp"
|
||||
#endif
|
||||
|
140
Engine/Source/Runtime/Core/Math/SIMD/Storage.h
Normal file
140
Engine/Source/Runtime/Core/Math/SIMD/Storage.h
Normal file
@@ -0,0 +1,140 @@
|
||||
// Defines on compile time, whether a xmm register or an array should be used.
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/SIMD/PhanesSIMDTypes.h"
|
||||
|
||||
#include "Core/public/Math/MathTypes.h"
|
||||
|
||||
namespace Phanes::Core::Math::SIMD
|
||||
{
|
||||
template<size_t L, typename T, bool UseSimd>
|
||||
struct Storage;
|
||||
|
||||
// General unaligned memory storage
|
||||
template<size_t L, typename T>
|
||||
struct Storage<L, T, false>
|
||||
{
|
||||
typedef T type[4];
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct Storage<3, T, false>
|
||||
{
|
||||
typedef T type[4];
|
||||
};
|
||||
|
||||
|
||||
// SSE4.2
|
||||
|
||||
template<>
|
||||
struct Storage<4, float, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec4f32Reg type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Storage<3, float, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec4f32Reg type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Storage<4, int, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec4i32Reg type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Storage<3, int, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec4i32Reg type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Storage<4, unsigned int, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec4u32Reg type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Storage<3, unsigned int, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec4u32Reg type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Storage<2, double, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec2f64Reg type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Storage<2, Phanes::Core::Types::int64, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec2i64Reg type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Storage<2, Phanes::Core::Types::uint64, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec2u64Reg type;
|
||||
};
|
||||
|
||||
|
||||
// AVX
|
||||
template<>
|
||||
struct Storage<4, double, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec4f64Reg type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Storage<3, double, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec4f64Reg type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Storage<8, float, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec4x2f32Reg type;
|
||||
};
|
||||
|
||||
|
||||
// AVX2
|
||||
template<>
|
||||
struct Storage<4, Phanes::Core::Types::int64, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec4i64Reg type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Storage<3, Phanes::Core::Types::int64, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec4i64Reg type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Storage<4, Phanes::Core::Types::uint64, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec4u64Reg type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Storage<3, Phanes::Core::Types::uint64, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec4u64Reg type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Storage<8, int, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec4x2i32Reg type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Storage<8, unsigned int, true>
|
||||
{
|
||||
typedef Phanes::Core::Types::Vec4x2u32Reg type;
|
||||
};
|
||||
}
|
1019
Engine/Source/Runtime/Core/Math/Vector2.hpp
Normal file
1019
Engine/Source/Runtime/Core/Math/Vector2.hpp
Normal file
File diff suppressed because it is too large
Load Diff
281
Engine/Source/Runtime/Core/Math/Vector2.inl
Normal file
281
Engine/Source/Runtime/Core/Math/Vector2.inl
Normal file
@@ -0,0 +1,281 @@
|
||||
/**
|
||||
* Contains functions, that have separate simd equivalents.
|
||||
*/
|
||||
|
||||
#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 S>
|
||||
TVector2<T, S>::TVector2(const TVector2<Real, S>& v)
|
||||
{
|
||||
Detail::construct_vec2<T, S>::map(*this, v);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>::TVector2(Real _x, Real _y)
|
||||
{
|
||||
Detail::construct_vec2<T, S>::map(*this, _x, _y);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>::TVector2(Real s)
|
||||
{
|
||||
Detail::construct_vec2<T, S>::map(*this, s);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>::TVector2(const Real* comp)
|
||||
{
|
||||
Detail::construct_vec2<T, S>::map(*this, comp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>& operator+=(TVector2<T, S>& v1, const TVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec2_add<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>& operator+=(TVector2<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_vec2_add<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>& operator-=(TVector2<T, S>& v1, const TVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec2_sub<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>& operator-=(TVector2<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_vec2_sub<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>& operator*=(TVector2<T, S>& v1, const TVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec2_mul<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>& operator*=(TVector2<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_vec2_mul<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>& operator/=(TVector2<T, S>& v1, const TVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec2_div<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>& operator/=(TVector2<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_vec2_div<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S> operator+(const TVector2<T, S>& v1, const TVector2<T, S>& v2)
|
||||
{
|
||||
TVector2<T, S> r;
|
||||
Detail::compute_vec2_add<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S> operator+(const TVector2<T, S>& v1, T s)
|
||||
{
|
||||
TVector2<T, S> r;
|
||||
Detail::compute_vec2_add<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S> operator-(const TVector2<T, S>& v1, const TVector2<T, S>& v2)
|
||||
{
|
||||
TVector2<T, S> r;
|
||||
Detail::compute_vec2_sub<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S> operator-(const TVector2<T, S>& v1, T s)
|
||||
{
|
||||
TVector2<T, S> r;
|
||||
Detail::compute_vec2_sub<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S> operator*(const TVector2<T, S>& v1, const TVector2<T, S>& v2)
|
||||
{
|
||||
TVector2<T, S> r;
|
||||
Detail::compute_vec2_mul<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S> operator*(const TVector2<T, S>& v1, T s)
|
||||
{
|
||||
TVector2<T, S> r;
|
||||
Detail::compute_vec2_mul<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S> operator/(const TVector2<T, S>& v1, const TVector2<T, S>& v2)
|
||||
{
|
||||
TVector2<T, S> r;
|
||||
Detail::compute_vec2_div<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S> operator/(const TVector2<T, S>& v1, T s)
|
||||
{
|
||||
TVector2<T, S> r;
|
||||
Detail::compute_vec2_div<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S> operator/(T s, const TVector2<T, S>& v1)
|
||||
{
|
||||
TVector2<T, S> r;
|
||||
Detail::compute_vec2_div<T, S>::map(r, s, v1);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S> operator-(T s, const TVector2<T, S>& v1)
|
||||
{
|
||||
TVector2<T, S> r;
|
||||
Detail::compute_vec2_sub<T, S>::map(r, s, v1);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Comparision
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool operator==(const TVector2<T, S>& v1, const TVector2<T, S>& v2)
|
||||
{
|
||||
return Detail::compute_vec2_eq<T, S>::map(v1, v2);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool operator!=(const TVector2<T, S>& v1, const TVector2<T, S>& v2)
|
||||
{
|
||||
return Detail::compute_vec2_ieq<T, S>::map(v1, v2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Inc- / Decrement
|
||||
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>& operator++(TVector2<T, S>& v1)
|
||||
{
|
||||
Detail::compute_vec2_inc<T, S>::map(v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>& operator--(TVector2<T, S>& v1)
|
||||
{
|
||||
Detail::compute_vec2_inc<T, S>::map(v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>& operator++(TVector2<T, S>& v1, int)
|
||||
{
|
||||
return ++v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>& operator--(TVector2<T, S>& v1, int)
|
||||
{
|
||||
return --v1;
|
||||
}
|
||||
|
||||
|
||||
template<RealType T, bool S>
|
||||
T Magnitude(const TVector2<T, S>& v1)
|
||||
{
|
||||
return Detail::compute_vec2_mag<T, S>::map(v1);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
T SqrMagnitude(const TVector2<T, S>& v1)
|
||||
{
|
||||
return Detail::compute_vec2_dotp<T, S>::map(v1, v1);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
inline T DotP(const TVector2<T, S>& v1, const TVector2<T, S>& v2)
|
||||
{
|
||||
return Detail::compute_vec2_dotp<T, S>::map(v1, v2);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>& MaxV(TVector2<T, S>& v1, const TVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec2_max<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S> Max(const TVector2<T, S>& v1, const TVector2<T, S>& v2)
|
||||
{
|
||||
TVector2<T, S> r;
|
||||
Detail::compute_vec2_max<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>& MinV(TVector2<T, S>& v1, const TVector2<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec2_min<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S> Min(const TVector2<T, S>& v1, const TVector2<T, S>& v2)
|
||||
{
|
||||
TVector2<T, S> r;
|
||||
Detail::compute_vec2_min<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector2<T, S>& Set(TVector2<T, S>& v1, T x, T y)
|
||||
{
|
||||
Detail::compute_vec2_set<T, S>::map(v1, x, y);
|
||||
return v1;
|
||||
}
|
||||
}
|
1182
Engine/Source/Runtime/Core/Math/Vector3.hpp
Normal file
1182
Engine/Source/Runtime/Core/Math/Vector3.hpp
Normal file
File diff suppressed because it is too large
Load Diff
308
Engine/Source/Runtime/Core/Math/Vector3.inl
Normal file
308
Engine/Source/Runtime/Core/Math/Vector3.inl
Normal file
@@ -0,0 +1,308 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/Detail/Vector3Decl.inl"
|
||||
#include "Core/public/Math/SIMD/SIMDIntrinsics.h"
|
||||
|
||||
#include "Core/public/Math/SIMD/PhanesSIMDTypes.h"
|
||||
|
||||
|
||||
|
||||
namespace Phanes::Core::Math
|
||||
{
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>::TVector3(Real _x, Real _y, Real _z)
|
||||
{
|
||||
Detail::construct_vec3<T, S>::map(*this, _x, _y, _z);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>::TVector3(Real s)
|
||||
{
|
||||
Detail::construct_vec3<T, S>::map(*this, s);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>::TVector3(const TVector2<Real, S>& v1, Real s)
|
||||
{
|
||||
Detail::construct_vec3<T, S>::map(*this, v1, s);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>::TVector3(const Real* comp)
|
||||
{
|
||||
static_assert(sizeof(comp) >= sizeof(T) * 3, "Size of comp has to be of at least three (3) components.");
|
||||
Detail::construct_vec3<T, S>::map(*this, comp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& operator+=(TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec3_add<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& operator+=(TVector3<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_vec3_add<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& operator-=(TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec3_sub<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& operator-=(TVector3<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_vec3_sub<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& operator*=(TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec3_mul<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& operator*=(TVector3<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_vec3_mul<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& operator/=(TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec3_div<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& operator/=(TVector3<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_vec3_div<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> operator+(const TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
TVector3<T, S> r;
|
||||
Detail::compute_vec3_add<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> operator+(const TVector3<T, S>& v1, T s)
|
||||
{
|
||||
TVector3<T, S> r;
|
||||
Detail::compute_vec3_add<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> operator-(const TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
TVector3<T, S> r;
|
||||
Detail::compute_vec3_sub<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> operator-(const TVector3<T, S>& v1, T s)
|
||||
{
|
||||
TVector3<T, S> r;
|
||||
Detail::compute_vec3_sub<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> operator-(T s, const TVector3<T, S>& v1)
|
||||
{
|
||||
TVector3<T, S> r;
|
||||
Detail::compute_vec3_sub<T, S>::map(r, s, v1);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> operator*(const TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
TVector3<T, S> r;
|
||||
Detail::compute_vec3_mul<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> operator*(const TVector3<T, S>& v1, T s)
|
||||
{
|
||||
TVector3<T, S> r;
|
||||
Detail::compute_vec3_mul<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> operator/(const TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
TVector3<T, S> r;
|
||||
Detail::compute_vec3_div<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> operator/(const TVector3<T, S>& v1, T s)
|
||||
{
|
||||
TVector3<T, S> r;
|
||||
Detail::compute_vec3_div<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> operator/(T s, const TVector3<T, S>& v1)
|
||||
{
|
||||
TVector3<T, S> r;
|
||||
Detail::compute_vec3_div<T, S>::map(r, s, v1);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Comparision
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool operator==(const TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
return Detail::compute_vec3_eq<T, S>::map(v1, v2);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool operator!=(const TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
return Detail::compute_vec3_ieq<T, S>::map(v1, v2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Inc- / Decrement
|
||||
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& operator++(TVector3<T, S>& v1)
|
||||
{
|
||||
Detail::compute_vec3_inc<T, S>::map(v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& operator--(TVector3<T, S>& v1)
|
||||
{
|
||||
Detail::compute_vec3_inc<T, S>::map(v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& operator++(TVector3<T, S>& v1, int)
|
||||
{
|
||||
return ++v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& operator--(TVector3<T, S>& v1, int)
|
||||
{
|
||||
return --v1;
|
||||
}
|
||||
|
||||
|
||||
// Other
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> CrossP(const TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
TVector3<T, S> r;
|
||||
Detail::compute_vec3_cross_p<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& CrossPV(TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec3_cross_p<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
inline T Magnitude(const TVector3<T, S>& v1)
|
||||
{
|
||||
return Detail::compute_vec3_mag<T, S>::map(v1);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
inline T SqrMagnitude(const TVector3<T, S>& v1)
|
||||
{
|
||||
return Detail::compute_vec3_dotp<T, S>::map(v1, v1);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
inline T DotP(const TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
return Detail::compute_vec3_dotp<T, S>::map(v1, v2);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& MaxV(TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec3_max<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> Max(TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
TVector3<T, S> r;
|
||||
Detail::compute_vec3_max<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& MinV(TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec3_min<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> Min(TVector3<T, S>& v1, const TVector3<T, S>& v2)
|
||||
{
|
||||
TVector3<T, S> r;
|
||||
Detail::compute_vec3_min<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& Set(TVector3<T, S>& v1, T x, T y, T z)
|
||||
{
|
||||
Detail::compute_vec3_set<T, S>::map(v1, x, y, z);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S>& ClampToCubeV(TVector3<T, S> v1, T cubeRadius)
|
||||
{
|
||||
Detail::compute_vec3_clamp<T, S>::map(v1, v1, cubeRadius);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector3<T, S> ClampToCube(const TVector3<T, S>& v1, T cubeRadius)
|
||||
{
|
||||
TVector3<T, S> r;
|
||||
Detail::compute_vec3_clamp<T, S>::map(r, v1, cubeRadius);
|
||||
return r;
|
||||
}
|
||||
}
|
867
Engine/Source/Runtime/Core/Math/Vector4.hpp
Normal file
867
Engine/Source/Runtime/Core/Math/Vector4.hpp
Normal file
@@ -0,0 +1,867 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
#include "Core/public/Math/MathCommon.hpp"
|
||||
#include "Core/public/Math/SIMD/Storage.h"
|
||||
#include "Core/public/Math/MathFwd.h"
|
||||
|
||||
|
||||
#include "Core/public/Math/Vector2.hpp"
|
||||
#include "Core/public/Math/Vector3.hpp"
|
||||
|
||||
#define PZeroVector4(type, aligned) Phanes::Core::Math::TVector4<##type, ##aligned>(0,0,0,0)
|
||||
|
||||
namespace Phanes::Core::Math
|
||||
{
|
||||
|
||||
/// 4D Vector defined with x, y, z, w.
|
||||
/// Alignment allows for possible simd optimization.
|
||||
template<RealType T, bool S = false>
|
||||
struct TVector4
|
||||
{
|
||||
|
||||
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, 4, S>::value>::type comp;
|
||||
typename SIMD::Storage<4, Real, SIMD::use_simd<T, 4, S>::value>::type data;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
public:
|
||||
/// Default constructor
|
||||
TVector4() = default;
|
||||
|
||||
/// <summary>
|
||||
/// Construct vector from one scalar.
|
||||
/// <para>x,y,z,w = s</para>
|
||||
/// </summary>
|
||||
/// <param name="s">Scalar</param>
|
||||
TVector4(Real s);
|
||||
|
||||
/// <summary>
|
||||
/// Construct vector from x, y, z, w components.
|
||||
/// </summary>
|
||||
/// <param name="_x">X component</param>
|
||||
/// <param name="_y">Y component</param>
|
||||
/// <param name="_z">Z component</param>
|
||||
/// <param name="_w">W component</param>
|
||||
TVector4(Real _x, Real _y, Real _z, Real _w);
|
||||
|
||||
/// <summary>
|
||||
/// Construct vector from two 2d vectors like:
|
||||
/// <para>x, y = v1.x, v1.y</para>
|
||||
/// z, w = v2.x, v2.y
|
||||
/// </summary>
|
||||
/// <param name="v1">TVector2 one</param>
|
||||
/// <param name="v2">TVector2 two</param>
|
||||
TVector4(const TVector2<Real, S>& v1, const TVector2<Real, S>& v2);
|
||||
|
||||
/// <summary>
|
||||
/// Construct vector from 3d vector (x,y,z) and w
|
||||
/// </summary>
|
||||
/// <param name="v1">TVector3</param>
|
||||
/// <param name="w">W</param>
|
||||
TVector4(const TVector3<Real, S>& v1, Real w);
|
||||
|
||||
/// <summary>
|
||||
/// Construct vector from array of components
|
||||
/// </summary>
|
||||
/// <param name="comp">Array of at least 4 components</param>
|
||||
TVector4(const Real* comp);
|
||||
|
||||
};
|
||||
|
||||
// ===================== //
|
||||
// Vector4 operators //
|
||||
// ===================== //
|
||||
|
||||
// Unary arithmetic operators
|
||||
|
||||
/// <summary>
|
||||
/// Vector addition.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator+= (TVector4<T, S>& v1, const TVector4<T, S>& v2);
|
||||
|
||||
/// <summary>
|
||||
/// Vector - scalar addition.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="s">Scalar</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator+= (TVector4<T, S>& v1, T s);
|
||||
|
||||
/// <summary>
|
||||
/// Vector substraction.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator-= (TVector4<T, S>& v1, const TVector4<T, S>& v2);
|
||||
|
||||
/// <summary>
|
||||
/// Vector - scalar substraction.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="s">Scalar</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator-= (TVector4<T, S>& v1, T s);
|
||||
|
||||
/// <summary>
|
||||
/// Vector - scalar multiplication.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="s">Scalar</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator*= (TVector4<T, S>& v1, T s);
|
||||
|
||||
/// <summary>
|
||||
/// Scale vector by another vector componentwise.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator*= (TVector4<T, S>& v1, const TVector4<T, S>& v2);
|
||||
|
||||
/// <summary>
|
||||
/// Vector - scalar division.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="s">Scalar</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator/= (TVector4<T, S>& v1, T s);
|
||||
|
||||
/// <summary>
|
||||
/// Coponentwise vector division.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator/= (TVector4<T, S>& v1, const TVector4<T, S>& v2);
|
||||
|
||||
|
||||
|
||||
// Unary arithmetic operators
|
||||
|
||||
/// <summary>
|
||||
/// Vector addition.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Computed vector.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator+ (const TVector4<T, S>& v1, const TVector4<T, S>& v2);
|
||||
|
||||
/// <summary>
|
||||
/// Vector - scalar addition.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="s">Scalar</param>
|
||||
/// <returns>Computed vector.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator+ (const TVector4<T, S>& v1, T s);
|
||||
|
||||
/// <summary>
|
||||
/// Vector substraction.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Computed vector.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator- (const TVector4<T, S>& v1, const TVector4<T, S>& v2);
|
||||
|
||||
/// <summary>
|
||||
/// Vector - scalar substraction.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="s">Scalar</param>
|
||||
/// <returns>Computed vector.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator- (const TVector4<T, S>& v1, T s);
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator- (T s, const TVector4<T, S>& v1);
|
||||
|
||||
/// <summary>
|
||||
/// Vector - scalar multiplication.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="s">Scalar</param>
|
||||
/// <returns>Computed vector.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator* (const TVector4<T, S>& v1, T s);
|
||||
|
||||
template<RealType T, bool S>
|
||||
FORCEINLINE TVector4<T, S> operator* (T s, const TVector4<T, S>& v1) { return v1 * s; };
|
||||
|
||||
/// <summary>
|
||||
/// Scale vector by another vector componentwise.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Computed vector.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator* (const TVector4<T, S>& v1, const TVector4<T, S>& v2);
|
||||
|
||||
/// <summary>
|
||||
/// Vector - scalar division.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="s">Scalar</param>
|
||||
/// <returns>Computed vector.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator/ (const TVector4<T, S>& v1, T s);
|
||||
|
||||
template<RealType T, bool S>
|
||||
FORCEINLINE TVector4<T, S> operator/ (T s, const TVector4<T, S>& v1);
|
||||
|
||||
/// <summary>
|
||||
/// Componentwise vector division.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Computed vector.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator/ (const TVector4<T, S>& v1, const TVector4<T, S>& v2);
|
||||
|
||||
|
||||
|
||||
// Comparison operators
|
||||
|
||||
/// <summary>
|
||||
/// Test to vectors for equality.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns><code>True</code>, if equal and <code>false</code> if not.</returns>
|
||||
template<RealType T, bool S>
|
||||
bool operator==(const TVector4<T, S>& v1, const TVector4<T, S>& v2);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test to vectors for inequality.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns><code>True</code>, if inequal and <code>false</code> if equal.</returns>
|
||||
template<RealType T, bool S>
|
||||
bool operator!=(const TVector4<T, S>& v1, const TVector4<T, S>& v2);
|
||||
|
||||
|
||||
|
||||
|
||||
// Unaray increment operators
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Increment vector by one
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator++(TVector4<T, S>& v1);
|
||||
|
||||
/// <summary>
|
||||
/// Decrement vector by one
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>v1</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator--(TVector4<T, S>& v1);
|
||||
|
||||
/// <summary>
|
||||
/// Increment vector by one
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>v1</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator++(TVector4<T, S>& v1, int);
|
||||
|
||||
/// <summary>
|
||||
/// Decrement vector by one
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator--(TVector4<T, S>& v1, int);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ====================== //
|
||||
// TVector4 functions //
|
||||
// ====================== //
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& Set(TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
v1 = v2;
|
||||
return v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set vector to values.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="x">X Component</param>
|
||||
/// <param name="y">Y Component</param>
|
||||
/// <param name="z">Z Component</param>
|
||||
/// <param name="w">W Component</param>
|
||||
/// <returns></returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& Set(TVector4<T, S>& v1, T x, T y, T z, T w);
|
||||
|
||||
/// <summary>
|
||||
/// Get magnitude of vector.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v">Vector</param>
|
||||
/// <returns>Magnitude of vector.</returns>
|
||||
template<RealType T, bool S>
|
||||
T Magnitude(const TVector4<T, S>& v);
|
||||
|
||||
/// <summary>
|
||||
/// Get square of magnitude of vector.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v">Vector</param>
|
||||
/// <returns>Square of magnitude of vector.</returns>
|
||||
template<RealType T, bool S>
|
||||
T SqrMagnitude(const TVector4<T, S>& v);
|
||||
|
||||
/// <summary>
|
||||
/// Get magnitude of vector.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v">Vector</param>
|
||||
/// <returns>Magnitude of vector.</returns>
|
||||
template<RealType T, bool S>
|
||||
constexpr T Length(const TVector4<T, S>& v) { return Magnitude(v); }
|
||||
|
||||
/// <summary>
|
||||
/// Get square of magnitude of vector.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v">Vector</param>
|
||||
/// <returns>Square of magnitude of vector.</returns>
|
||||
template<RealType T, bool S>
|
||||
constexpr T SqrLength(const TVector4<T, S>& v) { return SqrMagnitude(v); }
|
||||
|
||||
/// <summary>
|
||||
/// Angle between two vectors.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns></returns>
|
||||
template<RealType T, bool S>
|
||||
T Angle(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
return acos(DotP(v1, v2) / (Magnitude(v1) * Magnitude(v2)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cosine of angle between two vectors.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns></returns>
|
||||
template<RealType T, bool S>
|
||||
T CosineAngle(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
return DotP(v1, v2) / (Magnitude(v1) * Magnitude(v2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes a vector.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>Normalized vector</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> Normalize(const TVector4<T, S>& v1)
|
||||
{
|
||||
T vecNorm = Magnitude(v1);
|
||||
|
||||
vecNorm = (vecNorm < P_FLT_INAC) ? (T)1.0 : vecNorm;
|
||||
|
||||
return (v1 / vecNorm);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes a vector.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& NormalizeV(TVector4<T, S>& v1)
|
||||
{
|
||||
T vecNorm = Magnitude(v1);
|
||||
|
||||
vecNorm = (vecNorm < P_FLT_INAC) ? (T)1.0 : vecNorm;
|
||||
|
||||
v1 /= vecNorm;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes a vector.
|
||||
/// </summary>
|
||||
/// <remarks>Doesn't check for zero vector.</remarks>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>Normalized vector</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> UnsafeNormalize(const TVector4<T, S>& v1)
|
||||
{
|
||||
return v1 / Magnitude(v1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes a vector.
|
||||
/// </summary>
|
||||
/// <remarks>Doesn't check for zero vector.</remarks>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& UnsafeNormalizeV(TVector4<T, S>& v1)
|
||||
{
|
||||
v1 /= Magnitude(v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the dot product between two vectors.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Dot product between vectors.</returns>
|
||||
template<RealType T, bool S>
|
||||
T DotP(const TVector4<T, S>& v1, const TVector4<T, S>& v2);
|
||||
|
||||
/// <summary>
|
||||
/// Gets componentwise max of both vectors.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Vector with componentwise max of both vectors.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> Max(const TVector4<T, S>& v1, const TVector4<T, S>& v2);
|
||||
|
||||
/// <summary>
|
||||
/// Gets componentwise max of both vectors.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& MaxV(TVector4<T, S>& v1, const TVector4<T, S>& v2);
|
||||
|
||||
/// <summary>
|
||||
/// Gets componentwise min of both vectors.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Vector with componentwise max of both vectors.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> Min(const TVector4<T, S>& v1, const TVector4<T, S>& v2);
|
||||
|
||||
/// <summary>
|
||||
/// Gets componentwise min of both vectors.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector one</param>
|
||||
/// <param name="v2">Vector two</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& MinV(TVector4<T, S>& v1, const TVector4<T, S>& v2);
|
||||
|
||||
/// <summary>
|
||||
/// Inverses vector.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>Inverted vector</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> Negate(const TVector4<T, S>& v1)
|
||||
{
|
||||
return (T)0.0 - v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inverses vector.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& NegateV(TVector4<T, S>& v1)
|
||||
{
|
||||
return (v1 = (T)0.0 - v1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inverses the components of vector.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>Vector with reciprocal of components.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> CompInverse(const TVector4<T, S>& v1)
|
||||
{
|
||||
return (T)1.0 / v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inverses the components of vector.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& CompInverseV(TVector4<T, S>& v1)
|
||||
{
|
||||
return (v1 = (T)1.0 / v1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clamp the vectors length to a magnitude.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1"></param>
|
||||
/// <param name="s"></param>
|
||||
/// <returns>Vector with magnitude clamped to s.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> ClampToMagnitude(const TVector4<T, S>& v1, T min, T max)
|
||||
{
|
||||
T magnitude = Magnitude(v1);
|
||||
|
||||
TVector4<T, S> unitVec;
|
||||
unitVec = (magnitude > P_FLT_INAC) ? v1 / magnitude : PZeroVector4(T, false);
|
||||
|
||||
magnitude = Clamp(magnitude, min, max);
|
||||
|
||||
return unitVec * magnitude;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clamp the vectors length to a magnitude.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="s">Magnitude</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& ClampToMagnitudeV(TVector4<T, S>& v1, T min, T max)
|
||||
{
|
||||
T magnitude = Magnitude(v1);
|
||||
|
||||
v1 = (magnitude > P_FLT_INAC) ? v1 / magnitude : PZeroVector4(T, false);
|
||||
|
||||
v1 *= Clamp(magnitude, min, max);
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale vector to a magnitude
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="s">Magnitude</param>
|
||||
/// <returns>Vector with scaled magnitude.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> ScaleToMagnitude(const TVector4<T, S>& v1, T s)
|
||||
{
|
||||
return Normalize(v1) * s;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale vector to a magnitude
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="s">Magnitude</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& ScaleToMagnitudeV(TVector4<T, S>& v1, T s)
|
||||
{
|
||||
NormalizeV(v1);
|
||||
v1 *= s;
|
||||
return v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reflect vector on plane.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="normal">Planes normal</param>
|
||||
/// <returns>Reflected vector</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> Reflect(const TVector4<T, S>& v1, const TVector4<T, S> normal)
|
||||
{
|
||||
return ((T)2.0 * DotP(v1, normal) * normal) - v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reflect vector on plane.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="normal">Planes normal</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& ReflectV(TVector4<T, S>& v1, const TVector4<T, S> normal)
|
||||
{
|
||||
v1 = ((T)2.0 * DotP(v1, normal) * normal) - v1;
|
||||
return v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Project vector v1 onto v2.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector to project</param>
|
||||
/// <param name="v2">Vector to project on</param>
|
||||
/// <returns>Projected vector.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> Project(const TVector4<T, S>& v1, const TVector4<T, S> v2)
|
||||
{
|
||||
return (DotP(v1, v2) / DotP(v2, v2)) * v2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Project vector v1 onto v2.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector to project</param>
|
||||
/// <param name="v2">Vector to project on</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& ProjectV(TVector4<T, S>& v1, const TVector4<T, S> v2)
|
||||
{
|
||||
v1 = (DotP(v1, v2) / DotP(v2, v2)) * v2;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reject vector v1 from v2.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector to reject</param>
|
||||
/// <param name="v2">Vector to reject from</param>
|
||||
/// <returns>Rejected vector.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> Reject(const TVector4<T, S>& v1, const TVector4<T, S> v2)
|
||||
{
|
||||
return v1 - (DotP(v1, v2) / DotP(v2, v2)) * v2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reject vector v1 from v2.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector to reject</param>
|
||||
/// <param name="v2">Vector to reject from</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& RejectV(TVector4<T, S>& v1, const TVector4<T, S> v2)
|
||||
{
|
||||
v1 = v1 - (DotP(v1, v2) / DotP(v2, v2)) * v2;
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perspective divide vector.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>Perspective divided vector.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> PerspectiveDivide(const TVector4<T, S>& v1);
|
||||
|
||||
/// <summary>
|
||||
/// Perspective divide vector.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <typeparam name="A">Vector is aligned?</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <returns>Copy of v1.</returns>
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& PerspectiveDivideV(TVector4<T, S>& v1);
|
||||
|
||||
/// <summary>
|
||||
/// Tests if vector is normalized.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="threshold">Threshold to vector magnitude of 1.0</param>
|
||||
/// <returns>True if vector is normalized, false if not.</returns>
|
||||
template<RealType T, bool S>
|
||||
FORCEINLINE bool IsNormalized(const TVector4<T, S>& v1, T threshold = P_FLT_INAC)
|
||||
{
|
||||
return (SqrMagnitude(v1) - (T)1.0) < threshold;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if vectors are parallel.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="v2">Vector</param>
|
||||
/// <param name="threshold">Allowed T inaccuracy from one (e.g. 0.98f)</param>
|
||||
/// <returns>True if parallel, false if not.</returns>
|
||||
template<RealType T, bool S>
|
||||
FORCEINLINE bool IsParallel(const TVector4<T, S>& v1, const TVector4<T, S>& v2, T threshold = 1.0f - P_FLT_INAC)
|
||||
{
|
||||
return (abs(DotP(v1, v2)) > threshold);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests whether two vectors are coincident (Parallel and point in same direction).
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of vector</typeparam>
|
||||
/// <param name="v1">Vector</param>
|
||||
/// <param name="v2">Vector</param>
|
||||
/// <param name="threshold">Allowed T inaccuracy from one (e.g. 0.98f)</param>
|
||||
/// <returns>True if coincident, false if not.</returns>
|
||||
template<RealType T, bool S>
|
||||
FORCEINLINE bool IsCoincident(const TVector4<T, S>& v1, const TVector4<T, S>& v2, T threshold = 1.0f - P_FLT_INAC)
|
||||
{
|
||||
return (DotP(v1, v2) > threshold);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include "Core/public/Math/Vector4.inl"
|
294
Engine/Source/Runtime/Core/Math/Vector4.inl
Normal file
294
Engine/Source/Runtime/Core/Math/Vector4.inl
Normal file
@@ -0,0 +1,294 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/public/Math/Boilerplate.h"
|
||||
|
||||
#include "Core/public/Math/Detail/Vector4Decl.inl"
|
||||
#include "Core/public/Math/SIMD/SIMDIntrinsics.h"
|
||||
|
||||
|
||||
#include "Core/public/Math/SIMD/PhanesSIMDTypes.h"
|
||||
|
||||
namespace Phanes::Core::Math
|
||||
{
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>::TVector4(Real _x, Real _y, Real _z, Real _w)
|
||||
{
|
||||
Detail::construct_vec4<T, S>::map(*this, _x, _y, _z, _w);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
Phanes::Core::Math::TVector4<T, S>::TVector4(Real s)
|
||||
{
|
||||
Detail::construct_vec4<T, S>::map(*this, s);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
Phanes::Core::Math::TVector4<T, S>::TVector4(const TVector2<Real, S>& v1, const TVector2<Real, S>& v2)
|
||||
{
|
||||
Detail::construct_vec4<T, S>::map(*this, v1, v2);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
Phanes::Core::Math::TVector4<T, S>::TVector4(const Real* comp)
|
||||
{
|
||||
static_assert(sizeof(comp) >= sizeof(T) * 4, "Size of comp has to be of at least four (4) components.");
|
||||
Detail::construct_vec4<T, S>::map(*this, comp);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
Phanes::Core::Math::TVector4<T, S>::TVector4(const TVector3<T, S>& v, T w)
|
||||
{
|
||||
Detail::construct_vec4<T, S>::map(*this, v, w);
|
||||
}
|
||||
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator+=(TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec4_add<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator+=(TVector4<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_vec4_add<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator-=(TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec4_sub<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator-=(TVector4<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_vec4_sub<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator*=(TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec4_mul<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator*=(TVector4<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_vec4_mul<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator/=(TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec4_div<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator/=(TVector4<T, S>& v1, T s)
|
||||
{
|
||||
Detail::compute_vec4_div<T, S>::map(v1, v1, s);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator+(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
TVector4<T, S> r;
|
||||
Detail::compute_vec4_add<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator+(const TVector4<T, S>& v1, T s)
|
||||
{
|
||||
TVector4<T, S> r;
|
||||
Detail::compute_vec4_add<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator-(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
TVector4<T, S> r;
|
||||
Detail::compute_vec4_sub<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator-(const TVector4<T, S>& v1, T s)
|
||||
{
|
||||
TVector4<T, S> r;
|
||||
Detail::compute_vec4_sub<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator-(T s, const TVector4<T, S>& v1)
|
||||
{
|
||||
TVector4<T, S> r;
|
||||
Detail::compute_vec4_sub<T, S>::map(r, s, v1);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator*(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
TVector4<T, S> r;
|
||||
Detail::compute_vec4_mul<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator*(const TVector4<T, S>& v1, T s)
|
||||
{
|
||||
TVector4<T, S> r;
|
||||
Detail::compute_vec4_mul<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator/(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
TVector4<T, S> r;
|
||||
Detail::compute_vec4_div<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator/(const TVector4<T, S>& v1, T s)
|
||||
{
|
||||
TVector4<T, S> r;
|
||||
Detail::compute_vec4_div<T, S>::map(r, v1, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> operator/(T s, const TVector4<T, S>& v1)
|
||||
{
|
||||
TVector4<T, S> r;
|
||||
Detail::compute_vec4_div<T, S>::map(r, s, v1);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Comparision
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool operator==(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
return Detail::compute_vec4_eq<T, S>::map(v1, v2);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
bool operator!=(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
return Detail::compute_vec4_ieq<T, S>::map(v1, v2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Inc- / Decrement
|
||||
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator++(TVector4<T, S>& v1)
|
||||
{
|
||||
Detail::compute_vec4_inc<T, S>::map(v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator--(TVector4<T, S>& v1)
|
||||
{
|
||||
Detail::compute_vec4_dec<T, S>::map(v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator++(TVector4<T, S>& v1, int)
|
||||
{
|
||||
return ++v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& operator--(TVector4<T, S>& v1, int)
|
||||
{
|
||||
return --v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
T DotP(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
return Detail::compute_vec4_dotp<T, S> ::map(v1, v2);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& Set(TVector4<T, S>& v1, T x, T y, T z, T w)
|
||||
{
|
||||
Detail::compute_vec4_set<T, S>::map(v1, x, y, z, w);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
T Magnitude(const TVector4<T, S>& v)
|
||||
{
|
||||
return Detail::compute_vec4_mag<T, S>::map(v);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
T SqrMagnitude(const TVector4<T, S>& v)
|
||||
{
|
||||
return Detail::compute_vec4_dotp<T, S>::map(v, v);
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> Max(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
TVector4<T, S> r;
|
||||
Detail::compute_vec4_max<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& MaxV(TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec4_max<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> Min(const TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
TVector4<T, S> r;
|
||||
Detail::compute_vec4_min<T, S>::map(r, v1, v2);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& MinV(TVector4<T, S>& v1, const TVector4<T, S>& v2)
|
||||
{
|
||||
Detail::compute_vec4_min<T, S>::map(v1, v1, v2);
|
||||
return v1;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S> PerspectiveDivide(const TVector4<T, S>& v1)
|
||||
{
|
||||
TVector4<T, S> r;
|
||||
Detail::compute_vec4_pdiv<T, S>::map(r, v1);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<RealType T, bool S>
|
||||
TVector4<T, S>& PerspectiveDivideV(TVector4<T, S>& v1)
|
||||
{
|
||||
Detail::compute_vec4_pdiv<T, S>::map(v1, v1);
|
||||
return v1;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user