summaryrefslogtreecommitdiffstats
path: root/examples/graphicsview/boxes/trackball.cpp
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@nokia.com>2011-06-27 12:27:54 +0200
committerJørgen Lind <jorgen.lind@nokia.com>2011-06-27 12:27:54 +0200
commit18a3f6169bb8a763366003d92b8013950578c79f (patch)
treee39fa00a9511410fea9be35a6130007e43719ad8 /examples/graphicsview/boxes/trackball.cpp
parent371d398f70e10408e0eaba7b5f05e638a0048599 (diff)
parenta06c8405d053b16327d65415f3335eceb37abd3b (diff)
Merge remote-tracking branch 'base/master' into refactor
Conflicts: demos/demos.pro demos/embedded/digiflip/digiflip.pro examples/examples.pro examples/graphicsview/embeddeddialogs/embeddeddialogs.pro src/gui/kernel/qplatformglcontext_qpa.cpp src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp src/plugins/platforms/wayland/qwaylanddisplay.cpp src/plugins/platforms/wayland/qwaylandwindow.cpp Change-Id: I2a4ec9e2ca9c9aa9d57b55f98985e810b77bb745
Diffstat (limited to 'examples/graphicsview/boxes/trackball.cpp')
-rw-r--r--examples/graphicsview/boxes/trackball.cpp160
1 files changed, 160 insertions, 0 deletions
diff --git a/examples/graphicsview/boxes/trackball.cpp b/examples/graphicsview/boxes/trackball.cpp
new file mode 100644
index 0000000000..1bb864ce90
--- /dev/null
+++ b/examples/graphicsview/boxes/trackball.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "trackball.h"
+#include "scene.h"
+
+//============================================================================//
+// TrackBall //
+//============================================================================//
+
+TrackBall::TrackBall(TrackMode mode)
+ : m_angularVelocity(0)
+ , m_paused(false)
+ , m_pressed(false)
+ , m_mode(mode)
+{
+ m_axis = QVector3D(0, 1, 0);
+ m_rotation = QQuaternion();
+ m_lastTime = QTime::currentTime();
+}
+
+TrackBall::TrackBall(float angularVelocity, const QVector3D& axis, TrackMode mode)
+ : m_axis(axis)
+ , m_angularVelocity(angularVelocity)
+ , m_paused(false)
+ , m_pressed(false)
+ , m_mode(mode)
+{
+ m_rotation = QQuaternion();
+ m_lastTime = QTime::currentTime();
+}
+
+void TrackBall::push(const QPointF& p, const QQuaternion &)
+{
+ m_rotation = rotation();
+ m_pressed = true;
+ m_lastTime = QTime::currentTime();
+ m_lastPos = p;
+ m_angularVelocity = 0.0f;
+}
+
+void TrackBall::move(const QPointF& p, const QQuaternion &transformation)
+{
+ if (!m_pressed)
+ return;
+
+ QTime currentTime = QTime::currentTime();
+ int msecs = m_lastTime.msecsTo(currentTime);
+ if (msecs <= 20)
+ return;
+
+ switch (m_mode) {
+ case Plane:
+ {
+ QLineF delta(m_lastPos, p);
+ m_angularVelocity = 180*delta.length() / (PI*msecs);
+ m_axis = QVector3D(-delta.dy(), delta.dx(), 0.0f).normalized();
+ m_axis = transformation.rotatedVector(m_axis);
+ m_rotation = QQuaternion::fromAxisAndAngle(m_axis, 180 / PI * delta.length()) * m_rotation;
+ }
+ break;
+ case Sphere:
+ {
+ QVector3D lastPos3D = QVector3D(m_lastPos.x(), m_lastPos.y(), 0.0f);
+ float sqrZ = 1 - QVector3D::dotProduct(lastPos3D, lastPos3D);
+ if (sqrZ > 0)
+ lastPos3D.setZ(sqrt(sqrZ));
+ else
+ lastPos3D.normalize();
+
+ QVector3D currentPos3D = QVector3D(p.x(), p.y(), 0.0f);
+ sqrZ = 1 - QVector3D::dotProduct(currentPos3D, currentPos3D);
+ if (sqrZ > 0)
+ currentPos3D.setZ(sqrt(sqrZ));
+ else
+ currentPos3D.normalize();
+
+ m_axis = QVector3D::crossProduct(lastPos3D, currentPos3D);
+ float angle = 180 / PI * asin(sqrt(QVector3D::dotProduct(m_axis, m_axis)));
+
+ m_angularVelocity = angle / msecs;
+ m_axis.normalize();
+ m_axis = transformation.rotatedVector(m_axis);
+ m_rotation = QQuaternion::fromAxisAndAngle(m_axis, angle) * m_rotation;
+ }
+ break;
+ }
+
+
+ m_lastPos = p;
+ m_lastTime = currentTime;
+}
+
+void TrackBall::release(const QPointF& p, const QQuaternion &transformation)
+{
+ // Calling move() caused the rotation to stop if the framerate was too low.
+ move(p, transformation);
+ m_pressed = false;
+}
+
+void TrackBall::start()
+{
+ m_lastTime = QTime::currentTime();
+ m_paused = false;
+}
+
+void TrackBall::stop()
+{
+ m_rotation = rotation();
+ m_paused = true;
+}
+
+QQuaternion TrackBall::rotation() const
+{
+ if (m_paused || m_pressed)
+ return m_rotation;
+
+ QTime currentTime = QTime::currentTime();
+ float angle = m_angularVelocity * m_lastTime.msecsTo(currentTime);
+ return QQuaternion::fromAxisAndAngle(m_axis, angle) * m_rotation;
+}
+