mirror of
https://codeberg.org/icewind/vbsp.git
synced 2026-06-03 18:54:05 +02:00
impl BinRead for Leaves
Read LeafV1 and convert into Leaf
This commit is contained in:
parent
8d2ea3d6fb
commit
08414d9b51
2 changed files with 133 additions and 7 deletions
|
|
@ -2,7 +2,12 @@ use std::io::{Read, Seek};
|
||||||
use std::mem::{align_of, size_of};
|
use std::mem::{align_of, size_of};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use binrw::BinRead;
|
use binrw::{BinRead, BinResult, Endian};
|
||||||
|
|
||||||
|
use crate::bspfile::LumpType;
|
||||||
|
use crate::BspError;
|
||||||
|
|
||||||
|
use super::LumpArgs;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Leaves {
|
pub struct Leaves {
|
||||||
|
|
@ -36,6 +41,55 @@ impl Leaves {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BinRead for Leaves {
|
||||||
|
type Args<'a> = LumpArgs;
|
||||||
|
|
||||||
|
fn read_options<R: Read + Seek>(
|
||||||
|
reader: &mut R,
|
||||||
|
endian: Endian,
|
||||||
|
args: Self::Args<'_>,
|
||||||
|
) -> BinResult<Self> {
|
||||||
|
let item_size = match args.version {
|
||||||
|
1 => size_of::<LeafV1>(),
|
||||||
|
version => {
|
||||||
|
return Err(binrw::Error::Custom {
|
||||||
|
err: Box::new(BspError::LumpVersion(
|
||||||
|
crate::error::UnsupportedLumpVersion {
|
||||||
|
lump_type: "leaves",
|
||||||
|
version: version as u16,
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
pos: reader.stream_position().unwrap(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if args.length % item_size != 0 {
|
||||||
|
return Err(binrw::Error::Custom {
|
||||||
|
err: Box::new(BspError::InvalidLumpSize {
|
||||||
|
lump: LumpType::Leaves,
|
||||||
|
element_size: item_size,
|
||||||
|
lump_size: args.length,
|
||||||
|
}),
|
||||||
|
pos: reader.stream_position().unwrap(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let num_entries = args.length / item_size;
|
||||||
|
let mut entries = Vec::with_capacity(num_entries);
|
||||||
|
|
||||||
|
for _ in 0..num_entries {
|
||||||
|
entries.push(Leaf::read_options(
|
||||||
|
reader,
|
||||||
|
endian,
|
||||||
|
LeafArgs {
|
||||||
|
version: args.version,
|
||||||
|
},
|
||||||
|
)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self { leaves: entries })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct LeafClusters<'a> {
|
struct LeafClusters<'a> {
|
||||||
leaves: &'a [Leaf],
|
leaves: &'a [Leaf],
|
||||||
index: usize,
|
index: usize,
|
||||||
|
|
@ -135,7 +189,56 @@ impl<'a> IntoIterator for &'a mut Leaves {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(BinRead, Debug, Default, Clone, Copy)]
|
||||||
|
pub struct ColorRGBExp32 {
|
||||||
|
pub r: u8,
|
||||||
|
pub g: u8,
|
||||||
|
pub b: u8,
|
||||||
|
pub exponent: i8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(BinRead, Debug, Default, Clone, Copy)]
|
||||||
|
pub struct CompressedLightCube {
|
||||||
|
pub color: [ColorRGBExp32; 6],
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, BinRead)]
|
#[derive(Default, Debug, Clone, BinRead)]
|
||||||
|
pub struct LeafV1 {
|
||||||
|
pub contents: i32,
|
||||||
|
pub cluster: i16,
|
||||||
|
pub area_and_flags: i16,
|
||||||
|
// first 9 bits is area, last 7 bits is flags
|
||||||
|
pub mins: [i16; 3],
|
||||||
|
pub maxs: [i16; 3],
|
||||||
|
pub first_leaf_face: u16,
|
||||||
|
pub leaf_face_count: u16,
|
||||||
|
pub first_leaf_brush: u16,
|
||||||
|
pub leaf_brush_count: u16,
|
||||||
|
#[br(align_after = align_of::< LeafV1 > ())]
|
||||||
|
pub leaf_watter_data_id: i16,
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assertions::const_assert_eq!(size_of::<LeafV1>(), 32);
|
||||||
|
|
||||||
|
impl From<LeafV1> for Leaf {
|
||||||
|
fn from(value: LeafV1) -> Self {
|
||||||
|
Self {
|
||||||
|
contents: value.contents,
|
||||||
|
cluster: value.cluster,
|
||||||
|
area_and_flags: value.area_and_flags,
|
||||||
|
mins: value.mins,
|
||||||
|
maxs: value.maxs,
|
||||||
|
first_leaf_face: value.first_leaf_face,
|
||||||
|
leaf_face_count: value.leaf_face_count,
|
||||||
|
first_leaf_brush: value.first_leaf_brush,
|
||||||
|
leaf_brush_count: value.leaf_brush_count,
|
||||||
|
leaf_watter_data_id: value.leaf_watter_data_id,
|
||||||
|
cube: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone)]
|
||||||
pub struct Leaf {
|
pub struct Leaf {
|
||||||
pub contents: i32,
|
pub contents: i32,
|
||||||
pub cluster: i16,
|
pub cluster: i16,
|
||||||
|
|
@ -147,13 +250,39 @@ pub struct Leaf {
|
||||||
pub leaf_face_count: u16,
|
pub leaf_face_count: u16,
|
||||||
pub first_leaf_brush: u16,
|
pub first_leaf_brush: u16,
|
||||||
pub leaf_brush_count: u16,
|
pub leaf_brush_count: u16,
|
||||||
#[br(align_after = align_of::< Leaf > ())]
|
|
||||||
pub leaf_watter_data_id: i16,
|
pub leaf_watter_data_id: i16,
|
||||||
|
pub cube: CompressedLightCube,
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(size_of::<Leaf>(), 32);
|
static_assertions::const_assert_eq!(size_of::<Leaf>(), 56);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_leaf_bytes() {
|
fn test_leaf_bytes() {
|
||||||
super::test_read_bytes::<Leaf>();
|
super::test_read_bytes::<Leaf>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone)]
|
||||||
|
pub struct LeafArgs {
|
||||||
|
pub version: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BinRead for Leaf {
|
||||||
|
type Args<'a> = LeafArgs;
|
||||||
|
|
||||||
|
fn read_options<R: Read + Seek>(
|
||||||
|
reader: &mut R,
|
||||||
|
endian: Endian,
|
||||||
|
args: Self::Args<'_>,
|
||||||
|
) -> BinResult<Self> {
|
||||||
|
match args.version {
|
||||||
|
1 => LeafV1::read_options(reader, endian, ()).map(Leaf::from),
|
||||||
|
version => Err(binrw::Error::Custom {
|
||||||
|
err: Box::new(crate::error::UnsupportedLumpVersion {
|
||||||
|
lump_type: "leaves",
|
||||||
|
version: version as u16,
|
||||||
|
}),
|
||||||
|
pos: reader.stream_position().unwrap(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,10 +81,7 @@ impl Bsp {
|
||||||
let nodes = bsp_file
|
let nodes = bsp_file
|
||||||
.lump_reader(LumpType::Nodes)?
|
.lump_reader(LumpType::Nodes)?
|
||||||
.read_vec(|r| r.read())?;
|
.read_vec(|r| r.read())?;
|
||||||
let leaves = bsp_file
|
let leaves = bsp_file.lump_reader(LumpType::Leaves)?.read_args()?;
|
||||||
.lump_reader(LumpType::Leaves)?
|
|
||||||
.read_vec(|r| r.read())?
|
|
||||||
.into();
|
|
||||||
let leaf_faces = bsp_file
|
let leaf_faces = bsp_file
|
||||||
.lump_reader(LumpType::LeafFaces)?
|
.lump_reader(LumpType::LeafFaces)?
|
||||||
.read_vec(|r| r.read())?;
|
.read_vec(|r| r.read())?;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue