1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud (at) inria.fr> 5 // 6 // This Source Code Form is subject to the terms of the Mozilla 7 // Public License v. 2.0. If a copy of the MPL was not distributed 8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10 #include "trackball.h" 11 #include "camera.h" 12 13 using namespace Eigen; 14 15 void Trackball::track(const Vector2i& point2D) 16 { 17 if (mpCamera==0) 18 return; 19 Vector3f newPoint3D; 20 bool newPointOk = mapToSphere(point2D, newPoint3D); 21 22 if (mLastPointOk && newPointOk) 23 { 24 Vector3f axis = mLastPoint3D.cross(newPoint3D).normalized(); 25 float cos_angle = mLastPoint3D.dot(newPoint3D); 26 if ( internal::abs(cos_angle) < 1.0 ) 27 { 28 float angle = 2. * acos(cos_angle); 29 if (mMode==Around) 30 mpCamera->rotateAroundTarget(Quaternionf(AngleAxisf(angle, axis))); 31 else 32 mpCamera->localRotate(Quaternionf(AngleAxisf(-angle, axis))); 33 } 34 } 35 36 mLastPoint3D = newPoint3D; 37 mLastPointOk = newPointOk; 38 } 39 40 bool Trackball::mapToSphere(const Vector2i& p2, Vector3f& v3) 41 { 42 if ((p2.x() >= 0) && (p2.x() <= int(mpCamera->vpWidth())) && 43 (p2.y() >= 0) && (p2.y() <= int(mpCamera->vpHeight())) ) 44 { 45 double x = (double)(p2.x() - 0.5*mpCamera->vpWidth()) / (double)mpCamera->vpWidth(); 46 double y = (double)(0.5*mpCamera->vpHeight() - p2.y()) / (double)mpCamera->vpHeight(); 47 double sinx = sin(M_PI * x * 0.5); 48 double siny = sin(M_PI * y * 0.5); 49 double sinx2siny2 = sinx * sinx + siny * siny; 50 51 v3.x() = sinx; 52 v3.y() = siny; 53 v3.z() = sinx2siny2 < 1.0 ? sqrt(1.0 - sinx2siny2) : 0.0; 54 55 return true; 56 } 57 else 58 return false; 59 } 60