mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
work on a deltas, to store the diff while working on data.
this state does not work, because i tried to iplement delta in a trait type. however this is not necessary, i will revert this. Just keep this commit for historical reasons - it wont build.
This commit is contained in:
parent
536ef3d6ff
commit
d5dca4f6e8
22
worldsim/src/lodstore/area.rs
Normal file
22
worldsim/src/lodstore/area.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
use super::index::{
|
||||||
|
LodIndex,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
A LodArea is the area between 2 LodIndex
|
||||||
|
*/
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
|
||||||
|
pub struct LodArea {
|
||||||
|
pub lower: LodIndex,
|
||||||
|
pub upper: LodIndex,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LodArea {
|
||||||
|
pub fn new(lower: LodIndex, upper: LodIndex) -> Self {
|
||||||
|
LodArea {
|
||||||
|
lower,
|
||||||
|
upper,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
433
worldsim/src/lodstore/data.rs
Normal file
433
worldsim/src/lodstore/data.rs
Normal file
@ -0,0 +1,433 @@
|
|||||||
|
use std::u32;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use vek::*;
|
||||||
|
use super::index::{
|
||||||
|
self,
|
||||||
|
LodIndex,
|
||||||
|
AbsIndex,
|
||||||
|
relative_to_1d,
|
||||||
|
two_pow_u,
|
||||||
|
};
|
||||||
|
use super::area::{
|
||||||
|
LodArea,
|
||||||
|
};
|
||||||
|
use super::delta::{
|
||||||
|
LodDelta,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
LOD Data contains different Entries in different Vecs, every entry has a "pointer" to it's child start.
|
||||||
|
This is the structure to store a region and all subscribed information
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub trait LodIntoOptionUsize: Copy {
|
||||||
|
fn is_some(self) -> bool;
|
||||||
|
fn into_usize(self) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LodConfig {
|
||||||
|
type L0: Clone; // 2^-4
|
||||||
|
type L1: Clone;
|
||||||
|
type L2: Clone;
|
||||||
|
type L3: Clone;
|
||||||
|
type L4: Clone; // 2^0
|
||||||
|
type L5: Clone;
|
||||||
|
type L6: Clone;
|
||||||
|
type L7: Clone;
|
||||||
|
type L8: Clone;
|
||||||
|
type L9: Clone;
|
||||||
|
type L10: Clone;
|
||||||
|
type L11: Clone;
|
||||||
|
type L12: Clone;
|
||||||
|
type L13: Clone;
|
||||||
|
type L14: Clone;
|
||||||
|
type L15: Clone; // 2^11
|
||||||
|
|
||||||
|
type I0: LodIntoOptionUsize;
|
||||||
|
type I1: LodIntoOptionUsize;
|
||||||
|
type I2: LodIntoOptionUsize;
|
||||||
|
type I3: LodIntoOptionUsize;
|
||||||
|
type I4: LodIntoOptionUsize;
|
||||||
|
type I5: LodIntoOptionUsize;
|
||||||
|
type I6: LodIntoOptionUsize;
|
||||||
|
type I7: LodIntoOptionUsize;
|
||||||
|
type I8: LodIntoOptionUsize;
|
||||||
|
type I9: LodIntoOptionUsize;
|
||||||
|
type I10: LodIntoOptionUsize;
|
||||||
|
type I11: LodIntoOptionUsize;
|
||||||
|
type I12: LodIntoOptionUsize;
|
||||||
|
type I13: LodIntoOptionUsize;
|
||||||
|
type I14: LodIntoOptionUsize;
|
||||||
|
type I15: LodIntoOptionUsize;
|
||||||
|
|
||||||
|
type Delta: LodDelta;
|
||||||
|
type Additional;
|
||||||
|
|
||||||
|
/*
|
||||||
|
The Anchor marks the entrypoint for the LodStore, every access is done by HashLookup > VecAccess > VecAccess > VecAccess > ...
|
||||||
|
The first lookup is done in a HashMap, because this way we don't need to create alot of data
|
||||||
|
//TODO: Evaluate if we should drop the anchor design and make L15 as anchor, but on the other hand allow empty data where we have index data
|
||||||
|
Choose the anchor_layer wisely in order to minimize CPU and MEMORY consumption
|
||||||
|
*/
|
||||||
|
const anchor_layer_id: u8;
|
||||||
|
|
||||||
|
const layer_volume: [Vec3<u32>; 16]; // number of elements on this layer as Vec3 (not on child layer!)
|
||||||
|
const child_layer_id: [Option<u8>; 16]; // layer below this one
|
||||||
|
const layer_len: [usize; 16] = [ // optimisation for layer_volume, total no of elements as usize
|
||||||
|
(Self::layer_volume[0].x * Self::layer_volume[0].y * Self::layer_volume[0].z) as usize,
|
||||||
|
(Self::layer_volume[1].x * Self::layer_volume[1].y * Self::layer_volume[1].z) as usize,
|
||||||
|
(Self::layer_volume[2].x * Self::layer_volume[2].y * Self::layer_volume[2].z) as usize,
|
||||||
|
(Self::layer_volume[3].x * Self::layer_volume[3].y * Self::layer_volume[3].z) as usize,
|
||||||
|
(Self::layer_volume[4].x * Self::layer_volume[4].y * Self::layer_volume[4].z) as usize,
|
||||||
|
(Self::layer_volume[5].x * Self::layer_volume[5].y * Self::layer_volume[5].z) as usize,
|
||||||
|
(Self::layer_volume[6].x * Self::layer_volume[6].y * Self::layer_volume[6].z) as usize,
|
||||||
|
(Self::layer_volume[7].x * Self::layer_volume[7].y * Self::layer_volume[7].z) as usize,
|
||||||
|
(Self::layer_volume[8].x * Self::layer_volume[8].y * Self::layer_volume[8].z) as usize,
|
||||||
|
(Self::layer_volume[9].x * Self::layer_volume[9].y * Self::layer_volume[9].z) as usize,
|
||||||
|
(Self::layer_volume[10].x * Self::layer_volume[10].y * Self::layer_volume[10].z) as usize,
|
||||||
|
(Self::layer_volume[11].x * Self::layer_volume[11].y * Self::layer_volume[11].z) as usize,
|
||||||
|
(Self::layer_volume[12].x * Self::layer_volume[12].y * Self::layer_volume[12].z) as usize,
|
||||||
|
(Self::layer_volume[13].x * Self::layer_volume[13].y * Self::layer_volume[13].z) as usize,
|
||||||
|
(Self::layer_volume[14].x * Self::layer_volume[14].y * Self::layer_volume[14].z) as usize,
|
||||||
|
(Self::layer_volume[15].x * Self::layer_volume[15].y * Self::layer_volume[15].z) as usize,
|
||||||
|
];
|
||||||
|
|
||||||
|
fn setup(&mut self);
|
||||||
|
fn drill_down(data: &mut LodData::<Self>, abs: AbsIndex, delta: &mut Option<Self::Delta>) where Self: Sized;
|
||||||
|
fn drill_up(data: &mut LodData::<Self>, parent_abs: AbsIndex, delta: &mut Option<Self::Delta>) where Self: Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct LodData<X: LodConfig> {
|
||||||
|
pub layer0: Vec<X::L0>, // 1/16
|
||||||
|
pub layer1: Vec<X::L1>, // 1/8
|
||||||
|
pub layer2: Vec<X::L2>, // 1/4
|
||||||
|
pub layer3: Vec<X::L3>, // 1/2
|
||||||
|
pub layer4: Vec<X::L4>, // 1
|
||||||
|
pub layer5: Vec<X::L5>, // 2
|
||||||
|
pub layer6: Vec<X::L6>, // 4
|
||||||
|
pub layer7: Vec<X::L7>, // 8
|
||||||
|
pub layer8: Vec<X::L8>, // 16
|
||||||
|
pub layer9: Vec<X::L9>, // 32
|
||||||
|
pub layer10: Vec<X::L10>, // 64
|
||||||
|
pub layer11: Vec<X::L11>, // 128
|
||||||
|
pub layer12: Vec<X::L12>, // 256
|
||||||
|
pub layer13: Vec<X::L13>, // 512
|
||||||
|
pub layer14: Vec<X::L14>, // 1024
|
||||||
|
pub layer15: Vec<X::L15>, // 2048
|
||||||
|
|
||||||
|
pub child0: Vec<X::I0>,
|
||||||
|
pub child1: Vec<X::I1>,
|
||||||
|
pub child2: Vec<X::I2>,
|
||||||
|
pub child3: Vec<X::I3>,
|
||||||
|
pub child4: Vec<X::I4>,
|
||||||
|
pub child5: Vec<X::I5>,
|
||||||
|
pub child6: Vec<X::I6>,
|
||||||
|
pub child7: Vec<X::I7>,
|
||||||
|
pub child8: Vec<X::I8>,
|
||||||
|
pub child9: Vec<X::I9>,
|
||||||
|
pub child10: Vec<X::I10>,
|
||||||
|
pub child11: Vec<X::I11>,
|
||||||
|
pub child12: Vec<X::I12>,
|
||||||
|
pub child13: Vec<X::I13>,
|
||||||
|
pub child14: Vec<X::I14>,
|
||||||
|
pub child15: Vec<X::I15>,
|
||||||
|
|
||||||
|
pub anchor: HashMap<LodIndex, usize>,
|
||||||
|
pub additional: Option<X::Additional>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<X: LodConfig> LodData<X>
|
||||||
|
{
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
layer0: Vec::new(),
|
||||||
|
layer1: Vec::new(),
|
||||||
|
layer2: Vec::new(),
|
||||||
|
layer3: Vec::new(),
|
||||||
|
layer4: Vec::new(),
|
||||||
|
layer5: Vec::new(),
|
||||||
|
layer6: Vec::new(),
|
||||||
|
layer7: Vec::new(),
|
||||||
|
layer8: Vec::new(),
|
||||||
|
layer9: Vec::new(),
|
||||||
|
layer10: Vec::new(),
|
||||||
|
layer11: Vec::new(),
|
||||||
|
layer12: Vec::new(),
|
||||||
|
layer13: Vec::new(),
|
||||||
|
layer14: Vec::new(),
|
||||||
|
layer15: Vec::new(),
|
||||||
|
child0: Vec::new(),
|
||||||
|
child1: Vec::new(),
|
||||||
|
child2: Vec::new(),
|
||||||
|
child3: Vec::new(),
|
||||||
|
child4: Vec::new(),
|
||||||
|
child5: Vec::new(),
|
||||||
|
child6: Vec::new(),
|
||||||
|
child7: Vec::new(),
|
||||||
|
child8: Vec::new(),
|
||||||
|
child9: Vec::new(),
|
||||||
|
child10: Vec::new(),
|
||||||
|
child11: Vec::new(),
|
||||||
|
child12: Vec::new(),
|
||||||
|
child13: Vec::new(),
|
||||||
|
child14: Vec::new(),
|
||||||
|
child15: Vec::new(),
|
||||||
|
anchor: HashMap::new(),
|
||||||
|
additional: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dynamically dispatches the get_child_index, this is most prob the bottleneck function.
|
||||||
|
// evaluate the performacne impact!!!
|
||||||
|
fn int_get_child_index(&self, abs: AbsIndex) -> usize {
|
||||||
|
match abs.layer {
|
||||||
|
0 => self.child0[abs.index].into_usize(),
|
||||||
|
1 => self.child1[abs.index].into_usize(),
|
||||||
|
2 => self.child2[abs.index].into_usize(),
|
||||||
|
3 => self.child3[abs.index].into_usize(),
|
||||||
|
4 => self.child4[abs.index].into_usize(),
|
||||||
|
5 => self.child5[abs.index].into_usize(),
|
||||||
|
6 => self.child6[abs.index].into_usize(),
|
||||||
|
7 => self.child7[abs.index].into_usize(),
|
||||||
|
8 => self.child8[abs.index].into_usize(),
|
||||||
|
9 => self.child9[abs.index].into_usize(),
|
||||||
|
10 => self.child10[abs.index].into_usize(),
|
||||||
|
11 => self.child11[abs.index].into_usize(),
|
||||||
|
12 => self.child12[abs.index].into_usize(),
|
||||||
|
13 => self.child13[abs.index].into_usize(),
|
||||||
|
14 => self.child14[abs.index].into_usize(),
|
||||||
|
15 => self.child15[abs.index].into_usize(),
|
||||||
|
_ => panic!("wrong abs index"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the childs AbsIndex of Parent AbsIndex
|
||||||
|
// child_lod must lie within parent
|
||||||
|
// uses parent_lod as buffer, to not calculate it again
|
||||||
|
// uses parent_child_index as a buffer, to not calculate it again
|
||||||
|
fn int_get(parent_abs: AbsIndex, child_lod: LodIndex, parent_lod: LodIndex, parent_child_index: usize) -> AbsIndex {
|
||||||
|
let child_layer = X::child_layer_id[parent_abs.layer as usize].unwrap();
|
||||||
|
let child_lod = child_lod.align_to_layer_id(child_layer);
|
||||||
|
let child_offset = relative_to_1d(child_lod, parent_lod, child_layer, X::layer_volume[child_layer as usize]);
|
||||||
|
//println!("{} int_get - parent_abs {} child_lod {} parent_lod {} parent_child_index {} child_offset {}", Self::debug_offset(parent_abs.layer), parent_abs, child_lod, parent_lod, parent_child_index, child_offset);
|
||||||
|
AbsIndex::new(child_layer, parent_child_index + child_offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
// slower variant of int_get which requiere self lookups
|
||||||
|
fn int_get_lockup(&self, parent_abs: AbsIndex, child_lod: LodIndex) -> AbsIndex {
|
||||||
|
let parent_lod = child_lod.align_to_layer_id(parent_abs.layer);
|
||||||
|
let parent_child_index = self.int_get_child_index(parent_abs);
|
||||||
|
Self::int_get(parent_abs, child_lod, parent_lod, parent_child_index)
|
||||||
|
}
|
||||||
|
|
||||||
|
// target_layer is requiered because same LodIndex can exist for multiple layers, and guessing is stupid here
|
||||||
|
fn int_recursive_get(&self, parent_abs: AbsIndex, child_lod: LodIndex, target_layer:u8) -> AbsIndex {
|
||||||
|
let mut parent_abs = parent_abs;
|
||||||
|
while true {
|
||||||
|
//println!("{} int_recursive_get {} - {}", Self::debug_offset(parent_abs.layer), parent_abs, target_layer);
|
||||||
|
parent_abs = self.int_get_lockup(parent_abs, child_lod);
|
||||||
|
if parent_abs.layer <= target_layer {
|
||||||
|
return parent_abs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn int_get_n(&self, index: LodIndex, layer: u8) -> AbsIndex {
|
||||||
|
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
||||||
|
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
||||||
|
let wanted_abs = self.int_recursive_get(anchor_abs, index, layer);
|
||||||
|
debug_assert_eq!(wanted_abs.layer, layer);
|
||||||
|
wanted_abs
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get15(&self, index: LodIndex) -> &X::L15 { &self.layer15[self.int_get_n(index,15).index] }
|
||||||
|
|
||||||
|
pub fn get14(&self, index: LodIndex) -> &X::L14 { &self.layer14[self.int_get_n(index,14).index] }
|
||||||
|
|
||||||
|
pub fn get13(&self, index: LodIndex) -> &X::L13 { &self.layer13[self.int_get_n(index,13).index] }
|
||||||
|
|
||||||
|
pub fn get12(&self, index: LodIndex) -> &X::L12 { &self.layer12[self.int_get_n(index,12).index] }
|
||||||
|
|
||||||
|
pub fn get11(&self, index: LodIndex) -> &X::L11 { &self.layer11[self.int_get_n(index,11).index] }
|
||||||
|
|
||||||
|
pub fn get10(&self, index: LodIndex) -> &X::L10 { &self.layer10[self.int_get_n(index,10).index] }
|
||||||
|
|
||||||
|
pub fn get9(&self, index: LodIndex) -> &X::L9 {
|
||||||
|
&self.layer9[self.int_get_n(index,9).index]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get8(&self, index: LodIndex) -> &X::L8 {
|
||||||
|
&self.layer8[self.int_get_n(index,8).index]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get7(&self, index: LodIndex) -> &X::L7 {
|
||||||
|
&self.layer7[self.int_get_n(index,7).index]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get6(&self, index: LodIndex) -> &X::L6 {
|
||||||
|
&self.layer6[self.int_get_n(index,6).index]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get5(&self, index: LodIndex) -> &X::L5 {
|
||||||
|
&self.layer5[self.int_get_n(index,5).index]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get4(&self, index: LodIndex) -> &X::L4 {
|
||||||
|
&self.layer4[self.int_get_n(index,4).index]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get3(&self, index: LodIndex) -> &X::L3 {
|
||||||
|
&self.layer3[self.int_get_n(index,3).index]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get2(&self, index: LodIndex) -> &X::L2 {
|
||||||
|
&self.layer2[self.int_get_n(index,2).index]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get1(&self, index: LodIndex) -> &X::L1 {
|
||||||
|
&self.layer1[self.int_get_n(index,1).index]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get0(&self, index: LodIndex) -> &X::L0 {
|
||||||
|
&self.layer0[self.int_get_n(index,0).index]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set15(&mut self, index: LodIndex, value: X::L15, delta: Option<X::Delta>) {
|
||||||
|
let n = self.int_get_n(index,15).index;
|
||||||
|
delta.map(|d| d.changed15(index, Some(value.clone())));
|
||||||
|
self.layer15[n] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns the last LodIndex, that belongs to a parent AbsIndex
|
||||||
|
fn get_last_child_lod(parent: LodIndex, parent_layer: u8) -> LodIndex {
|
||||||
|
let child_width = two_pow_u(X::child_layer_id[parent_layer as usize].unwrap()) as u32;
|
||||||
|
parent + LodIndex::new(X::layer_volume[X::child_layer_id[parent_layer as usize].unwrap() as usize].map(|e| (e-1)*child_width))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn debug_offset(layer: u8) -> &'static str {
|
||||||
|
match layer {
|
||||||
|
0 => " | ",
|
||||||
|
4 => " ---- ",
|
||||||
|
5 => " ----- ",
|
||||||
|
9 => " ---------- ",
|
||||||
|
13 => " ------------- ",
|
||||||
|
_ => panic!("aaa"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
lower: must always be a LodIndex inside parent
|
||||||
|
upper: must always have same parent as lower -> parent
|
||||||
|
*/
|
||||||
|
fn int_make_at_least(&mut self, parent: AbsIndex, /*parent_lod2: LodIndex,*/ area: LodArea, target_layer: u8, delta: &mut Option<X::Delta>) {
|
||||||
|
let child_layer = X::child_layer_id[parent.layer as usize];
|
||||||
|
let parent_lod_width = two_pow_u(parent.layer) as u32;
|
||||||
|
let parent_lod = area.lower.align_to_layer_id(parent.layer);
|
||||||
|
//assert_eq!(parent_lod, parent_lod2);
|
||||||
|
//println!("{} lower, upper {} {} {} - {:?}", Self::debug_offset(parent.layer), area.lower, area.upper, parent_lod_width, child_layer);
|
||||||
|
if parent.layer > target_layer {
|
||||||
|
// create necessary childs:
|
||||||
|
X::drill_down(self, parent, delta);
|
||||||
|
//println!("{} DRILLED DOWN", Self::debug_offset(parent.layer));
|
||||||
|
if child_layer.is_some() && child_layer.unwrap() > target_layer {
|
||||||
|
let child_layer = child_layer.unwrap();
|
||||||
|
let child_lod_width = two_pow_u(child_layer) as u32;
|
||||||
|
//calc childs which needs to be called recusivly, there childs will be the new parents
|
||||||
|
let child_lower = area.lower.align_to_layer_id(child_layer);
|
||||||
|
let child_upper = area.upper.align_to_layer_id(child_layer);
|
||||||
|
let child_base_abs_index = self.int_get_child_index(parent);
|
||||||
|
let child_volume = X::layer_volume[child_layer as usize];
|
||||||
|
// loop over childs and calculate correct lower and
|
||||||
|
let lower_xyz = (child_lower.get()-parent_lod.get()).map(|e| e / child_lod_width);
|
||||||
|
let upper_xyz = (child_upper.get()-parent_lod.get()).map(|e| e / child_lod_width);
|
||||||
|
//println!("{} lxyz {}", Self::debug_offset(parent.layer), lower_xyz);
|
||||||
|
//println!("{} uxyz {}", Self::debug_offset(parent.layer), upper_xyz);
|
||||||
|
//println!("{} child_lod_width {}", Self::debug_offset(parent.layer), child_lod_width);
|
||||||
|
for x in lower_xyz[0]..upper_xyz[0]+1 {
|
||||||
|
for y in lower_xyz[1]..upper_xyz[1]+1 {
|
||||||
|
for z in lower_xyz[2]..upper_xyz[2]+1 {
|
||||||
|
//println!("{} xyz {} {} {}", Self::debug_offset(parent.layer), x, y, z);
|
||||||
|
//calculate individual abs values, because we now, how they are ordered in the vec
|
||||||
|
let child_abs_index = child_base_abs_index + (x * child_volume[2] * child_volume[1] + y * child_volume[2] + z) as usize;
|
||||||
|
let child_abs = AbsIndex::new(child_layer, child_abs_index);
|
||||||
|
let child_lower = parent_lod + LodIndex::new(Vec3::new(x * child_lod_width, y * child_lod_width, z * child_lod_width));
|
||||||
|
let child_upper = child_lower + LodIndex::new(Vec3::new(child_lod_width-1, child_lod_width-1, child_lod_width-1));
|
||||||
|
|
||||||
|
let inner_lower = index::max(area.lower, child_lower);
|
||||||
|
let inner_upper = index::min(area.upper, child_upper);
|
||||||
|
//println!("{} restrict {} {} to {} {}", Self::debug_offset(parent.layer), area.lower, area.upper, inner_lower, inner_upper);
|
||||||
|
let inner_area = LodArea::new(inner_lower, inner_upper);
|
||||||
|
Self::int_make_at_least(self, child_abs, inner_area, target_layer, delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
These functions allow you to make the LodLayer provide a certain LOD for the specified area
|
||||||
|
*/
|
||||||
|
/*is at least minimum or maximum*/
|
||||||
|
|
||||||
|
pub fn make_at_least(&mut self, area: LodArea, target_layer: u8, delta: &mut Option<X::Delta>) {
|
||||||
|
let anchor_layer_id = X::anchor_layer_id;
|
||||||
|
let anchor_lower = area.lower.align_to_layer_id(anchor_layer_id);
|
||||||
|
let anchor_upper = area.upper.align_to_layer_id(anchor_layer_id);
|
||||||
|
let lower_xyz = anchor_lower.get();
|
||||||
|
let upper_xyz = anchor_upper.get();
|
||||||
|
let anchor_width = index::two_pow_u(anchor_layer_id) as u32;
|
||||||
|
let mut x = lower_xyz[0];
|
||||||
|
//println!("{} xxx lower, upper {} {} {}", Self::debug_offset(anchor_layer_id), lower_xyz, upper_xyz, anchor_width);
|
||||||
|
while x <= upper_xyz[0] {
|
||||||
|
let mut y = lower_xyz[1];
|
||||||
|
while y <= upper_xyz[1] {
|
||||||
|
let mut z = lower_xyz[2];
|
||||||
|
while z <= upper_xyz[2] {
|
||||||
|
let anchor_lod = LodIndex::new(Vec3::new(x,y,z));
|
||||||
|
let anchor_abs = AbsIndex::new(anchor_layer_id, self.anchor[&anchor_lod]); ;
|
||||||
|
if anchor_abs.layer > target_layer {
|
||||||
|
X::drill_down(self, anchor_abs, delta);
|
||||||
|
let child_lod_upper = Self::get_last_child_lod(anchor_lod, anchor_abs.layer);
|
||||||
|
|
||||||
|
let inner_lower = index::max(area.lower, anchor_lod);
|
||||||
|
let inner_upper = index::min(area.upper, child_lod_upper);
|
||||||
|
|
||||||
|
//println!("{}call child with lower, upper {} {} instead of {} {} ", Self::debug_offset(anchor_layer_id), inner_lower, inner_upper, anchor_lod, child_lod_upper);
|
||||||
|
let inner_area = LodArea::new(inner_lower, inner_upper);
|
||||||
|
self.int_make_at_least(anchor_abs, inner_area, target_layer, delta);
|
||||||
|
}
|
||||||
|
z += anchor_width;
|
||||||
|
}
|
||||||
|
y += anchor_width;
|
||||||
|
}
|
||||||
|
x += anchor_width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn make_at_most(&mut self, area: LodArea, layer: i8) {
|
||||||
|
|
||||||
|
}
|
||||||
|
fn make_exactly(&mut self, area: LodArea, layer: i8) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LodIntoOptionUsize for () {
|
||||||
|
fn is_some(self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
fn into_usize(self) -> usize {
|
||||||
|
unreachable!("dummyUsize")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LodIntoOptionUsize for u32 {
|
||||||
|
fn is_some(self) -> bool {
|
||||||
|
self != u32::MAX
|
||||||
|
}
|
||||||
|
fn into_usize(self) -> usize {
|
||||||
|
self as usize
|
||||||
|
}
|
||||||
|
}
|
97
worldsim/src/lodstore/delta.rs
Normal file
97
worldsim/src/lodstore/delta.rs
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
use super::{
|
||||||
|
data::{
|
||||||
|
LodData,
|
||||||
|
LodConfig,
|
||||||
|
},
|
||||||
|
index::LodIndex,
|
||||||
|
area::LodArea,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
A LodDelta applies a change to a Lod
|
||||||
|
The rules for LodDeltas are strict in order to make them as simple as possible.
|
||||||
|
A LodDelta created from LodData A can only be applied safely to another LodData equal to A.
|
||||||
|
However LodDeltas can be combined and reverted
|
||||||
|
|
||||||
|
I am not sure about a Vec or Hashmap, the thing is Vec is easier to fill, but might contain duplicate entries:
|
||||||
|
E.g. change a item multiple time, bloats the Delta, with a Hashmap only the lastest state is kept.
|
||||||
|
However i belive that most algorithms only change every Value once.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub trait LodDelta {
|
||||||
|
type Config: LodConfig;
|
||||||
|
|
||||||
|
fn apply(&self, data: &mut LodData::<Self::Config>);
|
||||||
|
fn filter(&self, area: LodArea) -> Self;
|
||||||
|
|
||||||
|
fn changed0(&mut self, index: LodIndex, value: Option<<Self::Config as LodConfig>::L0>);
|
||||||
|
fn changed15(&mut self, index: LodIndex, value: Option<<Self::Config as LodConfig>::L15>);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct DefaultLodDelta<X: LodConfig> {
|
||||||
|
pub layer0: Vec<(LodIndex, Option<X::L0>)>, // 1/16
|
||||||
|
pub layer1: Vec<(LodIndex, Option<X::L1>)>, // 1/8
|
||||||
|
pub layer2: Vec<(LodIndex, Option<X::L2>)>, // 1/4
|
||||||
|
pub layer3: Vec<(LodIndex, Option<X::L3>)>, // 1/2
|
||||||
|
pub layer4: Vec<(LodIndex, Option<X::L4>)>, // 1
|
||||||
|
pub layer5: Vec<(LodIndex, Option<X::L5>)>, // 2
|
||||||
|
pub layer6: Vec<(LodIndex, Option<X::L6>)>, // 4
|
||||||
|
pub layer7: Vec<(LodIndex, Option<X::L7>)>, // 8
|
||||||
|
pub layer8: Vec<(LodIndex, Option<X::L8>)>, // 16
|
||||||
|
pub layer9: Vec<(LodIndex, Option<X::L9>)>, // 32
|
||||||
|
pub layer10: Vec<(LodIndex, Option<X::L10>)>, // 64
|
||||||
|
pub layer11: Vec<(LodIndex, Option<X::L11>)>, // 128
|
||||||
|
pub layer12: Vec<(LodIndex, Option<X::L12>)>, // 256
|
||||||
|
pub layer13: Vec<(LodIndex, Option<X::L13>)>, // 512
|
||||||
|
pub layer14: Vec<(LodIndex, Option<X::L14>)>, // 1024
|
||||||
|
pub layer15: Vec<(LodIndex, Option<X::L15>)>, // 2048
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<X: LodConfig> DefaultLodDelta<X> {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
layer0: Vec::new(),
|
||||||
|
layer1: Vec::new(),
|
||||||
|
layer2: Vec::new(),
|
||||||
|
layer3: Vec::new(),
|
||||||
|
layer4: Vec::new(),
|
||||||
|
layer5: Vec::new(),
|
||||||
|
layer6: Vec::new(),
|
||||||
|
layer7: Vec::new(),
|
||||||
|
layer8: Vec::new(),
|
||||||
|
layer9: Vec::new(),
|
||||||
|
layer10: Vec::new(),
|
||||||
|
layer11: Vec::new(),
|
||||||
|
layer12: Vec::new(),
|
||||||
|
layer13: Vec::new(),
|
||||||
|
layer14: Vec::new(),
|
||||||
|
layer15: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<X: LodConfig> LodDelta for DefaultLodDelta<X> {
|
||||||
|
type Config = X;
|
||||||
|
|
||||||
|
//TODO: apply that moves out
|
||||||
|
fn apply(&self, data: &mut LodData::<Self::Config>) {
|
||||||
|
for (index, item) in &self.layer15 {
|
||||||
|
if item.is_some() {
|
||||||
|
data.set15(*index, item.clone().unwrap(), None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn filter(&self, area: LodArea) -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn changed0(&mut self, index: LodIndex, value: Option<<Self::Config as LodConfig>::L0>) {
|
||||||
|
self.layer0.push((index, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn changed15(&mut self, index: LodIndex, value: Option<<Self::Config as LodConfig>::L15>){
|
||||||
|
self.layer15.push((index, value));
|
||||||
|
}
|
||||||
|
}
|
@ -5,22 +5,20 @@ use std::cmp;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
For our LodStructures we need a type that covers the values from 0 - 2047 in steps of 1/32.
|
A region owns the Values from in (0, 2048) 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.
|
But because regions can also subscribe we add support to the range (0, 2048*3).
|
||||||
Because for accessing the decimal point makes no difference we use a u16 to represent this value.
|
which is 13 bits for the digits before the decimal point and 5 bits for the digits after the decimal point.
|
||||||
The value needs to be shiftet to get it's "real inworld size",
|
We use our own LodIndex type to store and compute based on these values, because u16 arithmetic (inside the owned area) is super easy to archive and allows us to optimize a lot.
|
||||||
|
|
||||||
Edit: now it actually implements a value from 0 - 3*2048 - 1/32, covering over 3 regions for accessing neighbor region values
|
|
||||||
|
|
||||||
-- lower neighbor
|
-- lower neighbor
|
||||||
0 -> 0
|
0 -> 0
|
||||||
1 -> 2047 31/32
|
65535 -> 2047 31/32
|
||||||
-- owned
|
-- owned
|
||||||
65536 -> 2048
|
65536 -> 2048
|
||||||
131071 -> 4095 31/32
|
131071 -> 4095 31/32
|
||||||
-- upper neighbor
|
-- upper neighbor
|
||||||
196607 -> 6143 31/32
|
196607 -> 6143 31/32
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
|
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
|
||||||
@ -40,6 +38,7 @@ const BIT_Y_MASK: u64 = 0b0000_0000_0000_0000_0000_0000_0000_1111_1111_1111_1111
|
|||||||
const BIT_Z_MASK: u64 = 0b0000_0000_0011_1111_1111_1111_1111_0000_0000_0000_0000_0000_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;
|
const BIT_X_MASK32: u32 = 0b0000_0000_0000_0011_1111_1111_1111_1111;
|
||||||
|
|
||||||
|
//TODO: Optimize!
|
||||||
impl LodIndex {
|
impl LodIndex {
|
||||||
pub fn new(data: Vec3<u32>) -> Self {
|
pub fn new(data: Vec3<u32>) -> Self {
|
||||||
let mut index = LodIndex {data: 0};
|
let mut index = LodIndex {data: 0};
|
||||||
@ -61,9 +60,9 @@ impl LodIndex {
|
|||||||
self.data = x + y + z;
|
self.data = x + y + z;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn align_to_layer_id(&self, level: u8) -> LodIndex {
|
pub fn align_to_layer_id(&self, layer: u8) -> LodIndex {
|
||||||
let xyz = self.get();
|
let xyz = self.get();
|
||||||
let f = two_pow_u(level) as u32;
|
let f = two_pow_u(layer) as u32;
|
||||||
LodIndex::new(xyz.map(|i| {
|
LodIndex::new(xyz.map(|i| {
|
||||||
(i / f) * f
|
(i / f) * f
|
||||||
}))
|
}))
|
||||||
@ -105,6 +104,50 @@ impl fmt::Display for AbsIndex {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn two_pow_u(n: u8) -> u16 {
|
||||||
|
1 << n
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn relative_to_1d(child_lod: LodIndex, parent_lod: LodIndex, child_layer: u8, relative_size: Vec3<u32>) -> usize {
|
||||||
|
let width = two_pow_u(child_layer) as u32;
|
||||||
|
let index = (child_lod.get() - parent_lod.get()).map(|e| e / width);
|
||||||
|
(index[0] * relative_size[2] * relative_size[1] + index[1] * relative_size[2] + index[2]) as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn min(lhs: LodIndex, rhs: LodIndex) -> LodIndex {
|
||||||
|
let lhs = lhs.get();
|
||||||
|
let rhs = rhs.get();
|
||||||
|
LodIndex::new(lhs.map2(rhs, |a,b| cmp::min(a,b)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn max(lhs: LodIndex, rhs: LodIndex) -> LodIndex {
|
||||||
|
let lhs = lhs.get();
|
||||||
|
let rhs = rhs.get();
|
||||||
|
LodIndex::new(lhs.map2(rhs, |a,b| cmp::max(a,b)))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************
|
||||||
|
TESTS
|
||||||
|
**************/
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -213,43 +256,3 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn two_pow_u(n: u8) -> u16 {
|
|
||||||
1 << n
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn relative_to_1d(child_lod: LodIndex, parent_lod: LodIndex, child_layer: u8, relative_size: Vec3<u32>) -> usize {
|
|
||||||
let width = two_pow_u(child_layer) as u32;
|
|
||||||
let index = (child_lod.get() - parent_lod.get()).map(|e| e / width);
|
|
||||||
(index[0] * relative_size[2] * relative_size[1] + index[1] * relative_size[2] + index[2]) as usize
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn min(lhs: LodIndex, rhs: LodIndex) -> LodIndex {
|
|
||||||
let lhs = lhs.get();
|
|
||||||
let rhs = rhs.get();
|
|
||||||
LodIndex::new(lhs.map2(rhs, |a,b| cmp::min(a,b)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn max(lhs: LodIndex, rhs: LodIndex) -> LodIndex {
|
|
||||||
let lhs = lhs.get();
|
|
||||||
let rhs = rhs.get();
|
|
||||||
LodIndex::new(lhs.map2(rhs, |a,b| cmp::max(a,b)))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,469 +1,6 @@
|
|||||||
pub mod index;
|
pub mod index;
|
||||||
use std::u32;
|
pub mod area;
|
||||||
use std::sync::Arc;
|
pub mod data;
|
||||||
use std::collections::HashMap;
|
pub mod delta;
|
||||||
use vek::*;
|
pub use data::LodData;
|
||||||
use index::{
|
pub use data::LodConfig;
|
||||||
LodIndex,
|
|
||||||
AbsIndex,
|
|
||||||
relative_to_1d,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
LOD Data contains different Entries in different vecs, every entry has a "pointer" to it's child start.
|
|
||||||
This is the structure to store a region and all subscribed information
|
|
||||||
*/
|
|
||||||
|
|
||||||
pub trait LodIntoOptionUsize: Copy {
|
|
||||||
fn is_some(self) -> bool;
|
|
||||||
fn into_usize(self) -> usize;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait LodConfig {
|
|
||||||
type L0; // 2^-4
|
|
||||||
type L1;
|
|
||||||
type L2;
|
|
||||||
type L3;
|
|
||||||
type L4; // 2^0
|
|
||||||
type L5;
|
|
||||||
type L6;
|
|
||||||
type L7;
|
|
||||||
type L8;
|
|
||||||
type L9;
|
|
||||||
type L10;
|
|
||||||
type L11;
|
|
||||||
type L12;
|
|
||||||
type L13;
|
|
||||||
type L14;
|
|
||||||
type L15; // 2^11
|
|
||||||
|
|
||||||
type I0: LodIntoOptionUsize;
|
|
||||||
type I1: LodIntoOptionUsize;
|
|
||||||
type I2: LodIntoOptionUsize;
|
|
||||||
type I3: LodIntoOptionUsize;
|
|
||||||
type I4: LodIntoOptionUsize;
|
|
||||||
type I5: LodIntoOptionUsize;
|
|
||||||
type I6: LodIntoOptionUsize;
|
|
||||||
type I7: LodIntoOptionUsize;
|
|
||||||
type I8: LodIntoOptionUsize;
|
|
||||||
type I9: LodIntoOptionUsize;
|
|
||||||
type I10: LodIntoOptionUsize;
|
|
||||||
type I11: LodIntoOptionUsize;
|
|
||||||
type I12: LodIntoOptionUsize;
|
|
||||||
type I13: LodIntoOptionUsize;
|
|
||||||
type I14: LodIntoOptionUsize;
|
|
||||||
type I15: LodIntoOptionUsize;
|
|
||||||
|
|
||||||
const anchor_layer_id: u8;
|
|
||||||
|
|
||||||
const layer_volume: [Vec3<u32>; 16]; // number of elements on this layer as Vec3 (not on child layer!)
|
|
||||||
const child_layer_id: [Option<u8>; 16]; // layer below this one
|
|
||||||
const layer_len: [usize; 16]; // optimisation for layer_volume, total no of elements as usize
|
|
||||||
|
|
||||||
fn setup(&mut self);
|
|
||||||
fn drill_down(data: &mut LodData::<Self>, abs: AbsIndex) where Self: Sized;
|
|
||||||
fn drill_up(data: &mut LodData::<Self>, parent_abs: AbsIndex) where Self: Sized;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
There is another optimization problem: We have OWNED data and foreign DATA in the struct, but we don't want the foreign data to take a lot of space if unused
|
|
||||||
But both needs to be accessible transparent without overhead in calculation, difficult.
|
|
||||||
Imagine a Terrain, which top level is L13, so it would have 64 entries for the owned and 1664 for foreign data if everything is filled.
|
|
||||||
So we really only fill the boarder giving us 152 border areas.
|
|
||||||
One could think about multiple entry levels for foreign and owned data, but that means, that foreign data without a parent would exist, which might break algorithms....
|
|
||||||
So for now we go with a single anchorlevel for now, and hope the designer chooses good levels
|
|
||||||
*/
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct LodData<X: LodConfig> {
|
|
||||||
pub layer0: Vec<X::L0>, // 1/16
|
|
||||||
pub layer1: Vec<X::L1>, // 1/8
|
|
||||||
pub layer2: Vec<X::L2>, // 1/4
|
|
||||||
pub layer3: Vec<X::L3>, // 1/2
|
|
||||||
pub layer4: Vec<X::L4>, // 1
|
|
||||||
pub layer5: Vec<X::L5>, // 2
|
|
||||||
pub layer6: Vec<X::L6>, // 4
|
|
||||||
pub layer7: Vec<X::L7>, // 8
|
|
||||||
pub layer8: Vec<X::L8>, // 16
|
|
||||||
pub layer9: Vec<X::L9>, // 32
|
|
||||||
pub layer10: Vec<X::L10>, // 64
|
|
||||||
pub layer11: Vec<X::L11>, // 128
|
|
||||||
pub layer12: Vec<X::L12>, // 256
|
|
||||||
pub layer13: Vec<X::L13>, // 512
|
|
||||||
pub layer14: Vec<X::L14>, // 1024
|
|
||||||
pub layer15: Vec<X::L15>, // 2048
|
|
||||||
|
|
||||||
pub child0: Vec<X::I0>,
|
|
||||||
pub child1: Vec<X::I1>,
|
|
||||||
pub child2: Vec<X::I2>,
|
|
||||||
pub child3: Vec<X::I3>,
|
|
||||||
pub child4: Vec<X::I4>,
|
|
||||||
pub child5: Vec<X::I5>,
|
|
||||||
pub child6: Vec<X::I6>,
|
|
||||||
pub child7: Vec<X::I7>,
|
|
||||||
pub child8: Vec<X::I8>,
|
|
||||||
pub child9: Vec<X::I9>,
|
|
||||||
pub child10: Vec<X::I10>,
|
|
||||||
pub child11: Vec<X::I11>,
|
|
||||||
pub child12: Vec<X::I12>,
|
|
||||||
pub child13: Vec<X::I13>,
|
|
||||||
pub child14: Vec<X::I14>,
|
|
||||||
pub child15: Vec<X::I15>,
|
|
||||||
pub anchor: HashMap<LodIndex, usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<X: LodConfig> LodData<X>
|
|
||||||
{
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
layer0: Vec::new(),
|
|
||||||
layer1: Vec::new(),
|
|
||||||
layer2: Vec::new(),
|
|
||||||
layer3: Vec::new(),
|
|
||||||
layer4: Vec::new(),
|
|
||||||
layer5: Vec::new(),
|
|
||||||
layer6: Vec::new(),
|
|
||||||
layer7: Vec::new(),
|
|
||||||
layer8: Vec::new(),
|
|
||||||
layer9: Vec::new(),
|
|
||||||
layer10: Vec::new(),
|
|
||||||
layer11: Vec::new(),
|
|
||||||
layer12: Vec::new(),
|
|
||||||
layer13: Vec::new(),
|
|
||||||
layer14: Vec::new(),
|
|
||||||
layer15: Vec::new(),
|
|
||||||
child0: Vec::new(),
|
|
||||||
child1: Vec::new(),
|
|
||||||
child2: Vec::new(),
|
|
||||||
child3: Vec::new(),
|
|
||||||
child4: Vec::new(),
|
|
||||||
child5: Vec::new(),
|
|
||||||
child6: Vec::new(),
|
|
||||||
child7: Vec::new(),
|
|
||||||
child8: Vec::new(),
|
|
||||||
child9: Vec::new(),
|
|
||||||
child10: Vec::new(),
|
|
||||||
child11: Vec::new(),
|
|
||||||
child12: Vec::new(),
|
|
||||||
child13: Vec::new(),
|
|
||||||
child14: Vec::new(),
|
|
||||||
child15: Vec::new(),
|
|
||||||
anchor: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// dynamically dispatches the get_child_index, this is most prob the bottleneck function.
|
|
||||||
// evaluate the performacne impact!!!
|
|
||||||
fn int_get_child_index(&self, abs: AbsIndex) -> usize {
|
|
||||||
match abs.layer {
|
|
||||||
0 => self.child0[abs.index].into_usize(),
|
|
||||||
1 => self.child1[abs.index].into_usize(),
|
|
||||||
2 => self.child2[abs.index].into_usize(),
|
|
||||||
3 => self.child3[abs.index].into_usize(),
|
|
||||||
4 => self.child4[abs.index].into_usize(),
|
|
||||||
5 => self.child5[abs.index].into_usize(),
|
|
||||||
6 => self.child6[abs.index].into_usize(),
|
|
||||||
7 => self.child7[abs.index].into_usize(),
|
|
||||||
8 => self.child8[abs.index].into_usize(),
|
|
||||||
9 => self.child9[abs.index].into_usize(),
|
|
||||||
10 => self.child10[abs.index].into_usize(),
|
|
||||||
11 => self.child11[abs.index].into_usize(),
|
|
||||||
12 => self.child12[abs.index].into_usize(),
|
|
||||||
13 => self.child13[abs.index].into_usize(),
|
|
||||||
14 => self.child14[abs.index].into_usize(),
|
|
||||||
15 => self.child15[abs.index].into_usize(),
|
|
||||||
_ => panic!("wrong abs index"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the childs AbsIndex of Parent AbsIndex
|
|
||||||
// child_lod must lie within parent
|
|
||||||
// uses parent_lod as buffer, to not calculate it again
|
|
||||||
// uses parent_child_index as a buffer, to not calculate it again
|
|
||||||
fn int_get(parent_abs: AbsIndex, child_lod: LodIndex, parent_lod: LodIndex, parent_child_index: usize) -> AbsIndex {
|
|
||||||
let child_layer = X::child_layer_id[parent_abs.layer as usize].unwrap();
|
|
||||||
let child_lod = child_lod.align_to_layer_id(child_layer);
|
|
||||||
let child_offset = relative_to_1d(child_lod, parent_lod, child_layer, X::layer_volume[child_layer as usize]);
|
|
||||||
//println!("{} int_get - parent_abs {} child_lod {} parent_lod {} parent_child_index {} child_offset {}", Self::ppp(parent_abs.layer), parent_abs, child_lod, parent_lod, parent_child_index, child_offset);
|
|
||||||
AbsIndex::new(child_layer, parent_child_index + child_offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
// slower variant of int_get which requiere self lookups
|
|
||||||
fn int_get_lockup(&self, parent_abs: AbsIndex, child_lod: LodIndex) -> AbsIndex {
|
|
||||||
let parent_lod = child_lod.align_to_layer_id(parent_abs.layer);
|
|
||||||
let parent_child_index = self.int_get_child_index(parent_abs);
|
|
||||||
Self::int_get(parent_abs, child_lod, parent_lod, parent_child_index)
|
|
||||||
}
|
|
||||||
|
|
||||||
// target_layer is requiered because same LodIndex can exist for multiple layers, and guessing is stupid here
|
|
||||||
fn int_recursive_get(&self, parent_abs: AbsIndex, child_lod: LodIndex, target_layer:u8) -> AbsIndex {
|
|
||||||
let mut parent_abs = parent_abs;
|
|
||||||
while true {
|
|
||||||
//println!("{} int_recursive_get {} - {}", Self::ppp(parent_abs.layer), parent_abs, target_layer);
|
|
||||||
parent_abs = self.int_get_lockup(parent_abs, child_lod);
|
|
||||||
if parent_abs.layer <= target_layer {
|
|
||||||
return parent_abs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unreachable!();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get15(&self, index: LodIndex) -> &X::L15 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 15);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 15);
|
|
||||||
&self.layer15[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get14(&self, index: LodIndex) -> &X::L14 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 14);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 14);
|
|
||||||
&self.layer14[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get13(&self, index: LodIndex) -> &X::L13 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 13);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 13);
|
|
||||||
&self.layer13[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get12(&self, index: LodIndex) -> &X::L12 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 12);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 12);
|
|
||||||
&self.layer12[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get11(&self, index: LodIndex) -> &X::L11 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 11);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 11);
|
|
||||||
&self.layer11[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get10(&self, index: LodIndex) -> &X::L10 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 10);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 10);
|
|
||||||
&self.layer10[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get9(&self, index: LodIndex) -> &X::L9 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 9);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 9);
|
|
||||||
&self.layer9[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get8(&self, index: LodIndex) -> &X::L8 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 8);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 8);
|
|
||||||
&self.layer8[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get7(&self, index: LodIndex) -> &X::L7 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 7);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 7);
|
|
||||||
&self.layer7[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get6(&self, index: LodIndex) -> &X::L6 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 6);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 6);
|
|
||||||
&self.layer6[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get5(&self, index: LodIndex) -> &X::L5 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 5);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 5);
|
|
||||||
&self.layer5[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get4(&self, index: LodIndex) -> &X::L4 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
//println!("4aa4 {:?} - {:?}", anchor_lod, anchor_abs );
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 4);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 4);
|
|
||||||
&self.layer4[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get3(&self, index: LodIndex) -> &X::L3 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 3);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 3);
|
|
||||||
&self.layer3[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get2(&self, index: LodIndex) -> &X::L2 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 2);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 2);
|
|
||||||
&self.layer2[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get1(&self, index: LodIndex) -> &X::L1 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 1);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 1);
|
|
||||||
&self.layer1[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get0(&self, index: LodIndex) -> &X::L0 {
|
|
||||||
let anchor_lod = index.align_to_layer_id(X::anchor_layer_id);
|
|
||||||
let anchor_abs = AbsIndex::new(X::anchor_layer_id, self.anchor[&anchor_lod]);
|
|
||||||
let wanted_abs = self.int_recursive_get(anchor_abs, index, 0);
|
|
||||||
debug_assert_eq!(wanted_abs.layer, 0);
|
|
||||||
&self.layer0[wanted_abs.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns the last LodIndex, that belongs to a parent AbsIndex
|
|
||||||
fn get_last_child_lod(parent: LodIndex, parent_level: u8) -> LodIndex {
|
|
||||||
let child_width = index::two_pow_u(X::child_layer_id[parent_level as usize].unwrap()) as u32;
|
|
||||||
parent + LodIndex::new(X::layer_volume[X::child_layer_id[parent_level as usize].unwrap() as usize].map(|e| (e-1)*child_width))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ppp(level: u8) -> &'static str {
|
|
||||||
match level {
|
|
||||||
0 => " | ",
|
|
||||||
4 => " ---- ",
|
|
||||||
5 => " ----- ",
|
|
||||||
9 => " ---------- ",
|
|
||||||
13 => " ------------- ",
|
|
||||||
_ => panic!("aaa"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
lower: must always be a LodIndex inside parent
|
|
||||||
upper: must always have same parent as lower -> parent
|
|
||||||
*/
|
|
||||||
fn int_make_at_least(&mut self, parent: AbsIndex, /*parent_lod2: LodIndex,*/ lower: LodIndex, upper: LodIndex, target_level: u8) {
|
|
||||||
let child_layer = X::child_layer_id[parent.layer as usize];
|
|
||||||
let parent_lod_width = index::two_pow_u(parent.layer) as u32;
|
|
||||||
let parent_lod = lower.align_to_layer_id(parent.layer);
|
|
||||||
//assert_eq!(parent_lod, parent_lod2);
|
|
||||||
//println!("{} lower, upper {} {} {} - {:?}", Self::ppp(parent.layer), lower, upper, parent_lod_width, child_layer);
|
|
||||||
if parent.layer > target_level {
|
|
||||||
// create necessary childs:
|
|
||||||
X::drill_down(self, parent);
|
|
||||||
//println!("{} DRILLED DOWN", Self::ppp(parent.layer));
|
|
||||||
if child_layer.is_some() && child_layer.unwrap() > target_level {
|
|
||||||
let child_layer = child_layer.unwrap();
|
|
||||||
let child_lod_width = index::two_pow_u(child_layer) as u32;
|
|
||||||
//calc childs which needs to be called recusivly, there childs will be the new parents
|
|
||||||
let child_lower = lower.align_to_layer_id(child_layer);
|
|
||||||
let child_upper = upper.align_to_layer_id(child_layer);
|
|
||||||
let child_base_abs_index = self.int_get_child_index(parent);
|
|
||||||
let child_volume = X::layer_volume[child_layer as usize];
|
|
||||||
// loop over childs and calculate correct lower and
|
|
||||||
let lower_xyz = (child_lower.get()-parent_lod.get()).map(|e| e / child_lod_width);
|
|
||||||
let upper_xyz = (child_upper.get()-parent_lod.get()).map(|e| e / child_lod_width);
|
|
||||||
//println!("{} lxyz {}", Self::ppp(parent.layer), lower_xyz);
|
|
||||||
//println!("{} uxyz {}", Self::ppp(parent.layer), upper_xyz);
|
|
||||||
//println!("{} child_lod_width {}", Self::ppp(parent.layer), child_lod_width);
|
|
||||||
for x in lower_xyz[0]..upper_xyz[0]+1 {
|
|
||||||
for y in lower_xyz[1]..upper_xyz[1]+1 {
|
|
||||||
for z in lower_xyz[2]..upper_xyz[2]+1 {
|
|
||||||
//println!("{} xyz {} {} {}", Self::ppp(parent.layer), x, y, z);
|
|
||||||
//calculate individual abs values, because we now, how they are ordered in the vec
|
|
||||||
let child_abs_index = child_base_abs_index + (x * child_volume[2] * child_volume[1] + y * child_volume[2] + z) as usize;
|
|
||||||
let child_abs = AbsIndex::new(child_layer, child_abs_index);
|
|
||||||
let child_lower = parent_lod + LodIndex::new(Vec3::new(x * child_lod_width, y * child_lod_width, z * child_lod_width));
|
|
||||||
let child_upper = child_lower + LodIndex::new(Vec3::new(child_lod_width-1, child_lod_width-1, child_lod_width-1));
|
|
||||||
|
|
||||||
let inner_lower = index::max(lower, child_lower);
|
|
||||||
let inner_upper = index::min(upper, child_upper);
|
|
||||||
//println!("{} restrict {} {} to {} {}", Self::ppp(parent.layer), lower, upper, inner_lower, inner_upper);
|
|
||||||
Self::int_make_at_least(self, child_abs, inner_lower, inner_upper, target_level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
These functions allow you to make the LodLayer provide a certain LOD for the specified area
|
|
||||||
*/
|
|
||||||
/*is at least minimum or maximum*/
|
|
||||||
|
|
||||||
pub fn make_at_least(&mut self, lower: LodIndex, upper: LodIndex, target_level: u8) {
|
|
||||||
//ERROR, DOES NOT RECURSIVLY CALL
|
|
||||||
let anchor_layer_id = X::anchor_layer_id;
|
|
||||||
let anchor_lower = lower.align_to_layer_id(anchor_layer_id);
|
|
||||||
let anchor_upper = upper.align_to_layer_id(anchor_layer_id);
|
|
||||||
let lower_xyz = anchor_lower.get();
|
|
||||||
let upper_xyz = anchor_upper.get();
|
|
||||||
let anchor_width = index::two_pow_u(anchor_layer_id) as u32;
|
|
||||||
let mut x = lower_xyz[0];
|
|
||||||
//println!("{} xxx lower, upper {} {} {}", Self::ppp(anchor_layer_id), lower_xyz, upper_xyz, anchor_width);
|
|
||||||
while x <= upper_xyz[0] {
|
|
||||||
let mut y = lower_xyz[1];
|
|
||||||
while y <= upper_xyz[1] {
|
|
||||||
let mut z = lower_xyz[2];
|
|
||||||
while z <= upper_xyz[2] {
|
|
||||||
let anchor_lod = LodIndex::new(Vec3::new(x,y,z));
|
|
||||||
let anchor_abs = AbsIndex::new(anchor_layer_id, self.anchor[&anchor_lod]); ;
|
|
||||||
if anchor_abs.layer > target_level {
|
|
||||||
X::drill_down(self, anchor_abs);
|
|
||||||
let child_lod_upper = Self::get_last_child_lod(anchor_lod, anchor_abs.layer);
|
|
||||||
|
|
||||||
let inner_lower = index::max(lower, anchor_lod);
|
|
||||||
let inner_upper = index::min(upper, child_lod_upper);
|
|
||||||
|
|
||||||
//println!("{}call child with lower, upper {} {} instead of {} {} ", Self::ppp(anchor_layer_id), inner_lower, inner_upper, anchor_lod, child_lod_upper);
|
|
||||||
self.int_make_at_least(anchor_abs, inner_lower, inner_upper, target_level);
|
|
||||||
}
|
|
||||||
z += anchor_width;
|
|
||||||
}
|
|
||||||
y += anchor_width;
|
|
||||||
}
|
|
||||||
x += anchor_width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn make_at_most(&mut self, lower: LodIndex, upper: LodIndex, level: i8) {
|
|
||||||
|
|
||||||
}
|
|
||||||
fn make_exactly(&mut self, lower: LodIndex, upper: LodIndex, level: i8) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LodIntoOptionUsize for () {
|
|
||||||
fn is_some(self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
fn into_usize(self) -> usize {
|
|
||||||
unreachable!("dummyUsize")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LodIntoOptionUsize for u32 {
|
|
||||||
fn is_some(self) -> bool {
|
|
||||||
self != u32::MAX
|
|
||||||
}
|
|
||||||
fn into_usize(self) -> usize {
|
|
||||||
self as usize
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,6 +3,9 @@ use crate::lodstore::{
|
|||||||
LodConfig,
|
LodConfig,
|
||||||
index::LodIndex,
|
index::LodIndex,
|
||||||
index::AbsIndex,
|
index::AbsIndex,
|
||||||
|
area::LodArea,
|
||||||
|
delta::LodDelta,
|
||||||
|
delta::DefaultLodDelta,
|
||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
@ -73,6 +76,9 @@ impl LodConfig for ExampleLodConfig {
|
|||||||
type I14 = ();
|
type I14 = ();
|
||||||
type I15 = ();
|
type I15 = ();
|
||||||
|
|
||||||
|
type Delta = DefaultLodDelta<Self>;
|
||||||
|
type Additional = ();
|
||||||
|
|
||||||
const anchor_layer_id: u8 = 13;
|
const anchor_layer_id: u8 = 13;
|
||||||
|
|
||||||
// this is not for the children, a layer9 has 32x32x32 childs, not 16x16x16
|
// this is not for the children, a layer9 has 32x32x32 childs, not 16x16x16
|
||||||
@ -90,7 +96,7 @@ impl LodConfig for ExampleLodConfig {
|
|||||||
Vec3{x: 0, y: 0, z: 0},
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
Vec3{x: 0, y: 0, z: 0},
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
Vec3{x: 0, y: 0, z: 0},
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
Vec3{x: 16, y: 16, z: 16},
|
Vec3{x: 8, y: 8, z: 8},
|
||||||
Vec3{x: 0, y: 0, z: 0},
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
Vec3{x: 0, y: 0, z: 0},
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
];
|
];
|
||||||
@ -113,31 +119,11 @@ impl LodConfig for ExampleLodConfig {
|
|||||||
None,
|
None,
|
||||||
];
|
];
|
||||||
|
|
||||||
const layer_len: [usize; 16] = [
|
|
||||||
(Self::layer_volume[0].x * Self::layer_volume[0].y * Self::layer_volume[0].z) as usize,
|
|
||||||
(Self::layer_volume[1].x * Self::layer_volume[1].y * Self::layer_volume[1].z) as usize,
|
|
||||||
(Self::layer_volume[2].x * Self::layer_volume[2].y * Self::layer_volume[2].z) as usize,
|
|
||||||
(Self::layer_volume[3].x * Self::layer_volume[3].y * Self::layer_volume[3].z) as usize,
|
|
||||||
(Self::layer_volume[4].x * Self::layer_volume[4].y * Self::layer_volume[4].z) as usize,
|
|
||||||
(Self::layer_volume[5].x * Self::layer_volume[5].y * Self::layer_volume[5].z) as usize,
|
|
||||||
(Self::layer_volume[6].x * Self::layer_volume[6].y * Self::layer_volume[6].z) as usize,
|
|
||||||
(Self::layer_volume[7].x * Self::layer_volume[7].y * Self::layer_volume[7].z) as usize,
|
|
||||||
(Self::layer_volume[8].x * Self::layer_volume[8].y * Self::layer_volume[8].z) as usize,
|
|
||||||
(Self::layer_volume[9].x * Self::layer_volume[9].y * Self::layer_volume[9].z) as usize,
|
|
||||||
(Self::layer_volume[10].x * Self::layer_volume[10].y * Self::layer_volume[10].z) as usize,
|
|
||||||
(Self::layer_volume[11].x * Self::layer_volume[11].y * Self::layer_volume[11].z) as usize,
|
|
||||||
(Self::layer_volume[12].x * Self::layer_volume[12].y * Self::layer_volume[12].z) as usize,
|
|
||||||
(Self::layer_volume[13].x * Self::layer_volume[13].y * Self::layer_volume[13].z) as usize,
|
|
||||||
(Self::layer_volume[14].x * Self::layer_volume[14].y * Self::layer_volume[14].z) as usize,
|
|
||||||
(Self::layer_volume[15].x * Self::layer_volume[15].y * Self::layer_volume[15].z) as usize,
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
fn setup(&mut self) {
|
fn setup(&mut self) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drill_down(data: &mut LodData::<Self>, abs: AbsIndex) {
|
fn drill_down(data: &mut LodData::<Self>, abs: AbsIndex, delta: &mut Option<DefaultLodDelta<Self>>) {
|
||||||
match abs.layer {
|
match abs.layer {
|
||||||
0 => {
|
0 => {
|
||||||
panic!("cannot drill down further");
|
panic!("cannot drill down further");
|
||||||
@ -148,6 +134,12 @@ impl LodConfig for ExampleLodConfig {
|
|||||||
data.layer0.reserve(Self::layer_len[0]);
|
data.layer0.reserve(Self::layer_len[0]);
|
||||||
data.child4[abs.index] = insert as u32;
|
data.child4[abs.index] = insert as u32;
|
||||||
//debug!("set0 {:?} = {}", abs, insert);
|
//debug!("set0 {:?} = {}", abs, insert);
|
||||||
|
// in the future use something like a child_index as parameter and a RawVec for allocations
|
||||||
|
//data.layer0[child_index..child_index+Self::layer_len[0]].iter_mut().map(
|
||||||
|
// |e| *e = Example_4{
|
||||||
|
// data: 0,
|
||||||
|
// }
|
||||||
|
// );
|
||||||
for i in 0..Self::layer_len[0] {
|
for i in 0..Self::layer_len[0] {
|
||||||
data.layer0.push(Example_4{
|
data.layer0.push(Example_4{
|
||||||
data: 0,
|
data: 0,
|
||||||
@ -187,7 +179,7 @@ impl LodConfig for ExampleLodConfig {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drill_up(data: &mut LodData::<Self>, parent_abs: AbsIndex) {
|
fn drill_up(data: &mut LodData::<Self>, parent_abs: AbsIndex, delta: &mut Option<DefaultLodDelta<Self>>) {
|
||||||
match parent_abs.layer {
|
match parent_abs.layer {
|
||||||
0 => {
|
0 => {
|
||||||
panic!("SubBlocks_4 does not have children");
|
panic!("SubBlocks_4 does not have children");
|
||||||
@ -215,6 +207,9 @@ impl LodConfig for ExampleLodConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//DELTA
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -272,17 +267,20 @@ mod tests {
|
|||||||
while result.layer9.len() < act5 as usize {
|
while result.layer9.len() < act5 as usize {
|
||||||
let index = randIndex(&mut rng);
|
let index = randIndex(&mut rng);
|
||||||
let low = index.align_to_layer_id(9);
|
let low = index.align_to_layer_id(9);
|
||||||
result.make_at_least(low,low,9);
|
let area = LodArea::new(low, low);
|
||||||
|
result.make_at_least(area,9);
|
||||||
}
|
}
|
||||||
while result.layer4.len() < act0 as usize {
|
while result.layer4.len() < act0 as usize {
|
||||||
let index = randIndex(&mut rng);
|
let index = randIndex(&mut rng);
|
||||||
let low = index.align_to_layer_id(4);
|
let low = index.align_to_layer_id(4);
|
||||||
result.make_at_least(low,low,4);
|
let area = LodArea::new(low, low);
|
||||||
|
result.make_at_least(area, 4);
|
||||||
}
|
}
|
||||||
while result.layer0.len() < act_4 as usize {
|
while result.layer0.len() < act_4 as usize {
|
||||||
let index = randIndex(&mut rng);
|
let index = randIndex(&mut rng);
|
||||||
let low = index.align_to_layer_id(0);
|
let low = index.align_to_layer_id(0);
|
||||||
result.make_at_least(low,low,0);
|
let area = LodArea::new(low, low);
|
||||||
|
result.make_at_least(area, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("creating Region with {} 5er, {} 0er, {} -4er", act5, act0 , act_4);
|
println!("creating Region with {} 5er, {} 0er, {} -4er", act5, act0 , act_4);
|
||||||
@ -301,7 +299,8 @@ mod tests {
|
|||||||
let mut reg = createRegion(0.0, 0.0, 0.0, 0.1);
|
let mut reg = createRegion(0.0, 0.0, 0.0, 0.1);
|
||||||
let low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
let low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
||||||
let high = LodIndex::new(Vec3::new(16384, 16384, 16384));
|
let high = LodIndex::new(Vec3::new(16384, 16384, 16384));
|
||||||
reg.make_at_least(low,high,4);
|
let area = LodArea::new(low, high);
|
||||||
|
reg.make_at_least(area, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -309,7 +308,8 @@ mod tests {
|
|||||||
let mut reg = createRegion(0.0, 0.0, 0.0, 0.1);
|
let mut reg = createRegion(0.0, 0.0, 0.0, 0.1);
|
||||||
let low = LodIndex::new(Vec3::new(0, 0, 0));
|
let low = LodIndex::new(Vec3::new(0, 0, 0));
|
||||||
let high = LodIndex::new(Vec3::new(4, 4, 4));
|
let high = LodIndex::new(Vec3::new(4, 4, 4));
|
||||||
reg.make_at_least(low,high,0);
|
let area = LodArea::new(low, high);
|
||||||
|
reg.make_at_least(area, 0);
|
||||||
reg.get0(LodIndex::new(Vec3::new(0, 0, 0)));
|
reg.get0(LodIndex::new(Vec3::new(0, 0, 0)));
|
||||||
reg.get0(LodIndex::new(Vec3::new(1, 0, 0)));
|
reg.get0(LodIndex::new(Vec3::new(1, 0, 0)));
|
||||||
reg.get0(LodIndex::new(Vec3::new(0, 1, 0)));
|
reg.get0(LodIndex::new(Vec3::new(0, 1, 0)));
|
||||||
@ -325,7 +325,8 @@ mod tests {
|
|||||||
let mut reg = createRegion(0.0, 0.0, 0.0, 0.1);
|
let mut reg = createRegion(0.0, 0.0, 0.0, 0.1);
|
||||||
let low = LodIndex::new(Vec3::new(8704, 8704, 8704));
|
let low = LodIndex::new(Vec3::new(8704, 8704, 8704));
|
||||||
let high = LodIndex::new(Vec3::new(9216, 9216, 9216));
|
let high = LodIndex::new(Vec3::new(9216, 9216, 9216));
|
||||||
reg.make_at_least(low,high,0);
|
let area = LodArea::new(low, high);
|
||||||
|
reg.make_at_least(area, 0);
|
||||||
reg.get0(LodIndex::new(Vec3::new(8704, 8704, 8704)));
|
reg.get0(LodIndex::new(Vec3::new(8704, 8704, 8704)));
|
||||||
reg.get0(LodIndex::new(Vec3::new(9000, 9000, 9000)));
|
reg.get0(LodIndex::new(Vec3::new(9000, 9000, 9000)));
|
||||||
reg.get0(LodIndex::new(Vec3::new(9000, 9000, 9001)));
|
reg.get0(LodIndex::new(Vec3::new(9000, 9000, 9001)));
|
||||||
@ -342,7 +343,8 @@ mod tests {
|
|||||||
let mut reg = createRegion(0.0, 0.0, 0.0, 0.1);
|
let mut reg = createRegion(0.0, 0.0, 0.0, 0.1);
|
||||||
let low = LodIndex::new(Vec3::new(8704, 8704, 8704));
|
let low = LodIndex::new(Vec3::new(8704, 8704, 8704));
|
||||||
let high = LodIndex::new(Vec3::new(9216, 9216, 9216));
|
let high = LodIndex::new(Vec3::new(9216, 9216, 9216));
|
||||||
reg.make_at_least(low,high,0);
|
let area = LodArea::new(low, high);
|
||||||
|
reg.make_at_least(area, 0);
|
||||||
reg.get0(LodIndex::new(Vec3::new(8704, 8704, 8703)));
|
reg.get0(LodIndex::new(Vec3::new(8704, 8704, 8703)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,7 +354,8 @@ mod tests {
|
|||||||
let mut reg = createRegion(0.0, 0.0, 0.0, 0.1);
|
let mut reg = createRegion(0.0, 0.0, 0.0, 0.1);
|
||||||
let low = LodIndex::new(Vec3::new(8704, 8704, 8704));
|
let low = LodIndex::new(Vec3::new(8704, 8704, 8704));
|
||||||
let high = LodIndex::new(Vec3::new(9216, 9216, 9216));
|
let high = LodIndex::new(Vec3::new(9216, 9216, 9216));
|
||||||
reg.make_at_least(low,high,0);
|
let area = LodArea::new(low, high);
|
||||||
|
reg.make_at_least(area,0);
|
||||||
reg.get0(LodIndex::new(Vec3::new(10240, 10240, 10240)));
|
reg.get0(LodIndex::new(Vec3::new(10240, 10240, 10240)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,7 +364,8 @@ mod tests {
|
|||||||
let mut reg = createRegion(0.0, 0.0, 0.0, 0.1);
|
let mut reg = createRegion(0.0, 0.0, 0.0, 0.1);
|
||||||
let low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
let low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
||||||
let high = LodIndex::new(Vec3::new(10240, 10240, 10240));
|
let high = LodIndex::new(Vec3::new(10240, 10240, 10240));
|
||||||
reg.make_at_least(low,high,4);
|
let area = LodArea::new(low, high);
|
||||||
|
reg.make_at_least(area, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -370,7 +374,8 @@ mod tests {
|
|||||||
let mut reg = createRegion(0.0, 0.0, 0.0, 0.1);
|
let mut reg = createRegion(0.0, 0.0, 0.0, 0.1);
|
||||||
let low = LodIndex::new(Vec3::new(0, 0, 0));
|
let low = LodIndex::new(Vec3::new(0, 0, 0));
|
||||||
let high = LodIndex::new(Vec3::new(4, 4, 4));
|
let high = LodIndex::new(Vec3::new(4, 4, 4));
|
||||||
reg.make_at_least(low,high,0);
|
let area = LodArea::new(low, high);
|
||||||
|
reg.make_at_least(area, 0);
|
||||||
reg.get0(LodIndex::new(Vec3::new(5, 5, 5))); //this access is not guaranteed but will work
|
reg.get0(LodIndex::new(Vec3::new(5, 5, 5))); //this access is not guaranteed but will work
|
||||||
reg.get0(LodIndex::new(Vec3::new(16, 16, 16))); // out of range
|
reg.get0(LodIndex::new(Vec3::new(16, 16, 16))); // out of range
|
||||||
}
|
}
|
||||||
@ -393,7 +398,8 @@ mod tests {
|
|||||||
let high = LodIndex::new(Vec3::new(255, 255, 255));
|
let high = LodIndex::new(Vec3::new(255, 255, 255));
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut reg2 = region.clone();
|
let mut reg2 = region.clone();
|
||||||
reg2.make_at_least(low,high,0);
|
let area = LodArea::new(low, high);
|
||||||
|
reg2.make_at_least(area, 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,7 +410,8 @@ mod tests {
|
|||||||
let high = LodIndex::new(Vec3::new(4, 4, 4));
|
let high = LodIndex::new(Vec3::new(4, 4, 4));
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut reg2 = region.clone();
|
let mut reg2 = region.clone();
|
||||||
reg2.make_at_least(low,high,0);
|
let area = LodArea::new(low, high);
|
||||||
|
reg2.make_at_least(area, 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,7 +422,8 @@ mod tests {
|
|||||||
let high = LodIndex::new(Vec3::new(10240, 10240, 10240));
|
let high = LodIndex::new(Vec3::new(10240, 10240, 10240));
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut reg2 = region.clone();
|
let mut reg2 = region.clone();
|
||||||
reg2.make_at_least(low,high,4);
|
let area = LodArea::new(low, high);
|
||||||
|
reg2.make_at_least(area, 4);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,7 +433,8 @@ mod tests {
|
|||||||
let access = LodIndex::new(Vec3::new(8561, 8312, 8412));
|
let access = LodIndex::new(Vec3::new(8561, 8312, 8412));
|
||||||
let low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
let low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
||||||
let high = LodIndex::new(Vec3::new(8800, 8800, 8800));
|
let high = LodIndex::new(Vec3::new(8800, 8800, 8800));
|
||||||
reg.make_at_least(low,high,0);
|
let area = LodArea::new(low, high);
|
||||||
|
reg.make_at_least(area, 0);
|
||||||
b.iter(|| reg.get0(access));
|
b.iter(|| reg.get0(access));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,7 +443,8 @@ mod tests {
|
|||||||
let mut reg = createRegion(0.0015, 0.001, 0.001, 0.1);
|
let mut reg = createRegion(0.0015, 0.001, 0.001, 0.1);
|
||||||
let low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
let low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
||||||
let high = LodIndex::new(Vec3::new(8800, 8800, 8800));
|
let high = LodIndex::new(Vec3::new(8800, 8800, 8800));
|
||||||
reg.make_at_least(low,high,0);
|
let area = LodArea::new(low, high);
|
||||||
|
reg.make_at_least(area, 0);
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
reg.get0(LodIndex::new(Vec3::new(8561, 8312, 8412)));
|
reg.get0(LodIndex::new(Vec3::new(8561, 8312, 8412)));
|
||||||
reg.get0(LodIndex::new(Vec3::new(8200, 8599, 8413)));
|
reg.get0(LodIndex::new(Vec3::new(8200, 8599, 8413)));
|
||||||
@ -466,7 +476,8 @@ mod tests {
|
|||||||
let z: u16 = rng.gen();
|
let z: u16 = rng.gen();
|
||||||
accesslist.push(LodIndex::new(Vec3::new(x,y,z).map(|x| (8192 + x / 66) as u32)));
|
accesslist.push(LodIndex::new(Vec3::new(x,y,z).map(|x| (8192 + x / 66) as u32)));
|
||||||
}
|
}
|
||||||
reg.make_at_least(low,high,0);
|
let area = LodArea::new(low, high);
|
||||||
|
reg.make_at_least(area, 0);
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
for i in 0..1000000 {
|
for i in 0..1000000 {
|
||||||
reg.get0(accesslist[i]);
|
reg.get0(accesslist[i]);
|
||||||
@ -487,7 +498,8 @@ mod tests {
|
|||||||
let z: u16 = rng.gen();
|
let z: u16 = rng.gen();
|
||||||
accesslist.push(LodIndex::new(Vec3::new(x,y,z).map(|x| (8192 + x / 66) as u32)));
|
accesslist.push(LodIndex::new(Vec3::new(x,y,z).map(|x| (8192 + x / 66) as u32)));
|
||||||
}
|
}
|
||||||
reg.make_at_least(low,high,0);
|
let area = LodArea::new(low, high);
|
||||||
|
reg.make_at_least(area, 0);
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
for i in 0..9990000 {
|
for i in 0..9990000 {
|
||||||
reg.get0(accesslist[i]);
|
reg.get0(accesslist[i]);
|
||||||
@ -501,8 +513,11 @@ mod tests {
|
|||||||
let access = LodIndex::new(Vec3::new(9561, 9312, 8412));
|
let access = LodIndex::new(Vec3::new(9561, 9312, 8412));
|
||||||
let low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
let low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
||||||
let high = LodIndex::new(Vec3::new(10240, 10240, 10240));
|
let high = LodIndex::new(Vec3::new(10240, 10240, 10240));
|
||||||
reg.make_at_least(low,high,4);
|
let area = LodArea::new(low, high);
|
||||||
|
reg.make_at_least(area, 4);
|
||||||
|
|
||||||
b.iter(|| reg.get4(access));
|
b.iter(|| reg.get4(access));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DELTA TESTS
|
||||||
}
|
}
|
190
worldsim/src/region/lod/npcs.rs
Normal file
190
worldsim/src/region/lod/npcs.rs
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
use crate::lodstore::{
|
||||||
|
LodData,
|
||||||
|
LodConfig,
|
||||||
|
index::LodIndex,
|
||||||
|
index::AbsIndex,
|
||||||
|
delta::LodDelta,
|
||||||
|
delta::DefaultLodDelta,
|
||||||
|
};
|
||||||
|
use vek::*;
|
||||||
|
use std::u32;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Region9 {
|
||||||
|
precent_air: f32,
|
||||||
|
percent_forrest: f32,
|
||||||
|
percent_lava: f32,
|
||||||
|
percent_water: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Chunk6 {
|
||||||
|
precent_air: f32,
|
||||||
|
percent_forrest: f32,
|
||||||
|
percent_lava: f32,
|
||||||
|
percent_water: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct TerrainLodConfig {}
|
||||||
|
|
||||||
|
impl LodConfig for TerrainLodConfig {
|
||||||
|
type L0 = ();
|
||||||
|
type L1 = ();
|
||||||
|
type L2 = ();
|
||||||
|
type L3 = ();
|
||||||
|
type L4 = ();
|
||||||
|
type L5 = ();
|
||||||
|
type L6 = ();
|
||||||
|
type L7 = ();
|
||||||
|
type L8 = ();
|
||||||
|
type L9 = ();
|
||||||
|
type L10 = Chunk6;
|
||||||
|
type L11 = ();
|
||||||
|
type L12 = ();
|
||||||
|
type L13 = Region9;
|
||||||
|
type L14 = ();
|
||||||
|
type L15 = ();
|
||||||
|
|
||||||
|
type I0 = ();
|
||||||
|
type I1 = ();
|
||||||
|
type I2 = ();
|
||||||
|
type I3 = ();
|
||||||
|
type I4 = ();
|
||||||
|
type I5 = ();
|
||||||
|
type I6 = ();
|
||||||
|
type I7 = ();
|
||||||
|
type I8 = ();
|
||||||
|
type I9 = ();
|
||||||
|
type I10 = ();
|
||||||
|
type I11 = ();
|
||||||
|
type I12 = ();
|
||||||
|
type I13 = u16; // Chunk5 2^(6*3), this is valid
|
||||||
|
type I14 = ();
|
||||||
|
type I15 = ();
|
||||||
|
|
||||||
|
type Delta = DefaultLodDelta<Self>;
|
||||||
|
type Additional = ();
|
||||||
|
|
||||||
|
const anchor_layer_id: u8 = 13;
|
||||||
|
|
||||||
|
const layer_volume: [Vec3<u32>; 16] = [
|
||||||
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
|
Vec3{x: 8, y: 8, z: 8},
|
||||||
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
|
Vec3{x: 8, y: 8, z: 8},
|
||||||
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
|
];
|
||||||
|
const child_layer_id: [Option<u8>; 16] = [
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
Some(9),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
];
|
||||||
|
|
||||||
|
fn setup(&mut self) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn drill_down(data: &mut LodData::<Self>, abs: AbsIndex, delta: &mut Option<DefaultLodDelta<Self>>) {
|
||||||
|
match abs.layer {
|
||||||
|
0 => {
|
||||||
|
panic!("cannot drill down further");
|
||||||
|
},
|
||||||
|
4 => {
|
||||||
|
if data.child4[abs.index] != u32::MAX {return;}
|
||||||
|
let insert = data.layer0.len();
|
||||||
|
data.layer0.reserve(Self::layer_len[0]);
|
||||||
|
data.child4[abs.index] = insert as u32;
|
||||||
|
//debug!("set0 {:?} = {}", abs, insert);
|
||||||
|
for i in 0..Self::layer_len[0] {
|
||||||
|
data.layer0.push(SubBlock_4{
|
||||||
|
material: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
9 => {
|
||||||
|
if data.child9[abs.index] != u32::MAX {return;}
|
||||||
|
let insert = data.layer4.len();
|
||||||
|
data.layer4.reserve(Self::layer_len[4]);
|
||||||
|
data.child4.reserve(Self::layer_len[4]);
|
||||||
|
data.child9[abs.index] = insert as u32;
|
||||||
|
//debug!("set4 {:?} = {}", abs, insert);
|
||||||
|
for i in 0..Self::layer_len[4] {
|
||||||
|
data.layer4.push(Block0{
|
||||||
|
material: 0,
|
||||||
|
});
|
||||||
|
data.child4.push(u32::MAX);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
13 => {
|
||||||
|
if data.child13[abs.index] != u32::MAX {return;}
|
||||||
|
let insert = data.layer9.len();
|
||||||
|
data.layer9.reserve(Self::layer_len[9]);
|
||||||
|
data.child9.reserve(Self::layer_len[9]);
|
||||||
|
data.child13[abs.index] = insert as u32;
|
||||||
|
//debug!("set13 {:?} = {}", abs, insert);
|
||||||
|
for i in 0..Self::layer_len[9] {
|
||||||
|
data.layer9.push(Chunk5{
|
||||||
|
precent_air: 0.2,
|
||||||
|
percent_forrest: 0.3,
|
||||||
|
percent_lava: 0.4,
|
||||||
|
percent_water: 0.1,
|
||||||
|
});
|
||||||
|
data.child9.push(u32::MAX);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn drill_up(data: &mut LodData::<Self>, parent_abs: AbsIndex, delta: &mut Option<DefaultLodDelta<Self>>) {
|
||||||
|
unreachable!("finish this like in example");
|
||||||
|
match parent_abs.layer {
|
||||||
|
0 => {
|
||||||
|
panic!("SubBlocks_4 does not have children");
|
||||||
|
},
|
||||||
|
4 => {
|
||||||
|
//let delete = data.layer4[parent_abs.index].child_id.expect("has no childs to drill up") as usize;
|
||||||
|
//data.layer4[parent_abs.index].child_id = None;
|
||||||
|
//data.layer0.drain(delete..delete+Self::layer_len[0]);
|
||||||
|
},
|
||||||
|
9 => {
|
||||||
|
//let delete = data.layer9[parent_abs.index].child_id.expect("has no childs to drill up") as usize;
|
||||||
|
//data.layer9[parent_abs.index].child_id = None;
|
||||||
|
//data.layer4.drain(delete..delete+Self::layer_len[4]);
|
||||||
|
},
|
||||||
|
13 => {
|
||||||
|
//let delete = data.layer13[parent_abs.index].child_id.expect("has no childs to drill up") as usize;
|
||||||
|
//data.layer13[parent_abs.index].child_id = None;
|
||||||
|
//data.layer9.drain(delete..delete+Self::layer_len[9]);
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Terrain = LodData<TerrainLodConfig>;
|
@ -3,8 +3,11 @@ use crate::lodstore::{
|
|||||||
LodConfig,
|
LodConfig,
|
||||||
index::LodIndex,
|
index::LodIndex,
|
||||||
index::AbsIndex,
|
index::AbsIndex,
|
||||||
|
delta::LodDelta,
|
||||||
|
delta::DefaultLodDelta,
|
||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
use std::u32;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Region9 {
|
pub struct Region9 {
|
||||||
@ -70,6 +73,9 @@ impl LodConfig for TerrainLodConfig {
|
|||||||
type I14 = ();
|
type I14 = ();
|
||||||
type I15 = ();
|
type I15 = ();
|
||||||
|
|
||||||
|
type Delta = DefaultLodDelta<Self>;
|
||||||
|
type Additional = ();
|
||||||
|
|
||||||
const anchor_layer_id: u8 = 13;
|
const anchor_layer_id: u8 = 13;
|
||||||
|
|
||||||
const layer_volume: [Vec3<u32>; 16] = [
|
const layer_volume: [Vec3<u32>; 16] = [
|
||||||
@ -86,7 +92,7 @@ impl LodConfig for TerrainLodConfig {
|
|||||||
Vec3{x: 0, y: 0, z: 0},
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
Vec3{x: 0, y: 0, z: 0},
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
Vec3{x: 0, y: 0, z: 0},
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
Vec3{x: 16, y: 16, z: 16},
|
Vec3{x: 8, y: 8, z: 8},
|
||||||
Vec3{x: 0, y: 0, z: 0},
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
Vec3{x: 0, y: 0, z: 0},
|
Vec3{x: 0, y: 0, z: 0},
|
||||||
];
|
];
|
||||||
@ -108,72 +114,64 @@ impl LodConfig for TerrainLodConfig {
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
];
|
];
|
||||||
const layer_len: [usize; 16] = [
|
|
||||||
(Self::layer_volume[0].x * Self::layer_volume[0].y * Self::layer_volume[0].z) as usize,
|
|
||||||
(Self::layer_volume[1].x * Self::layer_volume[1].y * Self::layer_volume[1].z) as usize,
|
|
||||||
(Self::layer_volume[2].x * Self::layer_volume[2].y * Self::layer_volume[2].z) as usize,
|
|
||||||
(Self::layer_volume[3].x * Self::layer_volume[3].y * Self::layer_volume[3].z) as usize,
|
|
||||||
(Self::layer_volume[4].x * Self::layer_volume[4].y * Self::layer_volume[4].z) as usize,
|
|
||||||
(Self::layer_volume[5].x * Self::layer_volume[5].y * Self::layer_volume[5].z) as usize,
|
|
||||||
(Self::layer_volume[6].x * Self::layer_volume[6].y * Self::layer_volume[6].z) as usize,
|
|
||||||
(Self::layer_volume[7].x * Self::layer_volume[7].y * Self::layer_volume[7].z) as usize,
|
|
||||||
(Self::layer_volume[8].x * Self::layer_volume[8].y * Self::layer_volume[8].z) as usize,
|
|
||||||
(Self::layer_volume[9].x * Self::layer_volume[9].y * Self::layer_volume[9].z) as usize,
|
|
||||||
(Self::layer_volume[10].x * Self::layer_volume[10].y * Self::layer_volume[10].z) as usize,
|
|
||||||
(Self::layer_volume[11].x * Self::layer_volume[11].y * Self::layer_volume[11].z) as usize,
|
|
||||||
(Self::layer_volume[12].x * Self::layer_volume[12].y * Self::layer_volume[12].z) as usize,
|
|
||||||
(Self::layer_volume[13].x * Self::layer_volume[13].y * Self::layer_volume[13].z) as usize,
|
|
||||||
(Self::layer_volume[14].x * Self::layer_volume[14].y * Self::layer_volume[14].z) as usize,
|
|
||||||
(Self::layer_volume[15].x * Self::layer_volume[15].y * Self::layer_volume[15].z) as usize,
|
|
||||||
];
|
|
||||||
|
|
||||||
fn setup(&mut self) {
|
fn setup(&mut self) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drill_down(data: &mut LodData::<Self>, abs: AbsIndex) {
|
fn drill_down(data: &mut LodData::<Self>, abs: AbsIndex, delta: &mut Option<DefaultLodDelta<Self>>) {
|
||||||
match abs.layer {
|
match abs.layer {
|
||||||
0 => {
|
0 => {
|
||||||
panic!("cannot drill down further");
|
panic!("cannot drill down further");
|
||||||
},
|
},
|
||||||
4 => {
|
4 => {
|
||||||
|
if data.child4[abs.index] != u32::MAX {return;}
|
||||||
let insert = data.layer0.len();
|
let insert = data.layer0.len();
|
||||||
|
data.layer0.reserve(Self::layer_len[0]);
|
||||||
data.child4[abs.index] = insert as u32;
|
data.child4[abs.index] = insert as u32;
|
||||||
|
//debug!("set0 {:?} = {}", abs, insert);
|
||||||
for i in 0..Self::layer_len[0] {
|
for i in 0..Self::layer_len[0] {
|
||||||
data.layer0[i+insert] = SubBlock_4{
|
data.layer0.push(SubBlock_4{
|
||||||
material: 0,
|
material: 0,
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
9 => {
|
9 => {
|
||||||
|
if data.child9[abs.index] != u32::MAX {return;}
|
||||||
let insert = data.layer4.len();
|
let insert = data.layer4.len();
|
||||||
|
data.layer4.reserve(Self::layer_len[4]);
|
||||||
|
data.child4.reserve(Self::layer_len[4]);
|
||||||
data.child9[abs.index] = insert as u32;
|
data.child9[abs.index] = insert as u32;
|
||||||
|
//debug!("set4 {:?} = {}", abs, insert);
|
||||||
for i in 0..Self::layer_len[4] {
|
for i in 0..Self::layer_len[4] {
|
||||||
data.layer4[i+insert] = Block0{
|
data.layer4.push(Block0{
|
||||||
material: 0,
|
material: 0,
|
||||||
};
|
});
|
||||||
|
data.child4.push(u32::MAX);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
13 => {
|
13 => {
|
||||||
|
if data.child13[abs.index] != u32::MAX {return;}
|
||||||
let insert = data.layer9.len();
|
let insert = data.layer9.len();
|
||||||
data.child13[abs.index] = insert as u32;
|
data.layer9.reserve(Self::layer_len[9]);
|
||||||
for i in 0..Self::layer_len[9] {
|
data.child9.reserve(Self::layer_len[9]);
|
||||||
data.layer9[i+insert] = Chunk5{
|
data.child13[abs.index] = insert as u32;
|
||||||
precent_air: 0.2,
|
//debug!("set13 {:?} = {}", abs, insert);
|
||||||
percent_forrest: 0.3,
|
for i in 0..Self::layer_len[9] {
|
||||||
percent_lava: 0.4,
|
data.layer9.push(Chunk5{
|
||||||
percent_water: 0.1,
|
precent_air: 0.2,
|
||||||
};
|
percent_forrest: 0.3,
|
||||||
//ERROR HERE
|
percent_lava: 0.4,
|
||||||
unreachable!("finish this like in example");
|
percent_water: 0.1,
|
||||||
|
});
|
||||||
|
data.child9.push(u32::MAX);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drill_up(data: &mut LodData::<Self>, parent_abs: AbsIndex) {
|
fn drill_up(data: &mut LodData::<Self>, parent_abs: AbsIndex, delta: &mut Option<DefaultLodDelta<Self>>) {
|
||||||
unreachable!("finish this like in example");
|
unreachable!("finish this like in example");
|
||||||
match parent_abs.layer {
|
match parent_abs.layer {
|
||||||
0 => {
|
0 => {
|
||||||
|
@ -7,7 +7,6 @@ use std::sync::{
|
|||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use vek::*;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
job::JobManager,
|
job::JobManager,
|
||||||
|
Loading…
Reference in New Issue
Block a user