diff --git a/Engine/Source/Runtime/Core/public/Math/Detail/IntVector3Decl.inl b/Engine/Source/Runtime/Core/public/Math/Detail/IntVector3Decl.inl new file mode 100644 index 0000000..5ab529e --- /dev/null +++ b/Engine/Source/Runtime/Core/public/Math/Detail/IntVector3Decl.inl @@ -0,0 +1,280 @@ +#pragma once + +#include "Core/public/Math/Boilerplate.h" + +namespace Phanes::Core::Math::Detail +{ + template + struct construct_ivec3 {}; + + template + struct compute_ivec3_add {}; + + template + struct compute_ivec3_sub {}; + + template + struct compute_ivec3_mul {}; + + template + struct compute_ivec3_div {}; + + template + struct compute_ivec3_mod {}; + + template + struct compute_ivec3_eq {}; + + template + struct compute_ivec3_ieq {}; + + template + struct compute_ivec3_inc {}; + + template + struct compute_ivec3_dec {}; + + template + struct compute_ivec3_and {}; + + template + struct compute_ivec3_or {}; + + template + struct compute_ivec3_xor {}; + + template + struct compute_ivec3_left_shift {}; + + template + struct compute_ivec3_right_shift {}; + + template + struct compute_ivec3_bnot {}; + + + template + struct construct_ivec3 + { + static constexpr void map(Phanes::Core::Math::TIntVector2& v1, const TIntVector2& v2) + { + v1.x = v2.x; + v1.y = v2.y; + v1.z = v2.z; + } + + + static constexpr void map(Phanes::Core::Math::TIntVector2& v1, T s) + { + v1.x = s; + v1.y = s; + } + + static constexpr void map(Phanes::Core::Math::TIntVector2& v1, T x, T y) + { + v1.x = x; + v1.y = y; + } + + + static constexpr void map(Phanes::Core::Math::TIntVector2& v1, const T* comp) + { + v1.x = comp[0]; + v1.y = comp[1]; + } + }; + + + template + struct compute_ivec3_add + { + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, const Phanes::Core::Math::TIntVector2& v2) + { + r.x = v1.x + v2.x; + r.y = v1.y + v2.y; + } + + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, T s) + { + r.x = v1.x + s; + r.y = v1.y + s; + } + }; + + + template + struct compute_ivec3_sub + { + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, const Phanes::Core::Math::TIntVector2& v2) + { + r.x = v1.x - v2.x; + r.y = v1.y - v2.y; + } + + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, T s) + { + r.x = v1.x - s; + r.y = v1.y - s; + } + }; + + + template + struct compute_ivec3_mul + { + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, const Phanes::Core::Math::TIntVector2& v2) + { + r.x = v1.x * v2.x; + r.y = v1.y * v2.y; + } + + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, T s) + { + r.x = v1.x * s; + r.y = v1.y * s; + } + }; + + + template + struct compute_ivec3_div + { + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, const Phanes::Core::Math::TIntVector2& v2) + { + r.x = v1.x / v2.x; + r.y = v1.y / v2.y; + } + + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, T s) + { + s = (T)1.0 / s; + + r.x = v1.x * s; + r.y = v1.y * s; + } + }; + + template + struct compute_ivec3_mod + { + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, const Phanes::Core::Math::TIntVector2& v2) + { + r.x = v1.x % v2.x; + r.y = v1.y % v2.y; + } + + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, T s) + { + r.x = v1.x % s; + r.y = v1.y % s; + } + }; + + template + struct compute_ivec3_eq + { + static constexpr bool map(const Phanes::Core::Math::TIntVector2& v1, const Phanes::Core::Math::TIntVector2& v2) + { + return (Phanes::Core::Math::Abs(v1.x - v2.x) < P_FLT_INAC && + Phanes::Core::Math::Abs(v1.y - v2.y) < P_FLT_INAC); + } + }; + + template + struct compute_ivec3_ieq + { + static constexpr bool map(const Phanes::Core::Math::TIntVector2& v1, const Phanes::Core::Math::TIntVector2& v2) + { + return (Phanes::Core::Math::Abs(v1.x - v2.x) > P_FLT_INAC || + Phanes::Core::Math::Abs(v1.y - v2.y) > P_FLT_INAC); + } + }; + + template + struct compute_ivec3_inc + { + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1) + { + r.x = v1.x + 1; + r.y = v1.y + 1; + } + }; + + template + struct compute_ivec3_dec + { + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1) + { + r.x = v1.x - 1; + r.y = v1.y - 1; + } + }; + + + template + struct compute_ivec3_and + { + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, const Phanes::Core::Math::TIntVector2& v2) + { + r.x = v1.x & v2.x; + r.y = v1.y & v2.y; + } + + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, T s) + { + r.x = v1.x & s; + r.y = v1.y & s; + } + }; + + template + struct compute_ivec3_or + { + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, const Phanes::Core::Math::TIntVector2& v2) + { + r.x = v1.x | v2.x; + r.y = v1.y | v2.y; + } + }; + + template + struct compute_ivec3_xor + { + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, const Phanes::Core::Math::TIntVector2& v2) + { + r.x = v1.x ^ v2.x; + r.y = v1.y ^ v2.y; + } + }; + + template + struct compute_ivec3_left_shift + { + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, const Phanes::Core::Math::TIntVector2& v2) + { + r.x = v1.x << v2.x; + r.y = v1.y << v2.y; + } + }; + + template + struct compute_ivec3_right_shift + { + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1, const Phanes::Core::Math::TIntVector2& v2) + { + r.x = v1.x >> v2.x; + r.y = v1.y >> v2.y; + } + }; + + template + struct compute_ivec3_bnot + { + static constexpr void map(Phanes::Core::Math::TIntVector2& r, const Phanes::Core::Math::TIntVector2& v1) + { + r.x = ~v1.x; + r.y = ~v1.y; + } + }; +} + diff --git a/Engine/Source/Runtime/Core/public/Math/Detail/IntVector4Decl.inl b/Engine/Source/Runtime/Core/public/Math/Detail/IntVector4Decl.inl new file mode 100644 index 0000000..c75481d --- /dev/null +++ b/Engine/Source/Runtime/Core/public/Math/Detail/IntVector4Decl.inl @@ -0,0 +1,359 @@ +#pragma once + +#include "Core/public/Math/Boilerplate.h" + +namespace Phanes::Core::Math::Detail +{ + template + struct construct_ivec4 {}; + + template + struct compute_ivec4_add {}; + + template + struct compute_ivec4_sub {}; + + template + struct compute_ivec4_mul {}; + + template + struct compute_ivec4_div {}; + + template + struct compute_ivec4_mod {}; + + template + struct compute_ivec4_eq {}; + + template + struct compute_ivec4_ieq {}; + + template + struct compute_ivec4_inc {}; + + template + struct compute_ivec4_dec {}; + + template + struct compute_ivec4_and {}; + + template + struct compute_ivec4_or {}; + + template + struct compute_ivec4_xor {}; + + template + struct compute_ivec4_left_shift {}; + + template + struct compute_ivec4_right_shift {}; + + template + struct compute_ivec4_bnot {}; + + + template + struct construct_ivec4 + { + static constexpr void map(Phanes::Core::Math::TIntVector4& v1, const TIntVector4& 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& v1, T s) + { + v1.x = s; + v1.y = s; + v1.z = s; + v1.w = s; + } + + static constexpr void map(Phanes::Core::Math::TIntVector4& v1, T x, T y, T z, T w) + { + v1.x = x; + v1.y = y; + v1.y = z; + v1.y = w; + } + + + static constexpr void map(Phanes::Core::Math::TIntVector4& v1, const T* comp) + { + v1.x = comp[0]; + v1.y = comp[1]; + v1.z = comp[2]; + v1.w = comp[3]; + } + }; + + + template + struct compute_ivec4_add + { + static constexpr void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& 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& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.x = v1.x + s; + r.y = v1.y + s; + r.z = v1.z + s; + r.w = v1.w + s; + } + }; + + + template + struct compute_ivec4_sub + { + static constexpr void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& 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& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.x = v1.x - s; + r.y = v1.y - s; + r.z = v1.z - s; + r.w = v1.w - s; + } + }; + + + template + struct compute_ivec4_mul + { + static constexpr void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& 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& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.x = v1.x * s; + r.y = v1.y * s; + r.z = v1.z * s; + r.w = v1.w * s; + } + }; + + + template + struct compute_ivec4_div + { + static constexpr void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& 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& r, const Phanes::Core::Math::TIntVector4& 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; + } + }; + + template + struct compute_ivec4_mod + { + static constexpr void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& 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& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.x = v1.x % s; + r.y = v1.y % s; + r.z = v1.z % s; + r.w = v1.w % s; + } + }; + + template + struct compute_ivec4_eq + { + static constexpr bool map(const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& v2) + { + return (v1.x == v2.x && + v1.y == v2.y && + v1.z == v2.z && + v1.w == v2.w); + } + }; + + template + struct compute_ivec4_ieq + { + static constexpr bool map(const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& v2) + { + return (v1.x != v2.x || + v1.y != v2.y || + v1.z != v2.z || + v1.w != v2.w); + } + }; + + template + struct compute_ivec4_inc + { + static constexpr void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1) + { + r.x = v1.x + 1; + r.y = v1.y + 1; + r.z = v1.z + 1; + r.w = v1.w + 1; + } + }; + + template + struct compute_ivec4_dec + { + static constexpr void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1) + { + r.x = v1.x - 1; + r.y = v1.y - 1; + r.z = v1.z - 1; + r.w = v1.w - 1; + } + }; + + + template + struct compute_ivec4_and + { + static constexpr void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& 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& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.x = v1.x & s; + r.y = v1.y & s; + r.z = v1.z & s; + r.w = v1.w & s; + } + }; + + template + struct compute_ivec4_or + { + static constexpr void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& 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& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.x = v1.x | s; + r.y = v1.y | s; + r.z = v1.z | s; + r.w = v1.w | s; + } + }; + + template + struct compute_ivec4_xor + { + static constexpr void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& 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& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.x = v1.x ^ s; + r.y = v1.y ^ s; + r.z = v1.z ^ s; + r.w = v1.w ^ s; + } + }; + + template + struct compute_ivec4_left_shift + { + static constexpr void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& 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& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.x = v1.x << s; + r.y = v1.y << s; + r.z = v1.z << s; + r.w = v1.w << s; + } + }; + + template + struct compute_ivec4_right_shift + { + static constexpr void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& 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& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.x = v1.x >> s; + r.y = v1.y >> s; + r.z = v1.z >> s; + r.w = v1.w >> s; + } + }; + + template + struct compute_ivec4_bnot + { + static constexpr void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1) + { + r.x = ~v1.x; + r.y = ~v1.y; + } + }; +} + diff --git a/Engine/Source/Runtime/Core/public/Math/Include.h b/Engine/Source/Runtime/Core/public/Math/Include.h index 4bb732e..3080630 100644 --- a/Engine/Source/Runtime/Core/public/Math/Include.h +++ b/Engine/Source/Runtime/Core/public/Math/Include.h @@ -3,4 +3,5 @@ // --- Vectors ------------------------ #include "Core/public/Math/Vector2.hpp" // <-- Includes Vector3/4 automatically -#include "Core/public/Math/IntVector2.hpp" \ No newline at end of file +#include "Core/public/Math/IntVector2.hpp" +#include "Core/public/Math/IntVector4.hpp" \ No newline at end of file diff --git a/Engine/Source/Runtime/Core/public/Math/IntVector3.hpp b/Engine/Source/Runtime/Core/public/Math/IntVector3.hpp index b196da7..d1c601b 100644 --- a/Engine/Source/Runtime/Core/public/Math/IntVector3.hpp +++ b/Engine/Source/Runtime/Core/public/Math/IntVector3.hpp @@ -3,9 +3,12 @@ #include "Core/public/Math/Boilerplate.h" #include "Core/public/Math/MathCommon.hpp" -#include "Core/public/Math/MathAbstractTypes.h" #include "Core/public/Math/MathFwd.h" +#include "Core/public/Math/SIMD/Storage.h" + +#include "Core/public/Math/IntVector4.hpp" + #ifndef P_DEBUG #pragma warning(disable : 4244) #endif @@ -28,54 +31,8 @@ namespace Phanes::Core::Math { * A 3D Vector with components x, y and z with integer precision. */ - template - struct TIntVector3 { - - 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; - - /** 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; - }; - - /** Components array holding the data - * - * @ref [FIELD]x - * @ref [FIELD]y - * @ref [FIELD]z - * - * @note Components are split into x, y and z. Access and manipulation is possible by these variables. - */ - - T comp[3]; - - }; + template + struct TIntVector3 : public TIntVector4 { public: @@ -96,24 +53,7 @@ namespace Phanes::Core::Math { } /** - * Move constructor - */ - - TIntVector3(TIntVector3&& v) - { - this->comp = v.comp; - v.comp = nullptr; - } - - /** - * Convert other type of vector - */ - - template - explicit TIntVector3(const TIntVector3& v) : x((T)v.x), y((T)v.y) {}; - - /** - * Construct Vector from xy components. + * Construct Vector from xyz components. * * @param(x) X component * @param(y) Y component diff --git a/Engine/Source/Runtime/Core/public/Math/IntVector4.hpp b/Engine/Source/Runtime/Core/public/Math/IntVector4.hpp new file mode 100644 index 0000000..ff3d6c4 --- /dev/null +++ b/Engine/Source/Runtime/Core/public/Math/IntVector4.hpp @@ -0,0 +1,443 @@ +#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 + + +#ifndef INTVECTOR4_H +#define INTVECTOR4_H + +namespace Phanes::Core::Math { + + /** + * A 4D Vector with components x, y, z and w with integer precision. + */ + + template + 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::value>::type comp; + typename SIMD::Storage<4, T, SIMD::use_simd::value>::type data; + }; + }; + + + public: + + /** + * Default constructor without initialization + */ + + TIntVector4() = default; + + + /// + /// Copy constructor. + /// + /// + TIntVector4(const TIntVector4& v); + + /// + /// Construct vector from x, y, z, w components. + /// + /// + /// + /// + /// + TIntVector4(const T x, const T y, const T z, const T w); + + /// + /// Broadcast s into all components. + /// + /// + TIntVector4(T s); + + /** + * Construct Vector from two component array. + * + * @param comp Array of components + */ + + TIntVector4(const T *comp); + + /// + /// Construct vector from two 2d vectors + /// + /// x,y = v1.x, v2.y + /// + /// z,w = v2.x, v2.y + /// + /// + /// + TIntVector4(const TIntVector2& v1, const TIntVector2& v2); + + + + }; + + + /** + * Addition operation on same TIntVector4 (this) by a scalar value. + * + * @param(v1) Vector to add to + * @param(s) Scalar + */ + + template + TIntVector4 operator+= (TIntVector4& v1, T s); + + /** + * Addition operation on same TIntVector4 (this) by a another TIntVector4. + * + * @param(v1) Vector to add to + * @param(v2) Vector to add + */ + + template + TIntVector4 operator+= (TIntVector4& v1, const TIntVector4& v2); + + /** + * Substraction operation on same TIntVector4 (this) by a floating point. + * + * @param(v1) Vector to substract from + * @param(v2) Floating point to substract + */ + + template + TIntVector4 operator-= (TIntVector4& v1, T s); + + /** + * Substraction operation on same TIntVector4 (this) by a another TIntVector4. + * + * @param(v1) Vector to substract from + * @param(v2) Vector to substract + */ + + template + TIntVector4 operator-= (TIntVector4& v1, const TIntVector4& v2); + + + /** + * Multiplication of TIntVector4 (this) with a floating point. + * + * @param(v1) Vector to multiply with + * @param(s Floating point to multiply with + */ + + template + TIntVector4 operator*= (TIntVector4& v1, T s); + + /** + * Devision of Vector + * + * @param(v1) Vector to divide with + * @param(s) Scalar to divide with + * + * @note Result is rounded (obviously) + */ + + template + TIntVector4 operator/= (TIntVector4& v1, T s); + + /** + * Stores the remainder of division by a scalar. + * + * @param(v1) Vector to divide with + * @param(s) Scalar to divide with + */ + + template + TIntVector4 operator%= (TIntVector4& v1, const TIntVector4& v2); + + template + TIntVector4 operator%= (TIntVector4& v1, T s); + + template + inline TIntVector4 operator&= (TIntVector4& v1, const TIntVector4& v2); + + template + inline TIntVector4 operator&= (TIntVector4& v1, T s); + + template + inline TIntVector4 operator|= (TIntVector4& v1, const TIntVector4& v2); + + template + inline TIntVector4 operator|= (TIntVector4& v1, T s); + + template + inline TIntVector4 operator^= (TIntVector4& v1, const TIntVector4& v2); + + template + inline TIntVector4 operator^= (TIntVector4& v1, T s); + + template + inline TIntVector4 operator<<= (TIntVector4& v1, const TIntVector4& v2); + + template + inline TIntVector4 operator<<= (TIntVector4& v1, T s); + + template + inline TIntVector4 operator>>= (TIntVector4& v1, const TIntVector4& v2); + + template + inline TIntVector4 operator>>= (TIntVector4& v1, T s); + + /** + * Scale of Vector by floating point. (> Creates a new TIntVector4) + * + * @param(v1) Vector to multiply with + * @param(s Floating point to multiply with + * + * @return Result Vector + */ + + template + TIntVector4 operator* (const TIntVector4& v1, T s); + + /** + * Division of Vector by floating point. (> Creates another TIntVector4) + * + * @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 + TIntVector4 operator/ (const TIntVector4& v1, T s); + + /** + * Scale of Vector by floating point. (> Creates a new TIntVector4) + * + * @param(v1) Vector to multiply with + * @param(s Floating point to multiply with + * + * @return Result Vector + */ + + template + FORCEINLINE TIntVector4 operator* (T s, const TIntVector4& 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 + FORCEINLINE TIntVector4 operator/ (T s, const TIntVector4& v1) { return v1 / s; }; + + /** + * Dot product between two Vectors. + * + * @see [FUNC]DotP + * + * @param(v1) Vector one + * @param(v2) Vector two + * + * @result Dot product + */ + + template + T operator* (const TIntVector4& v1, const TIntVector4& v2); + + /** + * Componentwise addition of Vector with floating point. + * + * @param(v1) Vector to add to + * @param(s Floating point to add + * + * @return Result Vector + */ + + template + TIntVector4 operator+ (const TIntVector4& 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 + TIntVector4 operator+ (const TIntVector4& v1, const TIntVector4& v2); + + /** + * Componentwise substraction of Vector with floating point. + * + * @param(v1) Vector to substract from + * @param(s Floating point to substract + * + * @return Result Vector + */ + + template + TIntVector4 operator- (const TIntVector4& 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 + TIntVector4 operator- (const TIntVector4& v1, const TIntVector4& v2); + + + + + /** + * Scale of Vector by floating point. (> Creates a new TIntVector4) + * + * @param(v1) Vector to multiply with + * @param(s Floating point to multiply with + * + * @return Result Vector + */ + + template + FORCEINLINE TIntVector4 operator% (const TIntVector4& v1, const TIntVector4& v2); + + template + FORCEINLINE TIntVector4 operator% (const TIntVector4& v1, T s); + + + + template + inline TIntVector4 operator& (TIntVector4& v1, const TIntVector4& v2); + + template + inline TIntVector4 operator& (TIntVector4& v1, T s); + + template + inline TIntVector4 operator| (TIntVector4& v1, const TIntVector4& v2); + + template + inline TIntVector4 operator| (TIntVector4& v1, T s); + + template + inline TIntVector4 operator^ (TIntVector4& v1, const TIntVector4& v2); + + template + inline TIntVector4 operator^ (TIntVector4& v1, T s); + + template + inline TIntVector4 operator<< (TIntVector4& v1, const TIntVector4& v2); + + template + inline TIntVector4 operator<< (TIntVector4& v1, T s); + + template + inline TIntVector4 operator>> (TIntVector4& v1, const TIntVector4& v2); + + template + inline TIntVector4 operator>> (TIntVector4& v1, T s); + + template + inline TIntVector4 operator~ (TIntVector4& v1); + + + /** + * Compare Vector for equality. + * + * @see [FUNC]Equals + * + * @param(v1) Vector to negate + * + * @return true if equal, false if inequal + */ + + template + bool operator== (const TIntVector4& v1, const TIntVector4& v2); + + + /** + * Compare Vector for inequality. + * + * @see [FUNC]Equals + * + * @param(v1) Vector to negate + * + * @return true if inequal, false if equal + */ + + template + bool operator!= (const TIntVector4& v1, const TIntVector4& v2); + + + +} // phanes::core::math::coretypes + +#endif // !INTVECTOR3_H + + +#include "Core/public/Math/IntVector4.inl" \ No newline at end of file diff --git a/Engine/Source/Runtime/Core/public/Math/IntVector4.inl b/Engine/Source/Runtime/Core/public/Math/IntVector4.inl new file mode 100644 index 0000000..251f5e0 --- /dev/null +++ b/Engine/Source/Runtime/Core/public/Math/IntVector4.inl @@ -0,0 +1,409 @@ +#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" + +#include "IntVector4.hpp" + +namespace Phanes::Core::Math +{ + template + TIntVector4::TIntVector4(const TIntVector4& v) + { + Detail::construct_ivec4::value>::map(*this, v); + } + + template + TIntVector4::TIntVector4(const T _x, const T _y, const T _z, const T _w) + { + Detail::construct_ivec4::value>::map(*this, _x, _y, _z, _w); + } + + template + TIntVector4::TIntVector4(const T s) + { + Detail::construct_ivec4::value>::map(*this, s); + } + + template + TIntVector4::TIntVector4(const T* comp) + { + Detail::construct_ivec4::value>::map(*this, comp); + } + + template + TIntVector4::TIntVector4(const TIntVector2& v1, const TIntVector2& v2) + { + Detail::construct_ivec4::value>::map(*this, v1, v2); + } + + + + + template + TIntVector4 operator+=(TIntVector4& v1, const TIntVector4& v2) + { + Detail::compute_ivec4_add::value>::map(v1, v1, v2); + return v1; + } + + template + TIntVector4 operator+=(TIntVector4& v1, T s) + { + Detail::compute_ivec4_add::value>::map(v1, v1, s); + return v1; + } + + template + TIntVector4 operator-=(TIntVector4& v1, const TIntVector4& v2) + { + Detail::compute_ivec4_sub::value>::map(v1, v1, v2); + return v1; + } + + template + TIntVector4 operator-=(TIntVector4& v1, T s) + { + Detail::compute_ivec4_sub::value>::map(v1, v1, s); + return v1; + } + + template + TIntVector4 operator*=(TIntVector4& v1, const TIntVector4& v2) + { + Detail::compute_ivec4_mul::value>::map(v1, v1, v2); + return v1; + } + + template + TIntVector4 operator*=(TIntVector4& v1, T s) + { + Detail::compute_ivec4_mul::value>::map(v1, v1, s); + return v1; + } + + template + TIntVector4 operator/=(TIntVector4& v1, const TIntVector4& v2) + { + Detail::compute_ivec4_div::value>::map(v1, v1, v2); + return v1; + } + + template + TIntVector4 operator/=(TIntVector4& v1, T s) + { + Detail::compute_ivec4_div::value>::map(v1, v1, s); + return v1; + } + + template + TIntVector4 operator%=(TIntVector4& v1, const TIntVector4& v2) + { + Detail::compute_ivec4_mod::value>::map(v1, v1, v2); + return v1; + } + + template + TIntVector4 operator%=(TIntVector4& v1, T s) + { + Detail::compute_ivec4_mod::value>::map(v1, v1, s); + return v1; + } + + + template + TIntVector4 operator+(TIntVector4& v1, const TIntVector4& v2) + { + TIntVector4 r; + Detail::compute_ivec4_add::value>::map(r, v1, v2); + return r; + } + + template + TIntVector4 operator+(TIntVector4& v1, T s) + { + TIntVector4 r; + Detail::compute_ivec4_add::value>::map(r, v1, s); + return r; + } + + template + TIntVector4 operator-(TIntVector4& v1, const TIntVector4& v2) + { + TIntVector4 r; + Detail::compute_ivec4_sub::value>::map(r, v1, v2); + return r; + } + + template + TIntVector4 operator-(TIntVector4& v1, T s) + { + TIntVector4 r; + Detail::compute_ivec4_sub::value>::map(r, v1, s); + return r; + } + + template + TIntVector4 operator*(TIntVector4& v1, const TIntVector4& v2) + { + TIntVector4 r; + Detail::compute_ivec4_mul::value>::map(r, v1, v2); + return r; + } + + template + TIntVector4 operator*(TIntVector4& v1, T s) + { + TIntVector4 r; + Detail::compute_ivec4_mul::value>::map(r, v1, s); + return r; + } + + template + TIntVector4 operator/(TIntVector4& v1, const TIntVector4& v2) + { + TIntVector4 r; + Detail::compute_ivec4_div::value>::map(r, v1, v2); + return r; + } + + template + TIntVector4 operator/(TIntVector4& v1, T s) + { + TIntVector4 r; + Detail::compute_ivec4_div::value>::map(r, v1, s); + return r; + } + + template + TIntVector4 operator%(TIntVector4& v1, const TIntVector4& v2) + { + TIntVector4 r; + Detail::compute_ivec4_mod::value>::map(r, v1, v2); + return r; + } + + template + TIntVector4 operator%(TIntVector4& v1, T s) + { + TIntVector4 r; + Detail::compute_ivec4_mod::value>::map(r, v1, s); + return r; + } + + + + + // Bitwise operators + + template + TIntVector4 operator&=(TIntVector4& v1, const TIntVector4& v2) + { + Detail::compute_ivec4_and::value>::map(v1, v1, v2); + return v1; + } + + template + TIntVector4 operator&=(TIntVector4& v1, T s) + { + Detail::compute_ivec4_and::value>::map(v1, v1, s); + return v1; + } + + template + TIntVector4 operator|=(TIntVector4& v1, const TIntVector4& v2) + { + Detail::compute_ivec4_or::value>::map(v1, v1, v2); + return v1; + } + + template + TIntVector4 operator|=(TIntVector4& v1, T s) + { + Detail::compute_ivec4_or::value>::map(v1, v1, s); + return v1; + } + + template + TIntVector4 operator^=(TIntVector4& v1, const TIntVector4& v2) + { + Detail::compute_ivec4_xor::value>::map(v1, v1, v2); + return v1; + } + + template + TIntVector4 operator^=(TIntVector4& v1, T s) + { + Detail::compute_ivec4_xor::value>::map(v1, v1, s); + return v1; + } + + template + TIntVector4 operator<<=(TIntVector4& v1, const TIntVector4& v2) + { + Detail::compute_ivec4_left_shift::value>::map(v1, v1, v2); + return v1; + } + + template + TIntVector4 operator<<=(TIntVector4& v1, T s) + { + Detail::compute_ivec4_left_shift::value>::map(v1, v1, s); + return v1; + } + + template + TIntVector4 operator>>=(TIntVector4& v1, const TIntVector4& v2) + { + Detail::compute_ivec4_right_shift::value>::map(v1, v1, v2); + return v1; + } + + template + TIntVector4 operator>>=(TIntVector4& v1, T s) + { + Detail::compute_ivec4_right_shift::value>::map(v1, v1, s); + return v1; + } + + + + template + TIntVector4 operator&(TIntVector4& v1, const TIntVector4& v2) + { + TVector2 r; + Detail::compute_ivec4_and::value>::map(r, v1, v2); + return r; + } + + template + TIntVector4 operator&(TIntVector4& v1, T s) + { + TVector2 r; + Detail::compute_ivec4_and::value>::map(r, v1, s); + return r; + } + + template + TIntVector4 operator|(TIntVector4& v1, const TIntVector4& v2) + { + TVector2 r; + Detail::compute_ivec4_or::value>::map(r, v1, v2); + return r; + } + + template + TIntVector4 operator|(TIntVector4& v1, T s) + { + TVector2 r; + Detail::compute_ivec4_or::value>::map(r, v1, s); + return r; + } + + template + TIntVector4 operator^(TIntVector4& v1, const TIntVector4& v2) + { + TVector2 r; + Detail::compute_ivec4_xor::value>::map(r, v1, v2); + return r; + } + + template + TIntVector4 operator^(TIntVector4& v1, T s) + { + TVector2 r; + Detail::compute_ivec4_xor::value>::map(r, v1, s); + return r; + } + + template + TIntVector4 operator<<(TIntVector4& v1, const TIntVector4& v2) + { + TVector2 r; + Detail::compute_ivec4_left_shift::value>::map(r, v1, v2); + return r; + } + + template + TIntVector4 operator<<(TIntVector4& v1, T s) + { + TVector2 r; + Detail::compute_ivec4_left_shift::value>::map(r, v1, s); + return r; + } + + template + TIntVector4 operator>>(TIntVector4& v1, const TIntVector4& v2) + { + TVector2 r; + Detail::compute_ivec4_right_shift::value>::map(r, v1, v2); + return r; + } + + template + TIntVector4 operator>>(TIntVector4& v1, T s) + { + TVector2 r; + Detail::compute_ivec4_right_shift::value>::map(r, v1, s); + return r; + } + + template + TIntVector4 operator~(TIntVector4& v1) + { + TVector2 r; + Detail::compute_ivec4_bnot::value>::map(r, v1); + return r; + } + + + + // Comparision + + template + bool operator==(const TIntVector4& v1, const TIntVector4& v2) + { + return Detail::compute_ivec4_eq::value>::map(v1, v2); + } + + template + bool operator!=(const TIntVector4& v1, const TIntVector4& v2) + { + return Detail::compute_ivec4_ieq::value>::map(v1, v2); + } + + + + // Inc- / Decrement + + + template + TIntVector4& operator++(TIntVector4& v1) + { + Detail::compute_ivec4_inc::value>::map(v1); + return v1; + } + + template + TIntVector4& operator--(TIntVector4& v1) + { + Detail::compute_ivec4_inc::value>::map(v1); + return v1; + } + + template + TIntVector4& operator++(TIntVector4& v1, int) + { + return ++v1; + } + + template + TIntVector4& operator--(TIntVector4& v1, int) + { + return --v1; + } +} \ No newline at end of file diff --git a/Engine/Source/Runtime/Core/public/Math/MathFwd.h b/Engine/Source/Runtime/Core/public/Math/MathFwd.h index 9dfce21..0ede835 100644 --- a/Engine/Source/Runtime/Core/public/Math/MathFwd.h +++ b/Engine/Source/Runtime/Core/public/Math/MathFwd.h @@ -37,29 +37,20 @@ namespace Phanes::Core::Math { template struct TPoint2; template struct TPoint3; template struct TPoint4; - template struct TIntVector3; - template struct TIntVector4; template struct TIntPoint2; template struct TIntPoint3; template struct TIntPoint4; - template struct TIntVector2; template struct TVector2; template struct TVector3; template struct TVector4; + template struct TIntVector2; + template struct TIntVector3; + template struct TIntVector4; /** * Specific instantiation of forward declarations. */ - // TIntVector3 - typedef TIntVector3 IntVector3; - typedef TIntVector3 IntVector3l; - - typedef std::vector IntVector3List; - typedef std::vector IntVector3Listl; - - - // TMatrix2 typedef TMatrix2 Matrix2; typedef TMatrix2 Matrix2d; diff --git a/Engine/Source/Runtime/Core/public/Math/SIMD/PhanesVectorMathSSE.hpp b/Engine/Source/Runtime/Core/public/Math/SIMD/PhanesVectorMathSSE.hpp index 072d500..94d6add 100644 --- a/Engine/Source/Runtime/Core/public/Math/SIMD/PhanesVectorMathSSE.hpp +++ b/Engine/Source/Runtime/Core/public/Math/SIMD/PhanesVectorMathSSE.hpp @@ -494,4 +494,152 @@ namespace Phanes::Core::Math::Detail r.comp = _mm_srl_epi64(v1.comp, _mm_set1_epi64x(s)); } }; + + + // =============== // + // TIntVector4 // + // =============== // + + template<> + struct construct_ivec4 + { + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& v1, const TIntVector4& v2) + { + v1.comp = _mm_setr_epi32(v2.x, v2.y, v2.z, v2.w); + } + + + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& v1, int s) + { + v1.comp = _mm_set1_epi32(s); + } + + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& v1, int x, int y, int z, int w) + { + v1.comp = _mm_setr_epi32(x, y, z, w); + } + + + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& v1, const int* comp) + { + v1.comp = _mm_loadu_epi32(comp); + } + }; + + template<> + struct compute_ivec4_add + { + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& v2) + { + r.comp = _mm_add_epi32(v1.comp, v2.comp); + } + + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.comp = _mm_add_epi32(v1.comp, _mm_set1_epi32(s)); + } + }; + + template<> + struct compute_ivec4_sub + { + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& v2) + { + r.comp = _mm_sub_epi32(v1.comp, v2.comp); + } + + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.comp = _mm_sub_epi32(v1.comp, _mm_set1_epi32(s)); + } + }; + + template<> + struct compute_ivec4_inc + { + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1) + { + r.comp = _mm_add_epi32(v1.comp, _mm_set1_epi32(1)); + } + }; + + template<> + struct compute_ivec4_dec + { + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1) + { + r.comp = _mm_sub_epi32(v1.comp, _mm_set1_epi32(1)); + } + }; + + template<> + struct compute_ivec4_and + { + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& v2) + { + r.comp = _mm_and_si128(v1.comp, v2.comp); + } + + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.comp = _mm_and_si128(v1.comp, _mm_set1_epi32(s)); + } + }; + + template<> + struct compute_ivec4_or + { + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& v2) + { + r.comp = _mm_or_si128(v1.comp, v2.comp); + } + + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.comp = _mm_or_si128(v1.comp, _mm_set1_epi32(s)); + } + }; + + template<> + struct compute_ivec4_xor + { + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& v2) + { + r.comp = _mm_xor_si128(v1.comp, v2.comp); + } + + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.comp = _mm_xor_si128(v1.comp, _mm_set1_epi32(s)); + } + }; + + template<> + struct compute_ivec4_left_shift + { + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& v2) + { + r.comp = _mm_sll_epi32(v1.comp, v2.comp); + } + + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.comp = _mm_sll_epi32(v1.comp, _mm_set1_epi32(s)); + } + }; + + template<> + struct compute_ivec4_right_shift + { + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, const Phanes::Core::Math::TIntVector4& v2) + { + r.comp = _mm_srl_epi32(v1.comp, v2.comp); + } + + static FORCEINLINE void map(Phanes::Core::Math::TIntVector4& r, const Phanes::Core::Math::TIntVector4& v1, T s) + { + r.comp = _mm_srl_epi32(v1.comp, _mm_set1_epi32(s)); + } + }; + } \ No newline at end of file diff --git a/Engine/Source/Runtime/Core/public/Math/Vector2.hpp b/Engine/Source/Runtime/Core/public/Math/Vector2.hpp index 626135c..0aa92c7 100644 --- a/Engine/Source/Runtime/Core/public/Math/Vector2.hpp +++ b/Engine/Source/Runtime/Core/public/Math/Vector2.hpp @@ -987,7 +987,7 @@ namespace Phanes::Core::Math { TVector2 Normalize(const TVector2& v1) { float vecNorm = Magnitude(v1); - return (vecNorm < P_FLT_INAC) ? PZeroVector2(T) : (v1 / vecNorm); + return (vecNorm < P_FLT_INAC) ? PZeroVector2(T, false) : (v1 / vecNorm); } /** diff --git a/Engine/Source/Runtime/Core/public/Math/Vector3.hpp b/Engine/Source/Runtime/Core/public/Math/Vector3.hpp index 1c37e89..30ed8b4 100644 --- a/Engine/Source/Runtime/Core/public/Math/Vector3.hpp +++ b/Engine/Source/Runtime/Core/public/Math/Vector3.hpp @@ -675,7 +675,7 @@ namespace Phanes::Core::Math { { T magnitude = Magnitude(v1); - v1 = (magnitude > P_FLT_INAC) ? v1 / magnitude : PZeroVector3(T); + v1 = (magnitude > P_FLT_INAC) ? v1 / magnitude : PZeroVector3(T, false); Clamp(magnitude, min, max); @@ -933,7 +933,7 @@ namespace Phanes::Core::Math { TVector3 Normalize(const TVector3& v1) { float vecNorm = Magnitude(v1); - return (vecNorm < P_FLT_INAC) ? PZeroVector3(T) : v1 / vecNorm; + return (vecNorm < P_FLT_INAC) ? PZeroVector3(T, false) : v1 / vecNorm; } /** @@ -1110,7 +1110,7 @@ namespace Phanes::Core::Math { { T magnitude = Magnitude(v1); - const TVector3 unitVec = (magnitude > P_FLT_INAC) ? v1 / magnitude : PZeroVector3(T); + const TVector3 unitVec = (magnitude > P_FLT_INAC) ? v1 / magnitude : PZeroVector3(T, false); Clamp(magnitude, min, max);