diff options
Diffstat (limited to 'eigen/demos/opengl/trackball.cpp')
-rw-r--r-- | eigen/demos/opengl/trackball.cpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/eigen/demos/opengl/trackball.cpp b/eigen/demos/opengl/trackball.cpp new file mode 100644 index 0000000..77ac790 --- /dev/null +++ b/eigen/demos/opengl/trackball.cpp @@ -0,0 +1,59 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "trackball.h" +#include "camera.h" + +using namespace Eigen; + +void Trackball::track(const Vector2i& point2D) +{ + if (mpCamera==0) + return; + Vector3f newPoint3D; + bool newPointOk = mapToSphere(point2D, newPoint3D); + + if (mLastPointOk && newPointOk) + { + Vector3f axis = mLastPoint3D.cross(newPoint3D).normalized(); + float cos_angle = mLastPoint3D.dot(newPoint3D); + if ( internal::abs(cos_angle) < 1.0 ) + { + float angle = 2. * acos(cos_angle); + if (mMode==Around) + mpCamera->rotateAroundTarget(Quaternionf(AngleAxisf(angle, axis))); + else + mpCamera->localRotate(Quaternionf(AngleAxisf(-angle, axis))); + } + } + + mLastPoint3D = newPoint3D; + mLastPointOk = newPointOk; +} + +bool Trackball::mapToSphere(const Vector2i& p2, Vector3f& v3) +{ + if ((p2.x() >= 0) && (p2.x() <= int(mpCamera->vpWidth())) && + (p2.y() >= 0) && (p2.y() <= int(mpCamera->vpHeight())) ) + { + double x = (double)(p2.x() - 0.5*mpCamera->vpWidth()) / (double)mpCamera->vpWidth(); + double y = (double)(0.5*mpCamera->vpHeight() - p2.y()) / (double)mpCamera->vpHeight(); + double sinx = sin(M_PI * x * 0.5); + double siny = sin(M_PI * y * 0.5); + double sinx2siny2 = sinx * sinx + siny * siny; + + v3.x() = sinx; + v3.y() = siny; + v3.z() = sinx2siny2 < 1.0 ? sqrt(1.0 - sinx2siny2) : 0.0; + + return true; + } + else + return false; +} |