Crates.io | oktree |
lib.rs | oktree |
version | |
source | src |
created_at | 2024-11-03 23:42:13.33393 |
updated_at | 2024-12-04 00:48:15.293715 |
description | Fast octree implementation. |
homepage | |
repository | https://github.com/exor2008/oktree |
max_upload_size | |
id | 1434379 |
Cargo.toml error: | TOML parse error at line 17, column 1 | 17 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
Fast octree implementation.
Able to operate with Position
or Volume
data.
Could be used with the Bevy game engine or as a standalone tree.
To enable bevy integrations:
[dependencies]
oktree = { version = "0.4.1", features = ["bevy"] }
Unsigned
arithmetics, bitwise operations.Smallvec
and Heapless
structures are used.Rc
, RefCell
e.t.c)Compensation for the inconvenience is perfomance.
Octree dimensions: 4096x4096x4096
Operation | Quantity | Time |
---|---|---|
insertion | 65536 cells | 21 ms |
removing | 65536 cells | 1.5 ms |
find | 65536 searches in 65536 cells | 12 ms |
ray intersection | 4096 rays against 65536 cells | 37 ms |
sphere intersection | 4096 spheres against 65536 cells | 8 ms |
box intersection | 4096 boxes against 65536 cells | 7 ms |
Run benchmark:
cargo bench --all-features
You have to specify the type for the internal tree structure.
It must be any Unsigned
type (u8
, u16
, u32
, u64
, u128
or usize
).
Implement Position
or Volume
for the handled type, so that it can return it's spatial coordinates.
use bevy::math::{
bounding::{Aabb3d, BoundingSphere, RayCast3d},
Dir3, Vec3,
};
use oktree::prelude::*;
fn main() -> Result<(), TreeError> {
let aabb = Aabb::new(TUVec3::splat(16), 16u8);
let mut tree = Octree::from_aabb_with_capacity(aabb?, 10);
let c1 = DummyCell::new(TUVec3::splat(1u8));
let c2 = DummyCell::new(TUVec3::splat(8u8));
let c1_id = tree.insert(c1)?;
let c2_id = tree.insert(c2)?;
// Searching by position
assert_eq!(tree.find(&TUVec3::new(1, 1, 1)), Some(c1_id));
assert_eq!(tree.find(&TUVec3::new(8, 8, 8)), Some(c2_id));
assert_eq!(tree.find(&TUVec3::new(1, 2, 8)), None);
assert_eq!(tree.find(&TUVec3::splat(100)), None);
// Searching for the ray intersection
let ray = RayCast3d::new(Vec3::new(1.5, 7.0, 1.9), Dir3::NEG_Y, 100.0);
// Hit!
assert_eq!(
tree.ray_cast(&ray),
HitResult {
element: Some(ElementId(0)),
distance: 5.0
}
);
assert_eq!(tree.remove(ElementId(0)), Ok(()));
// Miss!
assert_eq!(
tree.ray_cast(&ray),
HitResult {
element: None,
distance: 0.0
}
);
let c1 = DummyCell::new(TUVec3::splat(1u8));
let c1_id = tree.insert(c1)?;
// Aabb intersection
let aabb = Aabb3d::new(Vec3::splat(2.0), Vec3::splat(2.0));
assert_eq!(tree.intersect(&aabb), vec![c1_id]);
// Sphere intersection
let sphere = BoundingSphere::new(Vec3::splat(2.0), 2.0);
assert_eq!(tree.intersect(&sphere), vec![c1_id]);
Ok(())
}
struct DummyCell {
position: TUVec3<u8>,
}
impl Position for DummyCell {
type U = u8;
fn position(&self) -> TUVec3<u8> {
self.position
}
}
impl DummyCell {
fn new(position: TUVec3<u8>) -> Self {
DummyCell { position }
}
}
Run bevy visual example:
cargo run --release --example bevy_tree --all-features
Feature and pull requests are welcomed.
tests
cargo test --all-targets --all-features --release
clippy
cargo clippy --all-targets --all-features
examples
cargo run --all-features --example simple
cargo run --all-features --example bevy_tree
benchmark
cargo bench --all-features
docs
cargo doc --no-deps --open --all-features