summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs128
1 files changed, 64 insertions, 64 deletions
diff --git a/src/main.rs b/src/main.rs
index 065fa0d..7f13114 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,14 +1,25 @@
+pub mod spatial;
+
use anyhow::Result;
use glam::DVec3;
use indicatif::ProgressIterator;
use log::{debug, info};
use osm_pbf_reader::{Blobs, data::primitives::Primitive};
use rayon::iter::{ParallelBridge, ParallelIterator};
-use std::{collections::HashMap, env::args, f64::consts::PI};
+use spatial::{SpatialTree, octtree::Octtree};
+use std::{collections::BTreeMap, env::args, f64::consts::PI, fs::File, io::BufWriter};
+use weareshared::{
+ helper::AABB,
+ packets::Resource,
+ resources::{Prefab, RespackEntry, SpatialIndex},
+ respack::save_full_respack,
+ store::ResourceStore,
+};
fn main() -> Result<()> {
env_logger::init_from_env("LOG");
let inpath = args().nth(1).unwrap();
+ let outpath = args().nth(2).unwrap();
let node_positions = Blobs::from_path(&inpath)?
.progress_count(1_500)
@@ -22,20 +33,20 @@ fn main() -> Result<()> {
let lat = n.nano_lat as f64 / 1_000_000_000. / 180. * PI;
let lon = n.nano_lon as f64 / 1_000_000_000. / 180. * PI;
let pos = DVec3::new(lat.sin() * lon.cos(), lon.sin(), lat.cos() * lon.cos());
- npos.push((n.id, pos));
+ npos.push((map_nodeid(n.id), pos));
};
}
npos
})
.fold(
- || HashMap::new(),
+ || BTreeMap::new(),
|mut a, b| {
a.extend(b);
a
},
)
.reduce(
- || HashMap::new(),
+ || BTreeMap::new(),
|mut a, b| {
if !a.is_empty() && !b.is_empty() {
debug!("merge positions {} + {}", a.len(), b.len());
@@ -45,78 +56,67 @@ fn main() -> Result<()> {
},
);
- let mut tree = MTree::default();
- info!("Building M-Tree over node positions...");
+ let mut tree = Octtree::new(DVec3::splat(1.5));
+ info!("Building tree over node positions...");
for (id, pos) in node_positions.into_iter().progress() {
tree.insert(pos, id);
}
info!("Done, depth={}", tree.depth());
- // Blobs::from_path(&inpath)?
- // .progress_count(1_500)
- // .par_bridge()
- // .map(|e| {
- // let mut e = e.unwrap();
- // let e = e.decode().unwrap();
- // for p in e.primitives() {
- // if let Primitive::Node(n) = p {
- // }
- // }
- // })
- // .for_each(|_| ());
+ let store = ResourceStore::new_memory();
+ let (_, root) = export_level(&tree, &store)?;
+ let entry = Some(store.set(&RespackEntry {
+ c_spatial_index: vec![root],
+ ..Default::default()
+ })?);
+ let output = BufWriter::new(File::create(outpath)?);
+ save_full_respack(output, &store, entry)?;
Ok(())
}
-type NodeID = i64;
+fn export_level(node: &Octtree, store: &ResourceStore) -> Result<(AABB, Resource<SpatialIndex>)> {
+ let child = node
+ .children
+ .iter()
+ .flat_map(|e| e.as_slice())
+ .flatten()
+ .flatten()
+ .map(|o| export_level(o, store))
+ .collect::<Result<Vec<_>>>()?;
+
+ let prefab = if node.elems.is_empty() {
+ None
+ } else {
+ Some(store.set(&Prefab {
+ ..Default::default()
+ })?)
+ };
-struct MTree {
- center: DVec3,
- radius: f64,
- nodes: Vec<(DVec3, NodeID)>,
- children: Vec<MTree>,
+ Ok((
+ AABB {
+ min: (node.center - node.size / 2.).as_vec3(),
+ max: (node.center + node.size / 2.).as_vec3(),
+ },
+ store.set(&SpatialIndex {
+ level: None,
+ prefab,
+ child,
+ })?,
+ ))
}
-impl Default for MTree {
- fn default() -> Self {
- Self {
- center: DVec3::ZERO,
- radius: 0.,
- nodes: Vec::new(),
- children: Vec::new(),
- }
- }
+
+type NodeID = u64;
+
+fn map_nodeid(id: i64) -> u64 {
+ // xorshift(xorshift(xorshift(id as u64)))
+ id as u64
}
-impl MTree {
- pub fn insert(&mut self, pos: DVec3, id: NodeID) {
- if self.children.is_empty() {
- self.nodes.push((pos, id));
- if self.nodes.len() > 16 {
- for (pos, id) in self.nodes.drain(..) {
- self.children.push(MTree {
- center: pos,
- radius: 0.,
- nodes: vec![(pos, id)],
- children: Vec::new(),
- });
- }
- }
- } else {
- let mut min_dist = f64::MAX;
- let mut min_index = 0;
- for (i, c) in self.children.iter().enumerate() {
- let d = c.center.distance_squared(pos);
- if d < min_dist {
- min_index = i;
- min_dist = d;
- }
- }
- self.radius = self.radius.max(min_dist.sqrt());
- self.children[min_index].insert(pos, id);
- }
- }
- pub fn depth(&self) -> usize {
- self.children.iter().map(|c| c.depth()).max().unwrap_or(0) + 1
- }
+fn xorshift(mut x: u64) -> u64 {
+ x ^= x << 13;
+ x ^= x >> 7;
+ x ^= x << 17;
+ x
}
enum Elem {