Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlGraphics/FlatManipulator.cpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #include <vlGraphics/FlatManipulator.hpp>
00033 #include <vlGraphics/OpenGLContext.hpp>
00034 
00035 using namespace vl;
00036 
00037 FlatManipulator::FlatManipulator(): mMode(NoMode),
00038       mTranslationButton(MiddleButton), mZoomButton(RightButton),
00039       mZoomSpeed(1.0f)
00040     {
00041       VL_DEBUG_SET_OBJECT_NAME()
00042     }
00043 
00044 //-----------------------------------------------------------------------------
00045 void FlatManipulator::setCamera(Camera* camera)
00046 {
00047     mCamera = camera;
00048 }
00049 //-----------------------------------------------------------------------------
00050 void FlatManipulator::mouseDownEvent(EMouseButton btn, int x, int y)
00051 {
00052     if ( camera() == NULL )
00053         return;
00054 
00055     // if already busy ignore the event, wadda heck!
00056     if (mode() != NoMode)
00057         return;
00058 
00059     //if the rodent is out of cage, kisses and bye-bye
00060     int vx, vy;
00061     if(mouseInViewport(x, y, vx, vy) == false)
00062         return;
00063     //store the rodent's position in the cage
00064     mMouseStart = vec2(x,y);
00065 
00066     // enter new mode
00067     if (btn == translationButton())
00068     {//we need world pixel size only in translation mode
00069         mMode = TranslationMode;
00070         //now let's find the pixel size, assuming an orthographic projection
00071         mPixelSize.x() = 2.0/camera()->projectionMatrix().e(0,0)/
00072                             camera()->viewport()->width();
00073         mPixelSize.y() =  2.0/camera()->projectionMatrix().e(1,1)/
00074                             camera()->viewport()->height();
00075     }
00076     else
00077     if (btn == zoomButton())
00078     {
00079         mMode = ZoomMode;
00080     }
00081 
00082     VL_CHECK(openglContext()->framebuffer())
00083 
00084 }
00085 //-----------------------------------------------------------------------------
00086 void FlatManipulator::mouseMoveEvent(int x, int y)
00087 {
00088     if ( camera() == NULL )
00089         return;
00090 
00091     // ignore the event if the manipulator is not in any mode
00092     if (mode() == NoMode)
00093         return;
00094 
00095     VL_CHECK(openglContext()->framebuffer())
00096 
00097     if (mode() == ZoomMode)
00098     {
00099         float scale = 1.0-(y - mMouseStart.y())*zoomSpeed()/100.0;
00100         camera()->setViewMatrix(
00101                         mat4::getScaling(scale, scale,1.0)*
00102                         camera()->viewMatrix());
00103         mMouseStart = vec2(x,y);
00104     }
00105     else
00106     if (mode() == TranslationMode)
00107     {
00108         vec2 shift = (vec2(x,y) - mMouseStart)*mPixelSize;
00109         camera()->setViewMatrix(
00110                     mat4::getTranslation(shift.x(), -shift.y(),0)*
00111                     camera()->viewMatrix());
00112         mMouseStart = vec2(x,y);
00113     }
00114 
00115     // update the view
00116     openglContext()->update();
00117 }
00118 //-----------------------------------------------------------------------------
00119 void FlatManipulator::mouseUpEvent(EMouseButton btn, int /*x*/, int /*y*/)
00120 {
00121   if ( camera() == NULL )
00122     return;
00123 
00124   // if the manipulator is not doing anything ignore the event
00125   if (mode() == NoMode)
00126     return;
00127 
00128   // leave the mode
00129   if (btn == translationButton() && mMode == TranslationMode)
00130     mMode = NoMode;
00131   else
00132   if (btn == zoomButton() && mMode == ZoomMode)
00133     mMode = NoMode;
00134 }
00135 //-----------------------------------------------------------------------------
00136 void FlatManipulator::enableEvent(bool enabled)
00137 {
00138   if (enabled)
00139   {
00140     mMode = NoMode;
00141     if ( openglContext() )
00142     {
00143       openglContext()->setMouseVisible(true);
00144       openglContext()->setContinuousUpdate(false);
00145     }
00146   }
00147 }
00148 //-----------------------------------------------------------------------------
00149 bool FlatManipulator::mouseInViewport(int mx, int my, int& vx, int& vy)
00150 {
00151     vx = mx - camera()->viewport()->x();
00152     vy = openglContext()->height() - my - camera()->viewport()->y();
00153 
00154     //if outside camera's viewport, return false
00155     if (vx<0 || vy<0 ||
00156       vx >= camera()->viewport()->width() ||
00157       vy >= camera()->viewport()->height())
00158     {
00159         return false;
00160     }
00161     return true;
00162 }
00163 //-----------------------------------------------------------------------------
00164 vl::ref<vl::Geometry> makeScales(bool X, bool Y, bool Z, int numArmTicks, float mmStep, float mmTickSize)
00165 {
00166     vl::ref<vl::Geometry> scales = new vl::Geometry();
00167     int numRulers = (X?1:0)+(Y?1:0)+(Z?1:0);
00168     if(numRulers == 0) return scales;
00169 
00170     vl::ref<vl::ArrayFloat3>    points(new vl::ArrayFloat3());
00171     vl::ref<vl::ArrayFloat3>    scalesPoints(new vl::ArrayFloat3());
00172 
00173     //the length of one arm of scales
00174     const float mmArmLength = numArmTicks*mmStep;
00175 
00176     //calculate the number of points, having marks at every 10 mm
00177     int     numAxisPoints   = ( 2*numArmTicks + 1)*2;
00178 
00179     //resize the array to accomodate a ruler
00180     points->resize(numAxisPoints);
00181     //room for up to three orthogonal rulers
00182     scalesPoints->resize(numRulers*points->size());
00183 
00184     float xpos = mmStep;
00185     int t;
00186     //generate the X ruler
00187     for(t = 0; t < numArmTicks; t++)
00188     {
00189         float height = mmTickSize;
00190 
00191         if((t+1)%10 == 0)//takes priority over '5'
00192             height *= 2;
00193         else
00194         if((t+1)%5 == 0)
00195             height *= 1.5;
00196 
00197         points->at(4*t)     = vl::fvec3(-xpos, -height,0);
00198         points->at(4*t+1)   = vl::fvec3(-xpos, +height,0);
00199         points->at(4*t+2)   = vl::fvec3(xpos, -height,0);
00200         points->at(4*t+3)   = vl::fvec3(xpos, +height,0);
00201 
00202         xpos += mmStep;
00203     }
00204     //now add the axis line
00205     points->at(4*t)     = vl::fvec3(-mmArmLength, 0.0,0);
00206     points->at(4*t+1)   = vl::fvec3(mmArmLength, 0.0,0);
00207 
00208     int i=0;
00209 
00210     if(X)//transfer the X ruler into the main array
00211     {
00212         for(size_t p=0; p < points->size(); i++, p++)
00213         {
00214             scalesPoints->at(i) = points->at(p);
00215         }
00216     }
00217     if(Y)//transfer the Y ruler into the main array
00218     {
00219         //rotate the generic ruler around Z axis to create the Y ruler
00220         points->transform(vl::fmat4::getRotation(90, 0, 0, 1));
00221 
00222         //copy the Y ruler into the scales array
00223         for(size_t p=0; p < points->size(); i++, p++)
00224         {
00225             scalesPoints->at(i) = points->at(p);
00226         }
00227     }
00228     if(Z)//transfer the Z ruler into the main array
00229     {
00230         //rotate the ruler based on the last rotation
00231         vl::fvec3 rotaxis = Y ? vl::fvec3(1,0,0) : vl::fvec3(0,1,0);
00232         points->transform(vl::fmat4::getRotation(90,rotaxis));
00233 
00234         //copy the Y ruler into the scales array
00235         for(size_t p=0; p < points->size(); i++, p++)
00236         {
00237             scalesPoints->at(i) = points->at(p);
00238         }
00239     }
00240     scales->setVertexArray(scalesPoints.get());
00241     //every consecutive pair of points make a line
00242     scales->drawCalls()->push_back( new vl::DrawArrays( vl::PT_LINES, 0, numRulers*points->size() ) );
00243     return scales;
00244 }

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:36.
Permission is granted to use this page to write and publish articles regarding Visualization Library.