summaryrefslogtreecommitdiff
path: root/src/proc_gen/herringbone.rs
diff options
context:
space:
mode:
authorKai Stevenson <kai@kaistevenson.com>2026-08-31 00:03:32 -0700
committerKai Stevenson <kai@kaistevenson.com>2026-08-31 00:03:32 -0700
commitd68cf09f7b8e5cb783dc495097c17eaf2a4d5427 (patch)
tree59216cae8c466ad63fa6ff47dc5c7f35c64c23d2 /src/proc_gen/herringbone.rs
parent8e128d3ca24fa10dc7d871f7daf6c43eaddc385c (diff)
Diffstat (limited to 'src/proc_gen/herringbone.rs')
-rw-r--r--src/proc_gen/herringbone.rs113
1 files changed, 16 insertions, 97 deletions
diff --git a/src/proc_gen/herringbone.rs b/src/proc_gen/herringbone.rs
index 271b7a1..e8569c8 100644
--- a/src/proc_gen/herringbone.rs
+++ b/src/proc_gen/herringbone.rs
@@ -1,111 +1,30 @@
use fxhash::hash32;
use glam::IVec2;
-use crate::{
- config::TILESET_SCALING,
- proc_gen::tileset_loader::{Tile, TileOrientation, Tileset, TilesetPixelType},
-};
+use crate::proc_gen::tileset_loader::TileOrientation;
-pub fn split_position(world: IVec2, tileset: &Tileset) -> (IVec2, IVec2, TileOrientation) {
- let s = tileset.dimensions.short as i32;
- let tx = world.x.div_euclid(s);
- let ty = world.y.div_euclid(s);
- let fx = world.x.rem_euclid(s);
- let fy = world.y.rem_euclid(s);
-
- match (tx - ty).rem_euclid(4) {
- // left half of horizontal tile
- 0 => (
- IVec2::new(tx, ty),
- IVec2::new(fx, fy),
- TileOrientation::Horizontal,
- ),
- // right half of horizontal tile
- 1 => (
- IVec2::new(tx - 1, ty),
- IVec2::new(fx + s, fy),
- TileOrientation::Horizontal,
- ),
- // top half of vertical tile
- 3 => (
- IVec2::new(tx, ty),
- IVec2::new(fx, fy),
- TileOrientation::Vertical,
- ),
- // bottom half of vertical tile
- 2 => (
- IVec2::new(tx, ty - 1),
- IVec2::new(fx, fy + s),
- TileOrientation::Vertical,
- ),
- _ => unreachable!(),
+fn tile_starting_at(grid: IVec2) -> Option<TileOrientation> {
+ match (grid.x - grid.y).rem_euclid(4) {
+ // 1 is the right half of the horizontal tile starting at 0,
+ // 2 is the bottom half of the vertical tile starting at 3
+ 0 => Some(TileOrientation::Horizontal),
+ 3 => Some(TileOrientation::Vertical),
+ _ => None,
}
}
+pub fn tiles_overlapping(min: IVec2, max: IVec2) -> impl Iterator<Item = (IVec2, TileOrientation)> {
+ ((min.y - 1)..max.y)
+ .flat_map(move |y| ((min.x - 1)..max.x).map(move |x| IVec2::new(x, y)))
+ .filter_map(|grid| tile_starting_at(grid).map(|orientation| (grid, orientation)))
+}
+
// better "%" for hashes since it prefers the high bits
#[inline]
fn reduce(h: u32, n: usize) -> usize {
(((h as u128) * (n as u128)) >> 32) as usize
}
-fn pick_variant(tile_pos: IVec2, orientation: TileOrientation, tileset: &Tileset) -> &Tile {
- let h = hash32(&tile_pos);
- match orientation {
- TileOrientation::Horizontal => {
- &tileset.horizontal_tiles[reduce(h, tileset.horizontal_tiles.len())]
- }
- TileOrientation::Vertical => {
- &tileset.vertical_tiles[reduce(h, tileset.vertical_tiles.len())]
- }
- }
-}
-
-// TODO: optimize
-fn get_pixel_at_position(world: IVec2, tileset: &Tileset) -> TilesetPixelType {
- let scaled_world = world.div_euclid(IVec2::new(TILESET_SCALING, TILESET_SCALING));
- let (tile_pos, local, orientation) = split_position(scaled_world, tileset);
- let tile = pick_variant(tile_pos, orientation, tileset);
- let width = match orientation {
- TileOrientation::Horizontal => tileset.dimensions.long as i32,
- TileOrientation::Vertical => tileset.dimensions.short as i32,
- };
- tile.pixels[(local.x + local.y * width) as usize]
+pub fn variant_index(grid: IVec2, variants: usize) -> usize {
+ reduce(hash32(&grid), variants)
}
-
-pub fn tiles_overlapping(
- a: IVec2,
- b: IVec2,
- tileset: &Tileset,
-) -> impl Iterator<Item = (IVec2, &Tile, TileOrientation)> {
- let s = IVec2::new(
- tileset.dimensions.short as i32,
- tileset.dimensions.short as i32,
- );
-
- let ta = a.div_euclid(s) - 1;
- let tb = (b - 1).div_euclid(s);
-
- (ta.y..=tb.y)
- .flat_map(move |ty| (ta.x..=tb.x).map(move |tx| (tx, ty)))
- .filter_map(move |(tx, ty)| match (tx - ty).rem_euclid(4) {
- 0 => Some((
- IVec2::new(tx, ty),
- pick_variant(IVec2::new(tx, ty), TileOrientation::Horizontal, tileset),
- TileOrientation::Horizontal,
- )),
- 3 => Some((
- IVec2::new(tx, ty),
- pick_variant(IVec2::new(tx, ty), TileOrientation::Vertical, tileset),
- TileOrientation::Vertical,
- )),
- _ => None,
- })
-}
-
-// pub fn get_cell_at_position(world: IVec2, tileset: &Tileset) -> Cell {
-// let pixel = get_pixel_at_position(world, tileset);
-// match pixel {
-// TilesetPixelType::Void => Cell::void(),
-// TilesetPixelType::Terrain => Cell::from_material(MaterialId::Dirt),
-// }
-// }