Author:ptrace Comitter:ptrace Date:2026-05-02 09:46:55 UTC

some notes

diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..d6eca8a --- /dev/null +++ b/notes.txt @@ -0,0 +1,88 @@ tree_refit :: (tree: *Tree, start_index: int) {     index := start_index;     while index > 0 {         i_left   := 2 * index + 1;         i_right  := 2 * index + 2;         i_parent := cast(int)floor((index - 1.0) / 2.0);         // Refit this node to enclose both children         tree.data[index].bounds = aabb_merge(tree.data[i_left].bounds,                                              tree.data[i_right].bounds);         index = i_parent;     }     // Refit the root (index 0) separately, since the while loop stops before it     i_left  := 1;     i_right := 2;     tree.data[0].bounds = aabb_merge(tree.data[i_left].bounds,                                      tree.data[i_right].bounds); } tree_rotate :: (tree: *Tree, index_b: int) {     // B is the node we're considering rotating at     // Its parent is A, its sibling is C     i_a := cast(int)floor((index_b - 1.0) / 2.0); // parent     i_c := (index_b % 2 == 1) ? index_b + 1 : index_b - 1; // sibling     i_d := 2 * index_b + 1; // B's left child     i_e := 2 * index_b + 2; // B's right child     if i_d >= tree.data.count return; // B is a leaf, nothing to rotate     // Compute cost of current arrangement vs swapping D or E up     cost_current := surface_area(tree.data[i_b]) + surface_area(tree.data[i_c]);     cost_swap_d  := surface_area(merge_bounds(tree.data[i_e], tree.data[i_c])) + surface_area(tree.data[i_d]);     cost_swap_e  := surface_area(merge_bounds(tree.data[i_d], tree.data[i_c])) + surface_area(tree.data[i_e]);     if cost_current <= cost_swap_d && cost_current <= cost_swap_e return; // already optimal     if cost_swap_d < cost_swap_e {         // Swap D and C: just swap their data in the array         tmp := tree.data[i_d];         tree.data[i_d] = tree.data[i_c];         tree.data[i_c] = tmp;         // Refit B since its children changed         tree.data[index_b] = merge_bounds(tree.data[i_d], tree.data[i_e]);     } else {         // Swap E and C         tmp := tree.data[i_e];         tree.data[i_e] = tree.data[i_c];         tree.data[i_c] = tmp;         // Refit B         tree.data[index_b] = merge_bounds(tree.data[i_d], tree.data[i_e]);     }     // A's bounds didn't change since D and C are both still under it } tree_collapse :: (tree: *Tree, parent_index: int) {     i_left  := 2 * parent_index + 1;     i_right := 2 * parent_index + 2;     // Sanity check — only collapse if both children are leaves     // (i.e. their own children slots are empty)     assert(tree_is_leaf(tree, i_left));     assert(tree_is_leaf(tree, i_right));     tree.data[i_left]  = EMPTY_NODE;     tree.data[i_right] = EMPTY_NODE;     // Parent is now a leaf — update its bounding volume or value here } tree_is_leaf :: (tree: Tree, index: int) -> bool {     i_left  := 2 * index + 1;     i_right := 2 * index + 2;     if i_left  >= tree.data.count then return true;     if i_right >= tree.data.count then return true;     return is_empty(tree.data[i_left]) && is_empty(tree.data[i_right]); }