v2.0.0
Loading...
Searching...
No Matches
cameracontroller.cpp
Go to the documentation of this file.
1//=============================================================================================================
34
35//=============================================================================================================
36// INCLUDES
37//=============================================================================================================
38
39#include "cameracontroller.h"
40
41#include <algorithm>
42#include <cmath>
43
44//=============================================================================================================
45// DEFINE MEMBER METHODS
46//=============================================================================================================
47
48CameraResult CameraController::computeForRotation(const QQuaternion &effectiveRotation,
49 float vpZoom,
50 const QVector2D &pan,
51 bool applyPan,
52 float aspectRatio) const
53{
54 CameraResult result;
55
56 // Projection
57 float farPlane = std::max(m_sceneSize * 20.0f, 100.0f);
58 result.projection.perspective(45.0f, aspectRatio, m_sceneSize * 0.01f, farPlane);
59
60 // Camera position from rotation + zoom
61 float baseDistance = m_sceneSize * 1.5f;
62 result.distance = baseDistance - vpZoom * (m_sceneSize * 0.05f);
63 result.cameraPos = effectiveRotation.rotatedVector(QVector3D(0, 0, result.distance));
64 result.upVector = effectiveRotation.rotatedVector(QVector3D(0, 1, 0));
65 result.lookAt = QVector3D(0, 0, 0);
66
67 // Pan: shift look-at and camera position along the view plane
68 if (applyPan && (pan.x() != 0.0f || pan.y() != 0.0f)) {
69 const QVector3D right = effectiveRotation.rotatedVector(QVector3D(1, 0, 0)).normalized();
70 const QVector3D up = result.upVector.normalized();
71 const QVector3D offset = right * pan.x() + up * pan.y();
72 result.lookAt += offset;
73 result.cameraPos += offset;
74 }
75
76 // View matrix
77 result.view.lookAt(result.cameraPos, result.lookAt, result.upVector);
78
79 // Model matrix: translate to scene center
80 result.model.translate(-m_sceneCenter);
81
82 return result;
83}
84
85//=============================================================================================================
86
88{
89 const QQuaternion preset = perspectivePresetRotation();
90 const QQuaternion effective = m_cameraRotation * preset;
91
92 return computeForRotation(effective, m_zoom, QVector2D(), false, aspectRatio);
93}
94
95//=============================================================================================================
96
97CameraResult CameraController::computeMultiView(const SubView &subView, float aspectRatio) const
98{
99 const int preset = std::clamp(subView.preset, 0, 6);
100 const QQuaternion presetOffset = multiViewPresetOffset(preset);
101
102 QQuaternion effectiveRotation;
103 if (multiViewPresetIsPerspective(preset)) {
104 effectiveRotation = subView.perspectiveRotation * presetOffset;
105 } else {
106 effectiveRotation = presetOffset;
107 }
108
109 const bool isPlanar = !multiViewPresetIsPerspective(preset);
110
111 return computeForRotation(effectiveRotation, subView.zoom, subView.pan,
112 isPlanar, aspectRatio);
113}
114
115//=============================================================================================================
116
118 QQuaternion &rotation,
119 float speed)
120{
121 const QQuaternion preset = perspectivePresetRotation();
122 QQuaternion effective = rotation * preset;
123
124 const QVector3D upAxis = effective.rotatedVector(QVector3D(0, 1, 0)).normalized();
125 const QVector3D rightAxis = effective.rotatedVector(QVector3D(1, 0, 0)).normalized();
126
127 QQuaternion yaw = QQuaternion::fromAxisAndAngle(upAxis, -delta.x() * speed);
128 QQuaternion pitch = QQuaternion::fromAxisAndAngle(rightAxis, -delta.y() * speed);
129
130 effective = yaw * pitch * effective;
131 rotation = effective * preset.conjugated();
132 rotation.normalize();
133}
134
135//=============================================================================================================
136
137void CameraController::applyMousePan(const QPoint &delta,
138 QVector2D &pan,
139 float sceneSize)
140{
141 const float panSpeed = sceneSize * 0.002f;
142 pan += QVector2D(-delta.x() * panSpeed, delta.y() * panSpeed);
143}
QQuaternion multiViewPresetOffset(int preset)
bool multiViewPresetIsPerspective(int preset)
QQuaternion perspectivePresetRotation()
CameraController class declaration.
QVector2D pan
Definition viewstate.h:154
QQuaternion perspectiveRotation
Definition viewstate.h:155
int preset
Definition viewstate.h:156
float zoom
Definition viewstate.h:153
QVector3D cameraPos
QMatrix4x4 view
QMatrix4x4 model
QMatrix4x4 projection
QVector3D upVector
static void applyMouseRotation(const QPoint &delta, QQuaternion &rotation, float speed=0.5f)
static void applyMousePan(const QPoint &delta, QVector2D &pan, float sceneSize)
QQuaternion rotation() const
CameraResult computeMultiView(const SubView &subView, float aspectRatio) const
CameraResult computeSingleView(float aspectRatio) const
float sceneSize() const