/* OpenSceneGraph example, osgintersection. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "variabledivision.h" namespace variabledivision { struct TriangleIndicesCollector { TriangleIndicesCollector(): _kdTree(0) { } inline void operator () (unsigned int p1, unsigned int p2, unsigned int p3) { unsigned int i = _kdTree->_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