Skip to content

Commit 2d7be3a

Browse files
authored
feat: integrate a* and pathfinding service (#259)
1 parent f37aed6 commit 2d7be3a

7 files changed

Lines changed: 558 additions & 10 deletions

File tree

Cargo.lock

Lines changed: 50 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

projects/ai-pathfinding.md

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ The visualization successfully displays:
166166

167167
## Phase 3: A* Pathfinding Integration
168168

169-
**Goal**: Implement pathfinding using the `pathfinding` crate to find routes through the cell graph.
169+
**Goal**: Implement pathfinding using the `pathfinding` crate to find routes through the cell graph with interactive testing.
170170

171171
### Dependencies
172172

@@ -179,9 +179,12 @@ pathfinding = "4"
179179

180180
| File | Action | Purpose |
181181
|------|--------|---------|
182-
| `shock2vr/src/pathfinding/mod.rs` | Create | Pathfinding service and queries |
182+
| `shock2vr/src/pathfinding/mod.rs` | Create | PathfindingService and AIPATH cell queries |
183183
| `shock2vr/src/pathfinding/cell_graph.rs` | Create | Graph adapter for pathfinding crate |
184+
| `shock2vr/src/pathfinding/path_visualization.rs` | Create | Multi-path visualization system |
184185
| `shock2vr/src/lib.rs` | Modify | Add pathfinding module |
186+
| `runtimes/desktop_runtime/src/main.rs` | Modify | Add P key for interactive pathfinding test |
187+
| `runtimes/debug_runtime/src/main.rs` | Modify | Add HTTP pathfinding-test commands |
185188

186189
### Core API Design
187190

@@ -193,7 +196,8 @@ pub struct PathfindingService {
193196
}
194197

195198
impl PathfindingService {
196-
/// Find the cell containing a world position
199+
/// Find the AIPATH cell containing a world position
200+
/// Uses simple point-in-polygon tests (can be optimized later)
197201
pub fn cell_from_position(&self, pos: Vector3<f32>) -> Option<u32>;
198202

199203
/// Find path from start position to goal position
@@ -216,6 +220,54 @@ impl PathfindingService {
216220
}
217221
```
218222

223+
### Interactive Pathfinding Test System
224+
225+
**Desktop Runtime (P Key):**
226+
- **Press 1**: Set start position (player location), show green marker
227+
- **Press 2**: Set goal position (player location), compute A* path, show green path
228+
- **Press 3**: Reset/clear all markers and test paths
229+
230+
**Debug Runtime (HTTP Commands):**
231+
```bash
232+
# Set start position to player's current location
233+
curl -X POST http://127.0.0.1:8080/v1/pathfinding-test -d '{"action": "set_start"}'
234+
235+
# Set goal position and compute path
236+
curl -X POST http://127.0.0.1:8080/v1/pathfinding-test -d '{"action": "set_goal"}'
237+
238+
# Clear test data
239+
curl -X POST http://127.0.0.1:8080/v1/pathfinding-test -d '{"action": "reset"}'
240+
```
241+
242+
### Multi-Path Visualization System
243+
244+
```rust
245+
// shock2vr/src/pathfinding/path_visualization.rs
246+
247+
pub struct PathVisualizationSystem {
248+
pub paths: HashMap<String, ComputedPath>,
249+
}
250+
251+
pub struct ComputedPath {
252+
pub waypoints: Vec<Vector3<f32>>,
253+
pub color: Vector3<f32>, // Green for test, different colors for AI
254+
pub name: String, // "test_path", "grunt_1_path", etc.
255+
pub markers: Vec<PathMarker>, // Start/goal markers
256+
}
257+
258+
pub struct PathMarker {
259+
pub position: Vector3<f32>,
260+
pub marker_type: MarkerType, // Start, Goal, Waypoint
261+
pub color: Vector3<f32>,
262+
}
263+
```
264+
265+
This design supports:
266+
- **Interactive testing** before AI integration
267+
- **Multiple simultaneous paths** for different AI entities
268+
- **Easy switching** between spatial query strategies
269+
- **Flexible visualization** with named paths and custom colors
270+
219271
### Implementation Steps
220272

221273
1. **Create pathfinding module structure**

shock2vr/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ num-derive = "0.3.3"
2323
num-traits = "0.2.15"
2424
once_cell = "1.17.0"
2525
ordered-float = "3.4.0"
26+
pathfinding = "4"
2627
pcx = "0.2.3"
2728
rapier3d = { version = "0.19.0", features = ["debug-render"] }
2829
serde_json = "1.0.91"

shock2vr/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ mod creature;
1212
mod gui;
1313
mod hud;
1414
mod mission;
15+
pub mod pathfinding;
1516
pub mod paths;
1617
mod physics;
1718
mod quest_info;

shock2vr/src/mission/pathfinding_debug.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
use crate::creature::HUMAN_HEIGHT;
12
/// Pathfinding debug visualization for AI navigation mesh
23
use cgmath::Vector3;
34
use dark::mission::PathDatabase;
45
use engine::scene::{SceneObject, VertexPosition, color_material, lines_mesh};
56

7+
/// Height offset for pathfinding visualization - center of human height
8+
const PATH_NODE_HEIGHT: f32 = HUMAN_HEIGHT / 2.0;
9+
610
/// Renders pathfinding visualization as scene objects
711
///
812
/// Creates cyan lines for navigation cells and polygons, and yellow lines for cell links.
@@ -14,9 +18,9 @@ pub fn render_pathfinding_debug(path_database: &PathDatabase) -> Vec<SceneObject
1418

1519
// Render path cells as cyan polygons and center crosses
1620
for cell in &path_database.cells {
17-
let center = cell.center;
21+
let center = cell.center + Vector3::new(0.0, PATH_NODE_HEIGHT, 0.0);
1822

19-
// Create a small cross at the center
23+
// Create a small cross at the center (raised to human eye level)
2024
let size = 0.1;
2125
cyan_lines.push(VertexPosition {
2226
position: Vector3::new(center.x - size, center.y, center.z),
@@ -66,14 +70,16 @@ pub fn render_pathfinding_debug(path_database: &PathDatabase) -> Vec<SceneObject
6670
let to_cell_idx = link.to_cell as usize;
6771

6872
if from_cell_idx < path_database.cells.len() && to_cell_idx < path_database.cells.len() {
69-
let from_center = &path_database.cells[from_cell_idx].center;
70-
let to_center = &path_database.cells[to_cell_idx].center;
73+
let from_center = path_database.cells[from_cell_idx].center
74+
+ Vector3::new(0.0, PATH_NODE_HEIGHT, 0.0);
75+
let to_center =
76+
path_database.cells[to_cell_idx].center + Vector3::new(0.0, PATH_NODE_HEIGHT, 0.0);
7177

7278
yellow_lines.push(VertexPosition {
73-
position: Vector3::new(from_center.x, from_center.y, from_center.z),
79+
position: from_center,
7480
});
7581
yellow_lines.push(VertexPosition {
76-
position: Vector3::new(to_center.x, to_center.y, to_center.z),
82+
position: to_center,
7783
});
7884
}
7985
}

0 commit comments

Comments
 (0)