Browse Source

Box and tests

Kajetan Johannes Hammerle 1 month ago
parent
commit
aa9f657380
5 changed files with 190 additions and 4 deletions
  1. 3 3
      CMakeLists.txt
  2. 18 0
      include/core/Box.h
  3. 68 0
      src/Box.c
  4. 1 1
      test/Main.c
  5. 100 0
      test/modules/BoxTests.c

+ 3 - 3
CMakeLists.txt

@@ -4,6 +4,7 @@ project(core)
 set(CMAKE_C_STANDARD 23)
 
 set(SRC
+    "src/Box.c"
     "src/Buffer.c"
     "src/Logger.c"
     "src/Matrix.c"
@@ -15,13 +16,13 @@ set(SRC
     "src/Vector.c"
     "src/View.c"
     #"src/BitArray.cpp"
-    #"src/Box.cpp"
     #"src/Frustum.cpp"
 )
 
 set(SRC_TESTS
     "test/Main.c"
     "test/Test.c"
+    "test/modules/BoxTests.c"
     "test/modules/BufferTests.c"
     "test/modules/MatrixTests.c"
     "test/modules/PlaneTests.c"
@@ -32,7 +33,6 @@ set(SRC_TESTS
     "test/modules/VectorTests.c"
     "test/modules/ViewTests.c"
     #"test/modules/BitArrayTests.cpp"
-    #"test/modules/BoxTests.cpp"
     #"test/modules/ComponentsTests.cpp"
     #"test/modules/FrustumTests.cpp"
     #"test/modules/HashMapTests.cpp"
@@ -96,6 +96,7 @@ target_sources(core PUBLIC
     FILE_SET HEADERS
     BASE_DIRS include
     FILES 
+        ./include/core/Box.h
         ./include/core/Buffer.h
         ./include/core/Check.h
         ./include/core/Logger.h
@@ -108,7 +109,6 @@ target_sources(core PUBLIC
         ./include/core/Utility.h
         ./include/core/View.h
 #        ./include/core/BitArray.hpp
-#        ./include/core/Box.hpp
 #        ./include/core/Components.hpp
 #        ./include/core/Frustum.hpp
 #        ./include/core/HashMap.hpp

+ 18 - 0
include/core/Box.h

@@ -0,0 +1,18 @@
+#ifndef CORE_BOX_H
+#define CORE_BOX_H
+
+#include "core/Vector.h"
+
+typedef struct {
+    CoreVector3 min;
+    CoreVector3 max;
+} CoreBox;
+
+CoreBox* coreSetBox(CoreBox* box, const CoreVector3* size);
+CoreBox* coreOffsetBox(CoreBox* box, const CoreVector3* offset);
+bool coreCollidesWithBox(const CoreBox* box, const CoreBox* other);
+CoreBox* coreExpandBox(CoreBox* box, const CoreVector3* offset);
+CoreBox* coreGrowBox(CoreBox* box, const CoreVector3* growth);
+size_t coreToStringBox(const CoreBox* box, char* buffer, size_t n);
+
+#endif

+ 68 - 0
src/Box.c

@@ -0,0 +1,68 @@
+#include "core/Box.h"
+
+#include <stdio.h>
+
+CoreBox* coreSetBox(CoreBox* box, const CoreVector3* size) {
+    for(size_t i = 0; i < 3; i++) {
+        if(size->data[i] < 0.0f) {
+            box->min.data[i] = size->data[i];
+            box->max.data[i] = 0.0f;
+        } else {
+            box->min.data[i] = 0.0f;
+            box->max.data[i] = size->data[i];
+        }
+    }
+    return box;
+}
+
+CoreBox* coreOffsetBox(CoreBox* box, const CoreVector3* offset) {
+    coreAddSetV3(&box->min, offset);
+    coreAddSetV3(&box->max, offset);
+    return box;
+}
+
+bool coreCollidesWithBox(const CoreBox* box, const CoreBox* other) {
+    return box->max.data[0] > other->min.data[0] &&
+           box->min.data[0] < other->max.data[0] &&
+           box->max.data[1] > other->min.data[1] &&
+           box->min.data[1] < other->max.data[1] &&
+           box->max.data[2] > other->min.data[2] &&
+           box->min.data[2] < other->max.data[2];
+}
+
+CoreBox* coreExpandBox(CoreBox* box, const CoreVector3* offset) {
+    for(size_t i = 0; i < 3; i++) {
+        if(offset->data[i] > 0.0f) {
+            box->max.data[i] += offset->data[i];
+        } else {
+            box->min.data[i] += offset->data[i];
+        }
+    }
+    return box;
+}
+
+CoreBox* coreGrowBox(CoreBox* box, const CoreVector3* growth) {
+    CoreVector3 half = {0};
+    coreMulV3F(&half, growth, 0.5f);
+    CoreVector3 nMin = {0};
+    coreSubV3(&nMin, &box->min, &half);
+    CoreVector3 nMax = {0};
+    coreAddV3(&nMax, &box->max, &half);
+    for(size_t i = 0; i < 3; i++) {
+        if(nMin.data[i] > nMax.data[i]) {
+            nMin.data[i] = (box->min.data[i] + box->max.data[i]) * 0.5f;
+            nMax.data[i] = nMin.data[i];
+        }
+    }
+    box->min = nMin;
+    box->max = nMax;
+    return box;
+}
+
+size_t coreToStringBox(const CoreBox* box, char* buffer, size_t n) {
+    int w = snprintf(buffer, n, "Box([%.3f, %.3f, %.3f], [%.3f, %.3f, %.3f])",
+                     (double)box->min.data[0], (double)box->min.data[1],
+                     (double)box->min.data[2], (double)box->min.data[3],
+                     (double)box->min.data[4], (double)box->min.data[5]);
+    return w < 0 ? 0 : (size_t)w;
+}

+ 1 - 1
test/Main.c

@@ -32,7 +32,6 @@ int main(int argAmount, const char** args) {
     }
 
     // coreTestBitArray();
-    // coreTestBox();
     // coreTestComponents();
     // coreTestFrustum();
     // coreTestHashMap(light);
@@ -41,6 +40,7 @@ int main(int argAmount, const char** args) {
     // coreTestMatrixStack(light);
     // coreTestRingBuffer();
     // coreTestStack(light);
+    coreTestBox();
     coreTestBuffer(light);
     coreTestMatrix();
     coreTestPlane();

+ 100 - 0
test/modules/BoxTests.c

@@ -0,0 +1,100 @@
+#include "../Tests.h"
+#include "core/Box.h"
+
+#define CV3(a, b, c) (&(CoreVector3){{a, b, c}})
+
+static void testInit() {
+    CoreBox box = {0};
+    coreSetBox(&box, CV3(1.0f, 2.0f, 3.0f));
+    char buffer[128];
+    coreToStringBox(&box, buffer, sizeof(buffer));
+    CORE_TEST_STRING("Box([0.000, 0.000, 0.000], [1.000, 2.000, 3.000])",
+                     buffer);
+    coreToStringV3(&box.min, buffer, sizeof(buffer));
+    CORE_TEST_STRING("[0.000, 0.000, 0.000]", buffer);
+    coreToStringV3(&box.max, buffer, sizeof(buffer));
+    CORE_TEST_STRING("[1.000, 2.000, 3.000]", buffer);
+
+    coreSetBox(&box, CV3(-1.0f, -2.0f, -3.0f));
+    coreToStringBox(&box, buffer, sizeof(buffer));
+    CORE_TEST_STRING("Box([-1.000, -2.000, -3.000], [0.000, 0.000, 0.000])",
+                     buffer);
+    coreToStringV3(&box.min, buffer, sizeof(buffer));
+    CORE_TEST_STRING("[-1.000, -2.000, -3.000]", buffer);
+    coreToStringV3(&box.max, buffer, sizeof(buffer));
+    CORE_TEST_STRING("[0.000, 0.000, 0.000]", buffer);
+}
+
+static void testOffset() {
+    CoreBox box = {0};
+    coreSetBox(&box, CV3(1.0f, 2.0f, 3.0f));
+    coreOffsetBox(&box, CV3(7.0f, -4.0f, 6.0f));
+    char buffer[128];
+    coreToStringBox(&box, buffer, sizeof(buffer));
+    CORE_TEST_STRING("Box([7.000, -4.000, 6.000], [8.000, -2.000, 9.000])",
+                     buffer);
+}
+
+static void testCollidesWith() {
+    CoreBox boxA = {0};
+    coreSetBox(&boxA, CV3(1.0f, 2.0f, 3.0f));
+    CoreBox boxB = {0};
+    coreSetBox(&boxB, CV3(-1.0f, -2.0f, -3.0f));
+    CoreBox boxC = {0};
+    coreSetBox(&boxC, CV3(2.0f, 2.0f, 2.0f));
+    coreOffsetBox(&boxC, CV3(-1.0f, -1.0f, -1.0f));
+
+    CORE_TEST_TRUE(coreCollidesWithBox(&boxC, &boxA));
+    CORE_TEST_TRUE(coreCollidesWithBox(&boxC, &boxB));
+    CORE_TEST_TRUE(coreCollidesWithBox(&boxA, &boxC));
+    CORE_TEST_TRUE(coreCollidesWithBox(&boxB, &boxC));
+    CORE_TEST_FALSE(coreCollidesWithBox(&boxA, &boxB));
+    CORE_TEST_FALSE(coreCollidesWithBox(&boxB, &boxA));
+}
+
+static void testExpand() {
+    CoreBox box = {0};
+    coreSetBox(&box, CV3(1.0f, 2.0f, 3.0f));
+    coreExpandBox(&box, CV3(7.0f, -4.0f, 6.0f));
+
+    char buffer[128];
+    coreToStringBox(&box, buffer, sizeof(buffer));
+    CORE_TEST_STRING("Box([0.000, -4.000, 0.000], [8.000, 2.000, 9.000])",
+                     buffer);
+
+    coreSetBox(&box, CV3(1.0f, 2.0f, 3.0f));
+    coreExpandBox(&box, CV3(-7.0f, 4.0f, -6.0f));
+    coreToStringBox(&box, buffer, sizeof(buffer));
+    CORE_TEST_STRING("Box([-7.000, 0.000, -6.000], [1.000, 6.000, 3.000])",
+                     buffer);
+}
+
+static void testGrow() {
+    CoreBox box = {0};
+    coreSetBox(&box, CV3(1.0f, 2.0f, 3.0f));
+    coreGrowBox(&box, CV3(4.0f, 2.0f, 6.0f));
+    char buffer[128];
+    coreToStringBox(&box, buffer, sizeof(buffer));
+    CORE_TEST_STRING("Box([-2.000, -1.000, -3.000], [3.000, 3.000, 6.000])",
+                     buffer);
+
+    coreSetBox(&box, CV3(1.0f, 2.0f, 3.0f));
+    coreGrowBox(&box, CV3(-4.0f, -2.0f, -6.0f));
+    coreToStringBox(&box, buffer, sizeof(buffer));
+    CORE_TEST_STRING("Box([0.500, 1.000, 1.500], [0.500, 1.000, 1.500])",
+                     buffer);
+
+    coreSetBox(&box, CV3(1.0f, 2.0f, 3.0f));
+    coreGrowBox(&box, CV3(-0.1f, -4.0f, -1.0f));
+    coreToStringBox(&box, buffer, sizeof(buffer));
+    CORE_TEST_STRING("Box([0.050, 1.000, 0.500], [0.950, 1.000, 2.500])",
+                     buffer);
+}
+
+void coreTestBox() {
+    testInit();
+    testOffset();
+    testCollidesWith();
+    testExpand();
+    testGrow();
+}