diff --git a/examples/osgkdtree/CMakeLists.txt b/examples/osgkdtree/CMakeLists.txt index ff0b86fe6..d9f3ceaeb 100644 --- a/examples/osgkdtree/CMakeLists.txt +++ b/examples/osgkdtree/CMakeLists.txt @@ -1,10 +1,12 @@ SET(TARGET_SRC fixeddivision.cpp + variabledivision.cpp osgkdtree.cpp ) SET(TARGET_H fixeddivision.h + variabledivision.h ) diff --git a/examples/osgkdtree/osgkdtree.cpp b/examples/osgkdtree/osgkdtree.cpp index e3b1fc979..50ce6efdd 100644 --- a/examples/osgkdtree/osgkdtree.cpp +++ b/examples/osgkdtree/osgkdtree.cpp @@ -38,6 +38,7 @@ #include #include "fixeddivision.h" +#include "variabledivision.h" int main(int argc, char **argv) @@ -89,6 +90,22 @@ int main(int argc, char **argv) } else { + variabledivision::KDTreeBuilder builder; + + builder._maxNumLevels = maxNumLevels; + builder._targetNumTrianglesPerLeaf = targetNumIndicesPerLeaf; + builder._processTriangles = processTriangles; + + + osg::Timer_t start = osg::Timer::instance()->tick(); + + + scene->accept(builder); + + osg::Timer_t end = osg::Timer::instance()->tick(); + double time = osg::Timer::instance()->delta_s(start,end); + osg::notify(osg::NOTICE)<<"Time to build "<_triangles.size(); + _kdTree->_triangles.push_back(Triangle(p1,p2,p3)); + + osg::BoundingBox bb; + bb.expandBy((*(_kdTree->_vertices))[p1]); + bb.expandBy((*(_kdTree->_vertices))[p2]); + bb.expandBy((*(_kdTree->_vertices))[p3]); + _kdTree->_boundingBoxes.push_back(bb); + + _kdTree->_centers.push_back(bb.center()); + + _kdTree->_primitiveIndices.push_back(i); + + } + + KDTree* _kdTree; + +}; + +KDTree* KDTreeBuilder::createKDTree(osg::Geometry* geometry) +{ +#ifdef VERBOSE_OUTPUT + osg::notify(osg::NOTICE)<<"osg::KDTreeBuilder::createKDTree()"<(geometry->getVertexArray()); + if (!vertices) return 0; + + if (vertices->size() <= _targetNumTrianglesPerLeaf) return 0; + + osg::ref_ptr kdTree = new KDTree; + kdTree->_geometry = geometry; + kdTree->_bb = kdTree->_geometry->getBound(); + kdTree->_vertices = vertices; + + unsigned int estimatedSize = (unsigned int)(2.0*float(vertices->size())/float(_targetNumTrianglesPerLeaf)); + +#ifdef VERBOSE_OUTPUT + osg::notify(osg::NOTICE)<<"kdTree->_kdNodes.reserve()="<_kdNodes.reserve(estimatedSize); + kdTree->_kdLeaves.reserve(estimatedSize); + + computeDivisions(*kdTree); + + + _numVerticesProcessed += vertices->size(); + + unsigned int estimatedNumTriangles = vertices->size()*2; + kdTree->_primitiveIndices.reserve(estimatedNumTriangles); + kdTree->_boundingBoxes.reserve(estimatedNumTriangles); + kdTree->_triangles.reserve(estimatedNumTriangles); + kdTree->_centers.reserve(estimatedNumTriangles); + + + + osg::TriangleIndexFunctor collectTriangleIndices; + collectTriangleIndices._kdTree = kdTree.get(); + geometry->accept(collectTriangleIndices); + + kdTree->_primitiveIndices.reserve(vertices->size()); + + + + KDLeaf leaf(0, kdTree->_primitiveIndices.size()); + + int leafNum = kdTree->addLeaf(leaf); + + osg::BoundingBox bb = kdTree->_bb; + int nodeNum = divide(*kdTree, bb, leafNum, 0); + +#ifdef VERBOSE_OUTPUT + osg::notify(osg::NOTICE)<<"Root nodeNum="<_kdNodes.size()="<_kdNodes.size()<_kdLeaves.size()="<_kdLeaves.size()<_kdNodes.size()="<_kdNodes.size()<<" estimated size = "<_kdLeaves.size()="<_kdLeaves.size()<<" estimated 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; + +#ifdef VERBOSE_OUTPUT + osg::notify(osg::NOTICE)<<" "<mid)) { --right; } + + while(leftmid)) { --right; } + + if (left + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + +#include +#include +#include + +#include + + +namespace variabledivision +{ + +typedef int value_type; +typedef std::vector< value_type > Indices; + +//#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 AxisStack; + typedef std::vector< KDNode > KDNodeList; + + 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.first) traverse(tree,node.first,level+1); + else output(level+1)<<"empty left child()"<asGeometry(); + if (geom) + { + geom->setShape(createKDTree(geom)); + } + } + } + + KDTree* createKDTree(osg::Geometry* geometry); + + void computeDivisions(KDTree& kdTree); + + int divide(KDTree& kdTree, osg::BoundingBox& bb, int nodeIndex, unsigned int level); + + unsigned int _maxNumLevels; + unsigned int _targetNumTrianglesPerLeaf; + + unsigned int _numVerticesProcessed; + bool _processTriangles; + +}; + + +} + +#endif