From afa96fff0e887032f8e514124733b8440275fe5e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 5 Dec 2006 12:58:29 +0000 Subject: [PATCH] Added more accurate computation of local height above sea level in the plane intersections routines --- examples/osgintersection/osgintersection.cpp | 2 +- include/osg/Plane | 4 +- include/osgUtil/PlaneIntersector | 26 ++++- src/osgSim/ElevationSlice.cpp | 18 +++- src/osgUtil/PlaneIntersector.cpp | 106 ++++++++++++++++--- 5 files changed, 130 insertions(+), 26 deletions(-) diff --git a/examples/osgintersection/osgintersection.cpp b/examples/osgintersection/osgintersection.cpp index 2a29fe4de..a9ed2cd2a 100644 --- a/examples/osgintersection/osgintersection.cpp +++ b/examples/osgintersection/osgintersection.cpp @@ -134,7 +134,7 @@ int main(int argc, char **argv) es.setDatabaseCacheReadCallback(los.getDatabaseCacheReadCallback()); es.setStartPoint(bs.center()+osg::Vec3d(bs.radius(),0.0,0.0) ); - es.setEndPoint(bs.center()+osg::Vec3d(0.0,0.0,bs.radius()) ); + es.setEndPoint(bs.center()+osg::Vec3d(bs.radius(),bs.radius(),bs.radius()) ); es.computeIntersections(scene.get()); diff --git a/include/osg/Plane b/include/osg/Plane index a9e17ccef..348b5e0d4 100644 --- a/include/osg/Plane +++ b/include/osg/Plane @@ -163,7 +163,7 @@ class OSG_EXPORT Plane _fv[3]; } - inline float distance(const osg::Vec3d& v) const + inline double distance(const osg::Vec3d& v) const { return _fv[0]*v.x()+ _fv[1]*v.y()+ @@ -180,7 +180,7 @@ class OSG_EXPORT Plane } /** calculate the dot product of the plane normal and a point.*/ - inline float dotProductNormal(const osg::Vec3d& v) const + inline double dotProductNormal(const osg::Vec3d& v) const { return _fv[0]*v.x()+ _fv[1]*v.y()+ diff --git a/include/osgUtil/PlaneIntersector b/include/osgUtil/PlaneIntersector index 58dd0c4ce..f8a81c96c 100644 --- a/include/osgUtil/PlaneIntersector +++ b/include/osgUtil/PlaneIntersector @@ -16,6 +16,8 @@ #include +#include + namespace osgUtil { @@ -47,11 +49,13 @@ class OSGUTIL_EXPORT PlaneIntersector : public Intersector } typedef std::vector Polyline; + typedef std::vector Attributes; osg::NodePath nodePath; osg::ref_ptr matrix; osg::ref_ptr drawable; Polyline polyline; + Attributes attributes; }; @@ -61,6 +65,15 @@ class OSGUTIL_EXPORT PlaneIntersector : public Intersector inline Intersections& getIntersections() { return _parent ? _parent->_intersections : _intersections; } + + void setRecordHeightsAsAttributes(bool flag) { _recordHeightsAsAttributes = flag; } + + bool getRecordHeightsAsAttributes() const { return _recordHeightsAsAttributes; } + + void setEllipsoidModel(osg::EllipsoidModel* em) { _em = em; } + + const osg::EllipsoidModel* getEllipsoidModel() const { return _em.get(); } + public: virtual Intersector* clone(osgUtil::IntersectionVisitor& iv); @@ -77,12 +90,15 @@ class OSGUTIL_EXPORT PlaneIntersector : public Intersector protected: - PlaneIntersector* _parent; - - osg::Plane _plane; - osg::Polytope _polytope; + PlaneIntersector* _parent; - Intersections _intersections; + bool _recordHeightsAsAttributes; + osg::ref_ptr _em; + + osg::Plane _plane; + osg::Polytope _polytope; + + Intersections _intersections; }; diff --git a/src/osgSim/ElevationSlice.cpp b/src/osgSim/ElevationSlice.cpp index 0950f1f1f..7b107df00 100644 --- a/src/osgSim/ElevationSlice.cpp +++ b/src/osgSim/ElevationSlice.cpp @@ -245,6 +245,10 @@ void ElevationSlice::computeIntersections(osg::Node* scene) osg::ref_ptr intersector = new osgUtil::PlaneIntersector(plane, boundingPolytope); + + intersector->setRecordHeightsAsAttributes(true); + intersector->setEllipsoidModel(em); + _intersectionVisitor.reset(); _intersectionVisitor.setIntersector( intersector.get() ); @@ -253,6 +257,7 @@ void ElevationSlice::computeIntersections(osg::Node* scene) osgUtil::PlaneIntersector::Intersections& intersections = intersector->getIntersections(); typedef osgUtil::PlaneIntersector::Intersection::Polyline Polyline; + typedef osgUtil::PlaneIntersector::Intersection::Attributes Attributes; if (!intersections.empty()) { @@ -300,14 +305,23 @@ void ElevationSlice::computeIntersections(osg::Node* scene) ++itr) { osgUtil::PlaneIntersector::Intersection& intersection = *itr; + + if (intersection.attributes.size()!=intersection.polyline.size()) continue; + + Attributes::iterator aitr = intersection.attributes.begin(); for(Polyline::iterator pitr = intersection.polyline.begin(); pitr != intersection.polyline.end(); - ++pitr) + ++pitr, ++aitr) { const osg::Vec3d& v = *pitr; double distance, height; dhc.computeDistanceHeight(v, distance, height); - distanceHeightSet.insert(ElevationSliceUtils::DistanceHeightXYZ( distance, height, v)); + + double pi_height = *aitr; + + osg::notify(osg::NOTICE)<<"computed height = "< ti; - ti.set(_plane,_polytope); + ti.set(_plane, _polytope, iv.getModelMatrix(), _recordHeightsAsAttributes, _em.get()); drawable->accept(ti); ti._polylineConnector.consolidatePolylineLists(); @@ -614,7 +676,19 @@ void PlaneIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable Intersection& new_intersection = intersections[pos]; new_intersection.matrix = iv.getModelMatrix(); - new_intersection.polyline = (*pitr)->_polyline; + + new_intersection.polyline.reserve((*pitr)->_polyline.size()); + if (_recordHeightsAsAttributes) new_intersection.attributes.reserve((*pitr)->_polyline.size()); + + for(PlaneIntersectorUtils::RefPolyline::Polyline::iterator vitr = (*pitr)->_polyline.begin(); + vitr != (*pitr)->_polyline.end(); + ++vitr) + { + const osg::Vec4d& v = *vitr; + new_intersection.polyline.push_back( osg::Vec3d(v.x(), v.y(), v.z()) ); + if (_recordHeightsAsAttributes) new_intersection.attributes.push_back( v.w() ); + } + new_intersection.nodePath = iv.getNodePath(); new_intersection.drawable = drawable; }