diff --git a/examples/osgkdtree/osgkdtree.cpp b/examples/osgkdtree/osgkdtree.cpp index 34c6e8ff5..aa45d3e08 100644 --- a/examples/osgkdtree/osgkdtree.cpp +++ b/examples/osgkdtree/osgkdtree.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -45,11 +46,43 @@ namespace osg typedef int value_type; typedef std::vector< value_type > Indices; -//#define VERBOSE_OUTPUT +// #define VERBOSE_OUTPUT typedef std::pair< value_type, value_type> KDNode; typedef std::pair< value_type, value_type> KDLeaf; +struct Triangle +{ + Triangle(unsigned int p1, unsigned int p2, unsigned int p3): + _p1(p1), _p2(p2), _p3(p3) {} + + bool operator < (const Triangle& rhs) const + { + if (_p1rhs._p1) return false; + if (_p2rhs._p2) return false; + return _p3_primitiveList.size()-1) + { + osg::notify(osg::NOTICE)<<"Warning: replaceChild("<_indices.clear(); + _leafRecycleList.push_back(leaf); + } + + inline KDPrimitiveLeaf* createKDPrimitiveLeaf() + { + if (_leafRecycleList.empty()) return new KDPrimitiveLeaf; + osg::ref_ptr leaf = _leafRecycleList.back(); + _leafRecycleList.pop_back(); + return leaf.release(); + } + + typedef std::list< osg::ref_ptr > LeafRecyleList; + LeafRecyleList _leafRecycleList; }; +struct TriangleIndicesCollector +{ + TriangleIndicesCollector(): + _indices(0) + { + } + + inline void operator () (unsigned int v1, unsigned int v2, unsigned int v3) + { + _indices->push_back(v1); + _indices->push_back(v2); + _indices->push_back(v3); + } + + Indices* _indices; + +}; KDTree* KDTreeBuilder::createKDTree(osg::Geometry* geometry) { @@ -246,13 +373,15 @@ KDTree* KDTreeBuilder::createKDTree(osg::Geometry* geometry) osg::Vec3Array* vertices = dynamic_cast(geometry->getVertexArray()); if (!vertices) return 0; + + if (vertices->size() <= _targetNumVerticesPerLeaf) return 0; osg::ref_ptr kdTree = new KDTree; kdTree->_geometry = geometry; kdTree->_bb = kdTree->_geometry->getBound(); kdTree->_vertices = vertices; - unsigned int estimatedSize = (unsigned int)(float(vertices->size())/float(_targetNumVerticesPerLeaf)*1.5); + unsigned int estimatedSize = (unsigned int)(2.0*float(vertices->size())/float(_targetNumVerticesPerLeaf)); #ifdef VERBOSE_OUTPUT osg::notify(osg::NOTICE)<<"kdTree->_kdNodes.reserve()="<size(); - kdTree->_vertexIndices.reserve(vertices->size()); - for(unsigned int i=0; isize(); ++i) + if (_processTriangles) { - kdTree->_vertexIndices.push_back(i); + + osg::TriangleIndexFunctor collectTriangleIndices; + collectTriangleIndices._indices = &(kdTree->_vertexIndices); + geometry->accept(collectTriangleIndices); + + KDPrimitiveLeaf* primitiveLeaf = createKDPrimitiveLeaf(); + primitiveLeaf->_indices.insert(primitiveLeaf->_indices.end(), + kdTree->_vertexIndices.begin(), + kdTree->_vertexIndices.end()); + + // osg::notify(osg::NOTICE)<<"kdTree->_vertexIndices.size()="<_vertexIndices.size()<addPrimitiveLeaf(primitiveLeaf); + + osg::BoundingBox bb = kdTree->_bb; + int nodeNum = divideTriangles(*kdTree, bb, leafNum, 0); + + std::cout<<"_vertexIndices.size() = "<_vertexIndices.size()<_kdNodes.size()="<_kdNodes.size()<_kdLeaves.size()="<_kdLeaves.size()<_kdNodes.size()="<_kdNodes.size()<<" estimated size = "<_kdLeaves.size()="<_kdLeaves.size()<<" estimated size = "<_indices.size()<=_targetNumIndicesPerLeaf) return nodeIndex; + +#ifdef VERBOSE_OUTPUT + osg::notify(osg::NOTICE)<<" divide leaf"<_indices; + +#ifdef VERBOSE_OUTPUT + osg::notify(osg::NOTICE)<<" divide leaf->_indices.size()="<_indices.size()< leftLeaf = createKDPrimitiveLeaf(); + osg::ref_ptr rightLeaf = createKDPrimitiveLeaf(); + + for(int i = 0; i0) + { + leftLeaf->_indices.push_back(i1); leftLeaf->_indices.push_back(i2); + leftLeaf->_indices.push_back(i3); + } + + if (numRight>0) + { + rightLeaf->_indices.push_back(i1); + rightLeaf->_indices.push_back(i2); + rightLeaf->_indices.push_back(i3); + } +#if 0 + if (numRight>0 && numLeft>0) + { + std::cout<<"In both"<_indices.empty()) + { +#ifdef VERBOSE_OUTPUT + osg::notify(osg::NOTICE)<<"LeftLeaf empty"<_indices.empty()) + { +#ifdef VERBOSE_OUTPUT + osg::notify(osg::NOTICE)<<"RightLeaf empty"<_vertexIndices.size()="<_vertexIndices.size()< scene = osgDB::readNodeFiles(arguments); if (!scene) @@ -499,7 +844,7 @@ int main(int argc, char **argv) osg::Timer_t start = osg::Timer::instance()->tick(); - osg::KDTreeBuilder builder; + scene->accept(builder); osg::Timer_t end = osg::Timer::instance()->tick();