source: experimental/osgVisualNG/visual_util.cpp @ 420

Last change on this file since 420 was 417, checked in by Torben Dannhauer, 12 years ago
  • Property svn:eol-style set to native
File size: 10.4 KB
Line 
1/* -*-c++-*- osgVisual - Copyright (C) 2009-2011 Torben Dannhauer
2 *
3 * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
9 * You have to aquire licenses for all used proprietary modules.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * OpenSceneGraph Public License for more details.
15*/
16
17#include <visual_util.h>
18#include <osg/Material>
19
20using namespace osgVisual;
21
22util::util(void)
23{
24}
25
26util::~util(void)
27{
28}
29
30osg::Node* util::findNamedNode(const std::string& searchName_, osg::Node* currNode_)
31{
32   osg::Group* currGroup;
33   osg::Node* foundNode;
34
35   // check to see if we have a valid (non-NULL) node.
36   // if we do have a null node, return NULL.
37   if ( !currNode_)
38   {
39      return NULL;
40   }
41
42   // We have a valid node, check to see if this is the node we
43   // are looking for. If so, return the current node.
44   if (currNode_->getName() == searchName_)
45   {
46      return currNode_;
47   }
48
49   // We have a valid node, but not the one we are looking for.
50   // Check to see if it has children (non-leaf node). If the node
51   // has children, check each of the child nodes by recursive call.
52   // If one of the recursive calls returns a non-null value we have
53   // found the correct node, so return this node.
54   // If we check all of the children and have not found the node,
55   // return NULL
56   currGroup = currNode_->asGroup(); // returns NULL if not a group.
57   if ( currGroup ) 
58   {
59      for (unsigned int i = 0 ; i < currGroup->getNumChildren(); i ++)
60      { 
61         foundNode = findNamedNode(searchName_, currGroup->getChild(i));
62         if (foundNode)
63                 {
64                         std::cout << "Node gefunden in Ebene: " << i << std::endl;
65            return foundNode; // found a match!
66                }
67      }
68      return NULL; // We have checked each child node - no match found.
69   }
70   else 
71           return NULL; // leaf node, no match
72}
73
74osg::ref_ptr<osg::Geode> util::getDemoCylinder(double length_, double width_, osg::Vec3 offset_ )
75{
76        osg::ref_ptr<osg::Geode> cyl = new osg::Geode();
77        osg::ref_ptr<osg::ShapeDrawable> shape = new osg::ShapeDrawable(new osg::Cylinder( offset_, width_, length_ ));
78        osg::Vec4 color = osg::Vec4(255.0, 0.0, 0.0, 1.0);
79        shape->setColor( color );
80        cyl->addDrawable( shape );
81
82        return cyl;
83}
84
85osg::ref_ptr<osg::Geode> util::getDemoSphere(double radius_, osg::Vec3 offset_ )
86{
87        osg::ref_ptr<osg::Geode> sphere = new osg::Geode();
88        osg::ref_ptr<osg::ShapeDrawable> shape = new osg::ShapeDrawable(new osg::Sphere( offset_, radius_ ) );
89        osg::Vec4 color = osg::Vec4(255.0, 0.0, 0.0, 1.0);
90        shape->setColor( color );
91        sphere->addDrawable( shape );
92
93        return sphere;
94}
95
96bool util::intersect(const osg::Vec3d& start_, const osg::Vec3d& end_, osg::Vec3d& intersection_, osg::Node* node_, osg::Node::NodeMask intersectTraversalMask_ )
97{
98        osg::ref_ptr<osgUtil::LineSegmentIntersector> lsi = new osgUtil::LineSegmentIntersector(start_,end_);
99
100        osgUtil::IntersectionVisitor iv(lsi.get());
101        iv.setTraversalMask(intersectTraversalMask_);
102   
103        node_->accept(iv);
104   
105        if (lsi->containsIntersections())
106        {
107                intersection_ = lsi->getIntersections().begin()->getWorldIntersectPoint();
108                return true;    // Intersect found
109        }
110        return false;   // No intersect found
111}
112
113bool util::queryHeightOfTerrain(double& hot_, osg::Node* rootNode_, double lat_, double lon_, osg::Node::NodeMask traversalMask_)
114{
115        // Get ellipsoid model
116        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
117        if ( !csn )
118        {
119                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightOfTerrain() :: Invalid CSN!" << std::endl;
120                return false;
121        }
122        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
123        if ( !ellipsoid )
124        {
125                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightOfTerrain() :: Invalid ellipsoid!" << std::endl;
126                return false;
127        }
128
129        // Setup both endpoints of intersect line
130        double X,Y,Z;
131        ellipsoid->convertLatLongHeightToXYZ(lat_, lon_, 30000, X, Y, Z);
132        osg::Vec3d s = osg::Vec3d(X, Y, Z);
133        ellipsoid->convertLatLongHeightToXYZ(lat_, lon_, -30000, X, Y, Z);
134        osg::Vec3d e = osg::Vec3d(X, Y, Z);
135
136        // Query intersection point
137        osg::Vec3d ip;
138        if ( util::intersect(s, e, ip, rootNode_, traversalMask_) )
139        {
140                double lat2_, lon2_;
141                ellipsoid->convertXYZToLatLongHeight( ip.x(), ip.y(), ip.z(), lat2_, lon2_, hot_ );     // Convert Intersection Point back to Lat Lon, HOT.
142                //OSG_NOTIFY(osg::ALWAYS) << "lat: "<< osg::RadiansToDegrees(lat2_) <<", Lon: " << osg::RadiansToDegrees(lon2_) << ", Hot: " << hot_ << std::endl;
143                return true;
144        }
145
146        // If no intersection point found: set HOT to zero and return false.
147        hot_ = 0;
148        return false;
149}
150
151bool util::queryHeightAboveTerrainInWGS84(double& hat_, osg::Node* rootNode_, double lat_, double lon_, double height_, osg::Node::NodeMask traversalMask_)
152{
153        // Get HOT by asking util::queryHeightOfTerrain() :)
154        double HOT;
155        if ( !util::queryHeightOfTerrain(HOT, rootNode_, lat_, lon_, traversalMask_) )
156        {
157                OSG_NOTIFY( osg::INFO ) << "util::queryHeightAboveTerrainInWGS84() :: Unable to get HOT, will use 0 for HOT!" << std::endl;
158        }
159
160        // Calculate HAT
161        hat_ = height_ - HOT;
162        return true;
163}
164
165bool util::queryHeightAboveTerrainInWorld(double& hat_, osg::Node* rootNode_, double x_, double y_, double z_, osg::Node::NodeMask traversalMask_)
166{
167        // Get ellipsoid model
168        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
169        if ( !csn )
170        {
171                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightAboveTerrainInWorld() :: Invalid CSN!" << std::endl;
172                return false;
173        }
174        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
175        if ( !ellipsoid )
176        {
177                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightAboveTerrainInWorld() :: Invalid ellipsoid!" << std::endl;
178                return false;
179        }
180
181        // Transform XYZ into LatLonHeight
182        double lat_, lon_, height_;
183        ellipsoid->convertXYZToLatLongHeight(x_, y_, z_, lat_, lon_, height_);
184
185        // ask util::queryHeightAboveTerrainInWGS84() to calc HAT :)
186        if( !util::queryHeightAboveTerrainInWGS84(hat_, rootNode_, lat_, lon_, height_, traversalMask_ ) )
187        {
188                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightAboveTerrainInWorld() :: Unable to get HAT!" << std::endl;
189                return false;
190        }
191
192        return true;
193}
194
195bool util::calculateEarthRadiusAtWGS84Coordinate(double lat_, double lon_, osg::Node* rootNode_, double& radius_)
196{
197        // Calculate radius:
198        double x, y, z;
199       
200        if ( util::calculateXYZAtWGS84Coordinate(lat_, lon_, 0.0, rootNode_, x, y, z) )
201        {
202                radius_ = sqrt( pow(x, 2) + pow(y, 2) + pow(z, 2) );
203                return true;
204        }
205        else
206        {
207                OSG_NOTIFY( osg::FATAL ) << "util::calculateEarthRadiusAtWGS84Coordinate() :: Unable to calculate Earth Radius!" << std::endl;
208                return false;
209        }
210}
211
212bool util::calculateXYZAtWGS84Coordinate(double lat_, double lon_, double height_, osg::Node* rootNode_, double& x_, double& y_, double& z_)
213{
214        // Get ellipsoid model
215        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
216        if ( !csn )
217                return false;
218        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
219        if ( !ellipsoid )
220                return false;
221
222        // Calculate xyz:
223        ellipsoid->convertLatLongHeightToXYZ( lat_, lon_, height_, x_, y_, z_);
224        return true;
225}
226
227bool util::getWGS84ofCamera( osg::Camera* camera_, osg::Node* rootNode_, double& lat_, double& lon_, double& height_ )
228{
229        // Get ellipsoid model
230        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
231        if ( !csn )
232                return false;
233        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
234        if ( !ellipsoid )
235                return false;
236
237        osg::Vec3d eye, dir, up;
238        camera_->getViewMatrixAsLookAt(eye,dir,up); // Get XYZ from camera
239        ellipsoid->convertXYZToLatLongHeight(eye.x(), eye.y(), eye.z(), lat_, lon_, height_);
240        return true;
241}
242
243void util::getXYZofCamera( osg::Camera* camera_, double& x_, double& y_, double& z_ )
244{
245        osg::Vec3d eye, dir, up;
246        camera_->getViewMatrixAsLookAt(eye,dir,up); // Get XYZ from camera
247        x_ = eye.x();
248        y_ = eye.y();
249        z_ = eye.z();
250}
251
252
253double util::strToDouble(std::string s)
254{
255        double tmp;
256        std::stringstream sstr(s);
257    if (!(sstr >> tmp))
258        {
259                OSG_ALWAYS << __FUNCTION__ << "Warning:Unable to convert "<< s <<" to double, using 0.0 as default!" << std::endl;
260                return 0.0;
261        }
262        else
263                return tmp;
264}
265
266int util::strToInt(std::string s)
267{
268        int tmp;
269        std::stringstream sstr(s);
270        if (!(sstr >> tmp))
271        {
272                OSG_ALWAYS << __FUNCTION__ << "Warning:Unable to convert "<< s <<" to int, using 0 as default!" << std::endl;
273                return 0;
274        }
275        else
276                return tmp;
277}
278
279bool util::strToBool(std::string s)
280{
281        if(s=="yes")
282                return(true);
283        if(s=="no")
284                return(false);
285        OSG_ALWAYS << __FUNCTION__ << "Warning:Unable to convert "<< s <<" to bool, using false as default!" << std::endl;
286        return(false);
287}
288
289void util::AddCylinderBetweenPoints(osg::Vec3d StartPoint, osg::Vec3d EndPoint, float radius, osg::Vec4d CylinderColor, osg::Group *pAddToThisGroup)
290{
291        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
292        osg::Vec3d center;
293        float height;
294        osg::ref_ptr<osg::Cylinder> cylinder;
295        osg::ref_ptr<osg::Drawable> cylinderDrawable;
296        osg::ref_ptr<osg::Material> pMaterial;
297
298        height = (StartPoint-EndPoint).length();
299        center = osg::Vec3( (StartPoint.x() + EndPoint.x()) / 2, (StartPoint.y() + EndPoint.y()) / 2, (StartPoint.z() + EndPoint.z()) / 2);
300
301        // This is the default direction for the cylinders to face in OpenGL
302        osg::Vec3d z = osg::Vec3d(0,0,1);
303
304        // Get diff between two points you want cylinder along
305        osg::Vec3d p = StartPoint - EndPoint;
306
307        // Get CROSS product (the axis of rotation)
308        osg::Vec3d t = z ^ p;
309
310        // Get angle. length is magnitude of the vector
311        double angle = acos( (z * p) / p.length());
312
313        // Create a cylinder between the two points with the given radius
314        cylinder = new osg::Cylinder(center,radius,height);
315        cylinder->setRotation(osg::Quat(angle, osg::Vec3(t.x(), t.y(), t.z())));
316
317        cylinderDrawable = new osg::ShapeDrawable(cylinder );
318        geode->addDrawable(cylinderDrawable);
319
320        // Set the color of the cylinder that extends between the two points.
321        pMaterial = new osg::Material;
322        pMaterial->setDiffuse( osg::Material::FRONT, CylinderColor);
323        geode->getOrCreateStateSet()->setAttribute( pMaterial, osg::StateAttribute::OVERRIDE );
324
325        // Add the cylinder between the two points to an existing group
326        pAddToThisGroup->addChild(geode);
327}
Note: See TracBrowser for help on using the repository browser.