summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2015-10-25 11:22:16 +0000
committerPaul Lemire <paul.lemire@kdab.com>2015-10-25 19:09:23 +0000
commit12461331112e06dc9bae36e03b2fa96a3784f103 (patch)
tree15e127ef48c38467d7b80bd595c1ea26ebda8588 /src
parent83c32b94872a82a6af8057f16c81326353e69c8f (diff)
Add first person camera controller mode and make it the default
For most scenes this is what people want in preference to the free-look mode. Keeping a consistent up vector is more natural for most people. This is a temporary hack until we get the InputManager completed and we have a proper abstraction for controllers. After all, who says the inputs should control the camera. They should be able to control any Entity with a Transform. This also requires the Transform refactoring to be completed before we can tie both sides together. Change-Id: If8f02c66febcdee31c13ee46b6651a0e923e8d09 Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src')
-rw-r--r--src/core/core-components/qcamera.cpp17
-rw-r--r--src/core/core-components/qcamera.h3
-rw-r--r--src/input/cameracontroller.cpp61
-rw-r--r--src/input/cameracontroller_p.h23
4 files changed, 95 insertions, 9 deletions
diff --git a/src/core/core-components/qcamera.cpp b/src/core/core-components/qcamera.cpp
index 0746b408b..53d22f1e5 100644
--- a/src/core/core-components/qcamera.cpp
+++ b/src/core/core-components/qcamera.cpp
@@ -196,6 +196,11 @@ QQuaternion QCamera::rollRotation(float angle) const
return QQuaternion::fromAxisAndAngle(viewVector, -angle);
}
+QQuaternion QCamera::rotation(float angle, const QVector3D &axis) const
+{
+ return QQuaternion::fromAxisAndAngle(axis, angle);
+}
+
void QCamera::tilt(float angle)
{
QQuaternion q = tiltRotation(angle);
@@ -208,6 +213,12 @@ void QCamera::pan(float angle)
rotate(q);
}
+void QCamera::pan(float angle, const QVector3D &axis)
+{
+ QQuaternion q = rotation(-angle, axis);
+ rotate(q);
+}
+
void QCamera::roll(float angle)
{
QQuaternion q = rollRotation(-angle);
@@ -226,6 +237,12 @@ void QCamera::panAboutViewCenter(float angle)
rotateAboutViewCenter(q);
}
+void QCamera::panAboutViewCenter(float angle, const QVector3D &axis)
+{
+ QQuaternion q = rotation(angle, axis);
+ rotateAboutViewCenter(q);
+}
+
void QCamera::rollAboutViewCenter(float angle)
{
QQuaternion q = rollRotation(angle);
diff --git a/src/core/core-components/qcamera.h b/src/core/core-components/qcamera.h
index 2b13e1f9d..305cae930 100644
--- a/src/core/core-components/qcamera.h
+++ b/src/core/core-components/qcamera.h
@@ -88,6 +88,7 @@ public:
QQuaternion tiltRotation(float angle) const;
QQuaternion panRotation(float angle) const;
QQuaternion rollRotation(float angle) const;
+ QQuaternion rotation(float angle, const QVector3D &axis) const;
// Translate relative to camera orientation axes
Q_INVOKABLE void translate(const QVector3D& vLocal, CameraTranslationOption option = TranslateViewCenter );
@@ -97,10 +98,12 @@ public:
Q_INVOKABLE void tilt(float angle);
Q_INVOKABLE void pan(float angle);
+ Q_INVOKABLE void pan(float angle, const QVector3D &axis);
Q_INVOKABLE void roll(float angle);
Q_INVOKABLE void tiltAboutViewCenter(float angle);
Q_INVOKABLE void panAboutViewCenter(float angle);
+ Q_INVOKABLE void panAboutViewCenter(float angle, const QVector3D &axis);
Q_INVOKABLE void rollAboutViewCenter(float angle);
Q_INVOKABLE void rotate(const QQuaternion& q);
diff --git a/src/input/cameracontroller.cpp b/src/input/cameracontroller.cpp
index d9af1d06f..0efd6d002 100644
--- a/src/input/cameracontroller.cpp
+++ b/src/input/cameracontroller.cpp
@@ -69,6 +69,8 @@ CameraController::CameraController(QObject *parent) :
m_lookRate( 0.1f ),
m_translateFast( false ),
m_multisampleEnabled( true ),
+ m_controlMode( FirstPerson ),
+ m_firstPersonUp( QVector3D( 0.0f, 1.0f, 0.0f ) ),
m_updateTimer(new QTimer(this))
{
m_updateTimer->setInterval(16);
@@ -268,15 +270,30 @@ void CameraController::mouseMoveEvent( QMouseEvent* e )
float dy = -(m_pos.y() - m_prevPos.y());
m_prevPos = m_pos;
- if ( m_leftButtonPressed )
- {
- m_camera->pan( dx * m_lookRate );
- m_camera->tilt( dy * m_lookRate );
- }
- else if ( m_orbitMode )
- {
- m_camera->panAboutViewCenter( dx * m_orbitRate );
- m_camera->tiltAboutViewCenter( dy * m_orbitRate );
+ if (m_leftButtonPressed) {
+ switch (m_controlMode) {
+ case FreeLook:
+ m_camera->pan(dx * m_lookRate);
+ break;
+
+ case FirstPerson:
+ m_camera->pan(dx * m_lookRate, m_firstPersonUp);
+ break;
+ }
+
+ m_camera->tilt(dy * m_lookRate);
+ } else if (m_orbitMode) {
+ switch (m_controlMode) {
+ case FreeLook:
+ m_camera->panAboutViewCenter(dx * m_orbitRate);
+ break;
+
+ case FirstPerson:
+ m_camera->panAboutViewCenter(dx * m_orbitRate, m_firstPersonUp);
+ break;
+ }
+
+ m_camera->tiltAboutViewCenter(dy * m_orbitRate);
}
}
@@ -291,6 +308,32 @@ void CameraController::toggleMSAA()
emit multisampleEnabledChanged();
}
+void CameraController::setControlMode(ControlMode controlMode)
+{
+ if (controlMode != m_controlMode) {
+ m_controlMode = controlMode;
+ emit controlModeChanged();
+ }
+}
+
+CameraController::ControlMode CameraController::controlMode() const
+{
+ return m_controlMode;
+}
+
+void CameraController::setFirstPersonUpVector(const QVector3D &up)
+{
+ if (m_firstPersonUp != up) {
+ m_firstPersonUp = up;
+ emit firstPersonUpVectorChanged();
+ }
+}
+
+QVector3D CameraController::firstPersonUpVector() const
+{
+ return m_firstPersonUp;
+}
+
bool CameraController::eventFilter(QObject *receiver, QEvent *event)
{
switch (event->type()) {
diff --git a/src/input/cameracontroller_p.h b/src/input/cameracontroller_p.h
index 2fc5b7d0e..956400b02 100644
--- a/src/input/cameracontroller_p.h
+++ b/src/input/cameracontroller_p.h
@@ -51,6 +51,7 @@
#include <QObject>
#include <QPoint>
+#include <QtGui/qvector3d.h>
QT_BEGIN_NAMESPACE
@@ -76,6 +77,9 @@ class CameraController : public QObject
Q_PROPERTY( float lookRate READ lookRate WRITE setLookRate NOTIFY lookRateChanged )
Q_PROPERTY( bool multisampleEnabled READ isMultisampleEnabled NOTIFY multisampleEnabledChanged )
+ Q_PROPERTY( ControlMode controlMode READ controlMode WRITE setControlMode NOTIFY controlModeChanged )
+ Q_PROPERTY( QVector3D firstPersonUpVector READ firstPersonUpVector WRITE setFirstPersonUpVector NOTIFY firstPersonUpVectorChanged )
+
public:
explicit CameraController(QObject *parent = 0);
@@ -101,6 +105,19 @@ public:
void update( double t );
bool isMultisampleEnabled() const;
+
+ enum ControlMode {
+ FreeLook,
+ FirstPerson
+ };
+ Q_ENUM(ControlMode)
+
+ void setControlMode( ControlMode controlMode );
+ ControlMode controlMode() const;
+
+ void setFirstPersonUpVector( const QVector3D &up );
+ QVector3D firstPersonUpVector() const;
+
public Q_SLOTS:
void toggleMSAA();
@@ -114,6 +131,9 @@ Q_SIGNALS:
void multisampleEnabledChanged();
+ void controlModeChanged();
+ void firstPersonUpVectorChanged();
+
private Q_SLOTS:
void onUpdate();
@@ -141,6 +161,9 @@ private:
bool m_translateFast;
bool m_multisampleEnabled;
+ ControlMode m_controlMode;
+ QVector3D m_firstPersonUp;
+
QTimer *m_updateTimer;
};