1use crate::{
2 ColumnSample, IndexRef,
3 column::ColumnGen,
4 sim::{self, SimChunk},
5 util::Sampler,
6};
7use common::{terrain::TerrainChunkSize, vol::RectVolSize};
8use vek::*;
9
10pub struct Land<'a> {
13 sim: Option<&'a sim::WorldSim>,
14}
15
16impl<'a> Land<'a> {
17 pub fn empty() -> Self { Self { sim: None } }
18
19 pub fn size(&self) -> Vec2<u32> { self.sim.map_or(Vec2::one(), |s| s.get_size()) }
20
21 pub fn from_sim(sim: &'a sim::WorldSim) -> Self { Self { sim: Some(sim) } }
22
23 pub fn get_interpolated<T>(&self, wpos: Vec2<i32>, f: impl FnMut(&SimChunk) -> T) -> T
24 where
25 T: Copy + Default + std::ops::Add<Output = T> + std::ops::Mul<f32, Output = T>,
26 {
27 self.sim
28 .and_then(|sim| sim.get_interpolated(wpos, f))
29 .unwrap_or_default()
30 }
31
32 pub fn get_surface_alt_approx(&self, wpos: Vec2<i32>) -> f32 {
34 self.sim
35 .map(|sim| sim.get_surface_alt_approx(wpos))
36 .unwrap_or(0.0)
37 }
38
39 pub fn get_alt_approx(&self, wpos: Vec2<i32>) -> f32 {
40 self.sim
41 .and_then(|sim| sim.get_alt_approx(wpos))
42 .unwrap_or(0.0)
43 }
44
45 pub fn get_downhill(&self, wpos: Vec2<i32>) -> Vec2<i32> {
46 self.sim
47 .and_then(|sim| sim.get_wpos(wpos))
48 .and_then(|c| c.downhill)
49 .unwrap_or(Vec2::zero())
50 }
51
52 pub fn get_gradient_approx(&self, wpos: Vec2<i32>) -> f32 {
53 self.sim
54 .and_then(|sim| sim.get_gradient_approx(self.wpos_chunk_pos(wpos)))
55 .unwrap_or(0.0)
56 }
57
58 pub fn wpos_chunk_pos(&self, wpos: Vec2<i32>) -> Vec2<i32> {
59 wpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz| e.div_euclid(sz as i32))
60 }
61
62 pub fn get_chunk(&self, chunk_pos: Vec2<i32>) -> Option<&sim::SimChunk> {
63 self.sim.and_then(|sim| sim.get(chunk_pos))
64 }
65
66 pub fn get_chunk_wpos(&self, wpos: Vec2<i32>) -> Option<&sim::SimChunk> {
67 self.sim.and_then(|sim| sim.get_wpos(wpos))
68 }
69
70 pub fn get_nearest_path(
71 &self,
72 wpos: Vec2<i32>,
73 ) -> Option<(f32, Vec2<f32>, sim::Path, Vec2<f32>)> {
74 self.sim.and_then(|sim| sim.get_nearest_path(wpos))
75 }
76
77 pub fn column_sample<'sample>(
78 &'sample self,
79 wpos: Vec2<i32>,
80 index: IndexRef<'sample>,
81 ) -> Option<ColumnSample<'sample>> {
82 self.sim
83 .and_then(|sim| ColumnGen::new(sim).get((wpos, index, None)))
84 }
85}