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;
|
||||
|
||||
/*
|
||||
For our LodStructures we need a type that covers the values from 0 - 2047 in steps of 1/32.
|
||||
which is 11 bits for the digits before the decimal point and 5 bits for the digits after the decimal point.
|
||||
Because for accessing the decimal point makes no difference we use a u16 to represent this value.
|
||||
The value needs to be shiftet to get it's "real inworld size",
|
||||
A region owns the Values from in (0, 2048) in steps of 1/32.
|
||||
But because regions can also subscribe we add support to the range (0, 2048*3).
|
||||
which is 13 bits for the digits before the decimal point and 5 bits for the digits after the decimal point.
|
||||
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
|
||||
0 -> 0
|
||||
1 -> 2047 31/32
|
||||
65535 -> 2047 31/32
|
||||
-- owned
|
||||
65536 -> 2048
|
||||
131071 -> 4095 31/32
|
||||
-- upper neighbor
|
||||
196607 -> 6143 31/32
|
||||
|
||||
*/
|
||||
|
||||
#[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_X_MASK32: u32 = 0b0000_0000_0000_0011_1111_1111_1111_1111;
|
||||
|
||||
//TODO: Optimize!
|
||||
impl LodIndex {
|
||||
pub fn new(data: Vec3<u32>) -> Self {
|
||||
let mut index = LodIndex {data: 0};
|
||||
@ -61,9 +60,9 @@ impl LodIndex {
|
||||
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 f = two_pow_u(level) as u32;
|
||||
let f = two_pow_u(layer) as u32;
|
||||
LodIndex::new(xyz.map(|i| {
|
||||
(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)]
|
||||
mod tests {
|
||||
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;
|
||||
use std::u32;
|
||||
use std::sync::Arc;
|
||||
use std::collections::HashMap;
|
||||
use vek::*;
|
||||
use index::{
|
||||
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
|
||||
}
|
||||
}
|
||||
pub mod area;
|
||||
pub mod data;
|
||||
pub mod delta;
|
||||
pub use data::LodData;
|
||||
pub use data::LodConfig;
|
@ -3,6 +3,9 @@ use crate::lodstore::{
|
||||
LodConfig,
|
||||
index::LodIndex,
|
||||
index::AbsIndex,
|
||||
area::LodArea,
|
||||
delta::LodDelta,
|
||||
delta::DefaultLodDelta,
|
||||
};
|
||||
use vek::*;
|
||||
use std::u32;
|
||||
@ -73,6 +76,9 @@ impl LodConfig for ExampleLodConfig {
|
||||
type I14 = ();
|
||||
type I15 = ();
|
||||
|
||||
type Delta = DefaultLodDelta<Self>;
|
||||
type Additional = ();
|
||||
|
||||
const anchor_layer_id: u8 = 13;
|
||||
|
||||
// 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: 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},
|
||||
];
|
||||
@ -113,31 +119,11 @@ impl LodConfig for ExampleLodConfig {
|
||||
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 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 {
|
||||
0 => {
|
||||
panic!("cannot drill down further");
|
||||
@ -148,6 +134,12 @@ impl LodConfig for ExampleLodConfig {
|
||||
data.layer0.reserve(Self::layer_len[0]);
|
||||
data.child4[abs.index] = insert as u32;
|
||||
//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] {
|
||||
data.layer0.push(Example_4{
|
||||
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 {
|
||||
0 => {
|
||||
panic!("SubBlocks_4 does not have children");
|
||||
@ -215,6 +207,9 @@ impl LodConfig for ExampleLodConfig {
|
||||
}
|
||||
}
|
||||
|
||||
//DELTA
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
@ -272,17 +267,20 @@ mod tests {
|
||||
while result.layer9.len() < act5 as usize {
|
||||
let index = randIndex(&mut rng);
|
||||
let low = index.align_to_layer_id(9);
|
||||
result.make_at_least(low,low,9);
|
||||
let area = LodArea::new(low, low);
|
||||
result.make_at_least(area,9);
|
||||
}
|
||||
while result.layer4.len() < act0 as usize {
|
||||
let index = randIndex(&mut rng);
|
||||
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 {
|
||||
let index = randIndex(&mut rng);
|
||||
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);
|
||||
@ -301,7 +299,8 @@ mod tests {
|
||||
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(16384, 16384, 16384));
|
||||
reg.make_at_least(low,high,4);
|
||||
let area = LodArea::new(low, high);
|
||||
reg.make_at_least(area, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -309,7 +308,8 @@ mod tests {
|
||||
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);
|
||||
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(1, 0, 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 low = LodIndex::new(Vec3::new(8704, 8704, 8704));
|
||||
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(9000, 9000, 9000)));
|
||||
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 low = LodIndex::new(Vec3::new(8704, 8704, 8704));
|
||||
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)));
|
||||
}
|
||||
|
||||
@ -352,7 +354,8 @@ mod tests {
|
||||
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);
|
||||
let area = LodArea::new(low, high);
|
||||
reg.make_at_least(area,0);
|
||||
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 low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
||||
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]
|
||||
@ -370,7 +374,8 @@ mod tests {
|
||||
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);
|
||||
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(16, 16, 16))); // out of range
|
||||
}
|
||||
@ -393,7 +398,8 @@ mod tests {
|
||||
let high = LodIndex::new(Vec3::new(255, 255, 255));
|
||||
b.iter(|| {
|
||||
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));
|
||||
b.iter(|| {
|
||||
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));
|
||||
b.iter(|| {
|
||||
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 low = LodIndex::new(Vec3::new(8192, 8192, 8192));
|
||||
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));
|
||||
}
|
||||
|
||||
@ -434,7 +443,8 @@ mod tests {
|
||||
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);
|
||||
let area = LodArea::new(low, high);
|
||||
reg.make_at_least(area, 0);
|
||||
b.iter(|| {
|
||||
reg.get0(LodIndex::new(Vec3::new(8561, 8312, 8412)));
|
||||
reg.get0(LodIndex::new(Vec3::new(8200, 8599, 8413)));
|
||||
@ -466,7 +476,8 @@ mod tests {
|
||||
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);
|
||||
let area = LodArea::new(low, high);
|
||||
reg.make_at_least(area, 0);
|
||||
b.iter(|| {
|
||||
for i in 0..1000000 {
|
||||
reg.get0(accesslist[i]);
|
||||
@ -487,7 +498,8 @@ mod tests {
|
||||
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);
|
||||
let area = LodArea::new(low, high);
|
||||
reg.make_at_least(area, 0);
|
||||
b.iter(|| {
|
||||
for i in 0..9990000 {
|
||||
reg.get0(accesslist[i]);
|
||||
@ -501,8 +513,11 @@ mod tests {
|
||||
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);
|
||||
let area = LodArea::new(low, high);
|
||||
reg.make_at_least(area, 4);
|
||||
|
||||
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,
|
||||
index::LodIndex,
|
||||
index::AbsIndex,
|
||||
delta::LodDelta,
|
||||
delta::DefaultLodDelta,
|
||||
};
|
||||
use vek::*;
|
||||
use std::u32;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Region9 {
|
||||
@ -70,6 +73,9 @@ impl LodConfig for TerrainLodConfig {
|
||||
type I14 = ();
|
||||
type I15 = ();
|
||||
|
||||
type Delta = DefaultLodDelta<Self>;
|
||||
type Additional = ();
|
||||
|
||||
const anchor_layer_id: u8 = 13;
|
||||
|
||||
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: 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},
|
||||
];
|
||||
@ -108,72 +114,64 @@ impl LodConfig for TerrainLodConfig {
|
||||
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 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 {
|
||||
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[i+insert] = SubBlock_4{
|
||||
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[i+insert] = Block0{
|
||||
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.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,
|
||||
};
|
||||
//ERROR HERE
|
||||
unreachable!("finish this like in example");
|
||||
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) {
|
||||
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 => {
|
||||
|
@ -7,7 +7,6 @@ use std::sync::{
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
use std::collections::HashMap;
|
||||
use vek::*;
|
||||
|
||||
use crate::{
|
||||
job::JobManager,
|
||||
|
Loading…
Reference in New Issue
Block a user