source: osgVisual/trunk/include/distortion/visual_distortion.h @ 191

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