source: experimental/distortionNG/DistortionManipulator.cpp @ 355

Last change on this file since 355 was 355, checked in by Torben Dannhauer, 12 years ago
File size: 12.5 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
40        _camera = 0;
41        //_distortionMesh(distortionMesh)
42}
43
44DistortionManipulator::~DistortionManipulator()
45{
46}
47
48void DistortionManipulator::getUsage(osg::ApplicationUsage& usage) const
49{
50    usage.addKeyboardMouseBinding("Keypad 7","Show distortion mesh / intensity map / none.");
51        usage.addKeyboardMouseBinding("Keypad 8","Save distortion set.");       // via plugin
52        usage.addKeyboardMouseBinding("Keypad 4","Toggles Setup Mode between DISABLED, MANUAL & DELEGATED.");
53        usage.addKeyboardMouseBinding("Keypad 5","MANUAL Mode: Toggle between blending & distortion setup.");
54        usage.addKeyboardMouseBinding("Keypad 6","MANUAL Mode: Toggle if distortion drags affect mesh or rtt texture coordinates.");    // Defaults to Mesh
55        usage.addKeyboardMouseBinding("Keypad 1","Reset distortion.");
56        usage.addKeyboardMouseBinding("Keypad 2","Reset intensity blending.");
57}
58
59bool DistortionManipulator::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, osg::Object* obj, osg::NodeVisitor* nv)
60{
61        switch(ea.getEventType())
62    {
63        case(osgGA::GUIEventAdapter::MOVE): break;
64        case(osgGA::GUIEventAdapter::DRAG):
65                {
66                        if ( activeSetupMode == MANUAL)
67                        {
68                                osg::notify(osg::ALWAYS)<<std::endl<<"Drag:"<<std::endl<<"ea.getGraphicsContext()="<<ea.getGraphicsContext()<<std::endl;
69                                osg::notify(osg::ALWAYS)<<"ea.getXnormalized()="<<ea.getXnormalized()<<std::endl;
70                                osg::notify(osg::ALWAYS)<<"ea.getYnormalized()="<<ea.getYnormalized()<<std::endl;
71                                osg::notify(osg::ALWAYS)<<"ea.getX()="<<ea.getX()<<std::endl;
72                                osg::notify(osg::ALWAYS)<<"ea.getXin()="<<ea.getXmin()<<std::endl;
73                                osg::notify(osg::ALWAYS)<<"ea.getXmax()="<<ea.getXmax()<<std::endl;
74                                osg::notify(osg::ALWAYS)<<"ea.getY()="<<ea.getY()<<std::endl;
75                                osg::notify(osg::ALWAYS)<<"ea.getYin()="<<ea.getYmin()<<std::endl;
76                                osg::notify(osg::ALWAYS)<<"ea.getYmax()="<<ea.getYmax()<<std::endl;
77
78                                return true;    // true means event handled: not forwarded to the camera manipulator;
79                        }
80                        break;
81
82                }
83        case(osgGA::GUIEventAdapter::PUSH):
84                {
85                        OSG_ALWAYS<<"mouse click!"<<std::endl;
86                        if ( activeSetupMode == MANUAL && ea.getModKeyMask()&osgGA::GUIEventAdapter::MODKEY_CTRL && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON )
87                        {
88                                osgViewer::View* viewer = dynamic_cast<osgViewer::View*>(&aa);
89                                if ( viewer )
90                                {
91                                        osg::notify(osg::ALWAYS)<<std::endl<<"Intersection:"<<std::endl<<"ea.getX()="<<ea.getX()<<std::endl;
92                                        osg::notify(osg::ALWAYS)<<"ea.getY()="<<ea.getY()<<std::endl;
93                                        osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::PROJECTION, ea.getX(), ea.getY());
94                                        osgUtil::IntersectionVisitor iv( intersector.get() );
95                                        _distortionSet->getDistortionCamera()->accept( iv );
96                               
97                                        if ( intersector->containsIntersections() )
98                                        {
99                                                osgUtil::LineSegmentIntersector::Intersection& result = *(intersector->getIntersections().begin());
100                                                computeSelectedVertex( result );
101                                        }
102                                }
103                        }
104                        break;
105                }
106        case(osgGA::GUIEventAdapter::RELEASE): break;
107        case(osgGA::GUIEventAdapter::KEYDOWN):
108                {
109                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_End)    // KP 1: reset distortion
110                        {
111                                resetDistortion();
112                                return(true);
113                        }
114                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Down)   // KP 2: reset intensity map
115                        {
116                                resetIntensityMap();
117                                return(true);
118                        }
119                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Left)   // KP 4: Toggles Setup Mode between DISABLED, MANUAL & DELEGATED.
120                        {
121                                switch(activeSetupMode)
122                                {
123                                        case DISABLED : 
124                                        {
125                                                activeSetupMode = MANUAL;
126                                                OSG_ALWAYS<<"SetupMode MANUAL activated"<<std::endl;
127                                                _distortionSet->getDistortionInternals()->setValue(1, true); // per definition #0 = mesh, #1 = highlighter
128                                                break;
129                                        }
130                                        case MANUAL :
131                                        {
132                                                activeSetupMode = DELEGATED;
133                                                _distortionSet->getDistortionInternals()->setValue(1, false); // per definition #0 = mesh, #1 = highlighter
134                                                OSG_ALWAYS<<"SetupMode DELEGATED activated"<<std::endl;
135                                                break;
136                                        }
137                                        case DELEGATED :
138                                        {
139                                                activeSetupMode = DISABLED;
140                                                _distortionSet->getDistortionInternals()->setValue(1, false); // per definition #0 = mesh, #1 = highlighter
141                                                OSG_ALWAYS<<"SetupMode DISABLED activated"<<std::endl;
142                                                break;
143                                        }
144                                }
145
146                                return(true);
147                        }
148                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Begin)  // KP 5: MANUAL Mode: Toggle between blending & distortion setup.
149                        {
150
151                                activeManualSetupMode = (activeManualSetupMode==DISTORTION?BLENDING:DISTORTION);
152                                OSG_ALWAYS<<"KEY_KP_5 : activeManualSetupMode is now "<<activeManualSetupMode<<std::endl;
153                                return(true);
154                        }
155                        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
156                        {
157                                activeDistortionMode = (activeDistortionMode==MESH?TEXCOORDINATES:MESH);
158                                OSG_ALWAYS<<"KEY_KP_6 : activeDistortionMode is now "<<activeDistortionMode<<std::endl;
159                                return(true);
160                        }
161                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Home)   // KP 7: Show distortion mesh / intensity map / none.
162                        {
163                                switch(activeVisualizationMode)
164                                {       
165                                        case DISTORTION_MESH : 
166                                        {
167                                                activeVisualizationMode = INTENSITY_MAP;
168                                                showDistortionMesh(true);
169                                                showIntensityMap(false);
170                                                break;
171                                        }
172                                        case INTENSITY_MAP :
173                                        {
174                                                activeVisualizationMode = NONE;
175                                                showDistortionMesh(false);
176                                                showIntensityMap(true);
177                                                break;
178                                        }
179                                        case NONE : 
180                                        {
181                                                activeVisualizationMode = DISTORTION_MESH;
182                                                showDistortionMesh(false);
183                                                showIntensityMap(false);
184                                                break;
185                                        }
186                                }
187
188
189                                OSG_ALWAYS<<"KEY_KP_7 : activeVisualizationMode is now "<<activeVisualizationMode<<std::endl<<std::endl;
190                                return(true);
191                        }
192                        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Up)     // KP 8: Save distortion set     via plugin
193                        {
194                                OSG_ALWAYS<<"KEY_KP_8 : todo: Save DistortionContainer"<<std::endl;
195                                return(true);
196                        }
197                       
198
199                        return false;   // Event ignored
200                }
201        case(osgGA::GUIEventAdapter::KEYUP): break;
202                case(osgGA::GUIEventAdapter::FRAME):
203                {
204                        //OSG_ALWAYS<<"FRAME!"<<std::endl;
205                        break;
206                }
207        case (osgGA::GUIEventAdapter::RESIZE):  // todo: adapt distortion mesh to new screen size
208                {
209                        OSG_ALWAYS<<"RESIZE!"<<std::endl;
210                        break;
211                }
212
213        default:
214            return false;
215    }
216    return false;
217}
218
219void DistortionManipulator::resetIntensityMap()
220{
221        if(!_distortionSet.valid())
222                return;
223
224        osg::ref_ptr<osg::Image> image = _distortionSet->getIntensityMap();
225
226        OSG_ALWAYS<<"Reseting IntensityMap Blending."<<std::endl;
227
228        if (!image->isDataContiguous())
229        {
230                OSG_WARN<<"Warning: DistortionManipulator does not support working with non contiguous imagery as blendmaps!"<<std::endl;
231                return;
232        }
233
234        // Fill intensity map with 255
235        unsigned char* dataPtr = image->data(); 
236        for(unsigned int i=0;i<image->getTotalSizeInBytes();i++)
237        {
238                *dataPtr++ = 255; 
239        }
240        image->dirty();
241}
242
243void DistortionManipulator::resetDistortion()
244{
245        if(!_distortionSet.valid())
246                return;
247
248        OSG_ALWAYS<<"ToDo: resetDistortion()"<<std::endl;
249}
250
251void DistortionManipulator::showDistortionMesh(bool show)
252{
253        OSG_ALWAYS<<"ToDo: showDistortionMesh(bool) is now "<<show<<std::endl;
254
255        // Todo: Stateset muss das von der MeshGeode sein.
256
257   /* osg::PolygonMode* polyModeObj = dynamic_cast<osg::PolygonMode*>(_stateset->getAttribute(osg::StateAttribute::POLYGONMODE));
258    if (!polyModeObj)
259    {
260        polyModeObj = new osg::PolygonMode;
261        _stateset->setAttribute(polyModeObj);
262    }
263 
264        if(show)
265                polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE);
266        else
267                polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::FILL);*/
268}
269
270void DistortionManipulator::showIntensityMap(bool show)
271{
272                OSG_ALWAYS<<"ToDo: showIntensityMap(bool) is now "<<show<<std::endl;
273
274                if(_distortionSet.valid())
275                        _distortionSet->setShowIntensityMapOnly(show);
276}
277
278void DistortionManipulator::createVertexHighlighter()
279{
280        osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
281        (*colors)[0] = _highlightColor;
282
283        _highlighter = new osg::Geometry;
284        _highlighter->setDataVariance( osg::Object::DYNAMIC );
285        _highlighter->setUseDisplayList( false );
286        _highlighter->setUseVertexBufferObjects( true );
287        _highlighter->setVertexArray( new osg::Vec3Array(1) );  // The highlighter vertex is updated by computeSelectedVertex(..)
288        _highlighter->setColorArray( colors.get() );
289        _highlighter->setColorBinding( osg::Geometry::BIND_OVERALL );
290        _highlighter->addPrimitiveSet( new osg::DrawArrays(GL_POINTS, 0, 1) );
291
292       
293        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
294        geode->addDrawable( _highlighter.get() );
295        geode->getOrCreateStateSet()->setAttributeAndModes( new osg::Point(8.0f) );
296        geode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
297        geode->setCullingActive(false); // disable the culling for the selector, otherwise the selector is culled away on the edge.
298
299        _distortionSet->getDistortionInternals()->addChild(geode, false);
300}
301
302void DistortionManipulator::computeSelectedVertex( osgUtil::LineSegmentIntersector::Intersection& result )
303{
304        osg::Geometry* geom = dynamic_cast<osg::Geometry*>( result.drawable.get() );
305        if ( !geom || geom==_highlighter )
306                return;
307
308        osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>( geom->getVertexArray() );
309        osg::Vec3Array* selVertices = dynamic_cast<osg::Vec3Array*>( _highlighter->getVertexArray() );
310        if ( !vertices || !selVertices )
311                return;
312       
313        OSG_NOTIFY(osg::ALWAYS)<<"size of vertices="<<vertices->size()<<std::endl;
314        OSG_NOTIFY(osg::ALWAYS)<<"size of selVertices="<<selVertices->size()<<std::endl;
315
316        osg::Vec3 point = result.getWorldIntersectPoint();
317        osg::Matrix matrix = osg::computeLocalToWorld( result.nodePath );       // To compute the intersection vertices in world coordinates not in model coordinates
318        OSG_NOTIFY(osg::ALWAYS) << "Intersection-indices: Size=" << result.indexList.size() << std::endl;
319        const std::vector<unsigned int>& selIndices = result.indexList;
320        {
321                double maxRatio = 0.0;
322                int closestVertexIndex = 0;
323                for ( unsigned int i=0; i<3 && i<result.ratioList.size(); i++ ) //iterate through rations and search for maxRation=nearestVertex
324                {
325                        if(result.ratioList[i] > maxRatio)
326                        {
327                                maxRatio = result.ratioList[i];
328                                closestVertexIndex = result.indexList[i];
329                        }
330                        OSG_NOTIFY(osg::ALWAYS)<<"maxRatio="<<maxRatio<<std::endl;
331                        OSG_NOTIFY(osg::ALWAYS)<<"closestVertexIndex="<<closestVertexIndex<<std::endl;
332                }
333                OSG_NOTIFY(osg::ALWAYS)<<"nearest vertex: X="<<(*vertices)[closestVertexIndex].x()<<" Y="<<(*vertices)[closestVertexIndex].y()<<" Z="<<(*vertices)[closestVertexIndex].z()<<std::endl;
334                osg::Vec3 vertex = (*vertices)[closestVertexIndex] * matrix;
335
336                selVertices->front() = vertex;         
337                OSG_NOTIFY(osg::ALWAYS)<<"selected vertice: X="<<vertex.x()<<" Y="<<vertex.y()<<" Z="<<vertex.z()<<std::endl;
338        }
339        selVertices->dirty();
340        _highlighter->dirtyBound(); 
341}
Note: See TracBrowser for help on using the repository browser.