Go to the documentation of this file.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 #include "trackball.h"
00026 #include "camera.h"
00027
00028 using namespace Eigen;
00029
00030 void Trackball::track(const Vector2i& point2D)
00031 {
00032 if (mpCamera==0)
00033 return;
00034 Vector3f newPoint3D;
00035 bool newPointOk = mapToSphere(point2D, newPoint3D);
00036
00037 if (mLastPointOk && newPointOk)
00038 {
00039 Vector3f axis = mLastPoint3D.cross(newPoint3D).normalized();
00040 float cos_angle = mLastPoint3D.dot(newPoint3D);
00041 if ( internal::abs(cos_angle) < 1.0 )
00042 {
00043 float angle = 2. * acos(cos_angle);
00044 if (mMode==Around)
00045 mpCamera->rotateAroundTarget(Quaternionf(AngleAxisf(angle, axis)));
00046 else
00047 mpCamera->localRotate(Quaternionf(AngleAxisf(-angle, axis)));
00048 }
00049 }
00050
00051 mLastPoint3D = newPoint3D;
00052 mLastPointOk = newPointOk;
00053 }
00054
00055 bool Trackball::mapToSphere(const Vector2i& p2, Vector3f& v3)
00056 {
00057 if ((p2.x() >= 0) && (p2.x() <= int(mpCamera->vpWidth())) &&
00058 (p2.y() >= 0) && (p2.y() <= int(mpCamera->vpHeight())) )
00059 {
00060 double x = (double)(p2.x() - 0.5*mpCamera->vpWidth()) / (double)mpCamera->vpWidth();
00061 double y = (double)(0.5*mpCamera->vpHeight() - p2.y()) / (double)mpCamera->vpHeight();
00062 double sinx = sin(M_PI * x * 0.5);
00063 double siny = sin(M_PI * y * 0.5);
00064 double sinx2siny2 = sinx * sinx + siny * siny;
00065
00066 v3.x() = sinx;
00067 v3.y() = siny;
00068 v3.z() = sinx2siny2 < 1.0 ? sqrt(1.0 - sinx2siny2) : 0.0;
00069
00070 return true;
00071 }
00072 else
00073 return false;
00074 }