00001 /*========================================================================= 00002 00003 Program: 3DMed 00004 Date: $Date: 2014-02-25 18:30:00 +0800 $ 00005 Version: $Version: 4.6.0 $ 00006 Copyright: MIPG, Institute of Automation, Chinese Academy of Sciences 00007 00008 =========================================================================*/ 00009 00010 00011 #ifndef __mitkTrackBall_h 00012 #define __mitkTrackBall_h 00013 00014 #include "mitkMatrix.h" 00015 #include "mitkQuaternion.h" 00016 #include "mitkVisualizationIncludes.h" 00017 00018 const unsigned int RENORMCOUNT = 97; 00019 00025 class MITK_VISUALIZATION_API mitkTrackBall 00026 { 00027 public: 00028 mitkTrackBall(); 00029 ~mitkTrackBall(); 00030 00031 void Start(float x, float y); 00032 void Update(float x, float y); 00033 void BuildRotMatrix(mitkMatrix &mat); 00034 const mitkQuaternion& GetCurrentQuat() { return m_CurQuat; } 00035 const mitkQuaternion& GetUpdateQuat() { return m_LastQuat; } 00036 00037 00038 protected: 00039 00040 private: 00041 // void _vZero(mitkVector &vec); 00042 // void _normalizeQuat(mitkVector &quat); 00043 float _projectToSphere(float r, float x, float y); 00044 // void _addQuats(mitkVector &q1, mitkVector &q2, mitkVector &dest); 00045 // void _axisToQuat(mitkVector &a, float phi, mitkVector &q); 00046 00047 static float m_BallSize; 00048 static unsigned int m_Count; 00049 00050 mitkQuaternion m_CurQuat; 00051 mitkQuaternion m_LastQuat; 00052 float m_LastX; 00053 float m_LastY; 00054 }; 00055 00056 //inline void mitkTrackBall::_vZero(mitkVector &vec) 00057 //{ 00058 // vec.ele[0] = 0.0f; 00059 // vec.ele[1] = 0.0f; 00060 // vec.ele[2] = 0.0f; 00061 //} 00062 00063 //inline void mitkTrackBall::_normalizeQuat(mitkVector &quat) 00064 //{ 00065 // float *q = quat; 00066 // float t = 1.0f / (q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]); 00067 // 00068 // q[0] *= t; 00069 // q[1] *= t; 00070 // q[2] *= t; 00071 // q[3] *= t; 00072 //} 00073 00074 inline float mitkTrackBall::_projectToSphere(float r, float x, float y) 00075 { 00076 float d, z; 00077 00078 d = x*x + y*y; 00079 if (d < r * r * 0.5f) // d < r / sqrt(2) --> inside sphere 00080 { 00081 z = sqrtf(r*r - d); 00082 } 00083 else // On hyperbola 00084 { 00085 z = 0.5f * r * r / sqrtf(d); 00086 } 00087 00088 return z; 00089 } 00090 00091 //inline void mitkTrackBall::_axisToQuat(mitkVector &a, float phi, mitkVector &q) 00092 //{ 00093 // a.Normalize(); 00094 // q = a; 00095 // q *= sinf(phi*0.5f); 00096 // q.ele[3] = cosf(phi*0.5f); 00097 //} 00098 00099 //inline void mitkTrackBall::_addQuats(mitkVector &q1, mitkVector &q2, mitkVector &dest) 00100 //{ 00101 // mitkVector t1(q1), t2(q2), t3 ,tf; 00102 // 00103 // t1 *= q2.ele[3]; 00104 // t2 *= q1.ele[3]; 00105 // t3 = q2 % q1; //cross 00106 // tf = t1 + t2 + t3; 00107 // tf.ele[3] = q1.ele[3] * q2.ele[3] - q1 * q2; 00108 // 00109 // dest = tf; 00110 // 00111 // if (++m_Count > RENORMCOUNT) 00112 // { 00113 // m_Count = 0; 00114 // this->_normalizeQuat(dest); 00115 // } 00116 //} 00117 00118 inline void mitkTrackBall::Start(float x, float y) 00119 { 00120 m_LastX = x; 00121 m_LastY = y; 00122 //this->_vZero(m_LastQuat); 00123 00124 //m_LastQuat.ele[3] = 1.0f; 00125 00126 m_LastQuat.Identity(); 00127 } 00128 00129 inline void mitkTrackBall::Update(float x, float y) 00130 { 00131 mitkVector a; /* Axis of rotation */ 00132 mitkVector p1, p2, d; 00133 float phi; /* how much to rotate about axis */ 00134 float t; 00135 00136 // Might just be able to return here. 00137 if (m_LastX == x && m_LastY == y) 00138 { 00139 /* Zero rotation */ 00140 //this->_vZero(m_LastQuat); 00141 //m_LastQuat[3] = 1.0; 00142 m_LastQuat.Identity(); 00143 return; 00144 } 00145 00146 /* 00147 * First, figure out z-coordinates for projection of P1 and P2 to 00148 * deformed sphere 00149 */ 00150 p1.ele[0] = m_LastX; 00151 p1.ele[1] = m_LastY; 00152 p1.ele[2] = this->_projectToSphere(m_BallSize, m_LastX, m_LastY); 00153 00154 p2.ele[0] = x; 00155 p2.ele[1] = y; 00156 p2.ele[2] = this->_projectToSphere(m_BallSize, x, y); 00157 00158 /* 00159 * Now, we want the cross product of P1 and P2 00160 */ 00161 a = p1 % p2; 00162 00163 /* 00164 * Figure out how much to rotate around that axis. 00165 */ 00166 d = p1 - p2; 00167 t = d.Length() / (2.0f * m_BallSize); 00168 00169 /* 00170 * Avoid problems with out-of-control values... 00171 */ 00172 if (t > 1.0f) t = 1.0f; 00173 if (t < -1.0f) t = -1.0f; 00174 phi = 2.0f * asinf(t); 00175 00176 //this->_axisToQuat(a, phi, m_LastQuat); 00177 m_LastQuat.AxisRadToQuat(a[0], a[1], a[2], phi); 00178 // this->_axisToQuat(a, phi, m_CurQuat); 00179 00180 m_LastX = x; 00181 m_LastY = y; 00182 00183 m_CurQuat = m_LastQuat * m_CurQuat; 00184 00185 if (++m_Count > RENORMCOUNT) 00186 { 00187 m_Count = 0; 00188 m_CurQuat.Normalize(); 00189 } 00190 00191 // this->_addQuats(m_LastQuat, m_CurQuat, m_CurQuat); 00192 } 00193 00194 inline void mitkTrackBall::BuildRotMatrix(mitkMatrix &mat) 00195 { 00196 // float *m = mat; 00197 00198 m_CurQuat.BuildMatrix(mat); 00199 00200 /* 00201 m[0] = 1.0f - 2.0f * (m_CurQuat[1] * m_CurQuat[1] + m_CurQuat[2] * m_CurQuat[2]); 00202 m[1] = 2.0f * (m_CurQuat[0] * m_CurQuat[1] + m_CurQuat[2] * m_CurQuat[3]); 00203 m[2] = 2.0f * (m_CurQuat[2] * m_CurQuat[0] - m_CurQuat[1] * m_CurQuat[3]); 00204 m[3] = 0.0f; 00205 00206 m[4] = 2.0f * (m_CurQuat[0] * m_CurQuat[1] - m_CurQuat[2] * m_CurQuat[3]); 00207 m[5] = 1.0f - 2.0f * (m_CurQuat[2] * m_CurQuat[2] + m_CurQuat[0] * m_CurQuat[0]); 00208 m[6] = 2.0f * (m_CurQuat[1] * m_CurQuat[2] + m_CurQuat[0] * m_CurQuat[3]); 00209 m[7] = 0.0f; 00210 00211 m[8] = 2.0f * (m_CurQuat[2] * m_CurQuat[0] + m_CurQuat[1] * m_CurQuat[3]); 00212 m[9] = 2.0f * (m_CurQuat[1] * m_CurQuat[2] - m_CurQuat[0] * m_CurQuat[3]); 00213 m[10] = 1.0f - 2.0f * (m_CurQuat[0] * m_CurQuat[0] + m_CurQuat[1] * m_CurQuat[1]); 00214 m[11] = 0.0f; 00215 00216 m[12] = 0.0f; 00217 m[13] = 0.0f; 00218 m[14] = 0.0f; 00219 m[15] = 1.0f; 00220 */ 00221 00222 00223 /* 00224 m[0] = 1.0f - 2.0f * (m_CurQuat[1] * m_CurQuat[1] + m_CurQuat[2] * m_CurQuat[2]); 00225 m[1] = 2.0f * (m_CurQuat[0] * m_CurQuat[1] - m_CurQuat[2] * m_CurQuat[3]); 00226 m[2] = 2.0f * (m_CurQuat[2] * m_CurQuat[0] + m_CurQuat[1] * m_CurQuat[3]); 00227 m[3] = 0.0f; 00228 00229 m[4] = 2.0f * (m_CurQuat[0] * m_CurQuat[1] + m_CurQuat[2] * m_CurQuat[3]); 00230 m[5] = 1.0f - 2.0f * (m_CurQuat[2] * m_CurQuat[2] + m_CurQuat[0] * m_CurQuat[0]); 00231 m[6] = 2.0f * (m_CurQuat[1] * m_CurQuat[2] - m_CurQuat[0] * m_CurQuat[3]); 00232 m[7] = 0.0f; 00233 00234 m[8] = 2.0f * (m_CurQuat[2] * m_CurQuat[0] - m_CurQuat[1] * m_CurQuat[3]); 00235 m[9] = 2.0f * (m_CurQuat[1] * m_CurQuat[2] + m_CurQuat[0] * m_CurQuat[3]); 00236 m[10] = 1.0f - 2.0f * (m_CurQuat[0] * m_CurQuat[0] + m_CurQuat[1] * m_CurQuat[1]); 00237 m[11] = 0.0f; 00238 00239 m[12] = 0.0f; 00240 m[13] = 0.0f; 00241 m[14] = 0.0f; 00242 m[15] = 1.0f; */ 00243 00244 00245 00246 /* 00247 m[0] = 1.0f - 2.0f * (m_CurQuat[1] * m_CurQuat[1] + m_CurQuat[2] * m_CurQuat[2]); 00248 m[1] = 2.0f * (m_CurQuat[0] * m_CurQuat[1] - m_CurQuat[2] * m_CurQuat[3]); 00249 m[2] = 2.0f * (m_CurQuat[2] * m_CurQuat[0] + m_CurQuat[1] * m_CurQuat[3]); 00250 m[3] = 0.0f; 00251 00252 m[4] = 2.0f * (m_CurQuat[0] * m_CurQuat[1] + m_CurQuat[2] * m_CurQuat[3]); 00253 m[5] = 1.0f - 2.0f * (m_CurQuat[2] * m_CurQuat[2] + m_CurQuat[0] * m_CurQuat[0]); 00254 m[6] = 2.0f * (m_CurQuat[1] * m_CurQuat[2] - m_CurQuat[0] * m_CurQuat[3]); 00255 m[7] = 0.0f; 00256 00257 m[8] = 2.0f * (m_CurQuat[2] * m_CurQuat[0] - m_CurQuat[1] * m_CurQuat[3]); 00258 m[9] = 2.0f * (m_CurQuat[1] * m_CurQuat[2] + m_CurQuat[0] * m_CurQuat[3]); 00259 m[10] = 1.0f - 2.0f * (m_CurQuat[1] * m_CurQuat[1] + m_CurQuat[0] * m_CurQuat[0]); 00260 m[11] = 0.0f; 00261 00262 m[12] = 0.0f; 00263 m[13] = 0.0f; 00264 m[14] = 0.0f; 00265 m[15] = 1.0f; 00266 */ 00267 } 00268 00269 /* 00270 * (c) Copyright 1993, 1994, Silicon Graphics, Inc. 00271 * ALL RIGHTS RESERVED 00272 * Permission to use, copy, modify, and distribute this software for 00273 * any purpose and without fee is hereby granted, provided that the above 00274 * copyright notice appear in all copies and that both the copyright notice 00275 * and this permission notice appear in supporting documentation, and that 00276 * the name of Silicon Graphics, Inc. not be used in advertising 00277 * or publicity pertaining to distribution of the software without specific, 00278 * written prior permission. 00279 * 00280 * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" 00281 * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, 00282 * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR 00283 * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 00284 * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, 00285 * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY 00286 * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, 00287 * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF 00288 * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN 00289 * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON 00290 * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE 00291 * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. 00292 * 00293 * US Government Users Restricted Rights 00294 * Use, duplication, or disclosure by the Government is subject to 00295 * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph 00296 * (c)(1)(ii) of the Rights in Technical Data and Computer Software 00297 * clause at DFARS 252.227-7013 and/or in similar or successor 00298 * clauses in the FAR or the DOD or NASA FAR Supplement. 00299 * Unpublished-- rights reserved under the copyright laws of the 00300 * United States. Contractor/manufacturer is Silicon Graphics, 00301 * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. 00302 * 00303 * OpenGL(TM) is a trademark of Silicon Graphics, Inc. 00304 */ 00305 00306 #endif 00307 00308