1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
//! # LodTree
//! LodTree, a simple tree data structure for doing chunk-based level of detail
//!
//! ### Goals
//! The aim of this crate is to provide a generic, easy to use tree data structure that can be used to make Lod Quadtrees, Octrees and more.
//!
//! Internally, the tree tries to keep as much memory allocated, to avoid the cost of heap allocation, and stores the actual chunks data seperate from the tree data.
//!
//! This does come at a cost, mainly, only the chunks that are going to be added and their locations can be retreived as a slice, although for most (procedural) terrain implementations
//! making new chunks and editing them will be the highest cost to do, so that shouldn't be the biggest issue.
//!
//! ### Usage:
//! Import the crate
//! ```rust
//! use lodtree::*;
//! use lodtree::coords::OctVec; // or QuadVec if you're making an octree
//! ```
//!
//! The tree is it's own struct, and accepts a chunk (anything that implements Sized) and the lod vector (Anything that implements the LodVec trait).
//! ```rust
//! # use lodtree::*;
//! # use lodtree::coords::OctVec;
//! # struct Chunk {}
//! let mut tree = Tree::<Chunk, OctVec>::new();
//! ```
//!
//! If you want to update chunks due to the camera being moved, you can check if it's needed with prepare_update.
//! It takes in 3 parameters.
//!
//! Targets: where to generate the most detail around.
//!
//! The given LodVec implementations (OctVec and QuadVec) take in 4 and 3 arguments respectively.
//! The first 3/2 are the position in the tree, which is dependant on the lod level.
//! and the last parameter is the lod level. No lods smaller than this will be generated for this target.
//!
//! Detail: The amount of detail for the targets.
//! The default implementation defines this as the amount of chunks at the target lod level surrounding the target chunk.
//!
//! Chunk creator:
//! Internally a buffer for new chunks is filled, and this function is called to create the new chunk.
//! It takes in the LodVec of the position of the chunk.
//! ```rust
//! # use lodtree::*;
//! # use lodtree::coords::OctVec;
//! # struct Chunk {}
//! # let mut tree = Tree::<Chunk, OctVec>::new();
//! let needs_updating = tree.prepare_update(
//! &[OctVec::new(8, 8, 8, 8)], // the target positions to generate the lod around
//! 4, // amount of detail
//! |pos| Chunk {} // and the function to construct the chunk with
//! );
//! ```
//!
//! Now, the tree is ready for an update, so now we'll want to do something with that.
//! First, we want to process all chunks that are going to be added.
//! This is the only thing the API exposes as a slice, so we can nicely iterate over that in parallel with rayon.
//! ```rust
//! # use lodtree::*;
//! # use lodtree::coords::QuadVec;
//! # struct Chunk {}
//! # impl Chunk {
//! # fn expensive_init(&mut self, pos: QuadVec) {}
//! # }
//! # let mut tree = Tree::<Chunk, QuadVec>::new();
//! tree.get_chunks_to_add_slice_mut()
//! .iter_mut() // or par_iter_mut() if you're using rayon
//! .for_each(|(position, chunk)| {
//!
//! // and run expensive init, probably does something with procedural generation
//! chunk.expensive_init(*position);
//! });
//! ```
//!
//! Next, we'll also want to change the visibility of some chunks so they don't overlap with higher detail lods.
//! ```rust
//! # use lodtree::*;
//! # use lodtree::coords::QuadVec;
//! # struct Chunk {}
//! # impl Chunk {
//! # fn set_visible(&mut self, v: bool) {}
//! # }
//! # let mut tree = Tree::<Chunk, QuadVec>::new();
//! // and make all chunks visible or not
//! for i in 0..tree.get_num_chunks_to_activate() {
//! tree.get_chunk_to_activate_mut(i).set_visible(true);
//! }
//!
//! for i in 0..tree.get_num_chunks_to_deactivate() {
//! tree.get_chunk_to_deactivate_mut(i).set_visible(false);
//! }
//! ```
//! We'll probably also want to do some cleanup with chunks that are removed.
//! ```rust
//! # use lodtree::*;
//! # use lodtree::coords::QuadVec;
//! # struct Chunk {}
//! # impl Chunk {
//! # fn cleanup(&mut self) {}
//! # }
//! # let mut tree = Tree::<Chunk, QuadVec>::new();
//! for i in 0..tree.get_num_chunks_to_remove() {
//! tree.get_chunk_to_remove_mut(i).cleanup();
//! }
//! ```
//! And finally, actually update the tree with the new chunks.
//! Note that it's likely needed to do the prepare_update and do_update cycle a number of times before no new chunks need to be added, as the tree only adds one lod level at a time.
//! ```rust
//! # use lodtree::*;
//! # use lodtree::coords::QuadVec;
//! # struct Chunk {}
//! # let mut tree = Tree::<Chunk, QuadVec>::new();
//! tree.do_update();
//! ```
pub mod coords;
pub mod traits;
pub mod tree;
pub use crate::traits::*;
pub use crate::tree::*;