kale2d/src/bsp/BSP.h

207 lines
3.8 KiB
C++

#pragma once
#include "../types.h"
#include <glm/glm.hpp>
#include <vector>
#include <string>
#include <map>
#define MAX_TEXTURE_NAME 16
#define MIP_LEVELS 4
struct SDL_GPUTexture;
#define MAX_MAP_HULLS 4
/* contains loading functions for Half Life BSPs */
namespace HLBSP {
struct Lump {
uint32_t offset;
uint32_t len;
};
using rgb = glm::uvec3;
using rgba = glm::uvec4;
using vec3 = glm::vec3;
using vec2 = glm::vec2;
using ivec3 = glm::vec<3, int16_t>;
struct Header {
uint32_t 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 {
uint32_t n_mip_textures;
int32_t offsets[];
};
struct MipTexture {
char name[MAX_TEXTURE_NAME];
uint32_t width, height;
/* is 0 if stored in WAD, otherwise, offset is from beginning of this struct */
uint32_t mip_offsets[MIP_LEVELS];
};
struct Vis {};
struct Node {
int32_t plane;
/* negative numbers are leaf indices */
int16_t children[2];
/* bounding box coords (integer) */
ivec3 bb_mins;
ivec3 bb_maxes;
int16_t first_face_idx;
int16_t n_faces;
};
struct TexInfo {
vec3 shift_s_dir;
float shift_s;
vec3 shift_t_dir;
float shift_t;
uint32_t mip_tex_idx;
/* seems to always be 0 */
uint32_t flags;
};
struct Face {
uint16_t plane_idx;
/* set if different normals orientation */
uint16_t plane_side;
uint32_t first_surf_edge_idx;
int16_t n_surf_edges;
int16_t tex_info_idx;
uint8_t lighting_styles[4];
uint32_t lightmap_offset;
};
struct Lightmap {
rgb* lights;
};
struct ClipNode {
int32_t plane_idx;
/* negative numbers are contents */
int16_t 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 */
int32_t vis_offset;
ivec3 bb_mins;
ivec3 bb_maxes;
uint16_t first_mark_surface_idx;
uint16_t n_mark_surfaces;
uint8_t ambient_sound_levels[4];
};
typedef uint16_t MarkSurface;
struct Edge {
uint16_t vertex_indices[2];
};
typedef int32_t Surfedge;
struct Model {
vec3 bb_mins;
vec3 bb_maxes;
vec3 origin;
int32_t head_node_indices[MAX_MAP_HULLS];
int32_t vis_leafs;
int32_t first_face_idx;
int32_t n_faces;
};
struct BSP {
BSP(const std::string& fname);
void load_vertices();
int determine_leaf(vec3 cam_pos);
bool determine_visibility(const Leaf& cam_leaf, const Leaf& leaf, const std::array<glm::vec4, 6>& frustum, const vec3 box_verts[8]);
int get_index_from_surfedge(int surfedge);
Header* header;
std::string filename;
std::vector<uint8_t> file_data;
std::vector<::std::map<::std::string, std::string>> entities;
std::vector<Plane> planes;
std::vector<MipTexture> textures;
std::vector<glm::vec3> vertices;
std::vector<glm::vec3> processed_vertices;
/* skipping vis for now */
std::vector<Node> nodes;
std::vector<TexInfo> tex_infos;
std::vector<Face> faces;
Lightmap lightmap;
std::vector<ClipNode> clip_nodes;
std::vector<Leaf> leaves;
std::vector<MarkSurface> mark_surfaces;
std::vector<Edge> edges;
std::vector<Surfedge> surfedges;
std::vector<Model> models;
std::vector<Vertex> textured_vertices;
/* to eliminate needless re-loading*/
int last_leaf = -0x1337;
};
}