mirror of
https://codeberg.org/icewind/vbsp.git
synced 2026-06-03 10:44:07 +02:00
visiblity work
This commit is contained in:
parent
130c2efc09
commit
f8b0624e40
3 changed files with 71 additions and 65 deletions
80
src/data.rs
80
src/data.rs
|
|
@ -61,7 +61,7 @@ pub struct LumpEntry {
|
|||
|
||||
#[derive(Debug, Clone, BinRead)]
|
||||
pub struct LeafFace {
|
||||
pub face: u32,
|
||||
pub face: u16,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
@ -276,7 +276,8 @@ static_assertions::const_assert_eq!(size_of::<Node>(), 32);
|
|||
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 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,
|
||||
|
|
@ -290,19 +291,21 @@ static_assertions::const_assert_eq!(size_of::<Leaf>(), 32);
|
|||
|
||||
#[derive(Debug, Clone, BinRead)]
|
||||
pub struct LeafBrush {
|
||||
pub brush: u32,
|
||||
pub brush: u16,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, BinRead)]
|
||||
pub struct Model {
|
||||
pub mins: [f32; 3],
|
||||
pub maxs: [f32; 3],
|
||||
pub face: u32,
|
||||
pub num_faces: u32,
|
||||
pub brush: u32,
|
||||
pub num_brushes: u32,
|
||||
pub mins: Vector,
|
||||
pub maxs: Vector,
|
||||
pub origin: Vector,
|
||||
pub head_node: i32,
|
||||
pub first_face: i32,
|
||||
pub face_count: i32,
|
||||
}
|
||||
|
||||
static_assertions::const_assert_eq!(size_of::<Model>(), 48);
|
||||
|
||||
#[derive(Debug, Clone, BinRead)]
|
||||
pub struct Brush {
|
||||
pub brush_side: u32,
|
||||
|
|
@ -312,8 +315,10 @@ pub struct Brush {
|
|||
|
||||
#[derive(Debug, Clone, BinRead)]
|
||||
pub struct BrushSide {
|
||||
pub plane: u32,
|
||||
pub texture: u32,
|
||||
pub plane: u16,
|
||||
pub texture_info: i16,
|
||||
pub displacement_info: i16,
|
||||
pub bevel: i16,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, BinRead)]
|
||||
|
|
@ -351,18 +356,6 @@ impl SurfaceEdge {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, BinRead)]
|
||||
pub struct MeshVert {
|
||||
pub offset: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, BinRead)]
|
||||
pub struct Effect {
|
||||
pub name: Name,
|
||||
pub brush: u32,
|
||||
pub unknown: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, BinRead)]
|
||||
pub struct Face {
|
||||
pub plane_num: u16,
|
||||
|
|
@ -404,9 +397,40 @@ pub struct Lightvol {
|
|||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct VisData {
|
||||
pub n_vecs: u32,
|
||||
// Number of vectors.
|
||||
pub sz_vecs: u32,
|
||||
// Size of each vector, in bytes.
|
||||
pub vecs: BitVec<u8>, // Visibility data. One bit per cluster per vector.
|
||||
pub cluster_count: u32,
|
||||
pub pvs_offsets: Vec<i32>,
|
||||
pub pas_offsets: Vec<i32>,
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl VisData {
|
||||
pub fn visible_clusters(&self, cluster: i16) -> BitVec<u8> {
|
||||
let offset = self.pvs_offsets[cluster as usize] as usize;
|
||||
let pvs_buffer = &self.data[offset..];
|
||||
let mut visible_clusters = BitVec::with_capacity(self.cluster_count as u64);
|
||||
visible_clusters.resize(self.cluster_count as u64, false);
|
||||
|
||||
let mut cluster_index = 0;
|
||||
let mut buffer_index = 0;
|
||||
|
||||
while cluster_index < self.cluster_count {
|
||||
if pvs_buffer[buffer_index] == 0 {
|
||||
let skip = pvs_buffer[buffer_index + 1];
|
||||
cluster_index += skip as u32;
|
||||
buffer_index += 2;
|
||||
} else {
|
||||
let packed = pvs_buffer[buffer_index];
|
||||
for i in 0..8 {
|
||||
let bit = 1 << i;
|
||||
if (packed & bit) == bit {
|
||||
visible_clusters.set(cluster_index as u64, true);
|
||||
}
|
||||
cluster_index += 1;
|
||||
}
|
||||
buffer_index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
visible_clusters
|
||||
}
|
||||
}
|
||||
|
|
|
|||
16
src/lib.rs
16
src/lib.rs
|
|
@ -12,12 +12,7 @@ use binread::BinRead;
|
|||
use bspfile::BspFile;
|
||||
use itertools::{GroupBy, Itertools};
|
||||
use reader::LumpReader;
|
||||
use std::{
|
||||
convert::TryInto,
|
||||
io::{self, Read},
|
||||
iter::once,
|
||||
ops::Deref,
|
||||
};
|
||||
use std::{io::Read, iter::once, ops::Deref};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
|
|
@ -316,8 +311,8 @@ impl<'a, T> Handle<'a, T> {
|
|||
|
||||
impl<'a> Handle<'a, Model> {
|
||||
pub fn faces(&self) -> impl Iterator<Item = Handle<'a, Face>> {
|
||||
let start = self.face as usize;
|
||||
let end = start + self.num_faces as usize;
|
||||
let start = self.first_face as usize;
|
||||
let end = start + self.face_count as usize;
|
||||
let bsp = self.bsp;
|
||||
|
||||
bsp.faces[start..end]
|
||||
|
|
@ -377,6 +372,7 @@ impl<'a> Handle<'a, Leaf> {
|
|||
if cluster < 0 {
|
||||
None
|
||||
} else {
|
||||
let visible_clusters = bsp.vis_data.visible_clusters(cluster);
|
||||
Some(
|
||||
bsp.leaves
|
||||
.iter()
|
||||
|
|
@ -384,9 +380,7 @@ impl<'a> Handle<'a, Leaf> {
|
|||
if leaf.cluster == cluster {
|
||||
true
|
||||
} else if leaf.cluster > 0 {
|
||||
let cluster_vis_start =
|
||||
leaf.cluster as u64 * bsp.vis_data.sz_vecs as u64 * 8;
|
||||
bsp.vis_data.vecs[cluster_vis_start + cluster as u64]
|
||||
visible_clusters[leaf.cluster as u64]
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use crate::*;
|
||||
use binread::BinReaderExt;
|
||||
use bv::BitVec;
|
||||
use std::borrow::Cow;
|
||||
use std::mem::size_of;
|
||||
|
||||
|
|
@ -50,34 +49,23 @@ impl<R: BinReaderExt + Read> LumpReader<R> {
|
|||
return Ok(VisData::default());
|
||||
}
|
||||
|
||||
let n_vecs = self.inner.read_le()?;
|
||||
let sz_vecs = self.inner.read_le()?;
|
||||
let vecs_size = n_vecs as u64 * sz_vecs as u64;
|
||||
let mut vecs = Vec::with_capacity(
|
||||
vecs_size
|
||||
.try_into()
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?,
|
||||
);
|
||||
self.inner
|
||||
.by_ref()
|
||||
.take(vecs_size as u64)
|
||||
.read_to_end(&mut vecs)?;
|
||||
let cluster_count = self.inner.read_le()?;
|
||||
let mut pvs_offsets = Vec::with_capacity(cluster_count as usize);
|
||||
let mut pas_offsets = Vec::with_capacity(cluster_count as usize);
|
||||
|
||||
if (vecs.len() as u64) < vecs_size {
|
||||
return Err(BspError::UnexpectedEOF);
|
||||
for _ in 0..cluster_count {
|
||||
pvs_offsets.push(self.inner.read_le()?);
|
||||
pas_offsets.push(self.inner.read_le()?);
|
||||
}
|
||||
|
||||
if (vecs.len() as u64) > vecs_size {
|
||||
return Err(BspError::UnexpectedExtraData);
|
||||
}
|
||||
let mut data = Vec::new();
|
||||
self.inner.read_to_end(&mut data)?;
|
||||
|
||||
let vecs = BitVec::from_bits(vecs);
|
||||
|
||||
let vis_data = VisData {
|
||||
n_vecs,
|
||||
sz_vecs,
|
||||
vecs,
|
||||
};
|
||||
Ok(vis_data)
|
||||
Ok(VisData {
|
||||
cluster_count,
|
||||
pvs_offsets,
|
||||
pas_offsets,
|
||||
data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue