FUNCTIONAL OCTTREES POGGORZ

This commit is contained in:
Lillian Vixe 2024-02-23 14:35:39 -08:00
parent 3ddfe54b97
commit 2a7c1f11c8
5 changed files with 516 additions and 111 deletions

202
Cargo.lock generated
View file

@ -88,9 +88,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
version = "0.8.7"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
checksum = "d713b3834d76b85304d4d525563c1276e2e30dc97cc67bfb4585a4a29fc2c89f"
dependencies = [
"cfg-if",
"getrandom",
@ -228,13 +228,13 @@ dependencies = [
[[package]]
name = "async-channel"
version = "2.1.1"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c"
checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3"
dependencies = [
"concurrent-queue",
"event-listener 4.0.3",
"event-listener-strategy",
"event-listener 5.1.0",
"event-listener-strategy 0.5.0",
"futures-core",
"pin-project-lite",
]
@ -281,7 +281,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b"
dependencies = [
"event-listener 4.0.3",
"event-listener-strategy",
"event-listener-strategy 0.4.0",
"pin-project-lite",
]
@ -427,7 +427,7 @@ dependencies = [
"bevy_macro_utils",
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
]
[[package]]
@ -493,7 +493,7 @@ checksum = "f484318350462c58ba3942a45a656c1fd6b6e484a6b6b7abc3a787ad1a51e500"
dependencies = [
"bevy_macro_utils",
"quote",
"syn 2.0.48",
"syn 2.0.50",
]
[[package]]
@ -541,7 +541,7 @@ dependencies = [
"bevy_macro_utils",
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
]
[[package]]
@ -713,7 +713,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustc-hash",
"syn 2.0.48",
"syn 2.0.50",
"toml_edit 0.20.7",
]
@ -796,7 +796,7 @@ dependencies = [
"bevy_macro_utils",
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
"uuid",
]
@ -855,7 +855,7 @@ dependencies = [
"bevy_macro_utils",
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
]
[[package]]
@ -1025,7 +1025,7 @@ checksum = "7aafecc952b6b8eb1a93c12590bd867d25df2f4ae1033a01dfdfc3c35ebccfff"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
]
[[package]]
@ -1086,7 +1086,7 @@ dependencies = [
"regex",
"rustc-hash",
"shlex",
"syn 2.0.48",
"syn 2.0.50",
]
[[package]]
@ -1163,7 +1163,7 @@ version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118"
dependencies = [
"async-channel 2.1.1",
"async-channel 2.2.0",
"async-lock 3.3.0",
"async-task",
"fastrand 2.0.1",
@ -1175,15 +1175,15 @@ dependencies = [
[[package]]
name = "bumpalo"
version = "3.14.0"
version = "3.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
checksum = "c764d619ca78fccbf3069b37bd7af92577f044bb15236036662d79b6559f25b7"
[[package]]
name = "bytemuck"
version = "1.14.2"
version = "1.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea31d69bda4949c1c1562c1e6f042a1caefac98cdc8a298260a2ff41c1e2d42b"
checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f"
dependencies = [
"bytemuck_derive",
]
@ -1196,7 +1196,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
]
[[package]]
@ -1213,11 +1213,10 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
[[package]]
name = "cc"
version = "1.0.83"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
checksum = "7f9fa1897e4325be0d68d48df6aa1a71ac2ed4d27723887e7754192705350730"
dependencies = [
"jobserver",
"libc",
]
@ -1424,9 +1423,9 @@ dependencies = [
[[package]]
name = "crc32fast"
version = "1.3.2"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
dependencies = [
"cfg-if",
]
@ -1483,9 +1482,9 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
[[package]]
name = "either"
version = "1.9.0"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
[[package]]
name = "encase"
@ -1516,7 +1515,7 @@ checksum = "3fe2568f851fd6144a45fa91cfed8fe5ca8fc0b56ba6797bfc1ed2771b90e37c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
]
[[package]]
@ -1560,6 +1559,17 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "event-listener"
version = "5.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7ad6fd685ce13acd6d9541a30f6db6567a7a24c9ffd4ba2955d29e3f22c8b27"
dependencies = [
"concurrent-queue",
"parking",
"pin-project-lite",
]
[[package]]
name = "event-listener-strategy"
version = "0.4.0"
@ -1570,6 +1580,16 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "event-listener-strategy"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291"
dependencies = [
"event-listener 5.1.0",
"pin-project-lite",
]
[[package]]
name = "fastrand"
version = "1.9.0"
@ -1643,7 +1663,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
]
[[package]]
@ -1800,7 +1820,7 @@ dependencies = [
"inflections",
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
]
[[package]]
@ -1967,9 +1987,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "2.2.2"
version = "2.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520"
checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177"
dependencies = [
"equivalent",
"hashbrown 0.14.3",
@ -2072,15 +2092,6 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
name = "jobserver"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d"
dependencies = [
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.68"
@ -2458,7 +2469,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
]
[[package]]
@ -2625,7 +2636,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9"
dependencies = [
"fixedbitset",
"indexmap 2.2.2",
"indexmap 2.2.3",
]
[[package]]
@ -2647,15 +2658,15 @@ dependencies = [
[[package]]
name = "pkg-config"
version = "0.3.29"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "png"
version = "0.17.11"
version = "0.17.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f6c3c3e617595665b8ea2ff95a86066be38fb121ff920a9c0eb282abcd1da5a"
checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1"
dependencies = [
"bitflags 1.3.2",
"crc32fast",
@ -2673,6 +2684,12 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro-crate"
version = "1.3.1"
@ -2694,9 +2711,9 @@ dependencies = [
[[package]]
name = "profiling"
version = "1.0.14"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f0f7f43585c34e4fdd7497d746bc32e14458cf11c69341cc0587b1d825dde42"
checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58"
[[package]]
name = "quote"
@ -2713,6 +2730,36 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17fd96390ed3feda12e1dfe2645ed587e0bea749e319333f104a33ff62f77a0b"
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "range-alloc"
version = "0.1.3"
@ -2852,9 +2899,9 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.16"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
[[package]]
name = "same-file"
@ -2873,29 +2920,29 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
version = "1.0.196"
version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.196"
version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
]
[[package]]
name = "serde_json"
version = "1.0.113"
version = "1.0.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79"
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
dependencies = [
"itoa",
"ryu",
@ -2994,9 +3041,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.48"
version = "2.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb"
dependencies = [
"proc-macro2",
"quote",
@ -3040,9 +3087,9 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.56"
version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
dependencies = [
"thiserror-impl",
]
@ -3064,25 +3111,25 @@ checksum = "e4c60d69f36615a077cc7663b9cb8e42275722d23e58a7fa3d2c7f2915d09d04"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
]
[[package]]
name = "thiserror-impl"
version = "1.0.56"
version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
]
[[package]]
name = "thread_local"
version = "1.1.7"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
dependencies = [
"cfg-if",
"once_cell",
@ -3115,7 +3162,7 @@ version = "0.19.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [
"indexmap 2.2.2",
"indexmap 2.2.3",
"toml_datetime",
"winnow",
]
@ -3126,7 +3173,7 @@ version = "0.20.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81"
dependencies = [
"indexmap 2.2.2",
"indexmap 2.2.3",
"toml_datetime",
"winnow",
]
@ -3150,7 +3197,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
]
[[package]]
@ -3281,6 +3328,7 @@ name = "vvu"
version = "0.1.0"
dependencies = [
"bevy",
"rand",
]
[[package]]
@ -3326,7 +3374,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
"wasm-bindgen-shared",
]
@ -3360,7 +3408,7 @@ checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -3819,9 +3867,9 @@ dependencies = [
[[package]]
name = "winnow"
version = "0.5.39"
version = "0.5.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5389a154b01683d28c77f8f68f49dea75f0a4da32557a58f68ee51ebba472d29"
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
dependencies = [
"memchr",
]
@ -3866,5 +3914,5 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
"syn 2.0.50",
]

View file

@ -7,3 +7,4 @@ edition = "2021"
[dependencies]
bevy = "0.12"
rand = "0.8.5"

View file

@ -2,6 +2,7 @@ use bevy::app::*;
use bevy::prelude::*;
use bevy::window::WindowResolution;
use bevy::DefaultPlugins;
pub mod oct_tree;
mod orbit_camera;
mod vvum;
use vvum::mesh_plugin;

350
src/oct_tree.rs Normal file
View file

@ -0,0 +1,350 @@
use bevy::math::Vec3;
use crate::oct_tree::constants::to_region_id;
use self::constants::{parent_region, sub_region};
use std::mem::swap;
#[derive(Clone, Default, Debug)]
enum TreeNode<T> {
Branch(Box<[TreeNode<T>; 8]>),
Leaf(T),
#[default]
None,
}
#[derive(Debug)]
struct OctTree<T> {
size: usize,
center: Vec3,
root: TreeNode<T>,
}
impl<T: Clone> OctTree<T> {
pub fn new(npos: Vec3, value: T) -> Self {
Self {
size: 1,
center: npos,
root: TreeNode::Leaf(value),
}
}
pub fn set_voxel(&mut self, location: Vec3, value: T) {
// if the tree is empty, we want to fall out immediately - no looping needed.
match self.root {
TreeNode::None => {
self.center = location;
self.size = 1;
self.root = TreeNode::Leaf(value);
return;
}
_ => {} // continue to modify the tree structure - no easy answer yet
}
// if we don't already have a big enough non-empty tree, we need to branch upward till our tree contains our subject matter
if !bounds_contains(self.center, self.size, location) {
println!("building up to contain addition {location}");
let search_direction = constants::to_region_id(self.center, location);
while !bounds_contains(self.center, self.size, location) {
println!(
"{0}, size {1}, region {search_direction}",
self.center, self.size
);
match &self.root {
TreeNode::Branch(_) | TreeNode::Leaf(_) => {
let mut branch_extension: [TreeNode<T>; 8] = Default::default();
let (extension_center, extension_size) =
constants::parent_region(self.center, self.size, search_direction);
let slot_within_new_branch =
constants::to_region_id(extension_center, self.center);
let mut old: TreeNode<T> = TreeNode::None;
swap(&mut self.root, &mut old);
branch_extension[slot_within_new_branch as usize] = old;
self.root = TreeNode::Branch(Box::new(branch_extension));
self.center = extension_center;
self.size = extension_size;
println!("{slot_within_new_branch} housing previous root");
match &self.root {
TreeNode::Branch(_) => {
println!("root is a branch");
}
TreeNode::Leaf(_) => todo!(),
TreeNode::None => todo!(),
}
}
TreeNode::None => {
println!("something went wrong with early fall-out. shouldn't be plausible unless you're using unsafe rust.");
return;
}
}
}
println!(
"{0}, size {1}, region {search_direction}",
self.center, self.size
);
}
// custom loop down: discover next position downward
let mut rc_center = self.center;
let mut rc_size = self.size;
let mut search_direction = constants::to_region_id(rc_center, location);
let mut rc_loc = &mut self.root;
println!("searching down to set {location}");
while rc_size > 0 {
println!("{rc_center}, size {rc_size}, region {search_direction}");
match rc_loc {
TreeNode::Branch(region) => {
let region = region.as_mut();
let next_rc_loc = &mut region[search_direction as usize];
(rc_center, rc_size) = sub_region(rc_center, rc_size, search_direction);
search_direction = constants::to_region_id(rc_center, location);
if rc_size == 1 {
println!(
"value set {location} within {rc_center}, {rc_size}, index {search_direction}"
);
let end = TreeNode::Leaf(value.clone());
*next_rc_loc = end;
return;
}
match next_rc_loc {
TreeNode::Branch(_) => {}
TreeNode::Leaf(lvalue) => {
if rc_size != 1 {
println!("tree edited to contain non-unit node size. returning instead of losing data");
return;
} else {
println!(
"value set {location} within {rc_center}, {rc_size}, index {search_direction}"
);
*lvalue = value.clone();
}
}
TreeNode::None => {
let branch_extension: [TreeNode<T>; 8] = Default::default();
let next_branch = TreeNode::Branch(Box::new(branch_extension));
*next_rc_loc = next_branch;
}
}
rc_loc = next_rc_loc;
}
TreeNode::Leaf(lvalue) => {
if rc_size == 1 {
println!(
"value set {location} within {rc_center}, {rc_size}, index {search_direction}"
);
*lvalue = value;
return;
} else {
println!("tree edited to contain non-unit node size. returning instead of losing data");
return;
}
}
TreeNode::None => {
println!(
"should be handled automatically before arrival at target node. returning"
);
return;
}
}
}
}
pub fn voxel_at(&self, location: Vec3) -> Option<T> {
if bounds_contains(self.center, self.size, location) {
let mut rc_center = self.center;
let mut rc_size = self.size;
let mut search_direction = constants::to_region_id(rc_center, location);
println!("searching for {location}");
let mut rc_loc = &self.root;
while rc_size > 1 {
println!("{rc_center}, size {rc_size}, region {search_direction}");
match rc_loc {
TreeNode::Branch(branch) => {
if search_direction == -1 {
panic!("search direction gone wrong");
}
rc_loc = &branch[search_direction as usize];
(rc_center, rc_size) = sub_region(rc_center, rc_size, search_direction);
search_direction = to_region_id(rc_center, location);
}
TreeNode::Leaf(_) => {
panic!("tree not constructed correctly - non-unit voxel size");
}
TreeNode::None => {
println!("doesn't seem to exist");
return None; // does not exist.
}
}
}
match rc_loc {
TreeNode::Leaf(value) => {
println!("found at {rc_center}, {rc_size}");
return Some(value.clone());
}
_ => {
println!("Couldn't find it..");
return None;
}
}
}
None
}
}
pub fn bounds_contains(center: Vec3, size: usize, subject: Vec3) -> bool {
let fsize = size as f32;
let min = center - Vec3::splat(fsize as f32 / 2.);
let max = center + Vec3::splat(fsize as f32 / 2.);
return min.x <= subject.x
&& subject.x <= max.x
&& min.y <= subject.y
&& subject.y <= max.y
&& min.z <= subject.z
&& subject.z <= max.z;
}
mod constants {
use bevy::math::Vec3;
pub fn to_region_id(center: Vec3, subject: Vec3) -> i32 {
if subject.x == center.x && subject.y == center.y && subject.z == center.z {
return -1;
}
let mut result: i32 = 0;
if subject.x >= center.x {
result += 4;
}
if subject.y >= center.y {
result += 2;
}
if subject.z >= center.z {
result += 1;
}
return result;
}
pub fn to_index(vec: Vec3) -> i32 {
let mut index = 0;
for i in quadrant_offsets::ordered {
if i == vec {
return index;
}
index += 1;
}
return -1;
}
pub fn from_index(index: i32) -> Vec3 {
if index < 0 || index >= 8 {
return Vec3::ZERO;
}
return quadrant_offsets::ordered[index as usize];
}
pub fn sub_region(position: Vec3, size: usize, subject: i32) -> (Vec3, usize) {
let size = size as f32;
let new_size = size / 2.;
let new_half_size = size / 4.;
let subvec = from_index(subject);
let offset = Vec3 {
x: subvec.x * new_half_size,
y: subvec.y * new_half_size,
z: subvec.z * new_half_size,
};
let newcenter = position + offset;
(newcenter, new_size as usize)
}
pub fn parent_region(position: Vec3, size: usize, subject: i32) -> (Vec3, usize) {
let size = size as f32;
let new_size = size * 2.;
let half_size = size / 2.;
let mut subvec = from_index(subject);
//subvec *= -1.;
let offset = Vec3 {
x: subvec.x * half_size,
y: subvec.y * half_size,
z: subvec.z * half_size,
};
let newcenter = position + offset;
(newcenter, new_size as usize)
}
mod quadrant_indices {
pub const NNN: i32 = 0;
pub const NNP: i32 = 1;
pub const NPN: i32 = 2;
pub const NPP: i32 = 3;
pub const PNN: i32 = 4;
pub const PNP: i32 = 5;
pub const PPN: i32 = 6;
pub const PPP: i32 = 7;
}
mod quadrant_offsets {
use bevy::math::Vec3;
pub const NNN: Vec3 = Vec3::new(-1., -1., -1.);
pub const NNP: Vec3 = Vec3::new(-1., -1., 1.);
pub const NPN: Vec3 = Vec3::new(-1., 1., -1.);
pub const NPP: Vec3 = Vec3::new(-1., 1., 1.);
pub const PNN: Vec3 = Vec3::new(1., -1., -1.);
pub const PNP: Vec3 = Vec3::new(1., -1., 1.);
pub const PPN: Vec3 = Vec3::new(1., 1., -1.);
pub const PPP: Vec3 = Vec3::new(1., 1., 1.);
pub const ordered: [Vec3; 8] = [NNN, NNP, NPN, NPP, PNN, PNP, PPN, PPP];
}
mod cardinal_directions {
use bevy::math::Vec3;
pub const PX: Vec3 = Vec3::X;
pub const NX: Vec3 = Vec3::NEG_X;
pub const PY: Vec3 = Vec3::Y;
pub const NY: Vec3 = Vec3::NEG_Y;
pub const PZ: Vec3 = Vec3::Z;
pub const NZ: Vec3 = Vec3::NEG_Z;
}
}
#[test]
pub fn test_octtree() {
let origin = Vec3::ZERO;
let neighbor = Vec3::new(1., 1., 1.);
let mut test_oct = OctTree::<i32>::new(origin, 1);
test_oct.set_voxel(neighbor, 2);
let far_off_bullshit = Vec3::new(26., 26., 26.);
test_oct.set_voxel(far_off_bullshit, 5);
dbg!(&test_oct);
assert_eq!(test_oct.voxel_at(neighbor), Some(2));
assert_eq!(test_oct.voxel_at(origin), Some(1));
assert_eq!(test_oct.voxel_at(far_off_bullshit), Some(5));
}
/*
use rand::Rng;
#[test]
pub fn fuzz_test_octtree() {
let mut list_to_test: Vec<(Vec3, i32)> = Vec::new();
let mut rng = rand::thread_rng();
for i in 0..256 {
list_to_test.push((
Vec3::new(
(rng.gen::<f32>() * 2000.).round(),
(rng.gen::<f32>() * 2000.).round(),
(rng.gen::<f32>() * 2000.).round(),
),
i,
));
}
let mut test_octtree = OctTree::<i32>::new(list_to_test[0].0, list_to_test[0].1);
for i in 1..256 {
test_octtree.set_voxel(list_to_test[i].0, list_to_test[i].1);
}
let x = format!("{test_octtree:#?}");
std::fs::write("./output.txt", x.as_bytes()).expect("Unable to write file");
for i in 0..256 {
assert_eq!(
test_octtree.voxel_at(list_to_test[i].0),
Some(list_to_test[i].1)
);
}
panic!("show me the data dickhead");
}
*/

View file

@ -10,13 +10,16 @@ pub mod mesh_plugin {
use crate::orbit_camera::orbit_camera::*;
#[derive(Event)]
pub struct SendMeshEvent {}
pub struct SendMeshEvent {
location: Vec3,
}
pub struct PluginInitializer;
impl Plugin for PluginInitializer {
fn build(&self, app: &mut App) {
app.add_systems(Startup, setup);
app.add_systems(Update, pan_orbit_camera);
app.add_systems(Update, (pan_orbit_camera, listen_send_mesh_event));
app.add_event::<SendMeshEvent>();
}
}
@ -190,44 +193,46 @@ pub mod mesh_plugin {
mut events: EventReader<SendMeshEvent>,
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut asset_server: ResMut<AssetServer>,
) {
/*
in the send mesh event will be the handle of what we update if it is already present, and the mesh data in an octtree or other voxel format
*/
for ev in events.iter() {
let mut vertices = Vec::new();
let mut normals = Vec::new();
let mut indices = Vec::new();
let mut colors: Vec<[f32; 4]> = Vec::new();
emit_cube_at(
ev.location,
&mut vertices,
&mut indices,
&mut normals,
&mut colors,
Color::RED,
true,
true,
true,
true,
true,
true,
);
let test_mesh_handle: Handle<Mesh> =
meshes.add(as_mesh(vertices, indices, normals, colors));
commands.spawn(PbrBundle {
mesh: test_mesh_handle,
..default()
});
}
}
fn setup(
mut commands: Commands,
asset_server: ResMut<AssetServer>,
mut material: ResMut<Assets<StandardMaterial>>,
mut meshes: ResMut<Assets<Mesh>>,
) {
let mut vertices = Vec::new();
let mut normals = Vec::new();
let mut indices = Vec::new();
let mut colors: Vec<[f32; 4]> = Vec::new();
emit_cube_at(
Vec3::ZERO,
&mut vertices,
&mut indices,
&mut normals,
&mut colors,
Color::RED,
true,
true,
true,
true,
true,
true,
);
let test_mesh_handle: Handle<Mesh> =
meshes.add(as_mesh(vertices, indices, normals, colors));
commands.spawn(PbrBundle {
mesh: test_mesh_handle,
..default()
fn setup(mut ev_sender: EventWriter<SendMeshEvent>, mut commands: Commands) {
ev_sender.send(SendMeshEvent {
location: Vec3::new(0., 0., 0.),
});
ev_sender.send(SendMeshEvent {
location: Vec3::new(1., 0., 0.),
});
let camera_and_light_transform =
Transform::from_xyz(1.8, 1.8, 1.8).looking_at(Vec3::ZERO, Vec3::Y);