#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; } }