Skip to content

Commit

Permalink
layers
Browse files Browse the repository at this point in the history
  • Loading branch information
mockersf committed Jul 16, 2024
1 parent 1e59e15 commit 39c9a77
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 31 deletions.
4 changes: 2 additions & 2 deletions benches/baking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ fn baking(c: &mut Criterion) {
.unwrap();
c.bench_function(&"baking".to_string(), |b| {
b.iter(|| {
mesh.layers[0].unbake();
mesh.layers[0].bake();
mesh.unbake();
mesh.bake();
})
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/input/triangulation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ impl Triangulation {
/// mesh.merge_polygons();
///
/// // One call to merge should have reduced the number of polygons, baking will be less expensive.
/// mesh.layers[0].bake();
/// mesh.bake();
/// ```
#[cfg_attr(feature = "tracing", instrument(skip_all))]
pub fn as_navmesh(&self) -> Mesh {
Expand Down
58 changes: 36 additions & 22 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ impl Layer {
self.baked_polygons = Some(BVH2d::build(&bounded_polygons));
}

/// Create a `Mesh` from a list of [`Vertex`] and [`Polygon`].
/// Create a `Layer` from a list of [`Vertex`] and [`Polygon`].
pub fn new(vertices: Vec<Vertex>, polygons: Vec<Polygon>) -> Result<Self, MeshError> {
if vertices.is_empty() || polygons.is_empty() {
return Err(MeshError::EmptyMesh);
Expand All @@ -266,6 +266,23 @@ impl Layer {
}

impl Mesh {
/// Pre-compute optimizations on the mesh
///
/// Call [Layer::bake] on each layer.
pub fn bake(&mut self) {
for layer in self.layers.iter_mut() {
layer.bake();
}
}

/// Remove pre-computed optimizations from the mesh. Call this if you modified the [`Mesh`].
#[inline]
pub fn unbake(&mut self) {
for layer in self.layers.iter_mut() {
layer.unbake();
}
}

/// Compute a path between two points.
///
/// This method returns a `Future`, to get the path in a blocking way use [`Self::path`].
Expand Down Expand Up @@ -455,20 +472,24 @@ impl Mesh {
Vec2::new(delta, -delta),
]
.iter()
.map(|delta| {
if self.layers[0].baked_polygons.is_none() {
self.get_point_location_unit(point + *delta)
} else {
self.get_point_location_unit_baked(point + *delta)
}
.flat_map(|delta| {
self.layers.iter().map(move |layer| {
if layer.baked_polygons.is_none() {
layer.get_point_location_unit(point + *delta)
} else {
layer.get_point_location_unit_baked(point + *delta)
}
})
})
.find(|poly| *poly != u32::MAX)
.unwrap_or(u32::MAX)
}
}

impl Layer {
#[cfg_attr(feature = "tracing", instrument(skip_all))]
fn get_point_location_unit(&self, point: Vec2) -> u32 {
for (i, polygon) in self.layers[0].polygons.iter().enumerate() {
for (i, polygon) in self.polygons.iter().enumerate() {
if self.point_in_polygon(point, polygon) {
return i as u32;
}
Expand All @@ -478,12 +499,11 @@ impl Mesh {

#[cfg_attr(feature = "tracing", instrument(skip_all))]
fn get_point_location_unit_baked(&self, point: Vec2) -> u32 {
self.layers[0]
.baked_polygons
self.baked_polygons
.as_ref()
.unwrap()
.contains_iterator(&point)
.find(|index| self.point_in_polygon(point, &self.layers[0].polygons[*index]))
.find(|index| self.point_in_polygon(point, &self.polygons[*index]))
.map(|index| index as u32)
.unwrap_or(u32::MAX)
}
Expand All @@ -493,22 +513,16 @@ impl Mesh {
fn point_in_polygon(&self, point: Vec2, polygon: &Polygon) -> bool {
let mut edged = false;
for edge in polygon.edges_index().iter() {
if edge.0.max(edge.1) as usize >= self.layers[0].vertices.len() {
if edge.0.max(edge.1) as usize >= self.vertices.len() {
return false;
}
edged = true;
// Bounds are checked just before
#[allow(unsafe_code)]
let (last, next) = unsafe {
(
self.layers[0]
.vertices
.get_unchecked(edge.0 as usize)
.coords,
self.layers[0]
.vertices
.get_unchecked(edge.1 as usize)
.coords,
self.vertices.get_unchecked(edge.0 as usize).coords,
self.vertices.get_unchecked(edge.1 as usize).coords,
)
};

Expand Down Expand Up @@ -623,7 +637,7 @@ mod tests {
#[test]
fn point_in_polygon() {
let mut mesh = mesh_u_grid();
mesh.layers[0].bake();
mesh.bake();
assert_eq!(mesh.get_point_location(Vec2::new(0.5, 0.5)), 0);
assert_eq!(mesh.get_point_location(Vec2::new(1.5, 0.5)), 1);
assert_eq!(mesh.get_point_location(Vec2::new(0.5, 1.5)), 3);
Expand Down Expand Up @@ -852,7 +866,7 @@ mod tests {
#[test]
fn paper_point_in_polygon() {
let mut mesh = mesh_from_paper();
mesh.layers[0].bake();
mesh.bake();
assert_eq!(mesh.get_point_location(Vec2::new(0.5, 0.5)), u32::MAX);
assert_eq!(mesh.get_point_location(Vec2::new(2.0, 6.0)), 0);
assert_eq!(mesh.get_point_location(Vec2::new(2.0, 5.1)), 0);
Expand Down
12 changes: 6 additions & 6 deletions src/merger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ impl Mesh {
#[cfg_attr(feature = "tracing", instrument(skip_all))]
pub fn merge_polygons(&mut self) -> bool {
// TODO: do it for each layer, keep the stitch polygons unmerged
self.layers[0].unbake();
self.unbake();
let mut area = self.layers[0]
.polygons
.iter()
Expand Down Expand Up @@ -210,15 +210,15 @@ mod test {
fn merge_u() {
let mut mesh = mesh_u_grid();
while mesh.merge_polygons() {}
mesh.layers[0].bake();
mesh.bake();
assert_eq!(mesh.layers[0].polygons.len(), 3);
}

#[test]
fn merge_and_path() {
let mut mesh = mesh_u_grid();
while mesh.merge_polygons() {}
mesh.layers[0].bake();
mesh.bake();
assert_eq!(mesh.layers[0].polygons.len(), 3);
assert_eq!(
mesh.layers[0].polygons[0],
Expand Down Expand Up @@ -291,7 +291,7 @@ mod test {
while mesh.merge_polygons() {
// println!("{:#?}", mesh);
}
mesh.layers[0].bake();
mesh.bake();
assert_eq!(mesh.layers[0].polygons.len(), 4);
dbg!(mesh.path(Vec2::new(0.5, 0.5), Vec2::new(9.5, 9.5)));
}
Expand Down Expand Up @@ -321,12 +321,12 @@ mod test {
triangulation.simplify(0.001);
let mut mesh = triangulation.as_navmesh();

mesh.layers[0].unbake();
mesh.unbake();
// println!("{:#?}", mesh);
while mesh.merge_polygons() {
// println!("{:#?}", mesh);
}
mesh.layers[0].bake();
mesh.bake();
assert_eq!(mesh.layers[0].polygons.len(), 6);
dbg!(mesh.path(Vec2::new(-4.5, 4.0), Vec2::new(-4.0, -4.5)));
}
Expand Down

0 comments on commit 39c9a77

Please sign in to comment.