source: osgVisual/include/distortion/visual_distortion.h @ 149

Last change on this file since 149 was 148, checked in by Torben Dannhauer, 14 years ago
File size: 13.7 KB
Line 
1#pragma once
2/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
3 *
4 * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under
5 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
6 * (at your option) any later version.  The full license is in LICENSE file
7 * included with this distribution, and on the openscenegraph.org website.
8 *
9 * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
10 * You have to aquire licenses for all used proprietary modules.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * OpenSceneGraph Public License for more details.
16*/
17
18#include <osg/NodeCallback>
19#include <osg/Node>
20#include <osg/Geode>
21#include <osg/Geometry>
22#include <osg/Texture2D>
23#include <osg/TextureRectangle>
24#include <osg/Notify>
25#include <osg/Referenced>
26
27#include <osgViewer/Viewer>
28
29#include <osgDB/ReadFile>
30#include <osgDB/FileUtils>
31
32#include <osgGA/GUIEventHandler>
33#include <osgGA/GUIActionAdapter>
34
35#include <visual_util.h>
36
37#include <string>
38#include <iostream>
39#include <fstream>
40
41// XML Parser
42#include <stdio.h>
43#include <libxml/parser.h>
44#include <libxml/tree.h>
45
46
47namespace osgVisual
48{
49
50
51//class CameraConfigParser;
52
53/**
54 * \brief This class distorts and blends the rendered image for projection in curved screens and multi channel setups.
55 *
56 * @todo Distortion algorithm seems to be erronous, small artefact lines are visible.
57 *
58 * @author Torben Dannhauer
59 * @date  Jul 2009
60 */ 
61class visual_distortion : public osg::Node
62{
63        #include <leakDetection.h>
64public:
65        /**
66         * \brief Constructor
67         *
68         */ 
69        visual_distortion(osgViewer::Viewer* viewer_, osg::ArgumentParser& arguments_, std::string configFileName);
70
71        /**
72         * \brief Destructor
73         *
74         */ 
75        virtual ~visual_distortion(void);
76
77        bool processXMLConfiguration(); 
78
79        /**
80         * \brief This function parses the arguments for distortion relevant parameters.
81         *
82         * @return : True if parsing was successful.
83         */ 
84        bool processCommandlineparameters();
85
86        /**
87         * \brief This function initializes the distortion node and creates the distortion camera and scene graph.
88         *
89         * @param subgraph : Undistorted scene graph.
90         * @param clearColor : Clear color for distortion.
91         * @return : Group node which contains the distortion and the undistorted scene graph.
92         */ 
93        osg::Group* initialize(osg::Group* subgraph, const osg::Vec4& clearColor );
94
95        /**
96         * \brief This function shuts the distortion module down.
97         *
98         */ 
99        void shutdown();
100
101        /**
102         * \brief This function enabels or disables the distortion
103         */ 
104        void toggleDistortion();
105
106        /**
107         * \brief This functions returns a pointer to the scene camera, which renders the undistorted scene (PRE_RENDER).
108         *
109         * @return Pointer to the scene camera.
110         */ 
111        osg::Camera* getSceneCamera() {return sceneCamera;};
112
113        /**
114         * \brief This function returns the distortedSceneGraph if the distortion module is initialized.
115         *
116         * @return NULL if not Initialized, Otherwith the distorted sceneGraph.
117         */ 
118        osg::Group* getDistortedSceneGraph() { if(initialized) return distortedGraph; else return NULL;};
119
120        /**
121         * \brief The function returns the frustum values which are parsed by the nested cameraConfigParser class.
122         *
123         * @return : Vector of double values which represent the frustum dataset. The order is the standart glu order.
124         */ 
125        std::vector<double> getFrustumDataset() {return parser->getFrustumDataset();};
126                       
127        /**
128         * \brief This function returns the retation values for the rendering camera for XYZ axis in degree.
129         *
130         * @return : Vector of double values which represent the rotation values for XYZ axis in degree.
131         */ 
132        std::vector<double> getRotationDataset() {return parser->getRotationDataset();};
133
134        /**
135         * \brief This function returns the translation values for the rendering camera along the XYZ axis in meter.
136         *
137         * @return : Vector of double values which represent the translation values for XYZ axis in meter.
138         */ 
139        std::vector<double> getTranslationDataset() {return parser->getTranslationDataset();};
140
141private:
142        /**
143         * \brief Callback class for update callback.
144         *
145         * This nested class is used for updating the distortion node every frame by installing this class as updateCallback for the distortion node.
146         * @author Torben Dannhauer
147         * @date  Jul 2009
148         */ 
149        class distortionUpdateCallback : public osg::NodeCallback
150        {
151        public: 
152                /**
153                 * \brief Constructor, for setting the member variables.
154                 *
155                 * @param viewer_ : Pointer to the viewer.
156                 * @param sceneCamera_ : Pointer to the scene camera.
157                 */ 
158                distortionUpdateCallback(osgViewer::Viewer* viewer_, osg::Camera* sceneCamera_)
159                        : viewer(viewer_), sceneCamera(sceneCamera_) {};
160
161                /**
162                 * \brief This function is executed as callback during update traversal.
163                 *
164                 */ 
165                virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
166        private:
167                /**
168                 * Referenced Pointer to the applications viewer.
169                 */ 
170                osg::ref_ptr<osgViewer::Viewer> viewer;
171
172                /**
173                 * Referenced Pointer to the scene camera.
174                 */ 
175                osg::ref_ptr<osg::Camera> sceneCamera;
176        };
177
178        /**
179         * \brief This nested class is a keyboard event adapter which allows distortion toggle. It never blocks the key event, therefore multiple events on a single key are possible.
180         *
181         * @author Torben Dannhauer
182         * @date  Jul 2009
183         */ 
184        class ToggleDistortionKBEventHandler : public osgGA::GUIEventHandler
185        {
186        public:
187                /**
188                 * \brief Constructor
189                 *
190                 * @param distortion_ : Pointer to the distortion class.
191                 * @param viewer_ : Reference to the applications viewer.
192                 */ 
193                ToggleDistortionKBEventHandler(visual_distortion* distortion_): distortion(distortion_) {}
194
195                /**
196                 * \brief This function is executed if an keyboard event appears
197                 *
198                 * @param ea : GUI event adapter.
199                 * @param : GUI action adapter.
200                 * @return : Returns always false to pass the event to other event adapter if installed.
201                 */   
202                virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
203                {
204                        if ( ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN &&  ea.getKey() == 'd' )
205                        {
206                                distortion->toggleDistortion();
207                                return false;
208                        }
209                        else
210                                return false;   // return false means: hand over the event to the next Eventhandler.  True means: absorb the event.
211                }
212
213        private:
214                /**
215                 * Pointer to he distortion class. INside this EventHandler a Referenced Pointer ist _NOT_ used,
216                 * because a circulare reference (distortion->kBEventHandler, kbEventHandler->distortion) would block both pointer to unref.
217                 */ 
218                visual_distortion* distortion;
219        };
220
221        /**
222         * \brief This nested class reads the Projection Designer's project file and extracts the frustum, translation and rotation values
223         *
224         * @author Torben Dannhauer
225         * @date  Aug 2009
226         */ 
227        class CameraConfigParser : public osg::Referenced
228        {
229        public:
230                CameraConfigParser(void)
231                {
232                        configParsed = false;
233                        frustumValues.clear();
234                        rotationValues.clear();
235                        rotationValues.resize(3,0);
236                        translationValues.clear();
237                        translationValues.resize(3,0);
238                }
239
240                virtual ~CameraConfigParser(void) {};
241
242                bool parseConfigFile(const char * filename)
243                {
244                  if (! osgDB::fileExists(filename) )
245                  {
246                          OSG_NOTIFY( osg::FATAL ) << "ERROR: File '" << filename << "' does not exist." << std::endl;
247                          return false;
248                  }
249
250                  frustumValues.clear();
251                  rotationValues.clear();
252                  rotationValues.resize(3,0);
253                  translationValues.clear();
254                  translationValues.resize(3,0);
255
256                  std::string line;
257                  std::ifstream configFile (filename);
258
259                  if (configFile.is_open())
260                  {
261                        while (! configFile.eof() )
262                        {
263                          getline (configFile,line);
264                          //cout << line << endl;
265
266                          // Auf Frustum untersuchen
267                          if( line.find("Frustum") != std::string::npos )
268                          {
269                                  extractFrustum(line);
270                          }
271
272                          // Auf Rotation untersuchen
273                          if( line.find("Rotate") != std::string::npos )
274                          {
275                                 extractRotation(line);
276                          }
277
278                          // Auf Translation untersuchens
279                          if( line.find("Translate") != std::string::npos )
280                          {
281                                 extractTranslation(line);
282                          }
283
284                        }
285                        configFile.close();
286                        configParsed = true;
287                        return true;
288                  }
289                  else 
290                  {
291                          OSG_NOTIFY( osg::FATAL ) << "Unable to open file:" << filename << std::endl;
292                          frustumValues.clear();
293                          configParsed = false;
294                          return false;
295                  }
296                }
297
298                bool extractFrustum(std::string data_)
299                {
300                        data_.replace(0,16,"");         // Delete leading spaces and "Frustum"
301                        data_.replace(data_.length()-1,1,"");   // Delete trailing ";"
302                        for( int i=0; i<6; i++)
303                        {
304                                size_t pos = data_.find(" ");    // Position of first value in string
305                                if( pos == -1) pos = data_.length();
306                                frustumValues.push_back( atof( data_.substr(0, pos).data() ) );
307                                data_.replace(0,pos+1,"");
308                        }
309                        return true;
310                }
311
312                bool extractRotation(std::string data_)
313                {
314                        data_.replace(0,15,"");         // Delete leading spaces and "Rotate"
315                        data_.replace(data_.length()-1,1,"");   // Delete trailing ";"
316
317                        size_t valuePos = data_.find(" ");    // First Value is RotationValue
318                        std::string axis = data_.substr( valuePos+1);
319                        switch(axis.find("1"))
320                        {
321                                case 0: rotationValues[0] = atof( data_.substr(0, valuePos).data() ); // X-Axis
322                                        break;
323                                case 2: rotationValues[1] = atof( data_.substr(0, valuePos).data() ); // Y-Axis
324                                        break;
325                                case 4: rotationValues[2] = atof( data_.substr(0, valuePos).data() ); // Z-Axis
326                                        break;
327                        };
328                        return true;
329                }
330
331                bool extractTranslation(std::string data_)
332                {
333                        data_.replace(0,18,"");         // Delete leading spaces and "Translate"
334                        data_.replace(data_.length()-1,1,"");   // Delete trailing ";"
335                        for( unsigned int i=0;i<translationValues.size(); i++)
336                        {
337                                size_t valuePos = data_.find(" ");
338                                std::string value = data_.substr(0, valuePos);
339                                data_.replace(0,valuePos+1,"");
340                                translationValues[i] = atof( value.data() );
341                        }
342                        return true;
343                }
344
345                std::vector<double> getFrustumDataset() {return(frustumValues);}
346                       
347                std::vector<double> getRotationDataset() {return(rotationValues);}
348
349                std::vector<double> getTranslationDataset() {return(translationValues);}
350
351                bool isConfigParsed() {return configParsed;};
352        private:
353                bool configParsed;
354                std::vector<double> frustumValues;
355                std::vector<double> rotationValues;
356                std::vector<double> translationValues;
357        };
358
359
360
361        /**
362         * Updatecallback as member variable of this class.
363         */ 
364        osg::ref_ptr<distortionUpdateCallback> updateCallback;
365
366        /**
367         * Keyboard Eventhandler for distortion toggle.
368         */ 
369        //osg::ref_ptr<ToggleDistortionKBEventHandler> kBEventHandler;
370        ToggleDistortionKBEventHandler* kBEventHandler;
371
372        /**
373         * \brief This functions creates the distortion environment.
374         *
375         * @param subgraph : Undistorted scene graph to distort.
376         * @param clearColor : OpenGL clear color to use for the distortion.
377         * @return : Group node which contains the distortion and the undistorted scene graph.
378         */ 
379        osg::Group* createPreRenderSubGraph(osg::Group* subgraph, const osg::Vec4& clearColor );
380
381        /**
382         * \brief This function loads a shader source file
383         *
384         * @param shader : Shader to load source in
385         * @param fileName : Filename of shader source file.
386         * @return : Returns true if successful.
387         */ 
388        bool loadShaderSource( osg::Shader* shader, const std::string& fileName );
389
390        /**
391         * \brief This function loads a shader Texture file
392         *
393         * @param fileName : Texture file to load.
394         * @return : Returns the loaded Texture.
395         */ 
396        osg::Texture* loadTexture( const std::string& fileName );
397       
398        /**
399         * Referenced Pointer to the loaded distortion Map
400         */ 
401        osg::ref_ptr<osg::Texture> distortMapTexture;
402
403        /**
404         * Referenced Pointer to the loaded blend map
405         */ 
406        osg::ref_ptr<osg::Texture> blendMapTexture;
407
408
409        /**
410         * Flag which indicates the initialization status
411         */ 
412        bool initialized;
413
414        /**
415         * Flag that indicates if distortion is actually enabled. This is imported for the toggleDistortion() function.
416         */ 
417        bool distortionEnabled;
418
419        /**
420         * Reference pointer to the distorted scene graph.
421         */ 
422        osg::ref_ptr<osg::Group> distortedGraph;
423
424        /**
425         * Reference pointer to the undistorted scene graph.
426         */ 
427        osg::ref_ptr<osg::Group> cleanGraph;
428
429        /**
430         * Reference pointer to the scen camera (PRE_RENDER)
431         */ 
432        osg::ref_ptr<osg::Camera> sceneCamera;
433
434        /**
435         * Referenced pointer to the main applications viewer
436         */ 
437        osg::ref_ptr<osgViewer::Viewer> viewer;
438
439        /**
440         * Parser object for parsing the camera configuration file which controlls frustum and camera PAT
441         */ 
442        osg::ref_ptr<CameraConfigParser> parser;
443
444        /**
445         * Texture width for render to texture (RTT).
446         */ 
447        unsigned tex_width;
448
449        /**
450         * Texture height for using render to texture (RTT).
451         */ 
452    unsigned tex_height;
453
454        /**
455         * Indicates of texture rectangle should be used.
456         */ 
457        bool useTextureRectangle;
458
459        /**
460         * Indicates if shader distortion should be used.
461         */ 
462        bool useShaderDistortion;
463
464        /**
465         * Indicates if high definition rendering shold be used.
466         */ 
467        bool useHDR;
468
469        /**
470         * Filename of the distorion map.
471         */ 
472        std::string distortMapFileName;
473
474        /**
475         * Filename of the blend map.
476         */ 
477        std::string blendMapFileName;
478
479        /**
480         * XML config filename
481         */ 
482        std::string configFileName;
483
484        /**
485         * Target implementation which should be used to distort.
486         */ 
487        osg::Camera::RenderTargetImplementation renderImplementation;
488
489        /**
490         * Reference to the global ArgumentParser.
491         */ 
492        osg::ArgumentParser& arguments;
493};
494
495}       // END NAMESPACE
Note: See TracBrowser for help on using the repository browser.