From 05bffbe9c4676ff47dbf9dcf989f4ae7dbbc0671 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 27 Nov 2006 20:25:36 +0000 Subject: [PATCH] Added beginnings of osgUtil::PlaneIntersector and osgSim::ElevationSlice --- VisualStudio/osgSim/osgSim.dsp | 8 +++ include/osgSim/ElevationSlice | 98 +++++++++++++++++++++++++++ include/osgUtil/IntersectionVisitor | 61 +++++++++++++++++ src/osgSim/ElevationSlice.cpp | 84 +++++++++++++++++++++++ src/osgSim/GNUmakefile | 1 + src/osgUtil/IntersectionVisitor.cpp | 101 +++++++++++++++++++++++++++- 6 files changed, 352 insertions(+), 1 deletion(-) create mode 100644 include/osgSim/ElevationSlice create mode 100644 src/osgSim/ElevationSlice.cpp diff --git a/VisualStudio/osgSim/osgSim.dsp b/VisualStudio/osgSim/osgSim.dsp index 386195051..15ea1d7fc 100644 --- a/VisualStudio/osgSim/osgSim.dsp +++ b/VisualStudio/osgSim/osgSim.dsp @@ -167,6 +167,10 @@ SOURCE=..\..\src\osgSim\DOFTransform.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osgSim\ElevationSlice.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osgSim\HeightAboveTerrain.cpp # End Source File # Begin Source File @@ -263,6 +267,10 @@ SOURCE=..\..\include\osgSim\HeightAboveTerrain # End Source File # Begin Source File +SOURCE=..\..\include\osgSim\ElevationSlice +# End Source File +# Begin Source File + SOURCE=..\..\Include\osgSim\Impostor # End Source File # Begin Source File diff --git a/include/osgSim/ElevationSlice b/include/osgSim/ElevationSlice new file mode 100644 index 000000000..bb7bde227 --- /dev/null +++ b/include/osgSim/ElevationSlice @@ -0,0 +1,98 @@ +/* -*-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 OSGSIM_ELEVATIONSLICE +#define OSGSIM_ELEVATIONSLICE 1 + +#include + +// include so we can get access to the DatabaseCacheReadCallback +#include + +namespace osgSim { + +/** Helper class for setting up and aquiring height above terrain intersections with terrain.*/ +class OSGSIM_EXPORT ElevationSlice +{ + public : + + + ElevationSlice(); + + /** Set the start point of the slice.*/ + void setStartPoint(const osg::Vec3d& startPoint) { _startPoint = startPoint; } + + /** Get the start point of the slice.*/ + const osg::Vec3d& getStartPoint() const { return _startPoint; } + + /** Set the end point of the slice.*/ + void setEndPoint(const osg::Vec3d& endPoint) { _endPoint = endPoint; } + + /** Get the end point of the slice.*/ + const osg::Vec3d& getEndPoint() const { return _endPoint; } + + + typedef std::vector Vec3dList; + + /** Get the intersections in the form of a vector of Vec3d. */ + const Vec3dList& getIntersections() const { return _intersections; } + + typedef std::pair DistanceHeight; + typedef std::vector DistanceHeightList; + + /** Get the intersections in the form a vector of pair representing distance along the slice and height. */ + const DistanceHeightList& getDistanceHeightIntersections() const { return _distanceHeightIntersections; } + + + /** Compute the intersections with the specified scene graph, the results are stored in vectors of Vec3d. + * Note, if the topmost node is a CoordinateSystemNode then the input points are assumed to be geocentric, + * with the up vector defined by the EllipsoidModel attached to the CoordinateSystemNode. + * If the topmost node is not a CoordinateSystemNode then a local coordinates frame is assumed, with a local up vector. */ + void computeIntersections(osg::Node* scene); + + /** Compute the vertical distance between the specified scene graph and a single HAT point. .*/ + static Vec3dList computeElevationSlice(osg::Node* scene, const osg::Vec3d& startPoint, const osg::Vec3d& endPoint); + + + /** Clear the database cache.*/ + void clearDatabaseCache() { if (_dcrc.valid()) _dcrc->clearDatabaseCache(); } + + /** Set the ReadCallback that does the reading of external PagedLOD models, and caching of loaded subgraphs. + * Note, if you have mulitple LineOfSight or ElevationSlice objects in use at one time then you should share a single + * DatabaseCacheReadCallback between all of them. */ + void setDatabaseCacheReadCallback(DatabaseCacheReadCallback* dcrc); + + /** Get the ReadCallback that does the reading of external PagedLOD models, and caching of loaded subgraphs.*/ + DatabaseCacheReadCallback* getDatabaseCacheReadCallback() { return _dcrc.get(); } + + /** Get the IntersectionVistor that does the intersection traversal over the scene. + * Note, if you want to customized the traversal then you can use the IntersectionVisitor's method to alter its behavior. */ + osgUtil::IntersectionVisitor& getIntersectionVisitor() { return _intersectionVisitor; } + + protected : + + + osg::Vec3d _startPoint; + osg::Vec3d _endPoint; + Vec3dList _intersections; + DistanceHeightList _distanceHeightIntersections; + + osg::ref_ptr _dcrc; + osgUtil::IntersectionVisitor _intersectionVisitor; + + +}; + +} + +#endif diff --git a/include/osgUtil/IntersectionVisitor b/include/osgUtil/IntersectionVisitor index 5f879fb1a..b6d827089 100644 --- a/include/osgUtil/IntersectionVisitor +++ b/include/osgUtil/IntersectionVisitor @@ -215,6 +215,67 @@ class OSGUTIL_EXPORT PolytopeIntersector : public Intersector }; +/** 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. */ class OSGUTIL_EXPORT IntersectorGroup : public Intersector diff --git a/src/osgSim/ElevationSlice.cpp b/src/osgSim/ElevationSlice.cpp new file mode 100644 index 000000000..7c13da2e6 --- /dev/null +++ b/src/osgSim/ElevationSlice.cpp @@ -0,0 +1,84 @@ +/* -*-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 + +using namespace osgSim; + +ElevationSlice::ElevationSlice() +{ + setDatabaseCacheReadCallback(new DatabaseCacheReadCallback); +} + +void ElevationSlice::computeIntersections(osg::Node* scene) +{ + osg::CoordinateSystemNode* csn = dynamic_cast(scene); + osg::EllipsoidModel* em = csn ? csn->getEllipsoidModel() : 0; + + + osg::Plane plane; + osg::Polytope boundingPolytope; + + if (em) + { + + osg::Vec3d upVector = em->computeLocalUpVector(_startPoint.x(), _startPoint.y(), _startPoint.z()); + + double latitude, longitude, height; + em->convertXYZToLatLongHeight(_startPoint.x(), _startPoint.y(), _startPoint.z(), latitude, longitude, height); + + osg::notify(osg::NOTICE)<<"lat = "< 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()) && _polytope.contains(node.getBound()) ); +} + + +void PlaneIntersector::leave() +{ + // do nothing. +} + + +void PlaneIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable) +{ + if ( !_plane.intersect( drawable->getBound() ) ) return; + if ( !_polytope.contains( drawable->getBound() ) ) return; + + Intersection hit; + hit.nodePath = iv.getNodePath(); + hit.drawable = drawable; + + insertIntersection(hit); +} + + +void PlaneIntersector::reset() +{ + Intersector::reset(); + + _intersections.clear(); +} + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // IntersectorGroup