source: osgVisual/trunk/src/util/visual_util.cpp @ 220

Last change on this file since 220 was 220, checked in by Torben Dannhauer, 14 years ago

Added util functions to convert string to bool, int or double.
Modified all files to use this functions.

File size: 17.8 KB
Line 
1/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 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
19using namespace osgVisual;
20
21util::util(void)
22{
23}
24
25util::~util(void)
26{
27}
28
29xmlNode* util::getSceneryXMLConfig(std::string configFilename, xmlDoc*& doc)
30{
31        doc = NULL;
32        xmlNode *root_element = NULL;
33
34        // Check for valid parameters
35        if(configFilename == "")
36        {
37                OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : Invalid Configuration Filename!" << std::endl;
38                return NULL;
39        }
40
41        // It is a valid XML document?
42        doc = xmlReadFile(configFilename.c_str(), NULL, 0);     
43        if (doc == NULL)
44        {
45                OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : " << configFilename << " is not a valid XML file!" << std::endl;
46                return NULL;
47        }
48
49        //  Get the root element node
50        root_element = xmlDocGetRootElement(doc);
51
52        // If file is a valid osgVisual config file, check all the root xml node and all of it's children of osgvisualconfiguration for the specified module
53        xmlNode* tmpNode = checkXMLNodeChildrenForScenery(root_element);
54
55        if( !tmpNode ) // if no valid node was found: clena up. Otherwise: the caller has to clean up.
56        {
57                xmlFreeDoc(doc);        // free the document
58                xmlCleanupParser();     // Free the global variables that may have been allocated by the parser.
59                return NULL;
60        }
61        else
62                return tmpNode;
63}
64
65xmlNode* util::checkXMLNodeChildrenForScenery(xmlNode* node)
66{
67        for (xmlNode *cur_node = node; cur_node; cur_node = cur_node->next)     // iterate through all elements
68        {
69                // Is the node the one we are searching for?
70                if (cur_node->type == XML_ELEMENT_NODE)
71                {
72                        std::string node_name=reinterpret_cast<const char*>(cur_node->name);
73                        if (node_name == "scenery")
74                        {
75                                OSG_DEBUG << "XML node scenery found" << std::endl;
76                                return cur_node;
77                        }
78                        else    // Otherwise: check its children..
79                        {
80                                xmlNode* tmp_XmlNode = checkXMLNodeChildrenForScenery(cur_node->children);
81                                if(tmp_XmlNode)
82                                        return tmp_XmlNode;
83                        }
84                }       // IF NODE TYPE = ELEMENT END
85
86                // Proceed with next node in this loop.
87        }
88        return NULL;
89}
90
91xmlNode* util::getModuleXMLConfig(std::string configFilename, std::string moduleName, xmlDoc*& doc, bool& disabled)
92{
93        doc = NULL;
94        disabled = false;
95        xmlNode *root_element = NULL;
96
97        // Check for valid parameters
98        if(configFilename == "")
99        {
100                OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : Invalid Configuration Filename!" << std::endl;
101                return NULL;
102        }
103        if(moduleName == "")
104        {
105                OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : Invalid Module Filename!" << std::endl;
106                return NULL;
107        }
108
109        // It is a valid XML document?
110        doc = xmlReadFile(configFilename.c_str(), NULL, 0);     
111        if (doc == NULL)
112        {
113                OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : " << configFilename << " is not a valid XML file!" << std::endl;
114                return NULL;
115        }
116
117        //  Get the root element node
118        root_element = xmlDocGetRootElement(doc);
119
120        // Check if it is an osgVisual configuration file
121        std::string node_name=reinterpret_cast<const char*>(root_element->name);
122        if(!(root_element->type == XML_ELEMENT_NODE && node_name == "osgvisualconfiguration"))
123        {
124                OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : " << configFilename << " is not an osgVisual configuration file!" << std::endl;
125                return NULL;
126        }
127
128        // If file is a valid osgVisual config file, check all the root xml node and all of it's children of osgvisualconfiguration for the specified module
129        xmlNode* tmpNode = checkXMLNodeChildrenForModule(root_element, moduleName, disabled);
130
131        if( !tmpNode ) // if no valid node was found or the module is disabled: clean up. Otherwise: the caller has to clean up.
132        {
133                xmlFreeDoc(doc);        // free the document
134                xmlCleanupParser();     // Free the global variables that may have been allocated by the parser.
135                return NULL;
136        }
137        else
138                return tmpNode;
139
140}
141
142xmlNode* util::checkXMLNodeChildrenForModule(xmlNode* node, std::string moduleName, bool& disabled)
143{
144        for (xmlNode *cur_node = node; cur_node; cur_node = cur_node->next)     // iterate through all XML elements
145        {
146                // Is the node the one we are searching for?
147                if (cur_node->type == XML_ELEMENT_NODE)
148                {
149                        // Extract Node Name and the first attribute: "module name"
150                        std::string node_name = reinterpret_cast<const char*>(cur_node->name);
151                        std::string modName = "";
152                        xmlAttr  *attr = cur_node->properties;
153                        while ( attr ) 
154                        { 
155                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
156                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
157                                if( attr_name == "name" )
158                                        modName = attr_value;
159                                attr = attr->next;
160                        }
161                       
162                        // Check each node for the searched module
163                        if (node_name == "module" && modName == moduleName)
164                        {
165                                // Check if the module is active
166                                xmlAttr  *attr = cur_node->properties;
167                                while ( attr ) 
168                                { 
169                                        std::string attr_name=reinterpret_cast<const char*>(attr->name);
170                                        std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
171                                        if( attr_name == "enabled" && attr_value == "yes" )
172                                        {
173                                                OSG_DEBUG << "Found XML module configuration for " << moduleName << std::endl;
174                                                return cur_node;
175                                        }
176                                        if( attr_name == "enabled" && attr_value == "no" )
177                                        {
178                                                disabled = true;
179                                                OSG_DEBUG << "Found XML module configuration for " << moduleName << ", but it is DISABLED." << std::endl;
180                                                return NULL;
181                                        }
182                                        attr = attr->next;
183                                }
184                        }
185                        else    // Otherwise: check its children..
186                        {
187                                xmlNode* tmp_XmlNode = checkXMLNodeChildrenForModule(cur_node->children, moduleName, disabled);
188                                if(tmp_XmlNode)
189                                        return tmp_XmlNode;
190                        }
191                }       // IF NODE TYPE = ELEMENT END
192
193                // Proceed with next node in this loop.
194        }
195        return NULL;
196}
197
198osg::Node* util::findNamedNode(const std::string& searchName_, osg::Node* currNode_)
199{
200   osg::Group* currGroup;
201   osg::Node* foundNode;
202
203   // check to see if we have a valid (non-NULL) node.
204   // if we do have a null node, return NULL.
205   if ( !currNode_)
206   {
207      return NULL;
208   }
209
210   // We have a valid node, check to see if this is the node we
211   // are looking for. If so, return the current node.
212   if (currNode_->getName() == searchName_)
213   {
214      return currNode_;
215   }
216
217   // We have a valid node, but not the one we are looking for.
218   // Check to see if it has children (non-leaf node). If the node
219   // has children, check each of the child nodes by recursive call.
220   // If one of the recursive calls returns a non-null value we have
221   // found the correct node, so return this node.
222   // If we check all of the children and have not found the node,
223   // return NULL
224   currGroup = currNode_->asGroup(); // returns NULL if not a group.
225   if ( currGroup ) 
226   {
227      for (unsigned int i = 0 ; i < currGroup->getNumChildren(); i ++)
228      { 
229         foundNode = findNamedNode(searchName_, currGroup->getChild(i));
230         if (foundNode)
231                 {
232                         std::cout << "Node gefunden in Ebene: " << i << std::endl;
233            return foundNode; // found a match!
234                }
235      }
236      return NULL; // We have checked each child node - no match found.
237   }
238   else 
239   {
240      return NULL; // leaf node, no match
241   }
242}
243
244osg::ref_ptr<osg::Geode> util::getDemoCylinder(double length_, double width_, osg::Vec3 offset_ )
245{
246        osg::ref_ptr<osg::Geode> cyl = new osg::Geode();
247        osg::ref_ptr<osg::ShapeDrawable> shape = new osg::ShapeDrawable(new osg::Cylinder( offset_, width_, length_ ));
248        osg::Vec4 color = osg::Vec4(255.0, 0.0, 0.0, 1.0);
249        shape->setColor( color );
250        cyl->addDrawable( shape );
251
252        return cyl;
253}
254
255osg::ref_ptr<osg::Geode> util::getDemoSphere(double radius_, osg::Vec3 offset_ )
256{
257        osg::ref_ptr<osg::Geode> sphere = new osg::Geode();
258        osg::ref_ptr<osg::ShapeDrawable> shape = new osg::ShapeDrawable(new osg::Sphere( offset_, radius_ ) );
259        osg::Vec4 color = osg::Vec4(255.0, 0.0, 0.0, 1.0);
260        shape->setColor( color );
261        sphere->addDrawable( shape );
262
263        return sphere;
264}
265
266bool util::intersect(const osg::Vec3d& start_, const osg::Vec3d& end_, osg::Vec3d& intersection_, osg::Node* node_, osg::Node::NodeMask intersectTraversalMask_ )
267{
268        osg::ref_ptr<osgUtil::LineSegmentIntersector> lsi = new osgUtil::LineSegmentIntersector(start_,end_);
269
270        osgUtil::IntersectionVisitor iv(lsi.get());
271        iv.setTraversalMask(intersectTraversalMask_);
272   
273        node_->accept(iv);
274   
275        if (lsi->containsIntersections())
276        {
277                intersection_ = lsi->getIntersections().begin()->getWorldIntersectPoint();
278                return true;    // Intersect found
279        }
280        return false;   // No intersect found
281}
282
283bool util::queryHeightOfTerrain(double& hot_, osg::Node* rootNode_, double lat_, double lon_, osg::Node::NodeMask traversalMask_)
284{
285        // Get ellipsoid model
286        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
287        if ( !csn )
288        {
289                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightOfTerrain() :: Invalid CSN!" << std::endl;
290                return false;
291        }
292        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
293        if ( !ellipsoid )
294        {
295                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightOfTerrain() :: Invalid ellipsoid!" << std::endl;
296                return false;
297        }
298
299        // Setup both endpoints of intersect line
300        double X,Y,Z;
301        ellipsoid->convertLatLongHeightToXYZ(lat_, lon_, 30000, X, Y, Z);
302        osg::Vec3d s = osg::Vec3d(X, Y, Z);
303        ellipsoid->convertLatLongHeightToXYZ(lat_, lon_, -30000, X, Y, Z);
304        osg::Vec3d e = osg::Vec3d(X, Y, Z);
305
306        // Query intersection point
307        osg::Vec3d ip;
308        if ( util::intersect(s, e, ip, rootNode_, traversalMask_) )
309        {
310                double lat2_, lon2_;
311                ellipsoid->convertXYZToLatLongHeight( ip.x(), ip.y(), ip.z(), lat2_, lon2_, hot_ );     // Convert Intersection Point back to Lat Lon, HOT.
312                //OSG_NOTIFY(osg::ALWAYS) << "lat: "<< osg::RadiansToDegrees(lat2_) <<", Lon: " << osg::RadiansToDegrees(lon2_) << ", Hot: " << hot_ << std::endl;
313                return true;
314        }
315
316        // If no intersection point found: set HOT to zero and return false.
317        hot_ = 0;
318        return false;
319}
320
321bool util::queryHeightAboveTerrainInWGS84(double& hat_, osg::Node* rootNode_, double lat_, double lon_, double height_, osg::Node::NodeMask traversalMask_)
322{
323        // Get HOT by asking util::queryHeightOfTerrain() :)
324        double HOT;
325        if ( !util::queryHeightOfTerrain(HOT, rootNode_, lat_, lon_, traversalMask_) )
326        {
327                OSG_NOTIFY( osg::INFO ) << "util::queryHeightAboveTerrainInWGS84() :: Unable to get HOT, will use 0 for HOT!" << std::endl;
328        }
329
330        // Calculate HAT
331        hat_ = height_ - HOT;
332        return true;
333}
334
335bool util::queryHeightAboveTerrainInWorld(double& hat_, osg::Node* rootNode_, double x_, double y_, double z_, osg::Node::NodeMask traversalMask_)
336{
337        // Get ellipsoid model
338        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
339        if ( !csn )
340        {
341                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightAboveTerrainInWorld() :: Invalid CSN!" << std::endl;
342                return false;
343        }
344        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
345        if ( !ellipsoid )
346        {
347                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightAboveTerrainInWorld() :: Invalid ellipsoid!" << std::endl;
348                return false;
349        }
350
351        // Transform XYZ into LatLonHeight
352        double lat_, lon_, height_;
353        ellipsoid->convertXYZToLatLongHeight(x_, y_, z_, lat_, lon_, height_);
354
355        // ask util::queryHeightAboveTerrainInWGS84() to calc HAT :)
356        if( !util::queryHeightAboveTerrainInWGS84(hat_, rootNode_, lat_, lon_, height_, traversalMask_ ) )
357        {
358                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightAboveTerrainInWorld() :: Unable to get HAT!" << std::endl;
359                return false;
360        }
361
362        return true;
363}
364
365bool util::calculateEarthRadiusAtWGS84Coordinate(double lat_, double lon_, osg::Node* rootNode_, double& radius_)
366{
367        // Calculate radius:
368        double x, y, z;
369       
370        if ( util::calculateXYZAtWGS84Coordinate(lat_, lon_, 0.0, rootNode_, x, y, z) )
371        {
372                radius_ = sqrt( pow(x, 2) + pow(y, 2) + pow(z, 2) );
373                return true;
374        }
375        else
376        {
377                OSG_NOTIFY( osg::FATAL ) << "util::calculateEarthRadiusAtWGS84Coordinate() :: Unable to calculate Earth Radius!" << std::endl;
378                return false;
379        }
380}
381
382bool util::calculateXYZAtWGS84Coordinate(double lat_, double lon_, double height_, osg::Node* rootNode_, double& x_, double& y_, double& z_)
383{
384        // Get ellipsoid model
385        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
386        if ( !csn )
387                return false;
388        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
389        if ( !ellipsoid )
390                return false;
391
392        // Calculate xyz:
393        ellipsoid->convertLatLongHeightToXYZ( lat_, lon_, height_, x_, y_, z_);
394        return true;
395}
396
397bool util::getWGS84ofCamera( osg::Camera* camera_, osg::Node* rootNode_, double& lat_, double& lon_, double& height_ )
398{
399        // Get ellipsoid model
400        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
401        if ( !csn )
402                return false;
403        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
404        if ( !ellipsoid )
405                return false;
406
407        osg::Vec3d eye, dir, up;
408        camera_->getViewMatrixAsLookAt(eye,dir,up); // Get XYZ from camera
409        ellipsoid->convertXYZToLatLongHeight(eye.x(), eye.y(), eye.z(), lat_, lon_, height_);
410        return true;
411}
412
413void util::getXYZofCamera( osg::Camera* camera_, double& x_, double& y_, double& z_ )
414{
415        osg::Vec3d eye, dir, up;
416        camera_->getViewMatrixAsLookAt(eye,dir,up); // Get XYZ from camera
417        x_ = eye.x();
418        y_ = eye.y();
419        z_ = eye.z();
420}
421
422bool util::removeClosebuttonOnGLWindow(osgViewer::Viewer* viewer_)
423{
424#ifdef FUNFUNCTIONS_ENABLED
425#ifdef WIN32
426        osgViewer::ViewerBase::Windows wins;
427        viewer_->getWindows(wins);
428        osgViewer::GraphicsHandleWin32* hwnd = dynamic_cast<osgViewer::GraphicsHandleWin32*>(wins[0]);
429       
430        HMENU hMenu = GetSystemMenu(hwnd->getHWND(), FALSE);
431        ::EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | (MF_DISABLED | MF_GRAYED)); 
432#endif
433#endif
434        return true;
435}
436
437bool util::setTransparentWindowBackground(osgViewer::Viewer* viewer_)
438{
439#ifdef FUNFUNCTIONS_ENABLED
440#ifdef WIN32
441        osgViewer::ViewerBase::Windows wins;
442        viewer_->getWindows(wins);
443        osgViewer::GraphicsHandleWin32* hwnd = dynamic_cast<osgViewer::GraphicsHandleWin32*>(wins[0]);
444        HWND _hwnd = hwnd->getHWND();
445        viewer_->getDisplaySettings()->setMinimumNumAlphaBits(8);
446
447   // Create and populate the Blur Behind structure
448   DWM_BLURBEHIND bb = {0};
449   // Disable Blur Behind and Blur Region;
450   bb.dwFlags = DWM_BB_ENABLE;
451   bb.fEnable = true;
452   bb.hRgnBlur = NULL;
453
454   // Ensable Blur Behind
455   HRESULT hr = DwmEnableBlurBehindWindow(_hwnd, &bb);
456   if (SUCCEEDED(hr))
457      return true;
458   else
459           return false;
460
461#endif
462#endif
463        return true;
464}
465
466std::vector<std::string> util::getTerrainFromXMLConfig(std::string configFilename)
467{
468        xmlDoc* tmpDoc;
469        xmlNode* sceneryNode = util::getSceneryXMLConfig(configFilename, tmpDoc);
470        std::vector<std::string> filenames;
471
472        // Iterate through nodes and search for terrian entry
473        for (xmlNode *cur_node = sceneryNode->children; cur_node; cur_node = cur_node->next)
474        {
475                std::string node_name=reinterpret_cast<const char*>(cur_node->name);
476
477                if(cur_node->type == XML_ELEMENT_NODE && node_name == "terrain")
478                {
479                        xmlAttr  *attr = cur_node->properties;
480                        while ( attr ) 
481                        { 
482                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
483                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
484                                if( attr_name.find("filename") != std::string::npos )
485                                {
486                                        filenames.push_back(attr_value);
487                                }
488                                attr = attr->next; 
489                        }
490                }
491        }// FOR all nodes END
492
493        // Cleanup
494        if(sceneryNode)
495        {
496                xmlFreeDoc(tmpDoc); xmlCleanupParser();
497        }
498
499        return filenames;
500}
501
502std::string util::getAnimationPathFromXMLConfig(std::string configFilename)
503{
504        xmlDoc* tmpDoc;
505        xmlNode* sceneryNode = util::getSceneryXMLConfig(configFilename, tmpDoc);
506        std::string animationpath = "";
507
508        // Iterate through nodes and search for terrian entry
509        for (xmlNode *cur_node = sceneryNode->children; cur_node; cur_node = cur_node->next)
510        {
511                std::string node_name=reinterpret_cast<const char*>(cur_node->name);
512
513                if(cur_node->type == XML_ELEMENT_NODE && node_name == "animationpath")
514                {
515                        xmlAttr  *attr = cur_node->properties;
516                        while ( attr ) 
517                        { 
518                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
519                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
520                                if( attr_name == "filename" )
521                                {
522                                        animationpath = attr_value;
523                                }
524                                attr = attr->next; 
525                        }
526                }
527        }// FOR all nodes END
528
529        // Cleanup
530        if(sceneryNode)
531        {
532                xmlFreeDoc(tmpDoc); xmlCleanupParser();
533        }
534
535        return animationpath;
536}
537
538double util::strToDouble(std::string s)
539{
540        double tmp;
541        std::stringstream sstr(s);
542    if (!(sstr >> tmp))
543        {
544                OSG_ALWAYS << __FUNCTION__ << "Warning:Unable to convert "<< s <<" to double, using 0.0 as default!" << std::endl;
545                return 0.0;
546        }
547        else
548                return tmp;
549}
550
551int util::strToInt(std::string s)
552{
553        int tmp;
554        std::stringstream sstr(s);
555        if (!(sstr >> tmp))
556        {
557                OSG_ALWAYS << __FUNCTION__ << "Warning:Unable to convert "<< s <<" to int, using 0 as default!" << std::endl;
558                return 0;
559        }
560        else
561                return tmp;
562}
563
564bool util::strToBool(std::string s)
565{
566        if(s=="yes")
567                return(true);
568        if(s=="no")
569                return(false);
570        OSG_ALWAYS << __FUNCTION__ << "Warning:Unable to convert "<< s <<" to bool, using false as default!" << std::endl;
571        return(false);
572}
Note: See TracBrowser for help on using the repository browser.