#include "unittest/TestSuite.h" #include "gamemath/Vector2f.h" #include "gamemath/Vector2i.h" #include "gamemath/Vector3f.h" #include "gamemath/Vector3i.h" #include "gamemath/Vector3x.h" #include "gamemath/Vector4f.h" #include "gamemath/Vector4d.h" #include #include #define assertVector2fExact(vector, expectedX, expectedY) { \ TestCase_assertFloatEqual(vector.x, (expectedX)); \ TestCase_assertFloatEqual(vector.y, (expectedY)); \ } #define assertVector3fExact(vector, expectedX, expectedY, expectedZ) { \ TestCase_assertFloatEqual(vector.x, (expectedX)); \ TestCase_assertFloatEqual(vector.y, (expectedY)); \ TestCase_assertFloatEqual(vector.z, (expectedZ)); \ } #define assertVector4fExact(vector, expectedX, expectedY, expectedZ, expectedW) { \ TestCase_assertFloatEqual(vector.x, (expectedX)); \ TestCase_assertFloatEqual(vector.y, (expectedY)); \ TestCase_assertFloatEqual(vector.z, (expectedZ)); \ TestCase_assertFloatEqual(vector.w, (expectedW)); \ } #define assertVector2fApproximate(vector, expectedX, expectedY, epsilon) { \ TestCase_assertFloatApproximate(vector.x, (expectedX), (epsilon)); \ TestCase_assertFloatApproximate(vector.y, (expectedY), (epsilon)); \ } #define assertVector3fApproximate(vector, expectedX, expectedY, expectedZ, epsilon) { \ TestCase_assertFloatApproximate(vector.x, (expectedX), (epsilon)); \ TestCase_assertFloatApproximate(vector.y, (expectedY), (epsilon)); \ TestCase_assertFloatApproximate(vector.z, (expectedZ), (epsilon)); \ } #define assertVector4fApproximate(vector, expectedX, expectedY, expectedZ, expectedW, epsilon) { \ TestCase_assertFloatApproximate(vector.x, (expectedX), (epsilon)); \ TestCase_assertFloatApproximate(vector.y, (expectedY), (epsilon)); \ TestCase_assertFloatApproximate(vector.z, (expectedZ), (epsilon)); \ TestCase_assertFloatApproximate(vector.w, (expectedW), (epsilon)); \ } #define assertVector2i(vector, expectedX, expectedY) { \ TestCase_assertIntEqual(vector.x, (expectedX)); \ TestCase_assertIntEqual(vector.y, (expectedY)); \ } #define assertVector3i(vector, expectedX, expectedY, expectedZ) { \ TestCase_assertIntEqual(vector.x, (expectedX)); \ TestCase_assertIntEqual(vector.y, (expectedY)); \ TestCase_assertIntEqual(vector.z, (expectedZ)); \ } #define assertVector3x(vector, expectedX, expectedY, expectedZ) { \ TestCase_assertFixed16_16Equal(vector.x, (expectedX)); \ TestCase_assertFixed16_16Equal(vector.y, (expectedY)); \ TestCase_assertFixed16_16Equal(vector.z, (expectedZ)); \ } #define assertVector4dExact(vector, expectedX, expectedY, expectedZ, expectedW) { \ TestCase_assertDoubleEqual(vector.x, (expectedX)); \ TestCase_assertDoubleEqual(vector.y, (expectedY)); \ TestCase_assertDoubleEqual(vector.z, (expectedZ)); \ TestCase_assertDoubleEqual(vector.w, (expectedW)); \ } #define EPSILON 0.0001f static void testInit(void) { Vector2f vector2; Vector3f vector3; Vector4f vector4; vector2 = VECTOR2f(0.0f, 1.0f); assertVector2fExact(vector2, 0.0f, 1.0f); vector2 = VECTOR2f(3.0f, 2.0f); assertVector2fExact(vector2, 3.0f, 2.0f); vector3 = VECTOR3f(0.0f, 1.0f, 2.0f); assertVector3fExact(vector3, 0.0f, 1.0f, 2.0f); vector3 = VECTOR3f(3.0f, 2.0f, 1.0f); assertVector3fExact(vector3, 3.0f, 2.0f, 1.0f); vector4 = VECTOR4f(0.0f, 1.0f, 2.0f, 3.0f); assertVector4fExact(vector4, 0.0f, 1.0f, 2.0f, 3.0f); vector4 = VECTOR4f(3.0f, 2.0f, 1.0f, 0.0f); assertVector4fExact(vector4, 3.0f, 2.0f, 1.0f, 0.0f); vector2 = VECTOR2f_REPEAT(0.0f); assertVector2fExact(vector2, 0.0f, 0.0f); vector2 = VECTOR2f_REPEAT(1.0f); assertVector2fExact(vector2, 1.0f, 1.0f); vector3 = VECTOR3f_REPEAT(0.0f); assertVector3fExact(vector3, 0.0f, 0.0f, 0.0f); vector3 = VECTOR3f_REPEAT(1.0f); assertVector3fExact(vector3, 1.0f, 1.0f, 1.0f); vector4 = VECTOR4f_REPEAT(0.0f); assertVector4fExact(vector4, 0.0f, 0.0f, 0.0f, 0.0f); vector4 = VECTOR4f_REPEAT(1.0f); assertVector4fExact(vector4, 1.0f, 1.0f, 1.0f, 1.0f); } static void testPrefabs(void) { Vector2f vector2; Vector3f vector3; Vector4f vector4; vector2 = VECTOR2f_ZERO; assertVector2fExact(vector2, 0.0f, 0.0f); vector3 = VECTOR3f_ZERO; assertVector3fExact(vector3, 0.0f, 0.0f, 0.0f); vector4 = VECTOR4f_ZERO; assertVector4fExact(vector4, 0.0f, 0.0f, 0.0f, 0.0f); vector3 = VECTOR3f_LEFT; assertVector3fExact(vector3, -1.0f, 0.0f, 0.0f); vector3 = VECTOR3f_RIGHT; assertVector3fExact(vector3, 1.0f, 0.0f, 0.0f); vector3 = VECTOR3f_DOWN; assertVector3fExact(vector3, 0.0f, -1.0f, 0.0f); vector3 = VECTOR3f_UP; assertVector3fExact(vector3, 0.0f, 1.0f, 0.0f); vector3 = VECTOR3f_BACK; assertVector3fExact(vector3, 0.0f, 0.0f, -1.0f); vector3 = VECTOR3f_FRONT; assertVector3fExact(vector3, 0.0f, 0.0f, 1.0f); } static void testNormalize(void) { Vector2f vector2, vector2Normalized; Vector3f vector3, vector3Normalized; Vector4f vector4, vector4Normalized; bool success; vector2 = VECTOR2f(5.0f, 0.0f); vector2Normalized = Vector2f_normalized(vector2); success = Vector2f_normalize(&vector2); TestCase_assert(!memcmp(&vector2, &vector2Normalized, sizeof(Vector2f)), "Vector2f_normalize produced different results (%f, %f) than Vector2f_normalized (%f, %f)", vector2.x, vector2.y, vector2Normalized.x, vector2Normalized.y); TestCase_assert(success, "Expected true but got false"); assertVector2fApproximate(vector2, 1.0f, 0.0f, EPSILON); vector2 = VECTOR2f(1.0f, 1.0f); vector2Normalized = Vector2f_normalized(vector2); success = Vector2f_normalize(&vector2); TestCase_assert(!memcmp(&vector2, &vector2Normalized, sizeof(Vector2f)), "Vector2f_normalize produced different results (%f, %f) than Vector2f_normalized (%f, %f)", vector2.x, vector2.y, vector2Normalized.x, vector2Normalized.y); TestCase_assert(success, "Expected true but got false"); assertVector2fApproximate(vector2, 0.707106781186548f, 0.707106781186548f, EPSILON); vector2 = VECTOR2f(0.0f, 0.0f); vector2Normalized = Vector2f_normalized(vector2); success = Vector2f_normalize(&vector2); TestCase_assert(!memcmp(&vector2, &vector2Normalized, sizeof(Vector2f)), "Vector2f_normalize produced different results (%f, %f) than Vector2f_normalized (%f, %f)", vector2.x, vector2.y, vector2Normalized.x, vector2Normalized.y); TestCase_assert(!success, "Expected false but got true"); assertVector2fExact(vector2, 0.0f, 0.0f); vector3 = VECTOR3f(0.0f, 5.0f, 0.0f); vector3Normalized = Vector3f_normalized(vector3); success = Vector3f_normalize(&vector3); TestCase_assert(!memcmp(&vector3, &vector3Normalized, sizeof(Vector3f)), "Vector3f_normalize produced different results (%f, %f, %f) than Vector3f_normalized (%f, %f, %f)", vector3.x, vector3.y, vector3.z, vector3Normalized.x, vector3Normalized.y, vector3Normalized.z); TestCase_assert(success, "Expected true but got false"); assertVector3fApproximate(vector3, 0.0f, 1.0f, 0.0f, EPSILON); vector3 = VECTOR3f(1.0f, 1.0f, 1.0f); vector3Normalized = Vector3f_normalized(vector3); success = Vector3f_normalize(&vector3); TestCase_assert(!memcmp(&vector3, &vector3Normalized, sizeof(Vector3f)), "Vector3f_normalize produced different results (%f, %f, %f) than Vector3f_normalized (%f, %f, %f)", vector3.x, vector3.y, vector3.z, vector3Normalized.x, vector3Normalized.y, vector3Normalized.z); TestCase_assert(success, "Expected true but got false"); assertVector3fApproximate(vector3, 0.577350269189626f, 0.577350269189626f, 0.577350269189626f, EPSILON); vector3 = VECTOR3f(0.0f, 0.0f, 0.0f); vector3Normalized = Vector3f_normalized(vector3); success = Vector3f_normalize(&vector3); TestCase_assert(!memcmp(&vector3, &vector3Normalized, sizeof(Vector3f)), "Vector3f_normalize produced different results (%f, %f, %f) than Vector3f_normalized (%f, %f, %f)", vector3.x, vector3.y, vector3.z, vector3Normalized.x, vector3Normalized.y, vector3Normalized.z); TestCase_assert(!success, "Expected false but got true"); assertVector3fExact(vector3, 0.0f, 0.0f, 0.0f); vector4 = VECTOR4f(0.0f, 0.0f, 5.0f, 0.0f); vector4Normalized = Vector4f_normalized(vector4); success = Vector4f_normalize(&vector4); TestCase_assert(!memcmp(&vector4, &vector4Normalized, sizeof(Vector4f)), "Vector4f_normalize produced different results (%f, %f, %f, %f) than Vector4f_normalized (%f, %f, %f, %f)", vector4.x, vector4.y, vector4.z, vector4.w, vector4Normalized.x, vector4Normalized.y, vector4Normalized.z, vector4Normalized.w); TestCase_assert(success, "Expected true but got false"); assertVector4fApproximate(vector4, 0.0f, 0.0f, 1.0f, 0.0f, EPSILON); vector4 = VECTOR4f(1.0f, 1.0f, 1.0f, 1.0f); vector4Normalized = Vector4f_normalized(vector4); success = Vector4f_normalize(&vector4); TestCase_assert(!memcmp(&vector4, &vector4Normalized, sizeof(Vector4f)), "Vector4f_normalize produced different results (%f, %f, %f, %f) than Vector4f_normalized (%f, %f, %f, %f)", vector4.x, vector4.y, vector4.z, vector4.w, vector4Normalized.x, vector4Normalized.y, vector4Normalized.z, vector4Normalized.w); TestCase_assert(success, "Expected true but got false"); assertVector4fApproximate(vector4, 0.5f, 0.5f, 0.5f, 0.5f, EPSILON); vector4 = VECTOR4f(0.0f, 0.0f, 0.0f, 0.0f); vector4Normalized = Vector4f_normalized(vector4); success = Vector4f_normalize(&vector4); TestCase_assert(!memcmp(&vector4, &vector4Normalized, sizeof(Vector4f)), "Vector4f_normalize produced different results (%f, %f, %f, %f) than Vector4f_normalized (%f, %f, %f, %f)", vector4.x, vector4.y, vector4.z, vector4.w, vector4Normalized.x, vector4Normalized.y, vector4Normalized.z, vector4Normalized.w); TestCase_assert(!success, "Expected false but got true"); assertVector4fExact(vector4, 0.0f, 0.0f, 0.0f, 0.0f); } static void testInvert(void) { Vector2f vector2, vector2Inverted; Vector3f vector3, vector3Inverted; Vector4f vector4, vector4Inverted; vector2 = VECTOR2f(1.0f, -1.0f); vector2Inverted = Vector2f_inverted(vector2); Vector2f_invert(&vector2); assertVector2fExact(vector2, -1.0f, 1.0f); assertVector2fExact(vector2Inverted, -1.0f, 1.0f); vector2 = VECTOR2f(-0.25f, 3.0f); vector2Inverted = Vector2f_inverted(vector2); Vector2f_invert(&vector2); assertVector2fExact(vector2, 0.25f, -3.0f); assertVector2fExact(vector2Inverted, 0.25f, -3.0f); vector3 = VECTOR3f(1.0f, -1.0f, 2.0f); vector3Inverted = Vector3f_inverted(vector3); Vector3f_invert(&vector3); assertVector3fExact(vector3, -1.0f, 1.0f, -2.0f); assertVector3fExact(vector3Inverted, -1.0f, 1.0f, -2.0f); vector3 = VECTOR3f(-0.25f, 3.0f, -2.5f); vector3Inverted = Vector3f_inverted(vector3); Vector3f_invert(&vector3); assertVector3fExact(vector3, 0.25f, -3.0f, 2.5f); assertVector3fExact(vector3Inverted, 0.25f, -3.0f, 2.5f); vector4 = VECTOR4f(1.0f, -1.0f, 2.0f, -2.0f); vector4Inverted = Vector4f_inverted(vector4); Vector4f_invert(&vector4); assertVector4fExact(vector4, -1.0f, 1.0f, -2.0f, 2.0f); assertVector4fExact(vector4Inverted, -1.0f, 1.0f, -2.0f, 2.0f); vector4 = VECTOR4f(-0.25f, 3.0f, -2.5f, 2.75f); vector4Inverted = Vector4f_inverted(vector4); Vector4f_invert(&vector4); assertVector4fExact(vector4, 0.25f, -3.0f, 2.5f, -2.75f); assertVector4fExact(vector4Inverted, 0.25f, -3.0f, 2.5f, -2.75f); } static void testMagnitude(void) { float magnitude; magnitude = Vector2f_magnitude(VECTOR2f(1.0f, 0.0f)); TestCase_assert(fabs(magnitude - 1.0f) < EPSILON, "Expected 1.0 but got %f", magnitude); magnitude = Vector2f_magnitude(VECTOR2f(1.4142135623731f, 1.4142135623731f)); TestCase_assert(fabs(magnitude - 2.0f) < EPSILON, "Expected 2.0 but got %f", magnitude); magnitude = Vector3f_magnitude(VECTOR3f(0.0f, 1.0f, 0.0f)); TestCase_assert(fabs(magnitude - 1.0f) < EPSILON, "Expected 1.0 but got %f", magnitude); magnitude = Vector3f_magnitude(VECTOR3f(1.4142135623731f, 1.4142135623731f, 1.4142135623731f)); TestCase_assert(fabs(magnitude - 2.44948974278318f) < EPSILON, "Expected 2.44948974278318 but got %f", magnitude); magnitude = Vector4f_magnitude(VECTOR4f(0.0f, 0.0f, 1.0f, 0.0f)); TestCase_assert(fabs(magnitude - 1.0f) < EPSILON, "Expected 1.0 but got %f", magnitude); magnitude = Vector4f_magnitude(VECTOR4f(1.4142135623731f, 1.4142135623731f, 1.4142135623731f, 1.4142135623731f)); TestCase_assert(fabs(magnitude - 2.82842712474619f) < EPSILON, "Expected 2.82842712474619 but got %f", magnitude); magnitude = Vector2f_magnitudeSquared(VECTOR2f(1.0f, 0.0f)); TestCase_assert(fabs(magnitude - 1.0f) < EPSILON, "Expected 1.0 but got %f", magnitude); magnitude = Vector2f_magnitudeSquared(VECTOR2f(1.4142135623731f, 1.4142135623731f)); TestCase_assert(fabs(magnitude - 4.0f) < EPSILON, "Expected 4.0 but got %f", magnitude); magnitude = Vector3f_magnitudeSquared(VECTOR3f(0.0f, 1.0f, 0.0f)); TestCase_assert(fabs(magnitude - 1.0f) < EPSILON, "Expected 1.0 but got %f", magnitude); magnitude = Vector3f_magnitudeSquared(VECTOR3f(1.4142135623731f, 1.4142135623731f, 1.4142135623731f)); TestCase_assert(fabs(magnitude - 6.0f) < EPSILON, "Expected 6.0 but got %f", magnitude); magnitude = Vector4f_magnitudeSquared(VECTOR4f(0.0f, 0.0f, 1.0f, 0.0f)); TestCase_assert(fabs(magnitude - 1.0f) < EPSILON, "Expected 1.0 but got %f", magnitude); magnitude = Vector4f_magnitudeSquared(VECTOR4f(1.4142135623731f, 1.4142135623731f, 1.4142135623731f, 1.4142135623731f)); TestCase_assert(fabs(magnitude - 8.0f) < EPSILON, "Expected 8.0 but got %f", magnitude); } static void testDistance(void) { float distance; distance = Vector2f_distance(VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 0.0f)); TestCase_assert(fabs(distance - 1.0f) < EPSILON, "Expected 1.0 but got %f", distance); distance = Vector2f_distance(VECTOR2f(0.0f, 1.0f), VECTOR2f(-1.0f, 2.0f)); TestCase_assert(fabs(distance - 1.4142135623731f) < EPSILON, "Expected 1.4142135623731 but got %f", distance); distance = Vector3f_distance(VECTOR3f(0.0f, 1.0f, 0.0f), VECTOR3f(0.0f, 0.0f, 0.0f)); TestCase_assert(fabs(distance - 1.0f) < EPSILON, "Expected 1.0 but got %f", distance); distance = Vector3f_distance(VECTOR3f(0.0f, 0.0f, 1.0f), VECTOR3f(0.0f, -1.0f, 2.0f)); TestCase_assert(fabs(distance - 1.4142135623731f) < EPSILON, "Expected 1.4142135623731 but got %f", distance); distance = Vector4f_distance(VECTOR4f(0.0f, 0.0f, 1.0f, 0.0f), VECTOR4f(0.0f, 0.0f, 0.0f, 0.0f)); TestCase_assert(fabs(distance - 1.0f) < EPSILON, "Expected 1.0 but got %f", distance); distance = Vector4f_distance(VECTOR4f(0.0f, 0.0f, 0.0f, 1.0f), VECTOR4f(0.0f, 0.0f, -1.0f, 2.0f)); TestCase_assert(fabs(distance - 1.4142135623731f) < EPSILON, "Expected 1.4142135623731 but got %f", distance); distance = Vector2f_distanceSquared(VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 0.0f)); TestCase_assert(fabs(distance - 1.0f) < EPSILON, "Expected 1.0 but got %f", distance); distance = Vector2f_distanceSquared(VECTOR2f(0.0f, 1.0f), VECTOR2f(-1.0f, 2.0f)); TestCase_assert(fabs(distance - 2.0f) < EPSILON, "Expected 2.0 but got %f", distance); distance = Vector3f_distanceSquared(VECTOR3f(0.0f, 1.0f, 0.0f), VECTOR3f(0.0f, 0.0f, 0.0f)); TestCase_assert(fabs(distance - 1.0f) < EPSILON, "Expected 1.0 but got %f", distance); distance = Vector3f_distanceSquared(VECTOR3f(0.0f, 0.0f, 1.0f), VECTOR3f(0.0f, -1.0f, 2.0f)); TestCase_assert(fabs(distance - 2.0f) < EPSILON, "Expected 2.0 but got %f", distance); distance = Vector4f_distanceSquared(VECTOR4f(0.0f, 0.0f, 1.0f, 0.0f), VECTOR4f(0.0f, 0.0f, 0.0f, 0.0f)); TestCase_assert(fabs(distance - 1.0f) < EPSILON, "Expected 1.0 but got %f", distance); distance = Vector4f_distanceSquared(VECTOR4f(0.0f, 0.0f, 0.0f, 1.0f), VECTOR4f(0.0f, 0.0f, -1.0f, 2.0f)); TestCase_assert(fabs(distance - 2.0f) < EPSILON, "Expected 2.0 but got %f", distance); } static void testArithmetic(void) { Vector2f vector2; Vector3f vector3; Vector4f vector4; vector2 = Vector2f_add(VECTOR2f(0.0f, 1.0f), VECTOR2f(2.0f, 3.0f)); assertVector2fApproximate(vector2, 2.0f, 4.0f, EPSILON); vector2 = Vector2f_add(VECTOR2f(1.5f, 0.5f), VECTOR2f(0.25f, -0.25f)); assertVector2fApproximate(vector2, 1.75f, 0.25f, EPSILON); vector2 = Vector2f_subtract(VECTOR2f(0.0f, 1.0f), VECTOR2f(2.0f, 3.0f)); assertVector2fApproximate(vector2, -2.0f, -2.0f, EPSILON); vector2 = Vector2f_subtract(VECTOR2f(1.5f, 0.5f), VECTOR2f(0.25f, -0.25f)); assertVector2fApproximate(vector2, 1.25f, 0.75f, EPSILON); vector2 = Vector2f_multiplyScalar(VECTOR2f(1.0f, 2.0f), 0.5f); assertVector2fApproximate(vector2, 0.5f, 1.0f, EPSILON); vector2 = Vector2f_multiplyScalar(VECTOR2f(3.0f, 4.0f), -2.0f); assertVector2fApproximate(vector2, -6.0f, -8.0f, EPSILON); vector2 = Vector2f_divideScalar(VECTOR2f(1.0f, 2.0f), 0.5f); assertVector2fApproximate(vector2, 2.0f, 4.0f, EPSILON); vector2 = Vector2f_divideScalar(VECTOR2f(3.0f, 4.0f), -2.0f); assertVector2fApproximate(vector2, -1.5f, -2.0f, EPSILON); vector2 = Vector2f_multiplyComponents(VECTOR2f(1.0f, 2.0f), VECTOR2f(0.5f, 1.5f)); assertVector2fApproximate(vector2, 0.5f, 3.0f, EPSILON); vector2 = Vector2f_multiplyComponents(VECTOR2f(3.0f, 4.0f), VECTOR2f(-2.0f, -1.0f)); assertVector2fApproximate(vector2, -6.0f, -4.0f, EPSILON); vector2 = Vector2f_divideComponents(VECTOR2f(1.0f, 2.0f), VECTOR2f(0.5f, 2.0f)); assertVector2fApproximate(vector2, 2.0f, 1.0f, EPSILON); vector2 = Vector2f_divideComponents(VECTOR2f(3.0f, 4.0f), VECTOR2f(-2.0f, -0.5f)); assertVector2fApproximate(vector2, -1.5f, -8.0f, EPSILON); vector3 = Vector3f_add(VECTOR3f(0.0f, 1.0f, 2.0f), VECTOR3f(2.0f, 3.0f, 4.0f)); assertVector3fApproximate(vector3, 2.0f, 4.0f, 6.0f, EPSILON); vector3 = Vector3f_add(VECTOR3f(1.5f, 0.5f, -0.5f), VECTOR3f(0.25f, -0.25f, 0.0f)); assertVector3fApproximate(vector3, 1.75f, 0.25f, -0.5f, EPSILON); vector3 = Vector3f_subtract(VECTOR3f(0.0f, 1.0f, 2.0f), VECTOR3f(2.0f, 3.0f, 4.0f)); assertVector3fApproximate(vector3, -2.0f, -2.0f, -2.0f, EPSILON); vector3 = Vector3f_subtract(VECTOR3f(1.5f, 0.5f, -0.5f), VECTOR3f(0.25f, -0.25f, 0.0f)); assertVector3fApproximate(vector3, 1.25f, 0.75f, -0.5f, EPSILON); vector3 = Vector3f_multiplyScalar(VECTOR3f(1.0f, 2.0f, 3.0f), 0.5f); assertVector3fApproximate(vector3, 0.5f, 1.0f, 1.5f, EPSILON); vector3 = Vector3f_multiplyScalar(VECTOR3f(3.0f, 4.0f, 5.0f), -2.0f); assertVector3fApproximate(vector3, -6.0f, -8.0f, -10.0f, EPSILON); vector3 = Vector3f_divideScalar(VECTOR3f(1.0f, 2.0f, 3.0f), 0.5f); assertVector3fApproximate(vector3, 2.0f, 4.0f, 6.0f, EPSILON); vector3 = Vector3f_divideScalar(VECTOR3f(3.0f, 4.0f, 5.0f), -2.0f); assertVector3fApproximate(vector3, -1.5f, -2.0f, -2.5f, EPSILON); vector3 = Vector3f_multiplyComponents(VECTOR3f(1.0f, 2.0f, 3.0f), VECTOR3f(0.5f, 1.5f, 2.0f)); assertVector3fApproximate(vector3, 0.5f, 3.0f, 6.0f, EPSILON); vector3 = Vector3f_multiplyComponents(VECTOR3f(3.0f, 4.0f, 5.0f), VECTOR3f(-2.0f, -1.0f, -0.5f)); assertVector3fApproximate(vector3, -6.0f, -4.0f, -2.5f, EPSILON); vector3 = Vector3f_divideComponents(VECTOR3f(1.0f, 2.0f, 3.0f), VECTOR3f(0.5f, 2.0f, 3.0f)); assertVector3fApproximate(vector3, 2.0f, 1.0f, 1.0f, EPSILON); vector3 = Vector3f_divideComponents(VECTOR3f(3.0f, 4.0f, 5.0f), VECTOR3f(-2.0f, -0.5f, -2.0f)); assertVector3fApproximate(vector3, -1.5f, -8.0f, -2.5f, EPSILON); vector4 = Vector4f_add(VECTOR4f(0.0f, 1.0f, 2.0f, 3.0f), VECTOR4f(2.0f, 3.0f, 4.0f, 5.0f)); assertVector4fApproximate(vector4, 2.0f, 4.0f, 6.0f, 8.0f, EPSILON); vector4 = Vector4f_add(VECTOR4f(1.5f, 0.5f, -0.5f, -1.5f), VECTOR4f(0.25f, -0.25f, 0.0f, 0.1f)); assertVector4fApproximate(vector4, 1.75f, 0.25f, -0.5f, -1.4f, EPSILON); vector4 = Vector4f_subtract(VECTOR4f(0.0f, 1.0f, 2.0f, 3.0f), VECTOR4f(2.0f, 3.0f, 4.0f, 5.0f)); assertVector4fApproximate(vector4, -2.0f, -2.0f, -2.0f, -2.0f, EPSILON); vector4 = Vector4f_subtract(VECTOR4f(1.5f, 0.5f, -0.5f, -1.5f), VECTOR4f(0.25f, -0.25f, 0.0f, 0.1f)); assertVector4fApproximate(vector4, 1.25f, 0.75f, -0.5f, -1.6f, EPSILON); vector4 = Vector4f_multiplyScalar(VECTOR4f(1.0f, 2.0f, 3.0f, 4.0f), 0.5f); assertVector4fApproximate(vector4, 0.5f, 1.0f, 1.5f, 2.0f, EPSILON); vector4 = Vector4f_multiplyScalar(VECTOR4f(3.0f, 4.0f, 5.0f, 6.0f), -2.0f); assertVector4fApproximate(vector4, -6.0f, -8.0f, -10.0f, -12.0f, EPSILON); vector4 = Vector4f_divideScalar(VECTOR4f(1.0f, 2.0f, 3.0f, 4.0f), 0.5f); assertVector4fApproximate(vector4, 2.0f, 4.0f, 6.0f, 8.0f, EPSILON); vector4 = Vector4f_divideScalar(VECTOR4f(3.0f, 4.0f, 5.0f, 6.0f), -2.0f); assertVector4fApproximate(vector4, -1.5f, -2.0f, -2.5f, -3.0f, EPSILON); vector4 = Vector4f_multiplyComponents(VECTOR4f(1.0f, 2.0f, 3.0f, 4.0f), VECTOR4f(0.5f, 1.5f, 2.0f, 2.5f)); assertVector4fApproximate(vector4, 0.5f, 3.0f, 6.0f, 10.0f, EPSILON); vector4 = Vector4f_multiplyComponents(VECTOR4f(3.0f, 4.0f, 5.0f, 6.0f), VECTOR4f(-2.0f, -1.0f, -0.5f, -1.5f)); assertVector4fApproximate(vector4, -6.0f, -4.0f, -2.5f, -9.0f, EPSILON); vector4 = Vector4f_divideComponents(VECTOR4f(1.0f, 2.0f, 3.0f, 4.0f), VECTOR4f(0.5f, 2.0f, 3.0f, 4.0f)); assertVector4fApproximate(vector4, 2.0f, 1.0f, 1.0f, 1.0f, EPSILON); vector4 = Vector4f_divideComponents(VECTOR4f(3.0f, 4.0f, 5.0f, 6.0f), VECTOR4f(-2.0f, -0.5f, -2.0f, -0.5f)); assertVector4fApproximate(vector4, -1.5f, -8.0f, -2.5f, -12.0f, EPSILON); } static void testInterpolate(void) { Vector2f vector2; Vector3f vector3; Vector4f vector4; vector2 = Vector2f_interpolate(VECTOR2f(0.0f, 1.0f), VECTOR2f(1.0f, 0.0f), 0.25f); assertVector2fApproximate(vector2, 0.25f, 0.75f, EPSILON); vector2 = Vector2f_interpolate(VECTOR2f(3.0f, -3.0f), VECTOR2f(0.0f, 0.0f), 1.5f); assertVector2fApproximate(vector2, -1.5f, 1.5f, EPSILON); vector3 = Vector3f_interpolate(VECTOR3f(0.0f, 1.0f, 2.0f), VECTOR3f(1.0f, 0.0f, -2.0f), 0.25f); assertVector3fApproximate(vector3, 0.25f, 0.75f, 1.0f, EPSILON); vector3 = Vector3f_interpolate(VECTOR3f(3.0f, -3.0f, 1.0f), VECTOR3f(0.0f, 0.0f, 1.5f), -0.5f); assertVector3fApproximate(vector3, 4.5f, -4.5f, 0.75f, EPSILON); vector4 = Vector4f_interpolate(VECTOR4f(0.0f, 1.0f, 2.0f, 3.0f), VECTOR4f(1.0f, 0.0f, -2.0f, -3.0f), 0.5f); assertVector4fApproximate(vector4, 0.5f, 0.5f, 0.0f, 0.0f, EPSILON); vector4 = Vector4f_interpolate(VECTOR4f(4.0f, -3.0f, 1.0f, -2.0f), VECTOR4f(0.0f, -1.0f, 1.5f, -1.0), 0.75f); assertVector4fApproximate(vector4, 1.0f, -1.5f, 1.375f, -1.25f, EPSILON); } static void testRound(void) { Vector2f vector2f; Vector3x vector3x; Vector4d vector4d; vector2f = Vector2f_round(VECTOR2f(1.5f, -6.5f)); assertVector2fExact(vector2f, 2.0f, -6.0f); vector2f = Vector2f_round(VECTOR2f(-3.7f, 2.1f)); assertVector2fExact(vector2f, -4.0f, 2.0f); vector3x = Vector3x_round(VECTOR3x(0x18000, -0x68000, 0x00000)); assertVector3x(vector3x, 0x20000, -0x60000, 0x00000); vector3x = Vector3x_round(VECTOR3x(-0x39000, 0x21000, 0x27FFF)); assertVector3x(vector3x, -0x40000, 0x20000, 0x20000); vector4d = Vector4d_round(VECTOR4d(1.5, -6.5, 0.0, -0.9)); assertVector4dExact(vector4d, 2.0, -6.0, 0.0, -1.0); vector4d = Vector4d_round(VECTOR4d(-3.7, 2.1, 2.49, -1.1)); assertVector4dExact(vector4d, -4.0, 2.0, 2.0, -1.0); } static void testReflect(void) { Vector2f vector2; Vector3f vector3; Vector4f vector4; vector2 = Vector2f_reflect(VECTOR2f(0.0f, 1.0f), VECTOR2f(sqrtf(0.5f), sqrtf(0.5f))); assertVector2fApproximate(vector2, -1.0f, 0.0f, EPSILON); vector2 = Vector2f_reflect(VECTOR2f(-5.0f, 1.0f), VECTOR2f(-1.0f, 0.0f)); assertVector2fApproximate(vector2, 5.0f, 1.0f, EPSILON); vector3 = Vector3f_reflect(VECTOR3f(0.0f, 1.0f, 0.0f), VECTOR3f(0.0f, sqrtf(0.5f), sqrtf(0.5f))); assertVector3fApproximate(vector3, 0.0f, 0.0f, -1.0f, EPSILON); vector3 = Vector3f_reflect(VECTOR3f(-5.0f, 1.0f, 0.0f), VECTOR3f(-1.0f, 0.0f, 0.0f)); assertVector3fApproximate(vector3, 5.0f, 1.0f, 0.0f, EPSILON); vector4 = Vector4f_reflect(VECTOR4f(0.0f, 1.0f, 0.0f, 0.0f), VECTOR4f(0.0f, 0.0f, sqrtf(0.5f), sqrtf(0.5f))); assertVector4fApproximate(vector4, 0.0f, 1.0f, 0.0f, 0.0f, EPSILON); vector4 = Vector4f_reflect(VECTOR4f(-5.0f, 1.0f, 0.0f, 0.0f), VECTOR4f(-1.0f, 0.0f, 0.0f, 0.0f)); assertVector4fApproximate(vector4, 5.0f, 1.0f, 0.0f, 0.0f, EPSILON); } static void testProject(void) { Vector2f vector2; Vector3f vector3; Vector4f vector4; vector2 = Vector2f_project(VECTOR2f(0.0f, 1.0f), VECTOR2f(sqrtf(0.5f), sqrtf(0.5f))); assertVector2fApproximate(vector2, -0.5f, 0.5f, EPSILON); vector2 = Vector2f_project(VECTOR2f(-1.0f, -2.0f), VECTOR2f(sqrtf(0.5f), sqrtf(0.5f))); assertVector2fApproximate(vector2, 0.5f, -0.5f, EPSILON); vector2 = Vector2f_project(VECTOR2f(-1.0f, -2.0f), VECTOR2f(0.0f, 1.0f)); assertVector2fApproximate(vector2, -1.0f, 0.0f, EPSILON); vector3 = Vector3f_project(VECTOR3f(0.0f, 0.0f, 1.0f), VECTOR3f(0.0f, sqrtf(0.5f), sqrtf(0.5f))); assertVector3fApproximate(vector3, 0.0f, -0.5f, 0.5f, EPSILON); vector3 = Vector3f_project(VECTOR3f(-1.0f, -2.0f, 0.0f), VECTOR3f(sqrtf(0.5f), sqrtf(0.5f), 0.0f)); assertVector3fApproximate(vector3, 0.5f, -0.5f, 0.0f, EPSILON); vector3 = Vector3f_project(VECTOR3f(-1.0f, -2.0f, 1.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fApproximate(vector3, -1.0f, 0.0f, 1.0f, EPSILON); vector4 = Vector4f_project(VECTOR4f(0.0f, 0.0f, 0.0f, 1.0f), VECTOR4f(0.0f, 0.0f, sqrtf(0.5f), sqrtf(0.5f))); assertVector4fApproximate(vector4, 0.0f, 0.0f, -0.5f, 0.5f, EPSILON); vector4 = Vector4f_project(VECTOR4f(-1.0f, 0.0f, -2.0f, 0.0f), VECTOR4f(sqrtf(0.5f), 0.0f, sqrtf(0.5f), 0.0f)); assertVector4fApproximate(vector4, 0.5f, 0.0f, -0.5f, 0.0f, EPSILON); vector4 = Vector4f_project(VECTOR4f(-1.0f, -2.0f, 1.0f, 4.0f), VECTOR4f(0.0f, 1.0f, 0.0f, 0.0f)); assertVector4fApproximate(vector4, -1.0f, 0.0f, 1.0f, 4.0f, EPSILON); } static void testIntersect(void) { Vector2f vector2; float distance; bool success = Vector2f_intersectLine(VECTOR2f(-1.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(-1.0f, 0.0f), &vector2, &distance); TestCase_assertBoolTrue(success); assertVector2fApproximate(vector2, 0.0f, 0.0f, EPSILON); TestCase_assertFloatApproximate(distance, 1.0f, EPSILON); success = Vector2f_intersectLine(VECTOR2f(-1.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 1.0f), &vector2, &distance); TestCase_assertBoolFalse(success); success = Vector2f_intersectLine(VECTOR2f(0.0f, 2.0f), VECTOR2f(sqrtf(0.5f), -sqrtf(0.5f)), VECTOR2f(0.0f, 1.0f), &vector2, &distance); TestCase_assertBoolTrue(success); assertVector2fApproximate(vector2, 2.0f, 0.0f, EPSILON); TestCase_assertFloatApproximate(distance, sqrtf(2.0f) * 2, EPSILON); success = Vector2f_intersectLine(VECTOR2f(1.0f, 1.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.382683f, 0.923880f), &vector2, &distance); TestCase_assertBoolTrue(success); assertVector2fApproximate(vector2, -1.0f - sqrtf(2.0f), 1.0f, EPSILON); TestCase_assertFloatApproximate(distance, -2.0f - sqrtf(2.0f), EPSILON); Vector3f vector3; success = Vector3f_intersectPlane(VECTOR3f(-1.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(-1.0f, 0.0f, 0.0f), &vector3, &distance); TestCase_assertBoolTrue(success); assertVector3fApproximate(vector3, 0.0f, 0.0f, 0.0f, EPSILON); TestCase_assertFloatApproximate(distance, 1.0f, EPSILON); success = Vector3f_intersectPlane(VECTOR3f(-1.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f), &vector3, &distance); TestCase_assertBoolFalse(success); success = Vector3f_intersectPlane(VECTOR3f(0.0f, 2.0f, 0.0f), VECTOR3f(sqrtf(0.5f), -sqrtf(0.5f), 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f), &vector3, &distance); TestCase_assertBoolTrue(success); assertVector3fApproximate(vector3, 2.0f, 0.0f, 0.0f, EPSILON); TestCase_assertFloatApproximate(distance, sqrtf(2.0f) * 2, EPSILON); success = Vector3f_intersectPlane(VECTOR3f(1.0f, 1.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.382683f, 0.923880f, 0.0f), &vector3, &distance); TestCase_assertBoolTrue(success); assertVector3fApproximate(vector3, -1.0f - sqrtf(2.0f), 1.0f, 0.0f, EPSILON); TestCase_assertFloatApproximate(distance, -2.0f - sqrtf(2.0f), EPSILON); Vector2f intersectionPoint; success = Vector2f_intersectLineSegments(VECTOR2f(-1.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, -1.0f), VECTOR2f(0.0f, 1.0f), &intersectionPoint); TestCase_assertBoolTrue(success); assertVector2fApproximate(intersectionPoint, 0.0f, 0.0f, EPSILON); success = Vector2f_intersectLineSegments(VECTOR2f(-1.0f, 0.0f), VECTOR2f(0.0f, 1.0f), VECTOR2f(0.0f, -1.0f), VECTOR2f(1.0f, 0.0f), &intersectionPoint); TestCase_assertBoolFalse(success); success = Vector2f_intersectLineSegments(VECTOR2f(0.0f, 0.0f), VECTOR2f(2.0f, 2.0f), VECTOR2f(0.0f, 1.0f), VECTOR2f(2.0f, 1.5f), &intersectionPoint); TestCase_assertBoolTrue(success); assertVector2fApproximate(intersectionPoint, 1.333333f, 1.333333f, EPSILON); } static void testRotate(void) { Vector2f result = Vector2f_rotate(VECTOR2f(1.0f, 0.0f), M_PI / 2); assertVector2fApproximate(result, 0.0f, 1.0f, EPSILON); result = Vector2f_rotate(VECTOR2f(1.0f, 0.0f), M_PI); assertVector2fApproximate(result, -1.0f, 0.0f, EPSILON); result = Vector2f_rotate(VECTOR2f(2.0f, 2.0f), -M_PI / 4); assertVector2fApproximate(result, 2.828427f, 0.0f, EPSILON); } static void testRotate902D(void) { Vector2f resultf = Vector2f_rotate90CW(VECTOR2f(1.0f, 2.0f)); assertVector2fExact(resultf, 2.0f, -1.0f); resultf = Vector2f_rotate90CW(VECTOR2f(-0.5f, 1.0f)); assertVector2fExact(resultf, 1.0f, 0.5f); resultf = Vector2f_rotate90CCW(VECTOR2f(2.0f, -1.0f)); assertVector2fExact(resultf, 1.0f, 2.0f); resultf = Vector2f_rotate90CCW(VECTOR2f(1.0f, 0.5f)); assertVector2fExact(resultf, -0.5f, 1.0f); Vector2i resulti = Vector2i_rotate90CW(VECTOR2i(1, 2)); assertVector2i(resulti, 2, -1); resulti = Vector2i_rotate90CW(VECTOR2i(-3, 1)); assertVector2i(resulti, 1, 3); resulti = Vector2i_rotate90CCW(VECTOR2i(2, -1)); assertVector2i(resulti, 1, 2); resulti = Vector2i_rotate90CCW(VECTOR2i(1, 3)); assertVector2i(resulti, -3, 1); } static void testRotate903D(void) { Vector3f resultf = Vector3f_rotate90XCW(VECTOR3f(1.0f, 2.0f, 3.0f)); assertVector3fExact(resultf, 1.0f, 3.0f, -2.0f); resultf = Vector3f_rotate90XCW(VECTOR3f(-0.5f, 1.0f, -1.5f)); assertVector3fExact(resultf, -0.5f, -1.5f, -1.0f); resultf = Vector3f_rotate90XCCW(VECTOR3f(1.0f, 2.0f, 3.0f)); assertVector3fExact(resultf, 1.0f, -3.0f, 2.0f); resultf = Vector3f_rotate90XCCW(VECTOR3f(-0.5f, 1.0f, -1.5f)); assertVector3fExact(resultf, -0.5f, 1.5f, 1.0f); resultf = Vector3f_rotate90YCW(VECTOR3f(1.0f, 2.0f, 3.0f)); assertVector3fExact(resultf, -3.0f, 2.0f, 1.0f); resultf = Vector3f_rotate90YCW(VECTOR3f(-0.5f, 1.0f, -1.5f)); assertVector3fExact(resultf, 1.5f, 1.0f, -0.5f); resultf = Vector3f_rotate90YCCW(VECTOR3f(1.0f, 2.0f, 3.0f)); assertVector3fExact(resultf, 3.0f, 2.0f, -1.0f); resultf = Vector3f_rotate90YCCW(VECTOR3f(-0.5f, 1.0f, -1.5f)); assertVector3fExact(resultf, -1.5f, 1.0f, 0.5f); resultf = Vector3f_rotate90ZCW(VECTOR3f(1.0f, 2.0f, 3.0f)); assertVector3fExact(resultf, 2.0f, -1.0f, 3.0f); resultf = Vector3f_rotate90ZCW(VECTOR3f(-0.5f, 1.0f, -1.5f)); assertVector3fExact(resultf, 1.0f, 0.5f, -1.5f); resultf = Vector3f_rotate90ZCCW(VECTOR3f(1.0f, 2.0f, 3.0f)); assertVector3fExact(resultf, -2.0f, 1.0f, 3.0f); resultf = Vector3f_rotate90ZCCW(VECTOR3f(-0.5f, 1.0f, -1.5f)); assertVector3fExact(resultf, -1.0f, -0.5f, -1.5f); Vector3i resulti = Vector3i_rotate90XCW(VECTOR3i(1, 2, 3)); assertVector3i(resulti, 1, 3, -2); resulti = Vector3i_rotate90XCW(VECTOR3i(-4, 1, -5)); assertVector3i(resulti, -4, -5, -1); resulti = Vector3i_rotate90XCCW(VECTOR3i(1, 2, 3)); assertVector3i(resulti, 1, -3, 2); resulti = Vector3i_rotate90XCCW(VECTOR3i(-4, 1, -5)); assertVector3i(resulti, -4, 5, 1); resulti = Vector3i_rotate90YCW(VECTOR3i(1, 2, 3)); assertVector3i(resulti, -3, 2, 1); resulti = Vector3i_rotate90YCW(VECTOR3i(-4, 1, -5)); assertVector3i(resulti, 5, 1, -4); resulti = Vector3i_rotate90YCCW(VECTOR3i(1, 2, 3)); assertVector3i(resulti, 3, 2, -1); resulti = Vector3i_rotate90YCCW(VECTOR3i(-4, 1, -5)); assertVector3i(resulti, -5, 1, 4); resulti = Vector3i_rotate90ZCW(VECTOR3i(1, 2, 3)); assertVector3i(resulti, 2, -1, 3); resulti = Vector3i_rotate90ZCW(VECTOR3i(-4, 1, -5)); assertVector3i(resulti, 1, 4, -5); resulti = Vector3i_rotate90ZCCW(VECTOR3i(1, 2, 3)); assertVector3i(resulti, -2, 1, 3); resulti = Vector3i_rotate90ZCCW(VECTOR3i(-4, 1, -5)); assertVector3i(resulti, -1, -4, -5); } static void testRotate1803D(void) { Vector3f resultf = Vector3f_rotate180X(VECTOR3f(1.0f, 2.0f, 3.0f)); assertVector3fExact(resultf, 1.0f, -2.0f, -3.0f); resultf = Vector3f_rotate180X(VECTOR3f(-0.5f, 1.0f, -1.5f)); assertVector3fExact(resultf, -0.5f, -1.0f, 1.5f); resultf = Vector3f_rotate180Y(VECTOR3f(1.0f, 2.0f, 3.0f)); assertVector3fExact(resultf, -1.0f, 2.0f, -3.0f); resultf = Vector3f_rotate180Y(VECTOR3f(-0.5f, 1.0f, -1.5f)); assertVector3fExact(resultf, 0.5f, 1.0f, 1.5f); resultf = Vector3f_rotate180Z(VECTOR3f(1.0f, 2.0f, 3.0f)); assertVector3fExact(resultf, -1.0f, -2.0f, 3.0f); resultf = Vector3f_rotate180Z(VECTOR3f(-0.5f, 1.0f, -1.5f)); assertVector3fExact(resultf, 0.5f, -1.0f, -1.5f); Vector3i resulti = Vector3i_rotate180X(VECTOR3i(1, 2, 3)); assertVector3i(resulti, 1, -2, -3); resulti = Vector3i_rotate180X(VECTOR3i(-4, 1, -5)); assertVector3i(resulti, -4, -1, 5); resulti = Vector3i_rotate180Y(VECTOR3i(1, 2, 3)); assertVector3i(resulti, -1, 2, -3); resulti = Vector3i_rotate180Y(VECTOR3i(-4, 1, -5)); assertVector3i(resulti, 4, 1, 5); resulti = Vector3i_rotate180Z(VECTOR3i(1, 2, 3)); assertVector3i(resulti, -1, -2, 3); resulti = Vector3i_rotate180Z(VECTOR3i(-4, 1, -5)); assertVector3i(resulti, 4, -1, -5); } static void testTranspose(void) { Vector2f result = Vector2f_transpose(VECTOR2f(1.0f, 2.0f)); assertVector2fExact(result, 2.0f, 1.0f); result = Vector2f_transpose(VECTOR2f(-4.0f, 3.0f)); assertVector2fExact(result, 3.0f, -4.0f); } static void testDot(void) { float dot; dot = Vector2f_dot(VECTOR2f(1.0f, 0.0f), VECTOR2f(0.5f, 1.0f)); TestCase_assert(fabs(dot - 0.5f) < EPSILON, "Expected 0.5 but got %f", dot); dot = Vector2f_dot(VECTOR2f(0.0f, 2.0f), VECTOR2f(0.0f, -1.0f)); TestCase_assert(fabs(dot - -2.0f) < EPSILON, "Expected -2.0 but got %f", dot); dot = Vector3f_dot(VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.5f, 1.0f, 10.0f)); TestCase_assert(fabs(dot - 0.5f) < EPSILON, "Expected 0.5 but got %f", dot); dot = Vector3f_dot(VECTOR3f(0.0f, 2.0f, 4.0f), VECTOR3f(0.0f, -1.0f, 0.5f)); TestCase_assert(fabs(dot - 0.0f) < EPSILON, "Expected 1.0 but got %f", dot); dot = Vector4f_dot(VECTOR4f(1.0f, 0.0f, 0.0f, 0.0f), VECTOR4f(0.5f, 1.0f, 10.0f, -2.0f)); TestCase_assert(fabs(dot - 0.5f) < EPSILON, "Expected 0.5 but got %f", dot); dot = Vector4f_dot(VECTOR4f(0.0f, 2.0f, 4.0f, 0.5f), VECTOR4f(0.0f, -1.0f, 0.5f, 2.0f)); TestCase_assert(fabs(dot - 1.0f) < EPSILON, "Expected 1.0 but got %f", dot); } static void testCross(void) { float cross2; Vector3f cross3; cross2 = Vector2f_cross(VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 2.0f)); TestCase_assert(fabs(cross2 - 2.0f) < EPSILON, "Expected 2.0 but got %f", cross2); cross2 = Vector2f_cross(VECTOR2f(-1.0f, 0.0f), VECTOR2f(0.0f, 1.0f)); TestCase_assert(fabs(cross2 - -1.0f) < EPSILON, "Expected -1.0 but got %f", cross2); cross3 = Vector3f_cross(VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fApproximate(cross3, 0.0f, 0.0f, 1.0f, EPSILON); cross3 = Vector3f_cross(VECTOR3f(0.0f, 0.0f, -1.0f), VECTOR3f(0.0f, -2.0f, 0.0f)); assertVector3fApproximate(cross3, -2.0f, 0.0f, 0.0f, EPSILON); } static void testToBarycenter(void) { Vector3f result; // Right triangle bottom left result = Vector2f_toBarycenter(VECTOR2f(0.0f, 0.0f), VECTOR2f(0.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 1.0f)); assertVector3fExact(result, 1.0f, 0.0f, 0.0f); result = Vector3f_toBarycenter(VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fExact(result, 1.0f, 0.0f, 0.0f); // Right triangle right result = Vector2f_toBarycenter(VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 1.0f)); assertVector3fExact(result, 0.0f, 1.0f, 0.0f); result = Vector3f_toBarycenter(VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fExact(result, 0.0f, 1.0f, 0.0f); // Right triangle top result = Vector2f_toBarycenter(VECTOR2f(0.0f, 1.0f), VECTOR2f(0.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 1.0f)); assertVector3fExact(result, 0.0f, 0.0f, 1.0f); result = Vector3f_toBarycenter(VECTOR3f(0.0f, 1.0f, 0.0f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fExact(result, 0.0f, 0.0f, 1.0f); // Right triangle hypotenuse center result = Vector2f_toBarycenter(VECTOR2f(0.5f, 0.5f), VECTOR2f(0.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 1.0f)); assertVector3fApproximate(result, 0.0f, 0.5f, 0.5f, EPSILON); result = Vector3f_toBarycenter(VECTOR3f(0.5f, 0.5f, 0.0f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fApproximate(result, 0.0f, 0.5f, 0.5f, EPSILON); // Right triangle vertical side center result = Vector2f_toBarycenter(VECTOR2f(0.0f, 0.5f), VECTOR2f(0.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 1.0f)); assertVector3fApproximate(result, 0.5f, 0.0f, 0.5f, EPSILON); result = Vector3f_toBarycenter(VECTOR3f(0.0f, 0.5f, 0.0f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fApproximate(result, 0.5f, 0.0f, 0.5f, EPSILON); // Right triangle horizontal side center result = Vector2f_toBarycenter(VECTOR2f(0.5f, 0.0f), VECTOR2f(0.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 1.0f)); assertVector3fApproximate(result, 0.5f, 0.5f, 0.0f, EPSILON); result = Vector3f_toBarycenter(VECTOR3f(0.5f, 0.0f, 0.0f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fApproximate(result, 0.5f, 0.5f, 0.0f, EPSILON); // Equilateral triangle center result = Vector2f_toBarycenter(VECTOR2f(0.0f, 0.0f), VECTOR2f(0.0f, 1.0f), VECTOR2f(0.8660254037844384, -0.5f), VECTOR2f(-0.8660254037844384, -0.5f)); assertVector3fApproximate(result, 1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f, EPSILON); result = Vector3f_toBarycenter(VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f), VECTOR3f(0.8660254037844384, -0.5f, 0.0f), VECTOR3f(-0.8660254037844384, -0.5f, 0.0f)); assertVector3fApproximate(result, 1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f, EPSILON); // Outside right triangle result = Vector2f_toBarycenter(VECTOR2f(1.0f, -1.0f), VECTOR2f(0.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 1.0f)); assertVector3fExact(result, 1.0f, 1.0f, -1.0f); result = Vector3f_toBarycenter(VECTOR3f(1.0f, -1.0f, 0.0f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fExact(result, 1.0f, 1.0f, -1.0f); // Right triangle hypotenuse center (different orientation) result = Vector3f_toBarycenter(VECTOR3f(0.5f, 0.5f, 0.5f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 0.0f, 1.0f)); assertVector3fApproximate(result, 0.0f, 0.5f, 0.5f, EPSILON); // Right triangle bottom left (different orientation) result = Vector3f_toBarycenter(VECTOR3f(-1.0f, 1.0f, 1.0f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 1.0f, 0.0f), VECTOR3f(0.0f, 1.0f, -1.0f)); assertVector3fExact(result, 1.0f, 0.0f, 0.0f); } static void testFromBarycenter(void) { Vector2f result2f; Vector3f result3f; // Right triangle bottom left result2f = Vector2f_fromBarycenter(VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR2f(0.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 1.0f)); assertVector2fExact(result2f, 0.0f, 0.0f); result3f = Vector3f_fromBarycenter(VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fExact(result3f, 0.0f, 0.0f, 0.0f); // Right triangle right result2f = Vector2f_fromBarycenter(VECTOR3f(0.0f, 1.0f, 0.0f), VECTOR2f(0.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 1.0f)); assertVector2fExact(result2f, 1.0f, 0.0f); result3f = Vector3f_fromBarycenter(VECTOR3f(0.0f, 1.0f, 0.0f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fExact(result3f, 1.0f, 0.0f, 0.0f); // Right triangle top result2f = Vector2f_fromBarycenter(VECTOR3f(0.0f, 0.0f, 1.0f), VECTOR2f(0.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 1.0f)); assertVector2fExact(result2f, 0.0f, 1.0f); result3f = Vector3f_fromBarycenter(VECTOR3f(0.0f, 0.0f, 1.0f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fExact(result3f, 0.0f, 1.0f, 0.0f); // Right triangle hypotenuse center result2f = Vector2f_fromBarycenter(VECTOR3f(0.0f, 0.5f, 0.5f), VECTOR2f(0.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 1.0f)); assertVector2fApproximate(result2f, 0.5f, 0.5f, EPSILON); result3f = Vector3f_fromBarycenter(VECTOR3f(0.0f, 0.5f, 0.5f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fApproximate(result3f, 0.5f, 0.5f, 0.0f, EPSILON); // Right triangle vertical side center result2f = Vector2f_fromBarycenter(VECTOR3f(0.5f, 0.0f, 0.5f), VECTOR2f(0.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 1.0f)); assertVector2fApproximate(result2f, 0.0f, 0.5f, EPSILON); result3f = Vector3f_fromBarycenter(VECTOR3f(0.5f, 0.0f, 0.5f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fApproximate(result3f, 0.0f, 0.5f, 0.0f, EPSILON); // Right triangle horizontal side center result2f = Vector2f_fromBarycenter(VECTOR3f(0.5f, 0.5f, 0.0f), VECTOR2f(0.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 1.0f)); assertVector2fApproximate(result2f, 0.5f, 0.0f, EPSILON); result3f = Vector3f_fromBarycenter(VECTOR3f(0.5f, 0.5f, 0.0f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fApproximate(result3f, 0.5f, 0.0f, 0.0f, EPSILON); // Equilateral triangle center result2f = Vector2f_fromBarycenter(VECTOR3f(1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f), VECTOR2f(0.0f, 1.0f), VECTOR2f(0.8660254037844384, -0.5f), VECTOR2f(-0.8660254037844384, -0.5f)); assertVector2fApproximate(result2f, 0.0f, 0.0f, EPSILON); result3f = Vector3f_fromBarycenter(VECTOR3f(1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f), VECTOR3f(0.0f, 1.0f, 0.0f), VECTOR3f(0.8660254037844384, -0.5f, 0.0f), VECTOR3f(-0.8660254037844384, -0.5f, 0.0f)); assertVector3fApproximate(result3f, 0.0f, 0.0f, 0.0f, EPSILON); // Outside right triangle result2f = Vector2f_fromBarycenter(VECTOR3f(1.0f, 1.0f, -1.0f), VECTOR2f(0.0f, 0.0f), VECTOR2f(1.0f, 0.0f), VECTOR2f(0.0f, 1.0f)); assertVector2fExact(result2f, 1.0f, -1.0f); result3f = Vector3f_fromBarycenter(VECTOR3f(1.0f, 1.0f, -1.0f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 1.0f, 0.0f)); assertVector3fExact(result3f, 1.0f, -1.0f, 0.0f); // Right triangle hypotenuse center (different orientation) result3f = Vector3f_fromBarycenter(VECTOR3f(0.0f, 0.5f, 0.5f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 0.0f, 0.0f), VECTOR3f(0.0f, 0.0f, 1.0f)); assertVector3fApproximate(result3f, 0.5f, 0.0f, 0.5f, EPSILON); // Right triangle right (different orientation) result3f = Vector3f_fromBarycenter(VECTOR3f(0.0f, 1.0f, 0.0f), VECTOR3f(0.0f, 0.0f, 0.0f), VECTOR3f(1.0f, 1.0f, 0.0f), VECTOR3f(0.0f, 1.0f, -1.0f)); assertVector3fExact(result3f, 1.0f, 1.0f, 0.0f); } static void testExtend(void) { Vector2f vector2f = {1.0f, 2.0f}; Vector3f vector3f = VECTOR3f_EXTEND2(vector2f, 3.0f); assertVector3fExact(vector3f, 1.0f, 2.0f, 3.0f); vector2f.x = -1.0f; vector2f.y = 0.5f; vector3f = VECTOR3f_EXTEND2(vector2f, 1.25f); assertVector3fExact(vector3f, -1.0f, 0.5f, 1.25f); Vector4f vector4f = VECTOR4f_EXTEND2(vector2f, 1.25f, -3.5f); assertVector4fExact(vector4f, -1.0f, 0.5f, 1.25f, -3.5f); vector2f.x = 0.0f; vector2f.y = -2.0f; vector4f = VECTOR4f_EXTEND2(vector2f, 1.75f, -0.5f); assertVector4fExact(vector4f, 0.0f, -2.0f, 1.75f, -0.5f); vector4f = VECTOR4f_EXTEND3(vector3f, 0.25f); assertVector4fExact(vector4f, -1.0f, 0.5f, 1.25f, 0.25f); vector3f.x = 1.0f; vector3f.y = 2.0f; vector3f.z = 3.0f; vector4f = VECTOR4f_EXTEND3(vector3f, 4.0f); assertVector4fExact(vector4f, 1.0f, 2.0f, 3.0f, 4.0f); } static void testTruncate(void) { Vector3f vector3f = {1.0f, 2.0f, 3.0f}; Vector2f vector2f = VECTOR2f_TRUNCATE(vector3f); assertVector2fExact(vector2f, 1.0f, 2.0f); vector3f.x = -1.0f; vector3f.y = 0.5f; vector3f.z = 1.25f; vector2f = VECTOR2f_TRUNCATE(vector3f); assertVector2fExact(vector2f, -1.0f, 0.5f); Vector4f vector4f = {1.0f, 2.0f, 3.0f, 4.0f}; vector3f = VECTOR3f_TRUNCATE(vector4f); assertVector3fExact(vector3f, 1.0f, 2.0f, 3.0f); vector2f = VECTOR2f_TRUNCATE(vector4f); assertVector2fExact(vector2f, 1.0f, 2.0f); vector4f.x = 0.0f; vector4f.y = -2.0f; vector4f.z = 0.25f; vector4f.w = -3.0f; vector3f = VECTOR3f_TRUNCATE(vector4f); assertVector3fExact(vector3f, 0.0f, -2.0f, 0.25f); vector2f = VECTOR2f_TRUNCATE(vector4f); assertVector2fExact(vector3f, 0.0f, -2.0f); } static void testNormalizeW(void) { Vector4f vector4 = {1.0f, 2.0f, 3.0f, 1.0f}; Vector4f result = Vector4f_normalizedW(vector4); assertVector4fExact(result, 1.0f, 2.0f, 3.0f, 1.0f); bool success = Vector4f_normalizeW(&vector4); TestCase_assertBoolTrue(success); assertVector4fExact(vector4, 1.0f, 2.0f, 3.0f, 1.0f); vector4.w = 4.0f; result = Vector4f_normalizedW(vector4); assertVector4fApproximate(result, 0.25f, 0.5f, 0.75f, 1.0f, EPSILON); success = Vector4f_normalizeW(&vector4); TestCase_assertBoolTrue(success); assertVector4fApproximate(vector4, 0.25f, 0.5f, 0.75f, 1.0f, EPSILON); vector4 = VECTOR4f(-1.0f, 0.5f, 4.0f, -2.0f); result = Vector4f_normalizedW(vector4); assertVector4fApproximate(result, 0.5f, -0.25f, -2.0f, 1.0f, EPSILON); success = Vector4f_normalizeW(&vector4); TestCase_assertBoolTrue(success); assertVector4fApproximate(vector4, 0.5f, -0.25f, -2.0f, 1.0f, EPSILON); vector4 = VECTOR4f(1.0f, 2.0f, 3.0f, 0.0f); success = Vector4f_normalizeW(&vector4); TestCase_assertBoolFalse(success); } static void testIsZero(void) { TestCase_assertBoolTrue(Vector2f_isZero(VECTOR2f_ZERO)); TestCase_assertBoolTrue(Vector2f_isZero(VECTOR2f(0.0f, 0.0f))); TestCase_assertBoolFalse(Vector2f_isZero(VECTOR2f(1.0f, 0.0f))); TestCase_assertBoolFalse(Vector2f_isZero(VECTOR2f(0.0f, -1.0f))); TestCase_assertBoolFalse(Vector2f_isZero(VECTOR2f(1.0f, -1.0f))); TestCase_assertBoolTrue(Vector3f_isZero(VECTOR3f_ZERO)); TestCase_assertBoolTrue(Vector3f_isZero(VECTOR3f(0.0f, 0.0f, 0.0f))); TestCase_assertBoolFalse(Vector3f_isZero(VECTOR3f(1.0f, 0.0f, 0.0f))); TestCase_assertBoolFalse(Vector3f_isZero(VECTOR3f(0.0f, -1.0f, 0.0f))); TestCase_assertBoolFalse(Vector3f_isZero(VECTOR3f(0.0f, 0.0f, 0.5f))); TestCase_assertBoolFalse(Vector3f_isZero(VECTOR3f(1.0f, -1.0f, 0.0f))); TestCase_assertBoolTrue(Vector4f_isZero(VECTOR4f_ZERO)); TestCase_assertBoolTrue(Vector4f_isZero(VECTOR4f(0.0f, 0.0f, 0.0f, 0.0f))); TestCase_assertBoolFalse(Vector4f_isZero(VECTOR4f(1.0f, 0.0f, 0.0f, 0.0f))); TestCase_assertBoolFalse(Vector4f_isZero(VECTOR4f(0.0f, -1.0f, 0.0f, 0.0f))); TestCase_assertBoolFalse(Vector4f_isZero(VECTOR4f(0.0f, 0.0f, 0.5f, 0.0f))); TestCase_assertBoolFalse(Vector4f_isZero(VECTOR4f(0.0f, 0.0f, 0.0f, -0.5f))); TestCase_assertBoolFalse(Vector4f_isZero(VECTOR4f(1.0f, -1.0f, 0.0f, 0.0f))); } static void testIsEqual(void) { TestCase_assertBoolTrue(Vector2f_isEqual(VECTOR2f_ZERO, VECTOR2f_ZERO)); TestCase_assertBoolTrue(Vector2f_isEqual(VECTOR2f(1.0f, 2.0f), VECTOR2f(1.0f, 2.0f))); TestCase_assertBoolFalse(Vector2f_isEqual(VECTOR2f(1.0f, 0.0f), VECTOR2f(1.0f, 2.0f))); TestCase_assertBoolFalse(Vector2f_isEqual(VECTOR2f(1.0f, 2.0f), VECTOR2f(0.0f, 2.0f))); TestCase_assertBoolTrue(Vector3f_isEqual(VECTOR3f_ZERO, VECTOR3f_ZERO)); TestCase_assertBoolTrue(Vector3f_isEqual(VECTOR3f(1.0f, 2.0f, 3.0f), VECTOR3f(1.0f, 2.0f, 3.0f))); TestCase_assertBoolFalse(Vector3f_isEqual(VECTOR3f(1.0f, 0.0f, 3.0f), VECTOR3f(1.0f, 2.0f, 3.0f))); TestCase_assertBoolFalse(Vector3f_isEqual(VECTOR3f(1.0f, 2.0f, 3.0f), VECTOR3f(0.0f, 2.0f, 3.0f))); TestCase_assertBoolFalse(Vector3f_isEqual(VECTOR3f(1.0f, 2.0f, 3.0f), VECTOR3f(1.0f, 2.0f, -1.0f))); TestCase_assertBoolTrue(Vector4f_isEqual(VECTOR4f_ZERO, VECTOR4f_ZERO)); TestCase_assertBoolTrue(Vector4f_isEqual(VECTOR4f(1.0f, 2.0f, 3.0f, 4.0f), VECTOR4f(1.0f, 2.0f, 3.0f, 4.0f))); TestCase_assertBoolFalse(Vector4f_isEqual(VECTOR4f(1.0f, 0.0f, 3.0f, 4.0f), VECTOR4f(1.0f, 2.0f, 3.0f, 4.0f))); TestCase_assertBoolFalse(Vector4f_isEqual(VECTOR4f(1.0f, 2.0f, 3.0f, 4.0f), VECTOR4f(0.0f, 2.0f, 3.0f, 4.0f))); TestCase_assertBoolFalse(Vector4f_isEqual(VECTOR4f(1.0f, 2.0f, 3.0f, 4.0f), VECTOR4f(1.0f, 2.0f, -1.0f, 4.0f))); TestCase_assertBoolFalse(Vector4f_isEqual(VECTOR4f(1.0f, 2.0f, 3.0f, 4.0f), VECTOR4f(1.0f, 2.0f, 3.0f, -2.0f))); } TEST_SUITE(VectorTest, testInit, testPrefabs, testNormalize, testInvert, testMagnitude, testDistance, testArithmetic, testInterpolate, testRound, testReflect, testProject, testIntersect, testRotate, testRotate902D, testRotate903D, testRotate1803D, testTranspose, testDot, testCross, testToBarycenter, testFromBarycenter, testExtend, testTruncate, testNormalizeW, testIsZero, testIsEqual)