mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
common, voxygen: Introduce traits RasterableVol
, RectRasterableVol
* `RasterableVol` represents a volume that is compile-time sized and has its lower bound at `(0, 0, 0)`. The name `RasterableVol` was chosen because such a volume can be used with `VolGrid3d`. * `RectRasterableVol` represents a volume that is compile-time sized at least in x and y direction and has its lower bound at `(0, 0, z)`. On the lower bound in z direction, there's no restriction. An `RectRasterableVol` can be used with `VolGrid2d`.
This commit is contained in:
parent
28c5886841
commit
9a488c4a25
@ -13,7 +13,7 @@ use common::{
|
||||
net::PostBox,
|
||||
state::{State, Uid},
|
||||
terrain::{block::Block, TerrainChunk, TerrainChunkSize},
|
||||
vol::VolSize,
|
||||
vol::RectVolSize,
|
||||
ChatType,
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
@ -207,7 +207,7 @@ impl Client {
|
||||
.cloned()?
|
||||
.0,
|
||||
)
|
||||
.map2(Vec2::from(TerrainChunkSize::SIZE), |e: f32, sz| {
|
||||
.map2(TerrainChunkSize::RECT_SIZE, |e: f32, sz| {
|
||||
(e as u32).div_euclid(sz) as i32
|
||||
});
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::{
|
||||
vol::{
|
||||
BaseVol, DefaultVolIterator, IntoVolIterator, ReadVol, SizedVol, VolSize, Vox, WriteVol,
|
||||
BaseVol, DefaultVolIterator, IntoVolIterator, ReadVol, RectRasterableVol, RectVolSize,
|
||||
SizedVol, VolSize, Vox, WriteVol,
|
||||
},
|
||||
volumes::{
|
||||
chunk::{Chunk, ChunkError},
|
||||
@ -18,23 +19,24 @@ pub enum ChonkError {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct SubChunkSize<ChonkSize: VolSize> {
|
||||
pub struct SubChunkSize<ChonkSize: RectVolSize> {
|
||||
phantom: PhantomData<ChonkSize>,
|
||||
}
|
||||
// TODO (haslersn): Assert ChonkSize::SIZE.x == ChonkSize::SIZE.y
|
||||
|
||||
impl<ChonkSize: VolSize> VolSize for SubChunkSize<ChonkSize> {
|
||||
// TODO (haslersn): Assert ChonkSize::RECT_SIZE.x == ChonkSize::RECT_SIZE.y
|
||||
|
||||
impl<ChonkSize: RectVolSize> VolSize for SubChunkSize<ChonkSize> {
|
||||
const SIZE: Vec3<u32> = Vec3 {
|
||||
x: ChonkSize::SIZE.x,
|
||||
y: ChonkSize::SIZE.x,
|
||||
z: ChonkSize::SIZE.x / 2,
|
||||
x: ChonkSize::RECT_SIZE.x,
|
||||
y: ChonkSize::RECT_SIZE.x,
|
||||
z: ChonkSize::RECT_SIZE.x / 2,
|
||||
};
|
||||
}
|
||||
|
||||
type SubChunk<V, S, M> = Chunk<V, SubChunkSize<S>, M>;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Chonk<V: Vox, S: VolSize, M: Clone> {
|
||||
pub struct Chonk<V: Vox, S: RectVolSize, M: Clone> {
|
||||
z_offset: i32,
|
||||
sub_chunks: Vec<SubChunk<V, S, M>>,
|
||||
below: V,
|
||||
@ -43,7 +45,7 @@ pub struct Chonk<V: Vox, S: VolSize, M: Clone> {
|
||||
phantom: PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<V: Vox, S: VolSize, M: Clone> Chonk<V, S, M> {
|
||||
impl<V: Vox, S: RectVolSize, M: Clone> Chonk<V, S, M> {
|
||||
pub fn new(z_offset: i32, below: V, above: V, meta: M) -> Self {
|
||||
Self {
|
||||
z_offset,
|
||||
@ -86,24 +88,16 @@ impl<V: Vox, S: VolSize, M: Clone> Chonk<V, S, M> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Vox, S: VolSize, M: Clone> BaseVol for Chonk<V, S, M> {
|
||||
impl<V: Vox, S: RectVolSize, M: Clone> BaseVol for Chonk<V, S, M> {
|
||||
type Vox = V;
|
||||
type Error = ChonkError;
|
||||
}
|
||||
|
||||
impl<V: Vox, S: VolSize, M: Clone> SizedVol for Chonk<V, S, M> {
|
||||
#[inline(always)]
|
||||
fn lower_bound(&self) -> Vec3<i32> {
|
||||
Vec3::zero()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn upper_bound(&self) -> Vec3<i32> {
|
||||
S::SIZE.map(|e| e as i32)
|
||||
}
|
||||
impl<V: Vox, S: RectVolSize, M: Clone> RectRasterableVol for Chonk<V, S, M> {
|
||||
const RECT_SIZE: Vec2<u32> = S::RECT_SIZE;
|
||||
}
|
||||
|
||||
impl<V: Vox, S: VolSize, M: Clone> ReadVol for Chonk<V, S, M> {
|
||||
impl<V: Vox, S: RectVolSize, M: Clone> ReadVol for Chonk<V, S, M> {
|
||||
#[inline(always)]
|
||||
fn get(&self, pos: Vec3<i32>) -> Result<&V, Self::Error> {
|
||||
if pos.z < self.get_min_z() {
|
||||
@ -125,7 +119,7 @@ impl<V: Vox, S: VolSize, M: Clone> ReadVol for Chonk<V, S, M> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Vox, S: VolSize, M: Clone> WriteVol for Chonk<V, S, M> {
|
||||
impl<V: Vox, S: RectVolSize, M: Clone> WriteVol for Chonk<V, S, M> {
|
||||
#[inline(always)]
|
||||
fn set(&mut self, pos: Vec3<i32>, block: Self::Vox) -> Result<(), Self::Error> {
|
||||
let mut sub_chunk_idx = self.sub_chunk_idx(pos.z);
|
||||
@ -152,18 +146,18 @@ impl<V: Vox, S: VolSize, M: Clone> WriteVol for Chonk<V, S, M> {
|
||||
}
|
||||
}
|
||||
|
||||
struct OuterChonkIter<'a, V: Vox, S: VolSize, M: Clone> {
|
||||
struct OuterChonkIter<'a, V: Vox, S: RectVolSize, M: Clone> {
|
||||
chonk: &'a Chonk<V, S, M>,
|
||||
lower_bound: Vec3<i32>,
|
||||
upper_bound: Vec3<i32>,
|
||||
}
|
||||
|
||||
enum OuterChonkIterItem<'a, V: Vox, S: VolSize, M: Clone> {
|
||||
enum OuterChonkIterItem<'a, V: Vox, S: RectVolSize, M: Clone> {
|
||||
ChunkIter(<&'a SubChunk<V, S, M> as IntoVolIterator<'a>>::IntoIter),
|
||||
DefaultIter((&'a V, MortonIter)),
|
||||
}
|
||||
|
||||
impl<'a, V: Vox, S: VolSize, M: Clone> Iterator for OuterChonkIter<'a, V, S, M> {
|
||||
impl<'a, V: Vox, S: RectVolSize, M: Clone> Iterator for OuterChonkIter<'a, V, S, M> {
|
||||
type Item = OuterChonkIterItem<'a, V, S, M>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
@ -195,12 +189,12 @@ impl<'a, V: Vox, S: VolSize, M: Clone> Iterator for OuterChonkIter<'a, V, S, M>
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChonkIter<'a, V: Vox, S: VolSize, M: Clone> {
|
||||
pub struct ChonkIter<'a, V: Vox, S: RectVolSize, M: Clone> {
|
||||
outer: OuterChonkIter<'a, V, S, M>,
|
||||
opt_inner: Option<OuterChonkIterItem<'a, V, S, M>>,
|
||||
}
|
||||
|
||||
impl<'a, V: Vox, S: VolSize, M: Clone> Iterator for ChonkIter<'a, V, S, M> {
|
||||
impl<'a, V: Vox, S: RectVolSize, M: Clone> Iterator for ChonkIter<'a, V, S, M> {
|
||||
type Item = (Vec3<i32>, &'a V);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
@ -231,7 +225,7 @@ impl<'a, V: Vox, S: VolSize, M: Clone> Iterator for ChonkIter<'a, V, S, M> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, V: Vox, S: VolSize, M: Clone> IntoVolIterator<'a> for &'a Chonk<V, S, M> {
|
||||
impl<'a, V: Vox, S: RectVolSize, M: Clone> IntoVolIterator<'a> for &'a Chonk<V, S, M> {
|
||||
type IntoIter = ChonkIter<'a, V, S, M>;
|
||||
|
||||
fn into_vol_iter(self, lower_bound: Vec3<i32>, upper_bound: Vec3<i32>) -> Self::IntoIter {
|
||||
|
@ -10,7 +10,7 @@ pub use self::{
|
||||
structure::Structure,
|
||||
};
|
||||
|
||||
use crate::{vol::VolSize, volumes::vol_grid_2d::VolGrid2d};
|
||||
use crate::{vol::RectVolSize, volumes::vol_grid_2d::VolGrid2d};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use vek::*;
|
||||
|
||||
@ -19,12 +19,8 @@ use vek::*;
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct TerrainChunkSize;
|
||||
|
||||
impl VolSize for TerrainChunkSize {
|
||||
const SIZE: Vec3<u32> = Vec3 {
|
||||
x: 32,
|
||||
y: 32,
|
||||
z: std::i32::MAX as u32,
|
||||
};
|
||||
impl RectVolSize for TerrainChunkSize {
|
||||
const RECT_SIZE: Vec2<u32> = Vec2 { x: 32, y: 32 };
|
||||
}
|
||||
|
||||
// TerrainChunkMeta
|
||||
@ -62,4 +58,4 @@ impl TerrainChunkMeta {
|
||||
// Terrain type aliases
|
||||
|
||||
pub type TerrainChunk = chonk::Chonk<Block, TerrainChunkSize, TerrainChunkMeta>;
|
||||
pub type TerrainGrid = VolGrid2d<TerrainChunk, TerrainChunkSize>;
|
||||
pub type TerrainGrid = VolGrid2d<TerrainChunk>;
|
||||
|
@ -2,6 +2,16 @@ use crate::ray::Ray;
|
||||
use std::fmt::Debug;
|
||||
use vek::*;
|
||||
|
||||
/// Used to specify a volume's compile-time size. This exists as a substitute until const generics
|
||||
/// are implemented.
|
||||
pub trait VolSize: Clone {
|
||||
const SIZE: Vec3<u32>;
|
||||
}
|
||||
|
||||
pub trait RectVolSize: Clone {
|
||||
const RECT_SIZE: Vec2<u32>;
|
||||
}
|
||||
|
||||
/// A voxel.
|
||||
pub trait Vox: Sized + Clone {
|
||||
fn empty() -> Self;
|
||||
@ -43,6 +53,44 @@ pub trait SizedVol: BaseVol {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait RasterableVol: BaseVol {
|
||||
const SIZE: Vec3<u32>;
|
||||
}
|
||||
|
||||
impl<V: RasterableVol> SizedVol for V {
|
||||
fn lower_bound(&self) -> Vec3<i32> {
|
||||
Vec3::zero()
|
||||
}
|
||||
|
||||
fn upper_bound(&self) -> Vec3<i32> {
|
||||
V::SIZE.map(|e| e as i32)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait RectSizedVol: BaseVol {
|
||||
fn lower_bound_xy(&self) -> Vec2<i32>;
|
||||
|
||||
fn upper_bound_xy(&self) -> Vec2<i32>;
|
||||
|
||||
fn get_size_xy(&self) -> Vec2<u32> {
|
||||
(self.upper_bound_xy() - self.lower_bound_xy()).map(|e| e as u32)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait RectRasterableVol: BaseVol {
|
||||
const RECT_SIZE: Vec2<u32>;
|
||||
}
|
||||
|
||||
impl<V: RectRasterableVol> RectSizedVol for V {
|
||||
fn lower_bound_xy(&self) -> Vec2<i32> {
|
||||
Vec2::zero()
|
||||
}
|
||||
|
||||
fn upper_bound_xy(&self) -> Vec2<i32> {
|
||||
V::RECT_SIZE.map(|e| e as i32)
|
||||
}
|
||||
}
|
||||
|
||||
/// A volume that provides read access to its voxel data.
|
||||
pub trait ReadVol: BaseVol {
|
||||
/// Get a reference to the voxel at the provided position in the volume.
|
||||
@ -153,11 +201,3 @@ impl<'a, T: ReadVol> Iterator for DefaultVolIterator<'a, T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WIP
|
||||
|
||||
/// Used to specify a volume's compile-time size. This exists as a substitute until const generics
|
||||
/// are implemented.
|
||||
pub trait VolSize: Clone {
|
||||
const SIZE: Vec3<u32>;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
vol::{BaseVol, IntoVolIterator, ReadVol, SizedVol, VolSize, Vox, WriteVol},
|
||||
vol::{BaseVol, IntoVolIterator, RasterableVol, ReadVol, SizedVol, VolSize, Vox, WriteVol},
|
||||
volumes::morton::{morton_to_xyz, xyz_to_morton, MortonIter},
|
||||
};
|
||||
use core::cmp::PartialOrd;
|
||||
@ -190,16 +190,8 @@ impl<V: Vox, S: VolSize, M> BaseVol for Chunk<V, S, M> {
|
||||
type Error = ChunkError;
|
||||
}
|
||||
|
||||
impl<V: Vox, S: VolSize, M> SizedVol for Chunk<V, S, M> {
|
||||
#[inline(always)]
|
||||
fn lower_bound(&self) -> Vec3<i32> {
|
||||
Vec3::zero()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn upper_bound(&self) -> Vec3<i32> {
|
||||
S::SIZE.map(|e| e as i32)
|
||||
}
|
||||
impl<V: Vox, S: VolSize, M> RasterableVol for Chunk<V, S, M> {
|
||||
const SIZE: Vec3<u32> = S::SIZE;
|
||||
}
|
||||
|
||||
impl<V: Vox, S: VolSize, M> ReadVol for Chunk<V, S, M> {
|
||||
|
@ -1,13 +1,13 @@
|
||||
use crate::{
|
||||
vol::{BaseVol, ReadVol, SampleVol, VolSize, WriteVol},
|
||||
vol::{BaseVol, ReadVol, RectRasterableVol, SampleVol, VolSize, WriteVol},
|
||||
volumes::dyna::DynaError,
|
||||
};
|
||||
use hashbrown::{hash_map, HashMap};
|
||||
use std::{fmt::Debug, marker::PhantomData, sync::Arc};
|
||||
use std::{fmt::Debug, sync::Arc};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum VolGrid2dError<V: BaseVol> {
|
||||
pub enum VolGrid2dError<V: RectRasterableVol> {
|
||||
NoSuchChunk,
|
||||
ChunkError(V::Error),
|
||||
DynaError(DynaError),
|
||||
@ -18,31 +18,30 @@ pub enum VolGrid2dError<V: BaseVol> {
|
||||
// S = Size (replace with a const when const generics is a thing)
|
||||
// M = Chunk metadata
|
||||
#[derive(Clone)]
|
||||
pub struct VolGrid2d<V: BaseVol, S: VolSize> {
|
||||
pub struct VolGrid2d<V: RectRasterableVol> {
|
||||
chunks: HashMap<Vec2<i32>, Arc<V>>,
|
||||
phantom: PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<V: BaseVol, S: VolSize> VolGrid2d<V, S> {
|
||||
impl<V: RectRasterableVol> VolGrid2d<V> {
|
||||
#[inline(always)]
|
||||
pub fn chunk_key<P: Into<Vec2<i32>>>(pos: P) -> Vec2<i32> {
|
||||
pos.into()
|
||||
.map2(S::SIZE.into(), |e, sz: u32| e >> (sz - 1).count_ones())
|
||||
.map2(V::RECT_SIZE, |e, sz: u32| e >> (sz - 1).count_ones())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn chunk_offs(pos: Vec3<i32>) -> Vec3<i32> {
|
||||
let offs = pos.map2(S::SIZE, |e, sz| e & (sz - 1) as i32);
|
||||
let offs = Vec2::<i32>::from(pos).map2(V::RECT_SIZE, |e, sz| e & (sz - 1) as i32);
|
||||
Vec3::new(offs.x, offs.y, pos.z)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: BaseVol + Debug, S: VolSize> BaseVol for VolGrid2d<V, S> {
|
||||
impl<V: RectRasterableVol + Debug> BaseVol for VolGrid2d<V> {
|
||||
type Vox = V::Vox;
|
||||
type Error = VolGrid2dError<V>;
|
||||
}
|
||||
|
||||
impl<V: BaseVol + ReadVol + Debug, S: VolSize> ReadVol for VolGrid2d<V, S> {
|
||||
impl<V: RectRasterableVol + ReadVol + Debug> ReadVol for VolGrid2d<V> {
|
||||
#[inline(always)]
|
||||
fn get(&self, pos: Vec3<i32>) -> Result<&V::Vox, VolGrid2dError<V>> {
|
||||
let ck = Self::chunk_key(pos);
|
||||
@ -58,8 +57,8 @@ impl<V: BaseVol + ReadVol + Debug, S: VolSize> ReadVol for VolGrid2d<V, S> {
|
||||
|
||||
// TODO: This actually breaks the API: samples are supposed to have an offset of zero!
|
||||
// TODO: Should this be changed, perhaps?
|
||||
impl<I: Into<Aabr<i32>>, V: BaseVol + ReadVol + Debug, S: VolSize> SampleVol<I> for VolGrid2d<V, S> {
|
||||
type Sample = VolGrid2d<V, S>;
|
||||
impl<I: Into<Aabr<i32>>, V: RectRasterableVol + ReadVol + Debug> SampleVol<I> for VolGrid2d<V> {
|
||||
type Sample = VolGrid2d<V>;
|
||||
|
||||
/// Take a sample of the terrain by cloning the voxels within the provided range.
|
||||
///
|
||||
@ -86,7 +85,7 @@ impl<I: Into<Aabr<i32>>, V: BaseVol + ReadVol + Debug, S: VolSize> SampleVol<I>
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: BaseVol + WriteVol + Clone + Debug, S: VolSize + Clone> WriteVol for VolGrid2d<V, S> {
|
||||
impl<V: RectRasterableVol + WriteVol + Clone + Debug> WriteVol for VolGrid2d<V> {
|
||||
#[inline(always)]
|
||||
fn set(&mut self, pos: Vec3<i32>, vox: V::Vox) -> Result<(), VolGrid2dError<V>> {
|
||||
let ck = Self::chunk_key(pos);
|
||||
@ -102,7 +101,7 @@ impl<V: BaseVol + WriteVol + Clone + Debug, S: VolSize + Clone> WriteVol for Vol
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: BaseVol, S: VolSize> VolGrid2d<V, S> {
|
||||
impl<V: RectRasterableVol> VolGrid2d<V> {
|
||||
pub fn new() -> Result<Self, VolGrid2dError<V>> {
|
||||
if Self::chunk_size()
|
||||
.map(|e| e.is_power_of_two() && e > 0)
|
||||
@ -110,7 +109,6 @@ impl<V: BaseVol, S: VolSize> VolGrid2d<V, S> {
|
||||
{
|
||||
Ok(Self {
|
||||
chunks: HashMap::default(),
|
||||
phantom: PhantomData,
|
||||
})
|
||||
} else {
|
||||
Err(VolGrid2dError::InvalidChunkSize)
|
||||
@ -118,7 +116,7 @@ impl<V: BaseVol, S: VolSize> VolGrid2d<V, S> {
|
||||
}
|
||||
|
||||
pub fn chunk_size() -> Vec2<u32> {
|
||||
S::SIZE.into()
|
||||
V::RECT_SIZE
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, key: Vec2<i32>, chunk: Arc<V>) -> Option<Arc<V>> {
|
||||
@ -149,7 +147,7 @@ impl<V: BaseVol, S: VolSize> VolGrid2d<V, S> {
|
||||
}
|
||||
|
||||
pub fn key_pos(&self, key: Vec2<i32>) -> Vec2<i32> {
|
||||
key * Vec2::<u32>::from(S::SIZE).map(|e| e as i32)
|
||||
key * V::RECT_SIZE.map(|e| e as i32)
|
||||
}
|
||||
|
||||
pub fn pos_key(&self, pos: Vec3<i32>) -> Vec2<i32> {
|
||||
@ -163,11 +161,11 @@ impl<V: BaseVol, S: VolSize> VolGrid2d<V, S> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChunkIter<'a, V: BaseVol> {
|
||||
pub struct ChunkIter<'a, V: RectRasterableVol> {
|
||||
iter: hash_map::Iter<'a, Vec2<i32>, Arc<V>>,
|
||||
}
|
||||
|
||||
impl<'a, V: BaseVol> Iterator for ChunkIter<'a, V> {
|
||||
impl<'a, V: RectRasterableVol> Iterator for ChunkIter<'a, V> {
|
||||
type Item = (Vec2<i32>, &'a Arc<V>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
|
@ -1,13 +1,13 @@
|
||||
use crate::{
|
||||
vol::{BaseVol, ReadVol, SampleVol, VolSize, WriteVol},
|
||||
vol::{BaseVol, RasterableVol, ReadVol, SampleVol, VolSize, WriteVol},
|
||||
volumes::dyna::DynaError,
|
||||
};
|
||||
use hashbrown::{hash_map, HashMap};
|
||||
use std::{fmt::Debug, marker::PhantomData, sync::Arc};
|
||||
use std::{fmt::Debug, sync::Arc};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum VolGrid3dError<V: BaseVol> {
|
||||
pub enum VolGrid3dError<V: RasterableVol> {
|
||||
NoSuchChunk,
|
||||
ChunkErr(V::Error),
|
||||
DynaError(DynaError),
|
||||
@ -18,15 +18,14 @@ pub enum VolGrid3dError<V: BaseVol> {
|
||||
// S = Size (replace with a const when const generics is a thing)
|
||||
// M = Chunk metadata
|
||||
#[derive(Clone)]
|
||||
pub struct VolGrid3d<V: BaseVol, S: VolSize> {
|
||||
pub struct VolGrid3d<V: RasterableVol> {
|
||||
chunks: HashMap<Vec3<i32>, Arc<V>>,
|
||||
phantom: PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<V: BaseVol, S: VolSize> VolGrid3d<V, S> {
|
||||
impl<V: RasterableVol> VolGrid3d<V> {
|
||||
#[inline(always)]
|
||||
pub fn chunk_key(pos: Vec3<i32>) -> Vec3<i32> {
|
||||
pos.map2(S::SIZE, |e, sz| {
|
||||
pos.map2(V::SIZE, |e, sz| {
|
||||
// Horrid, but it's faster than a cheetah with a red bull blood transfusion
|
||||
let log2 = (sz - 1).count_ones();
|
||||
((((i64::from(e) + (1 << 32)) as u64) >> log2) - (1 << (32 - log2))) as i32
|
||||
@ -35,19 +34,19 @@ impl<V: BaseVol, S: VolSize> VolGrid3d<V, S> {
|
||||
|
||||
#[inline(always)]
|
||||
pub fn chunk_offs(pos: Vec3<i32>) -> Vec3<i32> {
|
||||
pos.map2(S::SIZE, |e, sz| {
|
||||
pos.map2(V::SIZE, |e, sz| {
|
||||
// Horrid, but it's even faster than the aforementioned cheetah
|
||||
(((i64::from(e) + (1 << 32)) as u64) & u64::from(sz - 1)) as i32
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: BaseVol + Debug, S: VolSize> BaseVol for VolGrid3d<V, S> {
|
||||
impl<V: RasterableVol + Debug> BaseVol for VolGrid3d<V> {
|
||||
type Vox = V::Vox;
|
||||
type Error = VolGrid3dError<V>;
|
||||
}
|
||||
|
||||
impl<V: BaseVol + ReadVol + Debug, S: VolSize> ReadVol for VolGrid3d<V, S> {
|
||||
impl<V: RasterableVol + ReadVol + Debug> ReadVol for VolGrid3d<V> {
|
||||
#[inline(always)]
|
||||
fn get(&self, pos: Vec3<i32>) -> Result<&V::Vox, VolGrid3dError<V>> {
|
||||
let ck = Self::chunk_key(pos);
|
||||
@ -63,8 +62,8 @@ impl<V: BaseVol + ReadVol + Debug, S: VolSize> ReadVol for VolGrid3d<V, S> {
|
||||
|
||||
// TODO: This actually breaks the API: samples are supposed to have an offset of zero!
|
||||
// TODO: Should this be changed, perhaps?
|
||||
impl<I: Into<Aabb<i32>>, V: BaseVol + ReadVol + Debug, S: VolSize> SampleVol<I> for VolGrid3d<V, S> {
|
||||
type Sample = VolGrid3d<V, S>;
|
||||
impl<I: Into<Aabb<i32>>, V: RasterableVol + ReadVol + Debug> SampleVol<I> for VolGrid3d<V> {
|
||||
type Sample = VolGrid3d<V>;
|
||||
|
||||
/// Take a sample of the terrain by cloning the voxels within the provided range.
|
||||
///
|
||||
@ -92,7 +91,7 @@ impl<I: Into<Aabb<i32>>, V: BaseVol + ReadVol + Debug, S: VolSize> SampleVol<I>
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: BaseVol + WriteVol + Clone + Debug, S: VolSize + Clone> WriteVol for VolGrid3d<V, S> {
|
||||
impl<V: RasterableVol + WriteVol + Clone + Debug> WriteVol for VolGrid3d<V> {
|
||||
#[inline(always)]
|
||||
fn set(&mut self, pos: Vec3<i32>, vox: V::Vox) -> Result<(), VolGrid3dError<V>> {
|
||||
let ck = Self::chunk_key(pos);
|
||||
@ -108,7 +107,7 @@ impl<V: BaseVol + WriteVol + Clone + Debug, S: VolSize + Clone> WriteVol for Vol
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: BaseVol, S: VolSize> VolGrid3d<V, S> {
|
||||
impl<V: RasterableVol> VolGrid3d<V> {
|
||||
pub fn new() -> Result<Self, VolGrid3dError<V>> {
|
||||
if Self::chunk_size()
|
||||
.map(|e| e.is_power_of_two() && e > 0)
|
||||
@ -116,7 +115,6 @@ impl<V: BaseVol, S: VolSize> VolGrid3d<V, S> {
|
||||
{
|
||||
Ok(Self {
|
||||
chunks: HashMap::new(),
|
||||
phantom: PhantomData,
|
||||
})
|
||||
} else {
|
||||
Err(VolGrid3dError::InvalidChunkSize)
|
||||
@ -124,7 +122,7 @@ impl<V: BaseVol, S: VolSize> VolGrid3d<V, S> {
|
||||
}
|
||||
|
||||
pub fn chunk_size() -> Vec3<u32> {
|
||||
S::SIZE
|
||||
V::SIZE
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, key: Vec3<i32>, chunk: Arc<V>) -> Option<Arc<V>> {
|
||||
@ -147,7 +145,7 @@ impl<V: BaseVol, S: VolSize> VolGrid3d<V, S> {
|
||||
}
|
||||
|
||||
pub fn key_pos(&self, key: Vec3<i32>) -> Vec3<i32> {
|
||||
key * S::SIZE.map(|e| e as i32)
|
||||
key * V::SIZE.map(|e| e as i32)
|
||||
}
|
||||
|
||||
pub fn pos_key(&self, pos: Vec3<i32>) -> Vec3<i32> {
|
||||
@ -161,11 +159,11 @@ impl<V: BaseVol, S: VolSize> VolGrid3d<V, S> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChunkIter<'a, V: BaseVol> {
|
||||
pub struct ChunkIter<'a, V: RasterableVol> {
|
||||
iter: hash_map::Iter<'a, Vec3<i32>, Arc<V>>,
|
||||
}
|
||||
|
||||
impl<'a, V: BaseVol> Iterator for ChunkIter<'a, V> {
|
||||
impl<'a, V: RasterableVol> Iterator for ChunkIter<'a, V> {
|
||||
type Item = (Vec3<i32>, &'a Arc<V>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
|
@ -842,7 +842,7 @@ fn handle_debug_column(server: &mut Server, entity: EcsEntity, args: String, act
|
||||
let sim = server.world.sim();
|
||||
if let Ok((x, y)) = scan_fmt!(&args, action.arg_fmt, i32, i32) {
|
||||
let wpos = Vec2::new(x, y);
|
||||
/* let chunk_pos = wpos.map2(Vec2::from(TerrainChunkSize::SIZE), |e, sz: u32| {
|
||||
/* let chunk_pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| {
|
||||
e / sz as i32
|
||||
}); */
|
||||
|
||||
|
@ -23,8 +23,7 @@ use common::{
|
||||
net::PostOffice,
|
||||
state::{BlockChange, State, TimeOfDay, Uid},
|
||||
terrain::{block::Block, TerrainChunk, TerrainChunkSize, TerrainGrid},
|
||||
vol::Vox,
|
||||
vol::{ReadVol, VolSize},
|
||||
vol::{ReadVol, RectVolSize, Vox},
|
||||
};
|
||||
use crossbeam::channel;
|
||||
use hashbrown::HashSet;
|
||||
@ -1039,8 +1038,8 @@ impl Server {
|
||||
) {
|
||||
{
|
||||
// Check if the entity is in the client's range
|
||||
(pos.0 - client_pos.0)
|
||||
.map2(TerrainChunkSize::SIZE, |d, sz| {
|
||||
Vec2::from(pos.0 - client_pos.0)
|
||||
.map2(TerrainChunkSize::RECT_SIZE, |d: f32, sz| {
|
||||
(d.abs() as u32 / sz).checked_sub(2).unwrap_or(0)
|
||||
})
|
||||
.magnitude_squared()
|
||||
|
@ -38,7 +38,7 @@ use crate::{
|
||||
GlobalState,
|
||||
};
|
||||
use client::{Client, Event as ClientEvent};
|
||||
use common::{comp, terrain::TerrainChunkSize, vol::VolSize};
|
||||
use common::{comp, terrain::TerrainChunk, vol::RectRasterableVol};
|
||||
use conrod_core::{
|
||||
text::cursor::Index,
|
||||
widget::{self, Button, Image, Rectangle, Text},
|
||||
@ -485,8 +485,10 @@ impl Hud {
|
||||
.filter(|(entity, _, stats, _, _)| *entity != me && !stats.is_dead)
|
||||
// Don't process nametags outside the vd (visibility further limited by ui backend)
|
||||
.filter(|(_, pos, _, _, _)| {
|
||||
(pos.0 - player_pos)
|
||||
.map2(TerrainChunkSize::SIZE, |d, sz| d.abs() as f32 / sz as f32)
|
||||
Vec2::from(pos.0 - player_pos)
|
||||
.map2(TerrainChunk::RECT_SIZE, |d: f32, sz| {
|
||||
d.abs() as f32 / sz as f32
|
||||
})
|
||||
.magnitude()
|
||||
< view_distance as f32
|
||||
})
|
||||
@ -526,8 +528,10 @@ impl Hud {
|
||||
})
|
||||
// Don't process health bars outside the vd (visibility further limited by ui backend)
|
||||
.filter(|(_, pos, _, _)| {
|
||||
(pos.0 - player_pos)
|
||||
.map2(TerrainChunkSize::SIZE, |d, sz| d.abs() as f32 / sz as f32)
|
||||
Vec2::from(pos.0 - player_pos)
|
||||
.map2(TerrainChunk::RECT_SIZE, |d: f32, sz| {
|
||||
d.abs() as f32 / sz as f32
|
||||
})
|
||||
.magnitude()
|
||||
< view_distance as f32
|
||||
})
|
||||
|
@ -4,7 +4,7 @@ use crate::{
|
||||
};
|
||||
use common::{
|
||||
terrain::{Block, BlockKind},
|
||||
vol::{BaseVol, ReadVol, VolSize},
|
||||
vol::{ReadVol, RectRasterableVol},
|
||||
volumes::vol_grid_2d::VolGrid2d,
|
||||
};
|
||||
use std::fmt::Debug;
|
||||
@ -24,8 +24,8 @@ fn block_shadow_density(kind: BlockKind) -> (f32, f32) {
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: BaseVol<Vox = Block> + ReadVol + Debug, S: VolSize + Clone>
|
||||
Meshable<TerrainPipeline, FluidPipeline> for VolGrid2d<V, S>
|
||||
impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeline, FluidPipeline>
|
||||
for VolGrid2d<V>
|
||||
{
|
||||
type Pipeline = TerrainPipeline;
|
||||
type TranslucentPipeline = FluidPipeline;
|
||||
@ -126,7 +126,7 @@ impl<V: BaseVol<Vox = Block> + ReadVol + Debug, S: VolSize + Clone>
|
||||
}
|
||||
|
||||
/*
|
||||
impl<V: BaseVol<Vox = Block> + ReadVol + Debug, S: VolSize + Clone> Meshable for VolGrid3d<V, S> {
|
||||
impl<V: BaseVol<Vox = Block> + ReadVol + Debug> Meshable for VolGrid3d<V> {
|
||||
type Pipeline = TerrainPipeline;
|
||||
type Supplement = Aabb<i32>;
|
||||
|
||||
|
@ -14,8 +14,8 @@ use common::{
|
||||
assets,
|
||||
comp::{self, humanoid, item::Tool, object, quadruped, quadruped_medium, Body},
|
||||
figure::Segment,
|
||||
terrain::TerrainChunkSize,
|
||||
vol::VolSize,
|
||||
terrain::TerrainChunk,
|
||||
vol::RectRasterableVol,
|
||||
};
|
||||
use dot_vox::DotVoxData;
|
||||
use hashbrown::HashMap;
|
||||
@ -612,8 +612,10 @@ impl FigureMgr {
|
||||
.join()
|
||||
{
|
||||
// Don't process figures outside the vd
|
||||
let vd_frac = (pos.0 - player_pos)
|
||||
.map2(TerrainChunkSize::SIZE, |d, sz| d.abs() as f32 / sz as f32)
|
||||
let vd_frac = Vec2::from(pos.0 - player_pos)
|
||||
.map2(TerrainChunk::RECT_SIZE, |d: f32, sz| {
|
||||
d.abs() as f32 / sz as f32
|
||||
})
|
||||
.magnitude()
|
||||
/ view_distance as f32;
|
||||
// Keep from re-adding/removing entities on the border of the vd
|
||||
|
@ -15,7 +15,11 @@ use crate::{
|
||||
window::Event,
|
||||
};
|
||||
use client::Client;
|
||||
use common::{comp, terrain::BlockKind, vol::ReadVol};
|
||||
use common::{
|
||||
comp,
|
||||
terrain::{BlockKind, TerrainChunk},
|
||||
vol::ReadVol,
|
||||
};
|
||||
use specs::Join;
|
||||
use vek::*;
|
||||
|
||||
@ -42,7 +46,7 @@ pub struct Scene {
|
||||
|
||||
skybox: Skybox,
|
||||
postprocess: PostProcess,
|
||||
terrain: Terrain,
|
||||
terrain: Terrain<TerrainChunk>,
|
||||
loaded_distance: f32,
|
||||
|
||||
figure_mgr: FigureMgr,
|
||||
|
@ -9,15 +9,15 @@ use client::Client;
|
||||
use common::{
|
||||
assets,
|
||||
figure::Segment,
|
||||
terrain::{Block, BlockKind, TerrainChunkSize, TerrainGrid},
|
||||
vol::{ReadVol, SampleVol, VolSize, Vox},
|
||||
volumes::vol_grid_2d::VolGrid2dError,
|
||||
terrain::{Block, BlockKind},
|
||||
vol::{BaseVol, ReadVol, RectRasterableVol, SampleVol, Vox},
|
||||
volumes::vol_grid_2d::{VolGrid2d, VolGrid2dError},
|
||||
};
|
||||
use crossbeam::channel;
|
||||
use dot_vox::DotVoxData;
|
||||
use frustum_query::frustum::Frustum;
|
||||
use hashbrown::HashMap;
|
||||
use std::{f32, i32, ops::Mul, time::Duration};
|
||||
use std::{f32, fmt::Debug, i32, marker::PhantomData, ops::Mul, time::Duration};
|
||||
use vek::*;
|
||||
|
||||
struct TerrainChunk {
|
||||
@ -110,11 +110,11 @@ fn sprite_config_for(kind: BlockKind) -> Option<SpriteConfig> {
|
||||
}
|
||||
|
||||
/// Function executed by worker threads dedicated to chunk meshing.
|
||||
fn mesh_worker(
|
||||
fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
|
||||
pos: Vec2<i32>,
|
||||
z_bounds: (f32, f32),
|
||||
started_tick: u64,
|
||||
volume: <TerrainGrid as SampleVol<Aabr<i32>>>::Sample,
|
||||
volume: <VolGrid2d<V> as SampleVol<Aabr<i32>>>::Sample,
|
||||
range: Aabb<i32>,
|
||||
) -> MeshWorkerResponse {
|
||||
let (opaque_mesh, fluid_mesh) = volume.generate_mesh(range);
|
||||
@ -127,12 +127,11 @@ fn mesh_worker(
|
||||
sprite_instances: {
|
||||
let mut instances = HashMap::new();
|
||||
|
||||
for x in 0..TerrainChunkSize::SIZE.x as i32 {
|
||||
for y in 0..TerrainChunkSize::SIZE.y as i32 {
|
||||
for x in 0..V::RECT_SIZE.x as i32 {
|
||||
for y in 0..V::RECT_SIZE.y as i32 {
|
||||
for z in z_bounds.0 as i32..z_bounds.1 as i32 + 1 {
|
||||
let wpos = Vec3::from(
|
||||
pos * Vec2::from(TerrainChunkSize::SIZE).map(|e: u32| e as i32),
|
||||
) + Vec3::new(x, y, z);
|
||||
let wpos = Vec3::from(pos * V::RECT_SIZE.map(|e: u32| e as i32))
|
||||
+ Vec3::new(x, y, z);
|
||||
|
||||
let kind = volume.get(wpos).unwrap_or(&Block::empty()).kind();
|
||||
|
||||
@ -164,7 +163,7 @@ fn mesh_worker(
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Terrain {
|
||||
pub struct Terrain<V: RectRasterableVol> {
|
||||
chunks: HashMap<Vec2<i32>, TerrainChunk>,
|
||||
|
||||
// The mpsc sender and receiver used for talking to meshing worker threads.
|
||||
@ -175,9 +174,11 @@ pub struct Terrain {
|
||||
|
||||
// GPU data
|
||||
sprite_models: HashMap<(BlockKind, usize), Model<SpritePipeline>>,
|
||||
|
||||
phantom: PhantomData<V>,
|
||||
}
|
||||
|
||||
impl Terrain {
|
||||
impl<V: RectRasterableVol> Terrain<V> {
|
||||
pub fn new(renderer: &mut Renderer) -> Self {
|
||||
// Create a new mpsc (Multiple Produced, Single Consumer) pair for communicating with
|
||||
// worker threads that are meshing chunks.
|
||||
@ -324,6 +325,7 @@ impl Terrain {
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,10 +457,10 @@ impl Terrain {
|
||||
let aabr = Aabr {
|
||||
min: todo
|
||||
.pos
|
||||
.map2(TerrainGrid::chunk_size(), |e, sz| e * sz as i32 - 1),
|
||||
max: todo
|
||||
.pos
|
||||
.map2(TerrainGrid::chunk_size(), |e, sz| (e + 1) * sz as i32 + 1),
|
||||
.map2(VolGrid2d::<V>::chunk_size(), |e, sz| e * sz as i32 - 1),
|
||||
max: todo.pos.map2(VolGrid2d::<V>::chunk_size(), |e, sz| {
|
||||
(e + 1) * sz as i32 + 1
|
||||
}),
|
||||
};
|
||||
|
||||
// Copy out the chunk data we need to perform the meshing. We do this by taking a
|
||||
@ -534,7 +536,7 @@ impl Terrain {
|
||||
locals: renderer
|
||||
.create_consts(&[TerrainLocals {
|
||||
model_offs: Vec3::from(
|
||||
response.pos.map2(TerrainGrid::chunk_size(), |e, sz| {
|
||||
response.pos.map2(VolGrid2d::<V>::chunk_size(), |e, sz| {
|
||||
e as f32 * sz as f32
|
||||
}),
|
||||
)
|
||||
@ -563,7 +565,7 @@ impl Terrain {
|
||||
);
|
||||
|
||||
// Update chunk visibility
|
||||
let chunk_sz = TerrainChunkSize::SIZE.x as f32;
|
||||
let chunk_sz = V::RECT_SIZE.x as f32;
|
||||
for (pos, chunk) in &mut self.chunks {
|
||||
let chunk_pos = pos.map(|e| e as f32 * chunk_sz);
|
||||
|
||||
@ -615,9 +617,8 @@ impl Terrain {
|
||||
|
||||
const SPRITE_RENDER_DISTANCE: f32 = 128.0;
|
||||
|
||||
let chunk_center = pos.map2(Vec2::from(TerrainChunkSize::SIZE), |e, sz: u32| {
|
||||
(e as f32 + 0.5) * sz as f32
|
||||
});
|
||||
let chunk_center =
|
||||
pos.map2(V::RECT_SIZE, |e, sz: u32| (e as f32 + 0.5) * sz as f32);
|
||||
if Vec2::from(focus_pos).distance_squared(chunk_center)
|
||||
< SPRITE_RENDER_DISTANCE * SPRITE_RENDER_DISTANCE
|
||||
{
|
||||
|
@ -8,7 +8,7 @@ use crate::{
|
||||
use common::{
|
||||
assets,
|
||||
terrain::{BlockKind, Structure, TerrainChunkSize},
|
||||
vol::VolSize,
|
||||
vol::RectVolSize,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use noise::NoiseFn;
|
||||
@ -71,9 +71,7 @@ impl<'a> ColumnGen<'a> {
|
||||
.min_by_key(|(pos, _)| pos.distance_squared(wpos))
|
||||
.unwrap();
|
||||
|
||||
let chunk_pos = pos.map2(Vec2::from(TerrainChunkSize::SIZE), |e, sz: u32| {
|
||||
e / sz as i32
|
||||
});
|
||||
let chunk_pos = pos.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| e / sz as i32);
|
||||
let chunk = self.world.sim().get(chunk_pos)?;
|
||||
|
||||
if seed % 5 == 2
|
||||
@ -127,9 +125,7 @@ impl<'a> Sampler for ColumnGen<'a> {
|
||||
|
||||
fn get(&self, wpos: Vec2<i32>) -> Option<ColumnSample<'a>> {
|
||||
let wposf = wpos.map(|e| e as f64);
|
||||
let chunk_pos = wpos.map2(Vec2::from(TerrainChunkSize::SIZE), |e, sz: u32| {
|
||||
e / sz as i32
|
||||
});
|
||||
let chunk_pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| e / sz as i32);
|
||||
|
||||
let sim = self.world.sim();
|
||||
|
||||
|
@ -23,7 +23,7 @@ use crate::{
|
||||
};
|
||||
use common::{
|
||||
terrain::{Block, BlockKind, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
|
||||
vol::{ReadVol, VolSize, Vox, WriteVol},
|
||||
vol::{ReadVol, RectVolSize, Vox, WriteVol},
|
||||
};
|
||||
use rand::Rng;
|
||||
use std::time::Duration;
|
||||
@ -68,7 +68,7 @@ impl World {
|
||||
let stone = Block::new(BlockKind::Dense, Rgb::new(200, 220, 255));
|
||||
let water = Block::new(BlockKind::Water, Rgb::new(60, 90, 190));
|
||||
|
||||
let chunk_size2d = Vec2::from(TerrainChunkSize::SIZE);
|
||||
let chunk_size2d = TerrainChunkSize::RECT_SIZE;
|
||||
let (base_z, sim_chunk) = match self
|
||||
.sim
|
||||
.get_interpolated(
|
||||
@ -94,13 +94,13 @@ impl World {
|
||||
let meta = TerrainChunkMeta::new(sim_chunk.get_name(&self.sim), sim_chunk.get_biome());
|
||||
let mut sampler = self.sample_blocks();
|
||||
|
||||
let chunk_block_pos = Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32);
|
||||
let chunk_block_pos = Vec3::from(chunk_pos) * TerrainChunkSize::RECT_SIZE.map(|e| e as i32);
|
||||
|
||||
let mut chunk = TerrainChunk::new(base_z, stone, air, meta);
|
||||
for x in 0..TerrainChunkSize::SIZE.x as i32 {
|
||||
for y in 0..TerrainChunkSize::SIZE.y as i32 {
|
||||
for x in 0..TerrainChunkSize::RECT_SIZE.x as i32 {
|
||||
for y in 0..TerrainChunkSize::RECT_SIZE.y as i32 {
|
||||
let wpos2d = Vec2::new(x, y)
|
||||
+ Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32);
|
||||
+ Vec2::from(chunk_pos) * TerrainChunkSize::RECT_SIZE.map(|e| e as i32);
|
||||
|
||||
let z_cache = match sampler.get_z_cache(wpos2d) {
|
||||
Some(z_cache) => z_cache,
|
||||
@ -125,7 +125,7 @@ impl World {
|
||||
}
|
||||
|
||||
let gen_entity_pos = || {
|
||||
let lpos2d = Vec2::from(TerrainChunkSize::SIZE)
|
||||
let lpos2d = TerrainChunkSize::RECT_SIZE
|
||||
.map(|sz| rand::thread_rng().gen::<u32>().rem_euclid(sz));
|
||||
let mut lpos = Vec3::new(lpos2d.x as i32, lpos2d.y as i32, 0);
|
||||
|
||||
|
@ -16,7 +16,7 @@ use crate::{
|
||||
};
|
||||
use common::{
|
||||
terrain::{BiomeKind, TerrainChunkSize},
|
||||
vol::VolSize,
|
||||
vol::RectVolSize,
|
||||
};
|
||||
use noise::{
|
||||
BasicMulti, Billow, HybridMulti, MultiFractal, NoiseFn, RidgedMulti, Seedable, SuperSimplex,
|
||||
@ -314,7 +314,7 @@ impl WorldSim {
|
||||
self.rng.gen::<usize>() % grid_size.y,
|
||||
);
|
||||
let wpos = (cell_pos * cell_size + cell_size / 2)
|
||||
.map2(Vec2::from(TerrainChunkSize::SIZE), |e, sz: u32| {
|
||||
.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| {
|
||||
e as i32 * sz as i32 + sz as i32 / 2
|
||||
});
|
||||
|
||||
@ -364,8 +364,8 @@ impl WorldSim {
|
||||
for j in 0..WORLD_SIZE.y {
|
||||
let chunk_pos = Vec2::new(i as i32, j as i32);
|
||||
let block_pos = Vec2::new(
|
||||
chunk_pos.x * TerrainChunkSize::SIZE.x as i32,
|
||||
chunk_pos.y * TerrainChunkSize::SIZE.y as i32,
|
||||
chunk_pos.x * TerrainChunkSize::RECT_SIZE.x as i32,
|
||||
chunk_pos.y * TerrainChunkSize::RECT_SIZE.y as i32,
|
||||
);
|
||||
let _cell_pos = Vec2::new(i / cell_size, j / cell_size);
|
||||
|
||||
@ -375,9 +375,8 @@ impl WorldSim {
|
||||
.iter()
|
||||
.map(|(pos, seed)| RegionInfo {
|
||||
chunk_pos: *pos,
|
||||
block_pos: pos.map2(Vec2::from(TerrainChunkSize::SIZE), |e, sz: u32| {
|
||||
e * sz as i32
|
||||
}),
|
||||
block_pos: pos
|
||||
.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| e * sz as i32),
|
||||
dist: (pos - chunk_pos).map(|e| e as f32).magnitude(),
|
||||
seed: *seed,
|
||||
})
|
||||
@ -455,7 +454,7 @@ impl WorldSim {
|
||||
T: Copy + Default + Add<Output = T> + Mul<f32, Output = T>,
|
||||
F: FnMut(&SimChunk) -> T,
|
||||
{
|
||||
let pos = pos.map2(TerrainChunkSize::SIZE.into(), |e, sz: u32| {
|
||||
let pos = pos.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| {
|
||||
e as f64 / sz as f64
|
||||
});
|
||||
|
||||
@ -519,7 +518,7 @@ pub struct LocationInfo {
|
||||
impl SimChunk {
|
||||
fn generate(posi: usize, gen_ctx: &mut GenCtx, gen_cdf: &GenCdf) -> Self {
|
||||
let pos = uniform_idx_as_vec2(posi);
|
||||
let wposf = (pos * TerrainChunkSize::SIZE.map(|e| e as i32)).map(|e| e as f64);
|
||||
let wposf = (pos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32)).map(|e| e as f64);
|
||||
|
||||
// FIXME: Currently unused, but should represent fresh groundwater level.
|
||||
// Should be correlated a little with humidity, somewhat negatively with altitude,
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::WORLD_SIZE;
|
||||
use common::{terrain::TerrainChunkSize, vol::VolSize};
|
||||
use common::{terrain::TerrainChunkSize, vol::RectVolSize};
|
||||
use vek::*;
|
||||
|
||||
/// Computes the cumulative distribution function of the weighted sum of k independent,
|
||||
@ -141,7 +141,7 @@ pub fn uniform_noise(f: impl Fn(usize, Vec2<f64>) -> Option<f32>) -> InverseCdf
|
||||
.filter_map(|i| {
|
||||
(f(
|
||||
i,
|
||||
(uniform_idx_as_vec2(i) * TerrainChunkSize::SIZE.map(|e| e as i32))
|
||||
(uniform_idx_as_vec2(i) * TerrainChunkSize::RECT_SIZE.map(|e| e as i32))
|
||||
.map(|e| e as f64),
|
||||
)
|
||||
.map(|res| (i, res)))
|
||||
|
Loading…
Reference in New Issue
Block a user