#pragma once #include #include #include #include #define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS #include #include #include #define MAX_TEXTURE_NAME 16 #define MIP_LEVELS 4 #define MAX_MAP_HULLS 4 /* contains loading functions for Half Life BSPs */ namespace HLBSP { struct Lump { u32 offset; u32 len; }; using rgb = glm::u8vec3; using rgba = glm::u8vec4; using vec3 = glm::vec3; using vec2 = glm::vec2; using ivec3 = glm::vec<3, i16>; struct Header { u32 version; union { Lump lumps[15]; struct { Lump entities, planes, textures, vertices, visibility, nodes, texinfo, faces, lighting, clip_nodes, leaves, mark_surfaces, edges, surf_edges, models; }; }; }; struct Plane { vec3 norm; float dist; /* exists for certain optimizations (swaped y and z) */ enum PlaneType { eX, eZ, eY, eAnyX, eAnyZ, eAnyY, } type; }; struct TextureLump { u32 n_mip_textures; i32 offsets[]; }; struct MipTexture { char name[MAX_TEXTURE_NAME]; u32 width, height; /* is 0 if stored in WAD, otherwise, offset is from beginning of this struct */ u32 mip_offsets[MIP_LEVELS]; }; struct Vertex { vec3 pos; vec2 uv; static inline std::vector attrs(uint32_t binding) { return std::vector { { .location = 0, .binding = binding, .format = vk::Format::eR32G32B32Sfloat, .offset = offsetof(Vertex, pos), }, { .location = 1, .binding = binding, .format = vk::Format::eR32G32Sfloat, .offset = offsetof(Vertex, uv), } }; } }; struct Vis {}; struct Node { i32 plane; /* negative numbers are leaf indices */ i16 children[2]; /* bounding box coords (integer) */ ivec3 bb_mins; ivec3 bb_maxes; i16 first_face_idx; i16 n_faces; }; struct TexInfo { vec3 shift_s_dir; float shift_s; vec3 shift_t_dir; float shift_t; u32 mip_tex_idx; /* seems to always be 0 */ u32 flags; }; struct Face { u16 plane_idx; /* set if different normals orientation */ u16 plane_side; u32 first_surf_edge_idx; i16 n_surf_edges; i16 tex_info_idx; u8 lighting_styles[4]; u32 lightmap_offset; }; struct Lightmap { rgb* lights; }; struct ClipNode { i32 plane_idx; /* negative numbers are contents */ i16 children[2]; }; struct Leaf { enum { eEmpty = -1, eSolid = -2, eWater = -3, eSlime = -4, eLava = -5, eSky = -6, eOrigin = -7, eClip = -8, eCurrent0 = -9, eCurrent90 = -10, eCurrent180 = -11, eCurrent270 = -12, eCurrentUp = -13, eCurrentDown = -14, eTranslucent = -15, } contents; /* if this is -1, no VIS data */ i32 vis_offset; ivec3 bb_mins; ivec3 bb_maxes; u16 first_mark_surface_idx; u16 n_mark_surfaces; u8 ambient_sound_levels[4]; }; typedef u16 MarkSurface; struct Edge { u16 vertex_indices[2]; }; typedef i32 Surfedge; struct Model { vec3 bb_mins; vec3 bb_maxes; vec3 origin; i32 head_node_indices[MAX_MAP_HULLS]; i32 vis_leafs; i32 first_face_idx; i32 n_faces; }; struct BSP { BSP(vk::PhysicalDevice phys_dev, vk::Device dev, const std::string& fname); void load_vertices(const vec3& cam_pos, bool visibility_testing, const glm::mat4& view); int determine_leaf(vec3 cam_pos); bool determine_visibility(const Leaf& cam_leaf, const Leaf& leaf, const std::array& frustum, const vec3 box_verts[8]); int get_index_from_surfedge(int surfedge); vk::Device dev; Header* header; std::string filename; std::vector file_data; std::vector<::std::map<::std::string, std::string>> entities; std::vector planes; std::vector textures; std::vector vertices; std::vector processed_vertices; /* skipping vis for now */ std::vector nodes; std::vector tex_infos; std::vector faces; Lightmap lightmap; std::vector clip_nodes; std::vector leaves; std::vector mark_surfaces; std::vector edges; std::vector surfedges; std::vector models; std::vector textured_vertices; std::unique_ptr> vertex_buffer; std::unique_ptr pipeline; /* to eliminate needless re-loading*/ int last_leaf = -0x1337; ~BSP() { vertex_buffer.reset(); pipeline.reset(); } }; }