1
0
Fork 0
mirror of https://codeberg.org/icewind/vbsp.git synced 2026-06-03 10:44:07 +02:00

visiblity work

This commit is contained in:
Robin Appelman 2020-06-26 19:26:20 +02:00
commit f8b0624e40
3 changed files with 71 additions and 65 deletions

View file

@ -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
}
}

View file

@ -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
}

View file

@ -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,
})
}
}