You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
5.7 KiB
198 lines
5.7 KiB
/* -*-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. |
|
*/ |
|
|
|
#ifndef OSG_KDTREE |
|
#define OSG_KDTREE 1 |
|
|
|
#include <osg/Shape> |
|
#include <osg/Geometry> |
|
|
|
#include <map> |
|
|
|
namespace osg |
|
{ |
|
|
|
/** Implementation of a kdtree for Geometry leaves, to enable fast intersection tests.*/ |
|
class OSG_EXPORT KdTree : public osg::Shape |
|
{ |
|
public: |
|
|
|
|
|
KdTree(); |
|
|
|
KdTree(const KdTree& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); |
|
|
|
META_Shape(osg, KdTree) |
|
|
|
struct OSG_EXPORT BuildOptions |
|
{ |
|
BuildOptions(); |
|
|
|
unsigned int _numVerticesProcessed; |
|
unsigned int _targetNumTrianglesPerLeaf; |
|
unsigned int _maxNumLevels; |
|
}; |
|
|
|
|
|
/** Build the kdtree from the specified source geometry object. |
|
* retun true on success. */ |
|
virtual bool build(BuildOptions& buildOptions, osg::Geometry* geometry); |
|
|
|
struct LineSegmentIntersection |
|
{ |
|
LineSegmentIntersection(): |
|
ratio(-1.0), |
|
p0(0), |
|
p1(0), |
|
p2(0), |
|
r0(0.0f), |
|
r1(0.0f), |
|
r2(0.0f), |
|
primitiveIndex(0) {} |
|
|
|
bool operator < (const LineSegmentIntersection& rhs) const { return ratio < rhs.ratio; } |
|
|
|
typedef std::vector<unsigned int> IndexList; |
|
typedef std::vector<double> RatioList; |
|
|
|
double ratio; |
|
osg::Vec3d intersectionPoint; |
|
osg::Vec3 intersectionNormal; |
|
|
|
unsigned int p0; |
|
unsigned int p1; |
|
unsigned int p2; |
|
float r0; |
|
float r1; |
|
float r2; |
|
|
|
unsigned int primitiveIndex; |
|
}; |
|
|
|
|
|
typedef std::vector<LineSegmentIntersection> LineSegmentIntersections; |
|
|
|
/** compute the intersection of a line segment and the kdtree, return true if an intersection has been found.*/ |
|
virtual bool intersect(const osg::Vec3d& start, const osg::Vec3d& end, LineSegmentIntersections& intersections) const; |
|
|
|
|
|
typedef int value_type; |
|
|
|
struct KdNode |
|
{ |
|
KdNode(): |
|
first(0), |
|
second(0) {} |
|
|
|
KdNode(value_type f, value_type s): |
|
first(f), |
|
second(s) {} |
|
|
|
osg::BoundingBox bb; |
|
|
|
value_type first; |
|
value_type second; |
|
}; |
|
|
|
struct Triangle |
|
{ |
|
Triangle(): |
|
p0(0),p1(0),p2(0) {} |
|
|
|
Triangle(unsigned int ip0, unsigned int ip1, unsigned int ip2): |
|
p0(ip0), p1(ip1), p2(ip2) {} |
|
|
|
bool operator < (const Triangle& rhs) const |
|
{ |
|
if (p0<rhs.p0) return true; |
|
if (p0>rhs.p0) return false; |
|
if (p1<rhs.p1) return true; |
|
if (p1>rhs.p1) return false; |
|
return p2<rhs.p2; |
|
} |
|
|
|
unsigned int p0; |
|
unsigned int p1; |
|
unsigned int p2; |
|
}; |
|
|
|
typedef std::vector< KdNode > KdNodeList; |
|
typedef std::vector< Triangle > TriangleList; |
|
|
|
int addNode(const KdNode& node) |
|
{ |
|
int num = static_cast<int>(_kdNodes.size()); |
|
_kdNodes.push_back(node); |
|
return num; |
|
} |
|
|
|
KdNode& getNode(int nodeNum) { return _kdNodes[nodeNum]; } |
|
const KdNode& getNode(int nodeNum) const { return _kdNodes[nodeNum]; } |
|
|
|
KdNodeList& getNodes() { return _kdNodes; } |
|
const KdNodeList& getNodes() const { return _kdNodes; } |
|
|
|
void setVertices(osg::Vec3Array* vertices) { _vertices = vertices; } |
|
const osg::Vec3Array* getVertices() const { return _vertices.get(); } |
|
|
|
unsigned int addTriangle(const Triangle& tri) |
|
{ |
|
unsigned int num = static_cast<unsigned int>(_triangles.size()); |
|
_triangles.push_back(tri); |
|
return num; |
|
} |
|
|
|
Triangle& getTriangle(unsigned int i) { return _triangles[i]; } |
|
const Triangle& getTriangle(unsigned int i) const { return _triangles[i]; } |
|
|
|
TriangleList& getTriangles() { return _triangles; } |
|
const TriangleList& getTriangles() const { return _triangles; } |
|
|
|
|
|
protected: |
|
|
|
osg::ref_ptr<osg::Vec3Array> _vertices; |
|
KdNodeList _kdNodes; |
|
TriangleList _triangles; |
|
|
|
}; |
|
|
|
class OSG_EXPORT KdTreeBuilder : public osg::NodeVisitor |
|
{ |
|
public: |
|
|
|
KdTreeBuilder(); |
|
|
|
KdTreeBuilder(const KdTreeBuilder& rhs); |
|
|
|
META_NodeVisitor("osg","KdTreeBuilder") |
|
|
|
virtual KdTreeBuilder* clone() { return new KdTreeBuilder(*this); } |
|
|
|
void apply(osg::Geode& geode); |
|
|
|
KdTree::BuildOptions _buildOptions; |
|
|
|
osg::ref_ptr<osg::KdTree> _kdTreePrototype; |
|
|
|
|
|
|
|
protected: |
|
|
|
virtual ~KdTreeBuilder() {} |
|
|
|
}; |
|
|
|
} |
|
|
|
#endif
|
|
|