source: osgVisual/src/util/visual_util.cpp @ 151

Last change on this file since 151 was 151, checked in by Torben Dannhauer, 13 years ago
File size: 15.0 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)
92{
93        doc = NULL;
94        xmlNode *root_element = NULL;
95
96        // Check for valid parameters
97        if(configFilename == "")
98        {
99                OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : Invalid Configuration Filename!" << std::endl;
100                return NULL;
101        }
102        if(moduleName == "")
103        {
104                OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : Invalid Module Filename!" << std::endl;
105                return NULL;
106        }
107
108        // It is a valid XML document?
109        doc = xmlReadFile(configFilename.c_str(), NULL, 0);     
110        if (doc == NULL)
111        {
112                OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : " << configFilename << " is not a valid XML file!" << std::endl;
113                return NULL;
114        }
115
116        //  Get the root element node
117        root_element = xmlDocGetRootElement(doc);
118
119        // Check if it is an osgVisual configuration file
120        std::string node_name=reinterpret_cast<const char*>(root_element->name);
121        if(!(root_element->type == XML_ELEMENT_NODE && node_name == "osgvisualconfiguration"))
122        {
123                OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : " << configFilename << " is not an osgVisual configuration file!" << std::endl;
124                return NULL;
125        }
126
127        // 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
128        xmlNode* tmpNode = checkXMLNodeChildrenForModule(root_element, moduleName);
129
130        if( !tmpNode ) // if no valid node was found: clena up. Otherwise: the caller has to clean up.
131        {
132                xmlFreeDoc(doc);        // free the document
133                xmlCleanupParser();     // Free the global variables that may have been allocated by the parser.
134                return NULL;
135        }
136        else
137                return tmpNode;
138
139}
140
141xmlNode* util::checkXMLNodeChildrenForModule(xmlNode* node, std::string moduleName)
142{
143        for (xmlNode *cur_node = node; cur_node; cur_node = cur_node->next)     // iterate through all elements
144        {
145                // Is the node the one we are searching for?
146                if (cur_node->type == XML_ELEMENT_NODE)
147                {
148                        // Extract Node Name and the first attribute: "module name"
149                        std::string node_name = reinterpret_cast<const char*>(cur_node->name);
150                        std::string modName = "";
151                        xmlAttr  *attr = cur_node->properties;
152                        while ( attr ) 
153                        { 
154                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
155                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
156                                if( attr_name == "name" )
157                                        modName = attr_value;
158                                attr = attr->next;
159                        }
160                       
161                        // Check each node for the searched module
162                        if (node_name == "module" && modName == moduleName)
163                        {
164                                // Check if the module is active
165                                xmlAttr  *attr = cur_node->properties;
166                                while ( attr ) 
167                                { 
168                                        std::string attr_name=reinterpret_cast<const char*>(attr->name);
169                                        std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
170                                        if( attr_name == "enabled" && attr_value == "yes" )
171                                        {
172                                                OSG_ALWAYS << "Found XML module configuration for " << moduleName << std::endl;
173                                                return cur_node;
174                                        }
175                                        if( attr_name == "enabled" && attr_value == "no" )
176                                        {
177                                                OSG_ALWAYS << "Found XML module configuration for " << moduleName << ", but it is DISABLED." << std::endl;
178                                                return NULL;
179                                        }
180                                        attr = attr->next;
181                                }
182                        }
183                        else    // Otherwise: check its children..
184                        {
185                                xmlNode* tmp_XmlNode = checkXMLNodeChildrenForModule(cur_node->children, moduleName);
186                                if(tmp_XmlNode)
187                                        return tmp_XmlNode;
188                        }
189                }       // IF NODE TYPE = ELEMENT END
190
191                // Proceed with next node in this loop.
192        }
193        return NULL;
194}
195
196osg::Node* util::findNamedNode(const std::string& searchName_, osg::Node* currNode_)
197{
198   osg::Group* currGroup;
199   osg::Node* foundNode;
200
201   // check to see if we have a valid (non-NULL) node.
202   // if we do have a null node, return NULL.
203   if ( !currNode_)
204   {
205      return NULL;
206   }
207
208   // We have a valid node, check to see if this is the node we
209   // are looking for. If so, return the current node.
210   if (currNode_->getName() == searchName_)
211   {
212      return currNode_;
213   }
214
215   // We have a valid node, but not the one we are looking for.
216   // Check to see if it has children (non-leaf node). If the node
217   // has children, check each of the child nodes by recursive call.
218   // If one of the recursive calls returns a non-null value we have
219   // found the correct node, so return this node.
220   // If we check all of the children and have not found the node,
221   // return NULL
222   currGroup = currNode_->asGroup(); // returns NULL if not a group.
223   if ( currGroup ) 
224   {
225      for (unsigned int i = 0 ; i < currGroup->getNumChildren(); i ++)
226      { 
227         foundNode = findNamedNode(searchName_, currGroup->getChild(i));
228         if (foundNode)
229                 {
230                         std::cout << "Node gefunden in Ebene: " << i << std::endl;
231            return foundNode; // found a match!
232                }
233      }
234      return NULL; // We have checked each child node - no match found.
235   }
236   else 
237   {
238      return NULL; // leaf node, no match
239   }
240}
241
242osg::ref_ptr<osg::Geode> util::getDemoCylinder(double length_, double width_, osg::Vec3 offset_ )
243{
244        osg::ref_ptr<osg::Geode> cyl = new osg::Geode();
245        osg::ref_ptr<osg::ShapeDrawable> shape = new osg::ShapeDrawable(new osg::Cylinder( offset_, width_, length_ ));
246        osg::Vec4 color = osg::Vec4(255.0, 0.0, 0.0, 1.0);
247        shape->setColor( color );
248        cyl->addDrawable( shape );
249
250        return cyl;
251}
252
253osg::ref_ptr<osg::Geode> util::getDemoSphere(double radius_, osg::Vec3 offset_ )
254{
255        osg::ref_ptr<osg::Geode> sphere = new osg::Geode();
256        osg::ref_ptr<osg::ShapeDrawable> shape = new osg::ShapeDrawable(new osg::Sphere( offset_, radius_ ) );
257        osg::Vec4 color = osg::Vec4(255.0, 0.0, 0.0, 1.0);
258        shape->setColor( color );
259        sphere->addDrawable( shape );
260
261        return sphere;
262}
263
264bool util::intersect(const osg::Vec3d& start_, const osg::Vec3d& end_, osg::Vec3d& intersection_, osg::Node* node_, osg::Node::NodeMask intersectTraversalMask_ )
265{
266        osg::ref_ptr<osgUtil::LineSegmentIntersector> lsi = new osgUtil::LineSegmentIntersector(start_,end_);
267
268        osgUtil::IntersectionVisitor iv(lsi.get());
269        iv.setTraversalMask(intersectTraversalMask_);
270   
271        node_->accept(iv);
272   
273        if (lsi->containsIntersections())
274        {
275                intersection_ = lsi->getIntersections().begin()->getWorldIntersectPoint();
276                return true;    // Intersect found
277        }
278        return false;   // No intersect found
279}
280
281bool util::queryHeightOfTerrain(double& hot_, osg::Node* rootNode_, double lat_, double lon_, osg::Node::NodeMask traversalMask_)
282{
283        // Get ellipsoid model
284        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
285        if ( !csn )
286        {
287                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightOfTerrain() :: Invalid CSN!" << std::endl;
288                return false;
289        }
290        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
291        if ( !ellipsoid )
292        {
293                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightOfTerrain() :: Invalid ellipsoid!" << std::endl;
294                return false;
295        }
296
297        // Setup both endpoints of intersect line
298        double X,Y,Z;
299        ellipsoid->convertLatLongHeightToXYZ(lat_, lon_, 30000, X, Y, Z);
300        osg::Vec3d s = osg::Vec3d(X, Y, Z);
301        ellipsoid->convertLatLongHeightToXYZ(lat_, lon_, -30000, X, Y, Z);
302        osg::Vec3d e = osg::Vec3d(X, Y, Z);
303
304        // Query intersection point
305        osg::Vec3d ip;
306        if ( util::intersect(s, e, ip, rootNode_, traversalMask_) )
307        {
308                double lat2_, lon2_;
309                ellipsoid->convertXYZToLatLongHeight( ip.x(), ip.y(), ip.z(), lat2_, lon2_, hot_ );     // Convert Intersection Point back to Lat Lon, HOT.
310                //OSG_NOTIFY(osg::ALWAYS) << "lat: "<< osg::RadiansToDegrees(lat2_) <<", Lon: " << osg::RadiansToDegrees(lon2_) << ", Hot: " << hot_ << std::endl;
311                return true;
312        }
313
314        // If no intersection point found: set HOT to zero and return false.
315        hot_ = 0;
316        return false;
317}
318
319bool util::queryHeightAboveTerrainInWGS84(double& hat_, osg::Node* rootNode_, double lat_, double lon_, double height_, osg::Node::NodeMask traversalMask_)
320{
321        // Get HOT by asking util::queryHeightOfTerrain() :)
322        double HOT;
323        if ( !util::queryHeightOfTerrain(HOT, rootNode_, lat_, lon_, traversalMask_) )
324        {
325                OSG_NOTIFY( osg::INFO ) << "util::queryHeightAboveTerrainInWGS84() :: Unable to get HOT, will use 0 for HOT!" << std::endl;
326        }
327
328        // Calculate HAT
329        hat_ = height_ - HOT;
330        return true;
331}
332
333bool util::queryHeightAboveTerrainInWorld(double& hat_, osg::Node* rootNode_, double x_, double y_, double z_, osg::Node::NodeMask traversalMask_)
334{
335        // Get ellipsoid model
336        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
337        if ( !csn )
338        {
339                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightAboveTerrainInWorld() :: Invalid CSN!" << std::endl;
340                return false;
341        }
342        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
343        if ( !ellipsoid )
344        {
345                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightAboveTerrainInWorld() :: Invalid ellipsoid!" << std::endl;
346                return false;
347        }
348
349        // Transform XYZ into LatLonHeight
350        double lat_, lon_, height_;
351        ellipsoid->convertXYZToLatLongHeight(x_, y_, z_, lat_, lon_, height_);
352
353        // ask util::queryHeightAboveTerrainInWGS84() to calc HAT :)
354        if( !util::queryHeightAboveTerrainInWGS84(hat_, rootNode_, lat_, lon_, height_, traversalMask_ ) )
355        {
356                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightAboveTerrainInWorld() :: Unable to get HAT!" << std::endl;
357                return false;
358        }
359
360        return true;
361}
362
363bool util::calculateEarthRadiusAtWGS84Coordinate(double lat_, double lon_, osg::Node* rootNode_, double& radius_)
364{
365        // Calculate radius:
366        double x, y, z;
367       
368        if ( util::calculateXYZAtWGS84Coordinate(lat_, lon_, 0.0, rootNode_, x, y, z) )
369        {
370                radius_ = sqrt( pow(x, 2) + pow(y, 2) + pow(z, 2) );
371                return true;
372        }
373        else
374        {
375                OSG_NOTIFY( osg::FATAL ) << "util::calculateEarthRadiusAtWGS84Coordinate() :: Unable to calculate Earth Radius!" << std::endl;
376                return false;
377        }
378}
379
380bool util::calculateXYZAtWGS84Coordinate(double lat_, double lon_, double height_, osg::Node* rootNode_, double& x_, double& y_, double& z_)
381{
382        // Get ellipsoid model
383        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
384        if ( !csn )
385                return false;
386        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
387        if ( !ellipsoid )
388                return false;
389
390        // Calculate xyz:
391        ellipsoid->convertLatLongHeightToXYZ( lat_, lon_, height_, x_, y_, z_);
392        return true;
393}
394
395bool util::getWGS84ofCamera( osg::Camera* camera_, osg::Node* rootNode_, double& lat_, double& lon_, double& height_ )
396{
397        // Get ellipsoid model
398        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
399        if ( !csn )
400                return false;
401        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
402        if ( !ellipsoid )
403                return false;
404
405        osg::Vec3d eye, dir, up;
406        camera_->getViewMatrixAsLookAt(eye,dir,up); // Get XYZ from camera
407        ellipsoid->convertXYZToLatLongHeight(eye.x(), eye.y(), eye.z(), lat_, lon_, height_);
408        return true;
409}
410
411void util::getXYZofCamera( osg::Camera* camera_, double& x_, double& y_, double& z_ )
412{
413        osg::Vec3d eye, dir, up;
414        camera_->getViewMatrixAsLookAt(eye,dir,up); // Get XYZ from camera
415        x_ = eye.x();
416        y_ = eye.y();
417        z_ = eye.z();
418}
419
420bool util::removeClosebuttonOnGLWindow(osgViewer::Viewer* viewer_)
421{
422#ifdef FUNFUNCTIONS_ENABLED
423#ifdef WIN32
424        osgViewer::ViewerBase::Windows wins;
425        viewer_->getWindows(wins);
426        osgViewer::GraphicsHandleWin32* hwnd = dynamic_cast<osgViewer::GraphicsHandleWin32*>(wins[0]);
427       
428        HMENU hMenu = GetSystemMenu(hwnd->getHWND(), FALSE);
429        ::EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | (MF_DISABLED | MF_GRAYED)); 
430#endif
431#endif
432        return true;
433}
434
435bool util::setTransparentWindowBackground(osgViewer::Viewer* viewer_)
436{
437#ifdef FUNFUNCTIONS_ENABLED
438#ifdef WIN32
439        osgViewer::ViewerBase::Windows wins;
440        viewer_->getWindows(wins);
441        osgViewer::GraphicsHandleWin32* hwnd = dynamic_cast<osgViewer::GraphicsHandleWin32*>(wins[0]);
442        HWND _hwnd = hwnd->getHWND();
443        viewer_->getDisplaySettings()->setMinimumNumAlphaBits(8);
444
445   // Create and populate the Blur Behind structure
446   DWM_BLURBEHIND bb = {0};
447   // Disable Blur Behind and Blur Region;
448   bb.dwFlags = DWM_BB_ENABLE;
449   bb.fEnable = true;
450   bb.hRgnBlur = NULL;
451
452   // Ensable Blur Behind
453   HRESULT hr = DwmEnableBlurBehindWindow(_hwnd, &bb);
454   if (SUCCEEDED(hr))
455      return true;
456   else
457           return false;
458
459#endif
460#endif
461        return true;
462}
Note: See TracBrowser for help on using the repository browser.