use crate::{
BspData,
data::{
lighting::{LightmapOffset, LightmapStyle},
nodes::{BspNodeRef, FloatBoundingBox},
util::{NoField, UBspValue},
},
reader::BspVariableValue,
};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::Reflect;
use glam::Vec3;
use qbsp_macros::{BspValue, BspVariableValue};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(BspValue, Clone, PartialEq, Debug, Copy)]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Hulls {
pub root: BspNodeRef,
pub for_size: Option<PerSizeHulls>,
}
#[derive(BspValue, Clone, PartialEq, Debug, Copy)]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PerSizeHulls {
pub small: BspNodeRef,
pub large: BspNodeRef,
pub unused: BspNodeRef,
}
impl BspVariableValue for Option<PerSizeHulls> {
type Bsp29 = PerSizeHulls;
type Bsp2 = PerSizeHulls;
type Bsp30 = PerSizeHulls;
type Bsp38 = NoField;
type Qbism = NoField;
}
#[derive(BspVariableValue, Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[bsp29(u32)]
#[bsp2(u32)]
#[bsp30(u32)]
#[bsp38(NoField)]
#[qbism(NoField)]
pub struct VisleafsField(pub Option<u32>);
#[derive(BspValue, Debug, Clone, Copy)]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct BspModel {
pub bound: FloatBoundingBox,
pub origin: Vec3,
pub hulls: Hulls,
pub visleafs: VisleafsField,
pub first_face: u32,
pub num_faces: u32,
}
#[derive(BspValue, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct BspEdge {
pub a: UBspValue,
pub b: UBspValue,
}
#[derive(BspValue, Debug, Clone, Copy)]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct BspFace {
pub plane_idx: UBspValue,
pub plane_side: UBspValue,
pub first_edge: u32,
pub num_edges: UBspValue,
pub texture_info_idx: UBspValue,
pub lightmap_styles: [LightmapStyle; 4],
pub lightmap_offset: LightmapOffset,
}
impl BspFace {
#[inline]
pub fn vertices<'a>(&self, bsp: &'a BspData) -> impl Iterator<Item = Vec3> + 'a {
(self.first_edge..self.first_edge + self.num_edges.0).map(|i| {
let surf_edge = bsp.surface_edges[i as usize];
let edge = bsp.edges[surf_edge.unsigned_abs() as usize];
let vert_idx = if surf_edge.is_negative() { (edge.b, edge.a) } else { (edge.a, edge.b) };
bsp.vertices[*vert_idx.0 as usize]
})
}
}