2020-11-04 00:30:47 +00:00
|
|
|
use crate::{
|
|
|
|
block::ZCache,
|
|
|
|
column::ColumnSample,
|
|
|
|
index::IndexRef,
|
2021-03-05 01:23:11 +00:00
|
|
|
land::Land,
|
2021-02-28 23:34:36 +00:00
|
|
|
sim::{SimChunk, WorldSim},
|
2020-11-07 21:50:52 +00:00
|
|
|
util::Grid,
|
|
|
|
};
|
|
|
|
use common::{
|
|
|
|
terrain::{Block, TerrainChunk, TerrainChunkSize},
|
|
|
|
vol::{ReadVol, RectVolSize, WriteVol},
|
2020-11-04 00:30:47 +00:00
|
|
|
};
|
2020-11-07 21:50:52 +00:00
|
|
|
use std::ops::Deref;
|
|
|
|
use vek::*;
|
2020-11-04 00:30:47 +00:00
|
|
|
|
2020-11-07 21:50:52 +00:00
|
|
|
#[derive(Copy, Clone)]
|
2020-11-04 00:30:47 +00:00
|
|
|
pub struct CanvasInfo<'a> {
|
|
|
|
pub(crate) wpos: Vec2<i32>,
|
|
|
|
pub(crate) column_grid: &'a Grid<Option<ZCache<'a>>>,
|
|
|
|
pub(crate) column_grid_border: i32,
|
2021-02-28 23:34:36 +00:00
|
|
|
pub(crate) chunks: &'a WorldSim,
|
2020-11-04 00:30:47 +00:00
|
|
|
pub(crate) index: IndexRef<'a>,
|
2020-11-07 21:50:52 +00:00
|
|
|
pub(crate) chunk: &'a SimChunk,
|
2020-11-04 00:30:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> CanvasInfo<'a> {
|
2020-11-07 21:50:52 +00:00
|
|
|
pub fn wpos(&self) -> Vec2<i32> { self.wpos }
|
2020-11-04 00:30:47 +00:00
|
|
|
|
|
|
|
pub fn area(&self) -> Aabr<i32> {
|
2020-11-07 21:50:52 +00:00
|
|
|
Rect::from((
|
|
|
|
self.wpos(),
|
|
|
|
Extent2::from(TerrainChunkSize::RECT_SIZE.map(|e| e as i32)),
|
|
|
|
))
|
|
|
|
.into()
|
2020-11-04 00:30:47 +00:00
|
|
|
}
|
|
|
|
|
2020-11-07 21:50:52 +00:00
|
|
|
pub fn col(&self, pos: Vec2<i32>) -> Option<&'a ColumnSample> {
|
2020-11-04 00:30:47 +00:00
|
|
|
self.column_grid
|
|
|
|
.get(self.column_grid_border + pos - self.wpos())
|
|
|
|
.map(Option::as_ref)
|
|
|
|
.flatten()
|
|
|
|
.map(|zc| &zc.sample)
|
|
|
|
}
|
|
|
|
|
2020-11-07 21:50:52 +00:00
|
|
|
pub fn index(&self) -> IndexRef<'a> { self.index }
|
|
|
|
|
|
|
|
pub fn chunk(&self) -> &'a SimChunk { self.chunk }
|
|
|
|
|
2021-02-28 23:34:36 +00:00
|
|
|
pub fn chunks(&self) -> &'a WorldSim { self.chunks }
|
|
|
|
|
2021-03-05 01:23:11 +00:00
|
|
|
pub fn land(&self) -> Land<'_> { Land::from_sim(self.chunks) }
|
2020-11-04 00:30:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Canvas<'a> {
|
2020-11-07 21:50:52 +00:00
|
|
|
pub(crate) info: CanvasInfo<'a>,
|
2020-11-04 00:30:47 +00:00
|
|
|
pub(crate) chunk: &'a mut TerrainChunk,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Canvas<'a> {
|
2020-11-07 21:50:52 +00:00
|
|
|
/// The borrow checker complains at immutable features of canvas (column
|
|
|
|
/// sampling, etc.) being used at the same time as mutable features
|
|
|
|
/// (writing blocks). To avoid this, this method extracts the
|
|
|
|
/// inner `CanvasInfo` such that it may be used independently.
|
|
|
|
pub fn info(&mut self) -> CanvasInfo<'a> { self.info }
|
2020-11-04 00:30:47 +00:00
|
|
|
|
2021-03-05 00:40:15 +00:00
|
|
|
pub fn get(&mut self, pos: Vec3<i32>) -> Block {
|
2021-03-05 01:23:11 +00:00
|
|
|
self.chunk
|
|
|
|
.get(pos - self.wpos())
|
|
|
|
.ok()
|
|
|
|
.copied()
|
2021-03-06 17:23:03 +00:00
|
|
|
.unwrap_or_else(Block::empty)
|
2020-11-04 00:30:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set(&mut self, pos: Vec3<i32>, block: Block) {
|
|
|
|
let _ = self.chunk.set(pos - self.wpos(), block);
|
|
|
|
}
|
2020-11-07 21:50:52 +00:00
|
|
|
|
|
|
|
pub fn map(&mut self, pos: Vec3<i32>, f: impl FnOnce(Block) -> Block) {
|
|
|
|
let _ = self.chunk.map(pos - self.wpos(), f);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Execute an operation upon each column in this canvas.
|
|
|
|
pub fn foreach_col(&mut self, mut f: impl FnMut(&mut Self, Vec2<i32>, &ColumnSample)) {
|
|
|
|
for y in 0..self.area().size().h as i32 {
|
|
|
|
for x in 0..self.area().size().w as i32 {
|
|
|
|
let wpos2d = self.wpos() + Vec2::new(x, y);
|
|
|
|
let info = self.info;
|
|
|
|
let col = if let Some(col) = info.col(wpos2d) {
|
|
|
|
col
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
f(self, wpos2d, col);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Deref for Canvas<'a> {
|
|
|
|
type Target = CanvasInfo<'a>;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target { &self.info }
|
2020-11-04 00:30:47 +00:00
|
|
|
}
|