Browse Source

IntVector implementation and tests

Kajetan Johannes Hammerle 3 weeks ago
parent
commit
d419395439
3 changed files with 116 additions and 61 deletions
  1. 20 15
      include/core/Vector.h
  2. 62 39
      src/Vector.c
  3. 34 7
      test/modules/VectorTests.c

+ 20 - 15
include/core/Vector.h

@@ -6,7 +6,7 @@
 #define CORE_VECTOR_OP2(name) name *r, const name *a
 #define CORE_VECTOR_OP3(name) CORE_VECTOR_OP2(name), const name* b
 
-#define CORE_DEFINE_VECTOR(N, name, sname, type, factor)                       \
+#define CORE_DEFINE_VECTOR(N, name, sname, type)                               \
     typedef struct {                                                           \
         type data[N];                                                          \
     } name;                                                                    \
@@ -18,24 +18,29 @@
     name* coreMul##sname(CORE_VECTOR_OP3(name));                               \
     name* coreDivSet##sname(CORE_VECTOR_OP2(name));                            \
     name* coreDiv##sname(CORE_VECTOR_OP3(name));                               \
-    name* coreMulSet##sname##factor(name* r, type f);                          \
-    name* coreMul##sname##factor(name* r, const name* a, type f);              \
-    name* coreDivSet##sname##factor(name* r, type f);                          \
-    name* coreDiv##sname##factor(name* r, const name* a, type f);              \
+    name* coreMulSet##sname##F(name* r, type f);                               \
+    name* coreMul##sname##F(name* r, const name* a, type f);                   \
+    name* coreDivSet##sname##F(name* r, type f);                               \
+    name* coreDiv##sname##F(name* r, const name* a, type f);                   \
     name* coreInvertSet##sname(name* r);                                       \
     name* coreInvert##sname(name* r, const name* a);                           \
-    type coreDot##sname(const name* a, const name* b);                         \
-    type coreSquareLength##sname(const name* a);                               \
-    type coreLength##sname(const name* a);                                     \
-    name* coreNormalize##sname(name* r);                                       \
     void coreToString##sname(const name* a, char* buffer, size_t n);
 
-CORE_DEFINE_VECTOR(2, CoreVector2, V2, float, F)
-CORE_DEFINE_VECTOR(3, CoreVector3, V3, float, F)
-CORE_DEFINE_VECTOR(4, CoreVector4, V4, float, F)
-CORE_DEFINE_VECTOR(2, CoreIntVector2, IV2, int, I)
-CORE_DEFINE_VECTOR(3, CoreIntVector3, IV3, int, I)
-CORE_DEFINE_VECTOR(4, CoreIntVector4, IV4, int, I)
+#define CORE_DEFINE_FVECTOR(N, name)                                           \
+    float coreDotV##N(const name* a, const name* b);                           \
+    float coreSquareLengthV##N(const name* a);                                 \
+    float coreLengthV##N(const name* a);                                       \
+    name* coreNormalizeV##N(name* r);
+
+CORE_DEFINE_VECTOR(2, CoreVector2, V2, float)
+CORE_DEFINE_VECTOR(3, CoreVector3, V3, float)
+CORE_DEFINE_VECTOR(4, CoreVector4, V4, float)
+CORE_DEFINE_FVECTOR(2, CoreVector2)
+CORE_DEFINE_FVECTOR(3, CoreVector3)
+CORE_DEFINE_FVECTOR(4, CoreVector4)
+CORE_DEFINE_VECTOR(2, CoreIntVector2, IV2, int)
+CORE_DEFINE_VECTOR(3, CoreIntVector3, IV3, int)
+CORE_DEFINE_VECTOR(4, CoreIntVector4, IV4, int)
 
 CoreVector3* coreAngles(CoreVector3* r, float lengthAngle, float widthAngle);
 CoreVector3* coreCross(CORE_VECTOR_OP3(CoreVector3));

+ 62 - 39
src/Vector.c

@@ -5,9 +5,12 @@
 
 #include "core/Utility.h"
 
-#define V2 CoreVector2
-#define V3 CoreVector3
-#define V4 CoreVector4
+typedef CoreVector2 V2;
+typedef CoreVector3 V3;
+typedef CoreVector4 V4;
+typedef CoreIntVector2 IV2;
+typedef CoreIntVector3 IV3;
+typedef CoreIntVector4 IV4;
 
 V3* coreAngles(V3* r, float lengthAngle, float widthAngle) {
     lengthAngle = coreDegreeToRadian(lengthAngle);
@@ -31,85 +34,86 @@ V3* coreCross(V3* r, const V3* a, const V3* b) {
     return r;
 }
 
-#define VECTOR_IMPL(T, N, SN, F, CN)                                           \
-    T* coreAddSet##SN(T* r, const T* a) {                                      \
-        return coreAdd##SN(r, r, a);                                           \
+#define VECTOR_IMPL(T, N, FT)                                                  \
+    T* coreAddSet##T(T* r, const T* a) {                                       \
+        return coreAdd##T(r, r, a);                                            \
     }                                                                          \
                                                                                \
-    T* coreAdd##SN(T* r, const T* a, const T* b) {                             \
+    T* coreAdd##T(T* r, const T* a, const T* b) {                              \
         for(int i = 0; i < N; i++) {                                           \
             r->data[i] = a->data[i] + b->data[i];                              \
         }                                                                      \
         return r;                                                              \
     }                                                                          \
                                                                                \
-    T* coreSubSet##SN(T* r, const T* a) {                                      \
-        return coreSub##SN(r, r, a);                                           \
+    T* coreSubSet##T(T* r, const T* a) {                                       \
+        return coreSub##T(r, r, a);                                            \
     }                                                                          \
                                                                                \
-    T* coreSub##SN(T* r, const T* a, const T* b) {                             \
+    T* coreSub##T(T* r, const T* a, const T* b) {                              \
         for(int i = 0; i < N; i++) {                                           \
             r->data[i] = a->data[i] - b->data[i];                              \
         }                                                                      \
         return r;                                                              \
     }                                                                          \
                                                                                \
-    T* coreMulSet##SN(T* r, const T* a) {                                      \
-        return coreMul##SN(r, r, a);                                           \
+    T* coreMulSet##T(T* r, const T* a) {                                       \
+        return coreMul##T(r, r, a);                                            \
     }                                                                          \
                                                                                \
-    T* coreMul##SN(T* r, const T* a, const T* b) {                             \
+    T* coreMul##T(T* r, const T* a, const T* b) {                              \
         for(int i = 0; i < N; i++) {                                           \
             r->data[i] = a->data[i] * b->data[i];                              \
         }                                                                      \
         return r;                                                              \
     }                                                                          \
                                                                                \
-    T* coreDivSet##SN(T* r, const T* a) {                                      \
-        return coreDiv##SN(r, r, a);                                           \
+    T* coreDivSet##T(T* r, const T* a) {                                       \
+        return coreDiv##T(r, r, a);                                            \
     }                                                                          \
                                                                                \
-    T* coreDiv##SN(T* r, const T* a, const T* b) {                             \
+    T* coreDiv##T(T* r, const T* a, const T* b) {                              \
         for(int i = 0; i < N; i++) {                                           \
             r->data[i] = a->data[i] / b->data[i];                              \
         }                                                                      \
         return r;                                                              \
     }                                                                          \
                                                                                \
-    T* coreMulSet##SN##F(T* r, float f) {                                      \
-        return coreMul##SN##F(r, r, f);                                        \
+    T* coreMulSet##T##F(T* r, FT f) {                                          \
+        return coreMul##T##F(r, r, f);                                         \
     }                                                                          \
                                                                                \
-    T* coreMul##SN##F(T* r, const T* a, float f) {                             \
+    T* coreMul##T##F(T* r, const T* a, FT f) {                                 \
         for(int i = 0; i < N; i++) {                                           \
             r->data[i] = a->data[i] * f;                                       \
         }                                                                      \
         return r;                                                              \
     }                                                                          \
                                                                                \
-    T* coreDivSet##SN##F(T* r, float f) {                                      \
-        return coreDiv##SN##F(r, r, f);                                        \
+    T* coreDivSet##T##F(T* r, FT f) {                                          \
+        return coreDiv##T##F(r, r, f);                                         \
     }                                                                          \
                                                                                \
-    T* coreDiv##SN##F(T* r, const T* a, float f) {                             \
+    T* coreDiv##T##F(T* r, const T* a, FT f) {                                 \
         for(int i = 0; i < N; i++) {                                           \
             r->data[i] = a->data[i] / f;                                       \
         }                                                                      \
         return r;                                                              \
     }                                                                          \
                                                                                \
-    T* coreInvertSet##SN(T* r) {                                               \
-        return coreInvert##SN(r, r);                                           \
+    T* coreInvertSet##T(T* r) {                                                \
+        return coreInvert##T(r, r);                                            \
     }                                                                          \
                                                                                \
-    T* coreInvert##SN(T* r, const T* a) {                                      \
+    T* coreInvert##T(T* r, const T* a) {                                       \
         for(int i = 0; i < N; i++) {                                           \
             r->data[i] = -a->data[i];                                          \
         }                                                                      \
         return r;                                                              \
-    }                                                                          \
-                                                                               \
-    float coreDot##SN(const T* a, const T* b) {                                \
+    }
+
+#define VECTOR_IMPL_FLOAT(T, N, CN)                                            \
+    float coreDot##T(const T* a, const T* b) {                                 \
         float length = 0;                                                      \
         for(int i = 0; i < N; i++) {                                           \
             length += a->data[i] * b->data[i];                                 \
@@ -117,35 +121,41 @@ V3* coreCross(V3* r, const V3* a, const V3* b) {
         return length;                                                         \
     }                                                                          \
                                                                                \
-    float coreSquareLength##SN(const T* a) {                                   \
-        return coreDot##SN(a, a);                                              \
+    float coreSquareLength##T(const T* a) {                                    \
+        return coreDot##T(a, a);                                               \
     }                                                                          \
                                                                                \
-    float coreLength##SN(const T* a) {                                         \
-        return sqrtf(coreSquareLength##SN(a));                                 \
+    float coreLength##T(const T* a) {                                          \
+        return sqrtf(coreSquareLength##T(a));                                  \
     }                                                                          \
                                                                                \
-    T* coreNormalize##SN(T* r) {                                               \
-        return coreMulSet##SN##F(r, 1.0f / coreLength##SN(r));                 \
+    T* coreNormalize##T(T* r) {                                                \
+        return coreMulSet##T##F(r, 1.0f / coreLength##T(r));                   \
     }                                                                          \
                                                                                \
-    T* coreConvertI##SN(T* r, const CN* a) {                                   \
+    T* coreConvertI##T(T* r, const CN* a) {                                    \
         for(int i = 0; i < N; i++) {                                           \
             r->data[i] = (float)a->data[i];                                    \
         }                                                                      \
         return r;                                                              \
     }                                                                          \
                                                                                \
-    CN* coreConvert##SN(CN* r, const T* a) {                                   \
+    CN* coreConvert##T(CN* r, const T* a) {                                    \
         for(int i = 0; i < N; i++) {                                           \
             r->data[i] = (int)a->data[i];                                      \
         }                                                                      \
         return r;                                                              \
     }
 
-VECTOR_IMPL(CoreVector2, 2, V2, F, CoreIntVector2)
-VECTOR_IMPL(CoreVector3, 3, V3, F, CoreIntVector3)
-VECTOR_IMPL(CoreVector4, 4, V4, F, CoreIntVector4)
+VECTOR_IMPL(V2, 2, float)
+VECTOR_IMPL(V3, 3, float)
+VECTOR_IMPL(V4, 4, float)
+VECTOR_IMPL(IV2, 2, int)
+VECTOR_IMPL(IV3, 3, int)
+VECTOR_IMPL(IV4, 4, int)
+VECTOR_IMPL_FLOAT(V2, 2, IV2)
+VECTOR_IMPL_FLOAT(V3, 3, IV3)
+VECTOR_IMPL_FLOAT(V4, 4, IV4)
 
 void coreToStringV2(const V2* a, char* buffer, size_t n) {
     snprintf(buffer, n, "[%.3f, %.3f]", (double)a->data[0], (double)a->data[1]);
@@ -160,3 +170,16 @@ void coreToStringV4(const V4* a, char* buffer, size_t n) {
     snprintf(buffer, n, "[%.3f, %.3f, %.3f, %.3f]", (double)a->data[0],
              (double)a->data[1], (double)a->data[2], (double)a->data[3]);
 }
+
+void coreToStringIV2(const IV2* a, char* buffer, size_t n) {
+    snprintf(buffer, n, "[%d, %d]", a->data[0], a->data[1]);
+}
+
+void coreToStringIV3(const IV3* a, char* buffer, size_t n) {
+    snprintf(buffer, n, "[%d, %d, %d]", a->data[0], a->data[1], a->data[2]);
+}
+
+void coreToStringIV4(const IV4* a, char* buffer, size_t n) {
+    snprintf(buffer, n, "[%d, %d, %d, %d]", a->data[0], a->data[1], a->data[2],
+             a->data[3]);
+}

+ 34 - 7
test/modules/VectorTests.c

@@ -117,6 +117,9 @@ static void testSetAdd() {
     TEST_SET_ADD(V2)
     TEST_SET_ADD(V3)
     TEST_SET_ADD(V4)
+    TEST_SET_ADD(IV2)
+    TEST_SET_ADD(IV3)
+    TEST_SET_ADD(IV4)
 }
 
 static void testAdd() {
@@ -137,6 +140,9 @@ static void testSetSub() {
     TEST_SET_SUB(V2)
     TEST_SET_SUB(V3)
     TEST_SET_SUB(V4)
+    TEST_SET_SUB(IV2)
+    TEST_SET_SUB(IV3)
+    TEST_SET_SUB(IV4)
 }
 
 static void testSub() {
@@ -157,6 +163,9 @@ static void testSetMul() {
     TEST_SET_MUL(V2)
     TEST_SET_MUL(V3)
     TEST_SET_MUL(V4)
+    TEST_SET_MUL(IV2)
+    TEST_SET_MUL(IV3)
+    TEST_SET_MUL(IV4)
 }
 
 static void testMul() {
@@ -176,6 +185,9 @@ static void testSetMulVector() {
     TEST_SET_MUL_VECTOR(V2)
     TEST_SET_MUL_VECTOR(V3)
     TEST_SET_MUL_VECTOR(V4)
+    TEST_SET_MUL_VECTOR(IV2)
+    TEST_SET_MUL_VECTOR(IV3)
+    TEST_SET_MUL_VECTOR(IV4)
 }
 
 static void testMulVector() {
@@ -185,17 +197,20 @@ static void testMulVector() {
 
 #define TEST_SET_DIV(T)                                                        \
     {                                                                          \
-        T v = *C##T(12, 24, 9, 27);                                            \
+        T v = *C##T(18, 36, 9, 27);                                            \
         coreDivSet##T##F(&v, 3);                                               \
-        test##T(C##T(4, 8, 3, 9), &v);                                         \
-        coreDivSet##T##F(&v, -2);                                              \
-        test##T(C##T(-2, -4, -1.5f, -4.5f), &v);                               \
+        test##T(C##T(6, 12, 3, 9), &v);                                        \
+        coreDivSet##T##F(&v, -3);                                              \
+        test##T(C##T(-2, -4, -1, -3), &v);                                     \
     }
 
 static void testSetDiv() {
     TEST_SET_DIV(V2);
     TEST_SET_DIV(V3);
     TEST_SET_DIV(V4);
+    TEST_SET_DIV(IV2);
+    TEST_SET_DIV(IV3);
+    TEST_SET_DIV(IV4);
 }
 
 static void testDiv() {
@@ -204,17 +219,20 @@ static void testDiv() {
 
 #define TEST_SET_DIV_VECTOR(T)                                                 \
     {                                                                          \
-        T v = *C##T(3, 4, 6, 8);                                               \
+        T v = *C##T(12, 4, 6, 8);                                              \
         coreDivSet##T(&v, C##T(2, 1, 3, 4));                                   \
-        test##T(C##T(1.5f, 4, 2, 2), &v);                                      \
+        test##T(C##T(6, 4, 2, 2), &v);                                         \
         coreDivSet##T(&v, C##T(-3, 4, -2, -1));                                \
-        test##T(C##T(-0.5f, 1, -1, -2), &v);                                   \
+        test##T(C##T(-2, 1, -1, -2), &v);                                      \
     }
 
 static void testSetDivVector() {
     TEST_SET_DIV_VECTOR(V2)
     TEST_SET_DIV_VECTOR(V3)
     TEST_SET_DIV_VECTOR(V4)
+    TEST_SET_DIV_VECTOR(IV2)
+    TEST_SET_DIV_VECTOR(IV3)
+    TEST_SET_DIV_VECTOR(IV4)
 }
 
 static void testDivVector() {
@@ -226,6 +244,9 @@ static void testSetInvert() {
     testV2(FV2(-1, 2), coreInvertSetV2(FV2(1, -2)));
     testV3(FV3(-1, 2, 3), coreInvertSetV3(FV3(1, -2, -3)));
     testV4(CV4(-1, 2, 3, 4), coreInvertSetV4(CV4(1, -2, -3, -4)));
+    testIV2(FIV2(-1, 2), coreInvertSetIV2(FIV2(1, -2)));
+    testIV3(FIV3(-1, 2, 3), coreInvertSetIV3(FIV3(1, -2, -3)));
+    testIV4(CIV4(-1, 2, 3, 4), coreInvertSetIV4(CIV4(1, -2, -3, -4)));
 }
 
 static void testInvert() {
@@ -314,6 +335,12 @@ static void testToString() {
     CORE_TEST_STRING("[4.000, 5.000, 6.000]", buffer);
     coreToStringV4(CV4(4, 5, 6, 7), buffer, sizeof(buffer));
     CORE_TEST_STRING("[4.000, 5.000, 6.000, 7.000]", buffer);
+    coreToStringIV2(FIV2(4, 5), buffer, sizeof(buffer));
+    CORE_TEST_STRING("[4, 5]", buffer);
+    coreToStringIV3(FIV3(4, 5, 6), buffer, sizeof(buffer));
+    CORE_TEST_STRING("[4, 5, 6]", buffer);
+    coreToStringIV4(CIV4(4, 5, 6, 7), buffer, sizeof(buffer));
+    CORE_TEST_STRING("[4, 5, 6, 7]", buffer);
 }
 
 void coreTestVector() {