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)] #[derive(Debug, Clone, BinRead)]
pub struct LeafFace { pub struct LeafFace {
pub face: u32, pub face: u16,
} }
#[derive(Clone)] #[derive(Clone)]
@ -276,7 +276,8 @@ static_assertions::const_assert_eq!(size_of::<Node>(), 32);
pub struct Leaf { pub struct Leaf {
pub contents: i32, pub contents: i32,
pub cluster: i16, 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 mins: [i16; 3],
pub maxs: [i16; 3], pub maxs: [i16; 3],
pub first_leaf_face: u16, pub first_leaf_face: u16,
@ -290,19 +291,21 @@ static_assertions::const_assert_eq!(size_of::<Leaf>(), 32);
#[derive(Debug, Clone, BinRead)] #[derive(Debug, Clone, BinRead)]
pub struct LeafBrush { pub struct LeafBrush {
pub brush: u32, pub brush: u16,
} }
#[derive(Debug, Clone, BinRead)] #[derive(Debug, Clone, BinRead)]
pub struct Model { pub struct Model {
pub mins: [f32; 3], pub mins: Vector,
pub maxs: [f32; 3], pub maxs: Vector,
pub face: u32, pub origin: Vector,
pub num_faces: u32, pub head_node: i32,
pub brush: u32, pub first_face: i32,
pub num_brushes: u32, pub face_count: i32,
} }
static_assertions::const_assert_eq!(size_of::<Model>(), 48);
#[derive(Debug, Clone, BinRead)] #[derive(Debug, Clone, BinRead)]
pub struct Brush { pub struct Brush {
pub brush_side: u32, pub brush_side: u32,
@ -312,8 +315,10 @@ pub struct Brush {
#[derive(Debug, Clone, BinRead)] #[derive(Debug, Clone, BinRead)]
pub struct BrushSide { pub struct BrushSide {
pub plane: u32, pub plane: u16,
pub texture: u32, pub texture_info: i16,
pub displacement_info: i16,
pub bevel: i16,
} }
#[derive(Debug, Clone, BinRead)] #[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)] #[derive(Debug, Clone, BinRead)]
pub struct Face { pub struct Face {
pub plane_num: u16, pub plane_num: u16,
@ -404,9 +397,40 @@ pub struct Lightvol {
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
pub struct VisData { pub struct VisData {
pub n_vecs: u32, pub cluster_count: u32,
// Number of vectors. pub pvs_offsets: Vec<i32>,
pub sz_vecs: u32, pub pas_offsets: Vec<i32>,
// Size of each vector, in bytes. pub data: Vec<u8>,
pub vecs: BitVec<u8>, // Visibility data. One bit per cluster per vector. }
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 bspfile::BspFile;
use itertools::{GroupBy, Itertools}; use itertools::{GroupBy, Itertools};
use reader::LumpReader; use reader::LumpReader;
use std::{ use std::{io::Read, iter::once, ops::Deref};
convert::TryInto,
io::{self, Read},
iter::once,
ops::Deref,
};
use thiserror::Error; use thiserror::Error;
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -316,8 +311,8 @@ impl<'a, T> Handle<'a, T> {
impl<'a> Handle<'a, Model> { impl<'a> Handle<'a, Model> {
pub fn faces(&self) -> impl Iterator<Item = Handle<'a, Face>> { pub fn faces(&self) -> impl Iterator<Item = Handle<'a, Face>> {
let start = self.face as usize; let start = self.first_face as usize;
let end = start + self.num_faces as usize; let end = start + self.face_count as usize;
let bsp = self.bsp; let bsp = self.bsp;
bsp.faces[start..end] bsp.faces[start..end]
@ -377,6 +372,7 @@ impl<'a> Handle<'a, Leaf> {
if cluster < 0 { if cluster < 0 {
None None
} else { } else {
let visible_clusters = bsp.vis_data.visible_clusters(cluster);
Some( Some(
bsp.leaves bsp.leaves
.iter() .iter()
@ -384,9 +380,7 @@ impl<'a> Handle<'a, Leaf> {
if leaf.cluster == cluster { if leaf.cluster == cluster {
true true
} else if leaf.cluster > 0 { } else if leaf.cluster > 0 {
let cluster_vis_start = visible_clusters[leaf.cluster as u64]
leaf.cluster as u64 * bsp.vis_data.sz_vecs as u64 * 8;
bsp.vis_data.vecs[cluster_vis_start + cluster as u64]
} else { } else {
false false
} }

View file

@ -1,6 +1,5 @@
use crate::*; use crate::*;
use binread::BinReaderExt; use binread::BinReaderExt;
use bv::BitVec;
use std::borrow::Cow; use std::borrow::Cow;
use std::mem::size_of; use std::mem::size_of;
@ -50,34 +49,23 @@ impl<R: BinReaderExt + Read> LumpReader<R> {
return Ok(VisData::default()); return Ok(VisData::default());
} }
let n_vecs = self.inner.read_le()?; let cluster_count = self.inner.read_le()?;
let sz_vecs = self.inner.read_le()?; let mut pvs_offsets = Vec::with_capacity(cluster_count as usize);
let vecs_size = n_vecs as u64 * sz_vecs as u64; let mut pas_offsets = Vec::with_capacity(cluster_count as usize);
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)?;
if (vecs.len() as u64) < vecs_size { for _ in 0..cluster_count {
return Err(BspError::UnexpectedEOF); pvs_offsets.push(self.inner.read_le()?);
pas_offsets.push(self.inner.read_le()?);
} }
if (vecs.len() as u64) > vecs_size { let mut data = Vec::new();
return Err(BspError::UnexpectedExtraData); self.inner.read_to_end(&mut data)?;
}
let vecs = BitVec::from_bits(vecs); Ok(VisData {
cluster_count,
let vis_data = VisData { pvs_offsets,
n_vecs, pas_offsets,
sz_vecs, data,
vecs, })
};
Ok(vis_data)
} }
} }