Trackball.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                              SOFA :: Framework                              *
00020 *                                                                             *
00021 * Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
00022 * H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
00023 * M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
00024 *                                                                             *
00025 * Contact information: contact@sofa-framework.org                             *
00026 ******************************************************************************/
00027 /*
00028  * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
00029  * ALL RIGHTS RESERVED
00030  * Permission to use, copy, modify, and distribute this software for
00031  * any purpose and without fee is hereby granted, provided that the above
00032  * copyright notice appear in all copies and that both the copyright notice
00033  * and this permission notice appear in supporting documentation, and that
00034  * the name of Silicon Graphics, Inc. not be used in advertising
00035  * or publicity pertaining to distribution of the software without specific,
00036  * written prior permission.
00037  *
00038  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
00039  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
00040  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
00041  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
00042  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
00043  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
00044  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
00045  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
00046  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
00047  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
00048  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
00049  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
00050  *
00051  * US Government Users Restricted Rights
00052  * Use, duplication, or disclosure by the Government is subject to
00053  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
00054  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
00055  * clause at DFARS 252.227-7013 and/or in similar or successor
00056  * clauses in the FAR or the DOD or NASA FAR Supplement.
00057  * Unpublished-- rights reserved under the copyright laws of the
00058  * United States.  Contractor/manufacturer is Silicon Graphics,
00059  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
00060  *
00061  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
00062  */
00063 /*
00064  * Trackball code:
00065  *
00066  * Implementation of a virtual trackball.
00067  * Implemented by Gavin Bell, lots of ideas from Thant Tessman and
00068  *   the August '88 issue of Siggraph's "Computer Graphics," pp. 121-129.
00069  *
00070  * Modified by:
00071  *     Stephane Cotin
00072  *     Mitsubish Electric America
00073  *     June 1998
00074  */
00075 
00076 #include <math.h>
00077 #include <sofa/helper/gl/Trackball.h>
00078 
00079 namespace sofa
00080 {
00081 
00082 namespace helper
00083 {
00084 
00085 namespace gl
00086 {
00087 
00088 using namespace sofa::defaulttype;
00089 
00090 /*
00091  * This size should really be based on the distance from the center of
00092  * rotation to the point on the object underneath the mouse.  That
00093  * point would then track the mouse as closely as possible.  This is a
00094  * simple example, though, so that is left as an Exercise for the
00095  * Programmer.
00096  */
00097 #define TRACKBALLSIZE  (0.8)
00098 
00099 static double   tb_project_to_sphere(double, double, double);
00100 
00101 // Constructor
00102 Trackball::Trackball()
00103 {
00104     _quat[0] = 0.0;
00105     _quat[1] = 0.0;
00106     _quat[2] = 0.0;
00107     _quat[3] = 0.0;
00108 }
00109 
00110 // Destructor
00111 Trackball::~Trackball()
00112 {
00113 }
00114 
00115 Quaternion Trackball::GetQuaternion(void)
00116 {
00117     Quaternion  Q;
00118 
00119     Q[0] = _quat[0];
00120     Q[1] = _quat[1];
00121     Q[2] = _quat[2];
00122     Q[3] = _quat[3];
00123 
00124     return Q;
00125 }
00126 
00127 void Trackball::SetQuaternion(Quaternion Q)
00128 {
00129     _quat[0] = Q[0];
00130     _quat[1] = Q[1];
00131     _quat[2] = Q[2];
00132     _quat[3] = Q[3];
00133 }
00134 
00135 /*
00136  * Ok, simulate a track-ball.  Project the points onto the virtual
00137  * trackball, then figure out the axis of rotation, which is the cross
00138  * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
00139  * Note:  This is a deformed trackball-- is a trackball in the center,
00140  * but is deformed into a hyperbolic sheet of rotation away from the
00141  * center.  This particular function was chosen after trying out
00142  * several variations.
00143  *
00144  * It is assumed that the arguments to this routine are in the range
00145  * (-1.0 ... 1.0)
00146  */
00147 
00148 void Trackball::ComputeQuaternion(double p1x, double p1y, double p2x,
00149                                   double p2y)
00150 {
00151     double  phi;        /* how much to rotate about axis */
00152     double  t;
00153 
00154     if (p1x == p2x && p1y == p2y)
00155     {
00156         /* Zero rotation */
00157         _quat[0] = _quat[1] = _quat[2] = 0.0;
00158         _quat[3] = 1.0;
00159 
00160         return;
00161     }
00162 
00163     // First, figure out z-coordinates for projection of P1 and P2 to deformed sphere
00164     Vector3 p1  ((SReal)p1x, (SReal)p1y, (SReal)tb_project_to_sphere(TRACKBALLSIZE, p1x, p1y));
00165     Vector3 p2  ((SReal)p2x, (SReal)p2y, (SReal)tb_project_to_sphere(TRACKBALLSIZE, p2x, p2y));
00166 
00167     // Now, we want the cross product of P1 and P2          
00168     Vector3 a = cross(p2,p1);
00169 
00170     // Figure out how much to rotate around that axis.
00171     Vector3 d   = p1 - p2;
00172     t = d.norm() / (2.0 * TRACKBALLSIZE);
00173 
00174     // Avoid problems with out-of-control values...
00175     if (t > 1.0)
00176     {
00177         t = 1.0;
00178     }
00179     if (t < -1.0)
00180     {
00181         t = -1.0;
00182     }
00183     phi = 2.0 * asin(t);
00184 
00185     _quat.axisToQuat(a, (SReal)phi);
00186 }
00187 
00188 
00189 // Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
00190 // if we are away from the center of the sphere.
00191 static double tb_project_to_sphere(double r, double x, double y)
00192 {
00193     double  d, t, z;
00194 
00195     d = sqrt(x * x + y * y);
00196     if (d < r * 0.70710678118654752440)
00197     {
00198         /* Inside sphere */
00199         z = sqrt(r * r - d * d);
00200     }
00201     else
00202     {
00203         /* On hyperbola */
00204         t = r / 1.41421356237309504880;
00205         z = t * t / d;
00206     }
00207     return z;
00208 }
00209 
00210 } // namespace gl
00211 
00212 } // namespace helper
00213 
00214 } // namespace sofa
00215 

Generated on Sun Nov 23 02:29:30 2008 for Sofa by  doxygen 1.5.7.1