diff --git a/examples/osgkdtree/osgkdtree.cpp b/examples/osgkdtree/osgkdtree.cpp index b5676dcd2..2e860d85c 100644 --- a/examples/osgkdtree/osgkdtree.cpp +++ b/examples/osgkdtree/osgkdtree.cpp @@ -16,6 +16,11 @@ * THE SOFTWARE. */ + +#include + +#define _GLIBCXX_DEBUG + #include #include #include @@ -24,7 +29,6 @@ #include #include -#include #include #include @@ -35,6 +39,7 @@ #include + namespace osg { @@ -42,7 +47,22 @@ class KDNode { public: - typedef short value_type; + KDNode(): + _leftChild(0), + _rightChild(0) {} + + KDNode(const KDNode& rhs): + _leftChild(rhs._leftChild), + _rightChild(rhs._rightChild) {} + + KDNode& operator = (const KDNode& rhs) + { + _leftChild = rhs._leftChild; + _rightChild = rhs._rightChild; + return *this; + } + + typedef int value_type; value_type _leftChild; value_type _rightChild; @@ -52,7 +72,7 @@ class KDLeaf : public osg::Referenced { public: - KDLeaf(); + KDLeaf() {} typedef unsigned int index_type; typedef std::vector< index_type > Indices; @@ -79,6 +99,54 @@ class KDTree : public osg::Shape typedef std::vector< unsigned int > AxisStack; typedef std::vector< KDNode > KDNodeList; typedef std::vector< osg::ref_ptr > KDLeafList; + + + /// note, leafNum is negative to distinguish from nodeNum + int addLeaf(KDLeaf* leaf) { int num = _kdLeaves.size(); _kdLeaves.push_back(leaf); return -(num+1); } + + int replaceLeaf(int leafNum, KDLeaf* leaf) + { + int num = -leafNum-1; + + if (num>_kdLeaves.size()-1) + { + osg::notify(osg::NOTICE)<<"Warning: replaceChild("<=0) { KDNode& node = tree._kdNodes[nodeIndex]; - traverse(tree,node._leftChild,level+1); - traverse(tree,node._rightChild,level+1); + if (node._leftChild) traverse(tree,node._leftChild,level+1); + else output(level+1)<<"empty left child()"<(geometry->getVertexArray()); + if (!vertices) return 0; + + osg::ref_ptr kdTree = new KDTree; kdTree->_geometry = geometry; kdTree->_bb = kdTree->_geometry->getBound(); - osg::notify(osg::NOTICE)<<"osg::KDTreeBuilder::createKDTree()"<size())/float(_targetNumVerticesPerLeaf)*1.5); + + osg::notify(osg::NOTICE)<<"kdTree->_kdNodes.reserve()="<_kdNodes.reserve(estimatedSize); + kdTree->_kdLeaves.reserve(estimatedSize); + + computeDivisions(*kdTree); + + // create initial leaf list + osg::ref_ptr leaf = new KDLeaf; + leaf->_vertexIndices.reserve(vertices->size()); + for(unsigned int i=0; isize(); ++i) + { + leaf->_vertexIndices.push_back(i); + } + + osg::BoundingBox bb = kdTree->_bb; + + int leafNum = kdTree->addLeaf(leaf.get()); + int nodeNum = divide(*kdTree, bb, leafNum, 0); + + osg::notify(osg::NOTICE)<<"Root nodeNum="<_kdNodes.size()="<_kdNodes.size()<_kdLeaves.size()="<_kdLeaves.size()<=dimensions[1]) + { + if (dimensions[0]>=dimensions[2]) axis = 0; + else axis = 2; + } + else if (dimensions[1]>=dimensions[2]) axis = 1; + else axis = 2; + + kdTree._axisStack.push_back(axis); + dimensions[axis] /= 2.0f; + + osg::notify(osg::NOTICE)<<" "<_vertexIndices.size()<=_targetNumVerticesPerLeaf) return nodeIndex; + + osg::notify(osg::NOTICE)<<" divide leaf"< leaf = kdTree.getLeaf(nodeIndex); + + // create new node, and add two leaves to it. + osg::ref_ptr leftLeaf = new KDLeaf; + osg::ref_ptr rightLeaf = new KDLeaf; + + + osg::Vec3Array* vertices = dynamic_cast(kdTree._geometry->getVertexArray()); + + osg::notify(osg::NOTICE)<<" divide leaf->_vertexIndices.size()="<_vertexIndices.size()<_vertexIndices.size(); + leftLeaf->_vertexIndices.reserve(estimatedSize); + rightLeaf->_vertexIndices.reserve(estimatedSize); + + for(unsigned int i=0; i_vertexIndices.size(); ++i) + { + unsigned int vi = leaf->_vertexIndices[i]; + osg::Vec3& v = (*vertices)[vi]; + if (v[axis] <= mid) leftLeaf->_vertexIndices.push_back(vi); + else rightLeaf->_vertexIndices.push_back(vi); + } + + if (leftLeaf->_vertexIndices.empty()) + { + osg::notify(osg::NOTICE)<<"LeftLeaf empty"<_vertexIndices.empty()) + { + osg::notify(osg::NOTICE)<<"RightLeaf empty"<