Skip to content

Commit

Permalink
Add criterion & simple generation benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
TheGrimsey committed Sep 19, 2023
1 parent 83a1944 commit 9b0cf38
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 34 deletions.
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ default = []
rapier = ["bevy_rapier3d"]
xpbd = ["bevy_xpbd_3d"]
debug_draw = ["bevy/bevy_gizmos"]
trace = []

[[example]]
name = "rapier3d"
Expand Down Expand Up @@ -68,3 +67,8 @@ bevy = { version = "0.11", default-features = false, features = [
"zstd",
] }
futures-lite = "1.13"
criterion = { version = "0.5" }

[[bench]]
name = "simple_geometry"
harness = false
97 changes: 97 additions & 0 deletions benches/simple_geometry.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use bevy::prelude::{UVec2, Transform, Vec3};
use criterion::{Criterion, criterion_group, criterion_main, black_box};
use oxidized_navigation::{build_tile_sync, NavMeshSettings, conversion::{GeometryToConvert, GeometryCollection, ColliderType}};
use parry3d::shape::Cuboid;


fn generate_single_primitive_geometry() {
let tile_coord = UVec2::new(0, 0);
let heightfields = vec![];


let geometry_collections = vec![
GeometryCollection {
transform: Transform::from_xyz(0.0, 0.0, 0.0),
geometry_to_convert: GeometryToConvert::Collider(ColliderType::Cuboid(Cuboid::new(Vec3::new(10.0, 0.2, 10.0).into()))),
area: None
}
];
let nav_mesh_settings = NavMeshSettings {
cell_width: 0.25,
cell_height: 0.1,
tile_width: 100,
world_half_extents: 12.5,
world_bottom_bound: -100.0,
max_traversable_slope_radians: (40.0_f32 - 0.1).to_radians(),
walkable_height: 20,
walkable_radius: 1,
step_height: 3,
min_region_area: 100,
merge_region_area: 500,
max_contour_simplification_error: 1.1,
max_edge_length: 80,
max_tile_generation_tasks: Some(1),
};

black_box(build_tile_sync(geometry_collections, tile_coord, heightfields, &nav_mesh_settings));
}

fn generate_many_primitive_geometry() {
let tile_coord = UVec2::new(0, 0);
let heightfields = vec![];


let geometry_collections = vec![
GeometryCollection {
transform: Transform::from_xyz(0.0, 0.0, 0.0),
geometry_to_convert: GeometryToConvert::Collider(ColliderType::Cuboid(Cuboid::new(Vec3::new(10.0, 0.2, 10.0).into()))),
area: None
},
GeometryCollection {
transform: Transform::from_xyz(5.0, 1.0, 0.0),
geometry_to_convert: GeometryToConvert::Collider(ColliderType::Cuboid(Cuboid::new(Vec3::new(1.0, 1.0, 1.0).into()))),
area: None
},
GeometryCollection {
transform: Transform::from_xyz(-5.0, 1.0, 2.0),
geometry_to_convert: GeometryToConvert::Collider(ColliderType::Cuboid(Cuboid::new(Vec3::new(4.0, 1.0, 1.0).into()))),
area: None
},
GeometryCollection {
transform: Transform::from_xyz(-2.5, 2.0, 2.0),
geometry_to_convert: GeometryToConvert::Collider(ColliderType::Cuboid(Cuboid::new(Vec3::new(1.0, 2.0, 1.0).into()))),
area: None
},
GeometryCollection {
transform: Transform::from_xyz(-2.5, 2.0, -2.0),
geometry_to_convert: GeometryToConvert::Collider(ColliderType::Cuboid(Cuboid::new(Vec3::new(1.0, 2.0, 1.0).into()))),
area: None
}
];
let nav_mesh_settings = NavMeshSettings {
cell_width: 0.25,
cell_height: 0.1,
tile_width: 100,
world_half_extents: 12.5,
world_bottom_bound: -100.0,
max_traversable_slope_radians: (40.0_f32 - 0.1).to_radians(),
walkable_height: 20,
walkable_radius: 1,
step_height: 3,
min_region_area: 100,
merge_region_area: 500,
max_contour_simplification_error: 1.1,
max_edge_length: 80,
max_tile_generation_tasks: Some(1),
};

black_box(build_tile_sync(geometry_collections, tile_coord, heightfields, &nav_mesh_settings));
}

fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("Generate Single Primitive Geometry", |b| b.iter(generate_single_primitive_geometry));
c.bench_function("Generate Many Primitive Geometry", |b| b.iter(generate_many_primitive_geometry));
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
12 changes: 6 additions & 6 deletions src/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ use parry3d::{

use crate::{heightfields::TriangleCollection, Area};

pub(super) struct GeometryCollection {
pub(super) transform: Transform,
pub(super) geometry_to_convert: GeometryToConvert,
pub(super) area: Option<Area>,
pub struct GeometryCollection {
pub transform: Transform,
pub geometry_to_convert: GeometryToConvert,
pub area: Option<Area>,
}

pub(super) enum ColliderType {
pub enum ColliderType {
Cuboid(Cuboid),
Ball(Ball),
Capsule(Capsule),
Expand All @@ -22,7 +22,7 @@ pub(super) enum ColliderType {
Triangle(Triangle),
}

pub(super) enum GeometryToConvert {
pub enum GeometryToConvert {
Collider(ColliderType),
ParryTriMesh(Vec<Point3<Real>>, Vec<[u32; 3]>),
}
Expand Down
8 changes: 4 additions & 4 deletions src/heightfields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ pub(super) struct TriangleCollection {
pub(super) area: Option<Area>,
}

pub(super) struct HeightFieldCollection {
pub(super) transform: Transform,
pub(super) heightfield: Arc<HeightField>,
pub(super) area: Option<Area>,
pub struct HeightFieldCollection {
pub transform: Transform,
pub heightfield: Arc<HeightField>,
pub area: Option<Area>,
}

pub(super) fn build_heightfield_tile(
Expand Down
51 changes: 28 additions & 23 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ use parry3d::na::Vector3;
use parry3d::shape::{HeightField, TypedShape};
use regions::build_regions;
use smallvec::SmallVec;
use tiles::{create_nav_mesh_tile_from_poly_mesh, NavMeshTiles};
use tiles::{create_nav_mesh_tile_from_poly_mesh, NavMeshTiles, NavMeshTile};

pub mod colliders;
mod contour;
mod conversion;
pub mod conversion;
#[cfg(feature = "debug_draw")]
pub mod debug_draw;
mod heightfields;
Expand Down Expand Up @@ -614,8 +614,23 @@ async fn build_tile(
nav_mesh: Arc<RwLock<NavMeshTiles>>,
) {
#[cfg(feature = "trace")]
let _span = info_span!("Build Tile").entered();
let _span = info_span!("Async build Tile").entered();

let nav_mesh_tile = build_tile_sync(geometry_collections, tile_coord, heightfields, &nav_mesh_settings);

let Ok(mut nav_mesh) = nav_mesh.write() else {
error!("Nav-Mesh lock has been poisoned. Generation can no longer be continued.");
return;
};

if nav_mesh.tile_generations.get(&tile_coord).unwrap_or(&0) < &generation {
nav_mesh.tile_generations.insert(tile_coord, generation);

nav_mesh.add_tile(tile_coord, nav_mesh_tile, &nav_mesh_settings);
}
}

pub fn build_tile_sync(geometry_collections: Vec<GeometryCollection>, tile_coord: UVec2, heightfields: Vec<HeightFieldCollection>, nav_mesh_settings: &NavMeshSettings) -> NavMeshTile {
let triangle_collection = {
#[cfg(feature = "trace")]
let _span = info_span!("Convert Geometry Collections").entered();
Expand All @@ -629,61 +644,51 @@ async fn build_tile(
tile_coord,
triangle_collection,
heightfields,
&nav_mesh_settings,
nav_mesh_settings,
)
};

let mut open_tile = {
#[cfg(feature = "trace")]
let _span = info_span!("Build Open Heightfield Tile").entered();
build_open_heightfield_tile(voxelized_tile, &nav_mesh_settings)
build_open_heightfield_tile(voxelized_tile, nav_mesh_settings)
};

// Remove areas that are too close to a wall.
{
#[cfg(feature = "trace")]
let _span = info_span!("Erode walkable area").entered();
erode_walkable_area(&mut open_tile, &nav_mesh_settings);
erode_walkable_area(&mut open_tile, nav_mesh_settings);
}

{
#[cfg(feature = "trace")]
let _span = info_span!("Calculate distance field").entered();
calculate_distance_field(&mut open_tile, &nav_mesh_settings);
calculate_distance_field(&mut open_tile, nav_mesh_settings);
}
{
#[cfg(feature = "trace")]
let _span = info_span!("Build regions").entered();
build_regions(&mut open_tile, &nav_mesh_settings);
build_regions(&mut open_tile, nav_mesh_settings);
}

let contour_set = {
#[cfg(feature = "trace")]
let _span = info_span!("Build contours").entered();
build_contours(open_tile, &nav_mesh_settings)
build_contours(open_tile, nav_mesh_settings)
};

let poly_mesh = {
#[cfg(feature = "trace")]
let _span = info_span!("Build poly mesh").entered();
build_poly_mesh(contour_set, &nav_mesh_settings)
build_poly_mesh(contour_set, nav_mesh_settings)
};
let nav_mesh_tile = {

{
#[cfg(feature = "trace")]
let _span = info_span!("Create nav-mesh tile from poly mesh").entered();

create_nav_mesh_tile_from_poly_mesh(poly_mesh, tile_coord, &nav_mesh_settings)
};

let Ok(mut nav_mesh) = nav_mesh.write() else {
error!("Nav-Mesh lock has been poisoned. Generation can no longer be continued.");
return;
};

if nav_mesh.tile_generations.get(&tile_coord).unwrap_or(&0) < &generation {
nav_mesh.tile_generations.insert(tile_coord, generation);

nav_mesh.add_tile(tile_coord, nav_mesh_tile, &nav_mesh_settings);
create_nav_mesh_tile_from_poly_mesh(poly_mesh, tile_coord, nav_mesh_settings)
}
}

Expand Down

0 comments on commit 9b0cf38

Please sign in to comment.