Initial work on adding KdTree support for PolytopeIntersector.
This commit is contained in:
@@ -158,6 +158,32 @@ class OSG_EXPORT KdTree : public osg::Shape
|
||||
TriangleList& getTriangles() { return _triangles; }
|
||||
const TriangleList& getTriangles() const { return _triangles; }
|
||||
|
||||
template<class IntersectFunctor>
|
||||
void intersect(IntersectFunctor& functor, const KdNode& node) const
|
||||
{
|
||||
if (node.first<0)
|
||||
{
|
||||
// treat as a leaf
|
||||
int istart = -node.first-1;
|
||||
int iend = istart + node.second;
|
||||
|
||||
for(int i=istart; i<iend; ++i)
|
||||
{
|
||||
const KdTree::Triangle& tri = _triangles[i];
|
||||
|
||||
// OSG_NOTICE<<" tri("<<tri.p1<<","<<tri.p2<<","<<tri.p3<<")"<<std::endl;
|
||||
|
||||
functor.intersect(_vertices.get(), i, tri.p0, tri.p1, tri.p2);
|
||||
}
|
||||
}
|
||||
else if (functor.intersect(node.bb))
|
||||
{
|
||||
if (node.first>0) intersect(functor, _kdNodes[node.first]);
|
||||
if (node.second>0) intersect(functor, _kdNodes[node.second]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -358,6 +358,9 @@ class OSG_EXPORT Polytope
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Check whether any part of a triangle is contained within the polytope.*/
|
||||
bool contains(const osg::Vec3f& v0, const osg::Vec3f& v1, const osg::Vec3f& v2) const;
|
||||
|
||||
|
||||
/** Transform the clipping set by matrix. Note, this operations carries out
|
||||
* the calculation of the inverse of the matrix since a plane must
|
||||
|
||||
@@ -44,6 +44,13 @@ class OSGUTIL_EXPORT PolytopeIntersector : public Intersector
|
||||
* In VIEW and MODEL coordinates (clip space cube) creates a five sided polytope box that has a front face at 0.0 and sides around box xMin, yMin, xMax, yMax.*/
|
||||
PolytopeIntersector(CoordinateFrame cf, double xMin, double yMin, double xMax, double yMax);
|
||||
|
||||
/** Get the Polytope used by the intersector.*/
|
||||
osg::Polytope& getPolytope() { return _polytope;}
|
||||
|
||||
/** Get the const Polytope used by the intersector.*/
|
||||
const osg::Polytope& getPolytope() const { return _polytope;}
|
||||
|
||||
|
||||
typedef osg::Plane::Vec3_type Vec3_type;
|
||||
|
||||
struct Intersection
|
||||
|
||||
@@ -338,6 +338,7 @@ SET(TARGET_SRC
|
||||
PolygonMode.cpp
|
||||
PolygonOffset.cpp
|
||||
PolygonStipple.cpp
|
||||
Polytope.cpp
|
||||
PositionAttitudeTransform.cpp
|
||||
PrimitiveSet.cpp
|
||||
PrimitiveRestartIndex.cpp
|
||||
|
||||
26
src/osg/Polytope.cpp
Normal file
26
src/osg/Polytope.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 20017 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 <osg/Polytope>
|
||||
#include <osg/Notify>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
bool Polytope::contains(const osg::Vec3f& v0, const osg::Vec3f& v1, const osg::Vec3f& v2) const
|
||||
{
|
||||
if (contains(v0)) return true;
|
||||
if (contains(v1)) return true;
|
||||
if (contains(v2)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <osgUtil/PolytopeIntersector>
|
||||
|
||||
#include <osg/Geometry>
|
||||
#include <osg/KdTree>
|
||||
#include <osg/Notify>
|
||||
#include <osg/io_utils>
|
||||
#include <osg/TemplatePrimitiveFunctor>
|
||||
@@ -561,6 +562,69 @@ void PolytopeIntersector::leave()
|
||||
// do nothing.
|
||||
}
|
||||
|
||||
struct IntersectFunctor
|
||||
{
|
||||
|
||||
IntersectFunctor(osgUtil::PolytopeIntersector* pi):
|
||||
_polytopeIntersector(pi),
|
||||
_numHits(0),
|
||||
_numMisses(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
struct Hit
|
||||
{
|
||||
Hit(int in_pi, unsigned int in_p0, unsigned int in_p1, unsigned int in_p2):
|
||||
primitiveIndex(in_pi),
|
||||
p0(in_p0),
|
||||
p1(in_p1),
|
||||
p2(in_p2) {}
|
||||
|
||||
Hit():
|
||||
primitiveIndex(0),
|
||||
p0(0),
|
||||
p1(0),
|
||||
p2(0) {}
|
||||
|
||||
|
||||
int primitiveIndex;
|
||||
unsigned int p0;
|
||||
unsigned int p1;
|
||||
unsigned int p2;
|
||||
};
|
||||
|
||||
typedef std::vector<Hit> Hits;
|
||||
|
||||
bool intersect(const osg::BoundingBox& bb)
|
||||
{
|
||||
return _polytopeIntersector->getPolytope().contains(bb);
|
||||
}
|
||||
|
||||
bool intersect(const osg::Vec3Array* vertices, int i, unsigned int p0, unsigned int p1, unsigned int p2)
|
||||
{
|
||||
if (_polytopeIntersector->getPolytope().contains((*vertices)[p0], (*vertices)[p1], (*vertices)[p2]))
|
||||
{
|
||||
++_numHits;
|
||||
|
||||
_hits.push_back(Hit(i, p0, p1, p2));
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
++_numMisses;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
osgUtil::PolytopeIntersector* _polytopeIntersector;
|
||||
Hits _hits;
|
||||
unsigned int _numHits;
|
||||
unsigned int _numMisses;
|
||||
};
|
||||
|
||||
|
||||
void PolytopeIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable)
|
||||
{
|
||||
@@ -568,6 +632,36 @@ void PolytopeIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawa
|
||||
|
||||
if ( !_polytope.contains( drawable->getBoundingBox() ) ) return;
|
||||
|
||||
osg::KdTree* kdTree = iv.getUseKdTreeWhenAvailable() ? dynamic_cast<osg::KdTree*>(drawable->getShape()) : 0;
|
||||
if (kdTree)
|
||||
{
|
||||
|
||||
IntersectFunctor intersector(this);
|
||||
kdTree->intersect(intersector, kdTree->getNode(0));
|
||||
|
||||
for(IntersectFunctor::Hits::iterator itr = intersector._hits.begin();
|
||||
itr != intersector._hits.end();
|
||||
++itr)
|
||||
{
|
||||
IntersectFunctor::Hit& hit = *itr;
|
||||
|
||||
Intersection intersection;
|
||||
intersection.primitiveIndex = hit.primitiveIndex;
|
||||
intersection.nodePath = iv.getNodePath();
|
||||
intersection.drawable = drawable;
|
||||
intersection.matrix = iv.getModelMatrix();
|
||||
|
||||
//OSG_NOTICE<<"Inserting intersection.primitiveIndex="<<intersection.primitiveIndex<<std::endl;
|
||||
|
||||
insertIntersection(intersection);
|
||||
}
|
||||
|
||||
//OSG_NOTICE<<"NumHits "<<intersector._numHits<<std::endl;
|
||||
//OSG_NOTICE<<"NumMisses "<<intersector._numMisses<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
osg::TemplatePrimitiveFunctor<PolytopeIntersectorUtils::PolytopePrimitiveIntersector> func;
|
||||
func.setPolytope( _polytope, _referencePlane );
|
||||
func.setDimensionMask( _dimensionMask );
|
||||
|
||||
Reference in New Issue
Block a user