~saiarcot895/ubuntu/trusty/openscenegraph/armhf-support

« back to all changes in this revision

Viewing changes to OpenSceneGraph/src/osgViewer/Keystone.cpp

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2013-11-12 02:21:14 UTC
  • mfrom: (31.1.3 trusty-proposed)
  • Revision ID: package-import@ubuntu.com-20131112022114-qaxfhdnhn88vnh10
Tags: 3.2.0~rc1-1ubuntu1
Fix deprecated url_feof.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* OpenSceneGraph example, osgkeystone.
 
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 <osg/Notify>
 
20
#include <osg/io_utils>
 
21
#include <osg/DisplaySettings>
 
22
#include <osg/ValueObject>
 
23
 
 
24
#include <osgDB/WriteFile>
 
25
#include <osgDB/ReadFile>
 
26
 
 
27
#include <osgViewer/Keystone>
 
28
 
 
29
using namespace osgViewer;
 
30
 
 
31
Keystone::Keystone():
 
32
    keystoneEditingEnabled(false),
 
33
    gridColour(1.0f,1.0f,1.0f,1.0f),
 
34
    bottom_left(-1.0,-1.0),
 
35
    bottom_right(1.0,-1.0),
 
36
    top_left(-1.0,1.0),
 
37
    top_right(1.0,1.0) {}
 
38
 
 
39
Keystone::Keystone(const Keystone& rhs, const osg::CopyOp & copyop):
 
40
    osg::Object(rhs, copyop),
 
41
    keystoneEditingEnabled(rhs.keystoneEditingEnabled),
 
42
    gridColour(rhs.gridColour),
 
43
    bottom_left(rhs.bottom_left),
 
44
    bottom_right(rhs.bottom_right),
 
45
    top_left(rhs.top_left),
 
46
    top_right(rhs.top_right) {}
 
47
 
 
48
 
 
49
void Keystone::reset()
 
50
{
 
51
    bottom_left.set(-1.0,-1.0);
 
52
    bottom_right.set(1.0,-1.0);
 
53
    top_left.set(-1.0,1.0);
 
54
    top_right.set(1.0,1.0);
 
55
}
 
56
 
 
57
Keystone& Keystone::operator = (const Keystone& rhs)
 
58
{
 
59
    if (&rhs==this) return *this;
 
60
    keystoneEditingEnabled = rhs.keystoneEditingEnabled;
 
61
    gridColour = rhs.gridColour;
 
62
    bottom_left = rhs.bottom_left;
 
63
    bottom_right = rhs.bottom_right;
 
64
    top_left = rhs.top_left;
 
65
    top_right = rhs.top_right;
 
66
    return *this;
 
67
}
 
68
 
 
69
void Keystone::compute3DPositions(osg::DisplaySettings* ds, osg::Vec3& tl, osg::Vec3& tr, osg::Vec3& br, osg::Vec3& bl) const
 
70
{
 
71
    double tr_x = ((top_right-bottom_right).length()) / ((top_left-bottom_left).length());
 
72
    double r_left = sqrt(tr_x);
 
73
    double r_right = r_left/tr_x;
 
74
 
 
75
    double tr_y = ((top_right-top_left).length()) / ((bottom_right-bottom_left).length());
 
76
    double r_bottom = sqrt(tr_y);
 
77
    double r_top = r_bottom/tr_y;
 
78
 
 
79
    double screenDistance = ds->getScreenDistance();
 
80
    double screenWidth = ds->getScreenWidth();
 
81
    double screenHeight = ds->getScreenHeight();
 
82
 
 
83
    tl = osg::Vec3(screenWidth*0.5*top_left.x(), screenHeight*0.5*top_left.y(), -screenDistance)*r_left*r_top;
 
84
    tr = osg::Vec3(screenWidth*0.5*top_right.x(), screenHeight*0.5*top_right.y(), -screenDistance)*r_right*r_top;
 
85
    br = osg::Vec3(screenWidth*0.5*bottom_right.x(), screenHeight*0.5*bottom_right.y(), -screenDistance)*r_right*r_bottom;
 
86
    bl = osg::Vec3(screenWidth*0.5*bottom_left.x(), screenHeight*0.5*bottom_left.y(), -screenDistance)*r_left*r_bottom;
 
87
}
 
88
 
 
89
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
90
//
 
91
// Keystone helper functions
 
92
//
 
93
struct KeystoneCullCallback : public osg::Drawable::CullCallback
 
94
{
 
95
    KeystoneCullCallback(Keystone* keystone=0):_keystone(keystone) {}
 
96
    KeystoneCullCallback(const KeystoneCullCallback&, const osg::CopyOp&) {}
 
97
 
 
98
    META_Object(osg,KeystoneCullCallback);
 
99
 
 
100
    /** do customized cull code, return true if drawable should be culled.*/
 
101
    virtual bool cull(osg::NodeVisitor* /*nv*/, osg::Drawable* /*drawable*/, osg::RenderInfo* /*renderInfo*/) const
 
102
    {
 
103
        return _keystone.valid() ? !_keystone->getKeystoneEditingEnabled() : true;
 
104
    }
 
105
 
 
106
    osg::ref_ptr<Keystone> _keystone;
 
107
};
 
108
 
 
109
 
 
110
struct KeystoneUpdateCallback : public osg::Drawable::UpdateCallback
 
111
{
 
112
    KeystoneUpdateCallback(Keystone* keystone=0):_keystone(keystone) {}
 
113
    KeystoneUpdateCallback(const KeystoneUpdateCallback&, const osg::CopyOp&) {}
 
114
 
 
115
    META_Object(osg,KeystoneUpdateCallback);
 
116
 
 
117
    /** do customized update code.*/
 
118
    virtual void update(osg::NodeVisitor*, osg::Drawable* drawable)
 
119
    {
 
120
        update(dynamic_cast<osg::Geometry*>(drawable));
 
121
    }
 
122
 
 
123
    void update(osg::Geometry* geometry)
 
124
    {
 
125
        if (!geometry) return;
 
126
 
 
127
        osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
 
128
        if (!vertices) return;
 
129
 
 
130
        osg::Vec2Array* texcoords = dynamic_cast<osg::Vec2Array*>(geometry->getTexCoordArray(0));
 
131
        if (!texcoords) return;
 
132
 
 
133
        osg::Vec3 tl, tr, br, bl;
 
134
 
 
135
        _keystone->compute3DPositions(osg::DisplaySettings::instance().get(), tl, tr, br, bl);
 
136
 
 
137
        for(unsigned int i=0; i<vertices->size(); ++i)
 
138
        {
 
139
            osg::Vec3& v = (*vertices)[i];
 
140
            osg::Vec2& t = (*texcoords)[i];
 
141
            v = bl * ((1.0f-t.x())*(1.0f-t.y())) +
 
142
                br * ((t.x())*(1.0f-t.y())) +
 
143
                tl * ((1.0f-t.x())*(t.y())) +
 
144
                tr * ((t.x())*(t.y()));
 
145
        }
 
146
        geometry->dirtyBound();
 
147
    }
 
148
 
 
149
    osg::ref_ptr<Keystone> _keystone;
 
150
};
 
151
 
 
152
 
 
153
osg::Geode* Keystone::createKeystoneDistortionMesh()
 
154
{
 
155
    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
 
156
 
 
157
    osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
 
158
    geode->addDrawable(geometry.get());
 
159
 
 
160
    geometry->setUseDisplayList(false);
 
161
 
 
162
    osg::ref_ptr<KeystoneUpdateCallback> kuc = new KeystoneUpdateCallback(this);
 
163
    geometry->setUpdateCallback(kuc.get());
 
164
 
 
165
    osg::ref_ptr<osg::Vec4Array> colours = new osg::Vec4Array;
 
166
    colours->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
 
167
    geometry->setColorArray(colours.get(), osg::Array::BIND_OVERALL);
 
168
 
 
169
    osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
 
170
    geometry->setVertexArray(vertices.get());
 
171
 
 
172
    osg::ref_ptr<osg::Vec2Array> texcoords = new osg::Vec2Array;
 
173
    geometry->setTexCoordArray(0, texcoords.get());
 
174
 
 
175
    unsigned int numRows = 7;
 
176
    unsigned int numColumns = 7;
 
177
    unsigned int numVertices = numRows*numColumns;
 
178
 
 
179
    vertices->resize(numVertices);
 
180
    texcoords->resize(numVertices);
 
181
 
 
182
    for(unsigned j=0; j<numRows; j++)
 
183
    {
 
184
        for(unsigned i=0; i<numColumns; i++)
 
185
        {
 
186
            osg::Vec2& t = (*texcoords)[j*numColumns+i];
 
187
            t.set(static_cast<float>(i)/static_cast<float>(numColumns-1), static_cast<float>(j)/static_cast<float>(numRows-1));
 
188
        }
 
189
    }
 
190
 
 
191
    osg::ref_ptr<osg::DrawElementsUShort> elements = new osg::DrawElementsUShort(GL_TRIANGLES);
 
192
    geometry->addPrimitiveSet(elements.get());
 
193
    for(unsigned j=0; j<numRows-1; j++)
 
194
    {
 
195
        for(unsigned i=0; i<numColumns-1; i++)
 
196
        {
 
197
            unsigned int vi = j*numColumns+i;
 
198
 
 
199
            elements->push_back(vi+numColumns);
 
200
            elements->push_back(vi);
 
201
            elements->push_back(vi+1);
 
202
 
 
203
            elements->push_back(vi+numColumns);
 
204
            elements->push_back(vi+1);
 
205
            elements->push_back(vi+1+numColumns);
 
206
        }
 
207
    }
 
208
 
 
209
    geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
 
210
    geometry->getOrCreateStateSet()->setRenderBinDetails(0, "RenderBin");
 
211
 
 
212
    kuc->update(geometry.get());
 
213
 
 
214
    return geode.release();
 
215
}
 
216
 
 
217
osg::Node* Keystone::createGrid()
 
218
{
 
219
    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
 
220
 
 
221
    osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
 
222
    geode->addDrawable(geometry.get());
 
223
 
 
224
    geometry->setUseDisplayList(false);
 
225
 
 
226
    osg::ref_ptr<KeystoneUpdateCallback> kuc = new KeystoneUpdateCallback(this);
 
227
    geometry->setUpdateCallback(kuc.get());
 
228
 
 
229
    geometry->setCullCallback(new KeystoneCullCallback(this));
 
230
 
 
231
    osg::ref_ptr<osg::Vec4Array> colours = new osg::Vec4Array;
 
232
    colours->push_back(getGridColor());
 
233
    geometry->setColorArray(colours.get(), osg::Array::BIND_OVERALL);
 
234
 
 
235
    osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
 
236
    geometry->setVertexArray(vertices.get());
 
237
 
 
238
    osg::ref_ptr<osg::Vec2Array> texcoords = new osg::Vec2Array;
 
239
    geometry->setTexCoordArray(0, texcoords.get());
 
240
 
 
241
    osg::Vec2 origin(0.0f, 0.0f);
 
242
    osg::Vec2 widthVector(1.0f, 0.0f);
 
243
    osg::Vec2 heightVector(0.0f, 1.0f);
 
244
 
 
245
    unsigned int numIntervals = 7;
 
246
 
 
247
    // border line
 
248
    {
 
249
        unsigned int vi = texcoords->size();
 
250
        texcoords->push_back(origin);
 
251
        texcoords->push_back(origin+widthVector);
 
252
        texcoords->push_back(origin+widthVector+heightVector);
 
253
        texcoords->push_back(origin+heightVector);
 
254
        geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINE_LOOP, vi, 4));
 
255
    }
 
256
 
 
257
    // cross lines
 
258
    {
 
259
        unsigned int vi = texcoords->size();
 
260
        osg::Vec2 v = origin;
 
261
        osg::Vec2 dv = (widthVector+heightVector)/static_cast<float>(numIntervals-1);
 
262
        for(unsigned int i=0; i<numIntervals; ++i)
 
263
        {
 
264
            texcoords->push_back(v);
 
265
            v += dv;
 
266
        }
 
267
        geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, vi, numIntervals));
 
268
 
 
269
        vi = texcoords->size();
 
270
        v = origin+heightVector;
 
271
        dv = (widthVector-heightVector)/static_cast<float>(numIntervals-1);
 
272
        for(unsigned int i=0; i<numIntervals; ++i)
 
273
        {
 
274
            texcoords->push_back(v);
 
275
            v += dv;
 
276
        }
 
277
        geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, vi, numIntervals));
 
278
    }
 
279
 
 
280
    // vertices lines
 
281
    {
 
282
        unsigned int vi = texcoords->size();
 
283
        osg::Vec2 dv = widthVector/6.0;
 
284
        osg::Vec2 bv = origin+dv;
 
285
        osg::Vec2 tv = bv+heightVector;
 
286
        for(unsigned int i=0; i<5; ++i)
 
287
        {
 
288
            texcoords->push_back(bv);
 
289
            texcoords->push_back(tv);
 
290
            bv += dv;
 
291
            tv += dv;
 
292
        }
 
293
        geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINES, vi, 10));
 
294
    }
 
295
 
 
296
    // horizontal lines
 
297
    {
 
298
        unsigned int vi = texcoords->size();
 
299
        osg::Vec2 dv = heightVector/6.0;
 
300
        osg::Vec2 bv = origin+dv;
 
301
        osg::Vec2 tv = bv+widthVector;
 
302
        for(unsigned int i=0; i<5; ++i)
 
303
        {
 
304
            texcoords->push_back(bv);
 
305
            texcoords->push_back(tv);
 
306
            bv += dv;
 
307
            tv += dv;
 
308
        }
 
309
        geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINES, vi, 10));
 
310
    }
 
311
 
 
312
    vertices->resize(texcoords->size());
 
313
 
 
314
    geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
 
315
    geometry->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
 
316
    geometry->getOrCreateStateSet()->setRenderBinDetails(1, "RenderBin");
 
317
 
 
318
    kuc->update(geometry.get());
 
319
 
 
320
    return geode.release();
 
321
}
 
322
 
 
323
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
324
//
 
325
// KeystoneHandler
 
326
//
 
327
KeystoneHandler::KeystoneHandler(Keystone* keystone):
 
328
    _keystone(keystone),
 
329
    _defaultIncrement(0.0,0.0),
 
330
    _ctrlIncrement(1.0,1.0),
 
331
    _shiftIncrement(0.1,0.1),
 
332
    _keyIncrement(0.005, 0.005),
 
333
    _selectedRegion(NONE_SELECTED)
 
334
{
 
335
    _startControlPoints = new Keystone;
 
336
    _currentControlPoints = keystone; //new Keystone;
 
337
}
 
338
 
 
339
KeystoneHandler::Region KeystoneHandler::computeRegion(const osgGA::GUIEventAdapter& ea) const
 
340
{
 
341
    float x = ea.getXnormalized();
 
342
    float y = ea.getYnormalized();
 
343
    if (x<-0.33)
 
344
    {
 
345
        // left side
 
346
        if (y<-0.33) return BOTTOM_LEFT;
 
347
        else if (y<0.33) return LEFT;
 
348
        else return TOP_LEFT;
 
349
    }
 
350
    else if (x<0.33)
 
351
    {
 
352
        // center side
 
353
        if (y<-0.33) return BOTTOM;
 
354
        else if (y<0.33) return CENTER;
 
355
        else return TOP;
 
356
    }
 
357
    else
 
358
    {
 
359
        // right side
 
360
        if (y<-0.33) return BOTTOM_RIGHT;
 
361
        else if (y<0.33) return RIGHT;
 
362
        else return TOP_RIGHT;
 
363
    }
 
364
    return NONE_SELECTED;
 
365
}
 
366
 
 
367
void KeystoneHandler::move(Region region, const osg::Vec2d& delta)
 
368
{
 
369
    switch(region)
 
370
    {
 
371
        case(TOP_LEFT):
 
372
            _currentControlPoints->getTopLeft() += delta;
 
373
            break;
 
374
        case(TOP):
 
375
            _currentControlPoints->getTopLeft() += delta;
 
376
            _currentControlPoints->getTopRight() += delta;
 
377
            break;
 
378
        case(TOP_RIGHT):
 
379
            _currentControlPoints->getTopRight() += delta;
 
380
            break;
 
381
        case(RIGHT):
 
382
            _currentControlPoints->getTopRight() += delta;
 
383
            _currentControlPoints->getBottomRight() += delta;
 
384
            break;
 
385
        case(BOTTOM_RIGHT):
 
386
            _currentControlPoints->getBottomRight() += delta;
 
387
            break;
 
388
        case(BOTTOM):
 
389
            _currentControlPoints->getBottomRight() += delta;
 
390
            _currentControlPoints->getBottomLeft() += delta;
 
391
            break;
 
392
        case(BOTTOM_LEFT):
 
393
            _currentControlPoints->getBottomLeft() += delta;
 
394
            break;
 
395
        case(LEFT):
 
396
            _currentControlPoints->getBottomLeft() += delta;
 
397
            _currentControlPoints->getTopLeft() += delta;
 
398
            break;
 
399
        case(CENTER):
 
400
            _currentControlPoints->getBottomLeft() += delta;
 
401
            _currentControlPoints->getTopLeft() += delta;
 
402
            _currentControlPoints->getBottomRight() += delta;
 
403
            _currentControlPoints->getTopRight() += delta;
 
404
            break;
 
405
        case(NONE_SELECTED):
 
406
            break;
 
407
    }
 
408
}
 
409
 
 
410
osg::Vec2d KeystoneHandler::incrementScale(const osgGA::GUIEventAdapter& ea) const
 
411
{
 
412
    if (_ctrlIncrement!=osg::Vec2d(0.0,0.0) && (ea.getModKeyMask()==osgGA::GUIEventAdapter::MODKEY_LEFT_CTRL || ea.getModKeyMask()==osgGA::GUIEventAdapter::MODKEY_RIGHT_CTRL )) return _ctrlIncrement;
 
413
    if (_shiftIncrement!=osg::Vec2d(0.0,0.0) && (ea.getModKeyMask()==osgGA::GUIEventAdapter::MODKEY_LEFT_SHIFT || ea.getModKeyMask()==osgGA::GUIEventAdapter::MODKEY_RIGHT_SHIFT )) return _shiftIncrement;
 
414
    return _defaultIncrement;
 
415
}
 
416
 
 
417
bool KeystoneHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& /*aa*/, osg::Object* obj, osg::NodeVisitor* /*nv*/)
 
418
{
 
419
    osg::Camera* camera = dynamic_cast<osg::Camera*>(obj);
 
420
    osg::Viewport* viewport = camera ?  camera->getViewport() : 0;
 
421
 
 
422
    if (!viewport) return false;
 
423
 
 
424
    if (ea.getEventType()==osgGA::GUIEventAdapter::KEYDOWN && ((ea.getModKeyMask()==osgGA::GUIEventAdapter::MODKEY_LEFT_CTRL || ea.getModKeyMask()==osgGA::GUIEventAdapter::MODKEY_RIGHT_CTRL)))
 
425
    {
 
426
        if (ea.getUnmodifiedKey()=='g')
 
427
        {
 
428
            setKeystoneEditingEnabled(!getKeystoneEditingEnabled());
 
429
            return true;
 
430
        }
 
431
        if (ea.getUnmodifiedKey()=='r')
 
432
        {
 
433
            _selectedRegion = NONE_SELECTED;
 
434
            _startControlPoints->reset();
 
435
            _currentControlPoints->reset();
 
436
            return true;
 
437
        }
 
438
        else if (ea.getUnmodifiedKey()=='s')
 
439
        {
 
440
            _keystone->writeToFile();
 
441
            return true;
 
442
        }
 
443
    }
 
444
 
 
445
    bool haveCameraMatch = false;
 
446
    float x = ea.getXnormalized();
 
447
    float y = ea.getYnormalized();
 
448
    for(unsigned int i=0; i<ea.getNumPointerData(); ++i)
 
449
    {
 
450
        const osgGA::PointerData* pd = ea.getPointerData(i);
 
451
        if (pd->object==obj)
 
452
        {
 
453
            haveCameraMatch = true;
 
454
            x = pd->getXnormalized();
 
455
            y = pd->getYnormalized();
 
456
            break;
 
457
        }
 
458
    }
 
459
 
 
460
    if (!haveCameraMatch || !getKeystoneEditingEnabled()) return false;
 
461
 
 
462
    switch(ea.getEventType())
 
463
    {
 
464
        case(osgGA::GUIEventAdapter::PUSH):
 
465
        {
 
466
            osg::Vec2d scale = incrementScale(ea);
 
467
            if (scale.length2()!=0.0)
 
468
            {
 
469
                _selectedRegion = computeRegion(ea);
 
470
                (*_startControlPoints) = (*_currentControlPoints);
 
471
                _startPosition.set(x,y);
 
472
            }
 
473
            else
 
474
            {
 
475
                _selectedRegion = NONE_SELECTED;
 
476
            }
 
477
            return false;
 
478
        }
 
479
        case(osgGA::GUIEventAdapter::DRAG):
 
480
        {
 
481
            if (_selectedRegion!=NONE_SELECTED)
 
482
            {
 
483
                (*_currentControlPoints) = (*_startControlPoints);
 
484
                osg::Vec2d currentPosition(x, y);
 
485
                osg::Vec2d delta(currentPosition-_startPosition);
 
486
                osg::Vec2d scale = incrementScale(ea);
 
487
                move(_selectedRegion, osg::Vec2d(delta.x()*scale.x(), delta.y()*scale.y()) );
 
488
                return true;
 
489
            }
 
490
            return false;
 
491
        }
 
492
        case(osgGA::GUIEventAdapter::RELEASE):
 
493
        {
 
494
            _selectedRegion = NONE_SELECTED;
 
495
            return false;
 
496
        }
 
497
        case(osgGA::GUIEventAdapter::KEYDOWN):
 
498
        {
 
499
            if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Up)
 
500
            {
 
501
                move(computeRegion(ea), osg::Vec2d(0.0, _keyIncrement.y()*incrementScale(ea).y()) );
 
502
            }
 
503
            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Down)
 
504
            {
 
505
                move(computeRegion(ea), osg::Vec2d(0.0, -_keyIncrement.y()*incrementScale(ea).y()) );
 
506
            }
 
507
            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left)
 
508
            {
 
509
                move(computeRegion(ea), osg::Vec2d(-_keyIncrement.x()*incrementScale(ea).x(), 0.0) );
 
510
            }
 
511
            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Right)
 
512
            {
 
513
                move(computeRegion(ea), osg::Vec2d(_keyIncrement.x()*incrementScale(ea).x(), 0.0) );
 
514
            }
 
515
            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_7 || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Home)
 
516
            {
 
517
                _currentControlPoints->setTopLeft(osg::Vec2d(x, y));
 
518
            }
 
519
            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_9 || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Page_Up)
 
520
            {
 
521
                _currentControlPoints->setTopRight(osg::Vec2d(x, y));
 
522
            }
 
523
            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_3 || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Page_Down)
 
524
            {
 
525
                _currentControlPoints->setBottomRight(osg::Vec2d(x, y));
 
526
            }
 
527
            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_1 || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_End)
 
528
            {
 
529
                _currentControlPoints->setBottomLeft(osg::Vec2d(x, y));
 
530
            }
 
531
            return false;
 
532
        }
 
533
        default:
 
534
            return false;
 
535
    }
 
536
}
 
537
 
 
538
bool Keystone::writeToFile()
 
539
{
 
540
    std::string filename;
 
541
    if (getUserDataContainer()!=0 && getUserValue("filename", filename))
 
542
    {
 
543
        // we don't want to write the UDC to the keystone file so take a reference to it, and set the pointer to NULL.
 
544
        osg::ref_ptr<osg::UserDataContainer> temp_udc = getUserDataContainer();
 
545
        setUserDataContainer(0);
 
546
 
 
547
        OSG_NOTICE<<"Writing keystone to: "<<filename<<std::endl;
 
548
 
 
549
        // write the keystone out to disk
 
550
        osgDB::writeObjectFile(*this, filename);
 
551
 
 
552
        // reassign the UDC
 
553
        setUserDataContainer(temp_udc.get());
 
554
 
 
555
        return true;
 
556
    }
 
557
    else
 
558
    {
 
559
        return false;
 
560
    }
 
561
}
 
562
 
 
563
 
 
564
bool Keystone::loadKeystoneFiles(osg::DisplaySettings* ds)
 
565
{
 
566
    bool keystonesLoaded = false;
 
567
    if (!ds->getKeystoneFileNames().empty())
 
568
    {
 
569
        for(osg::DisplaySettings::FileNames::iterator itr = ds->getKeystoneFileNames().begin();
 
570
            itr != ds->getKeystoneFileNames().end();
 
571
            ++itr)
 
572
        {
 
573
            const std::string& filename = *itr;
 
574
            osg::ref_ptr<osgViewer::Keystone> keystone = osgDB::readFile<osgViewer::Keystone>(filename);
 
575
            if (keystone.valid())
 
576
            {
 
577
                keystone->setUserValue("filename",filename);
 
578
                ds->getKeystones().push_back(keystone.get());
 
579
                keystonesLoaded = true;
 
580
            }
 
581
            else
 
582
            {
 
583
                OSG_NOTICE<<"Creating Keystone for filename entry: "<<filename<<std::endl;
 
584
                keystone = new Keystone;
 
585
                keystone->setUserValue("filename",filename);
 
586
                ds->getKeystones().push_back(keystone.get());
 
587
                keystonesLoaded = true;
 
588
            }
 
589
        }
 
590
    }
 
591
    return keystonesLoaded;
 
592
}
 
593