mirror of
https://codeberg.org/icewind/vbsp.git
synced 2026-06-03 10:44:07 +02:00
texture info handling
This commit is contained in:
parent
c459a8308b
commit
e132a34a00
6 changed files with 69 additions and 7 deletions
|
|
@ -1,3 +1,4 @@
|
|||
#[allow(unused_imports)]
|
||||
use std::ops::Deref;
|
||||
|
||||
fn main() -> Result<(), vbsp::BspError> {
|
||||
|
|
@ -12,9 +13,13 @@ fn main() -> Result<(), vbsp::BspError> {
|
|||
// }
|
||||
// }
|
||||
|
||||
for prop in bsp.static_props() {
|
||||
dbg!(prop.deref());
|
||||
dbg!(prop.model());
|
||||
// for prop in bsp.static_props() {
|
||||
// dbg!(prop.deref());
|
||||
// dbg!(prop.model());
|
||||
// }
|
||||
|
||||
for tex in bsp.textures() {
|
||||
println!("{}", tex.name());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -43,10 +43,10 @@ impl<'a> BspFile<'a> {
|
|||
|
||||
pub fn lump_reader(&self, lump: LumpType) -> BspResult<LumpReader<Cursor<Cow<[u8]>>>> {
|
||||
let data = self.get_lump(lump)?;
|
||||
Ok(LumpReader::new(data))
|
||||
Ok(LumpReader::new(data, lump))
|
||||
}
|
||||
|
||||
fn get_lump(&self, lump: LumpType) -> BspResult<Cow<[u8]>> {
|
||||
pub fn get_lump(&self, lump: LumpType) -> BspResult<Cow<[u8]>> {
|
||||
let lump = &self.directories[lump];
|
||||
let raw_data = self
|
||||
.data
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use crate::data::*;
|
|||
use std::num::{ParseFloatError, ParseIntError};
|
||||
use thiserror::Error;
|
||||
use zip::result::ZipError;
|
||||
use crate::bspfile::LumpType;
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Error)]
|
||||
|
|
@ -16,6 +17,7 @@ pub enum BspError {
|
|||
MalformedCompressedGameLump,
|
||||
#[error("Invalid lump size, lump size {lump_size} is not a multiple of the element size {element_size}")]
|
||||
InvalidLumpSize {
|
||||
lump: LumpType,
|
||||
element_size: usize,
|
||||
lump_size: usize,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -119,3 +119,24 @@ impl<'a> Handle<'a, Leaf> {
|
|||
.filter_map(move |leaf_face| bsp.face(leaf_face.face as usize))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Handle<'a, TextureInfo> {
|
||||
pub fn texture_data(&self) -> Handle<'a, TextureData> {
|
||||
Handle::new(self.bsp, &self.bsp.textures_data[self.data.texture_data_index as usize])
|
||||
}
|
||||
pub fn name(&self) -> &'a str {
|
||||
self.texture_data().name()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Handle<'a, TextureData> {
|
||||
pub fn name(&self) -> &'a str {
|
||||
let start = self.bsp.texture_string_tables[self.name_string_table_id as usize] as usize;
|
||||
let part = &self.bsp.texture_string_data[start..];
|
||||
if let Some((s, _)) = part.split_once("\0") {
|
||||
s
|
||||
} else {
|
||||
part
|
||||
}
|
||||
}
|
||||
}
|
||||
31
src/lib.rs
31
src/lib.rs
|
|
@ -159,6 +159,8 @@ pub struct Bsp {
|
|||
pub entities: Entities,
|
||||
pub textures_data: Vec<TextureData>,
|
||||
pub textures_info: Vec<TextureInfo>,
|
||||
pub texture_string_tables: Vec<i32>,
|
||||
pub texture_string_data: String,
|
||||
pub planes: Vec<Plane>,
|
||||
pub nodes: Vec<Node>,
|
||||
pub leaves: Leaves,
|
||||
|
|
@ -191,6 +193,12 @@ impl Bsp {
|
|||
let textures_info = bsp_file
|
||||
.lump_reader(LumpType::TextureInfo)?
|
||||
.read_vec(|r| r.read())?;
|
||||
let texture_string_tables = bsp_file
|
||||
.lump_reader(LumpType::TextureDataStringTable)?
|
||||
.read_vec(|r| r.read())?;
|
||||
let texture_string_data = String::from_utf8(bsp_file
|
||||
.get_lump(LumpType::TextureDataStringData)?
|
||||
.into_owned()).map_err(|e| BspError::String(StringError::NonUTF8(e.utf8_error())))?;
|
||||
let planes = bsp_file
|
||||
.lump_reader(LumpType::Planes)?
|
||||
.read_vec(|r| r.read())?;
|
||||
|
|
@ -253,6 +261,8 @@ impl Bsp {
|
|||
entities,
|
||||
textures_data,
|
||||
textures_info,
|
||||
texture_string_tables,
|
||||
texture_string_data,
|
||||
planes,
|
||||
nodes,
|
||||
leaves,
|
||||
|
|
@ -315,6 +325,11 @@ impl Bsp {
|
|||
self.models.iter().map(move |m| Handle::new(self, m))
|
||||
}
|
||||
|
||||
/// Get all models stored in the bsp
|
||||
pub fn textures(&self) -> impl Iterator<Item = Handle<'_, TextureInfo>> {
|
||||
self.textures_info.iter().map(move |m| Handle::new(self, m))
|
||||
}
|
||||
|
||||
/// Find a leaf for a specific position
|
||||
pub fn leaf_at(&self, point: Vector) -> Handle<'_, Leaf> {
|
||||
let mut current = self.root_node();
|
||||
|
|
@ -424,6 +439,22 @@ impl Bsp {
|
|||
"texture_info",
|
||||
"texture_data",
|
||||
)?;
|
||||
self.validate_indexes(
|
||||
self.textures_data
|
||||
.iter()
|
||||
.map(|texture| texture.name_string_table_id),
|
||||
&self.texture_string_tables,
|
||||
"textures_data",
|
||||
"texture_string_tables",
|
||||
)?;
|
||||
self.validate_indexes(
|
||||
self.texture_string_tables
|
||||
.iter()
|
||||
.map(|texture| *texture),
|
||||
&self.texture_string_data.as_bytes(),
|
||||
"texture_string_tables",
|
||||
"texture_string_data",
|
||||
)?;
|
||||
self.validate_indexes(
|
||||
self.nodes.iter().map(|node| node.plane_index),
|
||||
&self.planes,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use crate::*;
|
||||
use binrw::BinReaderExt;
|
||||
// use std::any::type_name;
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Debug;
|
||||
use std::mem::size_of;
|
||||
|
|
@ -8,15 +7,17 @@ use std::mem::size_of;
|
|||
pub struct LumpReader<R> {
|
||||
inner: R,
|
||||
length: usize,
|
||||
lump: LumpType,
|
||||
}
|
||||
|
||||
impl<'a> LumpReader<Cursor<Cow<'a, [u8]>>> {
|
||||
pub fn new(data: Cow<'a, [u8]>) -> Self {
|
||||
pub fn new(data: Cow<'a, [u8]>, lump: LumpType) -> Self {
|
||||
let length = data.len();
|
||||
let reader = Cursor::new(data);
|
||||
LumpReader {
|
||||
inner: reader,
|
||||
length,
|
||||
lump,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -32,12 +33,14 @@ impl<R: BinReaderExt + Read> LumpReader<R> {
|
|||
Ok(Entities { entities })
|
||||
}
|
||||
|
||||
/// Read a list of items with a fixed size
|
||||
pub fn read_vec<F, T>(&mut self, mut f: F) -> BspResult<Vec<T>>
|
||||
where
|
||||
F: FnMut(&mut LumpReader<R>) -> BspResult<T>,
|
||||
{
|
||||
if self.length % size_of::<T>() != 0 {
|
||||
return Err(BspError::InvalidLumpSize {
|
||||
lump: self.lump,
|
||||
element_size: size_of::<T>(),
|
||||
lump_size: self.length,
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue