source: experimental/distortionNG/DistortionManipulator.cpp @ 380

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