Advertisement
Guest User

Untitled

a guest
Jul 21st, 2017
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.63 KB | None | 0 0
  1. #ifndef QUADTREE_HPP
  2. #define QUADTREE_HPP
  3.  
  4.  
  5. #include <list>
  6. #include <boost/array.hpp>
  7. #include <boost/unordered_map.hpp>
  8. #include <gmtl/gmtl.h>
  9. #include "spatial_storage_base.hpp"
  10.  
  11.  
  12. namespace zserver
  13. {
  14.  
  15. namespace game
  16. {
  17.  
  18. namespace storage
  19. {
  20.  
  21. /******************************************************************************
  22. * quadtree_node
  23. *
  24. * Helper class for quadtree which represents a single node within the tree.
  25. ******************************************************************************/
  26. template<class Item, class Locator = locator<Item> >
  27. class quadtree_node
  28. {
  29.     Locator                                         locator_;
  30.  
  31.     std::list<Item>                                 items_;
  32.     boost::array<quadtree_node<Item, Locator>*, 4>  childs_;
  33.     int                                             depth_;
  34.     gmtl::AABoxf                                    box_;
  35.  
  36. public:
  37.     /**************************************************************************
  38.     * Parameterized constructor.
  39.     **************************************************************************/
  40.     quadtree_node<Item, Locator>(int depth, gmtl::AABoxf const& box)
  41.         : items_(), childs_(), depth_(depth), box_(box)
  42.     {
  43.         if(depth <= 0)
  44.             return;
  45.  
  46.         gmtl::Vec3f half_width = gmtl::Vec3f(
  47.                                     (box.getMax()[0] - box.getMin()[0]) / 2.0f,
  48.                                     0.0f,
  49.                                     0.0f);
  50.         gmtl::Vec3f half_height = gmtl::Vec3f(
  51.                                     0.0f,
  52.                                     (box.getMax()[1] - box.getMin()[1]) / 2.0f,
  53.                                     0.0f);
  54.  
  55.         childs_[0] = new quadtree_node<Item>(
  56.                 depth - 1,
  57.                 gmtl::AABoxf(
  58.                         box.getMin(),
  59.                         box.getMin() + half_width + half_height));
  60.         childs_[1] = new quadtree_node<Item>(
  61.                 depth - 1,
  62.                 gmtl::AABoxf(
  63.                         box.getMin() + half_width,
  64.                         box.getMin() + 2.0f * half_width + half_height));
  65.         childs_[2] = new quadtree_node<Item>(
  66.                 depth - 1,
  67.                 gmtl::AABoxf(
  68.                         box.getMin() + half_height,
  69.                         box.getMin() + half_width + 2.0f * half_height));
  70.         childs_[3] = new quadtree_node<Item>(
  71.                 depth - 1,
  72.                 gmtl::AABoxf(
  73.                         box.getMin() + half_width + half_height,
  74.                         box.getMin() + 2.0f * half_height + 2.0f * half_width));
  75.     }
  76.  
  77.     /**************************************************************************
  78.     * Virtual destructor.
  79.     **************************************************************************/
  80.     ~quadtree_node<Item, Locator>()
  81.     {
  82.         for(int i = 0; i < 4; ++i)
  83.         {
  84.             if(childs_[i])
  85.                 delete childs_[i];
  86.  
  87.             childs_[i] = 0;
  88.         }
  89.     }
  90.  
  91.     /**************************************************************************
  92.     * Insert an item.
  93.     **************************************************************************/
  94.     quadtree_node<Item, Locator>* const insert(Item const& item)
  95.     {
  96.         if(depth_ > 0)
  97.             for(int i = 0; i < 4; ++i)
  98.             {
  99.             std::cout << "isInVolume(" << childs_[i]->box_ << ", " << locator_(item) << ")=" << gmtl::isInVolume(childs_[i]->box_, locator_(item)) << std::endl;
  100.                 if(gmtl::isInVolume(childs_[i]->box_, locator_(item)))
  101.                     return childs_[i]->insert(item);
  102.             }
  103.  
  104.         items_.push_back(item);
  105.         return this;
  106.     }
  107.  
  108.     /**************************************************************************
  109.     * Remove an item.
  110.     **************************************************************************/
  111.     void remove(Item const& item)
  112.     {
  113.         items_.remove(item);
  114.     }
  115.  
  116.     /**************************************************************************
  117.     * Find items contained or overlapped by a given box.
  118.     **************************************************************************/
  119.     void find(gmtl::AABoxf const& box, std::list<Item>& collected)
  120.     {
  121.         if(depth_ > 0)
  122.             for(int i = 0; i < 4; ++i)
  123.                 if(gmtl::intersect(box, childs_[i]->box_))
  124.                     childs_[i]->find(box, collected);
  125.  
  126.         collected.insert(collected.end(), items_.begin(), items_.end());
  127.     }
  128. };
  129.  
  130. /******************************************************************************
  131. * quadtree
  132. *
  133. * Utilizes a quadtree to store items in a spatial manner.
  134. ******************************************************************************/
  135. template<class Item, class Locator = locator<Item> >
  136. class quadtree : public spatial_storage_base<Item>
  137. {  
  138.     boost::unordered_map<Item,
  139.                          quadtree_node<Item, Locator>*>   item_node_lookup_;
  140.     quadtree_node<Item, Locator>                          root_;
  141.  
  142. public:
  143.     /**************************************************************************
  144.     * Parameterless constructor.
  145.     **************************************************************************/
  146.     quadtree<Item, Locator>(int depth, gmtl::AABoxf const& box)
  147.         : root_(depth, box)
  148.     {
  149.     }
  150.  
  151.     /**************************************************************************
  152.     * Virtual destructor.
  153.     **************************************************************************/
  154.     virtual ~quadtree<Item, Locator>()
  155.     {
  156.     }
  157.  
  158.     /**************************************************************************
  159.     * Insert an item.
  160.     **************************************************************************/
  161.     void insert(Item const& item)
  162.     {
  163.         item_node_lookup_[item] = root_.insert(item);
  164.     }
  165.  
  166.     /**************************************************************************
  167.     * Remove an item.
  168.     **************************************************************************/
  169.     void remove(Item const& item)
  170.     {
  171.         item_node_lookup_[item]->remove(item);
  172.         item_node_lookup_.erase(item);
  173.     }
  174.  
  175.     /**************************************************************************
  176.     * Find items contained or overlapped by a given box.
  177.     **************************************************************************/
  178.     std::list<Item> find(gmtl::AABoxf const& box)
  179.     {
  180.         std::list<Item> items;
  181.  
  182.         root_.find(box, items);
  183.  
  184.         return items;
  185.     }
  186. };
  187.  
  188. } // namespace storage
  189.  
  190. } // namespace game
  191.  
  192. } // namespace zserver
  193.  
  194.  
  195. #endif // QUADTREE_HPP
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement