source: experimental/distortionNG/DistortionSetupStrategyProjectionDesigner.cpp @ 411

Last change on this file since 411 was 411, checked in by Torben Dannhauer, 12 years ago
File size: 11.1 KB
Line 
1/* osgVisual test. distortionNG, experimental.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19#include <osg/Vec3d>
20#include <osg/ImageUtils>
21#include <osgDB/ReadFile>
22#include <osgDB/fstream>
23
24#include "DistortionSetupStrategyProjectionDesigner.h"
25
26CameraConfigParser::CameraConfigParser()
27{
28        configParsed = false;
29        frustumValues.clear();
30        rotationValues.clear();
31        rotationValues.resize(3,0);
32        translationValues.clear();
33        translationValues.resize(3,0);
34}
35
36bool CameraConfigParser::parseConfigFile(const char * filename)
37{
38        if (! osgDB::fileExists(filename) )
39        {
40                OSG_NOTIFY( osg::FATAL ) << "ERROR: File '" << filename << "' does not exist." << std::endl;
41                return false;
42        }
43
44        frustumValues.clear();
45        rotationValues.clear();
46        rotationValues.resize(3,0);
47        translationValues.clear();
48        translationValues.resize(3,0);
49
50        std::string line;
51        std::ifstream configFile (filename);
52
53        if (configFile.is_open())
54        {
55                while (! configFile.eof() )
56                {
57                        getline (configFile,line);
58
59                        // Auf Frustum untersuchen
60                        if( line.find("Frustum") != std::string::npos )
61                        {
62                                extractFrustum(line);
63                        }
64
65                        // Auf Rotation untersuchen
66                        if( line.find("Rotate") != std::string::npos )
67                        {
68                                extractRotation(line);
69                        }
70
71                        // Auf Translation untersuchens
72                        if( line.find("Translate") != std::string::npos )
73                        {
74                                extractTranslation(line);
75                        }
76                }
77                configFile.close();
78                configParsed = true;
79                return true;
80        }
81        else 
82        {
83                OSG_NOTIFY( osg::FATAL ) << "Unable to open file:" << filename << std::endl;
84                frustumValues.clear();
85                configParsed = false;
86                return false;
87        }
88}
89
90bool CameraConfigParser::extractFrustum(std::string data_)
91{
92        data_.replace(0,16,"");         // Delete leading spaces and "Frustum"
93        data_.replace(data_.length()-1,1,"");   // Delete trailing ";"
94        for( int i=0; i<6; i++)
95        {
96                size_t pos = data_.find(" ");    // Position of first value in string
97                if( pos == -1) pos = data_.length();
98                frustumValues.push_back( atof( data_.substr(0, pos).data() ) );
99                data_.replace(0,pos+1,"");
100        }
101        return true;
102}
103
104bool CameraConfigParser::extractRotation(std::string data_)
105{
106        data_.replace(0,15,"");         // Delete leading spaces and "Rotate"
107        data_.replace(data_.length()-1,1,"");   // Delete trailing ";"
108
109        size_t valuePos = data_.find(" ");    // First Value is RotationValue
110        std::string axis = data_.substr( valuePos+1);
111        switch(axis.find("1"))
112        {
113                case 0: rotationValues[0] = atof( data_.substr(0, valuePos).data() ); // X-Axis
114                        break;
115                case 2: rotationValues[1] = atof( data_.substr(0, valuePos).data() ); // Y-Axis
116                        break;
117                case 4: rotationValues[2] = atof( data_.substr(0, valuePos).data() ); // Z-Axis
118                        break;
119        };
120        return true;
121}
122
123bool CameraConfigParser::extractTranslation(std::string data_)
124{
125        data_.replace(0,18,"");         // Delete leading spaces and "Translate"
126        data_.replace(data_.length()-1,1,"");   // Delete trailing ";"
127        for( unsigned int i=0;i<translationValues.size(); i++)
128        {
129                size_t valuePos = data_.find(" ");
130                std::string value = data_.substr(0, valuePos);
131                data_.replace(0,valuePos+1,"");
132                translationValues[i] = atof( value.data() );
133        }
134        return true;
135}
136
137DistortionSetupStrategyProjectionDesigner::DistortionSetupStrategyProjectionDesigner()
138{
139        _blendmapFilename = "";
140        _frustumFilename = "";
141        _distortionFilename = "";
142        distortMapTexture = NULL;
143        _distortionInitialized=false;
144        parser = new CameraConfigParser();
145}
146
147DistortionSetupStrategyProjectionDesigner::~DistortionSetupStrategyProjectionDesigner()
148{
149
150}
151
152osg::Texture* DistortionSetupStrategyProjectionDesigner::loadTexture( const std::string& fileName )
153{
154        std::string foundFileName = osgDB::findDataFile(fileName);
155        if (foundFileName.length() != 0 )
156        {
157                // load distortion map texture file
158                osg::Image* image = osgDB::readImageFile(foundFileName);
159                if (image)
160                {
161                        osg::Texture2D* texture = new osg::Texture2D;
162                        texture->setImage(image);
163                        texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST);
164                        texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST);
165                        texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
166                        texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
167                        return texture;
168                }
169        }
170
171        OSG_NOTIFY(osg::WARN) << "File \"" << fileName << "\" not found." << std::endl;
172
173        return NULL;
174}
175
176void DistortionSetupStrategyProjectionDesigner::setDistortionInputFiles(std::string distortionFile, std::string blendmapFile, std::string frustumFile)
177{
178        _blendmapFilename = blendmapFile;
179        _frustumFilename = frustumFile;
180        _distortionFilename = distortionFile;
181}
182
183void DistortionSetupStrategyProjectionDesigner::delegateDistortionSetup(osgViewer::DistortionSet* distortionSet)
184{
185        if(distortionSet == NULL)
186        {
187                OSG_ALWAYS<<"DistortionSetupStrategyProjectionDesigner::delegateDistortionSetup : Invalid DistortionSet"<<std::endl;
188                return;
189        }
190
191        if(      _blendmapFilename.empty() || _frustumFilename.empty() ||  _distortionFilename.empty() )
192        {
193                OSG_ALWAYS<<"DistortionSetupStrategyProjectionDesigner::delegateDistortionSetup : You have not specified the imput filenames correctly!"<<std::endl;
194                return;
195        }
196
197        if(     !osgDB::fileExists(_blendmapFilename) || !osgDB::fileExists(_frustumFilename) || !osgDB::fileExists(_distortionFilename) )
198        {
199                OSG_ALWAYS<<"DistortionSetupStrategyProjectionDesigner::delegateDistortionSetup : One of the specified input files does not exist!"<<std::endl;
200                return;
201        }
202
203        if (_distortionInitialized==false )
204        {
205                _distortionInitialized=true;
206                distortionSet->dirtyMesh();
207                distortionSet->dirtyMatrix();
208
209                // ******************** //
210                // *** IntensityMap *** //
211                // ******************** //
212
213                osg::Image* intensityMap=NULL;
214                intensityMap=osgDB::readImageFile(_blendmapFilename);
215                osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
216                if (!wsi)
217                {
218                        OSG_NOTICE<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
219                        return;
220                }
221
222                osg::GraphicsContext::ScreenIdentifier si;
223                si.readDISPLAY();
224
225                if (si.displayNum<0) si.displayNum = 0;
226
227                si.screenNum = 0; //Fixed value, may be replaced later
228
229                unsigned int width=0, height=0;
230                wsi->getScreenResolution(si, width, height);
231
232                if(intensityMap->s()!=width || intensityMap->t()!=height)
233                        intensityMap->scaleImage(width, height, intensityMap->r());
234
235                // Copy image data and flag as dirty to update texture.
236                osg::copyImage(intensityMap, 0, 0, 0, intensityMap->s(), intensityMap->t(), intensityMap->r(), distortionSet->getIntensityMap(), 0, 0, 0, true);
237                distortionSet->getIntensityMap()->dirty();
238
239                // ******************************* //
240                // *** Frustum and View Offset *** //
241                // ******************************* //
242                parser->parseConfigFile((_frustumFilename).data());
243                if( parser->isConfigParsed())
244                {
245                        osg::Matrixd viewOffset=osg::Matrix::identity();
246                        osg::Matrixd projectionOffset=osg::Matrixd();
247
248                        osg::Matrixd rotViewOffset=osg::Matrixd();
249
250                        rotViewOffset.makeRotate(
251                                osg::DegreesToRadians((parser->getRotationDataset())[0]), osg::Vec3(0,1,0),     // heading
252                                osg::DegreesToRadians(-(parser->getRotationDataset())[1]), osg::Vec3(1,0,0),    // pitch
253                                osg::DegreesToRadians((parser->getRotationDataset())[2]), osg::Vec3(0,0,1));    // roll
254
255                        osg::Matrixd transViewOffset=osg::Matrixd();
256                        transViewOffset.makeTranslate( (parser->getTranslationDataset())[0], (parser->getTranslationDataset())[1], (parser->getTranslationDataset())[2]);
257
258                        viewOffset = viewOffset * rotViewOffset; // * transViewOffset;
259
260                        //Frustum Parameters: Left, Right, Bottom, Top, zNear, zFar.
261                        projectionOffset.makeFrustum(
262                                (parser->getFrustumDataset())[0],
263                                (parser->getFrustumDataset())[1],
264                                (parser->getFrustumDataset())[2],
265                                (parser->getFrustumDataset())[3],
266                                (parser->getFrustumDataset())[4],
267                                (parser->getFrustumDataset())[5]);
268
269                        distortionSet->setViewOffset(viewOffset);
270                        distortionSet->setProjectionOffset(projectionOffset);
271                }
272                else
273                {
274                        OSG_NOTIFY(osg::WARN) << "WARNING: Unable to parse Frustum values from '" << _frustumFilename << "' -- continue without valid frustum values." << std::endl;
275                }
276                // ******************************* //
277                // ******* Distortion Mesh ******* //
278                // ******************************* //
279
280                osg::Geometry* distortionMeshGeometry = distortionSet->getDistortionInternals()->getChild(osgViewer::DistortionSet::MESH)->asGeode()->getDrawable(0)->asGeometry();
281                if(distortionMeshGeometry)
282                {
283
284                        if ( osgDB::fileExists( _distortionFilename ) )
285                        {
286                                distortMapTexture = loadTexture(_distortionFilename);
287                                osg::Vec4Array* distortionMesh = new osg::Vec4Array;
288
289                                osg::Vec3 origin(0.0f,0.0f,0.0f);
290                                osg::Vec3 xAxis(1.0f,0.0f,0.0f);
291                                osg::Vec3 yAxis(0.0f,1.0f,0.0f);
292                                int noSteps = 128;
293
294                                osg::Vec3 bottom = origin;
295                                osg::Vec3 dx = xAxis*(width/((float)(noSteps-1)));
296                                osg::Vec3 dy = yAxis*(height/((float)(noSteps-1)));
297
298                                osg::Vec2 bottom_texcoord(0.0f,0.0f);
299                                osg::Vec2 dx_texcoord(1.0f/(float)(noSteps-1),0.0f);
300                                osg::Vec2 dy_texcoord(0.0f,1.0f/(float)(noSteps-1));
301
302                                osg::Vec2 texcoord = bottom_texcoord;
303                                int i,j;
304
305                                for(i=0;i<noSteps;++i)
306                                {
307                                        osg::Vec2 texcoord = bottom_texcoord+dy_texcoord*(float)i;
308                                        for(j=0;j<noSteps;++j)
309                                        {
310                                                if (distortMapTexture)
311                                                {
312                                                        osg::Vec2 imgcoord =    osg::Vec2((distortMapTexture->getImage(0)->s()-1) * texcoord.x(),
313                                                                                (distortMapTexture->getImage(0)->t()-1) * texcoord.y());
314                                                        unsigned char* pPixel = &distortMapTexture->getImage(0)->data()[(int)imgcoord.y()*distortMapTexture->getImage(0)->getRowSizeInBytes()+
315                                                                                (int)imgcoord.x()*distortMapTexture->getImage(0)->getPixelSizeInBits()/8];
316                                                        distortionMesh->push_back(osg::Vec4( texcoord.x(), texcoord.y(), ((float)pPixel[2] / 255.0f + (pPixel[0] % 16)) / 16.0f,
317                                                                                1.0f-((float)pPixel[1] / 255.0f + (pPixel[0] / 16)) / 16.0f));
318                                                }
319                                                texcoord += dx_texcoord;
320                                        }
321                                }
322
323                                distortionSet->setDistortionMesh(distortionMesh);
324                                distortionSet->setDistortionMeshDimensions(noSteps, noSteps);
325                        }
326                        else
327                        {
328                                OSG_NOTIFY(osg::WARN) << "WARNING: Unable to load Distortionmap '" << _distortionFilename << "' -- continue without distortion." << std::endl;
329                        }
330
331                }
332
333        }       
334}
Note: See TracBrowser for help on using the repository browser.