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
1.5.7.1