# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlGraphics/TrackballManipulator.cpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.com                                               */
    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/TrackballManipulator.hpp>
    00033 #include <vlGraphics/OpenGLContext.hpp>
    00034 #include <vlGraphics/Actor.hpp>
    00035 #include <vlGraphics/SceneManager.hpp>
    00036 #include <vlGraphics/Rendering.hpp>
    00037
    00038 using namespace vl;
    00039
    00040 //-----------------------------------------------------------------------------
    00041 void TrackballManipulator::mouseDownEvent(EMouseButton btn, int x, int y)
    00042 {
    00043   if ( camera() == NULL )
    00044     return;
    00045
    00046   // if already busy ignore the event
    00047   if (mode() != NoMode)
    00048     return;
    00049
    00050   // enter new mode
    00051   if (btn == rotationButton())
    00052     mMode = RotationMode;
    00053   else
    00054   if (btn == translationButton())
    00055     mMode = TranslationMode;
    00056   else
    00057   if (btn == zoomButton())
    00058     mMode = ZoomMode;
    00059
    00060   VL_CHECK(openglContext()->renderTarget())
    00061
    00062   // set x/y relative to the viewport
    00063   x -= camera()->viewport()->x();
    00064   y -= openglContext()->renderTarget()->height() - 1 - (camera()->viewport()->y() + camera()->viewport()->height() -1);
    00065
    00066   // check that the click is in the viewport
    00067   int w = camera()->viewport()->width();
    00068   int h = camera()->viewport()->height();
    00069
    00070   if (x<0 || y<0 || x>=w || y>=h)
    00071     return;
    00072
    00073   mMouseStart.x() = x;
    00074   mMouseStart.y() = y;
    00075
    00076   if (mTransform)
    00077   {
    00078     mStartMatrix = mTransform->localMatrix();
    00079     mPivot = mStartMatrix.getT();
    00080   }
    00081   else
    00082     mStartMatrix = camera()->inverseViewMatrix();
    00083
    00084   mStartCameraPos = camera()->inverseViewMatrix().getT();
    00085   mStartPivot = mPivot;
    00086 }
    00087 //-----------------------------------------------------------------------------
    00088 void TrackballManipulator::mouseUpEvent(EMouseButton btn, int /*x*/, int /*y*/)
    00089 {
    00090   if ( camera() == NULL )
    00091     return;
    00092
    00093   // if the trackball is not doing anything ignore the event
    00094   if (mode() == NoMode)
    00095     return;
    00096
    00097   // leave the mode
    00098   if (btn == rotationButton() && mMode == RotationMode)
    00099     mMode = NoMode;
    00100   else
    00101   if (btn == translationButton() && mMode == TranslationMode)
    00102     mMode = NoMode;
    00103   else
    00104   if (btn == zoomButton() && mMode == ZoomMode)
    00105     mMode = NoMode;
    00106 }
    00107 //-----------------------------------------------------------------------------
    00108 void TrackballManipulator::mouseMoveEvent(int x, int y)
    00109 {
    00110   if ( camera() == NULL )
    00111     return;
    00112
    00113   // ignore the event if the trackball is not in any mode
    00114   if (mode() == NoMode)
    00115     return;
    00116
    00117   VL_CHECK(openglContext()->renderTarget())
    00118   // set x/y relative to the top/left cornder of the viewport
    00119   x -= camera()->viewport()->x();
    00120   y -= openglContext()->renderTarget()->height() - 1 - (camera()->viewport()->y() + camera()->viewport()->height() -1);
    00121
    00122   if (mode() == RotationMode)
    00123   {
    00124     if (mTransform)
    00125     {
    00126       mTransform->setLocalMatrix( mat4::getTranslation(mPivot) * trackballRotation(x,y) * mat4::getTranslation(-mPivot) * mStartMatrix );
    00127       mTransform->computeWorldMatrix();
    00128       mStartMatrix = mTransform->localMatrix();
    00129     }
    00130     else
    00131     {
    00132       camera()->setInverseViewMatrix( mat4::getTranslation(mPivot) * trackballRotation(x,y) * mat4::getTranslation(-mPivot) * mStartMatrix );
    00133       mStartMatrix = camera()->inverseViewMatrix();
    00134     }
    00135
    00136     mMouseStart.x() = x;
    00137     mMouseStart.y() = y;
    00138   }
    00139   else
    00140   if (mode() == ZoomMode)
    00141   {
    00142     float t = (y-mMouseStart.y()) / 200.0f;
    00143     t *= zoomSpeed();
    00144     Real distance = (mStartCameraPos - mPivot).length();
    00145     vec3 camera_pos = mStartCameraPos - camera()->inverseViewMatrix().getZ()*t*distance;
    00146     mat4 m = camera()->inverseViewMatrix();
    00147     m.setT(camera_pos);
    00148     camera()->setInverseViewMatrix(m);
    00149   }
    00150   else
    00151   if (mode() == TranslationMode)
    00152   {
    00153     float tx = (mMouseStart.x() - x)  / 400.0f;
    00154     float ty = -(mMouseStart.y() - y) / 400.0f;
    00155     tx *= translationSpeed();
    00156     ty *= translationSpeed();
    00157     Real distance = (mStartCameraPos - mPivot).length();
    00158     vec3 up    = camera()->inverseViewMatrix().getY();
    00159     vec3 right = camera()->inverseViewMatrix().getX();
    00160     mat4 m = camera()->inverseViewMatrix();
    00161     m.setT(mStartCameraPos + up*distance*ty + right*distance*tx);
    00162     camera()->setInverseViewMatrix(m);
    00163     mPivot = mStartPivot + up*distance*ty + right*distance*tx;
    00164   }
    00165
    00166   // update the view
    00167   openglContext()->update();
    00168 }
    00169 //-----------------------------------------------------------------------------
    00170 mat4 TrackballManipulator::trackballRotation(int x, int y)
    00171 {
    00172   if( x==mMouseStart.x()  && y==mMouseStart.y() )
    00173     return mat4();
    00174
    00175   VL_CHECK(camera())
    00176   vec3 a = computeVector(mMouseStart.x(), mMouseStart.y());
    00177   vec3 b = computeVector(x, y);
    00178   vec3 n = cross(a, b);
    00179   n.normalize();
    00180   a.normalize();
    00181   b.normalize();
    00182   Real dot_a_b = dot(a,b);
    00183   dot_a_b = clamp(dot_a_b,(Real)-1.0,(Real)+1.0);
    00184   Real alpha = acos(dot_a_b) * (mTransform ? 1 : -1);
    00185   alpha = alpha * rotationSpeed();
    00186   vec3 nc =  camera()->inverseViewMatrix().get3x3() * n;
    00187   if (mTransform && mTransform->parent())
    00188     nc = mTransform->parent()->getComputedWorldMatrix().getInverse() * nc;
    00189   nc.normalize();
    00190   return mat4::getRotation(alpha*(Real)dRAD_TO_DEG, nc);
    00191 }
    00192 //-----------------------------------------------------------------------------
    00193 vec3 TrackballManipulator::computeVector(int x, int y)
    00194 {
    00195   vec3 c(camera()->viewport()->width() / 2.0f, camera()->viewport()->height() / 2.0f, 0);
    00196
    00197   float sphere_x = camera()->viewport()->width()  * 0.5f;
    00198   float sphere_y = camera()->viewport()->height() * 0.5f;
    00199
    00200   VL_CHECK(camera())
    00201   vec3 v((Real)x,(Real)y,0);
    00202   v -= c;
    00203   v.x() /= sphere_x;
    00204   v.y() /= sphere_y;
    00205   v.y() = -v.y();
    00206   //if (v.length() > 1.0f)
    00207   //  v.normalize();
    00208
    00209   Real z2 = 1.0f - v.x()*v.x() - v.y()*v.y();
    00210   if (z2 < 0)
    00211     z2 = 0;
    00212   v.z() = sqrt( z2 );
    00213   v.normalize();
    00214   return v;
    00215 }
    00216 //-----------------------------------------------------------------------------
    00217 void TrackballManipulator::adjustView(const AABB& aabb, const vec3& dir, const vec3& up, Real bias)
    00218 {
    00219   VL_CHECK(camera())
    00220   /*setTransform(NULL);*/
    00221   setPivot( aabb.center() );
    00222   camera()->adjustView(aabb, dir, up, bias);
    00223 }
    00224 //-----------------------------------------------------------------------------
    00225 void TrackballManipulator::adjustView(ActorCollection& actors, const vec3& dir, const vec3& up, Real bias)
    00226 {
    00227   AABB aabb;
    00228   for(int i=0; i<actors.size(); ++i)
    00229   {
    00230     if (actors.at(i)->transform())
    00231       actors.at(i)->transform()->computeWorldMatrix();
    00232     actors.at(i)->computeBounds();
    00233     aabb += actors.at(i)->boundingBox();
    00234   }
    00235   adjustView(aabb, dir, up, bias);
    00236 }
    00237 //-----------------------------------------------------------------------------
    00238 void TrackballManipulator::adjustView(SceneManager* scene, const vec3& dir, const vec3& up, Real bias)
    00239 {
    00240   ActorCollection actors;
    00241   scene->extractActors(actors);
    00242   adjustView(actors, dir, up, bias);
    00243 }
    00244 //-----------------------------------------------------------------------------
    00245 void TrackballManipulator::adjustView(Rendering* rendering, const vec3& dir, const vec3& up, Real bias)
    00246 {
    00247   ActorCollection actors;
    00248   for(int i=0; i<rendering->sceneManagers()->size(); ++i)
    00249     rendering->sceneManagers()->at(i)->extractActors(actors);
    00250   adjustView(actors, dir, up, bias);
    00251 }
    00252 //-----------------------------------------------------------------------------
    00253 void TrackballManipulator::enableEvent(bool enabled)
    00254 {
    00255   if (enabled)
    00256   {
    00257     mMode = NoMode;
    00258     if ( openglContext() )
    00259     {
    00260       openglContext()->setMouseVisible(true);
    00261       openglContext()->setContinuousUpdate(false);
    00262     }
    00263   }
    00264 }
    00265 //-----------------------------------------------------------------------------

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:25.
Permission is granted to use this page to write and publish articles regarding Visualization Library.