Skip to content

Commit

Permalink
use glam Vec2 instead of custom implementaion
Browse files Browse the repository at this point in the history
  • Loading branch information
klangner committed Jul 26, 2024
1 parent 5661fde commit bba34ea
Show file tree
Hide file tree
Showing 14 changed files with 83 additions and 95 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ edition = "2021"

[dependencies]
fastrand = "2.1"
glam = "0.28"

[workspace]
members = ["demo"]
4 changes: 2 additions & 2 deletions src/cave/drunkard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
//!

use fastrand::Rng;
use glam::UVec2;

use crate::geometry::Vec2u;
use crate::MapFilter;

use super::tile_map::Symmetry;
Expand Down Expand Up @@ -81,7 +81,7 @@ impl DrunkardsWalk {
fn build(&self, rng: &mut Rng, map: &CaveMap) -> CaveMap {
let mut new_map = map.clone();
// Set a central starting point
let starting_position = Vec2u::new(new_map.width / 2, new_map.height / 2);
let starting_position = UVec2::new(new_map.width / 2, new_map.height / 2);
new_map.set_walkable(starting_position.x, starting_position.y, true);

let total_tiles = new_map.width * new_map.height;
Expand Down
25 changes: 16 additions & 9 deletions src/cave/tile_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
//! The MapBuilder builds from this data the Map structure which is more suites for it.
//!

use crate::{
geometry::{diff_abs, Vec2u},
layer::WalkableLayer,
};
use glam::UVec2;

use crate::layer::WalkableLayer;
use std::fmt;

#[derive(PartialEq, Copy, Clone)]
Expand All @@ -27,8 +26,8 @@ pub struct CaveMap {
pub walkable_layer: WalkableLayer,
pub width: u32,
pub height: u32,
pub starting_point: Option<Vec2u>,
pub exit_point: Option<Vec2u>,
pub starting_point: Option<UVec2>,
pub exit_point: Option<UVec2>,
}

impl CaveMap {
Expand Down Expand Up @@ -75,8 +74,8 @@ impl CaveMap {
self.walkable_layer.xy_idx(x, y)
}

pub fn idx_point(&self, idx: usize) -> Vec2u {
Vec2u {
pub fn idx_point(&self, idx: usize) -> UVec2 {
UVec2 {
x: idx as u32 % self.width,
y: idx as u32 / self.width,
}
Expand Down Expand Up @@ -158,6 +157,14 @@ impl fmt::Display for CaveMap {
}
}

fn diff_abs(x: u32, y: u32) -> u32 {
if x >= y {
x - y
} else {
y - x
}
}

/// ------------------------------------------------------------------------------------------------
/// Module unit tests
/// ------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -206,7 +213,7 @@ mod tests {

let idx = map.xy_idx(x, y);

let Vec2u { x: x2, y: y2 } = map.idx_point(idx);
let UVec2 { x: x2, y: y2 } = map.idx_point(idx);

assert_eq!(x, x2);
assert_eq!(y, y2);
Expand Down
10 changes: 5 additions & 5 deletions src/cave/voronoi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
//!

use fastrand::Rng;
use glam::UVec2;

use crate::geometry::Vec2u;
use crate::MapFilter;

use super::CaveMap;
Expand Down Expand Up @@ -43,7 +43,7 @@ impl VoronoiHive {
let mut voronoi_membership: Vec<i32> = vec![0; (map.width * map.height) as usize];
for (i, vid) in voronoi_membership.iter_mut().enumerate() {
for (seed, pos) in seeds.iter().enumerate() {
let distance = pos.distance_to(&map.idx_point(i));
let distance = (pos.as_vec2() - map.idx_point(i).as_vec2()).length();
voronoi_distance[seed] = (seed, distance);
}

Expand Down Expand Up @@ -80,13 +80,13 @@ impl VoronoiHive {
}

/// Generate random seeds
fn generate_seeds(&self, rng: &mut Rng, width: u32, height: u32) -> Vec<Vec2u> {
let mut seeds: Vec<Vec2u> = Vec::new();
fn generate_seeds(&self, rng: &mut Rng, width: u32, height: u32) -> Vec<UVec2> {
let mut seeds: Vec<UVec2> = Vec::new();

while (seeds.len() as u32) < self.n_seeds {
let vx = rng.u32(1..width);
let vy = rng.u32(1..height);
let candidate = Vec2u::new(vx, vy);
let candidate = UVec2::new(vx, vy);
if !seeds.contains(&candidate) {
seeds.push(candidate);
}
Expand Down
42 changes: 4 additions & 38 deletions src/geometry.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,7 @@
//! Support function for 2D geometry
//! Support function for 2D/3D geometry
//!

/// Position on the map
#[derive(Default, PartialEq, Copy, Clone, Debug, Eq, Hash)]
pub struct Vec2u {
pub x: u32,
pub y: u32,
}

impl Vec2u {
/// Create new point
pub fn new(x: u32, y: u32) -> Vec2u {
Vec2u { x, y }
}

/// Euclidean distance to a given point
pub fn distance_to(self, point: &Vec2u) -> f32 {
let a = (self.x as f32 - point.x as f32).powf(2.0);
let b = (self.y as f32 - point.y as f32).powf(2.0);
(a + b).sqrt()
}
}
use glam::UVec2;

/// Rectangle region on the map
#[derive(PartialEq, Copy, Clone, Debug)]
Expand All @@ -46,8 +27,8 @@ impl Rect {
self.x1 <= other.x2 && self.x2 >= other.x1 && self.y1 <= other.y2 && self.y2 >= other.y1
}

pub fn center(&self) -> Vec2u {
Vec2u::new((self.x1 + self.x2) / 2, (self.y1 + self.y2) / 2)
pub fn center(&self) -> UVec2 {
UVec2::new((self.x1 + self.x2) / 2, (self.y1 + self.y2) / 2)
}

pub fn width(&self) -> u32 {
Expand Down Expand Up @@ -75,13 +56,6 @@ impl Rect {
/// assert_eq!(diff_abs(5, 3), 2);
/// assert_eq!(diff_abs(3, 5), 2);
/// ```
pub fn diff_abs(x: u32, y: u32) -> u32 {
if x >= y {
x - y
} else {
y - x
}
}

/// ------------------------------------------------------------------------------------------------
/// Module unit tests
Expand All @@ -90,14 +64,6 @@ pub fn diff_abs(x: u32, y: u32) -> u32 {
mod tests {
use super::*;

#[test]
fn test_distance() {
let p1 = Vec2u::new(10, 10);
let p2 = Vec2u::new(14, 7);
let distance = p1.distance_to(&p2);
assert_eq!(distance, 5.0);
}

#[test]
fn test_intersect() {
let rect1 = Rect::new(10, 10, 40, 40);
Expand Down
6 changes: 3 additions & 3 deletions src/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use std::fmt;

use crate::geometry::Vec2u;
use glam::UVec2;

#[derive(Default, Debug, Clone, PartialEq)]
pub struct WalkableLayer {
Expand Down Expand Up @@ -80,8 +80,8 @@ impl WalkableLayer {
map
}

pub fn idx_point(&self, idx: usize) -> Vec2u {
Vec2u {
pub fn idx_point(&self, idx: usize) -> UVec2 {
UVec2 {
x: idx as u32 % self.width,
y: idx as u32 / self.width,
}
Expand Down
13 changes: 8 additions & 5 deletions src/metric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
//! and the provide generator score as an average.
//!

use crate::{geometry::Vec2u, layer::WalkableLayer, path::DijkstraMap};
use glam::UVec2;

use crate::{layer::WalkableLayer, path::DijkstraMap};

/// This metric calculates the percentage of walkable cells (Floor).
/// If this number is very low (like < 10%) then it means that the map
Expand All @@ -17,7 +19,7 @@ pub fn density(walkable_layer: &WalkableLayer) -> f32 {
/// Calculate the length of the shortes path from the starting point
/// to the exit.
/// If this path is very short, then the map is probably degenerated.
pub fn path_length(map: &WalkableLayer, starting_point: &Vec2u, exit_point: &Vec2u) -> f32 {
pub fn path_length(map: &WalkableLayer, starting_point: &UVec2, exit_point: &UVec2) -> f32 {
let dijkstra = DijkstraMap::new(map, starting_point);
dijkstra.tiles[map.xy_idx(exit_point.x, exit_point.y)]
}
Expand All @@ -27,8 +29,9 @@ pub fn path_length(map: &WalkableLayer, starting_point: &Vec2u, exit_point: &Vec
/// ------------------------------------------------------------------------------------------------
#[cfg(test)]
mod tests {
use glam::UVec2;

use super::*;
use crate::geometry::Vec2u;

#[test]
fn test_density_no_floor() {
Expand Down Expand Up @@ -58,8 +61,8 @@ mod tests {
##########
";
let map = WalkableLayer::from_string(map_str);
let starting_point = Vec2u::new(1, 1);
let exit_point = Vec2u::new(8, 1);
let starting_point = UVec2::new(1, 1);
let exit_point = UVec2::new(8, 1);

let score = path_length(&map, &starting_point, &exit_point);
assert!(f32::abs(score - 7.9) <= 0.01);
Expand Down
14 changes: 7 additions & 7 deletions src/path/dijkstra.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@

use std::collections::VecDeque;

use crate::geometry::Vec2u;
use glam::UVec2;

use crate::layer::WalkableLayer;

/// Representation of a Dijkstra flow map.
Expand All @@ -43,7 +44,7 @@ pub struct DijkstraMap {

impl DijkstraMap {
//! Construct a new Dijkstra map, ready to run.
pub fn new(map: &WalkableLayer, starting_point: &Vec2u) -> DijkstraMap {
pub fn new(map: &WalkableLayer, starting_point: &UVec2) -> DijkstraMap {
let len = (map.width * map.height) as usize;
let tiles = vec![f32::MAX; len];
let mut d = DijkstraMap {
Expand All @@ -61,7 +62,7 @@ impl DijkstraMap {
/// depth is further than the current depth.
/// WARNING: Will give incorrect results when used with non-uniform exit costs. Much slower
/// algorithm required to support that.
fn build(&mut self, map: &WalkableLayer, starting_point: &Vec2u) {
fn build(&mut self, map: &WalkableLayer, starting_point: &UVec2) {
let mapsize = self.size_x * self.size_y;
let mut open_list: VecDeque<((u32, u32), f32)> = VecDeque::with_capacity(mapsize as usize);

Expand Down Expand Up @@ -98,7 +99,6 @@ impl DijkstraMap {
#[cfg(test)]
mod tests {
use super::*;
use crate::geometry::Vec2u;

#[test]
fn test_culling() {
Expand All @@ -108,7 +108,7 @@ mod tests {
##########
";
let map = WalkableLayer::from_string(map_str);
let dm = DijkstraMap::new(&map, &Vec2u::new(8, 1));
let dm = DijkstraMap::new(&map, &UVec2::new(8, 1));

println!(
"{:?}",
Expand Down Expand Up @@ -141,7 +141,7 @@ mod tests {
####
";
let map = WalkableLayer::from_string(map_str);
let starting_point = Vec2u::new(2, 2);
let starting_point = UVec2::new(2, 2);
let dm = DijkstraMap::new(&map, &starting_point);
let expected = [
f32::MAX,
Expand Down Expand Up @@ -174,7 +174,7 @@ mod tests {
##########
";
let map = WalkableLayer::from_string(map_str);
let starting_point = Vec2u::new(8, 2);
let starting_point = UVec2::new(8, 2);
let dm = DijkstraMap::new(&map, &starting_point);
let expected = [
f32::MAX,
Expand Down
11 changes: 7 additions & 4 deletions src/poi/cull_unreachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
//! It will add wall on every tile which is not accessible from the starting point.
//!

use crate::geometry::Vec2u;
use glam::UVec2;

use crate::layer::WalkableLayer;
use crate::path::DijkstraMap;

Expand All @@ -14,7 +15,7 @@ impl CullUnreachable {
Box::new(CullUnreachable {})
}

pub fn remove_walkable_tiles(starting_point: &Vec2u, map: &WalkableLayer) -> WalkableLayer {
pub fn remove_walkable_tiles(starting_point: &UVec2, map: &WalkableLayer) -> WalkableLayer {
let mut new_map = map.clone();

let dijkstra_map = DijkstraMap::new(map, starting_point);
Expand All @@ -36,7 +37,9 @@ impl CullUnreachable {
/// ------------------------------------------------------------------------------------------------
#[cfg(test)]
mod tests {
use crate::{geometry::Vec2u, layer::WalkableLayer, poi::CullUnreachable};
use glam::UVec2;

use crate::{layer::WalkableLayer, poi::CullUnreachable};

#[test]
fn test_culling() {
Expand All @@ -46,7 +49,7 @@ mod tests {
##########
";
let map = WalkableLayer::from_string(map_str);
let starting_point = Vec2u::new(9, 1);
let starting_point = UVec2::new(9, 1);
let expected_map_str = "
##########
#### #
Expand Down
13 changes: 8 additions & 5 deletions src/poi/distant_exit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
//! This module will try to add exit point as far as possible from the starting point.
//!

use crate::geometry::Vec2u;
use glam::UVec2;

use crate::layer::WalkableLayer;
use crate::path::DijkstraMap;
use std::f32;

pub struct DistantExit;

impl DistantExit {
pub fn find(starting_point: &Vec2u, map: &WalkableLayer) -> Vec2u {
pub fn find(starting_point: &UVec2, map: &WalkableLayer) -> UVec2 {
let mut best_idx = 0;
let mut best_value = 0.0;
let dijkstra_map = DijkstraMap::new(map, starting_point);
Expand All @@ -30,7 +31,9 @@ impl DistantExit {
/// ------------------------------------------------------------------------------------------------
#[cfg(test)]
mod tests {
use crate::{geometry::Vec2u, layer::WalkableLayer, poi::DistantExit};
use glam::UVec2;

use crate::{layer::WalkableLayer, poi::DistantExit};

#[test]
fn test_exit() {
Expand All @@ -41,9 +44,9 @@ mod tests {
##########
";
let map = WalkableLayer::from_string(map_str);
let starting_point = Vec2u::new(9, 2);
let starting_point = UVec2::new(9, 2);
let exit_point = DistantExit::find(&starting_point, &map);

assert_eq!(exit_point, Vec2u::new(1, 2));
assert_eq!(exit_point, UVec2::new(1, 2));
}
}
Loading

0 comments on commit bba34ea

Please sign in to comment.