diff --git a/examples/osgkeystone/osgkeystone.cpp b/examples/osgkeystone/osgkeystone.cpp index 374b12bac..bf10beb93 100644 --- a/examples/osgkeystone/osgkeystone.cpp +++ b/examples/osgkeystone/osgkeystone.cpp @@ -24,6 +24,279 @@ #include +class ControlPoints : public osg::Referenced +{ +public: + ControlPoints(): + bottom_left(-1.0,-1.0), + bottom_right(1.0,-1.0), + top_left(-1.0,1.0), + top_right(1.0,1.0) {} + + void reset() + { + bottom_left.set(-1.0,-1.0); + bottom_right.set(1.0,-1.0); + top_left.set(-1.0,1.0); + top_right.set(1.0,1.0); + } + + ControlPoints& operator = (const ControlPoints& rhs) + { + if (&rhs==this) return *this; + bottom_left = rhs.bottom_left; + bottom_right = rhs.bottom_right; + top_left = rhs.top_left; + top_right = rhs.top_right; + return *this; + } + + osg::Vec2d bottom_left; + osg::Vec2d bottom_right; + osg::Vec2d top_left; + osg::Vec2d top_right; +}; + +class Keystone : public osg::Referenced +{ +public: + Keystone(): + translate(0.0,0.0), + scale(1.0,1.0), + taper(1.0,1.0), + angle(0.0) + { + } + + void updateKeystone(ControlPoints cp) + { + // compute translation + translate = (cp.bottom_left+cp.bottom_right+cp.top_left+cp.top_right)*0.25; + + // adjust control points to fit translation + cp.top_left += translate; + cp.top_right += translate; + cp.bottom_right += translate; + cp.bottom_left += translate; + + // compute scaling + scale.x() = ( (cp.top_right.x()-cp.top_left.x()) + (cp.bottom_right.x()-cp.bottom_left.x()) )/4.0; + scale.y() = ( (cp.top_right.y()-cp.bottom_right.y()) + (cp.top_left.y()-cp.bottom_left.y()) )/4.0; + + // adjust control points to fit scaling + cp.top_left.x() *= scale.x(); + cp.top_right.x() *= scale.x(); + cp.bottom_right.x() *= scale.x(); + cp.bottom_left.x() *= scale.x(); + cp.top_left.y() *= scale.y(); + cp.top_right.y() *= scale.y(); + cp.bottom_right.y() *= scale.y(); + cp.bottom_left.y() *= scale.y(); + + //angle = atan2(-cp.bottom_left.x(),(-cp.bottom_left.y()) + //taper.x() = (cp.top_left-cp.bottom_left).length() / (cp.top_right-cp.bottom_right).length(); + //taper.y() = (cp.top_right-cp.top_left).length() / (cp.bottom_right-cp.bottom_left).length(); + OSG_NOTICE<<"translate="<top_left += delta; + break; + case(TOP): + _currentControlPoints->top_left += delta; + _currentControlPoints->top_right += delta; + break; + case(TOP_RIGHT): + _currentControlPoints->top_right += delta; + break; + case(RIGHT): + _currentControlPoints->top_right += delta; + _currentControlPoints->bottom_right += delta; + break; + case(BOTTOM_RIGHT): + _currentControlPoints->bottom_right += delta; + break; + case(BOTTOM): + _currentControlPoints->bottom_right += delta; + _currentControlPoints->bottom_left += delta; + break; + case(BOTTOM_LEFT): + _currentControlPoints->bottom_left += delta; + break; + case(LEFT): + _currentControlPoints->bottom_left += delta; + _currentControlPoints->top_left += delta; + break; + case(CENTER): + _currentControlPoints->bottom_left += delta; + _currentControlPoints->top_left += delta; + _currentControlPoints->bottom_right += delta; + _currentControlPoints->top_right += delta; + break; + case(NONE_SELECTED): + break; + } + _keystone->updateKeystone(*_currentControlPoints); + return true; + } + + return false; + } + case(osgGA::GUIEventAdapter::RELEASE): + { + OSG_NOTICE<<"Mouse released "<reset(); + _currentControlPoints->reset(); + _keystone->updateKeystone(*_currentControlPoints); + } + return false; + } + default: + return false; + } +} + int main( int argc, char **argv ) { @@ -32,16 +305,21 @@ int main( int argc, char **argv ) // initialize the viewer. osgViewer::Viewer viewer(arguments); - osg::Vec2d translate(0.0,0.0); - osg::Vec2d scale(1.0,1.0); - osg::Vec2d taper(1.0,1.0); - double angle = 0; // osg::inDegrees(45.0); + osg::ref_ptr keystone = new Keystone; - if (arguments.read("-a",angle)) { OSG_NOTICE<<"angle = "<taper.x() = (2.0 + (width/distance) * sin(osg::inDegrees(view_angle))) / (2.0 - (width/distance) * sin(osg::inDegrees(view_angle))); + //scale.x() = 1.0/cos(osg::inDegrees(view_angle)); + OSG_NOTICE<<"scale "<scale<taper<angle)) { OSG_NOTICE<<"angle = "<angle<angle = osg::inDegrees(keystone->angle); } + if (arguments.read("-t",keystone->translate.x(), keystone->translate.y())) { OSG_NOTICE<<"translate = "<translate<scale.x(), keystone->scale.y())) { OSG_NOTICE<<"scale = "<scale<taper.x(), keystone->taper.y())) { OSG_NOTICE<<"taper = "<taper< model = osgDB::readNodeFiles(arguments); @@ -60,22 +338,21 @@ int main( int argc, char **argv ) viewer.getCamera()->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR); - osg::Matrixd& pm = viewer.getCamera()->getProjectionMatrix(); + osg::Matrixd original_pm = viewer.getCamera()->getProjectionMatrix(); - pm.postMultRotate(osg::Quat(angle, osg::Vec3d(0.0,0.0,1.0))); - pm.postMultScale(osg::Vec3d(scale.x(),scale.y(),1.0)); - pm.postMultTranslate(osg::Vec3d(translate.x(),translate.y(),0.0)); + viewer.addEventHandler(new KeystoneHandler(keystone)); - if (taper.x()!=1.0) + while(!viewer.done()) { - double x0 = (1.0+taper.x())/(1-taper.x()); - OSG_NOTICE<<"x0 = "<setProjectionMatrix(original_pm * keystone->computeKeystoneMatrix()); + } + viewer.renderingTraversals(); } - - return viewer.run(); + return 0; }