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

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