Skip to content

Commit f4a5707

Browse files
committed
cli
1 parent 2425852 commit f4a5707

File tree

6 files changed

+239
-227
lines changed

6 files changed

+239
-227
lines changed

navpointmatrixcli/README.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Navpoint Matrix CLI
2+
3+
## Build Connected Nodes
4+
- `cargo run --bin navpointmatrixcli -- connected-nodes-from-navpoint-matrix --input "C:\Users\Benni\Patrician 3_workbench\navdata\matrix_int.dat" --output ./connected_nodes.navpointmatrix.dat`
5+
- `cargo run --bin navpointmatrixcli -- connected-nodes-from-navigation-data --navigation-matrix "C:\Users\Benni\Patrician 3_workbench\navdata\nav_matrix.dat" --navigation-vector "C:\Users\Benni\Patrician 3_workbench\navdata\nav_vec.dat" --output ./connected_nodes.navpointdata.dat`
6+
7+
## Build Navpoint Matrix
8+
- `cargo run --release --bin navpointmatrixcli -- navpoint-matrix --navigation-vector "C:\Users\Benni\Patrician 3_workbench\navdata\nav_vec.dat" --connected-nodes .\connected_nodes.navpointmatrix.dat --output ./matrix_int.dat`

navpointmatrixcli/src/cli.rs

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
use std::path::PathBuf;
2+
3+
use clap::{Args, Parser, Subcommand};
4+
5+
/// Patrician 3 navpoint matrix calculation
6+
#[derive(Parser, Debug)]
7+
#[command(version, about, long_about = None)]
8+
pub struct Cli {
9+
#[command(subcommand)]
10+
pub command: Command,
11+
}
12+
13+
#[derive(Subcommand, Debug)]
14+
pub enum Command {
15+
Test,
16+
ConnectedNodesFromNavpointMatrix(ConnectedNodesFromNavpointMatrixArgs),
17+
ConnectedNodesFromNavigationData(ConnectedNodesFromNavigationDataArgs),
18+
NavpointMatrix(BuildNavpointMatrixArgs),
19+
}
20+
21+
#[derive(Args, Debug)]
22+
pub struct BuildNavpointMatrixArgs {
23+
/// Path to the connected nodes file
24+
#[arg(long = "connected-nodes", value_name = "connected-nodes-file")]
25+
pub connected_nodes_file: PathBuf,
26+
27+
/// Path to the navigation vector file
28+
#[arg(long = "navigation-vector", value_name = "navigation-vector-file")]
29+
pub navigation_vector_file: PathBuf,
30+
31+
/// Path to the output navpoint matrix file
32+
#[arg(long = "output", value_name = "output-file")]
33+
pub output_file: PathBuf,
34+
}
35+
36+
#[derive(Args, Debug)]
37+
pub struct ConnectedNodesFromNavpointMatrixArgs {
38+
/// Path to the input navpoint matrix file
39+
#[arg(long = "input", value_name = "input-file")]
40+
pub navpoint_matrix_file: PathBuf,
41+
42+
/// Path to the output connected nodes file
43+
#[arg(long = "output", value_name = "output-file")]
44+
pub output_file: PathBuf,
45+
}
46+
47+
#[derive(Args, Debug)]
48+
pub struct ConnectedNodesFromNavigationDataArgs {
49+
/// Path to the input navigation matrix file
50+
#[arg(long = "navigation-matrix", value_name = "navigation-matrix-file")]
51+
pub navigation_matrix_file: PathBuf,
52+
53+
/// Path to the input navigation vector file
54+
#[arg(long = "navigation-vector", value_name = "navigation-vector-file")]
55+
pub navigation_vector_file: PathBuf,
56+
57+
/// Path to the output connected nodes file
58+
#[arg(long = "output", value_name = "output-file")]
59+
pub output_file: PathBuf,
60+
}
+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
use p3_api::data::{navigation_matrix::NavigationMatrix, navigation_vector::NavigationVector, navpoint_matrix::NavpointMatrix};
2+
3+
pub struct ConnectedNodes {
4+
pub connected_nodes: Vec<(u16, u16)>,
5+
}
6+
7+
impl ConnectedNodes {
8+
pub fn serialize(&self) -> Vec<u8> {
9+
let mut buf = vec![];
10+
for pair in &self.connected_nodes {
11+
buf.extend_from_slice(&pair.0.to_le_bytes());
12+
buf.extend_from_slice(&pair.1.to_le_bytes());
13+
}
14+
buf
15+
}
16+
17+
pub fn deserialize(data: &[u8]) -> Self {
18+
let len = data.len() / 4;
19+
let mut connected_nodes = Vec::with_capacity(len);
20+
for i in 0..len {
21+
let source = u16::from_le_bytes(data[i * 4..i * 4 + 2].try_into().unwrap());
22+
let destination = u16::from_le_bytes(data[i * 4 + 2..i * 4 + 4].try_into().unwrap());
23+
connected_nodes.push((source, destination));
24+
}
25+
26+
Self { connected_nodes }
27+
}
28+
29+
pub fn get_neighbours(&self, node_index: u16, nav_vec: &NavigationVector) -> Vec<(u16, i32)> {
30+
let mut neighbours = vec![];
31+
for n in &self.connected_nodes {
32+
if n.0 == node_index {
33+
neighbours.push((n.1, nav_vec.get_path_length(&[n.0 as _, n.1 as _])));
34+
}
35+
}
36+
37+
neighbours
38+
}
39+
40+
pub fn from_navigation_matrix(navigation_vector: &NavigationVector, navigation_matrix: &NavigationMatrix) -> Self {
41+
let mut nodes = vec![];
42+
for (source_index, source) in navigation_vector.points.iter().enumerate() {
43+
println!("Calculating neighbours for node {source_index}");
44+
for (destination_index, destination) in navigation_vector.points.iter().enumerate() {
45+
if is_connected(*source, *destination, navigation_matrix) {
46+
nodes.push((source_index as _, destination_index as _))
47+
}
48+
}
49+
}
50+
51+
ConnectedNodes { connected_nodes: nodes }
52+
}
53+
54+
pub fn from_navpoint_matrix(navpoint_matrix: &NavpointMatrix) -> Self {
55+
let mut nodes = vec![];
56+
let nodes_count = navpoint_matrix.matrix.len().isqrt();
57+
for source_index in 0..nodes_count {
58+
for destination_index in 0..nodes_count {
59+
let cell = &navpoint_matrix.matrix[source_index * nodes_count + destination_index];
60+
if cell.next == destination_index as u16 {
61+
nodes.push((source_index as _, destination_index as _));
62+
}
63+
}
64+
}
65+
ConnectedNodes { connected_nodes: nodes }
66+
}
67+
}
68+
69+
fn is_connected(p0: (i16, i16), p1: (i16, i16), navigation_matrix: &NavigationMatrix) -> bool {
70+
if p0 == p1 {
71+
return true;
72+
}
73+
74+
// Bresenham's Line Algorithm
75+
let (mut x0, mut y0) = p0;
76+
let (x1, y1) = p1;
77+
let dx = (x1 - x0).abs();
78+
let sx = if x0 < x1 { 1 } else { -1 };
79+
let dy = -(y1 - y0).abs();
80+
let sy = if y0 < y1 { 1 } else { -1 };
81+
let mut error = dx + dy;
82+
loop {
83+
if navigation_matrix.data[x0 as usize + navigation_matrix.width as usize * y0 as usize] == 1 {
84+
return false;
85+
}
86+
let e2 = 2 * error;
87+
if e2 >= dy {
88+
if x0 == x1 {
89+
break;
90+
}
91+
error += dy;
92+
x0 += sx;
93+
}
94+
if e2 <= dx {
95+
if y0 == y1 {
96+
break;
97+
}
98+
error += dx;
99+
y0 += sy;
100+
}
101+
}
102+
103+
navigation_matrix.data[x0 as usize + navigation_matrix.width as usize * y0 as usize] == 0
104+
}

0 commit comments

Comments
 (0)