Skip to content

Commit

Permalink
base layer
Browse files Browse the repository at this point in the history
  • Loading branch information
mockersf committed Jul 7, 2024
1 parent 22bd7ae commit b83d5ec
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 110 deletions.
2 changes: 1 addition & 1 deletion src/async_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl<'m> Future for FuturePath<'m> {
if ending_polygon == u32::MAX {
return Poll::Ready(None);
}
if let Some(islands) = self.mesh.islands.as_ref() {
if let Some(islands) = self.mesh.layers[0].islands.as_ref() {
let start_island = islands.get(starting_polygon_index as usize);
let end_island = islands.get(ending_polygon as usize);
if start_island.is_some() && end_island.is_some() && start_island != end_island {
Expand Down
14 changes: 9 additions & 5 deletions src/input/polyanya_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::io::{self, BufRead, Read, Write};

use glam::Vec2;

use crate::{Mesh, MeshError, Polygon, Vertex};
use crate::{Layer, Mesh, MeshError, Polygon, Vertex};

/// A mesh read from a Polyanya file in the format `mesh 2`.
///
Expand Down Expand Up @@ -142,15 +142,19 @@ impl TryFrom<PolyanyaFile> for Mesh {
type Error = MeshError;

fn try_from(value: PolyanyaFile) -> Result<Self, Self::Error> {
Mesh::new(value.vertices, value.polygons)
Ok(Mesh {
layers: vec![Layer::new(value.vertices, value.polygons)?],
..Default::default()
})
}
}

impl From<Mesh> for PolyanyaFile {
fn from(mesh: Mesh) -> Self {
fn from(mut mesh: Mesh) -> Self {
let last_layer = mesh.layers.pop().unwrap();
PolyanyaFile {
vertices: mesh.vertices,
polygons: mesh.polygons,
vertices: last_layer.vertices,
polygons: last_layer.polygons,
}
}
}
13 changes: 8 additions & 5 deletions src/input/triangulation.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::VecDeque;
use std::{collections::VecDeque, default};

#[cfg(feature = "tracing")]
use tracing::instrument;
Expand All @@ -8,7 +8,7 @@ use geo::{Contains, Coord, Polygon as GeoPolygon, SimplifyVwPreserve};
use glam::{vec2, Vec2};
use spade::{ConstrainedDelaunayTriangulation, Point2, Triangulation as SpadeTriangulation};

use crate::{Mesh, Polygon, Vertex};
use crate::{Layer, Mesh, Polygon, Vertex};

/// An helper to create a [`Mesh`] from a list of edges and obstacle, using a constrained Delaunay triangulation.
#[derive(Clone)]
Expand Down 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.bake();
/// mesh.layers[0].bake();
/// ```
#[cfg_attr(feature = "tracing", instrument(skip_all))]
pub fn as_navmesh(&self) -> Mesh {
Expand Down Expand Up @@ -239,8 +239,11 @@ impl Triangulation {
drop(vertex_span);

Mesh {
vertices,
polygons,
layers: vec![Layer {
vertices,
polygons,
..Default::default()
}],
..Default::default()
}
}
Expand Down
28 changes: 17 additions & 11 deletions src/input/trimesh.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{Mesh, MeshError, Polygon, Vertex};
use crate::{Layer, Mesh, MeshError, Polygon, Vertex};
use glam::Vec2;
use std::cmp::Ordering;
use std::iter;
use std::{default, iter};

trait Triangle {
fn get_clockwise_neighbor(&self, index: usize) -> usize;
Expand Down Expand Up @@ -120,7 +120,10 @@ impl TryFrom<Trimesh> for Mesh {
.into_iter()
.map(|vertex| Vertex::new(vertex.coords, vertex.polygons))
.collect();
Self::new(vertices, polygons)
Ok(Mesh {
layers: vec![Layer::new(vertices, polygons)?],
..Default::default()
})
}
}

Expand Down Expand Up @@ -198,39 +201,42 @@ mod tests {
triangles: vec![[0, 1, 4], [1, 2, 5], [5, 2, 3], [1, 5, 3], [0, 4, 3]],
}
.try_into()?;
assert_eq!(regular_mesh.polygons, from_trimesh.polygons);
for (index, (expected_vertex, actual_vertex)) in regular_mesh
assert_eq!(
regular_mesh.layers[0].polygons,
from_trimesh.layers[0].polygons
);
for (index, (expected_vertex, actual_vertex)) in regular_mesh.layers[0]
.vertices
.iter()
.zip(from_trimesh.vertices.iter())
.zip(from_trimesh.layers[0].vertices.iter())
.enumerate()
{
assert_eq!(
expected_vertex.coords, actual_vertex.coords,
"\nvertex {index} does not have the expected coords.\nExpected vertices: {0:?}\nGot vertices: {1:?}",
regular_mesh.vertices, from_trimesh.vertices
regular_mesh.layers[0].vertices, from_trimesh.layers[0].vertices
);

assert_eq!(
expected_vertex.is_corner, actual_vertex.is_corner,
"\nvertex {index} does not have the expected value for `is_corner`.\nExpected vertices: {0:?}\nGot vertices: {1:?}",
regular_mesh.vertices, from_trimesh.vertices
regular_mesh.layers[0].vertices, from_trimesh.layers[0].vertices
);
let adjusted_actual = wrap_to_first(&actual_vertex.polygons, |index| *index != -1).unwrap_or_else(||
panic!("vertex {index}: Found only surrounded by obstacles.\nExpected vertices: {0:?}\nGot vertices: {1:?}",
regular_mesh.vertices, from_trimesh.vertices));
regular_mesh.layers[0].vertices, from_trimesh.layers[0].vertices));

let adjusted_expectation= wrap_to_first(&expected_vertex.polygons, |polygon| {
*polygon == adjusted_actual[0]
})
.unwrap_or_else(||
panic!("vertex {index}: Failed to expected polygons.\nExpected vertices: {0:?}\nGot vertices: {1:?}",
regular_mesh.vertices, from_trimesh.vertices));
regular_mesh.layers[0].vertices, from_trimesh.layers[0].vertices));

assert_eq!(
adjusted_expectation, adjusted_actual,
"\nvertex {index} does not have the expected polygons.\nExpected vertices: {0:?}\nGot vertices: {1:?}",
regular_mesh.vertices, from_trimesh.vertices
regular_mesh.layers[0].vertices, from_trimesh.layers[0].vertices
);
}
Ok(())
Expand Down
38 changes: 23 additions & 15 deletions src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl<'m> SearchInstance<'m> {
to: (Vec2, u32),
#[cfg(feature = "stats")] start: Instant,
) -> Self {
let starting_polygon = &mesh.polygons[from.1 as usize];
let starting_polygon = &mesh.layers[0].polygons[from.1 as usize];

let mut search_instance = SearchInstance {
queue: BinaryHeap::with_capacity(15),
Expand Down Expand Up @@ -116,12 +116,12 @@ impl<'m> SearchInstance<'m> {
};

for edge in starting_polygon.edges_index().iter() {
let start = if let Some(v) = mesh.vertices.get(edge.0 as usize) {
let start = if let Some(v) = mesh.layers[0].vertices.get(edge.0 as usize) {
v
} else {
continue;
};
let end = if let Some(v) = mesh.vertices.get(edge.1 as usize) {
let end = if let Some(v) = mesh.layers[0].vertices.get(edge.1 as usize) {
v
} else {
continue;
Expand All @@ -134,8 +134,7 @@ impl<'m> SearchInstance<'m> {

if other_side == to.1 as isize
|| (other_side != isize::MAX
&& !search_instance
.mesh
&& !search_instance.mesh.layers[0]
.polygons
.get(other_side as usize)
.unwrap()
Expand Down Expand Up @@ -234,7 +233,7 @@ impl<'m> SearchInstance<'m> {
pub(crate) fn edges_between(&self, node: &SearchNode) -> SmallVec<[Successor; 10]> {
let mut successors = SmallVec::new();

let polygon = &self.mesh.polygons[node.polygon_to as usize];
let polygon = &self.mesh.layers[0].polygons[node.polygon_to as usize];

// if node.interval.0.distance(node.root) < 1.0e-5
// || node.interval.1.distance(node.root) < 1.0e-5
Expand All @@ -259,15 +258,15 @@ impl<'m> SearchInstance<'m> {

let mut ty = SuccessorType::RightNonObservable;
for edge in &polygon.circular_edges_index(right_index..=left_index) {
if edge.0.max(edge.1) as usize > self.mesh.vertices.len() {
if edge.0.max(edge.1) as usize > self.mesh.layers[0].vertices.len() {
continue;
}
// Bounds are checked just before
#[allow(unsafe_code)]
let (start, end) = unsafe {
(
self.mesh.vertices.get_unchecked(edge.0 as usize),
self.mesh.vertices.get_unchecked(edge.1 as usize),
self.mesh.layers[0].vertices.get_unchecked(edge.0 as usize),
self.mesh.layers[0].vertices.get_unchecked(edge.1 as usize),
)
};
let mut start_point = start.coords;
Expand Down Expand Up @@ -503,8 +502,12 @@ impl<'m> SearchInstance<'m> {
#[allow(unsafe_code)]
let (start, end) = unsafe {
(
self.mesh.vertices.get_unchecked(successor.edge.0 as usize),
self.mesh.vertices.get_unchecked(successor.edge.1 as usize),
self.mesh.layers[0]
.vertices
.get_unchecked(successor.edge.0 as usize),
self.mesh.layers[0]
.vertices
.get_unchecked(successor.edge.1 as usize),
)
};

Expand Down Expand Up @@ -536,8 +539,7 @@ impl<'m> SearchInstance<'m> {

// prune edges that only lead to one other polygon, and not the target: dead end pruning
if self.polygon_to != other_side
&& self
.mesh
&& self.mesh.layers[0]
.polygons
.get(other_side as usize)
.unwrap()
Expand All @@ -561,7 +563,10 @@ impl<'m> SearchInstance<'m> {
}
continue;
}
let vertex = self.mesh.vertices.get(node.edge.0 as usize).unwrap();
let vertex = self.mesh.layers[0]
.vertices
.get(node.edge.0 as usize)
.unwrap();
if vertex.is_corner
&& vertex.coords.distance_squared(node.interval.0) < EPSILON
{
Expand All @@ -583,7 +588,10 @@ impl<'m> SearchInstance<'m> {
}
continue;
}
let vertex = self.mesh.vertices.get(node.edge.1 as usize).unwrap();
let vertex = self.mesh.layers[0]
.vertices
.get(node.edge.1 as usize)
.unwrap();
if vertex.is_corner
&& vertex.coords.distance_squared(node.interval.1) < EPSILON
{
Expand Down
Loading

0 comments on commit b83d5ec

Please sign in to comment.