source: experimental/distortionNG/DistortionManipulator.cpp @ 373

Last change on this file since 373 was 373, checked in by Torben Dannhauer, 12 years ago
File size: 19.0 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
25#include <osgDB/Registry>
26#include <osgDB/ReaderWriter>
27#include <osgDB/WriteFile>
28
29#include "DistortionSetupStrategy.h"
30
31using namespace osg;
32using namespace osgViewer;
33
34
35DistortionManipulator::DistortionManipulator(DistortionSet* ds)
36 : _highlightColor( osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f) ), _distortionSet( ds )
37{
38        activeSetupMode = DISABLED;
39        activeDistortionMode = MESH;
40        activeManualSetupMode = DISTORTION;
41        activeVisualizationMode = NONE;
42
43        _delegatedDistortionSetupStrategy = NULL;
44
45        _highlighter = NULL;
46       
47        createVertexHighlighter();
48        createHUD();
49
50        _camera = 0;
51        //_distortionMesh(distortionMesh)
52
53        // Create Shader to vizualize intensitymap during blending setup.
54        osg::Shader* sh = osg::Shader::readShaderFile( osg::Shader::FRAGMENT, "shaderIntensityMapVis.frag" ); 
55        sh->setName("shaderIntensityMapVis");
56        ds->setShaderIntensityMapVis( sh );
57
58        //LF Get Screen Resolution for Cursor Position Scaling
59        osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
60        if (!wsi) { osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl; }
61        wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), _screenPixWidth, _screenPixHeight);
62
63
64}
65
66DistortionManipulator::~DistortionManipulator()
67{
68}
69
70void DistortionManipulator::getUsage(osg::ApplicationUsage& usage) const
71{
72        usage.addKeyboardMouseBinding("Keypad 0","Show/Hide distortion HUD.");
73        usage.addKeyboardMouseBinding("Keypad 1","Reset distortion.");
74        usage.addKeyboardMouseBinding("Keypad 2","Reset intensity blending.");
75        usage.addKeyboardMouseBinding("Keypad 4","Toggles Setup Mode between DISABLED, MANUAL & DELEGATED.");
76        usage.addKeyboardMouseBinding("Keypad 5","MANUAL Mode: Toggle between blending & distortion setup.");
77    usage.addKeyboardMouseBinding("Keypad 6","MANUAL Mode: Toggle if distortion drags affect mesh or rtt texture coordinates.");        // Defaults to Mesh
78        usage.addKeyboardMouseBinding("Keypad 7","Show distortion mesh / intensity map / none.");
79        usage.addKeyboardMouseBinding("Keypad 8","Save distortion set.");       // via plugin
80}
81
82bool DistortionManipulator::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, osg::Object* obj, osg::NodeVisitor* nv)
83{
84
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                                // ToDo :: nach dem der distortioncontainer von der strategy aktualisiert wurde muss nun noch der container noch angewendet werden.
261                                OSG_ALWAYS<<"..done"<<std::endl;
262                        }
263                        break;
264                }
265        case (osgGA::GUIEventAdapter::RESIZE):  // todo: adapt distortion mesh to new screen size
266                {
267                        OSG_ALWAYS<<"RESIZE!"<<std::endl;
268                        break;
269                }
270
271        default:
272            return false;
273    }
274    return false;
275}
276
277void DistortionManipulator::resetIntensityMap()
278{
279        if(!_distortionSet.valid())
280                return;
281
282        osg::ref_ptr<osg::Image> image = _distortionSet->getIntensityMap();
283
284        OSG_ALWAYS<<"Reseting IntensityMap Blending."<<std::endl;
285
286        if (!image->isDataContiguous())
287        {
288                OSG_WARN<<"Warning: DistortionManipulator does not support working with non contiguous imagery as blendmaps!"<<std::endl;
289                return;
290        }
291
292        // Fill intensity map with 255
293        unsigned char* dataPtr = image->data(); 
294        for(unsigned int i=0;i<image->getTotalSizeInBytes();i++)
295        {
296                *dataPtr++ = 255; 
297        }
298        image->dirty();
299}
300
301void DistortionManipulator::resetDistortion()
302{
303        if(!_distortionSet.valid())
304                return;
305
306        OSG_ALWAYS<<"ToDo: resetDistortion()"<<std::endl;
307}
308
309void DistortionManipulator::showDistortionMesh(bool show)
310{
311        osg::StateSet* stateset = _distortionSet->getDistortionInternals()->getChild(DistortionSet::MESH)->getOrCreateStateSet();
312
313        // Append a PolygonMode stateset if required
314    osg::PolygonMode* polyModeObj = dynamic_cast<osg::PolygonMode*>(stateset->getAttribute(osg::StateAttribute::POLYGONMODE));
315    if (!polyModeObj)
316    {
317        polyModeObj = new osg::PolygonMode;
318        stateset->setAttribute(polyModeObj, osg::StateAttribute::PROTECTED|osg::StateAttribute::ON);
319    }
320 
321        // Set Polygonmode
322        if(show)
323                polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE);
324        else
325                polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::FILL);
326}
327
328void DistortionManipulator::showIntensityMap(bool show)
329{
330        if(_distortionSet.valid())
331        {
332                osg::StateSet* stateset = _distortionSet->getDistortionInternals()->getChild(DistortionSet::MESH)->getOrCreateStateSet();
333                osg::Program* program = static_cast<osg::Program*>(stateset->getAttribute(::osg::StateAttribute::PROGRAM));
334
335                if(show)
336                {
337                        program->removeShader( _distortionSet->getShaderIntensityMap() );
338                        program->addShader( _distortionSet->getShaderIntensityMapVis() );
339                }
340                else
341                {
342                        program->removeShader( _distortionSet->getShaderIntensityMapVis() );
343                        program->addShader( _distortionSet->getShaderIntensityMap() );
344                }
345        }
346}
347
348void DistortionManipulator::createVertexHighlighter()
349{
350        osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
351        (*colors)[0] = _highlightColor;
352
353        _highlighter = new osg::Geometry;
354        _highlighter->setDataVariance( osg::Object::DYNAMIC );
355        _highlighter->setUseDisplayList( false );
356        _highlighter->setUseVertexBufferObjects( true );
357        _highlighter->setVertexArray( new osg::Vec3Array(1) );  // The highlighter vertex is updated by computeSelectedVertex(..)
358        _highlighter->setColorArray( colors.get() );
359        _highlighter->setColorBinding( osg::Geometry::BIND_OVERALL );
360        _highlighter->addPrimitiveSet( new osg::DrawArrays(GL_POINTS, 0, 1) );
361
362       
363        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
364        geode->addDrawable( _highlighter.get() );
365        geode->getOrCreateStateSet()->setAttributeAndModes( new osg::Point(8.0f) );
366        geode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
367        geode->setCullingActive(false); // disable the culling for the selector, otherwise the selector is culled away on the edge.
368
369        _distortionSet->getDistortionInternals()->addChild(geode, false);       //  = child #1  :definition: child #0 = mesh, #1 = highlighter, #2 HUD
370}
371
372void DistortionManipulator::createHUD()
373{
374        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
375       
376        osg::StateSet* stateSet = geode->getOrCreateStateSet();
377        stateSet->setRenderBinDetails( 99, "RenderBin");
378        // disable depth test to ensure that it is always drawn.
379        stateSet->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
380        stateSet->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
381
382        // Modify StateSet to protect it against state changes by the stateset Manipulator
383        osg::PolygonMode* polyModeObj = new osg::PolygonMode;
384    stateSet->setAttribute(polyModeObj, osg::StateAttribute::PROTECTED|osg::StateAttribute::ON);
385
386        // Add Text:
387        osg::Vec3 position(20.0f,120.0f,0.0f);
388        osg::Vec3 delta(0.0f,-25.0f,0.0f);
389        std::string timesFont("fonts/arial.ttf");
390        {
391                osg::ref_ptr<osgText::Text> textHeader = new osgText::Text;
392                textHeader->setText("Distortion Setup:");
393                textHeader->setFont(timesFont);
394                textHeader->setPosition(position);
395                textHeader->setCharacterSize(21);
396                textHeader->setDataVariance(osg::Object::STATIC); 
397                geode->addDrawable( textHeader );
398
399                position += delta;
400
401                hudSetupMode = new osgText::Text;
402                hudSetupMode->setFont(timesFont);
403                hudSetupMode->setPosition(position);
404                hudSetupMode->setCharacterSize(21);
405                hudSetupMode->setDataVariance(osg::Object::DYNAMIC); 
406                geode->addDrawable( hudSetupMode );
407
408                position += delta;
409
410                hudDistortionMode = new osgText::Text;
411                hudDistortionMode->setFont(timesFont);
412                hudDistortionMode->setPosition(position);
413                hudDistortionMode->setCharacterSize(21);
414                hudDistortionMode->setDataVariance(osg::Object::DYNAMIC); 
415                geode->addDrawable( hudDistortionMode );
416
417                position += delta;
418
419                hudManualSetupMode = new osgText::Text;
420                hudManualSetupMode->setFont(timesFont);
421                hudManualSetupMode->setPosition(position);
422                hudManualSetupMode->setCharacterSize(21);
423                hudManualSetupMode->setDataVariance(osg::Object::DYNAMIC); 
424                geode->addDrawable( hudManualSetupMode );
425
426                position += delta;
427
428                hudVisualizationMode = new osgText::Text;
429                hudVisualizationMode->setFont(timesFont);
430                hudVisualizationMode->setPosition(position);
431                hudVisualizationMode->setCharacterSize(21);
432                hudVisualizationMode->setDataVariance(osg::Object::DYNAMIC); 
433                geode->addDrawable( hudVisualizationMode );
434        }
435       
436        updateHUD();
437        _distortionSet->getDistortionInternals()->addChild(geode, false);       //  = child #2. The definition is: child #0 = mesh, #1 = highlighter, #2 HUD
438}
439
440void DistortionManipulator::updateHUD()
441{
442        switch(activeSetupMode)
443        {
444                case DISABLED : hudSetupMode->setText("Setup Mode : DISABLED"); break;
445                case MANUAL : hudSetupMode->setText("Setup Mode : MANUAL"); break;
446                case DELEGATED : hudSetupMode->setText("Setup Mode : DELEGATED"); break;
447                default: hudSetupMode->setText("");
448        };
449        switch(activeDistortionMode)
450        {
451                case MESH : hudDistortionMode->setText("Distortion Mode : MESH"); break;
452                case TEXCOORDINATES : hudDistortionMode->setText("Distortion Mode : TEXCOORDINATES"); break;
453                default: hudDistortionMode->setText("");
454        };
455        switch(activeManualSetupMode)
456        {
457                case DISTORTION : hudManualSetupMode->setText("Manual Setup Mode : DISTORTION"); break;
458                case BLENDING : hudManualSetupMode->setText("Manual Setup Mode : BLENDING"); break;
459                default: hudManualSetupMode->setText("");
460        };
461        switch(activeVisualizationMode)
462        {
463                case DISTORTION_MESH : hudVisualizationMode->setText("Visualization Mode : DISTORTION_MESH"); break;
464                case INTENSITY_MAP : hudVisualizationMode->setText("Visualization Mode : INTENSITY_MAP"); break;
465                case NONE : hudVisualizationMode->setText("Visualization Mode : NONE"); break;
466                default: hudVisualizationMode->setText("");
467        };
468}
469
470void DistortionManipulator::computeSelectedVertex( osgUtil::LineSegmentIntersector::Intersection& result )
471{
472        osg::Geometry* geom = dynamic_cast<osg::Geometry*>( result.drawable.get() );
473        if ( !geom || geom==_highlighter )
474                return;
475
476        osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>( geom->getVertexArray() );
477        osg::Vec3Array* selVertices = dynamic_cast<osg::Vec3Array*>( _highlighter->getVertexArray() );
478        if ( !vertices || !selVertices )
479                return;
480       
481        OSG_NOTIFY(osg::ALWAYS)<<"size of vertices="<<vertices->size()<<std::endl;
482        OSG_NOTIFY(osg::ALWAYS)<<"size of selVertices="<<selVertices->size()<<std::endl;
483
484        osg::Vec3 point = result.getWorldIntersectPoint();
485        osg::Matrix matrix = osg::computeLocalToWorld( result.nodePath );       // To compute the intersection vertices in world coordinates not in model coordinates
486        OSG_NOTIFY(osg::ALWAYS) << "Intersection-indices: Size=" << result.indexList.size() << std::endl;
487        const std::vector<unsigned int>& selIndices = result.indexList;
488        {
489                double maxRatio = 0.0;
490                int closestVertexIndex = 0;
491                for ( unsigned int i=0; i<3 && i<result.ratioList.size(); i++ ) //iterate through rations and search for maxRation=nearestVertex
492                {
493                        if(result.ratioList[i] > maxRatio)
494                        {
495                                maxRatio = result.ratioList[i];
496                                closestVertexIndex = result.indexList[i];
497                        }
498                        OSG_NOTIFY(osg::ALWAYS)<<"maxRatio="<<maxRatio<<std::endl;
499                        OSG_NOTIFY(osg::ALWAYS)<<"closestVertexIndex="<<closestVertexIndex<<std::endl;
500                }
501                OSG_NOTIFY(osg::ALWAYS)<<"nearest vertex: X="<<(*vertices)[closestVertexIndex].x()<<" Y="<<(*vertices)[closestVertexIndex].y()<<" Z="<<(*vertices)[closestVertexIndex].z()<<std::endl;
502                osg::Vec3 vertex = (*vertices)[closestVertexIndex] * matrix;
503
504                selVertices->front() = vertex;         
505                OSG_NOTIFY(osg::ALWAYS)<<"selected vertice: X="<<vertex.x()<<" Y="<<vertex.y()<<" Z="<<vertex.z()<<std::endl;
506        }
507        selVertices->dirty();
508        _highlighter->dirtyBound(); 
509}
Note: See TracBrowser for help on using the repository browser.