diff --git a/src/async_helpers.rs b/src/async_helpers.rs index 660942e..d647a69 100644 --- a/src/async_helpers.rs +++ b/src/async_helpers.rs @@ -5,8 +5,8 @@ use std::{fmt, future::Future, task::Poll}; use glam::Vec2; use crate::{ - instance::{InstanceStep, SearchInstance}, - Mesh, Path, PolygonInMesh, POLYGON_NOT_FOUND, + instance::{InstanceStep, SearchInstance, U32Layer}, + Mesh, Path, }; /// A future that will resolve to a [`Option`]. @@ -17,7 +17,7 @@ pub struct FuturePath<'m> { pub(crate) to: Vec2, pub(crate) mesh: &'m Mesh, pub(crate) instance: Option>, - pub(crate) ending_polygon: PolygonInMesh, + pub(crate) ending_polygon: u32, } impl<'m> fmt::Debug for FuturePath<'m> { @@ -51,20 +51,20 @@ impl<'m> Future for FuturePath<'m> { let start = Instant::now(); let starting_polygon_index = self.mesh.get_point_location(self.from); - if starting_polygon_index == POLYGON_NOT_FOUND { + if starting_polygon_index == u32::MAX { return Poll::Ready(None); } let ending_polygon = self.mesh.get_point_location(self.to); - if ending_polygon == POLYGON_NOT_FOUND { + if ending_polygon == u32::MAX { return Poll::Ready(None); } - if starting_polygon_index.layer == ending_polygon.layer { - if let Some(islands) = self.mesh.layers[starting_polygon_index.layer as usize] + if starting_polygon_index.layer() == ending_polygon.layer() { + if let Some(islands) = self.mesh.layers[starting_polygon_index.layer() as usize] .islands .as_ref() { - let start_island = islands.get(starting_polygon_index.polygon as usize); - let end_island = islands.get(ending_polygon.polygon as usize); + 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 { return Poll::Ready(None); diff --git a/src/instance.rs b/src/instance.rs index 83d38b6..1a560a4 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -12,7 +12,7 @@ use hashbrown::{hash_map::Entry, HashMap}; use crate::{ helpers::{heuristic, line_intersect_segment, turning_point, Vec2Helper}, - Mesh, Path, PolygonInMesh, SearchNode, POLYGON_NOT_FOUND, PRECISION, + Mesh, Path, SearchNode, PRECISION, }; pub(crate) struct Root(Vec2); @@ -62,7 +62,7 @@ pub(crate) struct SearchInstance<'m> { pub(crate) root_history: HashMap, pub(crate) from: Vec2, pub(crate) to: Vec2, - pub(crate) polygon_to: PolygonInMesh, + pub(crate) polygon_to: u32, pub(crate) mesh: &'m Mesh, #[cfg(feature = "stats")] pub(crate) start: Instant, @@ -88,15 +88,40 @@ pub(crate) enum InstanceStep { Continue, } +pub(crate) trait U32Layer { + fn layer(&self) -> u8; + + fn polygon(&self) -> u32; + + fn from_layer_and_polygon(layer: u8, polygon: u32) -> Self; +} + +impl U32Layer for u32 { + #[inline(always)] + fn layer(&self) -> u8 { + (*self >> 24) as u8 + } + + #[inline(always)] + fn polygon(&self) -> u32 { + *self & 0b00000000111111111111111111111111 + } + + #[inline(always)] + fn from_layer_and_polygon(layer: u8, polygon: u32) -> u32 { + ((layer as u32) << 24) | polygon + } +} + impl<'m> SearchInstance<'m> { pub(crate) fn setup( mesh: &'m Mesh, - from: (Vec2, PolygonInMesh), - to: (Vec2, PolygonInMesh), + from: (Vec2, u32), + to: (Vec2, u32), #[cfg(feature = "stats")] start: Instant, ) -> Self { let starting_polygon = - &mesh.layers[from.1.layer as usize].polygons[from.1.polygon as usize]; + &mesh.layers[from.1.layer() as usize].polygons[from.1.polygon() as usize]; let mut search_instance = SearchInstance { queue: BinaryHeap::with_capacity(15), @@ -130,26 +155,22 @@ impl<'m> SearchInstance<'m> { root: from.0, interval: (Vec2::new(0.0, 0.0), Vec2::new(0.0, 0.0)), edge: (0, 0), - polygon_from: POLYGON_NOT_FOUND, + polygon_from: u32::MAX, polygon_to: from.1, - previous_polygon_layer: to.1.layer, + previous_polygon_layer: to.1.layer(), f: 0.0, g: 0.0, }; + let from_layer = &mesh.layers[from.1.layer() as usize]; + for edge in starting_polygon.edges_index().iter() { - let start = if let Some(v) = mesh.layers[from.1.layer as usize] - .vertices - .get(edge.0 as usize) - { + let start = if let Some(v) = from_layer.vertices.get(edge.0 as usize) { v } else { continue; }; - let end = if let Some(v) = mesh.layers[from.1.layer as usize] - .vertices - .get(edge.1 as usize) - { + let end = if let Some(v) = from_layer.vertices.get(edge.1 as usize) { v } else { continue; @@ -158,24 +179,20 @@ impl<'m> SearchInstance<'m> { .polygons .iter() .filter(|i| **i != u32::MAX && end.polygons.contains(*i)) - .map(|i| PolygonInMesh { - layer: (*i >> 24) as u8, - polygon: *i & 0b00000000111111111111111111111111, - }) - .find(|poly| poly != &from.1) - .unwrap_or(POLYGON_NOT_FOUND); - - if other_side == to.1 - || (other_side != POLYGON_NOT_FOUND - && !search_instance.mesh.layers[other_side.layer as usize] + .find(|poly| *poly != &from.1) + .unwrap_or(&u32::MAX); + + if other_side == &to.1 + || (other_side != &u32::MAX + && !search_instance.mesh.layers[other_side.layer() as usize] .polygons - .get(other_side.polygon as usize) + .get(other_side.polygon() as usize) .unwrap() .is_one_way) { search_instance.add_node( from.0, - other_side, + *other_side, (start.coords, edge.0), (end.coords, edge.1), &empty_node, @@ -267,8 +284,9 @@ impl<'m> SearchInstance<'m> { pub(crate) fn edges_between(&self, node: &SearchNode) -> SmallVec<[Successor; 10]> { let mut successors = SmallVec::new(); - let polygon = &self.mesh.layers[node.polygon_to.layer as usize].polygons - [node.polygon_to.polygon as usize]; + let target_layer = &self.mesh.layers[node.polygon_to.layer() as usize]; + + let polygon = &target_layer.polygons[node.polygon_to.polygon() as usize]; // if node.interval.0.distance(node.root) < 1.0e-5 // || node.interval.1.distance(node.root) < 1.0e-5 @@ -287,11 +305,7 @@ impl<'m> SearchInstance<'m> { let edge = self.mesh.layers[node.previous_polygon_layer as usize].vertices [node.edge.1 as usize] .coords; - while self.mesh.layers[node.polygon_to.layer as usize].vertices - [polygon.vertices[temp] as usize] - .coords - != edge - { + while target_layer.vertices[polygon.vertices[temp] as usize].coords != edge { temp += 1; } temp + 1 @@ -300,23 +314,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.layers[node.polygon_to.layer as usize] - .vertices - .len() - { + if edge.0.max(edge.1) as usize > target_layer.vertices.len() { continue; } // Bounds are checked just before #[allow(unsafe_code)] let (start, end) = unsafe { ( - self.mesh.layers[node.polygon_to.layer as usize] - .vertices - .get_unchecked(edge.0 as usize), - self.mesh.layers[node.polygon_to.layer as usize] - .vertices - .get_unchecked(edge.1 as usize), + target_layer.vertices.get_unchecked(edge.0 as usize), + target_layer.vertices.get_unchecked(edge.1 as usize), ) }; let mut start_point = start.coords; @@ -449,7 +455,7 @@ impl<'m> SearchInstance<'m> { pub(crate) fn add_node( &mut self, root: Vec2, - other_side: PolygonInMesh, + other_side: u32, start: (Vec2, u32), end: (Vec2, u32), node: &SearchNode, @@ -482,7 +488,7 @@ impl<'m> SearchInstance<'m> { edge: (start.1, end.1), polygon_from: node.polygon_to, polygon_to: other_side, - previous_polygon_layer: node.polygon_to.layer, + previous_polygon_layer: node.polygon_to.layer(), f: new_f, g: heuristic, }; @@ -552,11 +558,12 @@ impl<'m> SearchInstance<'m> { // we know they exist, it's checked in `edges_between` #[allow(unsafe_code)] let (start, end) = unsafe { + let target_layer = &self.mesh.layers[node.polygon_to.layer() as usize]; ( - self.mesh.layers[node.polygon_to.layer as usize] + target_layer .vertices .get_unchecked(successor.edge.0 as usize), - self.mesh.layers[node.polygon_to.layer as usize] + target_layer .vertices .get_unchecked(successor.edge.1 as usize), ) @@ -571,12 +578,8 @@ impl<'m> SearchInstance<'m> { .polygons .iter() .filter(|i| **i != u32::MAX && end.polygons.contains(*i)) - .map(|i| PolygonInMesh { - layer: (*i >> 24) as u8, - polygon: *i & 0b00000000111111111111111111111111, - }) - .find(|poly| poly != &node.polygon_to) - .unwrap_or(POLYGON_NOT_FOUND); + .find(|poly| poly != &&node.polygon_to) + .unwrap_or(&u32::MAX); #[cfg(debug_assertions)] if self.debug { @@ -584,7 +587,7 @@ impl<'m> SearchInstance<'m> { } // prune edges that don't have a polygon on the other side: cul de sac pruning - if other_side == POLYGON_NOT_FOUND { + if other_side == &u32::MAX { #[cfg(debug_assertions)] if self.debug { println!("x cul de sac"); @@ -594,11 +597,9 @@ 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.layers[other_side.layer as usize] - .polygons - .get(other_side.polygon as usize) - .unwrap() + if &self.polygon_to != other_side + && self.mesh.layers[other_side.layer() as usize].polygons + [other_side.polygon() as usize] .is_one_way { #[cfg(debug_assertions)] @@ -619,7 +620,7 @@ impl<'m> SearchInstance<'m> { } continue; } - let vertex = self.mesh.layers[node.polygon_to.layer as usize] + let vertex = self.mesh.layers[node.polygon_to.layer() as usize] .vertices .get(node.edge.0 as usize) .unwrap(); @@ -644,7 +645,7 @@ impl<'m> SearchInstance<'m> { } continue; } - let vertex = self.mesh.layers[node.polygon_to.layer as usize] + let vertex = self.mesh.layers[node.polygon_to.layer() as usize] .vertices .get(node.edge.1 as usize) .unwrap(); @@ -669,7 +670,7 @@ impl<'m> SearchInstance<'m> { self.add_node( root, - other_side, + *other_side, (successor.interval.0, successor.edge.0), (successor.interval.1, successor.edge.1), &node, diff --git a/src/layers.rs b/src/layers.rs index 7562b87..7f2fcb3 100644 --- a/src/layers.rs +++ b/src/layers.rs @@ -215,7 +215,7 @@ impl Layer { mod tests { use glam::{vec2, Vec2}; - use crate::{Layer, Mesh, Path, Polygon, PolygonInMesh, SearchNode, Vertex, POLYGON_NOT_FOUND}; + use crate::{instance::U32Layer, Layer, Mesh, Path, Polygon, SearchNode, Vertex}; fn mesh_u_grid() -> Mesh { let main_layer = Layer { @@ -273,37 +273,16 @@ mod tests { #[test] fn point_in_polygon() { let mesh = mesh_u_grid(); - assert_eq!( - mesh.get_point_location(Vec2::new(0.5, 0.5)), - PolygonInMesh { - layer: 0, - polygon: 0 - } - ); - assert_eq!( - mesh.get_point_location(Vec2::new(1.5, 0.5)), - PolygonInMesh { - layer: 0, - polygon: 1 - } - ); + 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)), - PolygonInMesh { - layer: 1, - polygon: 0 - } - ); - assert_eq!( - mesh.get_point_location(Vec2::new(1.5, 1.5)), - POLYGON_NOT_FOUND + u32::from_layer_and_polygon(1, 0) ); + assert_eq!(mesh.get_point_location(Vec2::new(1.5, 1.5)), u32::MAX); assert_eq!( mesh.get_point_location(Vec2::new(2.5, 1.5)), - PolygonInMesh { - layer: 2, - polygon: 0 - } + u32::from_layer_and_polygon(2, 0) ); } @@ -347,10 +326,7 @@ mod tests { interval: (Vec2::new(0.0, 1.0), Vec2::new(1.0, 1.0)), edge: (4, 5), polygon_from: mesh.get_point_location(from), - polygon_to: PolygonInMesh { - layer: 0, - polygon: 0, - }, + polygon_to: 0, previous_polygon_layer: 0, f: 0.0, g: from.distance(to), @@ -363,14 +339,8 @@ mod tests { from.distance(Vec2::new(1.0, 1.0)) + Vec2::new(1.0, 1.0).distance(Vec2::new(2.0, 1.0)) ); assert_eq!(successors[0].g, Vec2::new(2.0, 1.0).distance(to)); - assert_eq!(successors[0].polygon_from.polygon, 2); - assert_eq!( - successors[0].polygon_to, - PolygonInMesh { - layer: 2, - polygon: 0 - } - ); + assert_eq!(successors[0].polygon_from.polygon(), 2); + assert_eq!(successors[0].polygon_to, u32::from_layer_and_polygon(2, 0)); assert_eq!( successors[0].interval, (Vec2::new(3.0, 1.0), Vec2::new(2.0, 1.0)) @@ -459,19 +429,10 @@ mod tests { #[test] fn find_point_on_layer() { let mesh = mesh_overlapping_layers(); - assert_eq!( - mesh.get_point_location_on_layer(vec2(2.5, 1.5), 0), - PolygonInMesh { - layer: 0, - polygon: 1, - } - ); + assert_eq!(mesh.get_point_location_on_layer(vec2(2.5, 1.5), 0), 1); assert_eq!( mesh.get_point_location_on_layer(vec2(2.5, 1.5), 1), - PolygonInMesh { - layer: 1, - polygon: 0, - } + u32::from_layer_and_polygon(1, 0) ); } } diff --git a/src/lib.rs b/src/lib.rs index fd94443..aa27a7a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,7 @@ use std::{ use bvh2d::aabb::{Bounded, AABB}; use glam::Vec2; -use instance::InstanceStep; +use instance::{InstanceStep, U32Layer}; use layers::Layer; use log::error; use thiserror::Error; @@ -60,18 +60,6 @@ pub struct Path { /// Coordinates for each step of the path. The destination is the last step. pub path: Vec, } - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -struct PolygonInMesh { - layer: u8, - polygon: u32, -} - -const POLYGON_NOT_FOUND: PolygonInMesh = PolygonInMesh { - layer: 0, - polygon: u32::MAX, -}; - /// A navigation mesh #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -158,7 +146,7 @@ impl Mesh { to, mesh: self, instance: None, - ending_polygon: POLYGON_NOT_FOUND, + ending_polygon: u32::MAX, } } @@ -174,20 +162,20 @@ impl Mesh { let start = Instant::now(); let starting_polygon_index = self.get_point_location(from); - if starting_polygon_index.polygon == u32::MAX { + if starting_polygon_index == u32::MAX { return None; } let ending_polygon = self.get_point_location(to); - if ending_polygon.polygon == u32::MAX { + if ending_polygon == u32::MAX { return None; } - if starting_polygon_index.layer == ending_polygon.layer { - if let Some(islands) = self.layers[starting_polygon_index.layer as usize] + if starting_polygon_index.layer() == ending_polygon.layer() { + if let Some(islands) = self.layers[starting_polygon_index.layer() as usize] .islands .as_ref() { - let start_island = islands.get(starting_polygon_index.polygon as usize); - let end_island = islands.get(ending_polygon.polygon as usize); + let start_island = islands.get(starting_polygon_index.polygon() as usize); + let end_island = islands.get(ending_polygon.polygon() as usize); if start_island.is_some() && end_island.is_some() && start_island != end_island { return None; } @@ -323,41 +311,40 @@ impl Mesh { /// Check if a given point is in a `Mesh` pub fn point_in_mesh(&self, point: Vec2) -> bool { - self.get_point_location(point).polygon != u32::MAX + self.get_point_location(point) != u32::MAX } /// Check if a given point is in a `Mesh` on a given `Layer` pub fn point_in_mesh_on_layer(&self, point: Vec2, layer: u8) -> bool { - self.get_point_location_on_layer(point, layer).polygon != u32::MAX + self.get_point_location_on_layer(point, layer) != u32::MAX } #[cfg_attr(feature = "tracing", instrument(skip_all))] - fn get_point_location(&self, point: Vec2) -> PolygonInMesh { + fn get_point_location(&self, point: Vec2) -> u32 { self.layers .iter() .enumerate() .flat_map(|(index, layer)| { - Some(PolygonInMesh { - layer: index as u8, - polygon: layer.get_point_location(point, self.delta)?, - }) + Some(U32Layer::from_layer_and_polygon( + index as u8, + layer.get_point_location(point, self.delta)?, + )) }) - .find(|poly| poly.polygon != u32::MAX) - .unwrap_or(POLYGON_NOT_FOUND) + .find(|poly| poly != &u32::MAX) + .unwrap_or(u32::MAX) } #[cfg_attr(feature = "tracing", instrument(skip_all))] - fn get_point_location_on_layer(&self, point: Vec2, layer_index: u8) -> PolygonInMesh { - let delta = self.delta; + fn get_point_location_on_layer(&self, point: Vec2, layer_index: u8) -> u32 { self.layers .get(layer_index as usize) .and_then(|layer| { - Some(PolygonInMesh { - layer: layer_index, - polygon: layer.get_point_location(point, delta)?, - }) + Some(U32Layer::from_layer_and_polygon( + layer_index, + layer.get_point_location(point, self.delta)?, + )) }) - .unwrap_or(POLYGON_NOT_FOUND) + .unwrap_or(u32::MAX) } } @@ -367,8 +354,8 @@ struct SearchNode { root: Vec2, interval: (Vec2, Vec2), edge: (u32, u32), - polygon_from: PolygonInMesh, - polygon_to: PolygonInMesh, + polygon_from: u32, + polygon_to: u32, previous_polygon_layer: u8, f: f32, g: f32, @@ -422,7 +409,7 @@ mod tests { use glam::Vec2; - use crate::{helpers::*, Layer, Mesh, Path, Polygon, PolygonInMesh, SearchNode, Vertex}; + use crate::{helpers::*, Layer, Mesh, Path, Polygon, SearchNode, Vertex}; fn mesh_u_grid() -> Mesh { let layer = Layer { @@ -459,14 +446,11 @@ mod tests { fn point_in_polygon() { let mut mesh = mesh_u_grid(); mesh.bake(); - assert_eq!(mesh.get_point_location(Vec2::new(0.5, 0.5)).polygon, 0); - assert_eq!(mesh.get_point_location(Vec2::new(1.5, 0.5)).polygon, 1); - assert_eq!(mesh.get_point_location(Vec2::new(0.5, 1.5)).polygon, 3); - assert_eq!( - mesh.get_point_location(Vec2::new(1.5, 1.5)).polygon, - u32::MAX - ); - assert_eq!(mesh.get_point_location(Vec2::new(2.5, 1.5)).polygon, 4); + 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); + assert_eq!(mesh.get_point_location(Vec2::new(1.5, 1.5)), u32::MAX); + assert_eq!(mesh.get_point_location(Vec2::new(2.5, 1.5)), 4); } #[test] @@ -481,10 +465,7 @@ mod tests { interval: (Vec2::new(1.0, 0.0), Vec2::new(1.0, 1.0)), edge: (1, 5), polygon_from: mesh.get_point_location(from), - polygon_to: PolygonInMesh { - layer: 0, - polygon: 1, - }, + polygon_to: 1, previous_polygon_layer: 0, f: from.distance(to), g: 0.0, @@ -494,8 +475,8 @@ mod tests { assert_eq!(successors[0].root, from); assert_eq!(successors[0].f, from.distance(to)); assert_eq!(successors[0].g, from.distance(to)); - assert_eq!(successors[0].polygon_from.polygon, 1); - assert_eq!(successors[0].polygon_to.polygon, 2); + assert_eq!(successors[0].polygon_from, 1); + assert_eq!(successors[0].polygon_to, 2); assert_eq!( successors[0].interval, (Vec2::new(2.0, 0.0), Vec2::new(2.0, 1.0)) @@ -525,10 +506,7 @@ mod tests { interval: (Vec2::new(2.0, 1.0), Vec2::new(2.0, 0.0)), edge: (6, 2), polygon_from: mesh.get_point_location(from), - polygon_to: PolygonInMesh { - layer: 0, - polygon: 1, - }, + polygon_to: 1, previous_polygon_layer: 0, f: 0.0, g: from.distance(to), @@ -538,8 +516,8 @@ mod tests { assert_eq!(successors[0].root, from); assert_eq!(successors[0].f, 0.0); assert_eq!(successors[0].g, to.distance(from)); - assert_eq!(successors[0].polygon_from.polygon, 1); - assert_eq!(successors[0].polygon_to.polygon, 0); + assert_eq!(successors[0].polygon_from, 1); + assert_eq!(successors[0].polygon_to, 0); assert_eq!( successors[0].interval, (Vec2::new(1.0, 1.0), Vec2::new(1.0, 0.0)) @@ -568,10 +546,7 @@ mod tests { interval: (Vec2::new(0.0, 1.0), Vec2::new(1.0, 1.0)), edge: (4, 5), polygon_from: mesh.get_point_location(from), - polygon_to: PolygonInMesh { - layer: 0, - polygon: 0, - }, + polygon_to: 0, previous_polygon_layer: 0, f: 0.0, g: from.distance(to), @@ -584,8 +559,8 @@ mod tests { from.distance(Vec2::new(1.0, 1.0)) + Vec2::new(1.0, 1.0).distance(Vec2::new(2.0, 1.0)) ); assert_eq!(successors[0].g, Vec2::new(2.0, 1.0).distance(to)); - assert_eq!(successors[0].polygon_from.polygon, 2); - assert_eq!(successors[0].polygon_to.polygon, 4); + assert_eq!(successors[0].polygon_from, 2); + assert_eq!(successors[0].polygon_to, 4); assert_eq!( successors[0].interval, (Vec2::new(3.0, 1.0), Vec2::new(2.0, 1.0)) @@ -615,14 +590,8 @@ mod tests { root: from, interval: (Vec2::new(1.0, 0.0), Vec2::new(1.0, 1.0)), edge: (1, 5), - polygon_from: PolygonInMesh { - layer: 0, - polygon: 0, - }, - polygon_to: PolygonInMesh { - layer: 0, - polygon: 1, - }, + polygon_from: 0, + polygon_to: 1, previous_polygon_layer: 0, f: 0.0, g: from.distance(to), @@ -635,8 +604,8 @@ mod tests { from.distance(Vec2::new(1.0, 1.0)) + Vec2::new(1.0, 1.0).distance(Vec2::new(2.0, 1.0)) ); assert_eq!(successors[0].g, Vec2::new(2.0, 1.0).distance(to)); - assert_eq!(successors[0].polygon_from.polygon, 2); - assert_eq!(successors[0].polygon_to.polygon, 4); + assert_eq!(successors[0].polygon_from, 2); + assert_eq!(successors[0].polygon_to, 4); assert_eq!( successors[0].interval, (Vec2::new(3.0, 1.0), Vec2::new(2.0, 1.0)) @@ -709,14 +678,11 @@ mod tests { fn paper_point_in_polygon() { let mut mesh = mesh_from_paper(); mesh.bake(); - assert_eq!( - mesh.get_point_location(Vec2::new(0.5, 0.5)).polygon, - u32::MAX - ); - assert_eq!(mesh.get_point_location(Vec2::new(2.0, 6.0)).polygon, 0); - assert_eq!(mesh.get_point_location(Vec2::new(2.0, 5.1)).polygon, 0); - assert_eq!(mesh.get_point_location(Vec2::new(2.0, 1.5)).polygon, 1); - assert_eq!(mesh.get_point_location(Vec2::new(4.0, 2.1)).polygon, 2); + 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); + assert_eq!(mesh.get_point_location(Vec2::new(2.0, 1.5)), 1); + assert_eq!(mesh.get_point_location(Vec2::new(4.0, 2.1)), 2); } #[test] @@ -731,10 +697,7 @@ mod tests { interval: (Vec2::new(11.0, 3.0), Vec2::new(7.0, 0.0)), edge: (16, 15), polygon_from: mesh.get_point_location(from), - polygon_to: PolygonInMesh { - layer: 0, - polygon: 4, - }, + polygon_to: 4, previous_polygon_layer: 0, f: 0.0, g: from.distance(to), @@ -749,8 +712,8 @@ mod tests { Vec2::new(11.0, 3.0).distance(Vec2::new(9.75, 6.75)) + Vec2::new(9.75, 6.75).distance(to) ); - assert_eq!(successors[1].polygon_from.polygon, 4); - assert_eq!(successors[1].polygon_to.polygon, 2); + assert_eq!(successors[1].polygon_from, 4); + assert_eq!(successors[1].polygon_to, 2); assert_eq!( successors[1].interval, (Vec2::new(10.0, 7.0), Vec2::new(9.75, 6.75)) @@ -761,8 +724,8 @@ mod tests { assert_eq!(successors[0].root, from); assert_eq!(successors[0].f, 0.0); assert_eq!(successors[0].g, from.distance(to)); - assert_eq!(successors[0].polygon_from.polygon, 4); - assert_eq!(successors[0].polygon_to.polygon, 2); + assert_eq!(successors[0].polygon_from, 4); + assert_eq!(successors[0].polygon_to, 2); assert_eq!( successors[0].interval, (Vec2::new(9.75, 6.75), Vec2::new(7.0, 4.0)) @@ -786,10 +749,7 @@ mod tests { interval: (Vec2::new(11.0, 3.0), Vec2::new(7.0, 0.0)), edge: (16, 15), polygon_from: mesh.get_point_location(from), - polygon_to: PolygonInMesh { - layer: 0, - polygon: 4, - }, + polygon_to: 4, previous_polygon_layer: 0, f: 0.0, g: from.distance(to), @@ -803,8 +763,8 @@ mod tests { successors[0].g, Vec2::new(11.0, 3.0).distance(Vec2::new(11.0, 5.0)) + Vec2::new(11.0, 5.0).distance(to) ); - assert_eq!(successors[0].polygon_from.polygon, 4); - assert_eq!(successors[0].polygon_to.polygon, 6); + assert_eq!(successors[0].polygon_from, 4); + assert_eq!(successors[0].polygon_to, 6); assert_eq!( successors[0].interval, (Vec2::new(11.0, 5.0), Vec2::new(10.0, 7.0)) @@ -818,8 +778,8 @@ mod tests { successors[1].g, Vec2::new(11.0, 3.0).distance(to.mirror((Vec2::new(10.0, 7.0), Vec2::new(9.75, 6.75)))) ); - assert_eq!(successors[1].polygon_from.polygon, 4); - assert_eq!(successors[1].polygon_to.polygon, 2); + assert_eq!(successors[1].polygon_from, 4); + assert_eq!(successors[1].polygon_to, 2); assert_eq!( successors[1].interval, (Vec2::new(10.0, 7.0), Vec2::new(9.75, 6.75)) @@ -835,8 +795,8 @@ mod tests { + Vec2::new(9.75, 6.75) .distance(to.mirror((Vec2::new(9.75, 6.75), Vec2::new(7.0, 4.0)))) ); - assert_eq!(successors[2].polygon_from.polygon, 4); - assert_eq!(successors[2].polygon_to.polygon, 2); + assert_eq!(successors[2].polygon_from, 4); + assert_eq!(successors[2].polygon_to, 2); assert_eq!( successors[2].interval, (Vec2::new(9.75, 6.75), Vec2::new(7.0, 4.0)) @@ -868,10 +828,7 @@ mod tests { interval: (Vec2::new(11.0, 3.0), Vec2::new(7.0, 0.0)), edge: (16, 15), polygon_from: mesh.get_point_location(from), - polygon_to: PolygonInMesh { - layer: 0, - polygon: 4, - }, + polygon_to: 4, previous_polygon_layer: 0, f: 0.0, g: from.distance(to), @@ -886,8 +843,8 @@ mod tests { Vec2::new(11.0, 3.0).distance(Vec2::new(9.75, 6.75)) + Vec2::new(9.75, 6.75).distance(to) ); - assert_eq!(successors[1].polygon_from.polygon, 4); - assert_eq!(successors[1].polygon_to.polygon, 2); + assert_eq!(successors[1].polygon_from, 4); + assert_eq!(successors[1].polygon_to, 2); assert_eq!( successors[1].interval, (Vec2::new(10.0, 7.0), Vec2::new(9.75, 6.75)) @@ -901,8 +858,8 @@ mod tests { successors[0].g, from.distance(Vec2::new(7.0, 4.0)) + Vec2::new(7.0, 4.0).distance(to) ); - assert_eq!(successors[0].polygon_from.polygon, 4); - assert_eq!(successors[0].polygon_to.polygon, 2); + assert_eq!(successors[0].polygon_from, 4); + assert_eq!(successors[0].polygon_to, 2); assert_eq!( successors[0].interval, (Vec2::new(9.75, 6.75), Vec2::new(7.0, 4.0)) @@ -947,10 +904,7 @@ mod tests { interval: (Vec2::new(11.0, 3.0), Vec2::new(7.0, 0.0)), edge: (16, 15), polygon_from: mesh.get_point_location(from), - polygon_to: PolygonInMesh { - layer: 0, - polygon: 4, - }, + polygon_to: 4, previous_polygon_layer: 0, f: 0.0, g: from.distance(to), @@ -965,8 +919,8 @@ mod tests { Vec2::new(11.0, 3.0).distance(Vec2::new(9.75, 6.75)) + Vec2::new(9.75, 6.75).distance(to) ); - assert_eq!(successors[1].polygon_from.polygon, 4); - assert_eq!(successors[1].polygon_to.polygon, 2); + assert_eq!(successors[1].polygon_from, 4); + assert_eq!(successors[1].polygon_to, 2); assert_eq!( successors[1].interval, (Vec2::new(10.0, 7.0), Vec2::new(9.75, 6.75)) @@ -980,8 +934,8 @@ mod tests { successors[0].g, from.distance(Vec2::new(7.0, 4.0)) + Vec2::new(7.0, 4.0).distance(to) ); - assert_eq!(successors[0].polygon_from.polygon, 4); - assert_eq!(successors[0].polygon_to.polygon, 2); + assert_eq!(successors[0].polygon_from, 4); + assert_eq!(successors[0].polygon_to, 2); assert_eq!( successors[0].interval, (Vec2::new(9.75, 6.75), Vec2::new(7.0, 4.0)) @@ -1019,10 +973,7 @@ mod tests { interval: (Vec2::new(11.0, 3.0), Vec2::new(7.0, 0.0)), edge: (16, 15), polygon_from: mesh.get_point_location(from), - polygon_to: PolygonInMesh { - layer: 0, - polygon: 4, - }, + polygon_to: 4, previous_polygon_layer: 0, f: 0.0, g: from.distance(to), @@ -1041,14 +992,8 @@ mod tests { root: from, interval: (Vec2::new(9.75, 6.75), Vec2::new(7.0, 4.0)), edge: (11, 10), - polygon_from: PolygonInMesh { - layer: 0, - polygon: 4, - }, - polygon_to: PolygonInMesh { - layer: 0, - polygon: 2, - }, + polygon_from: 4, + polygon_to: 2, previous_polygon_layer: 0, f: 0.0, g: from.distance(to), @@ -1067,14 +1012,8 @@ mod tests { root: Vec2::new(11.0, 3.0), interval: (Vec2::new(10.0, 7.0), Vec2::new(7.0, 4.0)), edge: (11, 10), - polygon_from: PolygonInMesh { - layer: 0, - polygon: 4, - }, - polygon_to: PolygonInMesh { - layer: 0, - polygon: 2, - }, + polygon_from: 4, + polygon_to: 2, previous_polygon_layer: 0, f: 0.0, g: from.distance(to), @@ -1096,14 +1035,8 @@ mod tests { root: Vec2::new(0.0, 0.0), interval: (Vec2::new(1.0, 0.0), Vec2::new(1.0, 1.0)), edge: (1, 5), - polygon_from: PolygonInMesh { - layer: 0, - polygon: 0, - }, - polygon_to: PolygonInMesh { - layer: 0, - polygon: 1, - }, + polygon_from: 0, + polygon_to: 1, previous_polygon_layer: 0, f: 0.0, g: 1.0, diff --git a/src/stitching.rs b/src/stitching.rs index 0d70ff3..e0b2570 100644 --- a/src/stitching.rs +++ b/src/stitching.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use glam::Vec2; -use crate::Mesh; +use crate::{instance::U32Layer, Mesh}; impl Mesh { fn stitch_internals( @@ -41,7 +41,7 @@ impl Mesh { let mut neighbors_from = vertex_from .polygons .iter() - .filter(|n| **n != u32::MAX && (*n >> 24) as u8 == from) + .filter(|n| **n != u32::MAX && n.layer() == from) .cloned() .collect::>(); let vertex_to = self @@ -55,7 +55,7 @@ impl Mesh { let neighbors_to = vertex_to .polygons .iter() - .filter(|n| **n != u32::MAX && (*n >> 24) as u8 == to) + .filter(|n| **n != u32::MAX && n.layer() == to) .cloned() .collect::>(); std::mem::swap(&mut vertex_to.polygons, &mut neighbors_from); @@ -92,8 +92,8 @@ impl Mesh { if *p == u32::MAX { return true; } - if (*p >> 24) as u8 == layer_index as u8 { - *p &= 0b00000000111111111111111111111111; + if p.layer() == layer_index as u8 { + *p = p.polygon(); true } else { false @@ -115,8 +115,8 @@ impl Mesh { if *p == u32::MAX { return true; } - if (*p >> 24) as u8 == layer_index as u8 { - *p &= 0b00000000111111111111111111111111; + if p.layer() == layer_index as u8 { + *p = p.polygon(); true } else { false @@ -128,7 +128,7 @@ impl Mesh { if *p == u32::MAX { return true; } - (*p >> 24) as u8 != target_layer + p.layer() != target_layer }) } }