mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
increasing performance by another 10-20% on read as well as on write
Option<usize> takes 16 bytes which we cannot allow, so we use a u32 to store the same information, we use std::u32::MAX to mark that a LOD has no children we have no checks for that limit, so we hope it never gets that high... dear god... the intel laptop statistics now seem to be alot more stable and even top the ryzen desktop statistics, we get faster in every bench
This commit is contained in:
parent
caa7150556
commit
536ef3d6ff
3
.gitignore
vendored
3
.gitignore
vendored
@ -23,6 +23,9 @@ target
|
||||
|
||||
.project
|
||||
|
||||
# Valgrind, Callgrind
|
||||
callgrind.out.*
|
||||
|
||||
# Veloren
|
||||
*.rar
|
||||
*.log
|
||||
|
@ -1,4 +1,5 @@
|
||||
pub mod index;
|
||||
use std::u32;
|
||||
use std::sync::Arc;
|
||||
use std::collections::HashMap;
|
||||
use vek::*;
|
||||
@ -12,27 +13,46 @@ use index::{
|
||||
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 LayerInfo {
|
||||
fn get_child_index(&self) -> Option<usize>;
|
||||
|
||||
pub trait LodIntoOptionUsize: Copy {
|
||||
fn is_some(self) -> bool;
|
||||
fn into_usize(self) -> usize;
|
||||
}
|
||||
|
||||
pub trait LodConfig {
|
||||
type L0: LayerInfo; // 2^-4
|
||||
type L1: LayerInfo;
|
||||
type L2: LayerInfo;
|
||||
type L3: LayerInfo;
|
||||
type L4: LayerInfo; // 2^0
|
||||
type L5: LayerInfo;
|
||||
type L6: LayerInfo;
|
||||
type L7: LayerInfo;
|
||||
type L8: LayerInfo;
|
||||
type L9: LayerInfo;
|
||||
type L10: LayerInfo;
|
||||
type L11: LayerInfo;
|
||||
type L12: LayerInfo;
|
||||
type L13: LayerInfo;
|
||||
type L14: LayerInfo;
|
||||
type L15: LayerInfo; // 2^11
|
||||
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;
|
||||
|
||||
@ -72,6 +92,23 @@ pub struct LodData<X: LodConfig> {
|
||||
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>,
|
||||
}
|
||||
|
||||
@ -95,30 +132,46 @@ impl<X: LodConfig> LodData<X>
|
||||
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) -> Option<usize> {
|
||||
fn int_get_child_index(&self, abs: AbsIndex) -> usize {
|
||||
match abs.layer {
|
||||
0 => self.layer0[abs.index].get_child_index(),
|
||||
1 => self.layer1[abs.index].get_child_index(),
|
||||
2 => self.layer2[abs.index].get_child_index(),
|
||||
3 => self.layer3[abs.index].get_child_index(),
|
||||
4 => self.layer4[abs.index].get_child_index(),
|
||||
5 => self.layer5[abs.index].get_child_index(),
|
||||
6 => self.layer6[abs.index].get_child_index(),
|
||||
7 => self.layer7[abs.index].get_child_index(),
|
||||
8 => self.layer8[abs.index].get_child_index(),
|
||||
9 => self.layer9[abs.index].get_child_index(),
|
||||
10 => self.layer10[abs.index].get_child_index(),
|
||||
11 => self.layer11[abs.index].get_child_index(),
|
||||
12 => self.layer12[abs.index].get_child_index(),
|
||||
13 => self.layer13[abs.index].get_child_index(),
|
||||
14 => self.layer14[abs.index].get_child_index(),
|
||||
15 => self.layer15[abs.index].get_child_index(),
|
||||
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"),
|
||||
}
|
||||
}
|
||||
@ -131,14 +184,14 @@ impl<X: LodConfig> LodData<X>
|
||||
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);
|
||||
//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).unwrap();
|
||||
let parent_child_index = self.int_get_child_index(parent_abs);
|
||||
Self::int_get(parent_abs, child_lod, parent_lod, parent_child_index)
|
||||
}
|
||||
|
||||
@ -146,7 +199,7 @@ impl<X: LodConfig> LodData<X>
|
||||
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);
|
||||
//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;
|
||||
@ -246,7 +299,7 @@ impl<X: LodConfig> LodData<X>
|
||||
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 );
|
||||
//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]
|
||||
@ -283,31 +336,6 @@ impl<X: LodConfig> LodData<X>
|
||||
debug_assert_eq!(wanted_abs.layer, 0);
|
||||
&self.layer0[wanted_abs.index]
|
||||
}
|
||||
/*
|
||||
function to return a trait object, should not be used because slow,
|
||||
so as a rule of thumb only use it in case i modify self, because modify should occur not that often, and is slow anyways
|
||||
*/
|
||||
fn get_mut_dyn(&mut self, abs: AbsIndex) -> &mut dyn LayerInfo {
|
||||
match abs.layer {
|
||||
0 => &mut self.layer0[abs.index],
|
||||
1 => &mut self.layer1[abs.index],
|
||||
2 => &mut self.layer2[abs.index],
|
||||
3 => &mut self.layer3[abs.index],
|
||||
4 => &mut self.layer4[abs.index],
|
||||
5 => &mut self.layer5[abs.index],
|
||||
6 => &mut self.layer6[abs.index],
|
||||
7 => &mut self.layer7[abs.index],
|
||||
8 => &mut self.layer8[abs.index],
|
||||
9 => &mut self.layer9[abs.index],
|
||||
10 => &mut self.layer10[abs.index],
|
||||
11 => &mut self.layer11[abs.index],
|
||||
12 => &mut self.layer12[abs.index],
|
||||
13 => &mut self.layer13[abs.index],
|
||||
14 => &mut self.layer14[abs.index],
|
||||
15 => &mut self.layer15[abs.index],
|
||||
_ => panic!("invalid level"),
|
||||
}
|
||||
}
|
||||
|
||||
// returns the last LodIndex, that belongs to a parent AbsIndex
|
||||
fn get_last_child_lod(parent: LodIndex, parent_level: u8) -> LodIndex {
|
||||
@ -335,29 +363,29 @@ impl<X: LodConfig> LodData<X>
|
||||
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);
|
||||
//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));
|
||||
//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).unwrap();
|
||||
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);
|
||||
//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);
|
||||
//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);
|
||||
@ -366,7 +394,7 @@ impl<X: LodConfig> LodData<X>
|
||||
|
||||
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);
|
||||
//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);
|
||||
}
|
||||
}
|
||||
@ -389,7 +417,7 @@ impl<X: LodConfig> LodData<X>
|
||||
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);
|
||||
//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] {
|
||||
@ -404,7 +432,7 @@ impl<X: LodConfig> LodData<X>
|
||||
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);
|
||||
//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;
|
||||
@ -422,8 +450,20 @@ impl<X: LodConfig> LodData<X>
|
||||
}
|
||||
}
|
||||
|
||||
impl LayerInfo for () {
|
||||
fn get_child_index(self: &Self) -> Option<usize> {
|
||||
None
|
||||
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
|
||||
}
|
||||
}
|
@ -1,28 +1,25 @@
|
||||
use crate::lodstore::{
|
||||
LodData,
|
||||
LayerInfo,
|
||||
LodConfig,
|
||||
index::LodIndex,
|
||||
index::AbsIndex,
|
||||
};
|
||||
use vek::*;
|
||||
use std::u32;
|
||||
|
||||
#[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)]
|
||||
@ -34,33 +31,10 @@ 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)
|
||||
}
|
||||
}
|
||||
|
||||
impl LayerInfo for Example5 {
|
||||
fn get_child_index(self: &Self) -> Option<usize> {
|
||||
self.child_id.map(|n| n as usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl LayerInfo for Example0 {
|
||||
fn get_child_index(self: &Self) -> Option<usize> {
|
||||
self.child_id.map(|n| n as usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl LayerInfo for Example_4 {
|
||||
fn get_child_index(self: &Self) -> Option<usize> { None }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ExampleLodConfig {}
|
||||
|
||||
@ -82,6 +56,23 @@ impl LodConfig for ExampleLodConfig {
|
||||
type L14 = ();
|
||||
type L15 = ();
|
||||
|
||||
type I0 = ();
|
||||
type I1 = ();
|
||||
type I2 = ();
|
||||
type I3 = ();
|
||||
type I4 = u32; // In reality 2^(16*3) SubBlock_4 should be possible, but 2^48 subblocks would kill anything anyway, so save 2 bytes here
|
||||
type I5 = ();
|
||||
type I6 = ();
|
||||
type I7 = ();
|
||||
type I8 = ();
|
||||
type I9 = u32; // see Block0 2^(12*3)
|
||||
type I10 = ();
|
||||
type I11 = ();
|
||||
type I12 = ();
|
||||
type I13 = u32; // Chunk5 2^(7*3), this is valid
|
||||
type I14 = ();
|
||||
type I15 = ();
|
||||
|
||||
const anchor_layer_id: u8 = 13;
|
||||
|
||||
// this is not for the children, a layer9 has 32x32x32 childs, not 16x16x16
|
||||
@ -152,10 +143,10 @@ impl LodConfig for ExampleLodConfig {
|
||||
panic!("cannot drill down further");
|
||||
},
|
||||
4 => {
|
||||
if data.layer4[abs.index].child_id.is_some() {return;}
|
||||
if data.child4[abs.index] != u32::MAX {return;}
|
||||
let insert = data.layer0.len();
|
||||
data.layer0.reserve(Self::layer_len[0]);
|
||||
data.layer4[abs.index].child_id = Some(insert as u32);
|
||||
data.child4[abs.index] = insert as u32;
|
||||
//debug!("set0 {:?} = {}", abs, insert);
|
||||
for i in 0..Self::layer_len[0] {
|
||||
data.layer0.push(Example_4{
|
||||
@ -164,29 +155,31 @@ impl LodConfig for ExampleLodConfig {
|
||||
}
|
||||
},
|
||||
9 => {
|
||||
if data.layer9[abs.index].child_id.is_some() {return;}
|
||||
if data.child9[abs.index] != u32::MAX {return;}
|
||||
let insert = data.layer4.len();
|
||||
data.layer4.reserve(Self::layer_len[4]);
|
||||
data.layer9[abs.index].child_id = Some(insert as u32);
|
||||
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(Example0{
|
||||
data: 0,
|
||||
child_id: None,
|
||||
});
|
||||
data.child4.push(u32::MAX);
|
||||
}
|
||||
},
|
||||
13 => {
|
||||
if data.layer13[abs.index].child_id.is_some() {return;}
|
||||
if data.child13[abs.index] != u32::MAX {return;}
|
||||
let insert = data.layer9.len();
|
||||
data.layer9.reserve(Self::layer_len[9]);
|
||||
data.layer13[abs.index].child_id = Some(insert as u32);
|
||||
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(Example5{
|
||||
data: [0; 130],
|
||||
child_id: None,
|
||||
});
|
||||
data.child9.push(u32::MAX);
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
@ -200,19 +193,22 @@ impl LodConfig for ExampleLodConfig {
|
||||
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;
|
||||
let delete = data.child4[parent_abs.index] as usize;
|
||||
data.child4[parent_abs.index] = u32::MAX;
|
||||
data.layer0.drain(delete..delete+Self::layer_len[0]);
|
||||
data.child0.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;
|
||||
let delete = data.child9[parent_abs.index] as usize;
|
||||
data.child9[parent_abs.index] = u32::MAX;
|
||||
data.layer4.drain(delete..delete+Self::layer_len[4]);
|
||||
data.child4.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;
|
||||
let delete = data.child13[parent_abs.index] as usize;
|
||||
data.child13[parent_abs.index] = u32::MAX;
|
||||
data.layer9.drain(delete..delete+Self::layer_len[9]);
|
||||
data.child9.drain(delete..delete+Self::layer_len[9]);
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
@ -251,13 +247,19 @@ mod tests {
|
||||
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 p_e9 = 1.0+p_foreign;
|
||||
let p_e5 = p_e9*p_e5;
|
||||
let p_e0 = p_e5*p_e0;
|
||||
let p_e_4 = p_e0*p_e_4;
|
||||
let act9 = (abs9 as f32 * p_e9 ) as u32;
|
||||
let act5 = (abs5 as f32 * p_e5) as u32;
|
||||
let act0 = (abs0 as f32 * p_e0 ) as u32;
|
||||
let act_4 = (abs_4 as f32 * p_e_4 ) as u32;
|
||||
|
||||
let w9 = index::two_pow_u(13) as u32;
|
||||
result.layer13 = vec![Example9::new(); 8*8*8];
|
||||
result.child13 = vec![u32::MAX; 8*8*8];
|
||||
println!("size test {} -- {}", size_of::<usize>(), size_of::<Option<usize>>());
|
||||
for x in 0..8 {
|
||||
for y in 0..8 {
|
||||
for z in 0..8 {
|
||||
@ -265,6 +267,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("creating Region with {} 5er, {} 0er, {} -4er", act5, act0 , act_4);
|
||||
while result.layer9.len() < act5 as usize {
|
||||
let index = randIndex(&mut rng);
|
||||
@ -289,10 +292,8 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reagiontest() {
|
||||
let reg = createRegion(0.0015, 0.01, 0.0000001, 0.1);
|
||||
|
||||
thread::sleep(time::Duration::from_secs(4));
|
||||
fn regiontest() {
|
||||
let reg = createRegion(0.0015, 0.001, 0.001, 0.1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -376,7 +377,122 @@ mod tests {
|
||||
|
||||
#[bench]
|
||||
fn bench_region(b: &mut Bencher) {
|
||||
b.iter(|| createRegion(0.00015, 0.0001, 0.00000001, 0.1));
|
||||
b.iter(|| createRegion(0.0015, 0.001, 0.001, 0.1));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_clone_region(b: &mut Bencher) {
|
||||
let region = createRegion(0.00015, 0.0001, 0.00000001, 0.1);
|
||||
b.iter(|| region.clone());
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_make_at_least1(b: &mut Bencher) {
|
||||
let region = createRegion(0.0, 0.0, 0.0, 0.1);
|
||||
let low = LodIndex::new(Vec3::new(0, 0, 0));
|
||||
let high = LodIndex::new(Vec3::new(255, 255, 255));
|
||||
b.iter(|| {
|
||||
let mut reg2 = region.clone();
|
||||
reg2.make_at_least(low,high,0);
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_make_at_least2(b: &mut Bencher) {
|
||||
let region = createRegion(0.0, 0.0, 0.0, 0.1);
|
||||
let low = LodIndex::new(Vec3::new(0, 0, 0));
|
||||
let high = LodIndex::new(Vec3::new(4, 4, 4));
|
||||
b.iter(|| {
|
||||
let mut reg2 = region.clone();
|
||||
reg2.make_at_least(low,high,0);
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_make_at_least3(b: &mut Bencher) {
|
||||
let region = createRegion(0.0, 0.0, 0.0, 0.1);
|
||||
let low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
||||
let high = LodIndex::new(Vec3::new(10240, 10240, 10240));
|
||||
b.iter(|| {
|
||||
let mut reg2 = region.clone();
|
||||
reg2.make_at_least(low,high,4);
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_access_0(b: &mut Bencher) {
|
||||
let mut reg = createRegion(0.0015, 0.001, 0.001, 0.1);
|
||||
let access = LodIndex::new(Vec3::new(8561, 8312, 8412));
|
||||
let low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
||||
let high = LodIndex::new(Vec3::new(8800, 8800, 8800));
|
||||
reg.make_at_least(low,high,0);
|
||||
b.iter(|| reg.get0(access));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_access_0_4_multiple(b: &mut Bencher) {
|
||||
let mut reg = createRegion(0.0015, 0.001, 0.001, 0.1);
|
||||
let low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
||||
let high = LodIndex::new(Vec3::new(8800, 8800, 8800));
|
||||
reg.make_at_least(low,high,0);
|
||||
b.iter(|| {
|
||||
reg.get0(LodIndex::new(Vec3::new(8561, 8312, 8412)));
|
||||
reg.get0(LodIndex::new(Vec3::new(8200, 8599, 8413)));
|
||||
reg.get0(LodIndex::new(Vec3::new(8300, 8782, 8414)));
|
||||
reg.get0(LodIndex::new(Vec3::new(8761, 8352, 8212)));
|
||||
reg.get0(LodIndex::new(Vec3::new(8261, 8282, 8712)));
|
||||
reg.get0(LodIndex::new(Vec3::new(8461, 8752, 8652)));
|
||||
reg.get0(LodIndex::new(Vec3::new(8661, 8512, 8582)));
|
||||
reg.get0(LodIndex::new(Vec3::new(8461, 8612, 8419)));
|
||||
reg.get0(LodIndex::new(Vec3::new(8261, 8192, 8414)));
|
||||
reg.get0(LodIndex::new(Vec3::new(8761, 8192, 8192)));
|
||||
reg.get4(LodIndex::new(Vec3::new(8448, 8704, 8704)));
|
||||
reg.get4(LodIndex::new(Vec3::new(8461, 8448, 8704)));
|
||||
reg.get4(LodIndex::new(Vec3::new(8704, 8192, 8704)));
|
||||
reg.get4(LodIndex::new(Vec3::new(8192, 8704, 8192)));
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_access_0_random1(b: &mut Bencher) {
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut reg = createRegion(0.0015, 0.001, 0.001, 0.1);
|
||||
let low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
||||
let high = LodIndex::new(Vec3::new(9192, 9192, 9192));
|
||||
let mut accesslist = Vec::new();
|
||||
for i in 0..1000000 {
|
||||
let x: u16 = rng.gen();
|
||||
let y: u16 = rng.gen();
|
||||
let z: u16 = rng.gen();
|
||||
accesslist.push(LodIndex::new(Vec3::new(x,y,z).map(|x| (8192 + x / 66) as u32)));
|
||||
}
|
||||
reg.make_at_least(low,high,0);
|
||||
b.iter(|| {
|
||||
for i in 0..1000000 {
|
||||
reg.get0(accesslist[i]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_access_0_random2(b: &mut Bencher) {
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut reg = createRegion(0.0015, 0.001, 0.001, 0.1);
|
||||
let low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
||||
let high = LodIndex::new(Vec3::new(9192, 9192, 9192));
|
||||
let mut accesslist = Vec::new();
|
||||
for i in 0..9990000 {
|
||||
let x: u16 = rng.gen();
|
||||
let y: u16 = rng.gen();
|
||||
let z: u16 = rng.gen();
|
||||
accesslist.push(LodIndex::new(Vec3::new(x,y,z).map(|x| (8192 + x / 66) as u32)));
|
||||
}
|
||||
reg.make_at_least(low,high,0);
|
||||
b.iter(|| {
|
||||
for i in 0..9990000 {
|
||||
reg.get0(accesslist[i]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::lodstore::{
|
||||
LodData,
|
||||
LayerInfo,
|
||||
LodConfig,
|
||||
index::LodIndex,
|
||||
index::AbsIndex,
|
||||
@ -13,7 +12,6 @@ pub struct Region9 {
|
||||
percent_forrest: f32,
|
||||
percent_lava: f32,
|
||||
percent_water: f32,
|
||||
child_id: Option<u32>, // Chunk5 2^(7*3), this is valid
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -22,13 +20,11 @@ pub struct Chunk5 {
|
||||
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)]
|
||||
@ -36,30 +32,6 @@ 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)
|
||||
}
|
||||
}
|
||||
|
||||
impl LayerInfo for Chunk5 {
|
||||
fn get_child_index(self: &Self) -> Option<usize> {
|
||||
self.child_id.map(|n| n as usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl LayerInfo for Block0 {
|
||||
fn get_child_index(self: &Self) -> Option<usize> {
|
||||
self.child_id.map(|n| n as usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl LayerInfo for SubBlock_4 {
|
||||
fn get_child_index(self: &Self) -> Option<usize> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TerrainLodConfig {}
|
||||
|
||||
@ -81,6 +53,23 @@ impl LodConfig for TerrainLodConfig {
|
||||
type L14 = ();
|
||||
type L15 = ();
|
||||
|
||||
type I0 = ();
|
||||
type I1 = ();
|
||||
type I2 = ();
|
||||
type I3 = ();
|
||||
type I4 = u32; // In reality 2^(16*3) SubBlock_4 should be possible, but 2^48 subblocks would kill anything anyway, so save 2 bytes here
|
||||
type I5 = ();
|
||||
type I6 = ();
|
||||
type I7 = ();
|
||||
type I8 = ();
|
||||
type I9 = u32; // see Block0 2^(12*3)
|
||||
type I10 = ();
|
||||
type I11 = ();
|
||||
type I12 = ();
|
||||
type I13 = u32; // Chunk5 2^(7*3), this is valid
|
||||
type I14 = ();
|
||||
type I15 = ();
|
||||
|
||||
const anchor_layer_id: u8 = 13;
|
||||
|
||||
const layer_volume: [Vec3<u32>; 16] = [
|
||||
@ -149,7 +138,7 @@ impl LodConfig for TerrainLodConfig {
|
||||
},
|
||||
4 => {
|
||||
let insert = data.layer0.len();
|
||||
data.layer4[abs.index].child_id = Some(insert as u32);
|
||||
data.child4[abs.index] = insert as u32;
|
||||
for i in 0..Self::layer_len[0] {
|
||||
data.layer0[i+insert] = SubBlock_4{
|
||||
material: 0,
|
||||
@ -158,25 +147,25 @@ impl LodConfig for TerrainLodConfig {
|
||||
},
|
||||
9 => {
|
||||
let insert = data.layer4.len();
|
||||
data.layer9[abs.index].child_id = Some(insert as u32);
|
||||
data.child9[abs.index] = insert as u32;
|
||||
for i in 0..Self::layer_len[4] {
|
||||
data.layer4[i+insert] = Block0{
|
||||
material: 0,
|
||||
child_id: None,
|
||||
};
|
||||
}
|
||||
},
|
||||
13 => {
|
||||
let insert = data.layer9.len();
|
||||
data.layer13[abs.index].child_id = Some(insert as u32);
|
||||
data.child13[abs.index] = insert as u32;
|
||||
for i in 0..Self::layer_len[9] {
|
||||
data.layer9[i+insert] = Chunk5{
|
||||
precent_air: 0.2,
|
||||
percent_forrest: 0.3,
|
||||
percent_lava: 0.4,
|
||||
percent_water: 0.1,
|
||||
child_id: None,
|
||||
};
|
||||
precent_air: 0.2,
|
||||
percent_forrest: 0.3,
|
||||
percent_lava: 0.4,
|
||||
percent_water: 0.1,
|
||||
};
|
||||
//ERROR HERE
|
||||
unreachable!("finish this like in example");
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
@ -185,24 +174,25 @@ impl LodConfig for TerrainLodConfig {
|
||||
}
|
||||
|
||||
fn drill_up(data: &mut LodData::<Self>, parent_abs: AbsIndex) {
|
||||
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]);
|
||||
//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]);
|
||||
//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]);
|
||||
//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!(),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user