1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 ** This file is part of the demonstration applications of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
10 ** This file contains pre-release code and may not be distributed.
11 ** You may use this file in accordance with the terms and conditions
12 ** contained in the Technology Preview License Agreement accompanying
15 ** GNU Lesser General Public License Usage
16 ** Alternatively, this file may be used under the terms of the GNU Lesser
17 ** General Public License version 2.1 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.LGPL included in the
19 ** packaging of this file. Please review the following information to
20 ** ensure the GNU Lesser General Public License version 2.1 requirements
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 ** In addition, as a special exception, Nokia gives you certain
24 ** additional rights. These rights are described in the Nokia Qt LGPL
25 ** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "trackball.h"
45 //============================================================================//
47 //============================================================================//
49 TrackBall::TrackBall(TrackMode mode
)
50 : m_angularVelocity(0)
55 m_axis
= QVector3D(0, 1, 0);
56 m_rotation
= QQuaternion();
57 m_lastTime
= QTime::currentTime();
60 TrackBall::TrackBall(float angularVelocity
, const QVector3D
& axis
, TrackMode mode
)
62 , m_angularVelocity(angularVelocity
)
67 m_rotation
= QQuaternion();
68 m_lastTime
= QTime::currentTime();
71 void TrackBall::push(const QPointF
& p
, const QQuaternion
&)
73 m_rotation
= rotation();
75 m_lastTime
= QTime::currentTime();
77 m_angularVelocity
= 0.0f
;
80 void TrackBall::move(const QPointF
& p
, const QQuaternion
&transformation
)
85 QTime currentTime
= QTime::currentTime();
86 int msecs
= m_lastTime
.msecsTo(currentTime
);
93 QLineF
delta(m_lastPos
, p
);
94 m_angularVelocity
= 180*delta
.length() / (PI
*msecs
);
95 m_axis
= QVector3D(delta
.dy(), -delta
.dx(), 0.0f
).normalized();
96 m_axis
= transformation
.rotateVector(m_axis
);
97 m_rotation
*= QQuaternion::fromAxisAndAngle(m_axis
, delta
.length());
102 QVector3D lastPos3D
= QVector3D(m_lastPos
.x(), m_lastPos
.y(), 0.0f
);
103 float sqrZ
= 1 - QVector3D::dotProduct(lastPos3D
, lastPos3D
);
105 lastPos3D
.setZ(sqrt(sqrZ
));
107 lastPos3D
.normalize();
109 QVector3D currentPos3D
= QVector3D(p
.x(), p
.y(), 0.0f
);
110 sqrZ
= 1 - QVector3D::dotProduct(currentPos3D
, currentPos3D
);
112 currentPos3D
.setZ(sqrt(sqrZ
));
114 currentPos3D
.normalize();
116 m_axis
= QVector3D::crossProduct(currentPos3D
, lastPos3D
);
117 float angle
= asin(sqrt(QVector3D::dotProduct(m_axis
, m_axis
)));
119 m_angularVelocity
= 180*angle
/ (PI
*msecs
);
121 m_axis
= transformation
.rotateVector(m_axis
);
122 m_rotation
*= QQuaternion::fromAxisAndAngle(m_axis
, angle
);
129 m_lastTime
= currentTime
;
132 void TrackBall::release(const QPointF
& p
, const QQuaternion
&transformation
)
134 // Calling move() caused the rotation to stop if the framerate was too low.
135 move(p
, transformation
);
139 void TrackBall::start()
141 m_lastTime
= QTime::currentTime();
145 void TrackBall::stop()
147 m_rotation
= rotation();
151 QQuaternion
TrackBall::rotation() const
153 if (m_paused
|| m_pressed
)
156 QTime currentTime
= QTime::currentTime();
157 float angle
= m_angularVelocity
* m_lastTime
.msecsTo(currentTime
);
158 return m_rotation
* QQuaternion::fromAxisAndAngle(m_axis
, angle
);