32 int32_t leaf = alloc_node();
42 remove_leaf(node_idx);
54 remove_leaf(node_idx);
57 insert_leaf(node_idx);
62 void query_pairs(std::vector<std::pair<int32_t, int32_t>>& out)
const {
64 if (m_root < 0)
return;
65 collect_pairs(m_root, m_root, out,
true);
73 bool empty()
const {
return m_root < 0; }
82 mutable std::vector<SiblingEntry> m_sibling_stack;
84 std::vector<FxAABBTreeNode> m_nodes;
86 int32_t m_free_head = -1;
89 int32_t alloc_node() {
90 if (m_free_head >= 0) {
91 int32_t idx = m_free_head;
96 m_nodes.emplace_back();
97 return static_cast<int32_t
>(m_nodes.size() - 1);
100 void free_node(int32_t idx) {
111 float mx = std::max(w * AABB_TREE_MARGIN, 0.01f);
112 float my = std::max(h * AABB_TREE_MARGIN, 0.01f);
117 void insert_leaf(int32_t leaf) {
124 int32_t best = find_best_sibling(leaf);
127 int32_t np = alloc_node();
148 int32_t find_best_sibling(int32_t leaf)
const {
150 float best_cost = std::numeric_limits<float>::max();
151 int32_t best = m_root;
155 m_sibling_stack.clear();
156 m_sibling_stack.push_back({m_root, 0.0f});
158 while (!m_sibling_stack.empty()) {
159 auto [idx, inh] = m_sibling_stack.back();
160 m_sibling_stack.pop_back();
164 float total = direct + inh;
166 if (total < best_cost) {
171 if (!
node(idx).is_leaf()) {
173 float lower_bound = la.
perimeter() + child_inh;
174 if (lower_bound < best_cost) {
175 m_sibling_stack.push_back({
node(idx).
left, child_inh});
176 m_sibling_stack.push_back({
node(idx).
right, child_inh});
184 void remove_leaf(int32_t leaf) {
185 if (m_root == leaf) {
195 if (
node(grandpa).left == parent)
node(grandpa).
left = sibling;
210 void refit_from(int32_t idx) {
214 if (l >= 0 && r >= 0)
222 void collect_pairs(int32_t a, int32_t b, std::vector<std::pair<int32_t, int32_t>>& out,
223 bool same_node)
const {
224 if (a < 0 || b < 0)
return;
230 collect_pairs(na.
left, na.
left, out,
true);
231 collect_pairs(na.
left, na.
right, out,
false);
238 if (x > y) std::swap(x, y);
239 out.emplace_back(x, y);
246 collect_pairs(na.
left, b, out,
false);
247 collect_pairs(na.
right, b, out,
false);
249 collect_pairs(a, nb.
left, out,
false);
250 collect_pairs(a, nb.
right, out,
false);