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

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

start to move osgVisual from argument based configuratiobn to xml file based configuration

File size: 12.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::getModuleXMLConfig(std::string configFilename, std::string moduleName, 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        if(moduleName == "")
41        {
42                OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : Invalid Module Filename!" << std::endl;
43                return NULL;
44        }
45
46        // It is a valid XML document?
47        doc = xmlReadFile(configFilename.c_str(), NULL, 0);     
48        if (doc == NULL)
49        {
50                OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : " << configFilename << " is not a valid XML file!" << std::endl;
51                return NULL;
52        }
53
54        //  Get the root element node
55        root_element = xmlDocGetRootElement(doc);
56
57        // Check if it is an osgVisual configuration file
58        std::string node_name=reinterpret_cast<const char*>(root_element->name);
59        if(!(root_element->type == XML_ELEMENT_NODE && node_name == "osgvisualconfiguration"))
60        {
61                OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : " << configFilename << " is not an osgVisual configuration file!" << std::endl;
62                return NULL;
63        }
64
65        // 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
66        xmlNode* tmpNode = checkXMLNodeChildrenForModule(root_element, moduleName);
67
68        if( !tmpNode ) // if no valid node was found: clena up. Otherwise: the caller has to clean up.
69        {
70                xmlFreeDoc(doc);        // free the document
71                xmlCleanupParser();     // Free the global variables that may have been allocated by the parser.
72                return NULL;
73        }
74        else
75                return tmpNode;
76
77}
78
79xmlNode* util::checkXMLNodeChildrenForModule(xmlNode* node, std::string moduleName)
80{
81        for (xmlNode *cur_node = node; cur_node; cur_node = cur_node->next)     // iterate through all elements
82        {
83                // Is the node the one we are searching for?
84                if (cur_node->type == XML_ELEMENT_NODE)
85                {
86                        std::string node_name=reinterpret_cast<const char*>(cur_node->name);
87                        if (node_name == "module")
88                        {
89                                OSG_DEBUG << "XML node module found" << std::endl;
90                                return cur_node;
91                        }
92                        else    // Otherwise: check its children..
93                        {
94                                xmlNode* tmp_XmlNode = checkXMLNodeChildrenForModule(cur_node->children, moduleName);
95                                if(tmp_XmlNode)
96                                        return tmp_XmlNode;
97                        }
98                }       // IF NODE TYPE = ELEMENT END
99
100                // Proceed with next node in this loop.
101        }
102}
103
104osg::Node* util::findNamedNode(const std::string& searchName_, osg::Node* currNode_)
105{
106   osg::Group* currGroup;
107   osg::Node* foundNode;
108
109   // check to see if we have a valid (non-NULL) node.
110   // if we do have a null node, return NULL.
111   if ( !currNode_)
112   {
113      return NULL;
114   }
115
116   // We have a valid node, check to see if this is the node we
117   // are looking for. If so, return the current node.
118   if (currNode_->getName() == searchName_)
119   {
120      return currNode_;
121   }
122
123   // We have a valid node, but not the one we are looking for.
124   // Check to see if it has children (non-leaf node). If the node
125   // has children, check each of the child nodes by recursive call.
126   // If one of the recursive calls returns a non-null value we have
127   // found the correct node, so return this node.
128   // If we check all of the children and have not found the node,
129   // return NULL
130   currGroup = currNode_->asGroup(); // returns NULL if not a group.
131   if ( currGroup ) 
132   {
133      for (unsigned int i = 0 ; i < currGroup->getNumChildren(); i ++)
134      { 
135         foundNode = findNamedNode(searchName_, currGroup->getChild(i));
136         if (foundNode)
137                 {
138                         std::cout << "Node gefunden in Ebene: " << i << std::endl;
139            return foundNode; // found a match!
140                }
141      }
142      return NULL; // We have checked each child node - no match found.
143   }
144   else 
145   {
146      return NULL; // leaf node, no match
147   }
148}
149
150osg::ref_ptr<osg::Geode> util::getDemoCylinder(double length_, double width_, osg::Vec3 offset_ )
151{
152        osg::ref_ptr<osg::Geode> cyl = new osg::Geode();
153        osg::ref_ptr<osg::ShapeDrawable> shape = new osg::ShapeDrawable(new osg::Cylinder( offset_, width_, length_ ));
154        osg::Vec4 color = osg::Vec4(255.0, 0.0, 0.0, 1.0);
155        shape->setColor( color );
156        cyl->addDrawable( shape );
157
158        return cyl;
159}
160
161osg::ref_ptr<osg::Geode> util::getDemoSphere(double radius_, osg::Vec3 offset_ )
162{
163        osg::ref_ptr<osg::Geode> sphere = new osg::Geode();
164        osg::ref_ptr<osg::ShapeDrawable> shape = new osg::ShapeDrawable(new osg::Sphere( offset_, radius_ ) );
165        osg::Vec4 color = osg::Vec4(255.0, 0.0, 0.0, 1.0);
166        shape->setColor( color );
167        sphere->addDrawable( shape );
168
169        return sphere;
170}
171
172bool util::intersect(const osg::Vec3d& start_, const osg::Vec3d& end_, osg::Vec3d& intersection_, osg::Node* node_, osg::Node::NodeMask intersectTraversalMask_ )
173{
174        osg::ref_ptr<osgUtil::LineSegmentIntersector> lsi = new osgUtil::LineSegmentIntersector(start_,end_);
175
176        osgUtil::IntersectionVisitor iv(lsi.get());
177        iv.setTraversalMask(intersectTraversalMask_);
178   
179        node_->accept(iv);
180   
181        if (lsi->containsIntersections())
182        {
183                intersection_ = lsi->getIntersections().begin()->getWorldIntersectPoint();
184                return true;    // Intersect found
185        }
186        return false;   // No intersect found
187}
188
189bool util::queryHeightOfTerrain(double& hot_, osg::Node* rootNode_, double lat_, double lon_, osg::Node::NodeMask traversalMask_)
190{
191        // Get ellipsoid model
192        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
193        if ( !csn )
194        {
195                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightOfTerrain() :: Invalid CSN!" << std::endl;
196                return false;
197        }
198        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
199        if ( !ellipsoid )
200        {
201                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightOfTerrain() :: Invalid ellipsoid!" << std::endl;
202                return false;
203        }
204
205        // Setup both endpoints of intersect line
206        double X,Y,Z;
207        ellipsoid->convertLatLongHeightToXYZ(lat_, lon_, 30000, X, Y, Z);
208        osg::Vec3d s = osg::Vec3d(X, Y, Z);
209        ellipsoid->convertLatLongHeightToXYZ(lat_, lon_, -30000, X, Y, Z);
210        osg::Vec3d e = osg::Vec3d(X, Y, Z);
211
212        // Query intersection point
213        osg::Vec3d ip;
214        if ( util::intersect(s, e, ip, rootNode_, traversalMask_) )
215        {
216                double lat2_, lon2_;
217                ellipsoid->convertXYZToLatLongHeight( ip.x(), ip.y(), ip.z(), lat2_, lon2_, hot_ );     // Convert Intersection Point back to Lat Lon, HOT.
218                //OSG_NOTIFY(osg::ALWAYS) << "lat: "<< osg::RadiansToDegrees(lat2_) <<", Lon: " << osg::RadiansToDegrees(lon2_) << ", Hot: " << hot_ << std::endl;
219                return true;
220        }
221
222        // If no intersection point found: set HOT to zero and return false.
223        hot_ = 0;
224        return false;
225}
226
227bool util::queryHeightAboveTerrainInWGS84(double& hat_, osg::Node* rootNode_, double lat_, double lon_, double height_, osg::Node::NodeMask traversalMask_)
228{
229        // Get HOT by asking util::queryHeightOfTerrain() :)
230        double HOT;
231        if ( !util::queryHeightOfTerrain(HOT, rootNode_, lat_, lon_, traversalMask_) )
232        {
233                OSG_NOTIFY( osg::INFO ) << "util::queryHeightAboveTerrainInWGS84() :: Unable to get HOT, will use 0 for HOT!" << std::endl;
234        }
235
236        // Calculate HAT
237        hat_ = height_ - HOT;
238        return true;
239}
240
241bool util::queryHeightAboveTerrainInWorld(double& hat_, osg::Node* rootNode_, double x_, double y_, double z_, osg::Node::NodeMask traversalMask_)
242{
243        // Get ellipsoid model
244        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
245        if ( !csn )
246        {
247                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightAboveTerrainInWorld() :: Invalid CSN!" << std::endl;
248                return false;
249        }
250        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
251        if ( !ellipsoid )
252        {
253                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightAboveTerrainInWorld() :: Invalid ellipsoid!" << std::endl;
254                return false;
255        }
256
257        // Transform XYZ into LatLonHeight
258        double lat_, lon_, height_;
259        ellipsoid->convertXYZToLatLongHeight(x_, y_, z_, lat_, lon_, height_);
260
261        // ask util::queryHeightAboveTerrainInWGS84() to calc HAT :)
262        if( !util::queryHeightAboveTerrainInWGS84(hat_, rootNode_, lat_, lon_, height_, traversalMask_ ) )
263        {
264                OSG_NOTIFY( osg::FATAL ) << "util::queryHeightAboveTerrainInWorld() :: Unable to get HAT!" << std::endl;
265                return false;
266        }
267
268        return true;
269}
270
271bool util::calculateEarthRadiusAtWGS84Coordinate(double lat_, double lon_, osg::Node* rootNode_, double& radius_)
272{
273        // Calculate radius:
274        double x, y, z;
275       
276        if ( util::calculateXYZAtWGS84Coordinate(lat_, lon_, 0.0, rootNode_, x, y, z) )
277        {
278                radius_ = sqrt( pow(x, 2) + pow(y, 2) + pow(z, 2) );
279                return true;
280        }
281        else
282        {
283                OSG_NOTIFY( osg::FATAL ) << "util::calculateEarthRadiusAtWGS84Coordinate() :: Unable to calculate Earth Radius!" << std::endl;
284                return false;
285        }
286}
287
288bool util::calculateXYZAtWGS84Coordinate(double lat_, double lon_, double height_, osg::Node* rootNode_, double& x_, double& y_, double& z_)
289{
290        // Get ellipsoid model
291        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
292        if ( !csn )
293                return false;
294        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
295        if ( !ellipsoid )
296                return false;
297
298        // Calculate xyz:
299        ellipsoid->convertLatLongHeightToXYZ( lat_, lon_, height_, x_, y_, z_);
300        return true;
301}
302
303bool util::getWGS84ofCamera( osg::Camera* camera_, osg::Node* rootNode_, double& lat_, double& lon_, double& height_ )
304{
305        // Get ellipsoid model
306        osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
307        if ( !csn )
308                return false;
309        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
310        if ( !ellipsoid )
311                return false;
312
313        osg::Vec3d eye, dir, up;
314        camera_->getViewMatrixAsLookAt(eye,dir,up); // Get XYZ from camera
315        ellipsoid->convertXYZToLatLongHeight(eye.x(), eye.y(), eye.z(), lat_, lon_, height_);
316        return true;
317}
318
319void util::getXYZofCamera( osg::Camera* camera_, double& x_, double& y_, double& z_ )
320{
321        osg::Vec3d eye, dir, up;
322        camera_->getViewMatrixAsLookAt(eye,dir,up); // Get XYZ from camera
323        x_ = eye.x();
324        y_ = eye.y();
325        z_ = eye.z();
326}
327
328bool util::removeClosebuttonOnGLWindow(osgViewer::Viewer* viewer_)
329{
330#ifdef FUNFUNCTIONS_ENABLED
331#ifdef WIN32
332        osgViewer::ViewerBase::Windows wins;
333        viewer_->getWindows(wins);
334        osgViewer::GraphicsHandleWin32* hwnd = dynamic_cast<osgViewer::GraphicsHandleWin32*>(wins[0]);
335       
336        HMENU hMenu = GetSystemMenu(hwnd->getHWND(), FALSE);
337        ::EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | (MF_DISABLED | MF_GRAYED)); 
338#endif
339#endif
340        return true;
341}
342
343bool util::setTransparentWindowBackground(osgViewer::Viewer* viewer_)
344{
345#ifdef FUNFUNCTIONS_ENABLED
346#ifdef WIN32
347        osgViewer::ViewerBase::Windows wins;
348        viewer_->getWindows(wins);
349        osgViewer::GraphicsHandleWin32* hwnd = dynamic_cast<osgViewer::GraphicsHandleWin32*>(wins[0]);
350        HWND _hwnd = hwnd->getHWND();
351        viewer_->getDisplaySettings()->setMinimumNumAlphaBits(8);
352
353   // Create and populate the Blur Behind structure
354   DWM_BLURBEHIND bb = {0};
355   // Disable Blur Behind and Blur Region;
356   bb.dwFlags = DWM_BB_ENABLE;
357   bb.fEnable = true;
358   bb.hRgnBlur = NULL;
359
360   // Ensable Blur Behind
361   HRESULT hr = DwmEnableBlurBehindWindow(_hwnd, &bb);
362   if (SUCCEEDED(hr))
363      return true;
364   else
365           return false;
366
367#endif
368#endif
369        return true;
370}
Note: See TracBrowser for help on using the repository browser.