mirror of
https://codeberg.org/icewind/vbsp.git
synced 2026-06-03 18:54:05 +02:00
some disaplacement cleanup
This commit is contained in:
parent
aeb8c1011d
commit
db9ca18975
4 changed files with 59 additions and 39 deletions
|
|
@ -78,6 +78,8 @@ pub enum ValidationError {
|
||||||
},
|
},
|
||||||
#[error("bsp contains no root node")]
|
#[error("bsp contains no root node")]
|
||||||
NoRootNode,
|
NoRootNode,
|
||||||
|
#[error("displacement face with {0} edges")]
|
||||||
|
NonSquareDisplacement(i16),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,18 @@ impl<'a> Handle<'a, DisplacementInfo> {
|
||||||
self.bsp.face(self.map_face as usize)
|
self.bsp.face(self.map_face as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn displaced_vertices(&self) -> Option<impl Iterator<Item = Vector> + 'a> {
|
/// Get the positions of the corners of the displaced face
|
||||||
let face = self.face()?;
|
fn corner_positions(&self) -> [Vector; 4] {
|
||||||
let steps = 2usize.pow(self.power as u32) + 1;
|
let face = self.face().unwrap();
|
||||||
|
let vertices: [_; 4] = face
|
||||||
let mut corner_positions: ArrayVec<_, 4> = face.vertices().map(|v| v.position).collect();
|
.vertices()
|
||||||
|
.collect::<ArrayVec<_, 4>>()
|
||||||
|
.as_ref()
|
||||||
|
.try_into()
|
||||||
|
.unwrap();
|
||||||
|
let mut corner_positions: [Vector; 4] = vertices.map(|v| v.position);
|
||||||
|
|
||||||
|
// find the corner closest to the start position of the displacement
|
||||||
let start_index = corner_positions
|
let start_index = corner_positions
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
|
|
@ -45,6 +51,12 @@ impl<'a> Handle<'a, DisplacementInfo> {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
corner_positions.rotate_left(start_index);
|
corner_positions.rotate_left(start_index);
|
||||||
|
corner_positions.try_into().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn subdivided_face(&self) -> impl Iterator<Item = Vector> + 'a {
|
||||||
|
let steps = 2usize.pow(self.power as u32) + 1;
|
||||||
|
let corner_positions = self.corner_positions();
|
||||||
|
|
||||||
let step_scale = 1.0 / (steps as f32 - 1.0);
|
let step_scale = 1.0 / (steps as f32 - 1.0);
|
||||||
let edge_intervals = [
|
let edge_intervals = [
|
||||||
|
|
@ -52,43 +64,42 @@ impl<'a> Handle<'a, DisplacementInfo> {
|
||||||
(corner_positions[2] - corner_positions[3]) * step_scale,
|
(corner_positions[2] - corner_positions[3]) * step_scale,
|
||||||
];
|
];
|
||||||
|
|
||||||
Some(
|
(0..steps)
|
||||||
self.displacement_vertices()
|
.flat_map(move |x| (0..steps).map(move |y| (x, y)))
|
||||||
.enumerate()
|
.map(move |(x, y)| {
|
||||||
.map(move |(i, displacement)| {
|
let edge_positions = [
|
||||||
let y = (i % steps) as f32;
|
corner_positions[0] + edge_intervals[0] * x as f32,
|
||||||
let x = (i / steps) as f32;
|
corner_positions[3] + edge_intervals[1] * x as f32,
|
||||||
let edge_positions = [
|
];
|
||||||
corner_positions[0] + edge_intervals[0] * x,
|
let segment_interval = (edge_positions[1] - edge_positions[0]) * step_scale;
|
||||||
corner_positions[3] + edge_intervals[1] * x,
|
edge_positions[0] + (segment_interval * y as f32)
|
||||||
];
|
})
|
||||||
let segment_interval = (edge_positions[1] - edge_positions[0]) * step_scale;
|
|
||||||
let base_pos = edge_positions[0] + (segment_interval * y);
|
|
||||||
base_pos + displacement.displacement()
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn triangulated_displaced_vertices(&self) -> Option<impl Iterator<Item = Vector> + 'a> {
|
pub fn displaced_vertices(&self) -> impl Iterator<Item = Vector> + 'a {
|
||||||
let vertices: Vec<_> = self.displaced_vertices()?.collect();
|
self.displacement_vertices()
|
||||||
|
.zip(self.subdivided_face())
|
||||||
|
.map(move |(displacement, base_pos)| base_pos + displacement.displacement())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn triangulated_displaced_vertices(&self) -> impl Iterator<Item = Vector> + 'a {
|
||||||
|
let vertices: Vec<_> = self.displaced_vertices().collect();
|
||||||
let steps = 2usize.pow(self.power as u32);
|
let steps = 2usize.pow(self.power as u32);
|
||||||
|
|
||||||
let index = move |x: usize, y: usize| y * (steps + 1) + x;
|
let index = move |x: usize, y: usize| y * (steps + 1) + x;
|
||||||
|
|
||||||
Some(
|
(0..steps)
|
||||||
(0..steps)
|
.flat_map(move |x| (0..steps).map(move |y| (x, y)))
|
||||||
.flat_map(move |x| (0..steps).map(move |y| (x, y)))
|
.flat_map(move |(x, y)| {
|
||||||
.flat_map(move |(x, y)| {
|
[
|
||||||
[
|
vertices[index(x, y)],
|
||||||
vertices[index(x, y)],
|
vertices[index(x + 1, y)],
|
||||||
vertices[index(x + 1, y)],
|
vertices[index(x, y + 1)],
|
||||||
vertices[index(x, y + 1)],
|
vertices[index(x, y + 1)],
|
||||||
vertices[index(x, y + 1)],
|
vertices[index(x + 1, y + 1)],
|
||||||
vertices[index(x + 1, y + 1)],
|
vertices[index(x + 1, y)],
|
||||||
vertices[index(x + 1, y)],
|
]
|
||||||
]
|
})
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ impl<'a> Handle<'a, Face> {
|
||||||
pub fn vertices(&self) -> impl Iterator<Item = &'a Vertex> + 'a {
|
pub fn vertices(&self) -> impl Iterator<Item = &'a Vertex> + 'a {
|
||||||
let bsp = self.bsp;
|
let bsp = self.bsp;
|
||||||
self.vertex_indexes()
|
self.vertex_indexes()
|
||||||
.flat_map(move |vert_index| bsp.vertices.get(vert_index as usize))
|
.map(move |vert_index| bsp.vertices.get(vert_index as usize).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the vertex indexes of all vertices making up the face
|
/// Get the vertex indexes of all vertices making up the face
|
||||||
|
|
@ -27,11 +27,12 @@ impl<'a> Handle<'a, Face> {
|
||||||
pub fn vertex_indexes(&self) -> impl Iterator<Item = u16> + 'a {
|
pub fn vertex_indexes(&self) -> impl Iterator<Item = u16> + 'a {
|
||||||
let bsp = self.bsp;
|
let bsp = self.bsp;
|
||||||
(self.data.first_edge..(self.data.first_edge + self.data.num_edges as i32))
|
(self.data.first_edge..(self.data.first_edge + self.data.num_edges as i32))
|
||||||
.flat_map(move |surface_edge| bsp.surface_edges.get(surface_edge as usize))
|
.map(move |surface_edge| bsp.surface_edges.get(surface_edge as usize).unwrap())
|
||||||
.flat_map(move |surface_edge| {
|
.map(move |surface_edge| {
|
||||||
bsp.edges
|
bsp.edges
|
||||||
.get(surface_edge.edge_index() as usize)
|
.get(surface_edge.edge_index() as usize)
|
||||||
.map(|edge| (edge, surface_edge.direction()))
|
.map(|edge| (edge, surface_edge.direction()))
|
||||||
|
.unwrap()
|
||||||
})
|
})
|
||||||
.map(|(edge, direction)| match direction {
|
.map(|(edge, direction)| match direction {
|
||||||
EdgeDirection::FirstToLast => edge.start_index,
|
EdgeDirection::FirstToLast => edge.start_index,
|
||||||
|
|
|
||||||
|
|
@ -434,6 +434,12 @@ impl Bsp {
|
||||||
return Err(ValidationError::NoRootNode.into());
|
return Err(ValidationError::NoRootNode.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for face in &self.faces {
|
||||||
|
if face.displacement_index().is_some() && face.num_edges != 4 {
|
||||||
|
return Err(ValidationError::NonSquareDisplacement(face.num_edges).into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue