diff --git a/examples/osgkdtree/osgkdtree.cpp b/examples/osgkdtree/osgkdtree.cpp index 1e177d05e..9e5de038e 100644 --- a/examples/osgkdtree/osgkdtree.cpp +++ b/examples/osgkdtree/osgkdtree.cpp @@ -44,29 +44,34 @@ namespace osg { +typedef int value_type; +typedef std::vector< value_type > Indices; + +//#define LEAF_OBJECT +//#define VERBOSE_OUTPUT + +#ifdef LEAF_OBJECT class KDNode { public: KDNode(): - _leftChild(0), - _rightChild(0) {} + first(0), + second(0) {} KDNode(const KDNode& rhs): - _leftChild(rhs._leftChild), - _rightChild(rhs._rightChild) {} + first(rhs.first), + second(rhs.second) {} KDNode& operator = (const KDNode& rhs) { - _leftChild = rhs._leftChild; - _rightChild = rhs._rightChild; + first = rhs.first; + second = rhs.second; return *this; } - typedef short value_type; - - value_type _leftChild; - value_type _rightChild; + value_type first; + value_type second; }; class KDLeaf : public osg::Referenced @@ -74,9 +79,6 @@ class KDLeaf : public osg::Referenced public: KDLeaf() {} - - typedef unsigned int index_type; - typedef std::vector< index_type > Indices; Indices _vertexIndices; @@ -85,6 +87,12 @@ class KDLeaf : public osg::Referenced virtual ~KDLeaf() {} }; +#else + typedef std::pair< value_type, value_type> KDNode; + typedef std::pair< value_type, value_type> KDLeaf; +#endif + + class KDTree : public osg::Shape { public: @@ -96,12 +104,14 @@ class KDTree : public osg::Shape Shape(rhs,copyop) {} META_Shape(osg, KDTree) + typedef std::vector< unsigned int > AxisStack; - typedef std::vector< KDNode > KDNodeList; + typedef std::vector< KDNode > KDNodeList; + +#ifdef LEAF_OBJECT 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); } @@ -130,6 +140,39 @@ class KDTree : public osg::Shape return _kdLeaves[num].get(); } + +#else + typedef std::vector< KDLeaf > KDLeafList; + + /// note, leafNum is negative to distinguish from nodeNum + int addLeaf(const KDLeaf& leaf) { int num = _kdLeaves.size(); _kdLeaves.push_back(leaf); return -(num+1); } + + int replaceLeaf(int leafNum, const KDLeaf& leaf) + { + int num = -leafNum-1; + + if (num>_kdLeaves.size()-1) + { + osg::notify(osg::NOTICE)<<"Warning: replaceChild("<=0) { KDNode& node = tree._kdNodes[nodeIndex]; - if (node._leftChild) traverse(tree,node._leftChild,level+1); + if (node.first) traverse(tree,node.first,level+1); else output(level+1)<<"empty left child()"<size())/float(_targetNumVerticesPerLeaf)*1.5); -#if VERBOSE_OUTPUT +#ifdef VERBOSE_OUTPUT osg::notify(osg::NOTICE)<<"kdTree->_kdNodes.reserve()="<size(); +#ifdef LEAF_OBJECT // create initial leaf list KDLeaf* leaf = new KDLeaf; leaf->_vertexIndices.reserve(vertices->size()); @@ -301,17 +362,29 @@ KDTree* KDTreeBuilder::createKDTree(osg::Geometry* geometry) { leaf->_vertexIndices.push_back(i); } +#else + + kdTree->_vertexIndices.reserve(vertices->size()); + for(unsigned int i=0; isize(); ++i) + { + kdTree->_vertexIndices.push_back(i); + } + KDLeaf leaf(0, kdTree->_vertexIndices.size()); + +#endif - osg::BoundingBox bb = kdTree->_bb; - int leafNum = kdTree->addLeaf(leaf); + osg::BoundingBox bb = kdTree->_bb; int nodeNum = divide(*kdTree, bb, leafNum, 0); + + + -#if VERBOSE_OUTPUT +#ifdef VERBOSE_OUTPUT osg::notify(osg::NOTICE)<<"Root nodeNum="<_vertexIndices.size()<=_targetNumVerticesPerLeaf) return nodeIndex; - +#else + if (kdTree.getLeaf(nodeIndex).second<=_targetNumVerticesPerLeaf) return nodeIndex; +#endif //osg::notify(osg::NOTICE)<<" divide leaf"< leaf = kdTree.getLeaf(nodeIndex); @@ -423,32 +501,105 @@ int KDTreeBuilder::divide(KDTree& kdTree, osg::BoundingBox& bb, int nodeIndex, u if (leftLeaf->_vertexIndices.empty()) { //osg::notify(osg::NOTICE)<<"LeftLeaf empty"<_vertexIndices.empty()) { //osg::notify(osg::NOTICE)<<"RightLeaf empty"<(kdTree._geometry->getVertexArray()); + + //osg::notify(osg::NOTICE)<<" divide leaf->_vertexIndices.size()="<_vertexIndices.size()<mid) { --right; } + + if (leftaccept(updateVisitor); + scene->getBound(); osg::Timer_t start = osg::Timer::instance()->tick();