diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2015-10-25 11:22:16 +0000 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2015-10-25 19:09:23 +0000 |
commit | 12461331112e06dc9bae36e03b2fa96a3784f103 (patch) | |
tree | 15e127ef48c38467d7b80bd595c1ea26ebda8588 /src | |
parent | 83c32b94872a82a6af8057f16c81326353e69c8f (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.cpp | 17 | ||||
-rw-r--r-- | src/core/core-components/qcamera.h | 3 | ||||
-rw-r--r-- | src/input/cameracontroller.cpp | 61 | ||||
-rw-r--r-- | src/input/cameracontroller_p.h | 23 |
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; }; |