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

Last change on this file since 47 was 32, checked in by Torben Dannhauer, 15 years ago

Adding first version of osgVisual!!

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