/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #include #include #include #include using namespace osg; //#define VERBOSE_OUTPUT //////////////////////////////////////////////////////////////////////////////// // // Functor for collecting triangle indices from Geometry 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(KdTree::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 KdTree::KdTree() { } KdTree::KdTree(const KdTree& rhs, const osg::CopyOp& copyop): Shape(rhs) { } bool KdTree::build(BuildOptions& options, osg::Geometry* geometry) { #ifdef VERBOSE_OUTPUT osg::notify(osg::NOTICE)<<"osg::KDTreeBuilder::createKDTree()"<(geometry->getVertexArray()); if (!vertices) return false; if (vertices->size() <= options._targetNumTrianglesPerLeaf) return false; _geometry = geometry; _bb = _geometry->getBound(); _vertices = vertices; unsigned int estimatedSize = (unsigned int)(2.0*float(vertices->size())/float(options._targetNumTrianglesPerLeaf)); #ifdef VERBOSE_OUTPUT osg::notify(osg::NOTICE)<<"kdTree->_kdNodes.reserve()="<size(); unsigned int estimatedNumTriangles = vertices->size()*2; _primitiveIndices.reserve(estimatedNumTriangles); _boundingBoxes.reserve(estimatedNumTriangles); _triangles.reserve(estimatedNumTriangles); _centers.reserve(estimatedNumTriangles); osg::TriangleIndexFunctor collectTriangleIndices; collectTriangleIndices._kdTree = this; geometry->accept(collectTriangleIndices); _primitiveIndices.reserve(vertices->size()); KdLeaf leaf(0, _primitiveIndices.size()); int leafNum = addLeaf(leaf); osg::BoundingBox bb = _bb; int nodeNum = divide(options, bb, leafNum, 0); #ifdef VERBOSE_OUTPUT osg::notify(osg::NOTICE)<<"Root nodeNum="<=dimensions[1]) { if (dimensions[0]>=dimensions[2]) axis = 0; else axis = 2; } else if (dimensions[1]>=dimensions[2]) axis = 1; else axis = 2; _axisStack.push_back(axis); dimensions[axis] /= 2.0f; #ifdef VERBOSE_OUTPUT osg::notify(osg::NOTICE)<<" "<mid)) { --right; } while(leftmid)) { --right; } if (left=0.0f) { if (ds12<0.0f) continue; if (ds12>d312) continue; } else // d312 < 0 { if (ds12>0.0f) continue; if (ds12=0.0f) { if (ds23<0.0f) continue; if (ds23>d123) continue; } else // d123 < 0 { if (ds23>0.0f) continue; if (ds23=0.0f) { if (ds31<0.0f) continue; if (ds31>d231) continue; } else // d231 < 0 { if (ds31>0.0f) continue; if (ds31_length) continue; osg::Vec3 normal = v12^v23; normal.normalize(); float r = d/_length; LineSegmentIntersection intersection; intersection.ratio = r; intersection.primitiveIndex = _primitiveIndices[i]; intersection.intersectionPoint = in; intersection.intersectionNormal = normal; intersection.indexList.push_back(tri._p1); intersection.indexList.push_back(tri._p2); intersection.indexList.push_back(tri._p3); intersection.ratioList.push_back(r1); intersection.ratioList.push_back(r2); intersection.ratioList.push_back(r3); intersections.insert(intersection); osg::notify(osg::NOTICE)<<" got intersection ("<asGeometry(); if (geom) { osg::KdTree* previous = dynamic_cast(geom->getShape()); if (previous) continue; osg::ref_ptr kdTree = dynamic_cast(_kdTreePrototype->cloneType()); if (kdTree->build(_buildOptions, geom)) { geom->setShape(kdTree.get()); } } } }