00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 #ifndef SIMGEAR_QUADTREEBUILDER_HXX
00017 #define SIMGEAR_QUADTREEBUILDER_HXX 1
00018 
00019 #include <algorithm>
00020 #include <functional>
00021 #include <vector>
00022 #include <osg/BoundingBox>
00023 #include <osg/ref_ptr>
00024 #include <osg/Node>
00025 #include <osg/Group>
00026 #include <osg/Matrix>
00027 #include <osg/Vec2>
00028 #include <osg/LOD>
00029 #include "VectorArrayAdapter.hxx"
00030 
00031 namespace simgear
00032 {
00033 typedef std::map<osg::ref_ptr<osg::Node>,int> LodMap;
00034 
00035 
00036 template <typename LeafType, typename ObjectType, typename MakeLeaf,
00037           typename AddLeafObject, typename GetObjectLocalCoords>
00038 class QuadTreeBuilder {
00039 public:
00040     QuadTreeBuilder(const GetObjectLocalCoords& getLocalCoords,
00041                     const AddLeafObject& addLeafObject, int depth = 2,
00042                     const MakeLeaf& makeLeaf = MakeLeaf()) :
00043         _root(new osg::Group), _depth(depth),
00044         _dimension(1 << depth), _leafStorage(_dimension * _dimension),
00045         _leaves(_leafStorage, _dimension),
00046         _leafParents(_leafParentStorage, _dimension / 2),
00047         _getLocalCoords(getLocalCoords),
00048         _addLeafObject(addLeafObject), _makeLeaf(makeLeaf)
00049     {
00050         using namespace std;
00051         using namespace osg;
00052         vector<Group*> parentNodes(1);
00053         parentNodes[0] = _root.get();
00054         unsigned leafDim = 2;
00055         for (int i = 0; i < depth - 1;  ++i, leafDim *= 2) {
00056             VectorArrayAdapter<vector<Group*> > parents(parentNodes, leafDim / 2);
00057             vector<Group*> interiorNodes(leafDim * leafDim);
00058             VectorArrayAdapter<vector<Group*> > interiors(interiorNodes, leafDim);
00059             for (unsigned j = 0; j < leafDim; ++j) {
00060                 for (unsigned k = 0; k < leafDim; ++k) {
00061                     interiors(j, k) = new Group;
00062                     parents(j / 2, k / 2)->addChild(interiors(j, k));
00063                 }
00064             }
00065             parentNodes.swap(interiorNodes);
00066         }
00067         
00068         _leafParentStorage = parentNodes;
00069     }
00070     osg::Vec2 getMin() { return _min; }
00071     void setMin(const osg::Vec2& min) { _min = min; }
00072     osg::Vec2 getMax() { return _max; }
00073     void setMax(const osg::Vec2& max) { _max = max; }
00074     ~QuadTreeBuilder() {}
00075     osg::Group* getRoot() { return _root.get(); }
00076 
00077     void addNode(ObjectType& obj)
00078     {
00079         using namespace osg;
00080         const Vec3 center(_getLocalCoords(obj));
00081         int x = 0;
00082         if (_max.x() != _min.x())
00083             x = (int)(_dimension * (center.x() - _min.x())
00084                       / (_max.x() - _min.x()));
00085         x = clampTo(x, 0, (_dimension - 1));
00086         int y = 0;
00087         if (_max.y() != _min.y())
00088             y = (int)(_dimension * (center.y() - _min.y())
00089                       / (_max.y() - _min.y()));
00090         y = clampTo(y, 0, (_dimension -1));
00091         if (!_leaves(y, x)) {
00092             _leaves(y, x) = _makeLeaf();
00093             _leafParents(y / 2, x / 2)->addChild(_leaves(y, x));
00094         }
00095         _addLeafObject(_leaves(y, x), obj);
00096     }
00097     
00098     struct AddNode
00099     {
00100         AddNode(QuadTreeBuilder* qt) : _qt(qt) {}
00101         AddNode(const AddNode& rhs) : _qt(rhs._qt) {}
00102         void operator() (ObjectType& obj) const { _qt->addNode(obj); }
00103         QuadTreeBuilder *_qt;
00104     };
00105     
00106     template <typename ForwardIterator>
00107     void buildQuadTree(const ForwardIterator& begin,
00108                        const ForwardIterator& end)
00109     {
00110         using namespace osg;
00111         BoundingBox extents;
00112         for (ForwardIterator iter = begin; iter != end; ++iter) {
00113             const Vec3 center = _getLocalCoords(*iter);
00114             extents.expandBy(center);
00115         }
00116         _min = Vec2(extents.xMin(), extents.yMin());
00117         _max = Vec2(extents.xMax(), extents.yMax());
00118         std::for_each(begin, end, AddNode(this));
00119     }
00120 
00121 protected:
00122     typedef std::vector<LeafType> LeafVector;
00123     osg::ref_ptr<osg::Group> _root;
00124     osg::Vec2 _min;
00125     osg::Vec2 _max;
00126     int _depth;
00127     int _dimension;
00128     LeafVector _leafStorage;
00129     VectorArrayAdapter<LeafVector> _leaves;
00130     std::vector<osg::Group*> _leafParentStorage;
00131     VectorArrayAdapter<std::vector<osg::Group*> > _leafParents;
00132     const GetObjectLocalCoords _getLocalCoords;
00133     const AddLeafObject _addLeafObject;
00134     const MakeLeaf _makeLeaf;
00135 };
00136 
00137 }
00138 #endif