#[derive(Clone, Copy, Debug, Default)]
pub struct Plane {
pub normal: [f32; 3],
pub dist: f32,
}
#[derive(Clone, Copy, Debug)]
pub struct Node {
pub plane: u16,
pub children: [i32; 2],
pub mins: [i16; 3],
pub maxs: [i16; 3],
pub first_face: u16,
pub num_faces: u16,
}
#[derive(Clone, Copy, Debug)]
pub struct Leaf {
pub cluster: i16,
pub mins: [i16; 3],
pub maxs: [i16; 3],
pub first_marksurface: u16,
pub num_marksurfaces: u16,
}
#[derive(Clone, Copy, Debug)]
pub struct Face {
pub first_vert: u32,
pub num_verts: u16,
pub texture_id: u32,
pub lightmap_id: u16,
pub plane: u16,
pub side: u8,
pub sector_light_id: u16,
}
pub struct BspWorld<'a> {
pub planes: &'a [Plane],
pub nodes: &'a [Node],
pub leaves: &'a [Leaf],
pub faces: &'a [Face],
pub marksurfaces: &'a [u16],
pub vertices: &'a [[f32; 3]],
pub uvs: &'a [[f32; 2]],
pub lm_uvs: &'a [[f32; 2]],
pub vis: &'a [u8],
pub vis_offsets: &'a [u32],
pub num_clusters: u16,
}
impl<'a> BspWorld<'a> {
#[allow(clippy::too_many_arguments)]
pub fn new(
planes: &'a [Plane],
nodes: &'a [Node],
leaves: &'a [Leaf],
faces: &'a [Face],
marksurfaces: &'a [u16],
vertices: &'a [[f32; 3]],
uvs: &'a [[f32; 2]],
lm_uvs: &'a [[f32; 2]],
vis: &'a [u8],
vis_offsets: &'a [u32],
num_clusters: u16,
) -> Self {
Self {
planes,
nodes,
leaves,
faces,
marksurfaces,
vertices,
uvs,
lm_uvs,
vis,
vis_offsets,
num_clusters,
}
}
}
#[derive(Clone, Copy, Debug)]
pub struct FrustumPlane {
pub normal: [f32; 3],
pub d: f32,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn bsp_world_new_borrows_all_lumps() {
let planes = [Plane {
normal: [1.0, 0.0, 0.0],
dist: 0.0,
}];
let nodes = [Node {
plane: 0,
children: [!0i32, !0i32],
mins: [-1, -1, -1],
maxs: [1, 1, 1],
first_face: 0,
num_faces: 0,
}];
let leaves = [Leaf {
cluster: 0,
mins: [-1, -1, -1],
maxs: [1, 1, 1],
first_marksurface: 0,
num_marksurfaces: 1,
}];
let faces = [Face {
first_vert: 0,
num_verts: 3,
texture_id: 7,
lightmap_id: 0xFFFF,
plane: 0,
side: 0,
sector_light_id: u16::MAX,
}];
let marksurfaces = [0u16];
let vertices = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let uvs = [[0.0, 0.0], [1.0, 0.0], [0.0, 1.0]];
let lm_uvs = [[0.0, 0.0], [1.0, 0.0], [0.0, 1.0]];
let vis = [0b1u8];
let vis_offsets = [0u32];
let world = BspWorld::new(
&planes,
&nodes,
&leaves,
&faces,
&marksurfaces,
&vertices,
&uvs,
&lm_uvs,
&vis,
&vis_offsets,
1,
);
assert_eq!(world.planes.len(), 1);
assert_eq!(world.nodes.len(), 1);
assert_eq!(world.leaves.len(), 1);
assert_eq!(world.faces[0].texture_id, 7);
assert_eq!(world.vertices.len(), 3);
assert_eq!(world.uvs.len(), 3);
assert_eq!(world.lm_uvs.len(), 3);
assert_eq!(world.vis_offsets[0], 0);
assert_eq!(world.num_clusters, 1);
}
#[test]
fn frustum_plane_inside_test_matches_definition() {
let p = FrustumPlane {
normal: [1.0, 0.0, 0.0],
d: -2.0,
};
let inside = p.normal[0] * 3.0 + p.normal[1] * 0.0 + p.normal[2] * 0.0 + p.d;
let outside = p.normal[0] * 1.0 + p.normal[1] * 0.0 + p.normal[2] * 0.0 + p.d;
assert!(inside >= 0.0);
assert!(outside < 0.0);
}
}