From caa715055677bdda368d75a780c6a1fe5ef92a2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=A4rtens?= Date: Thu, 18 Jul 2019 17:09:49 +0200 Subject: [PATCH] fix all tests, now the new ECS access should work fine. this implementations reaches about 3000 ns per access, need to improve further --- worldsim/src/lodstore/index.rs | 5 +- worldsim/src/lodstore/mod.rs | 25 +++--- worldsim/src/region/lod/example.rs | 118 +++++++++++++++++------------ worldsim/src/region/lod/terrain.rs | 40 +++++----- 4 files changed, 103 insertions(+), 85 deletions(-) diff --git a/worldsim/src/lodstore/index.rs b/worldsim/src/lodstore/index.rs index 9ab2ff5e7f..3b553348f0 100644 --- a/worldsim/src/lodstore/index.rs +++ b/worldsim/src/lodstore/index.rs @@ -235,8 +235,9 @@ pub const fn two_pow_u(n: u8) -> u16 { 1 << n } -pub fn relative_to_1d(index: LodIndex, relative_size: Vec3) -> usize { - let index = index.get(); +pub fn relative_to_1d(child_lod: LodIndex, parent_lod: LodIndex, child_layer: u8, relative_size: Vec3) -> 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 } diff --git a/worldsim/src/lodstore/mod.rs b/worldsim/src/lodstore/mod.rs index dd79b1ce14..7f4f053e16 100644 --- a/worldsim/src/lodstore/mod.rs +++ b/worldsim/src/lodstore/mod.rs @@ -36,9 +36,9 @@ pub trait LodConfig { const anchor_layer_id: u8; - const layer_volume: [Vec3; 16]; // e.g. (1|1|1) for l0 or (4|4|4) for l2 optimization - const child_layer_id: [Option; 16]; - const child_len: [usize; 16]; //number of childs on this layer, MUST BE 2^(SELF::child_dim*3) + const layer_volume: [Vec3; 16]; // number of elements on this layer as Vec3 (not on child layer!) + const child_layer_id: [Option; 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::, abs: AbsIndex) where Self: Sized; @@ -130,8 +130,8 @@ impl LodData 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, X::layer_volume[parent_abs.layer as usize]); - println!("int_get - parent_abs {} child_lod {} parent_lod {} parent_child_index {} child_offset {}", parent_abs, child_lod, parent_lod, parent_child_index, child_offset); + 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) } @@ -146,7 +146,7 @@ impl LodData 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 {} - {}", 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; @@ -318,7 +318,6 @@ impl LodData fn ppp(level: u8) -> &'static str { match level { 0 => " | ", - 1 => " - ", 4 => " ---- ", 5 => " ----- ", 9 => " ---------- ", @@ -337,7 +336,6 @@ impl LodData 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!("{} parent.layer {} child_layer {:?} target_level {}", Self::ppp(parent.layer), parent.layer, child_layer, target_level); if parent.layer > target_level { // create necessary childs: X::drill_down(self, parent); @@ -349,10 +347,10 @@ impl LodData 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 parent_children = X::layer_volume[parent.layer as usize]; + let child_volume = X::layer_volume[child_layer as usize]; // loop over childs and calculate correct lower and - let lower_xyz = child_lower.get().map(|e| e / child_lod_width); - let upper_xyz = child_upper.get().map(|e| e / child_lod_width); + 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); @@ -361,14 +359,13 @@ impl LodData 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 * parent_children[2] * parent_children[1] + y * parent_children[2] + z) as usize; + 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!("{} potential restrict {} {} ", Self::ppp(parent.layer), child_lower, 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); } @@ -416,8 +413,6 @@ impl LodData } x += anchor_width; } - const p: u8 = 3; - let u = X::child_len[7]; } fn make_at_most(&mut self, lower: LodIndex, upper: LodIndex, level: i8) { diff --git a/worldsim/src/region/lod/example.rs b/worldsim/src/region/lod/example.rs index a55e8d49c4..6bf5798cf8 100644 --- a/worldsim/src/region/lod/example.rs +++ b/worldsim/src/region/lod/example.rs @@ -84,23 +84,24 @@ impl LodConfig for ExampleLodConfig { const anchor_layer_id: u8 = 13; + // this is not for the children, a layer9 has 32x32x32 childs, not 16x16x16 const layer_volume: [Vec3; 16] = [ - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, Vec3{x: 16, y: 16, z: 16}, - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, + Vec3{x: 0, y: 0, z: 0}, + Vec3{x: 0, y: 0, z: 0}, + Vec3{x: 0, y: 0, z: 0}, Vec3{x: 32, y: 32, z: 32}, - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, + 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: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, + 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: 0, y: 0, z: 0}, + Vec3{x: 0, y: 0, z: 0}, ]; const child_layer_id: [Option; 16] = [ None, @@ -121,7 +122,7 @@ impl LodConfig for ExampleLodConfig { None, ]; - const child_len: [usize; 16] = [ + 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, @@ -153,10 +154,10 @@ impl LodConfig for ExampleLodConfig { 4 => { if data.layer4[abs.index].child_id.is_some() {return;} let insert = data.layer0.len(); - data.layer0.reserve(Self::child_len[4]); + data.layer0.reserve(Self::layer_len[0]); data.layer4[abs.index].child_id = Some(insert as u32); - println!("set0 {:?} = {}", abs, insert); - for i in 0..Self::child_len[4] { + //debug!("set0 {:?} = {}", abs, insert); + for i in 0..Self::layer_len[0] { data.layer0.push(Example_4{ data: 0, }); @@ -165,10 +166,10 @@ impl LodConfig for ExampleLodConfig { 9 => { if data.layer9[abs.index].child_id.is_some() {return;} let insert = data.layer4.len(); - data.layer4.reserve(Self::child_len[9]); + data.layer4.reserve(Self::layer_len[4]); data.layer9[abs.index].child_id = Some(insert as u32); - println!("set {:?} = {}", abs, insert); - for i in 0..Self::child_len[9] { + //debug!("set4 {:?} = {}", abs, insert); + for i in 0..Self::layer_len[4] { data.layer4.push(Example0{ data: 0, child_id: None, @@ -178,10 +179,10 @@ impl LodConfig for ExampleLodConfig { 13 => { if data.layer13[abs.index].child_id.is_some() {return;} let insert = data.layer9.len(); - data.layer9.reserve(Self::child_len[13]); + data.layer9.reserve(Self::layer_len[9]); data.layer13[abs.index].child_id = Some(insert as u32); - println!("set13 {:?} = {}", abs, insert); - for i in 0..Self::child_len[13] { + //debug!("set13 {:?} = {}", abs, insert); + for i in 0..Self::layer_len[9] { data.layer9.push(Example5{ data: [0; 130], child_id: None, @@ -201,17 +202,17 @@ impl LodConfig for ExampleLodConfig { 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::child_len[0]); + 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::child_len[5]); + 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::child_len[9]); + data.layer9.drain(delete..delete+Self::layer_len[9]); }, _ => unreachable!(), } @@ -260,8 +261,6 @@ mod tests { for x in 0..8 { for y in 0..8 { for z in 0..8 { - println!("{:?}", Vec3::new(x*w9,y*w9,z*w9)); - println!("{:?}", LodIndex::new(Vec3::new(x*w9,y*w9,z*w9))); result.anchor.insert(LodIndex::new(Vec3::new(x*w9,y*w9,z*w9)), (x*8*8+y*8+z) as usize); } } @@ -288,7 +287,7 @@ mod tests { println!("size {} {} {}", size_of::(), size_of::(), size_of::()); result } -/* + #[test] fn reagiontest() { let reg = createRegion(0.0015, 0.01, 0.0000001, 0.1); @@ -303,14 +302,12 @@ mod tests { let high = LodIndex::new(Vec3::new(16384, 16384, 16384)); reg.make_at_least(low,high,4); } -*/ - /* + #[test] - fn access_0() { + fn access_0a() { let mut reg = 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)); - //thread::sleep(time::Duration::from_secs(10)); reg.make_at_least(low,high,0); reg.get0(LodIndex::new(Vec3::new(0, 0, 0))); reg.get0(LodIndex::new(Vec3::new(1, 0, 0))); @@ -320,24 +317,50 @@ mod tests { reg.get0(LodIndex::new(Vec3::new(2, 2, 2))); reg.get0(LodIndex::new(Vec3::new(3, 3, 3))); reg.get0(LodIndex::new(Vec3::new(4, 4, 4))); - }*/ + } #[test] fn access_0b() { + let mut reg = createRegion(0.0, 0.0, 0.0, 0.1); + let low = LodIndex::new(Vec3::new(8704, 8704, 8704)); + let high = LodIndex::new(Vec3::new(9216, 9216, 9216)); + reg.make_at_least(low,high,0); + 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, 9001))); + reg.get0(LodIndex::new(Vec3::new(9001, 9000, 9000))); + reg.get0(LodIndex::new(Vec3::new(9001, 9001, 9001))); + reg.get0(LodIndex::new(Vec3::new(9216, 9216, 9216))); + reg.get4(LodIndex::new(Vec3::new(9000, 9000, 9000))); + reg.get9(LodIndex::new(Vec3::new(9000, 9000, 9000))); + } + + #[test] + #[should_panic] + fn access_0c_fail() { + let mut reg = createRegion(0.0, 0.0, 0.0, 0.1); + let low = LodIndex::new(Vec3::new(8704, 8704, 8704)); + let high = LodIndex::new(Vec3::new(9216, 9216, 9216)); + reg.make_at_least(low,high,0); + reg.get0(LodIndex::new(Vec3::new(8704, 8704, 8703))); + } + + #[test] + #[should_panic] + fn access_0d_fail() { + let mut reg = createRegion(0.0, 0.0, 0.0, 0.1); + let low = LodIndex::new(Vec3::new(8704, 8704, 8704)); + let high = LodIndex::new(Vec3::new(9216, 9216, 9216)); + reg.make_at_least(low,high,0); + reg.get0(LodIndex::new(Vec3::new(10240, 10240, 10240))); + } + + #[test] + fn access_4() { let mut reg = 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)); - //thread::sleep(time::Duration::from_secs(10)); - reg.make_at_least(low,high,0); - } -/* - #[test] - fn access_0b() { - let mut reg = 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)); - reg.make_at_least(low,high,0); - reg.get0(LodIndex::new(Vec3::new(5, 5, 5))); //this access is not guaranteed but will work + reg.make_at_least(low,high,4); } #[test] @@ -357,14 +380,13 @@ mod tests { } #[bench] - fn access_4(b: &mut Bencher) { + fn bench_access_4(b: &mut Bencher) { let mut reg = createRegion(0.0, 0.0, 0.0, 0.1); let access = LodIndex::new(Vec3::new(9561, 9312, 8412)); let low = LodIndex::new(Vec3::new(8192, 8192, 8192)); let high = LodIndex::new(Vec3::new(10240, 10240, 10240)); reg.make_at_least(low,high,4); - b.iter(|| reg.get4(access)); - }*/ + } } \ No newline at end of file diff --git a/worldsim/src/region/lod/terrain.rs b/worldsim/src/region/lod/terrain.rs index c6fa478fb6..a4c1ab5681 100644 --- a/worldsim/src/region/lod/terrain.rs +++ b/worldsim/src/region/lod/terrain.rs @@ -84,22 +84,22 @@ impl LodConfig for TerrainLodConfig { const anchor_layer_id: u8 = 13; const layer_volume: [Vec3; 16] = [ - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, Vec3{x: 16, y: 16, z: 16}, - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, + Vec3{x: 0, y: 0, z: 0}, + Vec3{x: 0, y: 0, z: 0}, + Vec3{x: 0, y: 0, z: 0}, Vec3{x: 32, y: 32, z: 32}, - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, + 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: 1, y: 1, z: 1}, - Vec3{x: 1, y: 1, z: 1}, + 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: 0, y: 0, z: 0}, + Vec3{x: 0, y: 0, z: 0}, ]; const child_layer_id: [Option; 16] = [ None, @@ -119,7 +119,7 @@ impl LodConfig for TerrainLodConfig { None, None, ]; - const child_len: [usize; 16] = [ + 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, @@ -150,7 +150,7 @@ impl LodConfig for TerrainLodConfig { 4 => { let insert = data.layer0.len(); data.layer4[abs.index].child_id = Some(insert as u32); - for i in 0..Self::child_len[4] { + for i in 0..Self::layer_len[0] { data.layer0[i+insert] = SubBlock_4{ material: 0, }; @@ -159,7 +159,7 @@ impl LodConfig for TerrainLodConfig { 9 => { let insert = data.layer4.len(); data.layer9[abs.index].child_id = Some(insert as u32); - for i in 0..Self::child_len[9] { + for i in 0..Self::layer_len[4] { data.layer4[i+insert] = Block0{ material: 0, child_id: None, @@ -169,7 +169,7 @@ impl LodConfig for TerrainLodConfig { 13 => { let insert = data.layer9.len(); data.layer13[abs.index].child_id = Some(insert as u32); - for i in 0..Self::child_len[13] { + for i in 0..Self::layer_len[9] { data.layer9[i+insert] = Chunk5{ precent_air: 0.2, percent_forrest: 0.3, @@ -192,17 +192,17 @@ impl LodConfig for TerrainLodConfig { 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::child_len[4]); + 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::child_len[9]); + 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::child_len[13]); + data.layer9.drain(delete..delete+Self::layer_len[9]); }, _ => unreachable!(), }