summary refs log tree commit diff
path: root/src/GFX/Util/Primitives.cpp
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2023-07-12 03:39:01 +0200
committerMel <einebeere@gmail.com>2023-07-12 03:39:01 +0200
commitf09e5791837bb003f7c5db8c0e3162636bc9a9c2 (patch)
tree36b9a007f119388bb7943489e8d203de04269483 /src/GFX/Util/Primitives.cpp
parent0ce26f2a49fd6d64a690b84b1932126edfbfbee6 (diff)
downloadmeowcraft-f09e5791837bb003f7c5db8c0e3162636bc9a9c2.tar.zst
meowcraft-f09e5791837bb003f7c5db8c0e3162636bc9a9c2.zip
3D Clouds
Diffstat (limited to 'src/GFX/Util/Primitives.cpp')
-rw-r--r--src/GFX/Util/Primitives.cpp107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/GFX/Util/Primitives.cpp b/src/GFX/Util/Primitives.cpp
new file mode 100644
index 0000000..d2c3690
--- /dev/null
+++ b/src/GFX/Util/Primitives.cpp
@@ -0,0 +1,107 @@
+#include "Primitives.hpp"
+
+namespace MC::GFX::Util::Primitives {
+
+PlanePrimitive plane(Math::AABB aabb, FaceSet face) {
+    decltype(PlanePrimitive::positions) positions;
+    auto [min, max] = aabb;
+
+    switch (face) {
+    case FaceSet::Front:
+        positions = {{
+            {min.x(), min.y(), min.z()}, {min.x(), max.y(), min.z()},
+            {max.x(), max.y(), min.z()}, {max.x(), min.y(), min.z()}
+        }};
+        break;
+    case FaceSet::Back:
+        positions = {{
+            {min.x(), min.y(), max.z()}, {max.x(), min.y(), max.z()},
+            {max.x(), max.y(), max.z()}, {min.x(), max.y(), max.z()}
+        }};
+        break;
+    case FaceSet::Top:
+        positions = {{
+            {min.x(), max.y(), min.z()}, {min.x(), max.y(), max.z()},
+            {max.x(), max.y(), max.z()}, {max.x(), max.y(), min.z()}
+        }};
+        break;
+    case FaceSet::Bottom:
+        positions = {{
+            {min.x(), min.y(), min.z()}, {max.x(), min.y(), min.z()},
+            {max.x(), min.y(), max.z()}, {min.x(), min.y(), max.z()}
+        }};
+        break;
+    case FaceSet::Right:
+        positions = {{
+            {max.x(), min.y(), min.z()}, {max.x(), max.y(), min.z()},
+            {max.x(), max.y(), max.z()}, {max.x(), min.y(), max.z()}
+        }};
+        break;
+    case FaceSet::Left:
+        positions = {{
+            {min.x(), min.y(), min.z()}, {min.x(), min.y(), max.z()},
+            {min.x(), max.y(), max.z()}, {min.x(), max.y(), min.z()}
+        }};
+        break;
+    }
+
+    auto is_side = [=](FaceSet f) -> I8 { return f == face; };
+    Vector<3, F32> normal = {
+        is_side(FaceSet::Right) - is_side(FaceSet::Left),
+        is_side(FaceSet::Top) - is_side(FaceSet::Bottom),
+        is_side(FaceSet::Front) - is_side(FaceSet::Back),
+    };
+
+    return {positions, {normal, normal, normal, normal}, {0, 1, 2, 2, 3, 0}};
+}
+
+BoxPrimitive box(Math::AABB aabb, FaceSet faces) {
+    BoxPrimitive box{};
+    auto [min, max] = aabb;
+
+    UInt set_faces = 0;
+    U8 face_value = 1;
+    for (UInt face_index = 0; face_index < FaceSet::Size; face_index++, face_value <<= 1) {
+        FaceSet face = (FaceSet::Value)face_value;
+        if ((faces & face) == 0) continue;
+
+        Math::AABB face_aabb;
+        switch (face) {
+        case FaceSet::Front:
+            face_aabb = {min, {max.x(), max.y(), min.z()}};
+            break;
+        case FaceSet::Back:
+            face_aabb = {{min.x(), min.y(), max.z()}, max};
+            break;
+        case FaceSet::Top:
+            face_aabb = {{min.x(), max.y(), min.z()}, {max.x(), max.y(), max.z()}};
+            break;
+        case FaceSet::Bottom:
+            face_aabb = {min, {max.x(), min.y(), max.z()}};
+            break;
+        case FaceSet::Right:
+            face_aabb = {{max.x(), min.y(), min.z()}, max};
+            break;
+        case FaceSet::Left:
+            face_aabb = {min, {min.x(), max.y(), max.z()}};
+            break;
+        }
+
+        auto p = plane(face_aabb, face);
+
+        for (UInt i = 0; i < p.positions.size(); i++) {
+            box.positions[set_faces * 4 + i] = p.positions[i];
+        }
+        for (UInt i = 0; i < p.normals.size(); i++) {
+            box.normals[set_faces * 4 + i] = p.normals[i];
+        }
+        for (UInt i = 0; i < p.indices.size(); i++) {
+            box.indices[set_faces * 6 + i] = p.indices[i] + set_faces * 4;
+        }
+        set_faces++;
+    }
+
+    return box;
+}
+
+}
\ No newline at end of file