From 128c6aca0789dbc2262e799f51089966e6eb8325 Mon Sep 17 00:00:00 2001 From: scorpioblood <77296181+scorpioblood@users.noreply.github.com> Date: Thu, 30 May 2024 22:03:34 +0200 Subject: [PATCH] Implement functions. --- .../Runtime/Core/public/Math/Vector4.hpp | 231 +++++++++++++++--- 1 file changed, 200 insertions(+), 31 deletions(-) diff --git a/Engine/Source/Runtime/Core/public/Math/Vector4.hpp b/Engine/Source/Runtime/Core/public/Math/Vector4.hpp index 1c4140b..13ee614 100644 --- a/Engine/Source/Runtime/Core/public/Math/Vector4.hpp +++ b/Engine/Source/Runtime/Core/public/Math/Vector4.hpp @@ -12,7 +12,8 @@ namespace Phanes::Core::Math { - /// 4D Vector defined with x, y, z, w. + /// 4D Vector defined with x, y, z, w. + /// Alignment allows for possible simd optimization. template struct TVector4 { @@ -361,6 +362,15 @@ namespace Phanes::Core::Math // TVector4 functions // // ====================== // + template + void Set(TVector4& v1, TVector4& v2) + { + v1.x = v2.x; + v1.y = v2.y; + v1.z = v2.z; + v1.w = v2.w; + } + /// /// Get magnitude of vector. /// @@ -368,8 +378,11 @@ namespace Phanes::Core::Math /// Vector is aligned? /// Vector /// Magnitude of vector. - template - T Magnitude(const TVector4& v); + template + T Magnitude(const TVector4& v) + { + return sqrt(DotP(v, v)); + } /// /// Get square of magnitude of vector. @@ -379,7 +392,10 @@ namespace Phanes::Core::Math /// Vector /// Square of magnitude of vector. template - T SqrMagnitude(const TVector4& v); + T SqrMagnitude(const TVector4& v) + { + return DotP(v, v); + } /// /// Get magnitude of vector. @@ -410,7 +426,10 @@ namespace Phanes::Core::Math /// Vector two /// template - T Angle(const TVector4& v1, const TVector4& v2); + T Angle(const TVector4& v1, const TVector4& v2) + { + return acos(DotP(v1, v2) / (Magnitude(v1) * Magnitude(v2))); + } /// /// Cosine of angle between two vectors. @@ -421,7 +440,10 @@ namespace Phanes::Core::Math /// Vector two /// template - T CosineAngle(const TVector4& v1, const TVector4& v2); + T CosineAngle(const TVector4& v1, const TVector4& v2) + { + return DotP(v1, v2) / (Magnitude(v1) * Magnitude(v2)); + } /// /// Normalizes a vector. @@ -431,7 +453,14 @@ namespace Phanes::Core::Math /// Vector /// Normalized vector template - TVector4 Normalize(const TVector4& v1); + TVector4 Normalize(const TVector4& v1) + { + T vecNorm = Magnitude(v1); + + vecNorm = (vecNorm < P_FLT_INAC) ? Magnitude(v1) : (T)1.0; + + return v1 / vecNorm; + } /// /// Normalizes a vector. @@ -441,7 +470,16 @@ namespace Phanes::Core::Math /// Vector /// Copy of v1. template - TVector4 NormalizeV(TVector4& v1); + TVector4 NormalizeV(TVector4& v1) + { + T vecNorm = Magnitude(v1); + + vecNorm = (vecNorm < P_FLT_INAC) ? Magnitude(v1) : (T)1.0; + + v1 /= vecNorm; + + return v1; + } /// /// Normalizes a vector. @@ -452,7 +490,10 @@ namespace Phanes::Core::Math /// Vector /// Normalized vector template - TVector4 UnsafeNormalize(const TVector4& v1); + TVector4 UnsafeNormalize(const TVector4& v1) + { + return v1 / Magnitude(v1); + } /// /// Normalizes a vector. @@ -463,7 +504,11 @@ namespace Phanes::Core::Math /// Vector /// Copy of v1. template - TVector4 UnsafeNormalizeV(TVector4& v1); + TVector4 UnsafeNormalizeV(TVector4& v1) + { + v1 /= Magnitude(v1); + return v1; + } /// /// Calculates the dot product between two vectors. @@ -474,7 +519,10 @@ namespace Phanes::Core::Math /// Vector two /// Dot product between vectors. template - T DotP(const TVector4& v1, const TVector4& v2); + T DotP(const TVector4& v1, const TVector4& v2) + { + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w; + } /// /// Gets componentwise max of both vectors. @@ -485,7 +533,15 @@ namespace Phanes::Core::Math /// Vector two /// Vector with componentwise max of both vectors. template - TVector4 Max(const TVector4& v1, const TVector4& v2); + TVector4 Max(const TVector4& v1, const TVector4& v2) + { + return TVector4( + (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 + ); + } /// /// Gets componentwise max of both vectors. @@ -496,7 +552,15 @@ namespace Phanes::Core::Math /// Vector two /// Copy of v1. template - TVector4 MaxV(TVector4& v1, const TVector4& v2); + TVector4 MaxV(TVector4& v1, const TVector4& 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; + } /// /// Gets componentwise min of both vectors. @@ -507,7 +571,15 @@ namespace Phanes::Core::Math /// Vector two /// Vector with componentwise max of both vectors. template - TVector4 Min(const TVector4& v1, const TVector4& v2); + TVector4 Min(const TVector4& v1, const TVector4& v2) + { + return TVector4( + (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 + ); + } /// /// Gets componentwise min of both vectors. @@ -518,7 +590,15 @@ namespace Phanes::Core::Math /// Vector two /// Copy of v1. template - TVector4 MinV(TVector4& v1, const TVector4& v2); + TVector4 MinV(TVector4& v1, const TVector4& 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; + } /// /// Inverses vector. @@ -528,7 +608,15 @@ namespace Phanes::Core::Math /// Vector /// Inverted vector template - TVector4 Negate(const TVector4& v1); + TVector4 Negate(const TVector4& v1) + { + return TVector4( + -v1.x, + -v1.y, + -v1.z, + -v1.w + ); + } /// /// Inverses vector. @@ -538,7 +626,13 @@ namespace Phanes::Core::Math /// Vector /// Copy of v1. template - TVector4 NegateV(TVector4& v1); + TVector4 NegateV(TVector4& v1) + { + v1.x = -v1.x; + v1.y = -v1.y; + v1.z = -v1.z; + v1.w = -v1.w; + } /// /// Inverses the components of vector. @@ -548,7 +642,15 @@ namespace Phanes::Core::Math /// Vector /// Vector with reciprocal of components. template - TVector4 CompInverse(const TVector4& v1); + TVector4 CompInverse(const TVector4& v1) + { + return TVector4( + (T)1.0 / v1.x, + (T)1.0 / v1.y, + (T)1.0 / v1.z, + (T)1.0 / v1.w + ); + } /// /// Inverses the components of vector. @@ -558,7 +660,15 @@ namespace Phanes::Core::Math /// Vector /// Copy of v1. template - TVector4 CompInverseV(TVector4& v1); + TVector4 CompInverseV(TVector4& v1) + { + v1.x = (T)1.0 / v1.x; + v1.y = (T)1.0 / v1.y; + v1.z = (T)1.0 / v1.z; + v1.w = (T)1.0 / v1.w; + + return v1; + } /// /// Clamp the vectors length to a magnitude. @@ -569,7 +679,12 @@ namespace Phanes::Core::Math /// /// Vector with magnitude clamped to s. template - TVector4 ClampToMagnitude(const TVector4& v1, T s); + TVector4 ClampToMagnitude(const TVector4& v1, T s) + { + float vecNorm = Magnitude(v1); + TVector4 newVec = (vecNorm > s) ? v1 : v1 / Magnitude(v1); + return newVec; + } /// /// Clamp the vectors length to a magnitude. @@ -580,7 +695,12 @@ namespace Phanes::Core::Math /// Magnitude /// Copy of v1. template - TVector4 ClampToMagnitudeV(TVector4& v1, T s); + TVector4 ClampToMagnitudeV(TVector4& v1, T s) + { + float vecNorm = Magnitude(v1); + v1 = (vecNorm > s) ? v1 : v1 / Magnitude(v1); + return v1; + } /// /// Scale vector to a magnitude @@ -591,7 +711,11 @@ namespace Phanes::Core::Math /// Magnitude /// Vector with scaled magnitude. template - TVector4 ScaleToMagnitude(const TVector4& v1, T s); + TVector4 ScaleToMagnitude(const TVector4& v1, T s) + { + TVector4 vecDir = v1 / Magnitude(v1); + return vecDir * s; + } /// /// Scale vector to a magnitude @@ -602,7 +726,12 @@ namespace Phanes::Core::Math /// Magnitude /// Copy of v1. template - TVector4 ScaleToMagnitudeV(TVector4& v1, T s); + TVector4 ScaleToMagnitudeV(TVector4& v1, T s) + { + v1 /= Magnitude(v1); + v1 *= s; + return v1; + } /// /// Reflect vector on plane. @@ -613,7 +742,10 @@ namespace Phanes::Core::Math /// Planes normal /// Reflected vector template - TVector4 Reflect(const TVector4& v1, const TVector4 normal); + TVector4 Reflect(const TVector4& v1, const TVector4 normal) + { + return v1 - (2 * (v1 * normal) * normal); + } /// /// Reflect vector on plane. @@ -624,7 +756,11 @@ namespace Phanes::Core::Math /// Planes normal /// Copy of v1. template - TVector4 ReflectV(TVector4& v1, const TVector4 normal); + TVector4 ReflectV(TVector4& v1, const TVector4 normal) + { + Set(v1, v1 - (2 * (v1 * normal) * normal)); + return v1; + } /// /// Project vector v1 onto v2. @@ -635,7 +771,10 @@ namespace Phanes::Core::Math /// Vector to project on /// Projected vector. template - TVector4 Project(const TVector4& v1, const TVector4 v2); + TVector4 Project(const TVector4& v1, const TVector4 v2) + { + return (DotP(v1, v2) / DotP(v2, v2)) * v2; + } /// /// Project vector v1 onto v2. @@ -646,7 +785,10 @@ namespace Phanes::Core::Math /// Vector to project on /// Copy of v1. template - TVector4 ProjectV(const TVector4& v1, const TVector4 v2); + TVector4 ProjectV(const TVector4& v1, const TVector4 v2) + { + Set(v1, (DotP(v1, v2) / DotP(v2, v2)) * v2); + } /// /// Reject vector v1 from v2. @@ -657,7 +799,10 @@ namespace Phanes::Core::Math /// Vector to reject from /// Rejected vector. template - TVector4 Reject(const TVector4& v1, const TVector4 v2); + TVector4 Reject(const TVector4& v1, const TVector4 v2) + { + return v1 - (DotP(v1, v2) / DotP(v2, v2))* v2; + } /// /// Reject vector v1 from v2. @@ -668,7 +813,12 @@ namespace Phanes::Core::Math /// Vector to reject from /// Copy of v1. template - TVector4 RejectV(const TVector4& v1, const TVector4 v2); + TVector4 RejectV(const TVector4& v1, const TVector4 v2) + { + Set(v1, v1 - (DotP(v1, v2) / DotP(v2, v2)) * v2); + + return v1; + } /// /// Perspective divide vector. @@ -678,7 +828,16 @@ namespace Phanes::Core::Math /// Vector /// Perspective divided vector. template - TVector4 PrespectiveDivide(const TVector4& v1); + TVector4 PrespectiveDivide(const TVector4& v1) + { + float _1_w = (T)1.0 / v1.w; + return TVector4( + v1.x * _1_w, + v1.y * _1_w, + v1.z * _1_w, + (T)0.0 + ); + } /// /// Perspective divide vector. @@ -688,7 +847,17 @@ namespace Phanes::Core::Math /// Vector /// Copy of v1. template - TVector4 PrespectiveDivideV(TVector4& v1); + TVector4 PrespectiveDivideV(TVector4& v1) + { + float _1_w = (T)1.0 / v1.w; + + v1.x *= _1_w; + v1.y *= _1_w; + v1.z *= _1_w; + v1.w = (T)0.0; + + return v1; + } }