58 lines
1.3 KiB
Odin
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)
|
|
}
|
|
}
|