minedmap/tile_renderer: add coord_offset() helper

This commit is contained in:
Matthias Schiffer 2023-08-02 21:51:59 +02:00
parent 35bbd167ba
commit dee00e7a02
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C

View file

@ -4,6 +4,7 @@ use std::{
}; };
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use num_integer::div_mod_floor;
use minedmap::{ use minedmap::{
io::{fs, storage}, io::{fs, storage},
@ -13,6 +14,29 @@ use minedmap::{
use super::{common::*, region_group::RegionGroup}; use super::{common::*, region_group::RegionGroup};
/// Offsets a chunk and block coordinate pair by a number of blocks
///
/// As the new coordinate may end up in a different region, a region offset
/// is returned together with the new chunk and block coordinates.
fn coord_offset<const AXIS: u8>(
chunk: ChunkCoord<AXIS>,
block: BlockCoord<AXIS>,
offset: i32,
) -> (i8, ChunkCoord<AXIS>, BlockCoord<AXIS>) {
const CHUNKS: i32 = CHUNKS_PER_REGION as i32;
const BLOCKS: i32 = BLOCKS_PER_CHUNK as i32;
let coord = chunk.0 as i32 * BLOCKS + block.0 as i32 + offset;
let (region_chunk, block) = div_mod_floor(coord, BLOCKS);
let (region, chunk) = div_mod_floor(region_chunk, CHUNKS);
(
region
.try_into()
.expect("the region coordinate should be in the valid range"),
ChunkCoord::new(chunk),
BlockCoord::new(block),
)
}
pub struct TileRenderer<'a> { pub struct TileRenderer<'a> {
config: &'a Config, config: &'a Config,
} }
@ -147,3 +171,37 @@ impl<'a> TileRenderer<'a> {
Ok(()) Ok(())
} }
} }
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_coord_offset() {
const CHUNKS: i32 = CHUNKS_PER_REGION as i32;
const BLOCKS: i32 = BLOCKS_PER_CHUNK as i32;
for chunk in ChunkX::iter() {
for block in BlockX::iter() {
assert_eq!(coord_offset(chunk, block, 0), (0, chunk, block));
assert_eq!(
coord_offset(chunk, block, -(CHUNKS * BLOCKS)),
(-1, chunk, block)
);
assert_eq!(
coord_offset(chunk, block, CHUNKS * BLOCKS),
(1, chunk, block)
);
for offset in -(CHUNKS * BLOCKS)..(CHUNKS * BLOCKS) {
let (region2, chunk2, block2) = coord_offset(chunk, block, offset);
assert!((-1..=1).contains(&region2));
let coord = chunk.0 as i32 * BLOCKS + block.0 as i32 + offset;
let coord2 =
((region2 as i32 * CHUNKS) + chunk2.0 as i32) * BLOCKS + block2.0 as i32;
assert_eq!(coord2, coord);
}
}
}
}
}