mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
implement a new version, that uses a more ecs approach of LOD.
the old implementation needed a Vec per Element, which itself needs 24 bytes, which is a huge overhead for a single byte element. the new implementation has global Vec per region and only needs a index for the first element, which might be 8 bytes (implementation 4 bytes because of some assumptions) or none at all. It's still not ideal, because it will requiere alot of duplicate coding. Former-commit-id: 7172829c18ceabe67689487ffd269ebe62d1647b
This commit is contained in:
parent
1456497bd0
commit
a3c36f135a
@ -1,34 +1,148 @@
|
||||
use vek::*;
|
||||
use std::ops::Sub;
|
||||
use std::ops::Add;
|
||||
|
||||
/*
|
||||
For our LodStructures we need a type that covers the values from 0 - 2047 in steps of 1/32.
|
||||
which is 11 bits for the digits before the decimal point and 5 bits for the digits after the decimal point.
|
||||
Because for accessing the decimal point makes no difference we use a u16 to represent this value.
|
||||
The value needs to be shiftet to get it's "real inworld size",
|
||||
e.g. 1 represents 1/32
|
||||
32 represents 1
|
||||
65535 represents 2047 + 31/32
|
||||
|
||||
Edit: now it actually implements a value from 0 - 3*2048 - 1/32, covering over 3 regions for accessing neighbor region values
|
||||
|
||||
-- lower neighbor
|
||||
0 -> 0
|
||||
1 -> 2047 31/32
|
||||
-- owned
|
||||
65536 -> 2048
|
||||
131071 -> 4095 31/32
|
||||
-- upper neighbor
|
||||
196607 -> 6143 31/32
|
||||
|
||||
*/
|
||||
|
||||
pub type LodIndex = Vec3<u16>;
|
||||
|
||||
pub fn to_lod_i(pos: Vec3<u16>) -> LodIndex {
|
||||
pos.map(|x| x * 32)
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
|
||||
pub struct LodIndex {
|
||||
/*
|
||||
bit 0..17 -> x
|
||||
bit 18..35 -> y
|
||||
bit 36..53 -> z
|
||||
bit 54..63 -> unused
|
||||
*/
|
||||
data: u64,
|
||||
}
|
||||
|
||||
/*will round*/
|
||||
pub fn to_lod_f(pos: Vec3<f32>) -> LodIndex {
|
||||
pos.map(|x| (x * 32.0).round() as u16)
|
||||
/*does not work on big endian!*/
|
||||
const BIT_X_MASK: u64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0011_1111_1111_1111_1111;
|
||||
const BIT_Y_MASK: u64 = 0b0000_0000_0000_0000_0000_0000_0000_1111_1111_1111_1111_1100_0000_0000_0000_0000;
|
||||
const BIT_Z_MASK: u64 = 0b0000_0000_0011_1111_1111_1111_1111_0000_0000_0000_0000_0000_0000_0000_0000_0000;
|
||||
const BIT_X_MASK32: u32 = 0b0000_0000_0000_0011_1111_1111_1111_1111;
|
||||
|
||||
impl LodIndex {
|
||||
pub fn new(data: Vec3<u32>) -> Self {
|
||||
let mut index = LodIndex {data: 0};
|
||||
index.set(data);
|
||||
index
|
||||
}
|
||||
|
||||
pub fn get(&self) -> Vec3<u32> {
|
||||
let x = (self.data & BIT_X_MASK) as u32;
|
||||
let y = ((self.data & BIT_Y_MASK) >> 18 ) as u32;
|
||||
let z = ((self.data & BIT_Z_MASK) >> 36 ) as u32;
|
||||
Vec3{x,y,z}
|
||||
}
|
||||
|
||||
pub fn set(&mut self, data: Vec3<u32>) {
|
||||
let x = (data.x & BIT_X_MASK32) as u64;
|
||||
let y = ((data.y & BIT_X_MASK32) as u64 ) << 18;
|
||||
let z = ((data.z & BIT_X_MASK32) as u64 ) << 36;
|
||||
self.data = x + y + z;
|
||||
}
|
||||
|
||||
pub fn align_to_layer_id(&self, level: u8) -> LodIndex {
|
||||
let xyz = self.get();
|
||||
let f = two_pow_u(level) as u32;
|
||||
LodIndex::new(xyz.map(|i| {
|
||||
(i / f) * f
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_pos_i(index: LodIndex) -> Vec3<u16> {
|
||||
index.map(|x| x / 32)
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
lodstore::index::LodIndex,
|
||||
};
|
||||
use vek::*;
|
||||
|
||||
#[test]
|
||||
fn setter_getter() {
|
||||
let i = LodIndex::new(Vec3::new(0,0,0));
|
||||
assert_eq!(i.get(), Vec3::new(0,0,0));
|
||||
|
||||
let i = LodIndex::new(Vec3::new(1337,0,0));
|
||||
assert_eq!(i.get(), Vec3::new(1337,0,0));
|
||||
|
||||
let i = LodIndex::new(Vec3::new(0,1337,0));
|
||||
assert_eq!(i.get(), Vec3::new(0,1337,0));
|
||||
|
||||
let i = LodIndex::new(Vec3::new(0,0,1337));
|
||||
assert_eq!(i.get(), Vec3::new(0,0,1337));
|
||||
|
||||
let i = LodIndex::new(Vec3::new(1,1,1));
|
||||
assert_eq!(i.get(), Vec3::new(1,1,1));
|
||||
|
||||
let i = LodIndex::new(Vec3::new(262143,262143,262143));
|
||||
assert_eq!(i.get(), Vec3::new(262143,262143,262143));
|
||||
|
||||
let i = LodIndex::new(Vec3::new(262144,262144,262144)); //overflow
|
||||
assert_eq!(i.get(), Vec3::new(0,0,0));
|
||||
|
||||
let i = LodIndex::new(Vec3::new(42,1337,69));
|
||||
assert_eq!(i.get(), Vec3::new(42,1337,69));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_pos_f(index: LodIndex) -> Vec3<f32> {
|
||||
index.map(|x| x as f32 / 32.0)
|
||||
impl Sub for LodIndex {
|
||||
type Output = LodIndex;
|
||||
fn sub(self, rhs: LodIndex) -> Self::Output {
|
||||
LodIndex {
|
||||
data: self.data - rhs.data /*fast but has overflow issues*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for LodIndex {
|
||||
type Output = LodIndex;
|
||||
fn add(self, rhs: LodIndex) -> Self::Output {
|
||||
LodIndex {
|
||||
data: self.data + rhs.data /*fast but has overflow issues*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
impl LodIndex {
|
||||
pub fn new(pos: Vec3<i32>) -> Self {
|
||||
Self {
|
||||
data: pos.map(|x| (x * 32 + 65535) as u32),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn newf(pos: Vec3<f32>) -> Self {
|
||||
Self {
|
||||
data: pos.map(|x| (x * 32.0).round() as u32 + 65535),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_pos_i(&self) -> Vec3<i32> { self.data.map(|x| (x / 32 - 2048) as i32) }
|
||||
|
||||
pub fn to_pos_f(&self) -> Vec3<f32> {
|
||||
self.data.map(|x| x as f32 / 32.0 - 2048.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub const LEVEL_LENGTH_POW_MAX: i8 = 11;
|
||||
pub const LEVEL_LENGTH_POW_MIN: i8 = -4;
|
||||
@ -44,4 +158,15 @@ pub const fn two_pow_u(n: u8) -> u16 {
|
||||
|
||||
pub fn two_pow_i(n: i8) -> f32 {
|
||||
2.0_f32.powi(n as i32)
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
pub const fn two_pow_u(n: u8) -> u16 {
|
||||
1 << n
|
||||
}
|
||||
|
||||
pub fn relative_to_1d(index: LodIndex, relative_size: Vec3<u32>) -> usize {
|
||||
let index = index.get();
|
||||
(index[0] + index[1] * relative_size[0] + index[2] * relative_size[0] * relative_size[1]) as usize
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
273
worldsim/src/region/lod/example.rs
Normal file
273
worldsim/src/region/lod/example.rs
Normal file
@ -0,0 +1,273 @@
|
||||
use crate::lodstore::{
|
||||
LodData,
|
||||
LayerInfo,
|
||||
LodConfig,
|
||||
index::LodIndex,
|
||||
};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Example9 {
|
||||
data: [u8; 700],
|
||||
child_id: Option<u32>, // Chunk5 2^(7*3), this is valid
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Example5 {
|
||||
data: [u8; 130],
|
||||
child_id: Option<u32>, // see Block0 2^(12*3)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Example0 {
|
||||
data: u32,
|
||||
child_id: Option<u32>,// In reality 2^(16*3) SubBlock_4 should be possible, but 2^48 subblocks would kill anything anyway, so save 2 bytes here
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Example_4 {
|
||||
data: u16,
|
||||
}
|
||||
|
||||
impl Example9 {
|
||||
pub fn new() -> Self {
|
||||
Example9{
|
||||
data: [0; 700],
|
||||
child_id: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LayerInfo for Example9 {
|
||||
fn get_child_index(self: &Self) -> Option<usize> {
|
||||
self.child_id.map(|n| n as usize)
|
||||
}
|
||||
const child_layer_id: Option<u8> = Some(9);
|
||||
const layer_volume: Vec3<u32> = Vec3{x: 16, y: 16, z: 16};
|
||||
const child_len: usize = 4096;//2_usize.pow(Self::child_dim*3);
|
||||
}
|
||||
|
||||
impl LayerInfo for Example5 {
|
||||
fn get_child_index(self: &Self) -> Option<usize> {
|
||||
self.child_id.map(|n| n as usize)
|
||||
}
|
||||
const child_layer_id: Option<u8> = Some(4);
|
||||
const layer_volume: Vec3<u32> = Vec3{x: 32, y: 32, z: 32};
|
||||
const child_len: usize = 32768;//2_usize.pow(Self::child_dim*3);
|
||||
}
|
||||
|
||||
impl LayerInfo for Example0 {
|
||||
fn get_child_index(self: &Self) -> Option<usize> {
|
||||
self.child_id.map(|n| n as usize)
|
||||
}
|
||||
const child_layer_id: Option<u8> = Some(0);
|
||||
const layer_volume: Vec3<u32> = Vec3{x: 16, y: 16, z: 16};
|
||||
const child_len: usize = 4096;//2_usize.pow(Self::child_dim*3);
|
||||
}
|
||||
|
||||
impl LayerInfo for Example_4 {
|
||||
fn get_child_index(self: &Self) -> Option<usize> { None }
|
||||
const child_layer_id: Option<u8> = None;
|
||||
const layer_volume: Vec3<u32> = Vec3{x: 1, y: 1, z: 1};
|
||||
const child_len: usize = 0;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ExampleLodConfig {}
|
||||
|
||||
impl LodConfig for ExampleLodConfig {
|
||||
type L0 = Example_4;
|
||||
type L1 = ();
|
||||
type L2 = ();
|
||||
type L3 = ();
|
||||
type L4 = Example0;
|
||||
type L5 = ();
|
||||
type L6 = ();
|
||||
type L7 = ();
|
||||
type L8 = ();
|
||||
type L9 = Example5;
|
||||
type L10 = ();
|
||||
type L11 = ();
|
||||
type L12 = ();
|
||||
type L13 = Example9;
|
||||
type L14 = ();
|
||||
type L15 = ();
|
||||
|
||||
const anchor_layer_id: u8 = 13;
|
||||
|
||||
fn setup(&mut self) {
|
||||
|
||||
}
|
||||
|
||||
fn drill_down(data: &mut LodData::<Self>, level: u8, index: usize) {
|
||||
match level {
|
||||
0 => {
|
||||
panic!("cannot drill down further");
|
||||
},
|
||||
4 => {
|
||||
if data.layer4[index].child_id.is_some() {return;}
|
||||
let insert = data.layer0.len();
|
||||
data.layer4.reserve(Example_4::child_len);
|
||||
data.layer4[index].child_id = Some(insert as u32);
|
||||
for i in 0..Example0::child_len {
|
||||
data.layer0.push(Example_4{
|
||||
data: 0,
|
||||
});
|
||||
}
|
||||
},
|
||||
9 => {
|
||||
if data.layer9[index].child_id.is_some() {return;}
|
||||
let insert = data.layer4.len();
|
||||
data.layer9.reserve(Example0::child_len);
|
||||
data.layer9[index].child_id = Some(insert as u32);
|
||||
for i in 0..Example5::child_len {
|
||||
data.layer4.push(Example0{
|
||||
data: 0,
|
||||
child_id: None,
|
||||
});
|
||||
}
|
||||
},
|
||||
13 => {
|
||||
if data.layer13[index].child_id.is_some() {return;}
|
||||
let insert = data.layer9.len();
|
||||
data.layer13.reserve(Example9::child_len);
|
||||
data.layer13[index].child_id = Some(insert as u32);
|
||||
for i in 0..Example9::child_len {
|
||||
data.layer9.push(Example5{
|
||||
data: [0; 130],
|
||||
child_id: None,
|
||||
});
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn drill_up(data: &mut LodData::<Self>, level: u8, parent_index: usize) {
|
||||
match level {
|
||||
0 => {
|
||||
panic!("SubBlocks_4 does not have children");
|
||||
},
|
||||
4 => {
|
||||
let delete = data.layer4[parent_index].child_id.expect("has no childs to drill up") as usize;
|
||||
data.layer4[parent_index].child_id = None;
|
||||
data.layer0.drain(delete..delete+Example0::child_len);
|
||||
},
|
||||
9 => {
|
||||
let delete = data.layer9[parent_index].child_id.expect("has no childs to drill up") as usize;
|
||||
data.layer9[parent_index].child_id = None;
|
||||
data.layer4.drain(delete..delete+Example5::child_len);
|
||||
},
|
||||
13 => {
|
||||
let delete = data.layer13[parent_index].child_id.expect("has no childs to drill up") as usize;
|
||||
data.layer13[parent_index].child_id = None;
|
||||
data.layer9.drain(delete..delete+Example9::child_len);
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
region::lod::example::ExampleLodConfig,
|
||||
region::lod::example::*,
|
||||
lodstore::LodData,
|
||||
lodstore::index::LodIndex,
|
||||
lodstore::index,
|
||||
};
|
||||
use std::{thread, time, mem::size_of};
|
||||
use vek::*;
|
||||
use rand::Rng;
|
||||
use rand::ThreadRng;
|
||||
|
||||
fn randIndex(rng: &mut ThreadRng) -> LodIndex {
|
||||
let x: u16 = rng.gen();
|
||||
let y: u16 = rng.gen();
|
||||
let z: u16 = rng.gen();
|
||||
LodIndex::new(Vec3::new(x,y,z).map(|x| x as u32))
|
||||
}
|
||||
|
||||
|
||||
pub type Example = LodData<ExampleLodConfig>;
|
||||
|
||||
fn createRegion(p_e5: f32, p_e0: f32, p_e_4: f32, p_foreign: f32) -> Example {
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut result = Example::new();
|
||||
let abs9 = (index::two_pow_u(15-13) as u64).pow(3);
|
||||
let abs5 = (index::two_pow_u(15-9) as u64).pow(3);
|
||||
let abs0 = (index::two_pow_u(15-4) as u64).pow(3);
|
||||
let abs_4 = (index::two_pow_u(15) as u64).pow(3);
|
||||
let act9 = (abs9 as f32 * (1.0+p_foreign) ) as u32;
|
||||
let act5 = (abs5 as f32 * (p_e5*(1.0+p_foreign))) as u32;
|
||||
let act0 = (abs0 as f32 * (p_e0*(1.0+p_foreign))) as u32;
|
||||
let act_4 = (abs_4 as f32 * (p_e_4*(1.0+p_foreign))) as u32;
|
||||
|
||||
let w9 = index::two_pow_u(13) as u32;
|
||||
result.layer13 = vec![Example9::new(); 8*8*8];
|
||||
for x in 0..8 {
|
||||
for y in 0..8 {
|
||||
for z in 0..8 {
|
||||
println!("{:?}", Vec3::new(x*w9,y*w9,z*w9));
|
||||
println!("{:?}", LodIndex::new(Vec3::new(x*w9,y*w9,z*w9)));
|
||||
result.anchor.insert(LodIndex::new(Vec3::new(x*w9,y*w9,z*w9)), (x+y*8+z*8*8) as usize);
|
||||
}
|
||||
}
|
||||
}
|
||||
while result.layer9.len() < act5 as usize {
|
||||
let index = randIndex(&mut rng);
|
||||
let low = index.align_to_layer_id(9);
|
||||
result.make_at_least(low,low,9);
|
||||
}/*
|
||||
while result.layer5.len() < act0 as usize {
|
||||
let index = randIndex(&mut rng);
|
||||
let low = index.align_to_layer_id(5);
|
||||
result.make_at_least(low,low,5);
|
||||
println!("{}", result.layer5.len());
|
||||
}*//*
|
||||
while result.layer0.len() < act_4 as usize {
|
||||
let index = randIndex(&mut rng);
|
||||
let low = index.align_to_layer_id(0);
|
||||
result.make_at_least(low,low,0);
|
||||
}*/
|
||||
|
||||
println!("creating Region with {} 5er, {} 0er, {} -4er", act5, act0 , act_4);
|
||||
println!("created Region l13: {} l9: {} l5: {} l0: {}", result.layer13.len(), result.layer9.len(), result.layer5.len(), result.layer0.len());
|
||||
println!("size {} {} {}", size_of::<Example>(), size_of::<Example9>(), size_of::<Example5>());
|
||||
result
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reagiontest() {
|
||||
let reg = createRegion(0.15, 0.01, 0.001, 0.1);
|
||||
|
||||
thread::sleep(time::Duration::from_secs(4));
|
||||
/*
|
||||
let i = LodIndex::new(Vec3::new(0,0,0));
|
||||
assert_eq!(i.get(), Vec3::new(0,0,0));
|
||||
|
||||
let i = LodIndex::new(Vec3::new(1337,0,0));
|
||||
assert_eq!(i.get(), Vec3::new(1337,0,0));
|
||||
|
||||
let i = LodIndex::new(Vec3::new(0,1337,0));
|
||||
assert_eq!(i.get(), Vec3::new(0,1337,0));
|
||||
|
||||
let i = LodIndex::new(Vec3::new(0,0,1337));
|
||||
assert_eq!(i.get(), Vec3::new(0,0,1337));
|
||||
|
||||
let i = LodIndex::new(Vec3::new(1,1,1));
|
||||
assert_eq!(i.get(), Vec3::new(1,1,1));
|
||||
|
||||
let i = LodIndex::new(Vec3::new(262143,262143,262143));
|
||||
assert_eq!(i.get(), Vec3::new(262143,262143,262143));
|
||||
|
||||
let i = LodIndex::new(Vec3::new(262144,262144,262144)); //overflow
|
||||
assert_eq!(i.get(), Vec3::new(0,0,0));
|
||||
|
||||
let i = LodIndex::new(Vec3::new(42,1337,69));
|
||||
assert_eq!(i.get(), Vec3::new(42,1337,69));
|
||||
*/
|
||||
}
|
||||
}
|
@ -1 +1,2 @@
|
||||
pub mod terrain;
|
||||
pub mod terrain;
|
||||
mod example;
|
@ -1,144 +1,168 @@
|
||||
use crate::lodstore::Layer;
|
||||
use crate::lodstore::LodLayer;
|
||||
use crate::lodstore::{
|
||||
LodData,
|
||||
LayerInfo,
|
||||
LodConfig,
|
||||
index::LodIndex,
|
||||
};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Terrain {
|
||||
// 11 is max
|
||||
Unused11,
|
||||
Region9 { //512m this is for normal simulation if no player nearby
|
||||
precent_air: f32,
|
||||
percent_forrest: f32,
|
||||
percent_lava: f32,
|
||||
percent_water: f32,
|
||||
},
|
||||
Chunk5 {//32m, same detail as region, but to not force block1 everywhere in 512 area
|
||||
precent_air: f32,
|
||||
percent_forrest: f32,
|
||||
percent_lava: f32,
|
||||
percent_water: f32,
|
||||
},
|
||||
Block1 {
|
||||
material: u32,
|
||||
},
|
||||
SubBlock_4 {
|
||||
material: u32,
|
||||
},
|
||||
// -4 is min
|
||||
pub struct Region9 {
|
||||
precent_air: f32,
|
||||
percent_forrest: f32,
|
||||
percent_lava: f32,
|
||||
percent_water: f32,
|
||||
child_id: Option<u32>, // Chunk5 2^(7*3), this is valid
|
||||
}
|
||||
|
||||
impl Terrain {
|
||||
fn new() -> Self {
|
||||
Terrain::Unused11
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Chunk5 {
|
||||
precent_air: f32,
|
||||
percent_forrest: f32,
|
||||
percent_lava: f32,
|
||||
percent_water: f32,
|
||||
child_id: Option<u32>, // see Block0 2^(12*3)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Block0 {
|
||||
material: u32,
|
||||
child_id: Option<u32>,// In reality 2^(16*3) SubBlock_4 should be possible, but 2^48 subblocks would kill anything anyway, so save 2 bytes here
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SubBlock_4 {
|
||||
material: u32,
|
||||
}
|
||||
|
||||
impl LayerInfo for Region9 {
|
||||
fn get_child_index(self: &Self) -> Option<usize> {
|
||||
self.child_id.map(|n| n as usize)
|
||||
}
|
||||
const child_layer_id: Option<u8> = Some(9);
|
||||
const layer_volume: Vec3<u32> = Vec3{x: 16, y: 16, z: 16};
|
||||
const child_len: usize = 4096;//2_usize.pow(Self::child_dim*3);
|
||||
}
|
||||
|
||||
impl LayerInfo for Chunk5 {
|
||||
fn get_child_index(self: &Self) -> Option<usize> {
|
||||
self.child_id.map(|n| n as usize)
|
||||
}
|
||||
const child_layer_id: Option<u8> = Some(4);
|
||||
const layer_volume: Vec3<u32> = Vec3{x: 32, y: 32, z: 32};
|
||||
const child_len: usize = 32768;//2_usize.pow(Self::child_dim*3);
|
||||
}
|
||||
|
||||
impl LayerInfo for Block0 {
|
||||
fn get_child_index(self: &Self) -> Option<usize> {
|
||||
self.child_id.map(|n| n as usize)
|
||||
}
|
||||
const child_layer_id: Option<u8> = Some(0);
|
||||
const layer_volume: Vec3<u32> = Vec3{x: 16, y: 16, z: 16};
|
||||
const child_len: usize = 4096;//2_usize.pow(Self::child_dim*3);
|
||||
}
|
||||
|
||||
impl LayerInfo for SubBlock_4 {
|
||||
fn get_child_index(self: &Self) -> Option<usize> {
|
||||
None
|
||||
}
|
||||
const child_layer_id: Option<u8> = None;
|
||||
const layer_volume: Vec3<u32> = Vec3{x: 1, y: 1, z: 1};
|
||||
const child_len: usize = 0;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TerrainLodConfig {}
|
||||
|
||||
impl LodConfig for TerrainLodConfig {
|
||||
type L0 = SubBlock_4;
|
||||
type L1 = ();
|
||||
type L2 = ();
|
||||
type L3 = ();
|
||||
type L4 = Block0;
|
||||
type L5 = ();
|
||||
type L6 = ();
|
||||
type L7 = ();
|
||||
type L8 = ();
|
||||
type L9 = Chunk5;
|
||||
type L10 = ();
|
||||
type L11 = ();
|
||||
type L12 = ();
|
||||
type L13 = Region9;
|
||||
type L14 = ();
|
||||
type L15 = ();
|
||||
|
||||
const anchor_layer_id: u8 = 13;
|
||||
|
||||
fn setup(&mut self) {
|
||||
|
||||
}
|
||||
|
||||
fn drill_down(data: &mut LodData::<Self>, level: u8, index: usize) {
|
||||
match level {
|
||||
0 => {
|
||||
panic!("cannot drill down further");
|
||||
},
|
||||
4 => {
|
||||
let insert = data.layer0.len();
|
||||
data.layer4[index].child_id = Some(insert as u32);
|
||||
for i in 0..Block0::child_len {
|
||||
data.layer0[i+insert] = SubBlock_4{
|
||||
material: 0,
|
||||
};
|
||||
}
|
||||
},
|
||||
9 => {
|
||||
let insert = data.layer4.len();
|
||||
data.layer9[index].child_id = Some(insert as u32);
|
||||
for i in 0..Chunk5::child_len {
|
||||
data.layer4[i+insert] = Block0{
|
||||
material: 0,
|
||||
child_id: None,
|
||||
};
|
||||
}
|
||||
},
|
||||
13 => {
|
||||
let insert = data.layer9.len();
|
||||
data.layer13[index].child_id = Some(insert as u32);
|
||||
for i in 0..Region9::child_len {
|
||||
data.layer9[i+insert] = Chunk5{
|
||||
precent_air: 0.2,
|
||||
percent_forrest: 0.3,
|
||||
percent_lava: 0.4,
|
||||
percent_water: 0.1,
|
||||
child_id: None,
|
||||
};
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn drill_up(data: &mut LodData::<Self>, level: u8, parent_index: usize) {
|
||||
match level {
|
||||
0 => {
|
||||
panic!("SubBlocks_4 does not have children");
|
||||
},
|
||||
4 => {
|
||||
let delete = data.layer4[parent_index].child_id.expect("has no childs to drill up") as usize;
|
||||
data.layer4[parent_index].child_id = None;
|
||||
data.layer0.drain(delete..delete+Block0::child_len);
|
||||
},
|
||||
9 => {
|
||||
let delete = data.layer9[parent_index].child_id.expect("has no childs to drill up") as usize;
|
||||
data.layer9[parent_index].child_id = None;
|
||||
data.layer4.drain(delete..delete+Chunk5::child_len);
|
||||
},
|
||||
13 => {
|
||||
let delete = data.layer13[parent_index].child_id.expect("has no childs to drill up") as usize;
|
||||
data.layer13[parent_index].child_id = None;
|
||||
data.layer9.drain(delete..delete+Region9::child_len);
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const LAYER5: i8 = 11;
|
||||
const LAYER4: i8 = 9;
|
||||
const LAYER3: i8 = 5;
|
||||
const LAYER2: i8 = 0;
|
||||
const LAYER1: i8 = -4;
|
||||
|
||||
|
||||
impl Layer for Terrain {
|
||||
fn new() -> LodLayer<Terrain> {
|
||||
let mut n = LodLayer::<Terrain>::new_data(Terrain::Unused11);
|
||||
Self::drill_down(&mut n);
|
||||
n
|
||||
}
|
||||
|
||||
fn get_level(layer: &LodLayer<Self>) -> i8 {
|
||||
match &layer.data {
|
||||
Terrain::Unused11 => LAYER5,
|
||||
Terrain::Region9{..} => LAYER4,
|
||||
Terrain::Chunk5{..} => LAYER3,
|
||||
Terrain::Block1{..} => LAYER2,
|
||||
Terrain::SubBlock_4{..} => -LAYER1,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_lower_level(layer: &LodLayer<Self>) -> Option<i8> {
|
||||
match &layer.data {
|
||||
Terrain::Unused11 => Some(LAYER4),
|
||||
Terrain::Region9{..} => Some(LAYER3),
|
||||
Terrain::Chunk5{..} => Some(LAYER2),
|
||||
Terrain::Block1{..} => Some(LAYER1),
|
||||
Terrain::SubBlock_4{..} => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn drill_down(layer: &mut LodLayer<Terrain>) {
|
||||
match &layer.data {
|
||||
Terrain::Unused11 => {
|
||||
let n = LodLayer::new_data(Terrain::Region9{
|
||||
precent_air: 1.0,
|
||||
percent_forrest: 0.0,
|
||||
percent_lava: 0.0,
|
||||
percent_water: 0.0,
|
||||
});
|
||||
layer.childs = vec![n; 2_usize.pow((LAYER5-LAYER4) as u32 *3)];
|
||||
},
|
||||
Terrain::Region9{..} => {
|
||||
let n = LodLayer::new_data(Terrain::Chunk5{
|
||||
precent_air: 1.0,
|
||||
percent_forrest: 0.0,
|
||||
percent_lava: 0.0,
|
||||
percent_water: 0.0,
|
||||
});
|
||||
layer.childs = vec![n; 2_usize.pow((LAYER4-LAYER3) as u32 *3)];
|
||||
},
|
||||
Terrain::Chunk5{..} => {
|
||||
let n = LodLayer::new_data( Terrain::Block1{
|
||||
material: 10,
|
||||
});
|
||||
layer.childs = vec![n; 2_usize.pow((LAYER3-LAYER2) as u32 *3)];
|
||||
},
|
||||
Terrain::Block1{..} => {
|
||||
let n = LodLayer::new_data( Terrain::SubBlock_4{
|
||||
material: 10,
|
||||
});
|
||||
layer.childs = vec![n; 2_usize.pow((LAYER2-LAYER1) as u32 *3)];
|
||||
},
|
||||
Terrain::SubBlock_4{..} => {
|
||||
panic!("cannot drillDown further")
|
||||
},
|
||||
}
|
||||
}
|
||||
fn drill_up(parent: &mut LodLayer<Terrain>) {
|
||||
match &parent.data {
|
||||
Terrain::Unused11 => {
|
||||
panic!("cannot drillUp further")
|
||||
},
|
||||
Terrain::Region9{..} => {
|
||||
//recalculate values here
|
||||
parent.data = Terrain::Region9{
|
||||
precent_air: 1.0,
|
||||
percent_forrest: 0.0,
|
||||
percent_lava: 0.0,
|
||||
percent_water: 0.0,
|
||||
};
|
||||
parent.childs = vec![];
|
||||
},
|
||||
Terrain::Chunk5{..} => {
|
||||
parent.data = Terrain::Chunk5{
|
||||
precent_air: 1.0,
|
||||
percent_forrest: 0.0,
|
||||
percent_lava: 0.0,
|
||||
percent_water: 0.0,
|
||||
};
|
||||
parent.childs = vec![];
|
||||
},
|
||||
Terrain::Block1{..} => {
|
||||
parent.data = Terrain::Block1{
|
||||
material: 10,
|
||||
};
|
||||
parent.childs = vec![];
|
||||
},
|
||||
Terrain::SubBlock_4{..} => {
|
||||
parent.data = Terrain::SubBlock_4{
|
||||
material: 10,
|
||||
};
|
||||
parent.childs = vec![];
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
pub type Terrain = LodData<TerrainLodConfig>;
|
@ -5,8 +5,6 @@ use std::sync::Arc;
|
||||
use crate::{
|
||||
regionmanager::meta::RegionId,
|
||||
job::JobManager,
|
||||
lodstore::LodLayer,
|
||||
lodstore::Layer,
|
||||
};
|
||||
use lod::terrain::Terrain;
|
||||
|
||||
@ -15,11 +13,11 @@ pub struct Region {
|
||||
id: RegionId,
|
||||
jobmanager: Arc<JobManager>,
|
||||
|
||||
pub block: LodLayer<Terrain>,
|
||||
temp: LodLayer<Terrain>,
|
||||
light: LodLayer<Terrain>,
|
||||
evil: LodLayer<Terrain>,
|
||||
civ: LodLayer<Terrain>,
|
||||
pub block: Terrain,
|
||||
temp: Terrain,
|
||||
light: Terrain,
|
||||
evil: Terrain,
|
||||
civ: Terrain,
|
||||
}
|
||||
|
||||
impl Region {
|
||||
@ -36,6 +34,39 @@ impl Region {
|
||||
}
|
||||
}
|
||||
|
||||
fn rasterize(region: &Region) -> Vec<u64> {
|
||||
let mut res = Vec::new();
|
||||
|
||||
// iterate over all Region9 / chunk5 / Block0 / subBlock that dont have children in RECT XYZ
|
||||
//region.block
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn plant_trees(region: &Region) -> Vec<u64> {
|
||||
let mut res = Vec::new();
|
||||
|
||||
// iterate over all Region9 / chunk5 / Block0 / subBlock that dont have children in RECT XYZ
|
||||
// acces blocks around
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn corrosion(region: &Region) -> Vec<u64> {
|
||||
let mut res = Vec::new();
|
||||
|
||||
// iterate over all Region9 / chunk5 / Block0 / subBlock that dont have children in RECT XYZ
|
||||
// access neighbours
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
pub type aaa = LodLayer<e::Terain>;
|
||||
@ -48,6 +79,7 @@ fn example() {
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
@ -84,4 +116,6 @@ mod tests {
|
||||
let mut r = Region::new((0,0), Arc::new(JobManager::new()));
|
||||
r.block.make_at_least(Vec3::new(0,0,0), Vec3::new(65535,65535,65535), -4);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
@ -71,9 +71,11 @@ impl Server {
|
||||
println!("new server found");
|
||||
},
|
||||
RegionManagerMsg::CreateRegion{region_id} => {
|
||||
/*
|
||||
let mut r = Region::new(region_id, self.jobmanager.clone());
|
||||
r.block.make_at_least(Vec3::new(0,0,0), Vec3::new(65535,65535,65535), 9);
|
||||
self.region.insert(region_id, r);
|
||||
*/
|
||||
println!("create region");
|
||||
},
|
||||
RegionManagerMsg::TakeOverRegionFrom{region_id, server_id} => {
|
||||
|
Loading…
Reference in New Issue
Block a user