Skip to content

Commit

Permalink
Pass a transform to find_linkable_edges.
Browse files Browse the repository at this point in the history
region_bounds is in Archipelago-space, but nav mesh edges are in Island-space. With this change, we can compute the Archipelago-space border edges and compare them in the same frame.
  • Loading branch information
andriyDev committed Jul 8, 2023
1 parent a536fe0 commit 0895c67
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/island.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,12 @@ impl Island {
linkable_distance_to_region_edge: f32,
) {
self.nav_data = Some(IslandNavigationData {
transform,
linkable_edges: nav_mesh.find_linkable_edges(
self.region_bounds,
transform,
linkable_distance_to_region_edge,
),
transform,
nav_mesh,
});
self.dirty = true;
Expand Down
81 changes: 79 additions & 2 deletions src/nav_mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::HashMap;

use glam::{swizzles::Vec3Swizzles, Vec3};

use crate::BoundingBox;
use crate::{BoundingBox, Transform};

// A navigation mesh.
#[derive(Clone)]
Expand Down Expand Up @@ -267,6 +267,7 @@ impl ValidNavigationMesh {
pub fn find_linkable_edges(
&self,
region_bounds: BoundingBox,
transform: Transform,
linkable_distance_to_region_edge: f32,
) -> [Vec<MeshEdgeRef>; 6] {
const ALIGNED_TO_PLANE_DIRECTION_DEVIATION_EPSILON: f32 = 1e-5;
Expand Down Expand Up @@ -324,6 +325,8 @@ impl ValidNavigationMesh {
[Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new()];
for boundary_edge in self.boundary_edges.iter() {
let edge_vertices = self.get_edge_points(boundary_edge.clone());
let edge_vertices =
(transform.apply(edge_vertices.0), transform.apply(edge_vertices.1));

if let Some(index) = find_plane_index(
&region_bounds,
Expand Down Expand Up @@ -430,11 +433,14 @@ impl ValidPolygon {

#[cfg(test)]
mod tests {
use std::f32::consts::PI;

use glam::Vec3;

use crate::{
nav_mesh::{Connectivity, MeshEdgeRef, ValidPolygon},
util::BoundingBox,
Transform,
};

use super::{NavigationMesh, ValidationError};
Expand Down Expand Up @@ -762,7 +768,11 @@ mod tests {
.validate()
.expect("Mesh is valid.");

let mut linkable_edges = mesh.find_linkable_edges(mesh.mesh_bounds, 1e-10);
let mut linkable_edges = mesh.find_linkable_edges(
mesh.mesh_bounds,
Transform { translation: Vec3::ZERO, rotation: 0.0 },
1e-10,
);

// Sort the edges so it matches the expected result.
linkable_edges.iter_mut().for_each(|edges| {
Expand All @@ -785,6 +795,73 @@ mod tests {
);
}

#[test]
fn finds_linkable_edges_with_transform() {
let tan_8th = (PI / 8.0).tan();

let mesh = NavigationMesh {
mesh_bounds: None,
vertices: vec![
Vec3::new(1.0, 0.0, -tan_8th),
Vec3::new(1.0, 0.0, tan_8th),
Vec3::new(tan_8th, 0.0, 1.0),
Vec3::new(-tan_8th, 0.0, 1.0),
Vec3::new(-1.0, 0.0, tan_8th),
Vec3::new(-1.0, 0.0, -tan_8th),
Vec3::new(-tan_8th, 0.0, -1.0),
Vec3::new(tan_8th, 0.0, -1.0),
],
polygons: vec![vec![0, 1, 2, 3, 4, 5, 6, 7]],
}
.validate()
.expect("Mesh is valid.");

// No transform.
let linkable_edges = mesh.find_linkable_edges(
mesh.mesh_bounds.expand_by_size(Vec3 { x: 0.0, y: 0.1, z: 0.0 }),
Transform { translation: Vec3::ZERO, rotation: 0.0 },
1e-10,
);

assert_eq!(
linkable_edges,
[
&[MeshEdgeRef { polygon_index: 0, edge_index: 4 }] as &[_],
&[MeshEdgeRef { polygon_index: 0, edge_index: 0 }] as &[_],
&[] as &[_],
&[] as &[_],
&[MeshEdgeRef { polygon_index: 0, edge_index: 6 }] as &[_],
&[MeshEdgeRef { polygon_index: 0, edge_index: 2 }] as &[_],
]
);

// Translated and rotated.
let translation = Vec3::new(-1.0, 2.0, 5.0);
let region_bounds = mesh
.mesh_bounds
.expand_by_size(Vec3 { x: 0.0, y: 0.1, z: 0.0 })
// Translate but don't rotate the bounds.
.transform(Transform { translation, rotation: 0.0 });
let linkable_edges = mesh.find_linkable_edges(
region_bounds,
// Fully transform the nav mesh.
Transform { translation, rotation: PI * 0.75 },
1e-10,
);

assert_eq!(
linkable_edges,
[
&[MeshEdgeRef { polygon_index: 0, edge_index: 7 }] as &[_],
&[MeshEdgeRef { polygon_index: 0, edge_index: 3 }] as &[_],
&[] as &[_],
&[] as &[_],
&[MeshEdgeRef { polygon_index: 0, edge_index: 1 }] as &[_],
&[MeshEdgeRef { polygon_index: 0, edge_index: 5 }] as &[_],
]
);
}

#[test]
fn sample_point_returns_none_for_far_point() {
let mesh = NavigationMesh {
Expand Down

0 comments on commit 0895c67

Please sign in to comment.