source: experimental/distortionNG/DistortionManipulator.cpp @ 367

Last change on this file since 367 was 367, checked in by Torben Dannhauer, 12 years ago

Dist-Plugin compiles, but not yet tested

File size: 18.3 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 "DistortionManipulator.h"
20
21#include <osgViewer/Viewer>
22#include <osg/Point>
23#include <osg/PolygonMode>
24
25#include <osgDB/Registry>
26#include <osgDB/ReaderWriter>
27#include <osgDB/WriteFile>
28
29using namespace osg;
30using namespace osgViewer;
31
32
33DistortionManipulator::DistortionManipulator(DistortionSet* ds)
34 : _highlightColor( osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f) ), _distortionSet( ds )
35{
36        activeSetupMode = DISABLED;
37        activeDistortionMode = MESH;
38        activeManualSetupMode = DISTORTION;
39        activeVisualizationMode = NONE;
40
41        _highlighter = NULL;
42       
43        createVertexHighlighter();
44        createHUD();
45
46        _camera = 0;
47        //_distortionMesh(distortionMesh)
48
49        // Create Shader to vizualize intensitymap during blending setup.
50        osg::Shader* sh = osg::Shader::readShaderFile( osg::Shader::FRAGMENT, "shaderIntensityMapVis.frag" ); 
51        sh->setName("shaderIntensityMapVis");
52        ds->setShaderIntensityMapVis( sh );
53}
54
55DistortionManipulator::~DistortionManipulator()
56{
57}
58
59void DistortionManipulator::getUsage(osg::ApplicationUsage& usage) const
60{
61        usage.addKeyboardMouseBinding("Keypad 0","Show/Hide distortion HUD.");
62        usage.addKeyboardMouseBinding("Keypad 1","Reset distortion.");
63        usage.addKeyboardMouseBinding("Keypad 2","Reset intensity blending.");
64        usage.addKeyboardMouseBinding("Keypad 4","Toggles Setup Mode between DISABLED, MANUAL & DELEGATED.");
65        usage.addKeyboardMouseBinding("Keypad 5","MANUAL Mode: Toggle between blending & distortion setup.");
66    usage.addKeyboardMouseBinding("Keypad 6","MANUAL Mode: Toggle if distortion drags affect mesh or rtt texture coordinates.");        // Defaults to Mesh
67        usage.addKeyboardMouseBinding("Keypad 7","Show distortion mesh / intensity map / none.");
68        usage.addKeyboardMouseBinding("Keypad 8","Save distortion set.");       // via plugin
69}
70
71bool DistortionManipulator::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, osg::Object* obj, osg::NodeVisitor* nv)
72{
73        switch(ea.getEventType())
74    {
75        case(osgGA::GUIEventAdapter::MOVE): break;
76        case(osgGA::GUIEventAdapter::DRAG):
77                {
78                        if ( activeSetupMode == MANUAL)
79                        {
80                                OSG_ALWAYS<<std::endl<<"Drag:"<<std::endl<<"ea.getGraphicsContext()="<<ea.getGraphicsContext()<<std::endl;
81                                OSG_ALWAYS<<"ea.getXnormalized()="<<ea.getXnormalized()<<std::endl;
82                                OSG_ALWAYS<<"ea.getYnormalized()="<<ea.getYnormalized()<<std::endl;
83                                OSG_ALWAYS<<"ea.getX()="<<ea.getX()<<std::endl;
84                                OSG_ALWAYS<<"ea.getXin()="<<ea.getXmin()<<std::endl;
85                                OSG_ALWAYS<<"ea.getXmax()="<<ea.getXmax()<<std::endl;
86                                OSG_ALWAYS<<"ea.getY()="<<ea.getY()<<std::endl;
87                                OSG_ALWAYS<<"ea.getYin()="<<ea.getYmin()<<std::endl;
88                                OSG_ALWAYS<<"ea.getYmax()="<<ea.getYmax()<<std::endl;
89
90
91
92                                if(activeDistortionMode == MESH)
93                                {
94                                        OSG_ALWAYS<<"MESH!"<<std::endl;
95                                }
96                                else if (activeDistortionMode == TEXCOORDINATES)
97                                {
98                                        OSG_ALWAYS<<"TEXCOORDINATES!"<<std::endl;
99                                }
100
101                                return true;    // true means event handled: not forwarded to the camera manipulator;
102                        }
103                        break;
104
105                }
106        case(osgGA::GUIEventAdapter::PUSH):
107                {
108                        OSG_ALWAYS<<"mouse click!"<<std::endl;
109                        if ( activeSetupMode == MANUAL /*&& ea.getModKeyMask()&osgGA::GUIEventAdapter::MODKEY_CTRL*/ && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON )
110                        {
111                                osgViewer::View* viewer = dynamic_cast<osgViewer::View*>(&aa);
112                                if ( viewer )
113                                {
114                                        osg::notify(osg::ALWAYS)<<std::endl<<"Intersection:"<<std::endl<<"ea.getX()="<<ea.getX()<<std::endl;
115                                        osg::notify(osg::ALWAYS)<<"ea.getY()="<<ea.getY()<<std::endl;
116                                        osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::PROJECTION, ea.getX(), ea.getY());
117                                        osgUtil::IntersectionVisitor iv( intersector.get() );
118                                        _distortionSet->getDistortionCamera()->accept( iv );
119                               
120                                        if ( intersector->containsIntersections() )
121                                        {
122                                                osgUtil::LineSegmentIntersector::Intersection& result = *(intersector->getIntersections().begin());
123                                                computeSelectedVertex( result );
124                                        }
125                                }
126                        }
127                        break;
128                }
129        case(osgGA::GUIEventAdapter::RELEASE): break;
130        case(osgGA::GUIEventAdapter::KEYDOWN):
131                {
132                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Insert) // KP 0: Show/Hide HUD
133                        {
134                                bool oldValue = _distortionSet->getDistortionInternals()->getValue(DistortionSet::HUD);
135                                _distortionSet->getDistortionInternals()->setValue(DistortionSet::HUD, !oldValue);
136                                return(true);
137                        }
138                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_End)    // KP 1: reset distortion
139                        {
140                                resetDistortion();
141                                return(true);
142                        }
143                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Down)   // KP 2: reset intensity map
144                        {
145                                resetIntensityMap();
146                                return(true);
147                        }
148                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Left)   // KP 4: Toggles Setup Mode between DISABLED, MANUAL & DELEGATED.
149                        {
150                                switch(activeSetupMode)
151                                {
152                                        case DISABLED : 
153                                        {
154                                                activeSetupMode = MANUAL;
155                                                OSG_NOTICE<<"SetupMode MANUAL activated"<<std::endl;
156                                                _distortionSet->getDistortionInternals()->setValue(DistortionSet::HIGHLIGHTER, true);
157                                                break;
158                                        }
159                                        case MANUAL :
160                                        {
161                                                activeSetupMode = DELEGATED;
162                                                _distortionSet->getDistortionInternals()->setValue(DistortionSet::HIGHLIGHTER, false);
163                                                OSG_NOTICE<<"SetupMode DELEGATED activated"<<std::endl;
164                                                break;
165                                        }
166                                        case DELEGATED :
167                                        {
168                                                activeSetupMode = DISABLED;
169                                                _distortionSet->getDistortionInternals()->setValue(DistortionSet::HIGHLIGHTER, false); 
170                                                OSG_NOTICE<<"SetupMode DISABLED activated"<<std::endl;
171                                                break;
172                                        }
173                                }
174                                updateHUD();
175                                return(true);
176                        }
177                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Begin)  // KP 5: MANUAL Mode: Toggle between blending & distortion setup.
178                        {
179
180                                activeManualSetupMode = (activeManualSetupMode==DISTORTION?BLENDING:DISTORTION);
181                                updateHUD();
182                                return(true);
183                        }
184                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Right)  // KP 6: MANUAL Mode: Toggle if distortion drags affect mesh or rtt texture coordinates -> defaults to Mesh
185                        {
186                                activeDistortionMode = (activeDistortionMode==MESH?TEXCOORDINATES:MESH);
187                                updateHUD();
188                                return(true);
189                        }
190                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Home)   // KP 7: Show distortion mesh / intensity map / none.
191                        {
192                                switch(activeVisualizationMode)
193                                {       
194                                        case DISTORTION_MESH : 
195                                        {
196                                                activeVisualizationMode = INTENSITY_MAP;
197                                                showDistortionMesh(false);
198                                                showIntensityMap(true);
199                                                break;
200                                        }
201                                        case INTENSITY_MAP :
202                                        {
203                                                activeVisualizationMode = NONE;
204                                                showDistortionMesh(false);
205                                                showIntensityMap(false);
206                                                break;
207                                        }
208                                        case NONE : 
209                                        {
210                                                activeVisualizationMode = DISTORTION_MESH;
211                                                showDistortionMesh(true);
212                                                showIntensityMap(false);
213                                                break;
214                                        }
215                                }
216
217                                updateHUD();
218                                return(true);
219                        }
220                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Up)     // KP 8: Save distortion set     via plugin
221                        {
222                                OSG_ALWAYS<<"KEY_KP_8 : todo: Save DistortionContainer"<<std::endl;
223
224
225
226        // Configure Compression and instantiate read/write-options
227        bool asAscii_ = true;
228        bool compressionEnabled = false;
229
230        std::string readOptionString = "";
231        std::string writeOptionString = "";
232        if(asAscii_)
233        {
234                readOptionString = "Ascii";
235                writeOptionString = "Ascii";
236        }
237        if (compressionEnabled)
238                writeOptionString+=" Compressor=zlib";
239       
240        osg::ref_ptr<osgDB::Options> readOptions = new osgDB::Options( readOptionString.c_str() );
241        osg::ref_ptr<osgDB::Options> writeOptions = new osgDB::Options( writeOptionString.c_str() );
242
243        //// Get ReaderWriter
244        //osg::ref_ptr<osgDB::ReaderWriter> rw = osgDB::Registry::instance()->getReaderWriterForExtension("osgb");     
245
246        //// Writing node to stream
247        //std::stringstream myOstream;
248        //if ( rw )
249        //{
250        //      osgDB::ReaderWriter::WriteResult wr = rw->writeObject( *_distortionSet, myOstream, writeOptions );
251        //      if (wr.success() )                     
252        //      {
253        //              OSG_ALWAYS<<"write node success"<<std::endl;
254        //      }
255        //      else
256        //      {
257        //              OSG_ALWAYS<<"write node failed"<<std::endl;
258        //      }
259        //}
260
261        if( osgDB::writeObjectFile(*_distortionSet, "test.osgt", writeOptions) )
262        {
263                OSG_ALWAYS<<"write node success"<<std::endl;
264        }
265        else
266        {
267                OSG_ALWAYS<<"write node failed"<<std::endl;
268        }
269
270
271
272
273
274
275
276
277
278
279
280
281
282                                return(true);
283                        }
284                       
285                        return false;   // Event ignored
286                }
287        case(osgGA::GUIEventAdapter::KEYUP): break;
288                case(osgGA::GUIEventAdapter::FRAME):
289                {
290                        if ( activeSetupMode == DELEGATED)
291                        {
292                                OSG_ALWAYS<<"Todo: Calling delegated class!"<<std::endl;
293                        }
294                        break;
295                }
296        case (osgGA::GUIEventAdapter::RESIZE):  // todo: adapt distortion mesh to new screen size
297                {
298                        OSG_ALWAYS<<"RESIZE!"<<std::endl;
299                        break;
300                }
301
302        default:
303            return false;
304    }
305    return false;
306}
307
308void DistortionManipulator::resetIntensityMap()
309{
310        if(!_distortionSet.valid())
311                return;
312
313        osg::ref_ptr<osg::Image> image = _distortionSet->getIntensityMap();
314
315        OSG_ALWAYS<<"Reseting IntensityMap Blending."<<std::endl;
316
317        if (!image->isDataContiguous())
318        {
319                OSG_WARN<<"Warning: DistortionManipulator does not support working with non contiguous imagery as blendmaps!"<<std::endl;
320                return;
321        }
322
323        // Fill intensity map with 255
324        unsigned char* dataPtr = image->data(); 
325        for(unsigned int i=0;i<image->getTotalSizeInBytes();i++)
326        {
327                *dataPtr++ = 255; 
328        }
329        image->dirty();
330}
331
332void DistortionManipulator::resetDistortion()
333{
334        if(!_distortionSet.valid())
335                return;
336
337        OSG_ALWAYS<<"ToDo: resetDistortion()"<<std::endl;
338}
339
340void DistortionManipulator::showDistortionMesh(bool show)
341{
342        osg::StateSet* stateset = _distortionSet->getDistortionInternals()->getChild(DistortionSet::MESH)->getOrCreateStateSet();
343
344        // Append a PolygonMode stateset if required
345    osg::PolygonMode* polyModeObj = dynamic_cast<osg::PolygonMode*>(stateset->getAttribute(osg::StateAttribute::POLYGONMODE));
346    if (!polyModeObj)
347    {
348        polyModeObj = new osg::PolygonMode;
349        stateset->setAttribute(polyModeObj, osg::StateAttribute::PROTECTED|osg::StateAttribute::ON);
350    }
351 
352        // Set Polygonmode
353        if(show)
354                polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE);
355        else
356                polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::FILL);
357}
358
359void DistortionManipulator::showIntensityMap(bool show)
360{
361        if(_distortionSet.valid())
362        {
363                osg::StateSet* stateset = _distortionSet->getDistortionInternals()->getChild(DistortionSet::MESH)->getOrCreateStateSet();
364                osg::Program* program = static_cast<osg::Program*>(stateset->getAttribute(::osg::StateAttribute::PROGRAM));
365
366                if(show)
367                {
368                        program->removeShader( _distortionSet->getShaderIntensityMap() );
369                        program->addShader( _distortionSet->getShaderIntensityMapVis() );
370                }
371                else
372                {
373                        program->removeShader( _distortionSet->getShaderIntensityMapVis() );
374                        program->addShader( _distortionSet->getShaderIntensityMap() );
375                }
376        }
377}
378
379void DistortionManipulator::createVertexHighlighter()
380{
381        osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
382        (*colors)[0] = _highlightColor;
383
384        _highlighter = new osg::Geometry;
385        _highlighter->setDataVariance( osg::Object::DYNAMIC );
386        _highlighter->setUseDisplayList( false );
387        _highlighter->setUseVertexBufferObjects( true );
388        _highlighter->setVertexArray( new osg::Vec3Array(1) );  // The highlighter vertex is updated by computeSelectedVertex(..)
389        _highlighter->setColorArray( colors.get() );
390        _highlighter->setColorBinding( osg::Geometry::BIND_OVERALL );
391        _highlighter->addPrimitiveSet( new osg::DrawArrays(GL_POINTS, 0, 1) );
392
393       
394        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
395        geode->addDrawable( _highlighter.get() );
396        geode->getOrCreateStateSet()->setAttributeAndModes( new osg::Point(8.0f) );
397        geode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
398        geode->setCullingActive(false); // disable the culling for the selector, otherwise the selector is culled away on the edge.
399
400        _distortionSet->getDistortionInternals()->addChild(geode, false);       //  = child #1  :definition: child #0 = mesh, #1 = highlighter, #2 HUD
401}
402
403void DistortionManipulator::createHUD()
404{
405        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
406       
407        osg::StateSet* stateSet = geode->getOrCreateStateSet();
408        stateSet->setRenderBinDetails( 99, "RenderBin");
409        // disable depth test to ensure that it is always drawn.
410        stateSet->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
411        stateSet->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
412
413        // Add Text:
414        osg::Vec3 position(20.0f,120.0f,0.0f);
415        osg::Vec3 delta(0.0f,-25.0f,0.0f);
416        std::string timesFont("fonts/arial.ttf");
417        {
418                osg::ref_ptr<osgText::Text> textHeader = new osgText::Text;
419                textHeader->setText("Distortion Setup:");
420                textHeader->setFont(timesFont);
421                textHeader->setPosition(position);
422                textHeader->setCharacterSize(21);
423                textHeader->setDataVariance(osg::Object::STATIC); 
424                geode->addDrawable( textHeader );
425
426                position += delta;
427
428                hudSetupMode = new osgText::Text;
429                hudSetupMode->setFont(timesFont);
430                hudSetupMode->setPosition(position);
431                hudSetupMode->setCharacterSize(21);
432                hudSetupMode->setDataVariance(osg::Object::DYNAMIC); 
433                geode->addDrawable( hudSetupMode );
434
435                position += delta;
436
437                hudDistortionMode = new osgText::Text;
438                hudDistortionMode->setFont(timesFont);
439                hudDistortionMode->setPosition(position);
440                hudDistortionMode->setCharacterSize(21);
441                hudDistortionMode->setDataVariance(osg::Object::DYNAMIC); 
442                geode->addDrawable( hudDistortionMode );
443
444                position += delta;
445
446                hudManualSetupMode = new osgText::Text;
447                hudManualSetupMode->setFont(timesFont);
448                hudManualSetupMode->setPosition(position);
449                hudManualSetupMode->setCharacterSize(21);
450                hudManualSetupMode->setDataVariance(osg::Object::DYNAMIC); 
451                geode->addDrawable( hudManualSetupMode );
452
453                position += delta;
454
455                hudVisualizationMode = new osgText::Text;
456                hudVisualizationMode->setFont(timesFont);
457                hudVisualizationMode->setPosition(position);
458                hudVisualizationMode->setCharacterSize(21);
459                hudVisualizationMode->setDataVariance(osg::Object::DYNAMIC); 
460                geode->addDrawable( hudVisualizationMode );
461        }
462       
463        updateHUD();
464        _distortionSet->getDistortionInternals()->addChild(geode, false);       //  = child #2  :definition: child #0 = mesh, #1 = highlighter, #2 HUD
465}
466
467void DistortionManipulator::updateHUD()
468{
469        switch(activeSetupMode)
470        {
471                case DISABLED : hudSetupMode->setText("Setup Mode : DISABLED"); break;
472                case MANUAL : hudSetupMode->setText("Setup Mode : MANUAL"); break;
473                case DELEGATED : hudSetupMode->setText("Setup Mode : DELEGATED"); break;
474                default: hudSetupMode->setText("");
475        };
476        switch(activeDistortionMode)
477        {
478                case MESH : hudDistortionMode->setText("Distortion Mode : MESH"); break;
479                case TEXCOORDINATES : hudDistortionMode->setText("Distortion Mode : TEXCOORDINATES"); break;
480                default: hudDistortionMode->setText("");
481        };
482        switch(activeManualSetupMode)
483        {
484                case DISTORTION : hudManualSetupMode->setText("Manual Setup Mode : DISTORTION"); break;
485                case BLENDING : hudManualSetupMode->setText("Manual Setup Mode : BLENDING"); break;
486                default: hudManualSetupMode->setText("");
487        };
488        switch(activeVisualizationMode)
489        {
490                case DISTORTION_MESH : hudVisualizationMode->setText("Visualization Mode : DISTORTION_MESH"); break;
491                case INTENSITY_MAP : hudVisualizationMode->setText("Visualization Mode : INTENSITY_MAP"); break;
492                case NONE : hudVisualizationMode->setText("Visualization Mode : NONE"); break;
493                default: hudVisualizationMode->setText("");
494        };
495}
496
497void DistortionManipulator::computeSelectedVertex( osgUtil::LineSegmentIntersector::Intersection& result )
498{
499        osg::Geometry* geom = dynamic_cast<osg::Geometry*>( result.drawable.get() );
500        if ( !geom || geom==_highlighter )
501                return;
502
503        osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>( geom->getVertexArray() );
504        osg::Vec3Array* selVertices = dynamic_cast<osg::Vec3Array*>( _highlighter->getVertexArray() );
505        if ( !vertices || !selVertices )
506                return;
507       
508        OSG_NOTIFY(osg::ALWAYS)<<"size of vertices="<<vertices->size()<<std::endl;
509        OSG_NOTIFY(osg::ALWAYS)<<"size of selVertices="<<selVertices->size()<<std::endl;
510
511        osg::Vec3 point = result.getWorldIntersectPoint();
512        osg::Matrix matrix = osg::computeLocalToWorld( result.nodePath );       // To compute the intersection vertices in world coordinates not in model coordinates
513        OSG_NOTIFY(osg::ALWAYS) << "Intersection-indices: Size=" << result.indexList.size() << std::endl;
514        const std::vector<unsigned int>& selIndices = result.indexList;
515        {
516                double maxRatio = 0.0;
517                int closestVertexIndex = 0;
518                for ( unsigned int i=0; i<3 && i<result.ratioList.size(); i++ ) //iterate through rations and search for maxRation=nearestVertex
519                {
520                        if(result.ratioList[i] > maxRatio)
521                        {
522                                maxRatio = result.ratioList[i];
523                                closestVertexIndex = result.indexList[i];
524                        }
525                        OSG_NOTIFY(osg::ALWAYS)<<"maxRatio="<<maxRatio<<std::endl;
526                        OSG_NOTIFY(osg::ALWAYS)<<"closestVertexIndex="<<closestVertexIndex<<std::endl;
527                }
528                OSG_NOTIFY(osg::ALWAYS)<<"nearest vertex: X="<<(*vertices)[closestVertexIndex].x()<<" Y="<<(*vertices)[closestVertexIndex].y()<<" Z="<<(*vertices)[closestVertexIndex].z()<<std::endl;
529                osg::Vec3 vertex = (*vertices)[closestVertexIndex] * matrix;
530
531                selVertices->front() = vertex;         
532                OSG_NOTIFY(osg::ALWAYS)<<"selected vertice: X="<<vertex.x()<<" Y="<<vertex.y()<<" Z="<<vertex.z()<<std::endl;
533        }
534        selVertices->dirty();
535        _highlighter->dirtyBound(); 
536}
Note: See TracBrowser for help on using the repository browser.