From c1aac567661d097e91e758e0cd26397dd65c7933 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Thu, 5 Mar 2020 22:13:13 +0100 Subject: [PATCH] Replace lol::array with std::vector in aabb_tree.h. --- TODO.md | 1 - legacy/lol/algorithm/aabb_tree.h | 213 +++++++++++++++++-------------- 2 files changed, 118 insertions(+), 96 deletions(-) diff --git a/TODO.md b/TODO.md index fd82d5f9..1423791e 100644 --- a/TODO.md +++ b/TODO.md @@ -47,7 +47,6 @@ ## headers to remove one day src/lol/algorithm/sort.h (there’s plenty of stuff in libc++) - src/lol/base/array.h (use std::vector) src/lol/base/enum.h (can’t see the point) src/lol/base/tuple.h (use std::tuple) diff --git a/legacy/lol/algorithm/aabb_tree.h b/legacy/lol/algorithm/aabb_tree.h index 506eb0af..d69f0274 100644 --- a/legacy/lol/algorithm/aabb_tree.h +++ b/legacy/lol/algorithm/aabb_tree.h @@ -13,10 +13,12 @@ #pragma once -#include #include #include +#include // std::vector +#include // std::tuple + namespace lol { @@ -29,37 +31,61 @@ template class Octree; namespace Debug { //-- +template +struct box_t +{ + TBB bbox; + vec4 color; +}; + +template +struct elem_t +{ + TE *elem; + int shadow; + vec4 color; +}; + +template +struct leaf_t +{ + int id; + TBB bbox; +}; + template -void DrawInner(TREE *tree, array &boxes, - array &elements, - array &leaves, int children, vec4 color) +void DrawInner(TREE *tree, + std::vector> &boxes, + std::vector> &elements, + std::vector> &leaves, int children, vec4 color) { - boxes.push(tree->GetAABB(), color::white); - leaves.push(0, boxes.last().m1); - while (leaves.count() > 0) + boxes.push_back(box_t { tree->GetAABB(), color::white }); + leaves.push_back(leaf_t { 0, boxes.last().bbox }); + + while (leaves.size() > 0) { - for (int j = 0; j < tree->GetTree()[leaves[0].m1].m_elements.count(); j++) + for (auto const eid : tree->GetTree()[leaves[0].id].m_elements) { bool done = false; - for (int k = 0; k < elements.count(); k++) + for (size_t k = 0; k < elements.size(); k++) { - if (elements[k].m1 == tree->GetElements()[tree->GetTree()[leaves[0].m1].m_elements[j]].m_element) + if (elements[k].elem == tree->GetElements()[eid].m_element) { - elements[k].m2++; + elements[k].shadow++; done = true; break; } } if (!done) - elements.push(tree->GetElements()[tree->GetTree()[leaves[0].m1].m_elements[j]].m_element, 1, color::red); + elements.push(tree->GetElements()[eid].m_element, 1, color::red); } for (int i = 0; i < children; i++) { - if (tree->GetTree()[leaves[0].m1].m_children[i] != 0) + if (tree->GetTree()[leaves[0].id].m_children[i] != 0) { - TBB bbox = tree->GetSubAABB(leaves[0].m2, i); - leaves.push(tree->GetTree()[leaves[0].m1].m_children[i], bbox); + TBB bbox = tree->GetSubAABB(leaves[0].bbox, i); + leaves.push(tree->GetTree()[leaves[0].id].m_children[i], bbox); boxes.push(bbox, color); } } @@ -71,76 +97,70 @@ void DrawInner(TREE *tree, array &boxes, template void Draw(Quadtree* tree, vec4 color) { - array boxes; - array elements; - array leaves; + std::vector> boxes; + std::vector> elements; + std::vector> leaves; DrawInner, TE, box2>(tree, boxes, elements, leaves, 4, color); vec3 off = vec3(0.0f, 0.1f, 0.0f); //vec3 add = vec3(0.0f, 0.1f, 0.0f); - while (boxes.count() > 0) + for (auto const &b : boxes) { - auto const &box = std::get<0>(boxes[0]); - auto const &col = std::get<1>(boxes[0]); - Debug::DrawBox(vec3(box.aa.x, tree->m_debug_y_offset, box.aa.y), - vec3(box.bb.x, tree->m_debug_y_offset, box.bb.y), - col); - boxes.remove(0); + Debug::DrawBox(vec3(b.bbox.aa.x, tree->m_debug_y_offset, b.bbox.aa.y), + vec3(b.bbox.bb.x, tree->m_debug_y_offset, b.bbox.bb.y), + b.color); } - while (elements.count() > 0) + boxes.clear(); + + for (auto const &e : elements) { - auto const *e = std::get<0>(elements[0]); - int shadow = std::get<1>(elements[0]); - while (shadow) + while (e.shadow) { - Debug::DrawBox(vec3(e->GetAABB().aa.x, tree->m_debug_y_offset, e->GetAABB().aa.y) + off * (float)shadow, - vec3(e->GetAABB().bb.x, tree->m_debug_y_offset, e->GetAABB().bb.y) + off * (float)shadow, - elements[0].m3); - --shadow; + Debug::DrawBox(vec3(e.elem->GetAABB().aa.x, tree->m_debug_y_offset, e.elem->GetAABB().aa.y) + off * (float)e.shadow, + vec3(e.elem->GetAABB().bb.x, tree->m_debug_y_offset, e.elem->GetAABB().bb.y) + off * (float)e.shadow, + e.color); + --e.shadow; } - elements.remove(0); } + elements.clear(); } -//-- + template void Draw(Octree* tree, vec4 color) { - array boxes; - array elements; - array leaves; + std::vector> boxes; + std::vector> elements; + std::vector> leaves; DrawInner, TE, box3>(tree, boxes, elements, leaves, 8, color); vec3 off = vec3(0.0f, 0.1f, 0.0f); //vec3 add = vec3(0.0f, 0.1f, 0.0f); - while (boxes.count() > 0) + for (auto const &b : boxes) { - auto const &box = std::get<0>(boxes[0]); - auto const &col = std::get<1>(boxes[0]); //float size = box.bb.x - box.aa.x; - Debug::DrawBox(box.aa, /* + off * (m_size.x / size) */ - box.bb, /* + off * (m_size.x / size) */ - col); + Debug::DrawBox(b.bbox.aa, /* + off * (m_size.x / size) */ + b.bbox.bb, /* + off * (m_size.x / size) */ + b.color); //off += add; - boxes.remove(0); } - while (elements.count() > 0) + boxes.clear(); + + for (auto const &e : elements) { - auto const *e = std::get<0>(elements[0]); - int shadow = std::get<1>(elements[0]); - while (shadow) + while (e.shadow) { - Debug::DrawBox(e->GetAABB().aa + off * (float)shadow, - e->GetAABB().bb + off * (float)shadow, - elements[0].m3); - --shadow; + Debug::DrawBox(e.elem->GetAABB().aa + off * (float)e.shadow, + e.elem->GetAABB().bb + off * (float)e.shadow, + e.color); + --e.shadow; } - elements.remove(0); } + elements.clear(); } -//-- -} + +} // namespace Debug //-- template @@ -148,11 +168,11 @@ class AABBTree { struct NodeLeaf { - int m_parent; + int m_parent; //Children pos in the list - int m_children[child_nb]; + size_t m_children[child_nb]; //Element list - array m_elements; + std::vector m_elements; NodeLeaf(int parent) { @@ -164,8 +184,8 @@ class AABBTree struct TreeElement { - TE* m_element; - array m_leaves; + TE *m_element; + std::vector m_leaves; inline bool operator==(const TE*& element) { return m_element == element; } }; @@ -208,9 +228,9 @@ private: { for (size_t i = 0; i < child_nb; ++i) { - int old_leaf = m_tree[leaf].m_children[i]; + size_t old_leaf = m_tree[leaf].m_children[i]; if (old_leaf != 0) - m_free_leaves << old_leaf; + m_free_leaves.push_back(old_leaf); m_tree[leaf].m_children[i] = 0; } return true; @@ -221,7 +241,7 @@ private: void RemoveElement(TE* element) { int idx = INDEX_NONE; - for (int i = 0; i < m_elements.count(); ++i) + for (size_t i = 0; i < m_elements.size(); ++i) if (m_elements[i].m_element == element) idx = i; @@ -229,8 +249,8 @@ private: return; //Remove item from tree leaves - for (int i = 0; i < m_elements[idx].m_leaves.count(); i++) - m_tree[m_elements[idx].m_leaves[i]].m_elements.removeItem(idx); + for (auto const &lid : m_elements[idx].m_leaves) + m_tree[lid].m_elements.removeItem(idx); //Try leaves cleanup CleanupEmptyLeaves(); @@ -238,32 +258,32 @@ private: //-- int AddElement(TE* element) { - for (int i = 0; i < m_elements.count(); ++i) + for (size_t i = 0; i < m_elements.size(); ++i) if (m_elements[i].m_element == element) - return i; + return int(i); TreeElement new_element; new_element.m_element = element; - new_element.m_leaves = array(); - m_elements << new_element; - return m_elements.count() - 1; + new_element.m_leaves.clear(); + m_elements.push_back(new_element); + return int(m_elements.size()) - 1; } //-- int AddLeaf(int parent) { - int idx = m_tree.count(); - if (m_free_leaves.count()) + int idx(m_tree.size()); + if (m_free_leaves.size()) { - idx = m_free_leaves.pop(); + idx = m_free_leaves.pop_back(); m_tree[idx] = NodeLeaf(parent); } else - m_tree << NodeLeaf(parent); + m_tree.push_back(NodeLeaf(parent)); return idx; } //-- - bool TestLeaf(int leaf, const TB& leaf_bb, const TB& test_bb, array& elements) + bool TestLeaf(int leaf, const TB& leaf_bb, const TB& test_bb, std::vector& elements) { bool result = false; if (TestAABBVsAABB(leaf_bb, test_bb)) @@ -278,7 +298,7 @@ private: } else { - for (int j = 0; j < node.m_elements.count(); j++) + for (size_t j = 0; j < node.m_elements.size(); j++) elements.push_unique(m_elements[node.m_elements[j]].m_element); result = true; } @@ -303,23 +323,26 @@ private: if (found_child) return true; - //Too much elements, we need to re-dispatch the elements - if (m_tree[leaf].m_elements.count() + 1 > m_max_element && + //Too many elements, we need to re-dispatch the elements + if (int(m_tree[leaf].m_elements.size()) >= m_max_element && depth < m_max_depth) { //Extract elements - array elements = m_tree[leaf].m_elements; - elements.push_unique(AddElement(element)); + std::vector elements = m_tree[leaf].m_elements; + int new_eid = AddElement(element); + // Add new element to list if not already here + for (auto const eid : elements) + if (eid == new_eid) + new_eid = -1; + if (new_eid != -1) + elements.push_back(new_eid); m_tree[leaf].m_elements.clear(); //Add children for (size_t j = 0; j < child_nb; ++j) m_tree[leaf].m_children[j] = AddLeaf(leaf); //Re-run extracted elements - while (elements.count()) - { - RegisterElement(m_elements[elements[0]].m_element, leaf, leaf_bb, depth); - elements.remove(0); - } + for (auto const eid : elements) + RegisterElement(m_elements[eid].m_element, leaf, leaf_bb, depth); } //else add to list. else @@ -336,7 +359,7 @@ private: public: void RegisterElement(TE* element) { RegisterElement(element, 0, GetAABB(), 0); } void UnregisterElement(TE* element) { RemoveElement(element); } - bool FindElements(const TB& bbox, array& elements) { return TestLeaf(0, GetAABB(), bbox, elements); } + bool FindElements(const TB& bbox, std::vector& elements) { return TestLeaf(0, GetAABB(), bbox, elements); } void Clear() { m_tree.clear(); @@ -362,23 +385,23 @@ public: void SetMaxDepth(int max_depth) { m_max_depth = max_depth; } void SetMaxElement(int max_element) { m_max_element = max_element; } - array const & GetTree() const + std::vector const & GetTree() const { return m_tree; } - array const & GetElements() const + std::vector const & GetElements() const { return m_elements; } protected: - array m_tree; //actual tree - array m_elements; //elements to leaves - array m_free_leaves; //leaves removed from tree - TV m_size; //Main tree size - int m_max_depth; //Maximum depth possible - int m_max_element; //Maximum element per leaf + std::vector m_tree; // actual tree + std::vector m_elements; // elements to leaves + std::vector m_free_leaves; // leaves removed from tree + TV m_size; // Main tree size + int m_max_depth; // Maximum depth possible + int m_max_element; // Maximum element per leaf }; //--