source: experimental/distortionNG/DistortionManipulator.cpp @ 403

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

placebo Manipulator added to allow to use manipulators together with directly set Viewer matrix

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