#include #include #include #include #include using namespace XCEngine::Math; namespace { // ============================================================ // Vector2 Tests // ============================================================ TEST(Math_Vector2, DefaultConstructor_InitializesToZero) { Vector2 v; EXPECT_FLOAT_EQ(v.x, 0.0f); EXPECT_FLOAT_EQ(v.y, 0.0f); } TEST(Math_Vector2, ParameterConstructor) { Vector2 v(3.0f, 4.0f); EXPECT_FLOAT_EQ(v.x, 3.0f); EXPECT_FLOAT_EQ(v.y, 4.0f); } TEST(Math_Vector2, StaticFactories) { EXPECT_EQ(Vector2::Zero(), Vector2(0, 0)); EXPECT_EQ(Vector2::One(), Vector2(1, 1)); EXPECT_EQ(Vector2::Up(), Vector2(0, 1)); EXPECT_EQ(Vector2::Down(), Vector2(0, -1)); EXPECT_EQ(Vector2::Right(), Vector2(1, 0)); EXPECT_EQ(Vector2::Left(), Vector2(-1, 0)); } TEST(Math_Vector2, Dot_Orthogonal_ReturnsZero) { EXPECT_FLOAT_EQ(Vector2::Dot(Vector2::Right(), Vector2::Up()), 0.0f); } TEST(Math_Vector2, Dot_SameDirection_ReturnsMagnitudeProduct) { EXPECT_FLOAT_EQ(Vector2::Dot(Vector2(1, 0), Vector2(2, 0)), 2.0f); } TEST(Math_Vector2, Cross_ReturnsScalar) { EXPECT_FLOAT_EQ(Vector2::Cross(Vector2::Right(), Vector2::Up()), 1.0f); } TEST(Math_Vector2, Magnitude) { EXPECT_FLOAT_EQ(Vector2(3, 4).Magnitude(), 5.0f); } TEST(Math_Vector2, SqrMagnitude) { EXPECT_FLOAT_EQ(Vector2(3, 4).SqrMagnitude(), 25.0f); } TEST(Math_Vector2, Normalize_NonZero_ReturnsUnitVector) { Vector2 v = Vector2(3, 4).Normalized(); EXPECT_NEAR(v.Magnitude(), 1.0f, 1e-6f); } TEST(Math_Vector2, Normalize_ZeroVector_ReturnsZeroVector) { Vector2 v = Vector2::Zero(); Vector2 normalized = Vector2::Normalize(v); EXPECT_FLOAT_EQ(normalized.x, 0.0f); EXPECT_FLOAT_EQ(normalized.y, 0.0f); } TEST(Math_Vector2, Lerp) { Vector2 a(0, 0); Vector2 b(10, 10); Vector2 result = Vector2::Lerp(a, b, 0.5f); EXPECT_FLOAT_EQ(result.x, 5.0f); EXPECT_FLOAT_EQ(result.y, 5.0f); } TEST(Math_Vector2, Lerp_ClampsToZero) { Vector2 a(0, 0); Vector2 b(10, 10); Vector2 result = Vector2::Lerp(a, b, -0.5f); EXPECT_FLOAT_EQ(result.x, 0.0f); } TEST(Math_Vector2, Lerp_ClampsToOne) { Vector2 a(0, 0); Vector2 b(10, 10); Vector2 result = Vector2::Lerp(a, b, 1.5f); EXPECT_FLOAT_EQ(result.x, 10.0f); } TEST(Math_Vector2, MoveTowards) { Vector2 current(0, 0); Vector2 target(10, 0); Vector2 result = Vector2::MoveTowards(current, target, 3.0f); EXPECT_FLOAT_EQ(result.x, 3.0f); EXPECT_FLOAT_EQ(result.y, 0.0f); } TEST(Math_Vector2, MoveTowards_AlreadyAtTarget) { Vector2 current(10, 10); Vector2 target(10, 10); Vector2 result = Vector2::MoveTowards(current, target, 5.0f); EXPECT_EQ(result, target); } TEST(Math_Vector2, Operators) { Vector2 a(1, 2); Vector2 b(3, 4); Vector2 sum = a + b; EXPECT_FLOAT_EQ(sum.x, 4.0f); EXPECT_FLOAT_EQ(sum.y, 6.0f); Vector2 diff = b - a; EXPECT_FLOAT_EQ(diff.x, 2.0f); EXPECT_FLOAT_EQ(diff.y, 2.0f); Vector2 scaled = a * 2.0f; EXPECT_FLOAT_EQ(scaled.x, 2.0f); EXPECT_FLOAT_EQ(scaled.y, 4.0f); Vector2 divided = a / 2.0f; EXPECT_FLOAT_EQ(divided.x, 0.5f); EXPECT_FLOAT_EQ(divided.y, 1.0f); } TEST(Math_Vector2, Equality) { Vector2 a(1.0f, 2.0f); Vector2 b(1.0f, 2.0f); Vector2 c(1.0f, 3.0f); EXPECT_TRUE(a == b); EXPECT_FALSE(a == c); } // ============================================================ // Vector3 Tests // ============================================================ TEST(Math_Vector3, DefaultConstructor_InitializesToZero) { Vector3 v; EXPECT_FLOAT_EQ(v.x, 0.0f); EXPECT_FLOAT_EQ(v.y, 0.0f); EXPECT_FLOAT_EQ(v.z, 0.0f); } TEST(Math_Vector3, ParameterConstructor) { Vector3 v(1.0f, 2.0f, 3.0f); EXPECT_FLOAT_EQ(v.x, 1.0f); EXPECT_FLOAT_EQ(v.y, 2.0f); EXPECT_FLOAT_EQ(v.z, 3.0f); } TEST(Math_Vector3, StaticFactories) { EXPECT_EQ(Vector3::Zero(), Vector3(0, 0, 0)); EXPECT_EQ(Vector3::One(), Vector3(1, 1, 1)); EXPECT_EQ(Vector3::Forward(), Vector3(0, 0, 1)); EXPECT_EQ(Vector3::Back(), Vector3(0, 0, -1)); EXPECT_EQ(Vector3::Up(), Vector3(0, 1, 0)); EXPECT_EQ(Vector3::Down(), Vector3(0, -1, 0)); EXPECT_EQ(Vector3::Right(), Vector3(1, 0, 0)); EXPECT_EQ(Vector3::Left(), Vector3(-1, 0, 0)); } TEST(Math_Vector3, Dot_Orthogonal_ReturnsZero) { EXPECT_FLOAT_EQ(Vector3::Dot(Vector3::Right(), Vector3::Up()), 0.0f); } TEST(Math_Vector3, Cross_Orthogonal_ReturnsPerpendicular) { Vector3 result = Vector3::Cross(Vector3::Right(), Vector3::Up()); EXPECT_FLOAT_EQ(result.x, 0.0f); EXPECT_FLOAT_EQ(result.y, 0.0f); EXPECT_FLOAT_EQ(result.z, 1.0f); } TEST(Math_Vector3, Cross_SameVector_ReturnsZero) { Vector3 result = Vector3::Cross(Vector3::Right(), Vector3::Right()); EXPECT_FLOAT_EQ(result.x, 0.0f); EXPECT_FLOAT_EQ(result.y, 0.0f); EXPECT_FLOAT_EQ(result.z, 0.0f); } TEST(Math_Vector3, Magnitude) { EXPECT_FLOAT_EQ(Vector3(1, 2, 2).Magnitude(), 3.0f); } TEST(Math_Vector3, SqrMagnitude) { EXPECT_FLOAT_EQ(Vector3(1, 2, 2).SqrMagnitude(), 9.0f); } TEST(Math_Vector3, Normalize) { Vector3 v = Vector3(3, 4, 0).Normalized(); EXPECT_NEAR(v.Magnitude(), 1.0f, 1e-6f); } TEST(Math_Vector3, Lerp) { Vector3 a(0, 0, 0); Vector3 b(10, 10, 10); Vector3 result = Vector3::Lerp(a, b, 0.5f); EXPECT_FLOAT_EQ(result.x, 5.0f); EXPECT_FLOAT_EQ(result.y, 5.0f); EXPECT_FLOAT_EQ(result.z, 5.0f); } TEST(Math_Vector3, Project_OntoNormal) { Vector3 v(1, 1, 0); Vector3 normal(1, 0, 0); Vector3 result = Vector3::Project(v, normal); EXPECT_FLOAT_EQ(result.x, 1.0f); EXPECT_FLOAT_EQ(result.y, 0.0f); EXPECT_FLOAT_EQ(result.z, 0.0f); } TEST(Math_Vector3, ProjectOnPlane) { Vector3 v(1, 1, 1); Vector3 planeNormal(0, 0, 1); Vector3 result = Vector3::ProjectOnPlane(v, planeNormal); EXPECT_FLOAT_EQ(result.x, 1.0f); EXPECT_FLOAT_EQ(result.y, 1.0f); EXPECT_FLOAT_EQ(result.z, 0.0f); } TEST(Math_Vector3, Angle) { float angle = Vector3::Angle(Vector3::Right(), Vector3::Up()); EXPECT_NEAR(angle, 90.0f, 1e-5f); } TEST(Math_Vector3, Reflect) { Vector3 direction(1, -1, 0); Vector3 normal(0, 1, 0); Vector3 result = Vector3::Reflect(direction, normal); EXPECT_FLOAT_EQ(result.x, 1.0f); EXPECT_FLOAT_EQ(result.y, 1.0f); EXPECT_FLOAT_EQ(result.z, 0.0f); } TEST(Math_Vector3, MoveTowards) { Vector3 current(0, 0, 0); Vector3 target(10, 0, 0); Vector3 result = Vector3::MoveTowards(current, target, 4.0f); EXPECT_FLOAT_EQ(result.x, 4.0f); } TEST(Math_Vector3, Operators) { Vector3 a(1, 2, 3); Vector3 b(4, 5, 6); Vector3 sum = a + b; EXPECT_FLOAT_EQ(sum.x, 5.0f); EXPECT_FLOAT_EQ(sum.y, 7.0f); EXPECT_FLOAT_EQ(sum.z, 9.0f); Vector3 diff = b - a; EXPECT_FLOAT_EQ(diff.x, 3.0f); EXPECT_FLOAT_EQ(diff.y, 3.0f); EXPECT_FLOAT_EQ(diff.z, 3.0f); Vector3 scaled = a * 2.0f; EXPECT_FLOAT_EQ(scaled.x, 2.0f); EXPECT_FLOAT_EQ(scaled.y, 4.0f); EXPECT_FLOAT_EQ(scaled.z, 6.0f); } TEST(Math_Vector3, IndexOperator) { Vector3 v(1, 2, 3); EXPECT_FLOAT_EQ(v[0], 1.0f); EXPECT_FLOAT_EQ(v[1], 2.0f); EXPECT_FLOAT_EQ(v[2], 3.0f); } // ============================================================ // Vector4 Tests // ============================================================ TEST(Math_Vector4, DefaultConstructor_InitializesToZero) { Vector4 v; EXPECT_FLOAT_EQ(v.x, 0.0f); EXPECT_FLOAT_EQ(v.y, 0.0f); EXPECT_FLOAT_EQ(v.z, 0.0f); EXPECT_FLOAT_EQ(v.w, 0.0f); } TEST(Math_Vector4, ParameterConstructor) { Vector4 v(1.0f, 2.0f, 3.0f, 4.0f); EXPECT_FLOAT_EQ(v.x, 1.0f); EXPECT_FLOAT_EQ(v.y, 2.0f); EXPECT_FLOAT_EQ(v.z, 3.0f); EXPECT_FLOAT_EQ(v.w, 4.0f); } TEST(Math_Vector4, ConstructFromVector3) { Vector3 v3(1, 2, 3); Vector4 v(v3, 4.0f); EXPECT_FLOAT_EQ(v.x, 1.0f); EXPECT_FLOAT_EQ(v.y, 2.0f); EXPECT_FLOAT_EQ(v.z, 3.0f); EXPECT_FLOAT_EQ(v.w, 4.0f); } TEST(Math_Vector4, StaticFactories) { EXPECT_EQ(Vector4::Zero(), Vector4(0, 0, 0, 0)); EXPECT_EQ(Vector4::One(), Vector4(1, 1, 1, 1)); } TEST(Math_Vector4, Dot) { Vector4 a(1, 2, 3, 4); Vector4 b(2, 3, 4, 5); float result = Vector4::Dot(a, b); EXPECT_FLOAT_EQ(result, 40.0f); } TEST(Math_Vector4, ToVector3) { Vector4 v(1, 2, 3, 4); Vector3 v3 = v.ToVector3(); EXPECT_FLOAT_EQ(v3.x, 1.0f); EXPECT_FLOAT_EQ(v3.y, 2.0f); EXPECT_FLOAT_EQ(v3.z, 3.0f); } TEST(Math_Vector4, Operators) { Vector4 a(1, 2, 3, 4); Vector4 b(5, 6, 7, 8); Vector4 sum = a + b; EXPECT_FLOAT_EQ(sum.x, 6.0f); EXPECT_FLOAT_EQ(sum.y, 8.0f); EXPECT_FLOAT_EQ(sum.z, 10.0f); EXPECT_FLOAT_EQ(sum.w, 12.0f); Vector4 scaled = a * 2.0f; EXPECT_FLOAT_EQ(scaled.x, 2.0f); } } // namespace