source: experimental/distortionNG/DistortionManipulator.cpp @ 356

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