Skip to content

Commit

Permalink
pathfinding wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Amatsugu committed Oct 5, 2024
1 parent 5adfbd5 commit 5e7ab32
Show file tree
Hide file tree
Showing 15 changed files with 287 additions and 125 deletions.
228 changes: 136 additions & 92 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion engine/asset_loader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ edition = "2021"
[dependencies]
serde = "1.0.204"
serde_json = "1.0.120"
bevy = "0.14.0"
bevy = "0.14.2"
ron = "0.8.1"
2 changes: 1 addition & 1 deletion engine/world_generation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bevy = "0.14.0"
bevy = "0.14.2"
noise = "0.9.0"
serde = { version = "1.0.203", features = ["derive"] }
serde_json = "1.0.115"
Expand Down
2 changes: 1 addition & 1 deletion engine/world_generation/src/hex_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub fn get_tile_count(radius: usize) -> usize {
return 1 + 3 * (radius + 1) * radius;
}

#[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
#[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Hash)]
pub struct HexCoord {
pub hex: IVec3,
}
Expand Down
12 changes: 12 additions & 0 deletions engine/world_generation/src/map/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ pub struct Map {
}

impl Map {
pub fn get_tile_count(&self) -> usize {
return self.get_tile_width() * self.get_tile_height();
}

pub fn get_tile_width(&self) -> usize {
return self.width * Chunk::SIZE;
}

pub fn get_tile_height(&self) -> usize {
return self.height * Chunk::SIZE;
}

pub fn get_chunk_mesh_data(&self, chunk_index: usize) -> MeshChunkData {
#[cfg(feature = "tracing")]
let _spawn_span = info_span!("Chunk Mesh Data").entered();
Expand Down
2 changes: 1 addition & 1 deletion game/buildings/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bevy = "0.14.0"
bevy = "0.14.2"
world_generation = { path = "../../engine/world_generation" }
shared = { path = "../shared" }
bevy_rapier3d = "0.27.0"
Expand Down
2 changes: 1 addition & 1 deletion game/main/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ build = "build.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bevy = { version = "0.14.0", features = ["file_watcher"] }
bevy = { version = "0.14.2", features = ["file_watcher"] }
bevy-inspector-egui = "0.25.0"
iyes_perf_ui = "0.3.0"
noise = "0.8.2"
Expand Down
2 changes: 1 addition & 1 deletion game/shared/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bevy = "0.14.0"
bevy = "0.14.2"
serde = { version = "1.0.204", features = ["derive"] }
world_generation = { path = "../../engine/world_generation" }

Expand Down
4 changes: 3 additions & 1 deletion game/units/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"

[dependencies]
bevy = "0.14.0"
bevy = "0.14.2"
world_generation = { path = "../../engine/world_generation" }
shared = { path = "../shared" }
bevy_rapier3d = "0.27.0"
Expand All @@ -17,6 +17,8 @@ bevy_asset_loader = { version = "0.21.0", features = [
"3d",
] }
quadtree_rs = "0.1.3"
pathfinding = "4.11.0"
ordered-float = "4.3.0"

[features]
tracing = []
3 changes: 2 additions & 1 deletion game/units/src/components.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use bevy::{ecs::world::CommandQueue, prelude::*, tasks::Task};
use serde::{Deserialize, Serialize};
use world_generation::hex_utils::HexCoord;

#[derive(Component, Debug)]
pub struct Unit;
Expand All @@ -19,7 +20,7 @@ pub enum UnitDomain {
}

#[derive(Component, Debug)]
pub struct Target(pub Vec3);
pub struct Target(pub HexCoord);

#[derive(Component, Debug)]
pub struct Path(pub Vec<Vec3>, pub usize);
Expand Down
3 changes: 3 additions & 0 deletions game/units/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@

pub mod assets;
pub mod components;
pub mod nav_data;
pub mod resources;
#[cfg(debug_assertions)]
pub mod units_debug_plugin;
pub mod units_plugin;
Expand Down
70 changes: 70 additions & 0 deletions game/units/src/nav_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use ordered_float::OrderedFloat;
use world_generation::{
hex_utils::HexCoord,
prelude::{Chunk, Map},
};

#[derive(Clone)]
pub struct NavData {
pub tiles: Vec<NavTile>,
pub map_height: usize,
pub map_width: usize,
}

impl NavData {
pub fn get_neighbors(&self, coord: &HexCoord) -> Vec<(HexCoord, OrderedFloat<f32>)> {
let mut neighbors = Vec::with_capacity(6);
for i in 0..6 {
let n = coord.get_neighbor(i);
if !self.is_in_bounds(&n) {
continue;
}
neighbors.push((n, OrderedFloat(1.0)));
}
return neighbors;
}
pub fn get(&self, coord: &HexCoord) -> &NavTile {
return &self.tiles[coord.to_index(self.map_width)];
}

pub fn is_in_bounds(&self, pos: &HexCoord) -> bool {
return pos.is_in_bounds(self.map_height, self.map_width);
}

pub fn build(map: &Map) -> NavData {
let mut tiles = Vec::with_capacity(map.get_tile_count());
let h = map.get_tile_height();
let w = map.get_tile_width();
for y in 0..h {
for x in 0..w {
let coord = HexCoord::from_grid_pos(x, y);
let height = map.sample_height(&coord);
let tile = NavTile {
coord,
height,
move_cost: 1.0,
};
tiles.push(tile);
}
}

return NavData {
tiles,
map_width: w,
map_height: h,
};
}
}

#[derive(Clone)]
pub struct NavTile {
pub height: f32,
pub move_cost: f32,
pub coord: HexCoord,
}

impl NavTile {
pub fn calculate_heuristic(&self, to: &HexCoord) -> OrderedFloat<f32> {
todo!();
}
}
1 change: 1 addition & 0 deletions game/units/src/resources.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use bevy::prelude::*;
2 changes: 1 addition & 1 deletion game/units/src/units_debug_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ fn set_unit_target(
for e in units.iter() {
info!("Setting Target");
let mut e = commands.entity(e);
e.insert(Target(contact.surface));
e.insert(Target(contact.tile));
}
}
}
77 changes: 53 additions & 24 deletions game/units/src/units_plugin.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
use bevy::{
ecs::world::CommandQueue, prelude::*, tasks::AsyncComputeTaskPool, transform::commands, utils::futures,
window::PrimaryWindow,
};
use bevy_asset_loader::loading_state::{
config::{ConfigureLoadingState, LoadingStateConfig},
LoadingStateAppExt,
};
use shared::{resources::TileUnderCursor, sets::GameplaySet, states::AssetLoadState};
use std::collections::HashMap;

use bevy::{ecs::world::CommandQueue, prelude::*, tasks::AsyncComputeTaskPool, utils::futures};
use pathfinding::prelude::astar;
use shared::{resources::TileUnderCursor, sets::GameplaySet};
use world_generation::{hex_utils::HexCoord, prelude::Map};

use crate::{
assets::{unit_asset::UnitAssetPlugin, unit_database::UnitDatabase},
assets::unit_asset::UnitAssetPlugin,
components::{Path, PathTask, Target, Unit},
nav_data::{self, NavData},
units_debug_plugin::UnitsDebugPlugin,
};

Expand All @@ -28,7 +25,10 @@ impl Plugin for UnitsPlugin {

app.add_systems(Update, units_control.in_set(GameplaySet));
app.add_systems(Update, move_unit.in_set(GameplaySet));
app.add_systems(FixedPreUpdate, (calculate_path, resolve_path_task).in_set(GameplaySet));
app.add_systems(
FixedPreUpdate,
(dispatch_path_requests, resolve_path_task).in_set(GameplaySet),
);
}
}

Expand Down Expand Up @@ -60,27 +60,41 @@ fn move_unit(
}
}

fn calculate_path(
fn dispatch_path_requests(
units: Query<(&Transform, &Target, Entity), (With<Unit>, Without<PathTask>)>,
map: Res<Map>,
mut commands: Commands,
) {
let pool = AsyncComputeTaskPool::get();
let mut groups: HashMap<HexCoord, Vec<PathRequest>> = HashMap::new();

for (transform, target, entity) in units.iter() {
let from = transform.translation;
let to = target.0;
let req = PathRequest {
entity,
to: HexCoord::from_world_pos(transform.translation),
};
if let Some(group) = groups.get_mut(&target.0) {
group.push(req);
} else {
groups.insert(target.0, vec![req]);
}
}

let task = pool.spawn(async move {
let mut queue = CommandQueue::default();
let nav_data = NavData::build(&map);

queue.push(move |world: &mut World| {
//todo: calculate path
world.entity_mut(entity).insert(Path(vec![from, to], 0));
let pool = AsyncComputeTaskPool::get();
for (from, units) in groups {
for req in units {
let d = nav_data.clone();
let task = pool.spawn(async move {
let path = calculate_path(&from, &req.to, d);
let mut queue = CommandQueue::default();
queue.push(move |world: &mut World| {
world.entity_mut(req.entity).insert(path);
});
return queue;
});
return queue;
});

commands.entity(entity).insert(PathTask(task)).remove::<Target>();
commands.entity(req.entity).insert(PathTask(task)).remove::<Target>();
}
}
}

Expand All @@ -92,3 +106,18 @@ fn resolve_path_task(mut tasks: Query<(&mut PathTask, Entity), With<Unit>>, mut
}
}
}

fn calculate_path(from: &HexCoord, to: &HexCoord, nav: NavData) -> Path {
let path = astar(
from,
|n| nav.get_neighbors(n),
|n| nav.get(n).calculate_heuristic(to),
|n| n == to,
);
todo!("Convert path");
}

struct PathRequest {
pub entity: Entity,
pub to: HexCoord,
}

0 comments on commit 5e7ab32

Please sign in to comment.