fix all tests, now the new ECS access should work fine.

this implementations reaches about 3000 ns per access, need to improve further
This commit is contained in:
Marcel Märtens 2019-07-18 17:09:49 +02:00
parent 3c92e831e7
commit caa7150556
4 changed files with 103 additions and 85 deletions

View File

@ -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<u32>) -> usize {
let index = index.get();
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
}

View File

@ -36,9 +36,9 @@ pub trait LodConfig {
const anchor_layer_id: u8;
const layer_volume: [Vec3<u32>; 16]; // e.g. (1|1|1) for l0 or (4|4|4) for l2 optimization
const child_layer_id: [Option<u8>; 16];
const child_len: [usize; 16]; //number of childs on this layer, MUST BE 2^(SELF::child_dim*3)
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;
@ -130,8 +130,8 @@ impl<X: LodConfig> LodData<X>
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<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 {} - {}", 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<X: LodConfig> LodData<X>
fn ppp(level: u8) -> &'static str {
match level {
0 => " | ",
1 => " - ",
4 => " ---- ",
5 => " ----- ",
9 => " ---------- ",
@ -337,7 +336,6 @@ impl<X: LodConfig> LodData<X>
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<X: LodConfig> LodData<X>
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<X: LodConfig> LodData<X>
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<X: LodConfig> LodData<X>
}
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) {

View File

@ -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<u32>; 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<u8>; 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::<Example>(), size_of::<Example9>(), size_of::<Example5>());
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));
}*/
}
}

View File

@ -84,22 +84,22 @@ impl LodConfig for TerrainLodConfig {
const anchor_layer_id: u8 = 13;
const layer_volume: [Vec3<u32>; 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<u8>; 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!(),
}