mirror of
https://codeberg.org/icewind/vbsp.git
synced 2026-06-03 18:54:05 +02:00
move Leaves code into module
This commit is contained in:
parent
0d2113f2e6
commit
75728cfab6
3 changed files with 163 additions and 156 deletions
159
src/data/leaves.rs
Normal file
159
src/data/leaves.rs
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
use std::io::{Read, Seek};
|
||||
use std::mem::{align_of, size_of};
|
||||
use std::ops::Deref;
|
||||
|
||||
use binrw::BinRead;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Leaves {
|
||||
leaves: Vec<Leaf>,
|
||||
}
|
||||
|
||||
impl Leaves {
|
||||
pub fn new(mut leaves: Vec<Leaf>) -> Self {
|
||||
leaves.sort_unstable_by_key(|leaf| leaf.cluster);
|
||||
|
||||
Leaves { leaves }
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Leaf> {
|
||||
self.into_iter()
|
||||
}
|
||||
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Leaf> {
|
||||
self.into_iter()
|
||||
}
|
||||
|
||||
pub fn into_inner(self) -> Vec<Leaf> {
|
||||
self.leaves
|
||||
}
|
||||
|
||||
pub fn clusters(&self) -> impl Iterator<Item = impl Iterator<Item = &Leaf>> {
|
||||
LeafClusters {
|
||||
leaves: &self.leaves,
|
||||
index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LeafClusters<'a> {
|
||||
leaves: &'a [Leaf],
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for LeafClusters<'a> {
|
||||
type Item = <&'a [Leaf] as IntoIterator>::IntoIter;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let cluster = self.leaves.get(self.index)?.cluster;
|
||||
let remaining_leaves = self.leaves.get(self.index..)?;
|
||||
let cluster_size = remaining_leaves
|
||||
.iter()
|
||||
.take_while(|leaf| leaf.cluster == cluster)
|
||||
.count();
|
||||
self.index += cluster_size;
|
||||
Some(remaining_leaves[0..cluster_size].iter())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_leaf_clusters() {
|
||||
let leaves: Leaves = vec![
|
||||
Leaf {
|
||||
contents: 0,
|
||||
cluster: 0,
|
||||
..Default::default()
|
||||
},
|
||||
Leaf {
|
||||
contents: 1,
|
||||
cluster: 0,
|
||||
..Default::default()
|
||||
},
|
||||
Leaf {
|
||||
contents: 2,
|
||||
cluster: 1,
|
||||
..Default::default()
|
||||
},
|
||||
Leaf {
|
||||
contents: 3,
|
||||
cluster: 2,
|
||||
..Default::default()
|
||||
},
|
||||
Leaf {
|
||||
contents: 4,
|
||||
cluster: 2,
|
||||
..Default::default()
|
||||
},
|
||||
]
|
||||
.into();
|
||||
|
||||
let clustered: Vec<Vec<i32>> = leaves
|
||||
.clusters()
|
||||
.map(|cluster| cluster.map(|leaf| leaf.contents).collect())
|
||||
.collect();
|
||||
assert_eq!(vec![vec![0, 1], vec![2], vec![3, 4]], clustered);
|
||||
}
|
||||
|
||||
impl From<Vec<Leaf>> for Leaves {
|
||||
fn from(other: Vec<Leaf>) -> Self {
|
||||
Self::new(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Leaves {
|
||||
type Target = [Leaf];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.leaves
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for Leaves {
|
||||
type Item = Leaf;
|
||||
type IntoIter = <Vec<Leaf> as IntoIterator>::IntoIter;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.leaves.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a Leaves {
|
||||
type Item = &'a Leaf;
|
||||
type IntoIter = <&'a [Leaf] as IntoIterator>::IntoIter;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.leaves[..].iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a mut Leaves {
|
||||
type Item = &'a mut Leaf;
|
||||
type IntoIter = <&'a mut [Leaf] as IntoIterator>::IntoIter;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.leaves.iter_mut()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, BinRead)]
|
||||
pub struct Leaf {
|
||||
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::< Leaf > ())]
|
||||
pub leaf_watter_data_id: i16,
|
||||
}
|
||||
|
||||
static_assertions::const_assert_eq!(size_of::<Leaf>(), 32);
|
||||
|
||||
#[test]
|
||||
fn test_leaf_bytes() {
|
||||
super::test_read_bytes::<Leaf>();
|
||||
}
|
||||
|
|
@ -1,12 +1,14 @@
|
|||
mod displacement;
|
||||
mod entity;
|
||||
mod game;
|
||||
mod leaves;
|
||||
mod prop;
|
||||
mod vector;
|
||||
|
||||
pub use self::displacement::*;
|
||||
pub use self::entity::*;
|
||||
pub use self::game::*;
|
||||
pub use self::leaves::*;
|
||||
pub use self::prop::PropPlacement;
|
||||
pub use self::vector::*;
|
||||
use crate::bspfile::LumpType;
|
||||
|
|
@ -26,7 +28,7 @@ use std::cmp::min;
|
|||
use std::fmt;
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::io::{Cursor, Read, Seek};
|
||||
use std::mem::{align_of, size_of};
|
||||
use std::mem::size_of;
|
||||
use std::ops::Index;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Mutex;
|
||||
|
|
@ -225,29 +227,6 @@ pub struct Node {
|
|||
|
||||
static_assertions::const_assert_eq!(size_of::<Node>(), 32);
|
||||
|
||||
#[derive(Default, Debug, Clone, BinRead)]
|
||||
pub struct Leaf {
|
||||
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::< Leaf > ())]
|
||||
pub leaf_watter_data_id: i16,
|
||||
}
|
||||
|
||||
static_assertions::const_assert_eq!(size_of::<Leaf>(), 32);
|
||||
|
||||
#[test]
|
||||
fn test_leaf_bytes() {
|
||||
test_read_bytes::<Leaf>();
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, BinRead)]
|
||||
pub struct LeafBrush {
|
||||
pub brush: u16,
|
||||
|
|
|
|||
133
src/lib.rs
133
src/lib.rs
|
|
@ -17,141 +17,10 @@ pub use error::{BspError, StringError};
|
|||
use lzma_rs::decompress::{Options, UnpackedSize};
|
||||
use reader::LumpReader;
|
||||
use std::cmp::min;
|
||||
use std::{io::Read, ops::Deref};
|
||||
use std::io::Read;
|
||||
|
||||
pub type BspResult<T> = Result<T, BspError>;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Leaves {
|
||||
leaves: Vec<Leaf>,
|
||||
}
|
||||
|
||||
impl Leaves {
|
||||
pub fn new(mut leaves: Vec<Leaf>) -> Self {
|
||||
leaves.sort_unstable_by_key(|leaf| leaf.cluster);
|
||||
|
||||
Leaves { leaves }
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Leaf> {
|
||||
self.into_iter()
|
||||
}
|
||||
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Leaf> {
|
||||
self.into_iter()
|
||||
}
|
||||
|
||||
pub fn into_inner(self) -> Vec<Leaf> {
|
||||
self.leaves
|
||||
}
|
||||
|
||||
pub fn clusters(&self) -> impl Iterator<Item = impl Iterator<Item = &Leaf>> {
|
||||
LeafClusters {
|
||||
leaves: &self.leaves,
|
||||
index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LeafClusters<'a> {
|
||||
leaves: &'a [Leaf],
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for LeafClusters<'a> {
|
||||
type Item = <&'a [Leaf] as IntoIterator>::IntoIter;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let cluster = self.leaves.get(self.index)?.cluster;
|
||||
let remaining_leaves = self.leaves.get(self.index..)?;
|
||||
let cluster_size = remaining_leaves
|
||||
.iter()
|
||||
.take_while(|leaf| leaf.cluster == cluster)
|
||||
.count();
|
||||
self.index += cluster_size;
|
||||
Some(remaining_leaves[0..cluster_size].iter())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_leaf_clusters() {
|
||||
let leaves: Leaves = vec![
|
||||
Leaf {
|
||||
contents: 0,
|
||||
cluster: 0,
|
||||
..Default::default()
|
||||
},
|
||||
Leaf {
|
||||
contents: 1,
|
||||
cluster: 0,
|
||||
..Default::default()
|
||||
},
|
||||
Leaf {
|
||||
contents: 2,
|
||||
cluster: 1,
|
||||
..Default::default()
|
||||
},
|
||||
Leaf {
|
||||
contents: 3,
|
||||
cluster: 2,
|
||||
..Default::default()
|
||||
},
|
||||
Leaf {
|
||||
contents: 4,
|
||||
cluster: 2,
|
||||
..Default::default()
|
||||
},
|
||||
]
|
||||
.into();
|
||||
|
||||
let clustered: Vec<Vec<i32>> = leaves
|
||||
.clusters()
|
||||
.map(|cluster| cluster.map(|leaf| leaf.contents).collect())
|
||||
.collect();
|
||||
assert_eq!(vec![vec![0, 1], vec![2], vec![3, 4]], clustered);
|
||||
}
|
||||
|
||||
impl From<Vec<Leaf>> for Leaves {
|
||||
fn from(other: Vec<Leaf>) -> Self {
|
||||
Self::new(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Leaves {
|
||||
type Target = [Leaf];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.leaves
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for Leaves {
|
||||
type Item = Leaf;
|
||||
type IntoIter = <Vec<Leaf> as IntoIterator>::IntoIter;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.leaves.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a Leaves {
|
||||
type Item = &'a Leaf;
|
||||
type IntoIter = <&'a [Leaf] as IntoIterator>::IntoIter;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.leaves[..].iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a mut Leaves {
|
||||
type Item = &'a mut Leaf;
|
||||
type IntoIter = <&'a mut [Leaf] as IntoIterator>::IntoIter;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.leaves.iter_mut()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Store all the allocated objects inline to improve cache usage
|
||||
/// A parsed bsp file
|
||||
#[derive(Debug)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue