source: experimental/distortionNG/DistortionManipulator.cpp @ 426

Last change on this file since 426 was 408, checked in by Torben Dannhauer, 12 years ago
File size: 24.6 KB
RevLine 
[346]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"
[380]20#include "extViewer.h"
[346]21
[358]22#include <osgViewer/Viewer>
23#include <osg/Point>
24#include <osg/PolygonMode>
[381]25#include <osg/TextureRectangle>
[347]26
[361]27#include <osgDB/Registry>
28#include <osgDB/ReaderWriter>
29#include <osgDB/WriteFile>
30
[371]31#include "DistortionSetupStrategy.h"
32
[346]33using namespace osg;
34using namespace osgViewer;
35
36
[380]37DistortionManipulator::DistortionManipulator(extViewer* viewer, DistortionSet* ds)
38 : _highlightColor( osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f) ), _distortionSet( ds ), _viewer(viewer)
[346]39{
[348]40        activeSetupMode = DISABLED;
41        activeDistortionMode = MESH;
42        activeManualSetupMode = DISTORTION;
43        activeVisualizationMode = NONE;
[349]44
[371]45        _delegatedDistortionSetupStrategy = NULL;
46
[353]47        _highlighter = NULL;
48       
49        createVertexHighlighter();
[356]50        createHUD();
[353]51
52        _camera = 0;
53        //_distortionMesh(distortionMesh)
[361]54
[392]55        // Create Shader to visualize intensitymap during blending setup.
[361]56        osg::Shader* sh = osg::Shader::readShaderFile( osg::Shader::FRAGMENT, "shaderIntensityMapVis.frag" ); 
57        sh->setName("shaderIntensityMapVis");
58        ds->setShaderIntensityMapVis( sh );
[370]59
60        //LF Get Screen Resolution for Cursor Position Scaling
61        osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
62        if (!wsi) { osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl; }
63        wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), _screenPixWidth, _screenPixHeight);
64
65
[346]66}
67
68DistortionManipulator::~DistortionManipulator()
69{
70}
71
72void DistortionManipulator::getUsage(osg::ApplicationUsage& usage) const
73{
[356]74        usage.addKeyboardMouseBinding("Keypad 0","Show/Hide distortion HUD.");
75        usage.addKeyboardMouseBinding("Keypad 1","Reset distortion.");
76        usage.addKeyboardMouseBinding("Keypad 2","Reset intensity blending.");
[346]77        usage.addKeyboardMouseBinding("Keypad 4","Toggles Setup Mode between DISABLED, MANUAL & DELEGATED.");
78        usage.addKeyboardMouseBinding("Keypad 5","MANUAL Mode: Toggle between blending & distortion setup.");
[356]79    usage.addKeyboardMouseBinding("Keypad 6","MANUAL Mode: Toggle if distortion drags affect mesh or rtt texture coordinates.");        // Defaults to Mesh
80        usage.addKeyboardMouseBinding("Keypad 7","Show distortion mesh / intensity map / none.");
81        usage.addKeyboardMouseBinding("Keypad 8","Save distortion set.");       // via plugin
[346]82}
83
[348]84bool DistortionManipulator::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, osg::Object* obj, osg::NodeVisitor* nv)
[346]85{
[347]86        switch(ea.getEventType())
[346]87    {
[348]88        case(osgGA::GUIEventAdapter::MOVE): break;
[346]89        case(osgGA::GUIEventAdapter::DRAG):
90                {
[355]91                        if ( activeSetupMode == MANUAL)
92                        {
[357]93                                OSG_ALWAYS<<std::endl<<"Drag:"<<std::endl<<"ea.getGraphicsContext()="<<ea.getGraphicsContext()<<std::endl;
94                                OSG_ALWAYS<<"ea.getXnormalized()="<<ea.getXnormalized()<<std::endl;
95                                OSG_ALWAYS<<"ea.getYnormalized()="<<ea.getYnormalized()<<std::endl;
96                                OSG_ALWAYS<<"ea.getX()="<<ea.getX()<<std::endl;
97                                OSG_ALWAYS<<"ea.getXin()="<<ea.getXmin()<<std::endl;
98                                OSG_ALWAYS<<"ea.getXmax()="<<ea.getXmax()<<std::endl;
99                                OSG_ALWAYS<<"ea.getY()="<<ea.getY()<<std::endl;
100                                OSG_ALWAYS<<"ea.getYin()="<<ea.getYmin()<<std::endl;
101                                OSG_ALWAYS<<"ea.getYmax()="<<ea.getYmax()<<std::endl;
[370]102                               
103                                //LF get X,Y normalized to lowerleftcorner (0,0) / upperrightcorner (1,1)
104                                OSG_ALWAYS<<"getXnormalizedLF()="<<(ea.getXnormalized()+1.0)/2.0<<std::endl;
105                                OSG_ALWAYS<<"getYnormalizedLF()="<<(ea.getYnormalized()+1.0)/2.0<<std::endl;
[353]106
[370]107                                //LF get X,Y in pixels (lowerleftcorner (0,0) / upperrightcorner (screenwidth,screenheigth)
108                                OSG_ALWAYS<<std::endl<<"Screen Resolution: "<<_screenPixWidth<<" x "<<_screenPixHeight<<std::endl;
109                                OSG_ALWAYS<<"getXPixelspaceLF()="<<(int)((float)_screenPixWidth*(ea.getXnormalized()+1.0)/2.0)<<std::endl;
110                                OSG_ALWAYS<<"getYPixelspaceLF()="<<(int)((float)_screenPixHeight*(ea.getYnormalized()+1.0)/2.0)<<std::endl;
[367]111
[357]112                                if(activeDistortionMode == MESH)
113                                {
114                                        OSG_ALWAYS<<"MESH!"<<std::endl;
115                                }
116                                else if (activeDistortionMode == TEXCOORDINATES)
117                                {
118                                        OSG_ALWAYS<<"TEXCOORDINATES!"<<std::endl;
119                                }
120
[355]121                                return true;    // true means event handled: not forwarded to the camera manipulator;
122                        }
123                        break;
[353]124
[346]125                }
126        case(osgGA::GUIEventAdapter::PUSH):
[348]127                {
[353]128                        OSG_ALWAYS<<"mouse click!"<<std::endl;
[361]129                        if ( activeSetupMode == MANUAL /*&& ea.getModKeyMask()&osgGA::GUIEventAdapter::MODKEY_CTRL*/ && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON )
[348]130                        {
[353]131                                osgViewer::View* viewer = dynamic_cast<osgViewer::View*>(&aa);
132                                if ( viewer )
133                                {
134                                        osg::notify(osg::ALWAYS)<<std::endl<<"Intersection:"<<std::endl<<"ea.getX()="<<ea.getX()<<std::endl;
135                                        osg::notify(osg::ALWAYS)<<"ea.getY()="<<ea.getY()<<std::endl;
136                                        osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::PROJECTION, ea.getX(), ea.getY());
137                                        osgUtil::IntersectionVisitor iv( intersector.get() );
138                                        _distortionSet->getDistortionCamera()->accept( iv );
139                               
140                                        if ( intersector->containsIntersections() )
141                                        {
[370]142                                                //osgUtil::LineSegmentIntersector::Intersection& result = *(intersector->getIntersections().begin());
143                                                osgUtil::LineSegmentIntersector::Intersection *result;
144                                                result=&intersector->getFirstIntersection();
145                                                computeSelectedVertex( *result );
146                                                //computeSelectedVertex( result );
[353]147                                        }
148                                }
[348]149                        }
150                        break;
151                }
152        case(osgGA::GUIEventAdapter::RELEASE): break;
[346]153        case(osgGA::GUIEventAdapter::KEYDOWN):
[347]154                {
[357]155                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Insert) // KP 0: Show/Hide HUD
[356]156                        {
[357]157                                bool oldValue = _distortionSet->getDistortionInternals()->getValue(DistortionSet::HUD);
158                                _distortionSet->getDistortionInternals()->setValue(DistortionSet::HUD, !oldValue);
[356]159                                return(true);
160                        }
[347]161                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_End)    // KP 1: reset distortion
162                        {
163                                resetDistortion();
164                                return(true);
165                        }
166                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Down)   // KP 2: reset intensity map
167                        {
168                                resetIntensityMap();
169                                return(true);
170                        }
171                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Left)   // KP 4: Toggles Setup Mode between DISABLED, MANUAL & DELEGATED.
172                        {
[348]173                                switch(activeSetupMode)
174                                {
[353]175                                        case DISABLED : 
176                                        {
177                                                activeSetupMode = MANUAL;
[356]178                                                OSG_NOTICE<<"SetupMode MANUAL activated"<<std::endl;
[357]179                                                _distortionSet->getDistortionInternals()->setValue(DistortionSet::HIGHLIGHTER, true);
[353]180                                                break;
181                                        }
182                                        case MANUAL :
183                                        {
184                                                activeSetupMode = DELEGATED;
[357]185                                                _distortionSet->getDistortionInternals()->setValue(DistortionSet::HIGHLIGHTER, false);
[356]186                                                OSG_NOTICE<<"SetupMode DELEGATED activated"<<std::endl;
[353]187                                                break;
188                                        }
189                                        case DELEGATED :
190                                        {
191                                                activeSetupMode = DISABLED;
[357]192                                                _distortionSet->getDistortionInternals()->setValue(DistortionSet::HIGHLIGHTER, false); 
[356]193                                                OSG_NOTICE<<"SetupMode DISABLED activated"<<std::endl;
[353]194                                                break;
195                                        }
[348]196                                }
[356]197                                updateHUD();
[347]198                                return(true);
199                        }
200                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Begin)  // KP 5: MANUAL Mode: Toggle between blending & distortion setup.
201                        {
[348]202
203                                activeManualSetupMode = (activeManualSetupMode==DISTORTION?BLENDING:DISTORTION);
[356]204                                updateHUD();
[347]205                                return(true);
206                        }
207                        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
208                        {
[348]209                                activeDistortionMode = (activeDistortionMode==MESH?TEXCOORDINATES:MESH);
[356]210                                updateHUD();
[347]211                                return(true);
212                        }
213                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Home)   // KP 7: Show distortion mesh / intensity map / none.
214                        {
[348]215                                switch(activeVisualizationMode)
216                                {       
[349]217                                        case DISTORTION_MESH : 
218                                        {
219                                                activeVisualizationMode = INTENSITY_MAP;
[358]220                                                showDistortionMesh(false);
221                                                showIntensityMap(true);
[349]222                                                break;
223                                        }
224                                        case INTENSITY_MAP :
225                                        {
226                                                activeVisualizationMode = NONE;
227                                                showDistortionMesh(false);
[358]228                                                showIntensityMap(false);
[349]229                                                break;
230                                        }
231                                        case NONE : 
232                                        {
233                                                activeVisualizationMode = DISTORTION_MESH;
[358]234                                                showDistortionMesh(true);
[349]235                                                showIntensityMap(false);
236                                                break;
237                                        }
[348]238                                }
[349]239
[356]240                                updateHUD();
[347]241                                return(true);
242                        }
243                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Up)     // KP 8: Save distortion set     via plugin
244                        {
[349]245                                OSG_ALWAYS<<"KEY_KP_8 : todo: Save DistortionContainer"<<std::endl;
[361]246
[370]247                                osgDB::writeObjectFile( *_distortionSet, "distortionset.dist" );
[347]248                                return(true);
249                        }
250                       
251                        return false;   // Event ignored
252                }
[348]253        case(osgGA::GUIEventAdapter::KEYUP): break;
[346]254                case(osgGA::GUIEventAdapter::FRAME):
255                {
[371]256                        if ( activeSetupMode == DELEGATED && _delegatedDistortionSetupStrategy.valid())
[356]257                        {
[379]258                                //OSG_ALWAYS<<"Calling delegated class.."<<std::endl;
[371]259                                _delegatedDistortionSetupStrategy->delegateDistortionSetup(_distortionSet);
[380]260                                if( _distortionSet->isDirty() && _viewer.valid())
[379]261                                {
[381]262                                        updateDistortionSetup();
[379]263                                }
264                                //OSG_ALWAYS<<"..done"<<std::endl;
[356]265                        }
[346]266                        break;
267                }
268        case (osgGA::GUIEventAdapter::RESIZE):  // todo: adapt distortion mesh to new screen size
269                {
[349]270                        OSG_ALWAYS<<"RESIZE!"<<std::endl;
[346]271                        break;
272                }
273
274        default:
275            return false;
276    }
277    return false;
[347]278}
279
280void DistortionManipulator::resetIntensityMap()
281{
[349]282        if(!_distortionSet.valid())
283                return;
284
285        osg::ref_ptr<osg::Image> image = _distortionSet->getIntensityMap();
286
287        OSG_ALWAYS<<"Reseting IntensityMap Blending."<<std::endl;
288
[391]289        //isDataContiguous is unknown to MSVS2010 and GCC
290        /*if (!image->isDataContiguous())
[349]291        {
292                OSG_WARN<<"Warning: DistortionManipulator does not support working with non contiguous imagery as blendmaps!"<<std::endl;
293                return;
[391]294        }*/
[349]295
296        // Fill intensity map with 255
297        unsigned char* dataPtr = image->data(); 
298        for(unsigned int i=0;i<image->getTotalSizeInBytes();i++)
299        {
300                *dataPtr++ = 255; 
301        }
302        image->dirty();
[347]303}
304
305void DistortionManipulator::resetDistortion()
306{
[349]307        if(!_distortionSet.valid())
308                return;
309
[407]310       
311        _distortionSet->setDistortionMeshDimensions(2, 2, true);        // Reset dimensions and coordinates/texcoords & rebuild mesh data
[408]312        _distortionSet->dirtyMesh();
313       
[407]314        // Restore ProjectionMatrix
[408]315        // Set up basic projection Matrix
316        double fovy = 30., aspectRatio = 1., zNear = 1., zFar = 1000.;
317        _distortionSet->getProjectionOffset().makePerspective( fovy, aspectRatio, zNear, zFar );
[407]318
[408]319        double newAspectRatio = double(_distortionSet->getIntensityMap()->s()) / double(_distortionSet->getIntensityMap()->t());
[407]320        double aspectRatioChange = newAspectRatio / aspectRatio;
321        if (aspectRatioChange != 1.0)
322        {
[408]323                _distortionSet->getProjectionOffset() *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0);
[407]324        }
325
[408]326        _distortionSet->dirtyMatrix();
[349]327}
328
329void DistortionManipulator::showDistortionMesh(bool show)
330{
[358]331        osg::StateSet* stateset = _distortionSet->getDistortionInternals()->getChild(DistortionSet::MESH)->getOrCreateStateSet();
[349]332
[358]333        // Append a PolygonMode stateset if required
334    osg::PolygonMode* polyModeObj = dynamic_cast<osg::PolygonMode*>(stateset->getAttribute(osg::StateAttribute::POLYGONMODE));
[349]335    if (!polyModeObj)
336    {
337        polyModeObj = new osg::PolygonMode;
[361]338        stateset->setAttribute(polyModeObj, osg::StateAttribute::PROTECTED|osg::StateAttribute::ON);
[349]339    }
340 
[358]341        // Set Polygonmode
[349]342        if(show)
343                polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE);
344        else
[358]345                polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::FILL);
[349]346}
347
348void DistortionManipulator::showIntensityMap(bool show)
349{
[361]350        if(_distortionSet.valid())
351        {
352                osg::StateSet* stateset = _distortionSet->getDistortionInternals()->getChild(DistortionSet::MESH)->getOrCreateStateSet();
353                osg::Program* program = static_cast<osg::Program*>(stateset->getAttribute(::osg::StateAttribute::PROGRAM));
[350]354
[361]355                if(show)
356                {
357                        program->removeShader( _distortionSet->getShaderIntensityMap() );
358                        program->addShader( _distortionSet->getShaderIntensityMapVis() );
359                }
360                else
361                {
362                        program->removeShader( _distortionSet->getShaderIntensityMapVis() );
363                        program->addShader( _distortionSet->getShaderIntensityMap() );
364                }
365        }
[349]366}
[353]367
368void DistortionManipulator::createVertexHighlighter()
369{
370        osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
371        (*colors)[0] = _highlightColor;
372
373        _highlighter = new osg::Geometry;
374        _highlighter->setDataVariance( osg::Object::DYNAMIC );
375        _highlighter->setUseDisplayList( false );
376        _highlighter->setUseVertexBufferObjects( true );
377        _highlighter->setVertexArray( new osg::Vec3Array(1) );  // The highlighter vertex is updated by computeSelectedVertex(..)
378        _highlighter->setColorArray( colors.get() );
379        _highlighter->setColorBinding( osg::Geometry::BIND_OVERALL );
380        _highlighter->addPrimitiveSet( new osg::DrawArrays(GL_POINTS, 0, 1) );
381
382       
383        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
384        geode->addDrawable( _highlighter.get() );
385        geode->getOrCreateStateSet()->setAttributeAndModes( new osg::Point(8.0f) );
386        geode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
387        geode->setCullingActive(false); // disable the culling for the selector, otherwise the selector is culled away on the edge.
388
[356]389        _distortionSet->getDistortionInternals()->addChild(geode, false);       //  = child #1  :definition: child #0 = mesh, #1 = highlighter, #2 HUD
[353]390}
391
[356]392void DistortionManipulator::createHUD()
393{
394        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
395       
396        osg::StateSet* stateSet = geode->getOrCreateStateSet();
397        stateSet->setRenderBinDetails( 99, "RenderBin");
398        // disable depth test to ensure that it is always drawn.
399        stateSet->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
400        stateSet->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
401
[370]402        // Modify StateSet to protect it against state changes by the stateset Manipulator
403        osg::PolygonMode* polyModeObj = new osg::PolygonMode;
404    stateSet->setAttribute(polyModeObj, osg::StateAttribute::PROTECTED|osg::StateAttribute::ON);
405
[356]406        // Add Text:
407        osg::Vec3 position(20.0f,120.0f,0.0f);
408        osg::Vec3 delta(0.0f,-25.0f,0.0f);
409        std::string timesFont("fonts/arial.ttf");
410        {
411                osg::ref_ptr<osgText::Text> textHeader = new osgText::Text;
412                textHeader->setText("Distortion Setup:");
413                textHeader->setFont(timesFont);
414                textHeader->setPosition(position);
415                textHeader->setCharacterSize(21);
416                textHeader->setDataVariance(osg::Object::STATIC); 
417                geode->addDrawable( textHeader );
418
419                position += delta;
420
421                hudSetupMode = new osgText::Text;
422                hudSetupMode->setFont(timesFont);
423                hudSetupMode->setPosition(position);
424                hudSetupMode->setCharacterSize(21);
425                hudSetupMode->setDataVariance(osg::Object::DYNAMIC); 
426                geode->addDrawable( hudSetupMode );
427
428                position += delta;
429
430                hudDistortionMode = new osgText::Text;
431                hudDistortionMode->setFont(timesFont);
432                hudDistortionMode->setPosition(position);
433                hudDistortionMode->setCharacterSize(21);
434                hudDistortionMode->setDataVariance(osg::Object::DYNAMIC); 
435                geode->addDrawable( hudDistortionMode );
436
437                position += delta;
438
439                hudManualSetupMode = new osgText::Text;
440                hudManualSetupMode->setFont(timesFont);
441                hudManualSetupMode->setPosition(position);
442                hudManualSetupMode->setCharacterSize(21);
443                hudManualSetupMode->setDataVariance(osg::Object::DYNAMIC); 
444                geode->addDrawable( hudManualSetupMode );
445
446                position += delta;
447
448                hudVisualizationMode = new osgText::Text;
449                hudVisualizationMode->setFont(timesFont);
450                hudVisualizationMode->setPosition(position);
451                hudVisualizationMode->setCharacterSize(21);
452                hudVisualizationMode->setDataVariance(osg::Object::DYNAMIC); 
453                geode->addDrawable( hudVisualizationMode );
454        }
455       
456        updateHUD();
[370]457        _distortionSet->getDistortionInternals()->addChild(geode, false);       //  = child #2. The definition is: child #0 = mesh, #1 = highlighter, #2 HUD
[356]458}
459
460void DistortionManipulator::updateHUD()
461{
462        switch(activeSetupMode)
463        {
464                case DISABLED : hudSetupMode->setText("Setup Mode : DISABLED"); break;
465                case MANUAL : hudSetupMode->setText("Setup Mode : MANUAL"); break;
466                case DELEGATED : hudSetupMode->setText("Setup Mode : DELEGATED"); break;
467                default: hudSetupMode->setText("");
468        };
469        switch(activeDistortionMode)
470        {
471                case MESH : hudDistortionMode->setText("Distortion Mode : MESH"); break;
472                case TEXCOORDINATES : hudDistortionMode->setText("Distortion Mode : TEXCOORDINATES"); break;
473                default: hudDistortionMode->setText("");
474        };
475        switch(activeManualSetupMode)
476        {
477                case DISTORTION : hudManualSetupMode->setText("Manual Setup Mode : DISTORTION"); break;
478                case BLENDING : hudManualSetupMode->setText("Manual Setup Mode : BLENDING"); break;
479                default: hudManualSetupMode->setText("");
480        };
481        switch(activeVisualizationMode)
482        {
483                case DISTORTION_MESH : hudVisualizationMode->setText("Visualization Mode : DISTORTION_MESH"); break;
484                case INTENSITY_MAP : hudVisualizationMode->setText("Visualization Mode : INTENSITY_MAP"); break;
485                case NONE : hudVisualizationMode->setText("Visualization Mode : NONE"); break;
486                default: hudVisualizationMode->setText("");
487        };
488}
489
[353]490void DistortionManipulator::computeSelectedVertex( osgUtil::LineSegmentIntersector::Intersection& result )
491{
492        osg::Geometry* geom = dynamic_cast<osg::Geometry*>( result.drawable.get() );
493        if ( !geom || geom==_highlighter )
494                return;
495
496        osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>( geom->getVertexArray() );
497        osg::Vec3Array* selVertices = dynamic_cast<osg::Vec3Array*>( _highlighter->getVertexArray() );
498        if ( !vertices || !selVertices )
499                return;
500       
501        OSG_NOTIFY(osg::ALWAYS)<<"size of vertices="<<vertices->size()<<std::endl;
502        OSG_NOTIFY(osg::ALWAYS)<<"size of selVertices="<<selVertices->size()<<std::endl;
503
504        osg::Vec3 point = result.getWorldIntersectPoint();
505        osg::Matrix matrix = osg::computeLocalToWorld( result.nodePath );       // To compute the intersection vertices in world coordinates not in model coordinates
506        OSG_NOTIFY(osg::ALWAYS) << "Intersection-indices: Size=" << result.indexList.size() << std::endl;
507        const std::vector<unsigned int>& selIndices = result.indexList;
508        {
509                double maxRatio = 0.0;
510                int closestVertexIndex = 0;
511                for ( unsigned int i=0; i<3 && i<result.ratioList.size(); i++ ) //iterate through rations and search for maxRation=nearestVertex
512                {
513                        if(result.ratioList[i] > maxRatio)
514                        {
515                                maxRatio = result.ratioList[i];
516                                closestVertexIndex = result.indexList[i];
517                        }
518                        OSG_NOTIFY(osg::ALWAYS)<<"maxRatio="<<maxRatio<<std::endl;
519                        OSG_NOTIFY(osg::ALWAYS)<<"closestVertexIndex="<<closestVertexIndex<<std::endl;
520                }
521                OSG_NOTIFY(osg::ALWAYS)<<"nearest vertex: X="<<(*vertices)[closestVertexIndex].x()<<" Y="<<(*vertices)[closestVertexIndex].y()<<" Z="<<(*vertices)[closestVertexIndex].z()<<std::endl;
522                osg::Vec3 vertex = (*vertices)[closestVertexIndex] * matrix;
523
524                selVertices->front() = vertex;         
525                OSG_NOTIFY(osg::ALWAYS)<<"selected vertice: X="<<vertex.x()<<" Y="<<vertex.y()<<" Z="<<vertex.z()<<std::endl;
526        }
527        selVertices->dirty();
528        _highlighter->dirtyBound(); 
[370]529}
[381]530
531void DistortionManipulator::updateDistortionSetup()
532{
[396]533        updateDistortionViewProjectionMatrix();
[381]534        updateDistortionMesh();
[384]535        _distortionSet->clearDirtyStatus();
[381]536}
537
538void DistortionManipulator::updateDistortionViewProjectionMatrix()
539{
540        if(!_distortionSet.valid())
541        {
542                osg::notify(osg::WARN) << "You cannot update the distortion without distortion set up." << std::endl;
543                return;
544        }
545
546        if(_viewer.valid())
[406]547        {
548
[408]549#if 0
[406]550                /*******************************************/
551                /***   ViewMatrix-Testcase  "Garching"   ***/
552                /*******************************************/
553
[408]554                osg::Matrixd viewMatrix, transView, rotView;
[406]555               
[408]556                rotView.makeRotate(
[405]557                        osg::DegreesToRadians(-130.0), osg::Vec3(0,1,0),                // heading
558                        osg::DegreesToRadians(0.0), osg::Vec3(-1,0,0),  // pitch
[406]559                        osg::DegreesToRadians(-80.0), osg::Vec3(0,0,1));        // roll
[403]560
[408]561                transView.makeTranslate(-4169457.75*0.99975, -860009.06*0.99975, -4737192.00*0.99975);
562                viewMatrix = transView * rotView;
[406]563
564                if(_viewer->getCameraManipulator()==NULL)
565                {
[408]566                        _viewer->getCamera()->setViewMatrix(viewMatrix);
[406]567                }
568                else
569                {
[408]570                        _viewer->getCameraManipulator()->setByMatrix(osg::Matrixd::inverse(viewMatrix));
[406]571                }
572
[408]573                /**************************************/
574                /***   End of Testcase "Garching"   ***/
575                /**************************************/
576#endif
577
[406]578                _viewer->getCamera()->setProjectionMatrix(osg::Matrix::identity());
579
[403]580                // Get slave struct to update the offset matrixes.
581                //Slave Camera Settings
[398]582                osgViewer::View::Slave* sceneSlave = _viewer->findSlaveForCamera( _distortionSet->getSceneCamera() );
583                sceneSlave->_projectionOffset = _distortionSet->getProjectionOffset();
584                sceneSlave->_viewOffset = _distortionSet->getViewOffset();
[391]585
[401]586#if 0
587                // Print viewMatrixAsLookAt for Debug Purposes
588                osg::Vec3 Eye,Focus,Vertical;
589                _viewer->getCamera()->getViewMatrixAsLookAt(Eye,Focus,Vertical);
590                OSG_ALWAYS<<"Camera Eyepoint: X:"<<Eye.x()<<" Y:"<<Eye.y()<<" Z:"<<Eye.z()<<std::endl;
591                printf("Camera Eyepoint: %.2lf, %.2lf, %.2lf\n",Eye.x(),Eye.y(),Eye.z());
592                printf("Camera Direction: %.2lf, %.2lf, %.2lf\n",Focus.x()-Eye.x(),Focus.y()-Eye.y(),Focus.z()-Eye.z());
593                printf("Vertical after: %.2lf, %.2lf, %.2lf\n",Vertical.x()-Eye.x(),Vertical.y()-Eye.y(),Vertical.z()-Eye.z());
594#endif
[391]595
[381]596        }
597        else
598                OSG_NOTIFY(osg::ALWAYS)<<"Invalid viewer!"<<std::endl;
599}
600
601void DistortionManipulator::updateDistortionMesh()
602{
[385]603        // Create mesh vertex array & textCoord array
[384]604        osg::Vec3Array* vertices = new osg::Vec3Array;
605        osg::Vec2Array* texCoords = new osg::Vec2Array;
[386]606        osg::Vec4Array* colors = new osg::Vec4Array;
[384]607
608        for(unsigned int i=0;i<_distortionSet->getDistortionMesh()->size();i++)
609        {
[387]610                osg::Vec4 tmpSrc = _distortionSet->getDistortionMesh()->at(i);
611
[384]612                // Scale vector with the screen resolution
[387]613                osg::Vec3 tmpVec = osg::Vec3(   tmpSrc.x()*_screenPixWidth,
614                                                                                tmpSrc.y()*_screenPixHeight,
[384]615                                                                                0.0     );
616                vertices->push_back( tmpVec );
[408]617                //OSG_ALWAYS<<"Transfering mesh vertex : X:"<<tmpVec.x()<<" Y:"<<tmpVec.y()<<" Z:"<<tmpVec.z()<<std::endl;
[384]618
619                // Note texCoords
[387]620                osg::Vec2 tmpTexCoords = osg::Vec2(     tmpSrc.z()*_screenPixWidth,
621                                                                                        tmpSrc.w()*_screenPixHeight );
[393]622
[384]623                texCoords->push_back(tmpTexCoords);
[408]624                //OSG_ALWAYS<<"Transfering texcoord vertex : X:"<<tmpTexCoords.x()<<" Y:"<<tmpTexCoords.y()<<std::endl;
[386]625
626                colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
[384]627        }
628
[387]629        // --------- Apply Arrays -----------------
[386]630        osg::Geometry* geom = _distortionSet->getDistortionInternals()->getChild(osgViewer::DistortionSet::MESH)->asGeode()->getDrawable(0)->asGeometry();
631
[387]632        // If arraysize differs: Replace primite sets
633        bool regeneratePrimitiveSets = true;
634        osg::Vec3Array* prevArray = dynamic_cast<osg::Vec3Array*>(geom->getVertexArray());
635        if(prevArray) 
636                regeneratePrimitiveSets = prevArray->size()!=vertices->size()?true:false;
637       
638        // Set new Arrays
[386]639        geom->setVertexArray(vertices);
640        geom->setTexCoordArray(0, texCoords);   // todo: 0 ist hardcoded und müsste durch getTexUnitScene() ersetzt werden
641        geom->setColorArray(colors);
[387]642
643        // If required: regenerate primitiveset:
644        OSG_ALWAYS<<"PrimitiveSet regeneration required!"<<std::endl;
645        geom->removePrimitiveSet(0, geom->getNumPrimitiveSets());       
646        //// Create new primitives : Quads grid
[386]647        unsigned int rows = _distortionSet->getDistortionMeshRows();
648        unsigned int columns = _distortionSet->getDistortionMeshColumns();
649        for ( unsigned int row=0; row<rows-1; row++ )   // each strip consists of two affected vertex rows, so we need only row-1 strips.
650        {
651                osg::ref_ptr<osg::DrawElementsUInt> de = new osg::DrawElementsUInt(osg::PrimitiveSet::QUAD_STRIP, columns*2);   // columns*2 = number of involved vertices for this strip.
652                for ( unsigned int col=0; col<columns; col++ )
653                {
654                        (*de)[col*2 + 0] = row*columns + col;
655                        (*de)[col*2 + 1] = (row+1)*columns + col;
656                }
657                geom->addPrimitiveSet( de.get() );
658        }
[384]659}
Note: See TracBrowser for help on using the repository browser.