From a2e79f6a3842423996ae9b4bdb501a2de0865ca0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 28 Nov 2006 16:30:38 +0000 Subject: [PATCH] Moved osgUtil::PolytopeIntersector, osgUtil::PlaneIntersector and osgUtil::LineSegmentIntersector out from include/osgUtil/IntersecionVisitor into their own seperate files. --- VisualStudio/osgUtil/osgUtil.dsp | 22 +- examples/osgintersection/osgintersection.cpp | 1 + .../osgkeyboardmouse/osgkeyboardmouse.cpp | 2 + include/osgUtil/IntersectionVisitor | 199 ----- include/osgUtil/LineSegmentIntersector | 99 +++ include/osgUtil/PlaneIntersector | 85 +++ include/osgUtil/PolytopeIntersector | 90 +++ src/osgSim/ElevationSlice.cpp | 1 + src/osgSim/HeightAboveTerrain.cpp | 1 + src/osgSim/LineOfSight.cpp | 2 +- src/osgUtil/GNUmakefile | 3 + src/osgUtil/IntersectionVisitor.cpp | 705 ------------------ src/osgUtil/LineSegmentIntersector.cpp | 497 ++++++++++++ src/osgUtil/PlaneIntersector.cpp | 124 +++ src/osgUtil/PolytopeIntersector.cpp | 140 ++++ 15 files changed, 1065 insertions(+), 906 deletions(-) create mode 100644 include/osgUtil/LineSegmentIntersector create mode 100644 include/osgUtil/PlaneIntersector create mode 100644 include/osgUtil/PolytopeIntersector create mode 100644 src/osgUtil/LineSegmentIntersector.cpp create mode 100644 src/osgUtil/PlaneIntersector.cpp create mode 100644 src/osgUtil/PolytopeIntersector.cpp diff --git a/VisualStudio/osgUtil/osgUtil.dsp b/VisualStudio/osgUtil/osgUtil.dsp index ecbf3960b..4fc4bc212 100755 --- a/VisualStudio/osgUtil/osgUtil.dsp +++ b/VisualStudio/osgUtil/osgUtil.dsp @@ -187,7 +187,15 @@ SOURCE=..\..\src\osgUtil\IntersectVisitor.cpp # End Source File # Begin Source File -SOURCE=..\..\src\osgUtil\IntersectionVisitor.cpp +SOURCE=..\..\src\osgUtil\LineSegmentIntersector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\osgUtil\PlaneIntersector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\osgUtil\PolytopeIntersector.cpp # End Source File # Begin Source File @@ -303,6 +311,18 @@ SOURCE=..\..\Include\osgUtil\IntersectionVisitor # End Source File # Begin Source File +SOURCE=..\..\Include\osgUtil\LineSegmentIntersector +# End Source File +# Begin Source File + +SOURCE=..\..\Include\osgUtil\PlaneIntersector +# End Source File +# Begin Source File + +SOURCE=..\..\Include\osgUtil\PolytopeIntersector +# End Source File +# Begin Source File + SOURCE=..\..\include\osgUtil\Optimizer # End Source File # Begin Source File diff --git a/examples/osgintersection/osgintersection.cpp b/examples/osgintersection/osgintersection.cpp index 498595d4c..334b3baf3 100644 --- a/examples/osgintersection/osgintersection.cpp +++ b/examples/osgintersection/osgintersection.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include diff --git a/examples/osgkeyboardmouse/osgkeyboardmouse.cpp b/examples/osgkeyboardmouse/osgkeyboardmouse.cpp index f0939afc7..9976ab448 100644 --- a/examples/osgkeyboardmouse/osgkeyboardmouse.cpp +++ b/examples/osgkeyboardmouse/osgkeyboardmouse.cpp @@ -12,6 +12,8 @@ #include #include +#include +#include #include #include diff --git a/include/osgUtil/IntersectionVisitor b/include/osgUtil/IntersectionVisitor index b6d827089..de8029bba 100644 --- a/include/osgUtil/IntersectionVisitor +++ b/include/osgUtil/IntersectionVisitor @@ -76,205 +76,6 @@ class Intersector : public osg::Referenced }; -/** Concrent class for implementing line intersections with the scene graph. - * To be used in conjunction with IntersectionVisitor. */ -class OSGUTIL_EXPORT LineSegmentIntersector : public Intersector -{ - public: - - /** Construct a LineSegmentIntersector the runs between the secified start and end points in MODEL coordinates. */ - LineSegmentIntersector(const osg::Vec3d& start, const osg::Vec3d& end); - - /** Construct a LineSegmentIntersector the runs between the secified start and end points in the specified coordinate frame. */ - LineSegmentIntersector(CoordinateFrame cf, const osg::Vec3d& start, const osg::Vec3d& end); - - /** Convinience constructor for supporting picking in WINDOW, or PROJECTION coorindates - * In WINDOW coordinates creates a start value of (x,y,0) and end value of (x,y,1). - * In PROJECTION coordinates (clip space cube) creates a start value of (x,y,1) and end value of (x,y,-1). - * In VIEW and MODEL coordinates creates a start value of (x,y,0) and end value of (x,y,1).*/ - LineSegmentIntersector(CoordinateFrame cf, double x, double y); - - struct Intersection - { - Intersection(): - ratio(-1.0), - primitiveIndex(0) {} - - bool operator < (const Intersection& rhs) const { return ratio < rhs.ratio; } - - typedef std::vector IndexList; - - double ratio; - osg::NodePath nodePath; - osg::ref_ptr drawable; - osg::ref_ptr matrix; - osg::Vec3d localIntersectionPoint; - osg::Vec3 localIntersectionNormal; - IndexList indexList; - unsigned int primitiveIndex; - }; - - typedef std::multiset Intersections; - - inline void insertIntersection(const Intersection& intersection) { getIntersections().insert(intersection); } - - inline Intersections& getIntersections() { return _parent ? _parent->_intersections : _intersections; } - - inline Intersection getFirstIntersection() { Intersections& intersections = getIntersections(); return intersections.empty() ? Intersection() : *(intersections.begin()); } - - public: - - virtual Intersector* clone(osgUtil::IntersectionVisitor& iv); - - virtual bool enter(const osg::Node& node); - - virtual void leave(); - - virtual void intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable); - - virtual void reset(); - - virtual bool containsIntersections() { return !_intersections.empty(); } - - protected: - - bool intersects(const osg::BoundingSphere& bs); - bool intersectAndClip(osg::Vec3d& s, osg::Vec3d& e,const osg::BoundingBox& bb); - - LineSegmentIntersector* _parent; - - osg::Vec3d _start; - osg::Vec3d _end; - - Intersections _intersections; - -}; - -/** Concrent class for implementing polytope intersections with the scene graph. - * To be used in conjunction with IntersectionVisitor. */ -class OSGUTIL_EXPORT PolytopeIntersector : public Intersector -{ - public: - - /** Construct a PolytopeIntersector using speified polytope in MODEL coordinates.*/ - PolytopeIntersector(const osg::Polytope& polytope); - - /** Construct a PolytopeIntersector using speified polytope in specified coordinate frame.*/ - PolytopeIntersector(CoordinateFrame cf, const osg::Polytope& polytope); - - /** Convinience constructor for supporting picking in WINDOW, or PROJECTION coorindates - * In WINDOW 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. - * In PROJECTION coordinates (clip space cube) creates a five sided polytope box that has a front face at -1 and sides around box xMin, yMin, xMax, yMax. - * 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); - - struct Intersection - { - Intersection() {} - - bool operator < (const Intersection& rhs) const - { - if (nodePath < rhs.nodePath) return true; - if (rhs.nodePath < nodePath ) return false; - return (drawable < rhs.drawable); - } - - osg::NodePath nodePath; - osg::ref_ptr drawable; - }; - - typedef std::set Intersections; - - inline void insertIntersection(const Intersection& intersection) { getIntersections().insert(intersection); } - - inline Intersections& getIntersections() { return _parent ? _parent->_intersections : _intersections; } - - inline Intersection getFirstIntersection() { Intersections& intersections = getIntersections(); return intersections.empty() ? Intersection() : *(intersections.begin()); } - - public: - - virtual Intersector* clone(osgUtil::IntersectionVisitor& iv); - - virtual bool enter(const osg::Node& node); - - virtual void leave(); - - virtual void intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable); - - virtual void reset(); - - virtual bool containsIntersections() { return !_intersections.empty(); } - - protected: - - PolytopeIntersector* _parent; - - osg::Polytope _polytope; - - Intersections _intersections; - -}; - -/** Concrent class for implementing polytope intersections with the scene graph. - * To be used in conjunction with IntersectionVisitor. */ -class OSGUTIL_EXPORT PlaneIntersector : public Intersector -{ - public: - - /** Construct a PolytopeIntersector using speified polytope in MODEL coordinates.*/ - PlaneIntersector(const osg::Plane& plane, const osg::Polytope& boundingPolytope=osg::Polytope()); - - /** Construct a PolytopeIntersector using speified polytope in specified coordinate frame.*/ - PlaneIntersector(CoordinateFrame cf, const osg::Plane& plane, const osg::Polytope& boundingPolytope=osg::Polytope()); - - struct Intersection - { - Intersection() {} - - bool operator < (const Intersection& rhs) const - { - if (nodePath < rhs.nodePath) return true; - if (rhs.nodePath < nodePath ) return false; - return (drawable < rhs.drawable); - } - - osg::NodePath nodePath; - osg::ref_ptr drawable; - }; - - typedef std::set Intersections; - - inline void insertIntersection(const Intersection& intersection) { getIntersections().insert(intersection); } - - inline Intersections& getIntersections() { return _parent ? _parent->_intersections : _intersections; } - - inline Intersection getFirstIntersection() { Intersections& intersections = getIntersections(); return intersections.empty() ? Intersection() : *(intersections.begin()); } - - public: - - virtual Intersector* clone(osgUtil::IntersectionVisitor& iv); - - virtual bool enter(const osg::Node& node); - - virtual void leave(); - - virtual void intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable); - - virtual void reset(); - - virtual bool containsIntersections() { return !_intersections.empty(); } - - protected: - - PlaneIntersector* _parent; - - osg::Plane _plane; - osg::Polytope _polytope; - - Intersections _intersections; - -}; - /** Concrent class for passing multiple intersectors through the scene graph. * To be used in conjunction with IntersectionVisitor. */ diff --git a/include/osgUtil/LineSegmentIntersector b/include/osgUtil/LineSegmentIntersector new file mode 100644 index 000000000..113bdaf9a --- /dev/null +++ b/include/osgUtil/LineSegmentIntersector @@ -0,0 +1,99 @@ +/* -*-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 OSGUTIL_LINESEGMENTINTERSECTOR +#define OSGUTIL_LINESEGMENTINTERSECTOR 1 + +#include + +namespace osgUtil +{ + +/** Concrent class for implementing line intersections with the scene graph. + * To be used in conjunction with IntersectionVisitor. */ +class OSGUTIL_EXPORT LineSegmentIntersector : public Intersector +{ + public: + + /** Construct a LineSegmentIntersector the runs between the secified start and end points in MODEL coordinates. */ + LineSegmentIntersector(const osg::Vec3d& start, const osg::Vec3d& end); + + /** Construct a LineSegmentIntersector the runs between the secified start and end points in the specified coordinate frame. */ + LineSegmentIntersector(CoordinateFrame cf, const osg::Vec3d& start, const osg::Vec3d& end); + + /** Convinience constructor for supporting picking in WINDOW, or PROJECTION coorindates + * In WINDOW coordinates creates a start value of (x,y,0) and end value of (x,y,1). + * In PROJECTION coordinates (clip space cube) creates a start value of (x,y,1) and end value of (x,y,-1). + * In VIEW and MODEL coordinates creates a start value of (x,y,0) and end value of (x,y,1).*/ + LineSegmentIntersector(CoordinateFrame cf, double x, double y); + + struct Intersection + { + Intersection(): + ratio(-1.0), + primitiveIndex(0) {} + + bool operator < (const Intersection& rhs) const { return ratio < rhs.ratio; } + + typedef std::vector IndexList; + + double ratio; + osg::NodePath nodePath; + osg::ref_ptr drawable; + osg::ref_ptr matrix; + osg::Vec3d localIntersectionPoint; + osg::Vec3 localIntersectionNormal; + IndexList indexList; + unsigned int primitiveIndex; + }; + + typedef std::multiset Intersections; + + inline void insertIntersection(const Intersection& intersection) { getIntersections().insert(intersection); } + + inline Intersections& getIntersections() { return _parent ? _parent->_intersections : _intersections; } + + inline Intersection getFirstIntersection() { Intersections& intersections = getIntersections(); return intersections.empty() ? Intersection() : *(intersections.begin()); } + + public: + + virtual Intersector* clone(osgUtil::IntersectionVisitor& iv); + + virtual bool enter(const osg::Node& node); + + virtual void leave(); + + virtual void intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable); + + virtual void reset(); + + virtual bool containsIntersections() { return !_intersections.empty(); } + + protected: + + bool intersects(const osg::BoundingSphere& bs); + bool intersectAndClip(osg::Vec3d& s, osg::Vec3d& e,const osg::BoundingBox& bb); + + LineSegmentIntersector* _parent; + + osg::Vec3d _start; + osg::Vec3d _end; + + Intersections _intersections; + +}; + +} + +#endif + diff --git a/include/osgUtil/PlaneIntersector b/include/osgUtil/PlaneIntersector new file mode 100644 index 000000000..223b9966d --- /dev/null +++ b/include/osgUtil/PlaneIntersector @@ -0,0 +1,85 @@ +/* -*-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 OSGUTIL_PLANEINTERSECTOR +#define OSGUTIL_PLANEINTERSECTOR 1 + +#include + +namespace osgUtil +{ + +/** Concrent class for implementing polytope intersections with the scene graph. + * To be used in conjunction with IntersectionVisitor. */ +class OSGUTIL_EXPORT PlaneIntersector : public Intersector +{ + public: + + /** Construct a PolytopeIntersector using speified polytope in MODEL coordinates.*/ + PlaneIntersector(const osg::Plane& plane, const osg::Polytope& boundingPolytope=osg::Polytope()); + + /** Construct a PolytopeIntersector using speified polytope in specified coordinate frame.*/ + PlaneIntersector(CoordinateFrame cf, const osg::Plane& plane, const osg::Polytope& boundingPolytope=osg::Polytope()); + + struct Intersection + { + Intersection() {} + + bool operator < (const Intersection& rhs) const + { + if (nodePath < rhs.nodePath) return true; + if (rhs.nodePath < nodePath ) return false; + return (drawable < rhs.drawable); + } + + osg::NodePath nodePath; + osg::ref_ptr drawable; + }; + + typedef std::set Intersections; + + inline void insertIntersection(const Intersection& intersection) { getIntersections().insert(intersection); } + + inline Intersections& getIntersections() { return _parent ? _parent->_intersections : _intersections; } + + inline Intersection getFirstIntersection() { Intersections& intersections = getIntersections(); return intersections.empty() ? Intersection() : *(intersections.begin()); } + + public: + + virtual Intersector* clone(osgUtil::IntersectionVisitor& iv); + + virtual bool enter(const osg::Node& node); + + virtual void leave(); + + virtual void intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable); + + virtual void reset(); + + virtual bool containsIntersections() { return !_intersections.empty(); } + + protected: + + PlaneIntersector* _parent; + + osg::Plane _plane; + osg::Polytope _polytope; + + Intersections _intersections; + +}; + +} + +#endif + diff --git a/include/osgUtil/PolytopeIntersector b/include/osgUtil/PolytopeIntersector new file mode 100644 index 000000000..1e210501e --- /dev/null +++ b/include/osgUtil/PolytopeIntersector @@ -0,0 +1,90 @@ +/* -*-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 OSGUTIL_POLYTOPEINTERSECTOR +#define OSGUTIL_POLYTOPEINTERSECTOR 1 + +#include + +namespace osgUtil +{ + +/** Concrent class for implementing polytope intersections with the scene graph. + * To be used in conjunction with IntersectionVisitor. */ +class OSGUTIL_EXPORT PolytopeIntersector : public Intersector +{ + public: + + /** Construct a PolytopeIntersector using speified polytope in MODEL coordinates.*/ + PolytopeIntersector(const osg::Polytope& polytope); + + /** Construct a PolytopeIntersector using speified polytope in specified coordinate frame.*/ + PolytopeIntersector(CoordinateFrame cf, const osg::Polytope& polytope); + + /** Convinience constructor for supporting picking in WINDOW, or PROJECTION coorindates + * In WINDOW 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. + * In PROJECTION coordinates (clip space cube) creates a five sided polytope box that has a front face at -1 and sides around box xMin, yMin, xMax, yMax. + * 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); + + struct Intersection + { + Intersection() {} + + bool operator < (const Intersection& rhs) const + { + if (nodePath < rhs.nodePath) return true; + if (rhs.nodePath < nodePath ) return false; + return (drawable < rhs.drawable); + } + + osg::NodePath nodePath; + osg::ref_ptr drawable; + }; + + typedef std::set Intersections; + + inline void insertIntersection(const Intersection& intersection) { getIntersections().insert(intersection); } + + inline Intersections& getIntersections() { return _parent ? _parent->_intersections : _intersections; } + + inline Intersection getFirstIntersection() { Intersections& intersections = getIntersections(); return intersections.empty() ? Intersection() : *(intersections.begin()); } + + public: + + virtual Intersector* clone(osgUtil::IntersectionVisitor& iv); + + virtual bool enter(const osg::Node& node); + + virtual void leave(); + + virtual void intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable); + + virtual void reset(); + + virtual bool containsIntersections() { return !_intersections.empty(); } + + protected: + + PolytopeIntersector* _parent; + + osg::Polytope _polytope; + + Intersections _intersections; + +}; + +} + +#endif + diff --git a/src/osgSim/ElevationSlice.cpp b/src/osgSim/ElevationSlice.cpp index dc4dd22de..c662df084 100644 --- a/src/osgSim/ElevationSlice.cpp +++ b/src/osgSim/ElevationSlice.cpp @@ -15,6 +15,7 @@ #include #include +#include using namespace osgSim; diff --git a/src/osgSim/HeightAboveTerrain.cpp b/src/osgSim/HeightAboveTerrain.cpp index 1a28935ea..37ac2e865 100644 --- a/src/osgSim/HeightAboveTerrain.cpp +++ b/src/osgSim/HeightAboveTerrain.cpp @@ -15,6 +15,7 @@ #include #include +#include using namespace osgSim; diff --git a/src/osgSim/LineOfSight.cpp b/src/osgSim/LineOfSight.cpp index c8b8892ae..85d4c3140 100644 --- a/src/osgSim/LineOfSight.cpp +++ b/src/osgSim/LineOfSight.cpp @@ -14,8 +14,8 @@ #include #include - #include +#include using namespace osgSim; diff --git a/src/osgUtil/GNUmakefile b/src/osgUtil/GNUmakefile index bffdb8c1b..2bf2509d0 100644 --- a/src/osgUtil/GNUmakefile +++ b/src/osgUtil/GNUmakefile @@ -11,6 +11,9 @@ CXXFILES = \ HalfWayMapGenerator.cpp\ HighlightMapGenerator.cpp\ IntersectionVisitor.cpp\ + LineSegmentIntersector.cpp\ + PlaneIntersector.cpp\ + PolytopeIntersector.cpp\ IntersectVisitor.cpp\ Optimizer.cpp\ RenderBin.cpp\ diff --git a/src/osgUtil/IntersectionVisitor.cpp b/src/osgUtil/IntersectionVisitor.cpp index 13cea9549..04b02f0cf 100644 --- a/src/osgUtil/IntersectionVisitor.cpp +++ b/src/osgUtil/IntersectionVisitor.cpp @@ -23,715 +23,10 @@ #include #include #include -#include using namespace osgUtil; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// LineSegmentIntersector -// - - -struct TriangleIntersection -{ - TriangleIntersection(unsigned int index, const osg::Vec3& normal, float r1, const osg::Vec3* v1, float r2, const osg::Vec3* v2, float r3, const osg::Vec3* v3): - _index(index), - _normal(normal), - _r1(r1), - _v1(v1), - _r2(r2), - _v2(v2), - _r3(r3), - _v3(v3) {} - - unsigned int _index; - const osg::Vec3 _normal; - float _r1; - const osg::Vec3* _v1; - float _r2; - const osg::Vec3* _v2; - float _r3; - const osg::Vec3* _v3; -}; - - -struct TriangleIntersector -{ - osg::Vec3 _s; - osg::Vec3 _d; - float _length; - - int _index; - float _ratio; - bool _hit; - - typedef std::multimap TriangleIntersections; - - TriangleIntersections _intersections; - - TriangleIntersector() - { - } - - TriangleIntersector(const osg::Vec3d& start, osg::Vec3d& end, float ratio=FLT_MAX) - { - set(start,end,ratio); - } - - void set(const osg::Vec3d& start, osg::Vec3d& end, float ratio=FLT_MAX) - { - _hit=false; - _index = 0; - _ratio = ratio; - - _s = start; - _d = end - start; - _length = _d.length(); - _d /= _length; - } - - // bool intersect(const Vec3& v1,const Vec3& v2,const Vec3& v3,float& r) - inline void operator () (const osg::Vec3& v1,const osg::Vec3& v2,const osg::Vec3& v3, bool treatVertexDataAsTemporary) - { - ++_index; - - if (v1==v2 || v2==v3 || v1==v3) return; - - osg::Vec3 v12 = v2-v1; - osg::Vec3 n12 = v12^_d; - float ds12 = (_s-v1)*n12; - float d312 = (v3-v1)*n12; - if (d312>=0.0f) - { - if (ds12<0.0f) return; - if (ds12>d312) return; - } - else // d312 < 0 - { - if (ds12>0.0f) return; - if (ds12=0.0f) - { - if (ds23<0.0f) return; - if (ds23>d123) return; - } - else // d123 < 0 - { - if (ds23>0.0f) return; - if (ds23=0.0f) - { - if (ds31<0.0f) return; - if (ds31>d231) return; - } - else // d231 < 0 - { - if (ds31>0.0f) return; - if (ds31_length) return; - - osg::Vec3 normal = v12^v23; - normal.normalize(); - - float r = d/_length; - - - if (treatVertexDataAsTemporary) - { - _intersections.insert(std::pair(r,TriangleIntersection(_index-1,normal,r1,0,r2,0,r3,0))); - } - else - { - _intersections.insert(std::pair(r,TriangleIntersection(_index-1,normal,r1,&v1,r2,&v2,r3,&v3))); - } - _hit = true; - - } - -}; - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// LineSegmentIntersector -// - -LineSegmentIntersector::LineSegmentIntersector(const osg::Vec3d& start, const osg::Vec3d& end): - _parent(0), - _start(start), - _end(end) -{ -} - -LineSegmentIntersector::LineSegmentIntersector(CoordinateFrame cf, const osg::Vec3d& start, const osg::Vec3d& end): - Intersector(cf), - _parent(0), - _start(start), - _end(end) -{ -} - -LineSegmentIntersector::LineSegmentIntersector(CoordinateFrame cf, double x, double y): - Intersector(cf), - _parent(0) -{ - switch(cf) - { - case WINDOW : _start.set(x,y,0.0); _end.set(x,y,1.0); break; - case PROJECTION : _start.set(x,y,1.0); _end.set(x,y,-1.0); break; - case VIEW : _start.set(x,y,0.0); _end.set(x,y,1.0); break; - case MODEL : _start.set(x,y,0.0); _end.set(x,y,1.0); break; - } -} - -Intersector* LineSegmentIntersector::clone(osgUtil::IntersectionVisitor& iv) -{ - if (_coordinateFrame==MODEL && iv.getModelMatrix()==0) - { - osg::ref_ptr lsi = new LineSegmentIntersector(_start, _end); - lsi->_parent = this; - return lsi.release(); - } - - // compute the matrix that takes this Intersector from its CoordinateFrame into the local MODEL coordinate frame - // that geometry in the scene graph will always be in. - osg::Matrix matrix; - switch (_coordinateFrame) - { - case(WINDOW): - if (iv.getWindowMatrix()) matrix.preMult( *iv.getWindowMatrix() ); - if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() ); - if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); - if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); - break; - case(PROJECTION): - if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() ); - if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); - if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); - break; - case(VIEW): - if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); - if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); - break; - case(MODEL): - if (iv.getModelMatrix()) matrix = *iv.getModelMatrix(); - break; - } - - osg::Matrix inverse; - inverse.invert(matrix); - - osg::ref_ptr lsi = new LineSegmentIntersector(_start * inverse, _end * inverse); - lsi->_parent = this; - return lsi.release(); -} - -bool LineSegmentIntersector::enter(const osg::Node& node) -{ - return !node.isCullingActive() || intersects( node.getBound() ); -} - -void LineSegmentIntersector::leave() -{ - // do nothing -} - -void LineSegmentIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable) -{ - osg::Vec3d s(_start), e(_end); - if ( !intersectAndClip( s, e, drawable->getBound() ) ) return; - - // reset the clipped range as it can be too close in on the BB, and cause missing due precission issues. - s = _start; - e = _end; - - osg::TriangleFunctor ti; - ti.set(s,e); - drawable->accept(ti); - if (ti._hit) - { - osg::Geometry* geometry = drawable->asGeometry(); - - for(TriangleIntersector::TriangleIntersections::iterator thitr = ti._intersections.begin(); - thitr != ti._intersections.end(); - ++thitr) - { - - // get ratio in s,e range - float ratio = thitr->first; - - // remap ratio into _start, _end range - ratio = ((s-_start).length() + ratio * (e-s).length() )/(_end-_start).length(); - - TriangleIntersection& triHit = thitr->second; - - Intersection hit; - hit.ratio = ratio; - hit.matrix = iv.getModelMatrix(); - hit.nodePath = iv.getNodePath(); - hit.drawable = drawable; - hit.primitiveIndex = triHit._index; - - hit.localIntersectionPoint = s*(1.0f-ratio) + e*ratio; - hit.localIntersectionNormal = triHit._normal; - - if (geometry) - { - osg::Vec3Array* vertices = dynamic_cast(geometry->getVertexArray()); - if (vertices) - { - osg::Vec3* first = &(vertices->front()); - if (triHit._v1) hit.indexList.push_back(triHit._v1-first); - if (triHit._v2) hit.indexList.push_back(triHit._v2-first); - if (triHit._v3) hit.indexList.push_back(triHit._v3-first); - } - } - - insertIntersection(hit); - - } - } - -} - -void LineSegmentIntersector::reset() -{ - Intersector::reset(); - - _intersections.clear(); -} - -bool LineSegmentIntersector::intersects(const osg::BoundingSphere& bs) -{ - // if bs not valid then return true based on the assumption that an invalid sphere is yet to be defined. - if (!bs.valid()) return true; - - osg::Vec3d sm = _start - bs._center; - double c = sm.length2()-bs._radius*bs._radius; - if (c<0.0) return true; - - osg::Vec3d se = _end-_start; - double a = se.length2(); - double b = (sm*se)*2.0; - double d = b*b-4.0*a*c; - - if (d<0.0) return false; - - d = sqrt(d); - - double div = 1.0/(2.0*a); - - double r1 = (-b-d)*div; - double r2 = (-b+d)*div; - - if (r1<=0.0 && r2<=0.0) return false; - - if (r1>=1.0 && r2>=1.0) return false; - - // passed all the rejection tests so line must intersect bounding sphere, return true. - return true; -} - -bool LineSegmentIntersector::intersectAndClip(osg::Vec3d& s, osg::Vec3d& e,const osg::BoundingBox& bb) -{ - // compate s and e against the xMin to xMax range of bb. - if (s.x()<=e.x()) - { - - // trivial reject of segment wholely outside. - if (e.x()bb.xMax()) return false; - - if (s.x()bb.xMax()) - { - // clip e to xMax. - e = s+(e-s)*(bb.xMax()-s.x())/(e.x()-s.x()); - } - } - else - { - if (s.x()bb.xMax()) return false; - - if (e.x()bb.xMax()) - { - // clip e to xMax. - s = s+(e-s)*(bb.xMax()-s.x())/(e.x()-s.x()); - } - } - - // compate s and e against the yMin to yMax range of bb. - if (s.y()<=e.y()) - { - - // trivial reject of segment wholely outside. - if (e.y()bb.yMax()) return false; - - if (s.y()bb.yMax()) - { - // clip e to yMax. - e = s+(e-s)*(bb.yMax()-s.y())/(e.y()-s.y()); - } - } - else - { - if (s.y()bb.yMax()) return false; - - if (e.y()bb.yMax()) - { - // clip e to yMax. - s = s+(e-s)*(bb.yMax()-s.y())/(e.y()-s.y()); - } - } - - // compate s and e against the zMin to zMax range of bb. - if (s.z()<=e.z()) - { - - // trivial reject of segment wholely outside. - if (e.z()bb.zMax()) return false; - - if (s.z()bb.zMax()) - { - // clip e to zMax. - e = s+(e-s)*(bb.zMax()-s.z())/(e.z()-s.z()); - } - } - else - { - if (s.z()bb.zMax()) return false; - - if (e.z()bb.zMax()) - { - // clip e to zMax. - s = s+(e-s)*(bb.zMax()-s.z())/(e.z()-s.z()); - } - } - - // osg::notify(osg::NOTICE)<<"clampped segment "< pi = new PolytopeIntersector(_polytope); - pi->_parent = this; - return pi.release(); - } - - // compute the matrix that takes this Intersector from its CoordinateFrame into the local MODEL coordinate frame - // that geometry in the scene graph will always be in. - osg::Matrix matrix; - switch (_coordinateFrame) - { - case(WINDOW): - if (iv.getWindowMatrix()) matrix.preMult( *iv.getWindowMatrix() ); - if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() ); - if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); - if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); - break; - case(PROJECTION): - if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() ); - if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); - if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); - break; - case(VIEW): - if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); - if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); - break; - case(MODEL): - if (iv.getModelMatrix()) matrix = *iv.getModelMatrix(); - break; - } - - osg::Polytope transformedPolytope; - transformedPolytope.setAndTransformProvidingInverse(_polytope, matrix); - - osg::ref_ptr pi = new PolytopeIntersector(transformedPolytope); - pi->_parent = this; - return pi.release(); -} - -bool PolytopeIntersector::enter(const osg::Node& node) -{ - return !node.isCullingActive() || _polytope.contains( node.getBound() ); -} - - -void PolytopeIntersector::leave() -{ - // do nothing. -} - - -void PolytopeIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable) -{ - if ( !_polytope.contains( drawable->getBound() ) ) return; - - osg::Geometry* geometry = drawable->asGeometry(); - osg::Vec3Array* vertices = geometry ? dynamic_cast(geometry->getVertexArray()) : 0; - if (vertices) - { - if (!_polytope.contains(*vertices)) return; - } - - Intersection hit; - hit.nodePath = iv.getNodePath(); - hit.drawable = drawable; - - insertIntersection(hit); -} - - -void PolytopeIntersector::reset() -{ - Intersector::reset(); - - _intersections.clear(); -} - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// PlaneIntersector -// -PlaneIntersector::PlaneIntersector(const osg::Plane& plane, const osg::Polytope& boundingPolytope): - _parent(0), - _plane(plane), - _polytope(boundingPolytope) -{ -} - -PlaneIntersector::PlaneIntersector(CoordinateFrame cf, const osg::Plane& plane, const osg::Polytope& boundingPolytope): - Intersector(cf), - _parent(0), - _plane(plane), - _polytope(boundingPolytope) -{ -} - -Intersector* PlaneIntersector::clone(osgUtil::IntersectionVisitor& iv) -{ - if (_coordinateFrame==MODEL && iv.getModelMatrix()==0) - { - osg::ref_ptr pi = new PlaneIntersector(_plane, _polytope); - pi->_parent = this; - return pi.release(); - } - - // compute the matrix that takes this Intersector from its CoordinateFrame into the local MODEL coordinate frame - // that geometry in the scene graph will always be in. - osg::Matrix matrix; - switch (_coordinateFrame) - { - case(WINDOW): - if (iv.getWindowMatrix()) matrix.preMult( *iv.getWindowMatrix() ); - if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() ); - if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); - if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); - break; - case(PROJECTION): - if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() ); - if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); - if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); - break; - case(VIEW): - if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); - if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); - break; - case(MODEL): - if (iv.getModelMatrix()) matrix = *iv.getModelMatrix(); - break; - } - - osg::Plane plane = _plane; - plane.transformProvidingInverse(matrix); - - osg::Polytope transformedPolytope; - transformedPolytope.setAndTransformProvidingInverse(_polytope, matrix); - - osg::ref_ptr pi = new PlaneIntersector(plane, transformedPolytope); - pi->_parent = this; - return pi.release(); -} - -bool PlaneIntersector::enter(const osg::Node& node) -{ - return !node.isCullingActive() || - ( _plane.intersect(node.getBound())==0 && _polytope.contains(node.getBound()) ); -} - - -void PlaneIntersector::leave() -{ - // do nothing. -} - - -void PlaneIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable) -{ - osg::notify(osg::NOTICE)<<"PlaneIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable)"<getBound() ) ) return; - if ( !_polytope.contains( drawable->getBound() ) ) return; - - osg::notify(osg::NOTICE)<<"Succed PlaneIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable)"< + +#include +#include +#include +#include + +using namespace osgUtil; + +struct TriangleIntersection +{ + TriangleIntersection(unsigned int index, const osg::Vec3& normal, float r1, const osg::Vec3* v1, float r2, const osg::Vec3* v2, float r3, const osg::Vec3* v3): + _index(index), + _normal(normal), + _r1(r1), + _v1(v1), + _r2(r2), + _v2(v2), + _r3(r3), + _v3(v3) {} + + unsigned int _index; + const osg::Vec3 _normal; + float _r1; + const osg::Vec3* _v1; + float _r2; + const osg::Vec3* _v2; + float _r3; + const osg::Vec3* _v3; +}; + + +struct TriangleIntersector +{ + osg::Vec3 _s; + osg::Vec3 _d; + float _length; + + int _index; + float _ratio; + bool _hit; + + typedef std::multimap TriangleIntersections; + + TriangleIntersections _intersections; + + TriangleIntersector() + { + } + + TriangleIntersector(const osg::Vec3d& start, osg::Vec3d& end, float ratio=FLT_MAX) + { + set(start,end,ratio); + } + + void set(const osg::Vec3d& start, osg::Vec3d& end, float ratio=FLT_MAX) + { + _hit=false; + _index = 0; + _ratio = ratio; + + _s = start; + _d = end - start; + _length = _d.length(); + _d /= _length; + } + + // bool intersect(const Vec3& v1,const Vec3& v2,const Vec3& v3,float& r) + inline void operator () (const osg::Vec3& v1,const osg::Vec3& v2,const osg::Vec3& v3, bool treatVertexDataAsTemporary) + { + ++_index; + + if (v1==v2 || v2==v3 || v1==v3) return; + + osg::Vec3 v12 = v2-v1; + osg::Vec3 n12 = v12^_d; + float ds12 = (_s-v1)*n12; + float d312 = (v3-v1)*n12; + if (d312>=0.0f) + { + if (ds12<0.0f) return; + if (ds12>d312) return; + } + else // d312 < 0 + { + if (ds12>0.0f) return; + if (ds12=0.0f) + { + if (ds23<0.0f) return; + if (ds23>d123) return; + } + else // d123 < 0 + { + if (ds23>0.0f) return; + if (ds23=0.0f) + { + if (ds31<0.0f) return; + if (ds31>d231) return; + } + else // d231 < 0 + { + if (ds31>0.0f) return; + if (ds31_length) return; + + osg::Vec3 normal = v12^v23; + normal.normalize(); + + float r = d/_length; + + + if (treatVertexDataAsTemporary) + { + _intersections.insert(std::pair(r,TriangleIntersection(_index-1,normal,r1,0,r2,0,r3,0))); + } + else + { + _intersections.insert(std::pair(r,TriangleIntersection(_index-1,normal,r1,&v1,r2,&v2,r3,&v3))); + } + _hit = true; + + } + +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// LineSegmentIntersector +// + +LineSegmentIntersector::LineSegmentIntersector(const osg::Vec3d& start, const osg::Vec3d& end): + _parent(0), + _start(start), + _end(end) +{ +} + +LineSegmentIntersector::LineSegmentIntersector(CoordinateFrame cf, const osg::Vec3d& start, const osg::Vec3d& end): + Intersector(cf), + _parent(0), + _start(start), + _end(end) +{ +} + +LineSegmentIntersector::LineSegmentIntersector(CoordinateFrame cf, double x, double y): + Intersector(cf), + _parent(0) +{ + switch(cf) + { + case WINDOW : _start.set(x,y,0.0); _end.set(x,y,1.0); break; + case PROJECTION : _start.set(x,y,1.0); _end.set(x,y,-1.0); break; + case VIEW : _start.set(x,y,0.0); _end.set(x,y,1.0); break; + case MODEL : _start.set(x,y,0.0); _end.set(x,y,1.0); break; + } +} + +Intersector* LineSegmentIntersector::clone(osgUtil::IntersectionVisitor& iv) +{ + if (_coordinateFrame==MODEL && iv.getModelMatrix()==0) + { + osg::ref_ptr lsi = new LineSegmentIntersector(_start, _end); + lsi->_parent = this; + return lsi.release(); + } + + // compute the matrix that takes this Intersector from its CoordinateFrame into the local MODEL coordinate frame + // that geometry in the scene graph will always be in. + osg::Matrix matrix; + switch (_coordinateFrame) + { + case(WINDOW): + if (iv.getWindowMatrix()) matrix.preMult( *iv.getWindowMatrix() ); + if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() ); + if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); + if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); + break; + case(PROJECTION): + if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() ); + if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); + if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); + break; + case(VIEW): + if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); + if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); + break; + case(MODEL): + if (iv.getModelMatrix()) matrix = *iv.getModelMatrix(); + break; + } + + osg::Matrix inverse; + inverse.invert(matrix); + + osg::ref_ptr lsi = new LineSegmentIntersector(_start * inverse, _end * inverse); + lsi->_parent = this; + return lsi.release(); +} + +bool LineSegmentIntersector::enter(const osg::Node& node) +{ + return !node.isCullingActive() || intersects( node.getBound() ); +} + +void LineSegmentIntersector::leave() +{ + // do nothing +} + +void LineSegmentIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable) +{ + osg::Vec3d s(_start), e(_end); + if ( !intersectAndClip( s, e, drawable->getBound() ) ) return; + + // reset the clipped range as it can be too close in on the BB, and cause missing due precission issues. + s = _start; + e = _end; + + osg::TriangleFunctor ti; + ti.set(s,e); + drawable->accept(ti); + if (ti._hit) + { + osg::Geometry* geometry = drawable->asGeometry(); + + for(TriangleIntersector::TriangleIntersections::iterator thitr = ti._intersections.begin(); + thitr != ti._intersections.end(); + ++thitr) + { + + // get ratio in s,e range + float ratio = thitr->first; + + // remap ratio into _start, _end range + ratio = ((s-_start).length() + ratio * (e-s).length() )/(_end-_start).length(); + + TriangleIntersection& triHit = thitr->second; + + Intersection hit; + hit.ratio = ratio; + hit.matrix = iv.getModelMatrix(); + hit.nodePath = iv.getNodePath(); + hit.drawable = drawable; + hit.primitiveIndex = triHit._index; + + hit.localIntersectionPoint = s*(1.0f-ratio) + e*ratio; + hit.localIntersectionNormal = triHit._normal; + + if (geometry) + { + osg::Vec3Array* vertices = dynamic_cast(geometry->getVertexArray()); + if (vertices) + { + osg::Vec3* first = &(vertices->front()); + if (triHit._v1) hit.indexList.push_back(triHit._v1-first); + if (triHit._v2) hit.indexList.push_back(triHit._v2-first); + if (triHit._v3) hit.indexList.push_back(triHit._v3-first); + } + } + + insertIntersection(hit); + + } + } + +} + +void LineSegmentIntersector::reset() +{ + Intersector::reset(); + + _intersections.clear(); +} + +bool LineSegmentIntersector::intersects(const osg::BoundingSphere& bs) +{ + // if bs not valid then return true based on the assumption that an invalid sphere is yet to be defined. + if (!bs.valid()) return true; + + osg::Vec3d sm = _start - bs._center; + double c = sm.length2()-bs._radius*bs._radius; + if (c<0.0) return true; + + osg::Vec3d se = _end-_start; + double a = se.length2(); + double b = (sm*se)*2.0; + double d = b*b-4.0*a*c; + + if (d<0.0) return false; + + d = sqrt(d); + + double div = 1.0/(2.0*a); + + double r1 = (-b-d)*div; + double r2 = (-b+d)*div; + + if (r1<=0.0 && r2<=0.0) return false; + + if (r1>=1.0 && r2>=1.0) return false; + + // passed all the rejection tests so line must intersect bounding sphere, return true. + return true; +} + +bool LineSegmentIntersector::intersectAndClip(osg::Vec3d& s, osg::Vec3d& e,const osg::BoundingBox& bb) +{ + // compate s and e against the xMin to xMax range of bb. + if (s.x()<=e.x()) + { + + // trivial reject of segment wholely outside. + if (e.x()bb.xMax()) return false; + + if (s.x()bb.xMax()) + { + // clip e to xMax. + e = s+(e-s)*(bb.xMax()-s.x())/(e.x()-s.x()); + } + } + else + { + if (s.x()bb.xMax()) return false; + + if (e.x()bb.xMax()) + { + // clip e to xMax. + s = s+(e-s)*(bb.xMax()-s.x())/(e.x()-s.x()); + } + } + + // compate s and e against the yMin to yMax range of bb. + if (s.y()<=e.y()) + { + + // trivial reject of segment wholely outside. + if (e.y()bb.yMax()) return false; + + if (s.y()bb.yMax()) + { + // clip e to yMax. + e = s+(e-s)*(bb.yMax()-s.y())/(e.y()-s.y()); + } + } + else + { + if (s.y()bb.yMax()) return false; + + if (e.y()bb.yMax()) + { + // clip e to yMax. + s = s+(e-s)*(bb.yMax()-s.y())/(e.y()-s.y()); + } + } + + // compate s and e against the zMin to zMax range of bb. + if (s.z()<=e.z()) + { + + // trivial reject of segment wholely outside. + if (e.z()bb.zMax()) return false; + + if (s.z()bb.zMax()) + { + // clip e to zMax. + e = s+(e-s)*(bb.zMax()-s.z())/(e.z()-s.z()); + } + } + else + { + if (s.z()bb.zMax()) return false; + + if (e.z()bb.zMax()) + { + // clip e to zMax. + s = s+(e-s)*(bb.zMax()-s.z())/(e.z()-s.z()); + } + } + + // osg::notify(osg::NOTICE)<<"clampped segment "< + +#include +#include +#include +#include + +using namespace osgUtil; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// PlaneIntersector +// +PlaneIntersector::PlaneIntersector(const osg::Plane& plane, const osg::Polytope& boundingPolytope): + _parent(0), + _plane(plane), + _polytope(boundingPolytope) +{ +} + +PlaneIntersector::PlaneIntersector(CoordinateFrame cf, const osg::Plane& plane, const osg::Polytope& boundingPolytope): + Intersector(cf), + _parent(0), + _plane(plane), + _polytope(boundingPolytope) +{ +} + +Intersector* PlaneIntersector::clone(osgUtil::IntersectionVisitor& iv) +{ + if (_coordinateFrame==MODEL && iv.getModelMatrix()==0) + { + osg::ref_ptr pi = new PlaneIntersector(_plane, _polytope); + pi->_parent = this; + return pi.release(); + } + + // compute the matrix that takes this Intersector from its CoordinateFrame into the local MODEL coordinate frame + // that geometry in the scene graph will always be in. + osg::Matrix matrix; + switch (_coordinateFrame) + { + case(WINDOW): + if (iv.getWindowMatrix()) matrix.preMult( *iv.getWindowMatrix() ); + if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() ); + if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); + if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); + break; + case(PROJECTION): + if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() ); + if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); + if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); + break; + case(VIEW): + if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); + if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); + break; + case(MODEL): + if (iv.getModelMatrix()) matrix = *iv.getModelMatrix(); + break; + } + + osg::Plane plane = _plane; + plane.transformProvidingInverse(matrix); + + osg::Polytope transformedPolytope; + transformedPolytope.setAndTransformProvidingInverse(_polytope, matrix); + + osg::ref_ptr pi = new PlaneIntersector(plane, transformedPolytope); + pi->_parent = this; + return pi.release(); +} + +bool PlaneIntersector::enter(const osg::Node& node) +{ + return !node.isCullingActive() || + ( _plane.intersect(node.getBound())==0 && _polytope.contains(node.getBound()) ); +} + + +void PlaneIntersector::leave() +{ + // do nothing. +} + + +void PlaneIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable) +{ + osg::notify(osg::NOTICE)<<"PlaneIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable)"<getBound() ) ) return; + if ( !_polytope.contains( drawable->getBound() ) ) return; + + osg::notify(osg::NOTICE)<<"Succed PlaneIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable)"< + +#include +#include +#include +#include + +using namespace osgUtil; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// PolytopeIntersector +// +PolytopeIntersector::PolytopeIntersector(const osg::Polytope& polytope): + _parent(0), + _polytope(polytope) +{ +} + +PolytopeIntersector::PolytopeIntersector(CoordinateFrame cf, const osg::Polytope& polytope): + Intersector(cf), + _parent(0), + _polytope(polytope) +{ +} + +PolytopeIntersector::PolytopeIntersector(CoordinateFrame cf, double xMin, double yMin, double xMax, double yMax): + Intersector(cf), + _parent(0) +{ + double zNear = 0.0; + switch(cf) + { + case WINDOW : zNear = 0.0; break; + case PROJECTION : zNear = 1.0; break; + case VIEW : zNear = 0.0; break; + case MODEL : zNear = 0.0; break; + } + + _polytope.add(osg::Plane(1.0, 0.0, 0.0, -xMin)); + _polytope.add(osg::Plane(-1.0,0.0 ,0.0, xMax)); + _polytope.add(osg::Plane(0.0, 1.0, 0.0,-yMin)); + _polytope.add(osg::Plane(0.0,-1.0,0.0, yMax)); + _polytope.add(osg::Plane(0.0,0.0,1.0, zNear)); +} + +Intersector* PolytopeIntersector::clone(osgUtil::IntersectionVisitor& iv) +{ + if (_coordinateFrame==MODEL && iv.getModelMatrix()==0) + { + osg::ref_ptr pi = new PolytopeIntersector(_polytope); + pi->_parent = this; + return pi.release(); + } + + // compute the matrix that takes this Intersector from its CoordinateFrame into the local MODEL coordinate frame + // that geometry in the scene graph will always be in. + osg::Matrix matrix; + switch (_coordinateFrame) + { + case(WINDOW): + if (iv.getWindowMatrix()) matrix.preMult( *iv.getWindowMatrix() ); + if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() ); + if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); + if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); + break; + case(PROJECTION): + if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() ); + if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); + if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); + break; + case(VIEW): + if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); + if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); + break; + case(MODEL): + if (iv.getModelMatrix()) matrix = *iv.getModelMatrix(); + break; + } + + osg::Polytope transformedPolytope; + transformedPolytope.setAndTransformProvidingInverse(_polytope, matrix); + + osg::ref_ptr pi = new PolytopeIntersector(transformedPolytope); + pi->_parent = this; + return pi.release(); +} + +bool PolytopeIntersector::enter(const osg::Node& node) +{ + return !node.isCullingActive() || _polytope.contains( node.getBound() ); +} + + +void PolytopeIntersector::leave() +{ + // do nothing. +} + + +void PolytopeIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable) +{ + if ( !_polytope.contains( drawable->getBound() ) ) return; + + osg::Geometry* geometry = drawable->asGeometry(); + osg::Vec3Array* vertices = geometry ? dynamic_cast(geometry->getVertexArray()) : 0; + if (vertices) + { + if (!_polytope.contains(*vertices)) return; + } + + Intersection hit; + hit.nodePath = iv.getNodePath(); + hit.drawable = drawable; + + insertIntersection(hit); +} + + +void PolytopeIntersector::reset() +{ + Intersector::reset(); + + _intersections.clear(); +}