mirror of
https://codeberg.org/icewind/vbsp.git
synced 2026-06-03 18:54:05 +02:00
more validation
This commit is contained in:
parent
26a606db55
commit
aeb8c1011d
4 changed files with 72 additions and 27 deletions
|
|
@ -76,6 +76,8 @@ pub enum ValidationError {
|
||||||
index: i64,
|
index: i64,
|
||||||
size: usize,
|
size: usize,
|
||||||
},
|
},
|
||||||
|
#[error("bsp contains no root node")]
|
||||||
|
NoRootNode,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use crate::data::*;
|
||||||
|
|
||||||
impl<'a> Handle<'a, Face> {
|
impl<'a> Handle<'a, Face> {
|
||||||
/// Get the texture of the face
|
/// Get the texture of the face
|
||||||
pub fn texture(&self) -> Option<Handle<TextureInfo>> {
|
pub fn texture(&self) -> Handle<TextureInfo> {
|
||||||
self.bsp
|
self.bsp
|
||||||
.textures_info
|
.textures_info
|
||||||
.get(self.texture_info as usize)
|
.get(self.texture_info as usize)
|
||||||
|
|
@ -11,6 +11,7 @@ impl<'a> Handle<'a, Face> {
|
||||||
bsp: self.bsp,
|
bsp: self.bsp,
|
||||||
data: texture_info,
|
data: texture_info,
|
||||||
})
|
})
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get all vertices making up the face
|
/// Get all vertices making up the face
|
||||||
|
|
@ -44,21 +45,18 @@ impl<'a> Handle<'a, Face> {
|
||||||
|
|
||||||
/// Check if the face is flagged as visible
|
/// Check if the face is flagged as visible
|
||||||
pub fn is_visible(&self) -> bool {
|
pub fn is_visible(&self) -> bool {
|
||||||
self.texture()
|
let texture = self.texture();
|
||||||
.map(|texture| {
|
!texture.flags.intersects(
|
||||||
!texture.flags.intersects(
|
TextureFlags::LIGHT
|
||||||
TextureFlags::LIGHT
|
| TextureFlags::SKY2D
|
||||||
| TextureFlags::SKY2D
|
| TextureFlags::SKY
|
||||||
| TextureFlags::SKY
|
| TextureFlags::WARP
|
||||||
| TextureFlags::WARP
|
| TextureFlags::TRIGGER
|
||||||
| TextureFlags::TRIGGER
|
| TextureFlags::HINT
|
||||||
| TextureFlags::HINT
|
| TextureFlags::SKIP
|
||||||
| TextureFlags::SKIP
|
| TextureFlags::NODRAW
|
||||||
| TextureFlags::NODRAW
|
| TextureFlags::HITBOX,
|
||||||
| TextureFlags::HITBOX,
|
)
|
||||||
)
|
|
||||||
})
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Triangulate the face
|
/// Triangulate the face
|
||||||
|
|
|
||||||
|
|
@ -56,17 +56,20 @@ impl<'a> Handle<'a, Model> {
|
||||||
|
|
||||||
impl<'a> Handle<'a, TextureInfo> {
|
impl<'a> Handle<'a, TextureInfo> {
|
||||||
/// Get the texture data references by the texture
|
/// Get the texture data references by the texture
|
||||||
pub fn texture(&self) -> Option<&TextureData> {
|
pub fn texture(&self) -> Handle<'a, TextureData> {
|
||||||
self.bsp
|
let texture = self
|
||||||
|
.bsp
|
||||||
.textures_data
|
.textures_data
|
||||||
.get(self.data.texture_data_index as usize)
|
.get(self.data.texture_data_index as usize)
|
||||||
|
.unwrap();
|
||||||
|
Handle::new(self.bsp, texture)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Handle<'_, Node> {
|
impl Handle<'_, Node> {
|
||||||
/// Get the plane splitting this node
|
/// Get the plane splitting this node
|
||||||
pub fn plane(&self) -> Option<Handle<'_, Plane>> {
|
pub fn plane(&self) -> Handle<'_, Plane> {
|
||||||
self.bsp.plane(self.plane_index as _)
|
self.bsp.plane(self.plane_index as _).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
56
src/lib.rs
56
src/lib.rs
|
|
@ -295,8 +295,8 @@ impl Bsp {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the root node of the bsp
|
/// Get the root node of the bsp
|
||||||
pub fn root_node(&self) -> Option<Handle<'_, Node>> {
|
pub fn root_node(&self) -> Handle<'_, Node> {
|
||||||
self.node(0)
|
self.node(0).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get all models stored in the bsp
|
/// Get all models stored in the bsp
|
||||||
|
|
@ -305,11 +305,11 @@ impl Bsp {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find a leaf for a specific position
|
/// Find a leaf for a specific position
|
||||||
pub fn leaf_at(&self, point: Vector) -> Option<Handle<'_, Leaf>> {
|
pub fn leaf_at(&self, point: Vector) -> Handle<'_, Leaf> {
|
||||||
let mut current = self.root_node()?;
|
let mut current = self.root_node();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let plane = current.plane()?;
|
let plane = current.plane();
|
||||||
let dot: f32 = point
|
let dot: f32 = point
|
||||||
.iter()
|
.iter()
|
||||||
.zip(plane.normal.iter())
|
.zip(plane.normal.iter())
|
||||||
|
|
@ -321,9 +321,9 @@ impl Bsp {
|
||||||
let next = if dot < plane.dist { back } else { front };
|
let next = if dot < plane.dist { back } else { front };
|
||||||
|
|
||||||
if next < 0 {
|
if next < 0 {
|
||||||
return self.leaf((!next) as usize);
|
return self.leaf((!next) as usize).unwrap();
|
||||||
} else {
|
} else {
|
||||||
current = self.node(next as usize)?;
|
current = self.node(next as usize).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -391,6 +391,48 @@ impl Bsp {
|
||||||
"displacement",
|
"displacement",
|
||||||
"displacement",
|
"displacement",
|
||||||
)?;
|
)?;
|
||||||
|
self.validate_indexes(
|
||||||
|
self.faces.iter().map(|face| face.texture_info),
|
||||||
|
&self.textures_info,
|
||||||
|
"face",
|
||||||
|
"texture_info",
|
||||||
|
)?;
|
||||||
|
self.validate_indexes(
|
||||||
|
self.textures_info
|
||||||
|
.iter()
|
||||||
|
.map(|texture| texture.texture_data_index),
|
||||||
|
&self.textures_data,
|
||||||
|
"texture_info",
|
||||||
|
"texture_data",
|
||||||
|
)?;
|
||||||
|
self.validate_indexes(
|
||||||
|
self.nodes.iter().map(|node| node.plane_index),
|
||||||
|
&self.planes,
|
||||||
|
"node",
|
||||||
|
"plane",
|
||||||
|
)?;
|
||||||
|
self.validate_indexes(
|
||||||
|
self.nodes
|
||||||
|
.iter()
|
||||||
|
.flat_map(|node| node.children)
|
||||||
|
.filter_map(|index| (index >= 0).then(|| index)),
|
||||||
|
&self.nodes,
|
||||||
|
"node",
|
||||||
|
"node",
|
||||||
|
)?;
|
||||||
|
self.validate_indexes(
|
||||||
|
self.nodes
|
||||||
|
.iter()
|
||||||
|
.flat_map(|node| node.children)
|
||||||
|
.filter_map(|index| (index < 0).then(|| !index)),
|
||||||
|
&self.leaves,
|
||||||
|
"node",
|
||||||
|
"leaf",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
if self.nodes.is_empty() {
|
||||||
|
return Err(ValidationError::NoRootNode.into());
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue