00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <OSGConfig.h>
00040 #include <OSGBaseTypes.h>
00041 #include <OSGMatrix.h>
00042 #include <OSGMatrixUtility.h>
00043
00044 #include "OSGNodePtr.h"
00045 #include "OSGTrackballNavigator.h"
00046
00047 OSG_USING_NAMESPACE
00048
00049
00050
00051
00052
00108
00109
00110 TrackballNavigator::TrackballNavigator(Real32 rSize): _rRadius(rSize)
00111 {
00112 _finalMatrix.setIdentity();
00113 _tMatrix.setIdentity();
00114 _pFrom.setValues(0,0,0);
00115 _pAt .setValues(0,0,1);
00116 _vUp .setValues(0,1,0);
00117 _rDistance=(_pAt-_pFrom).length();
00118 }
00119
00120
00121
00122 TrackballNavigator::~TrackballNavigator()
00123 {
00124 }
00125
00126
00127
00130 Matrix &TrackballNavigator::getMatrix()
00131 {
00132 updateFinalMatrix();
00133 return _finalMatrix;
00134 }
00135
00140 Pnt3f &TrackballNavigator::getFrom()
00141 {
00142 _pFrom = (Pnt3f)_finalMatrix[3];
00143 return _pFrom;
00144 }
00145
00150 Pnt3f &TrackballNavigator::getAt()
00151 {
00152 _pAt = (Pnt3f)(_finalMatrix[3] - (_rDistance*_finalMatrix[2]));
00153 return _pAt;
00154 }
00155
00160 Vec3f &TrackballNavigator::getUp()
00161 {
00162 _vUp = (Vec3f)_finalMatrix[1];
00163 return _vUp;
00164 }
00165
00166 Real32 TrackballNavigator::getDistance()
00167 {
00168 return _rDistance;
00169 }
00170
00171
00172
00173
00176 void TrackballNavigator::setFrom(Pnt3f new_from)
00177 {
00178 set(new_from, getAt(), getUp());
00179 }
00180
00183 void TrackballNavigator::setAt(Pnt3f new_at)
00184 {
00185 set(getFrom(),new_at,getUp());
00186 }
00187
00190 void TrackballNavigator::setDistance(Real32 new_distance)
00191 {
00192 _rDistance = new_distance;
00193 updateFinalMatrix();
00194 }
00195
00198 void TrackballNavigator::setUp(Vec3f new_up)
00199 {
00200 set(getFrom(),getAt(),new_up);
00201 }
00202
00205 void TrackballNavigator::set(Pnt3f new_from, Pnt3f new_at, Vec3f new_up)
00206 {
00207 bool b = MatrixLookAt(_tMatrix, new_at, new_at+(new_at-new_from), new_up);
00208 if(!b)
00209 {
00210 _rDistance = (new_at - new_from).length();
00211 updateFinalMatrix();
00212 }
00213 else
00214 {
00215 FNOTICE(("TrackballNavigator: set(.,.,.), failed"));
00216 }
00217 }
00218
00221 void TrackballNavigator::set(Matrix new_matrix)
00222 {
00223
00224 Vec3f translation( new_matrix[3][0], new_matrix[3][1], new_matrix[3][2] );
00225 _rDistance = translation.length();
00226
00227 _pFrom = (Pnt3f) new_matrix[3];
00228 _pAt = (Pnt3f)(new_matrix[3] - (_rDistance * new_matrix[2]));
00229 _vUp = (Vec3f) new_matrix[1];
00230 set(_pFrom, _pAt, _vUp);
00231 }
00232
00233
00234
00238 void TrackballNavigator::rotate(Real32 fromX, Real32 fromY, Real32 toX, Real32 toY)
00239 {
00240 Quaternion qCurrVal;
00241
00242 Vec3f vAxis;
00243 Real32 rPhi;
00244
00245 Vec3f vP1, vP2, vDiff;
00246
00247 Real32 rTmp;
00248
00249 if(osgabs(fromX - toX) > Eps || osgabs(fromY - toY) > Eps)
00250 {
00251 vP1.setValues(fromX, fromY, projectToSphere(_rRadius, fromX, fromY));
00252 vP2.setValues(toX, toY, projectToSphere(_rRadius, toX, toY));
00253
00254 vAxis = vP2;
00255 vAxis.crossThis(vP1);
00256
00257 vDiff = vP1;
00258 vDiff -= vP2;
00259
00260 rTmp = osgClamp(-1.0f, vDiff.length() / (2.0f * _rRadius), 1.0f);
00261
00262 rPhi = 2.0f * osgasin(rTmp);
00263 qCurrVal.setValueAsAxisRad(vAxis, rPhi);
00264
00265 Matrix temp;
00266 qCurrVal.getValue(temp);
00267
00268 _tMatrix.mult(temp);
00269 }
00270 }
00271
00274 void TrackballNavigator::translateXY(Real32 distanceX, Real32 distanceY)
00275 {
00276 Matrix temp;
00277 temp.setIdentity();
00278 temp.setTranslate(distanceX,distanceY,0);
00279 _tMatrix.mult(temp);
00280 }
00281
00285 void TrackballNavigator::translateZ(Real32 distance)
00286 {
00287 _rDistance+=distance;
00288
00289
00290
00291 }
00292
00297 Real32 TrackballNavigator::projectToSphere(Real32 rRadius, Real32 rX, Real32 rY)
00298 {
00299 Real32 d, t, z;
00300
00301 d = sqrt(rX * rX + rY * rY);
00302
00303 if (d < rRadius * 0.70710678118654752440f)
00304 {
00305 z = sqrt(rRadius * rRadius - d * d);
00306 }
00307 else
00308 {
00309 t = rRadius / 1.41421356237309504880f;
00310 z = t * t / d;
00311 }
00312
00313 return z;
00314 }
00315
00319 void TrackballNavigator::updateFinalMatrix()
00320 {
00321 Matrix temp;
00322 _finalMatrix=_tMatrix;
00323 temp.setIdentity();
00324 temp.setTranslate(0,0,_rDistance);
00325
00326 _finalMatrix.mult(temp);
00327 }
00328
00329
00330
00331
00332
00333 #ifdef __sgi
00334 #pragma set woff 1174
00335 #endif
00336
00337 #ifdef OSG_LINUX_ICC
00338 #pragma warning( disable : 177 )
00339 #endif
00340
00341 namespace
00342 {
00343 static Char8 cvsid_cpp [] = "@(#)$Id: OSGTrackballNavigator.cpp,v 1.5 2002/06/26 16:43:45 istoynov Exp $";
00344 static Char8 cvsid_hpp [] = OSGTRACKBALLNAVIGATOR_HEADER_CVSID;
00345
00346
00347 static Char8 cvsid_fields_hpp[] = OSGTRACKBALLNAVIGATOR_HEADER_CVSID;
00348 }