source: experimental/distortionNG/DistortionManipulator.cpp @ 358

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