]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/util/QuadTreeBuilder.cxx
Work around apparent OSG 3.2.0 normal binding bug.
[simgear.git] / simgear / scene / util / QuadTreeBuilder.cxx
index 4fe230c5b5cbe10c57067c943a30e9c5dc89e7d9..199efb7d439352d8c8738730d2dc71525763633f 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <osg/BoundingBox>
 #include <osg/Math>
+#include <simgear/scene/util/SGNodeMasks.hxx>
 
 #include "QuadTreeBuilder.hxx"
 
@@ -24,38 +25,57 @@ using namespace osg;
 
 namespace simgear
 {
-QuadTreeBuilder::QuadTreeBuilder(const Vec2& min, const Vec2& max) :
-    _root(new osg::Group), _min(min), _max(max)
+#if 0
+QuadTreeBuilder::QuadTreeBuilder(const Vec2& min, const Vec2& max, int depth) :
+    _root(new osg::Group), _min(min), _max(max), _depth(depth),
+    _dimension(1 << depth), _leafStorage(_dimension * _dimension),
+    _leaves(_leafStorage, _dimension)
 {
-    for (int i = 0; i < 4; ++i) {
-        Group* interior = new osg::Group;
-        _root->addChild(interior);
-        for (int j = 0; j < 4; ++j) {
-            Group* leaf = new osg::Group;
-            interior->addChild(leaf);
-            _leaves[i][j] = leaf;
+    for (LeafVector::iterator iter = _leafStorage.begin();
+         iter != _leafStorage.end();
+         ++iter)
+        *iter = new LOD;
+    vector<Group*> parentNodes(1);
+    parentNodes[0] = _root.get();
+    unsigned leafDim = 2;
+    for (int i = 0; i < depth - 1;  ++i, leafDim *= 2) {
+        VectorArrayAdapter<vector<Group*> > parents(parentNodes, leafDim / 2);
+        vector<Group*> interiorNodes(leafDim * leafDim);
+        VectorArrayAdapter<vector<Group*> > interiors(interiorNodes, leafDim);
+        for (unsigned j = 0; j < leafDim; ++j) {
+            for (unsigned k = 0; k < leafDim; ++k) {
+                interiors(j, k) = new Group;
+                parents(j / 2, k / 2)->addChild(interiors(j, k));
+            }
         }
+        parentNodes.swap(interiorNodes);
     }
+    VectorArrayAdapter<vector<Group*> > leafParents(parentNodes,
+                                                    _dimension / 2);
+    for (int j = 0; j < _dimension; ++j)
+        for (int k =0; k < _dimension; ++k)
+            leafParents(j / 2, k / 2)->addChild(_leaves(j, k));
 }
 
-void QuadTreeBuilder::addNode(Node* node, const Matrix& transform)
+void QuadTreeBuilder::addNode(Node* node, int lod, const Matrix& transform)
 {
     Vec3 center = node->getBound().center() * transform;
 
-    int x = (int)(4.0 * (center.x() - _min.x()) / (_max.x() - _min.x()));
-    x = clampTo(x, 0, 3);
-    int y = (int)(4.0 * (center.y() - _min.y()) / (_max.y() - _min.y()));
-    y = clampTo(y, 0, 3);
-    _leaves[y][x]->addChild(node);
+    int x = (int)(_dimension * (center.x() - _min.x()) / (_max.x() - _min.x()));
+    x = clampTo(x, 0, (_dimension - 1));
+    int y = (int)(_dimension * (center.y() - _min.y()) / (_max.y() - _min.y()));
+    y = clampTo(y, 0, (_dimension -1));
+    
+    _leaves(y, x)->addChild(node, 0, lod);
 }
 
-osg::Group* QuadTreeBuilder::makeQuadTree(vector<ref_ptr<Node> >& nodes,
+osg::Group* QuadTreeBuilder::makeQuadTree(LodMap& models,
                                           const Matrix& transform)
 {
     typedef vector<ref_ptr<Node> > NodeList;
     BoundingBox extents;
-    for (NodeList::iterator iter = nodes.begin(); iter != nodes.end(); ++iter) {
-        const Vec3 center = (*iter)->getBound().center() * transform;
+    for (LodMap::iterator iter = models.begin(); iter != models.end(); ++iter) {
+        const Vec3 center = (*iter).first->getBound().center() * transform;
         extents.expandBy(center);
     }
     const Vec2 quadMin(extents.xMin(), extents.yMin());
@@ -63,14 +83,14 @@ osg::Group* QuadTreeBuilder::makeQuadTree(vector<ref_ptr<Node> >& nodes,
     ref_ptr<Group> result;
     {
         QuadTreeBuilder quadTree(quadMin, quadMax);
-        for (NodeList::iterator iter = nodes.begin();
-             iter != nodes.end();
+        for (LodMap::iterator iter = models.begin();
+             iter != models.end();
              ++iter) {
-            quadTree.addNode(iter->get(), transform);
+            quadTree.addNode(iter->first.get(), iter->second, transform);
         }
         result = quadTree.getRoot();
     }
     return result.release();
 }
-
+#endif
 }