2025-01-03 00:42:38 +04:00

58 lines
1.3 KiB
Odin

package collision
import fl "common:container/freelist"
Octree :: struct {
elements: fl.Free_List(Element),
element_nodes: fl.Free_List(Element_Node),
root: Octree_Node,
nodes: fl.Free_List(Octree_Node_Children),
free_node_plus_one: int,
root_aabb: Aabb,
max_depth: int,
}
// You insert elements
Element :: struct {
id: i32,
aabb: Aabb,
}
// Elements may spawn multiple element nodes
Element_Node :: struct {
next: i32,
element: i32,
}
Octree_Node_Children :: struct {
children: [8]Octree_Node,
}
Octree_Node :: struct {
// Index of children if this node is a branch or first element if this node is a leaf
children_or_first_element: i32,
// Number of elements in a leaf or -1 if not a leaf
len: i32,
}
is_leaf :: proc(node: Octree_Node) -> bool {
return node.len != -1
}
add_element_to_leaf :: #force_inline proc(octree: ^Octree, node: ^Octree_Node, el_index: i32) {
new_elem_node_idx := fl.insert(
&octree.element_nodes,
Element_Node{element = el_index, next = node.children_or_first_element},
)
node.children_or_first_element = i32(new_elem_node_idx)
}
insert :: proc(octree: ^Octree, el: Element) {
el_index := i32(fl.insert(&octree.elements, el))
if is_leaf(octree.root) {
add_element_to_leaf(octree, &octree.root, el_index)
}
}