summaryrefslogtreecommitdiffstats
path: root/demos/qt3d/photobrowser3d/pancontroller.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'demos/qt3d/photobrowser3d/pancontroller.cpp')
-rw-r--r--demos/qt3d/photobrowser3d/pancontroller.cpp244
1 files changed, 244 insertions, 0 deletions
diff --git a/demos/qt3d/photobrowser3d/pancontroller.cpp b/demos/qt3d/photobrowser3d/pancontroller.cpp
new file mode 100644
index 000000000..e45b4abeb
--- /dev/null
+++ b/demos/qt3d/photobrowser3d/pancontroller.cpp
@@ -0,0 +1,244 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "pancontroller.h"
+#include "qglview.h"
+#include "qglcamera.h"
+#include "photobrowser3dview.h"
+
+#include <qmath.h>
+
+#include <QtGlobal>
+#include <QTime>
+
+class PanControllerPrivate
+{
+public:
+ PanControllerPrivate()
+ : speed(0.0f)
+ , angle(0.0f)
+ , arrowDirection(Qt::NoArrow)
+ , view(0)
+ , maxSpeed(4.0f)
+ , defaultDistance(0.0f)
+ , panDistance(0.0f)
+ , panViewAngle(M_PI / 4.0f) // 45 degrees in radians
+ , animating(false)
+ , elapsed(0.0f)
+ {
+ panTime.start();
+ }
+
+ void calculateValues();
+
+ qreal speed;
+ qreal angle;
+ Qt::ArrowType arrowDirection;
+ QGLView *view;
+ QTime panTime;
+ qreal maxSpeed;
+ qreal defaultDistance;
+ qreal panDistance;
+ qreal panViewAngle;
+ bool animating;
+ qreal elapsed;
+};
+
+PanController::PanController(QObject *parent)
+ : QObject(parent)
+ , d(new PanControllerPrivate)
+{
+ QGLView *v = qobject_cast<QGLView*>(parent);
+ if (v)
+ d->view = v;
+}
+
+PanController::~PanController()
+{
+ delete d;
+}
+
+qreal PanController::defaultDistance() const
+{
+ return d->defaultDistance;
+}
+
+void PanController::setDefaultDistance(qreal dist)
+{
+ d->defaultDistance = dist;
+}
+
+qreal PanController::panDistance() const
+{
+ return d->panDistance;
+}
+
+void PanController::setPanDistance(qreal dist)
+{
+ d->panDistance = dist;
+}
+
+qreal PanController::panViewAngle() const
+{
+ return d->panViewAngle;
+}
+
+void PanController::setPanViewAngle(qreal angle)
+{
+ d->panViewAngle = angle;
+}
+
+void PanController::setMaxSpeed(qreal maxSpeed)
+{
+ d->maxSpeed = maxSpeed;
+}
+
+qreal PanController::maxSpeed() const
+{
+ return d->maxSpeed;
+}
+
+void PanController::setSpeed(qreal speed)
+{
+ qreal t = d->panTime.restart();
+ if (d->speed != speed)
+ {
+ d->speed = speed;
+ d->angle = speed * d->panViewAngle;
+ if (!qIsNull(d->speed))
+ d->animating = true;
+ d->elapsed += t;
+ d->calculateValues();
+ emit speedChanged();
+ }
+}
+
+qreal PanController::speed() const
+{
+ return d->speed;
+}
+
+void PanController::pan()
+{
+ if (d->animating)
+ {
+ qreal t = d->panTime.restart();
+ d->elapsed += t;
+ // dont recalculate every single time
+ // 30ms frame time == 33fps - more than enough
+ if (d->elapsed > 30)
+ d->calculateValues();
+
+ PhotoBrowser3DView *view = qobject_cast<PhotoBrowser3DView*>(parent());
+ Q_ASSERT(view);
+ view->update();
+ }
+}
+
+void PanControllerPrivate::calculateValues()
+{
+ if (view && animating)
+ {
+ QGLCamera *cam = view->camera();
+ Q_ASSERT(cam);
+
+ QVector3D c = cam->center();
+ QVector3D e = cam->eye();
+
+ if (qFuzzyIsNull(speed))
+ {
+ c.setX(e.x());
+ e.setZ(defaultDistance);
+ }
+ else
+ {
+ // as speed goes from 0 -> 1, eye moves closer to z=0 plane
+ e.setZ(defaultDistance - (speed * (defaultDistance - panDistance)));
+
+ // the view angle is a direct function of the speed see setSpeed() above
+ // and as view angle increases we look further along the x-axis
+ qreal opp = (e.z() - c.z()) * qTan(angle);
+
+ // velocity along the x axis is controlled by speed (a value from 0 -> 1
+ // which is a modifier for the maxSpeed, a constant). the velocity gives
+ // us the incremental change in x for this unit time
+ qreal dx = (speed * maxSpeed * elapsed);
+
+ if (arrowDirection == Qt::LeftArrow)
+ {
+ e.setX(e.x() - dx);
+ c.setX(e.x() - opp);
+ }
+ else if (arrowDirection == Qt::RightArrow)
+ {
+ e.setX(e.x() + dx);
+ c.setX(e.x() + opp);
+ }
+ }
+ cam->setEye(e);
+ cam->setCenter(c);
+ }
+ elapsed = 0;
+ if (qIsNull(speed))
+ animating = false;
+}
+
+Qt::ArrowType PanController::direction() const
+{
+ return d->arrowDirection;
+}
+
+void PanController::setDirection(Qt::ArrowType arrow)
+{
+ Q_ASSERT(arrow == Qt::LeftArrow || arrow == Qt::RightArrow);
+ d->arrowDirection = arrow;
+}
+
+QGLView *PanController::view() const
+{
+ return d->view;
+}
+
+void PanController::setView(QGLView *view)
+{
+ d->view = view;
+}
+