use std::{num::NonZeroU16, time::Duration}; use bevy::prelude::*; use bevy_rapier3d::prelude::{Collider, NoUserData, RapierPhysicsPlugin}; use oxidized_navigation::{ query::find_path, ActiveGenerationTasks, NavMesh, NavMeshAffector, NavMeshSettings, OxidizedNavigationPlugin, }; const TIMEOUT_DURATION: Duration = Duration::new(15, 0); const SLEEP_DURATION: Duration = Duration::from_millis(2); fn setup_world_system(mut commands: Commands) { // Plane commands.spawn(( TransformBundle::IDENTITY, Collider::cuboid(25.0, 0.1, 25.0), NavMeshAffector, )); // Cube commands.spawn(( TransformBundle::from_transform(Transform::from_xyz(-5.0, 0.8, -5.0)), Collider::cuboid(1.25, 1.25, 1.25), NavMeshAffector, )); // Tall Cube commands.spawn(( TransformBundle::from_transform( Transform::from_xyz(-0.179, 18.419, -27.744).with_scale(Vec3::new(15.0, 15.0, 15.0)), ), Collider::cuboid(1.25, 1.25, 1.25), NavMeshAffector, )); // Thin wall commands.spawn(( TransformBundle::from_transform( Transform::from_xyz(-3.0, 0.8, 5.0).with_scale(Vec3::new(50.0, 15.0, 1.0)), ), Collider::cuboid(0.05, 0.05, 0.05), NavMeshAffector, )); } fn setup_heightfield_system(mut commands: Commands) { let heightfield_heights = (0..(50 * 50)) .map(|value| { let position = value / 50; (position as f32 / 10.0).sin() / 10.0 }) .collect(); // Heightfield. commands.spawn(( TransformBundle::from_transform(Transform::from_xyz(0.0, 0.0, 0.0)), Collider::heightfield(heightfield_heights, 50, 50, Vec3::new(50.0, 50.0, 50.0)), NavMeshAffector, )); } fn setup_app(app: &mut App) { app.add_plugins(( MinimalPlugins, TransformPlugin, OxidizedNavigationPlugin::::new(NavMeshSettings { cell_width: 0.25, cell_height: 0.1, tile_width: 100, world_half_extents: 250.0, 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, max_region_area_to_merge_into: 500, max_contour_simplification_error: 1.1, max_edge_length: 80, max_tile_generation_tasks: NonZeroU16::new(8), // Github Actions are limited to 7 GB. }), RapierPhysicsPlugin::::default(), )); // Required by Rapier. } fn wait_for_generation_to_finish(app: &mut App) { loop { app.update(); if app.world().resource::().is_empty() { break; } else if app.world().resource::