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

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