diff --git a/Engine/Source/Runtime/Core/public/Math/Vector2.hpp b/Engine/Source/Runtime/Core/public/Math/Vector2.hpp index 1683be6..faebf52 100644 --- a/Engine/Source/Runtime/Core/public/Math/Vector2.hpp +++ b/Engine/Source/Runtime/Core/public/Math/Vector2.hpp @@ -16,12 +16,12 @@ #ifndef VECTOR2_H #define VECTOR2_H -#define PZeroVector2(type, aligned) TVector2<##type, ##aligned>(0,0) -#define PVectorSouth2(type, aligned) TVector2<##type, ##aligned>(0,-1) -#define PVectorNorth2(type, aligned) TVector2<##type, ##aligned>(0,1) -#define PVectorEast2(type, aligned) TVector2<##type, ##aligned>(1,0) -#define PVectorWest2(type, aligned) TVector2<##type, ##aligned>(-1,0) +#define PZeroVector2(type, aligned) Phanes::Core::Math::TVector2<##type, ##aligned>(0,0) +#define PVectorSouth2(type, aligned) Phanes::Core::Math::TVector2<##type, ##aligned>(0,-1) +#define PVectorNorth2(type, aligned) Phanes::Core::Math::TVector2<##type, ##aligned>(0,1) +#define PVectorEast2(type, aligned) Phanes::Core::Math::TVector2<##type, ##aligned>(1,0) +#define PVectorWest2(type, aligned) Phanes::Core::Math::TVector2<##type, ##aligned>(-1,0) namespace Phanes::Core::Math { @@ -648,7 +648,7 @@ namespace Phanes::Core::Math { template TVector2 ReflectV(TVector2& v1, const TVector2& normal) { - v1 = (2.0f * DotP(v1, normal) * normal) - v1; + v1 = ((T)2.0 * DotP(v1, normal) * normal) - v1; return v1; } @@ -837,7 +837,7 @@ namespace Phanes::Core::Math { template TVector2 Reflect(const TVector2& v1, const TVector2& normal) { - return TVector2((2.0f * DotP(v1, normal) * normal) - v1); + return (((T)2.0 * DotP(v1, normal) * normal) - v1); } /** @@ -982,7 +982,7 @@ namespace Phanes::Core::Math { template TVector2 SignVector(const TVector2& v1) { - return TVector2((v1.x >= (T)0.0) ? 1 : -1, (v1.y >= (T)0.0) ? (T)1.0 : (T)-1.0); + return TVector2((v1.x >= (T)0.0) ? (T)1.0 : (T)-1.0, (v1.y >= (T)0.0) ? (T)1.0 : (T)-1.0); } /** diff --git a/Engine/Source/Runtime/Core/public/Math/Vector3.hpp b/Engine/Source/Runtime/Core/public/Math/Vector3.hpp index b7ed19b..4ca23f4 100644 --- a/Engine/Source/Runtime/Core/public/Math/Vector3.hpp +++ b/Engine/Source/Runtime/Core/public/Math/Vector3.hpp @@ -18,21 +18,21 @@ #ifndef VECTOR3_H #define VECTOR3_H -#define PZeroVector3(type, aligned) TVector3<##type, ##aligned>(0,0,0) -#define PVectorForward3(type, aligned) TVector3<##type, ##aligned>(1,0,0) -#define PVectorBackward3(type, aligned) TVector3<##type, ##aligned>(-1,0,0) -#define PVectorEast3(type, aligned) TVector3<##type, ##aligned>(0,1,0) -#define PVectorWest3(type, aligned) TVector3<##type, ##aligned>(0,-1,0) -#define PVectorUp3(type, aligned) TVector3<##type, ##aligned>(0,0,1) -#define PVectorDown3(type, aligned) TVector3<##type, ##aligned>(0,0,-1) +#define PZeroVector3(type, aligned) Phanes::Core::Math::TVector3<##type, ##aligned>(0,0,0) +#define PVectorForward3(type, aligned) Phanes::Core::Math::TVector3<##type, ##aligned>(1,0,0) +#define PVectorBackward3(type, aligned) Phanes::Core::Math::TVector3<##type, ##aligned>(-1,0,0) +#define PVectorEast3(type, aligned) Phanes::Core::Math::TVector3<##type, ##aligned>(0,1,0) +#define PVectorWest3(type, aligned) Phanes::Core::Math::TVector3<##type, ##aligned>(0,-1,0) +#define PVectorUp3(type, aligned) Phanes::Core::Math::TVector3<##type, ##aligned>(0,0,1) +#define PVectorDown3(type, aligned) Phanes::Core::Math::TVector3<##type, ##aligned>(0,0,-1) namespace Phanes::Core::Math { // Basic 3D vector (x, y, z) - template - struct TVector3 : public TVector4 { + template + struct TVector3 : public TVector4 { public: using Real = T; @@ -46,7 +46,7 @@ namespace Phanes::Core::Math { /// Copy constructor. /// /// - TVector3(const TVector3& v); + TVector3(const TVector3& v); /// /// Broadcast s into x, y, z. @@ -73,7 +73,7 @@ namespace Phanes::Core::Math { /// /// Vector /// Scalar - TVector3(const TVector2& v, Real s); + TVector3(const TVector2& v, Real s); }; @@ -90,8 +90,8 @@ namespace Phanes::Core::Math { /// Vector one /// Vector two /// Copy of v1. - template - inline TVector3 operator+= (TVector3& v1, const TVector3& v2); + template + inline TVector3 operator+= (TVector3& v1, const TVector3& v2); /// /// Vector - scalar addition. @@ -101,19 +101,8 @@ namespace Phanes::Core::Math { /// Vector one /// Vector two /// Copy of v1. - template - inline TVector3 operator+= (TVector3& v1, T s); - - /// - /// Vector substraction. - /// - /// Type of vector - /// Vector is aligned? - /// Vector one - /// Vector two - /// Copy of v1. - template - inline TVector3 operator-= (TVector3& v1, T s); + template + inline TVector3 operator+= (TVector3& v1, T s); /// /// Vector - scalar substraction @@ -123,18 +112,51 @@ namespace Phanes::Core::Math { /// Vector one /// Vector two /// Copy of v1. - template - inline TVector3 operator-= (TVector3& v1, const TVector3& v2); + template + inline TVector3 operator-= (TVector3& v1, const TVector3& v2); + + /// + /// Vector substraction. + /// + /// Type of vector + /// Vector is aligned? + /// Vector one + /// Vector two + /// Copy of v1. + template + inline TVector3 operator-= (TVector3& v1, T s); + + /// + /// Componentwise multiplication + /// + /// Type of vector + /// Vector is aligned? + /// + /// + /// Copy of v1. + template + inline TVector3 operator*=(TVector3& v1, const TVector3& v2); /** - * Dot product between two 3D Vectors + * Componentwise multiplication * * @param(v1) vector one * @param(s) floating point */ - template - inline TVector3 operator*= (TVector3& v1, T s); + template + inline TVector3 operator*= (TVector3& v1, T s); + + /// + /// Componentwise division + /// + /// Type of vector + /// Vector is aligned? + /// + /// + /// Copy of v1. + template + inline TVector3 operator/=(TVector3& v1, const TVector3& v2); /** * Coponentwise division of 3D vector with floating point @@ -143,8 +165,22 @@ namespace Phanes::Core::Math { * @param(s) floating point to divide with */ - template - inline TVector3 operator/= (TVector3& v1, T s); + template + inline TVector3 operator/= (TVector3& v1, T s); + + + + /** + * Componentwise multiplication + * + * @param(v1) vector one + * @param(v2) vector two + * + * @return Dot product of Vectors + */ + + template + TVector3 operator* (const TVector3& v1, const TVector3& v2); /** * Coponentwise multiplication of 3D Vectors with floating point @@ -155,8 +191,21 @@ namespace Phanes::Core::Math { * @return Resulting vector */ - template - TVector3 operator* (const TVector3& v1, T s); + template + TVector3 operator* (const TVector3& v1, T s); + + /** + * Componentwise division + * + * @param(v1) vector one + * @param(v2) vector two + * + * @return Dot product of Vectors + */ + + template + TVector3 operator/ (const TVector3& v1, const TVector3& v2); + /** * Coponentwise division of 3D Vectors with floating point @@ -167,8 +216,8 @@ namespace Phanes::Core::Math { * @return Resulting vector */ - template - TVector3 operator/ (const TVector3& v1, T s); + template + TVector3 operator/ (const TVector3& v1, T s); /** * Coponentwise multiplication of 3D Vectors with floating point @@ -179,8 +228,11 @@ namespace Phanes::Core::Math { * @return Resultion vector */ - template - FORCEINLINE TVector3 operator* (T s, const TVector3& v1) { return v1 * s; }; + template + FORCEINLINE TVector3 operator* (T s, const TVector3& v1) + { + return v1 * s; + }; /** * Coponentwise multiplication of 3D Vectors with floating point @@ -191,20 +243,11 @@ namespace Phanes::Core::Math { * @return Resultion vector */ - template - FORCEINLINE TVector3 operator/ (T s, const TVector3& v1) { return v1 / s; }; - - /** - * Dot product between two 3D Vectors - * - * @param(v1) vector one - * @param(v2) vector two - * - * @return Dot product of Vectors - */ - - template - inline T operator* (const TVector3& v1, const TVector3& v2); + template + FORCEINLINE TVector3 operator/ (T s, const TVector3& v1) + { + return v1 / s; + }; /** * Coponentwise addition of floating point to 3D vector @@ -215,8 +258,8 @@ namespace Phanes::Core::Math { * @return Resulting vector */ - template - TVector3 operator+ (const TVector3& v1, T s); + template + TVector3 operator+ (const TVector3& v1, T s); /** * Coponentwise addition of 3D vector to 3D vector @@ -227,8 +270,8 @@ namespace Phanes::Core::Math { * @return Resulting vector */ - template - TVector3 operator+ (const TVector3& v1, const TVector3& v2); + template + TVector3 operator+ (const TVector3& v1, const TVector3& v2); /** * Coponentwise substraction of floating point of 3D vector @@ -239,8 +282,8 @@ namespace Phanes::Core::Math { * @return Resulting vector */ - template - TVector3 operator- (const TVector3& v1, T s); + template + TVector3 operator- (const TVector3& v1, T s); /** * Coponentwise substraction of floating point of 3D vector @@ -251,8 +294,8 @@ namespace Phanes::Core::Math { * @return Resulting vector */ - template - TVector3 operator- (const TVector3& v1, const TVector3& v2); + template + TVector3 operator- (const TVector3& v1, const TVector3& v2); /** * Tests two 3D vectors for equality. @@ -267,8 +310,8 @@ namespace Phanes::Core::Math { * @note Uses [MACRO]P_FLT_INAC */ - template - inline bool operator== (const TVector3& v1, const TVector3& v2); + template + inline bool operator== (const TVector3& v1, const TVector3& v2); /** * Tests two 3D vectors for inequality. @@ -279,9 +322,20 @@ namespace Phanes::Core::Math { * @return True if inequal, false if not. */ - template - inline bool operator!= (const TVector3& v1, const TVector3& v2); + template + inline bool operator!= (const TVector3& v1, const TVector3& v2); + template + TVector3& operator++(TVector3& v1); + + template + TVector3& operator--(TVector3& v1); + + template + TVector3& operator++(TVector3& v1, int); + + template + TVector3& operator--(TVector3& v1, int); // ==================================== // // TVector3 function implementation // @@ -375,7 +429,7 @@ namespace Phanes::Core::Math { template TVector3 ReflectV(TVector3& v1, const TVector3& normal) { - Set(v1, v1 - (2 * DotP(v1, normal) * normal)); + v1 = ((T)2.0 * DotP(v1, normal) * normal) - v1; return v1; } @@ -392,7 +446,7 @@ namespace Phanes::Core::Math { template T Angle(const TVector3& v1, const TVector3& v2) { - return acos((v1 * v2) / (Magnitude(v1) * Magnitude(v2))); + return acos(DotP(v1, v2) / (Magnitude(v1) * Magnitude(v2))); } /** @@ -446,21 +500,6 @@ namespace Phanes::Core::Math { NormalizeV(v3); } - /** - * Returns signs of components in vector: -1 / +1 / 0. - * - * @param(v1) Vector one - * - * @return Vector with signs a components. - */ - - template - TVector3 SignVector(const TVector3& v1) - { - return TVector3((v1.x >= 0) ? 1 : -1, - (v1.y >= 0) ? 1 : -1, - (v1.z >= 0) ? 1 : -1); - } /** * Tests two vectors for equality. @@ -503,8 +542,8 @@ namespace Phanes::Core::Math { * @note result is stored in v1. */ - template - TVector3 CrossPV(TVector3& v1, const TVector3& v2); + template + TVector3 CrossPV(TVector3& v1, const TVector3& v2); /** * Gets the componentwise max of both vectors. @@ -593,8 +632,10 @@ namespace Phanes::Core::Math { template TVector3 ProjectV(TVector3& v1, const TVector3& v2) { - float x = (v1 * v2) / (v2 * v2); + float x = DotP(v1, v2) / DotP(v2, v2); v1 = x * v2; + + return v1; } /** @@ -609,7 +650,7 @@ namespace Phanes::Core::Math { template TVector3 RejectV(TVector3& v1, const TVector3& v2) { - float x = (v1 * v2) / (v2 * v2); + float x = DotP(v1, v2) / DotP(v2, v2); v1 -= x * v2; return v1; @@ -756,9 +797,9 @@ namespace Phanes::Core::Math { template TVector3 SignVectorV(TVector3& v1) { - v1.x = (v1.x >= 0) ? 1 : -1; - v1.y = (v1.y >= 0) ? 1 : -1; - v1.z = (v1.z >= 0) ? 1 : -1; + v1.x = (v1.x >= (T)0.0) ? (T)1.0 : (T)-1; + v1.y = (v1.y >= (T)0.0) ? (T)1.0 : (T)-1; + v1.z = (v1.z >= (T)0.0) ? (T)1.0 : (T)-1; return v1; } @@ -793,7 +834,7 @@ namespace Phanes::Core::Math { template T CosineAngle(const TVector3& v1, const TVector3& v2) { - return (v1 * v2) / (Magnitude(v1) * Magnitude(v2)); + return DotP(v1, v2) / ((Magnitude(v1) * Magnitude(v2))); } /** @@ -874,7 +915,7 @@ namespace Phanes::Core::Math { template inline bool IsNormalized(const TVector3& v1, T threshold = P_FLT_INAC) { - return (SqrMagnitude(v1) < threshold); + return (abs(SqrMagnitude(v1) - 1) < threshold); } /** @@ -939,6 +980,23 @@ namespace Phanes::Core::Math { return v1 / Magnitude(v1); } + + /** + * Returns signs of components in vector: -1 / +1 / 0. + * + * @param(v1) Vector one + * + * @return Vector with signs a components. + */ + + template + TVector3 SignVector(const TVector3& v1) + { + return TVector3((v1.x >= 0) ? 1 : -1, + (v1.y >= 0) ? 1 : -1, + (v1.z >= 0) ? 1 : -1); + } + /** * Reflects a vector on a surface * @@ -951,7 +1009,7 @@ namespace Phanes::Core::Math { template TVector3 Reflect(const TVector3& v1, const TVector3& normal) { - return v1 - (2 * DotP(v1, normal) * normal); + return (2 * DotP(v1, normal) * normal) - v1; } diff --git a/Engine/Source/Runtime/Core/public/Math/Vector3.inl b/Engine/Source/Runtime/Core/public/Math/Vector3.inl index f40271a..443970b 100644 --- a/Engine/Source/Runtime/Core/public/Math/Vector3.inl +++ b/Engine/Source/Runtime/Core/public/Math/Vector3.inl @@ -101,7 +101,7 @@ namespace Phanes::Core::Math } template - TVector3 operator+(TVector3& v1, const TVector3& v2) + TVector3 operator+(const TVector3& v1, const TVector3& v2) { TVector3 r; Detail::compute_vec3_add::map(r, v1, v2); @@ -109,7 +109,7 @@ namespace Phanes::Core::Math } template - TVector3 operator+(TVector3& v1, T s) + TVector3 operator+(const TVector3& v1, T s) { TVector3 r; Detail::compute_vec3_add::map(r, v1, s); @@ -117,7 +117,7 @@ namespace Phanes::Core::Math } template - TVector3 operator-(TVector3& v1, const TVector3& v2) + TVector3 operator-(const TVector3& v1, const TVector3& v2) { TVector3 r; Detail::compute_vec3_sub::map(r, v1, v2); @@ -125,7 +125,7 @@ namespace Phanes::Core::Math } template - TVector3 operator-(TVector3& v1, T s) + TVector3 operator-(const TVector3& v1, T s) { TVector3 r; Detail::compute_vec3_sub::map(r, v1, s); @@ -133,7 +133,7 @@ namespace Phanes::Core::Math } template - TVector3 operator*(TVector3& v1, const TVector3& v2) + TVector3 operator*(const TVector3& v1, const TVector3& v2) { TVector3 r; Detail::compute_vec3_mul::map(r, v1, v2); @@ -141,7 +141,7 @@ namespace Phanes::Core::Math } template - TVector3 operator*(TVector3& v1, T s) + TVector3 operator*(const TVector3& v1, T s) { TVector3 r; Detail::compute_vec3_mul::map(r, v1, s); @@ -149,7 +149,7 @@ namespace Phanes::Core::Math } template - TVector3 operator/(TVector3& v1, const TVector3& v2) + TVector3 operator/(const TVector3& v1, const TVector3& v2) { TVector3 r; Detail::compute_vec3_div::map(r, v1, v2); @@ -157,7 +157,7 @@ namespace Phanes::Core::Math } template - TVector3 operator/(TVector3& v1, T s) + TVector3 operator/(const TVector3& v1, T s) { TVector3 r; Detail::compute_vec3_div::map(r, v1, s); @@ -224,5 +224,6 @@ namespace Phanes::Core::Math TVector3 CrossPV(TVector3& v1, const TVector3& v2) { Detail::compute_vec3_cross_p::map(v1, v1, v2); + return v1; } } \ No newline at end of file diff --git a/MathTestFPU/test.cpp b/MathTestFPU/test.cpp index 08e0ae7..2817228 100644 --- a/MathTestFPU/test.cpp +++ b/MathTestFPU/test.cpp @@ -160,4 +160,138 @@ namespace VectorTests EXPECT_TRUE(PMath::Rotate(v0, (float)30.0_deg) == PMath::Vector2(0.528460969082653f, 3.88467875173176f)); EXPECT_TRUE(PMath::ClockwiseRotate(v0, (float)30.0_deg) == PMath::Vector2(3.628461f, 1.484679f)); } + + // -------------- + + TEST(Vector3, OperatorTests) + { + PMath::Vector3 v0(2.4f, 3.1f, 5.6f); + PMath::Vector3 v1(5.1f, 2.5f, 7.2f); + + + v0 += v1; + EXPECT_TRUE(v0 == PMath::Vector3(7.5f, 5.6f, 12.8f)); + + v0 -= v1; + EXPECT_TRUE(v0 == PMath::Vector3(2.4f, 3.1f, 5.6f)); + + v0 *= v1; + EXPECT_TRUE(v0 == PMath::Vector3(12.24f, 7.75f, 40.32f)); + + v0 /= v1; + EXPECT_TRUE(v0 == PMath::Vector3(2.4f, 3.1f, 5.6f)); + + + v0 += 4.0f; + EXPECT_TRUE(v0 == PMath::Vector3(6.4f, 7.1f, 9.6f)); + + v0 -= 4.0f; + EXPECT_TRUE(v0 == PMath::Vector3(2.4f, 3.1f, 5.6f)); + + v0 *= 4.0f; + EXPECT_TRUE(v0 == PMath::Vector3(9.6f, 12.4f, 22.4f)); + + v0 /= 4.0f; + EXPECT_TRUE(v0 == PMath::Vector3(2.4f, 3.1f, 5.6f)); + + // ------------------------------------------ + + PMath::Vector3 r; + + r = v0 + v1; + EXPECT_TRUE(r == PMath::Vector3(7.5f, 5.6f, 12.8f)); + + r = v0 - v1; + EXPECT_TRUE(r == PMath::Vector3(-2.7f, 0.6f, -1.6f)); + + r = v0 * v1; + EXPECT_TRUE(r == PMath::Vector3(12.24f, 7.75f, 40.32f)); + + r = v0 / v1; + EXPECT_TRUE(r == PMath::Vector3(0.470588f, 1.24f, 0.777777777777f)); + + + + r = v0 + 4.0f; + EXPECT_TRUE(r == PMath::Vector3(6.4f, 7.1f, 9.6f)); + + r = v0 - 4.0f; + EXPECT_TRUE(r == PMath::Vector3(-1.6f, -0.9f, 1.6f)); + + r = v0 * 4.0f; + EXPECT_TRUE(r == PMath::Vector3(9.6f, 12.4f, 22.4f)); + + r = v0 / 4.0f; + EXPECT_TRUE(r == PMath::Vector3(0.6f, 0.775f, 1.4f)); + + // -------------------------------------------- + + EXPECT_TRUE(r != PMath::Vector3(0.480588f, 3.24f, 34.5f)); + + EXPECT_FALSE(r != PMath::Vector3(0.6f, 0.775f, 1.4f)); + } + + TEST(Vector3, FunctionTest) + { + PMath::Vector3 v0(2.4f, 3.1f, 5.6f); + PMath::Vector3 v1(5.1f, 2.5f, 7.2f); + PMath::Vector3 v2(0.0f, 0.0f, 0.0f); + PMath::Vector3 n(0.70710678f, 0.42426406f, 0.56568542f); + + EXPECT_FLOAT_EQ(PMath::Magnitude(v0), 6.835934464f); + EXPECT_FLOAT_EQ(PMath::SqrMagnitude(v0), 46.73f); + EXPECT_TRUE(PMath::NormalizeV(v0) == PMath::Vector3(0.351086f, 0.453486f, 0.8192f)); + EXPECT_TRUE(PMath::NormalizeV(v2) == PMath::Vector3(0.0f, 0.0f, 0.0f)); + EXPECT_TRUE(PMath::IsNormalized(v0)); + EXPECT_TRUE(PMath::Abs(PMath::Angle(v0, v1) - 15.8372675_deg) < P_FLT_INAC); + EXPECT_FLOAT_EQ(PMath::CosineAngle(v0, v1), 0.962040687624f); + EXPECT_TRUE(PMath::SignVectorV(v0) == PMath::Vector3(1, 1, 1)); + + // Re-init vectors. + v0 = PMath::Vector3(2.4f, 3.1f, 5.6f); + + EXPECT_FLOAT_EQ(PMath::DotP(v0, v1), 60.31f); + + EXPECT_TRUE(PMath::MaxV(v0, v1) == PMath::Vector3(5.1f, 3.1f, 7.2f)); + + // Re-init vector + v0 = PMath::Vector3(2.4f, 3.1f, 5.6f); + + EXPECT_TRUE(PMath::MinV(v0, v1) == PMath::Vector3(2.4f, 2.5f, 5.6f)); + + EXPECT_TRUE(PMath::ReflectV(v0, n) == PMath::Vector3(5.979999f, 2.5279994f, 1.1039991f)); + + PMath::Vector3 up(PVectorUp3(float, false)); + PMath::Vector3 right(PVectorEast3(float, false)); + PMath::Vector3 front(5.4f, 0.0f, 0.0f); + + PMath::Orthogonalize(up, right, front); + EXPECT_TRUE(PMath::DotP(up, front) == 0.0f); + EXPECT_TRUE(PMath::DotP(right, front) == 0.0f); + + PMath::OrthoNormalize(up, right, front); + EXPECT_TRUE(PMath::DotP(up, front) == 0.0f); + EXPECT_TRUE(PMath::DotP(right, front) == 0.0f); + EXPECT_FLOAT_EQ(PMath::Magnitude(front), 1.0f); + + // Re-init vector + v0 = PMath::Vector3(2.4f, 3.1f, 5.6f); + + EXPECT_TRUE(PMath::PerspectiveDivideV(v0) == PMath::Vector3(0.4285714f, 0.55357142f, 0.0f)); + + // Re-init vector + v0 = PMath::Vector3(2.4f, 3.1f, 5.6f); + EXPECT_TRUE(PMath::CrossPV(v0,v1) == PMath::Vector3(8.32f,11.28,-9.81)); + EXPECT_TRUE(PMath::NegateV(v0) == PMath::Vector3(-8.32f, -11.28f, 9.81f)); + EXPECT_TRUE(PMath::ScaleV(v0, v1) == PMath::Vector3(-42.432f, -28.2f, 70.632f)); + + // Re-init vector + v0 = PMath::Vector3(2.4f, 3.1f, 5.6f); + EXPECT_TRUE(PMath::ProjectV(v0, v1) == PMath::Vector3(3.65732461f, 1.7928061f, 5.16328180f)); + + EXPECT_TRUE(PMath::IsPerpendicular(PMath::Reject(v0, v1), v1)); + // std::cerr << PMath::ToString(PMath::Magnitude(v0)) << std::endl; + // Re-init vector + v0 = PMath::Vector3(2.4f, 3.1f, 5.6f); + } } \ No newline at end of file