v2.0.0
Loading...
Searching...
No Matches
cameracontroller.cpp
Go to the documentation of this file.
1//=============================================================================================================
12
13//=============================================================================================================
14// INCLUDES
15//=============================================================================================================
16
17#include "cameracontroller.h"
18
19#include <algorithm>
20#include <cmath>
21
22//=============================================================================================================
23// DEFINE MEMBER METHODS
24//=============================================================================================================
25
26CameraResult CameraController::computeForRotation(const QQuaternion &effectiveRotation,
27 float vpZoom,
28 const QVector2D &pan,
29 bool applyPan,
30 float aspectRatio) const
31{
32 CameraResult result;
33
34 // Projection
35 float farPlane = std::max(m_sceneSize * 20.0f, 100.0f);
36 result.projection.perspective(45.0f, aspectRatio, m_sceneSize * 0.01f, farPlane);
37
38 // Camera position from rotation + zoom
39 float baseDistance = m_sceneSize * 1.5f;
40 result.distance = baseDistance - vpZoom * (m_sceneSize * 0.05f);
41 result.cameraPos = effectiveRotation.rotatedVector(QVector3D(0, 0, result.distance));
42 result.upVector = effectiveRotation.rotatedVector(QVector3D(0, 1, 0));
43 result.lookAt = QVector3D(0, 0, 0);
44
45 // Pan: shift look-at and camera position along the view plane
46 if (applyPan && (pan.x() != 0.0f || pan.y() != 0.0f)) {
47 const QVector3D right = effectiveRotation.rotatedVector(QVector3D(1, 0, 0)).normalized();
48 const QVector3D up = result.upVector.normalized();
49 const QVector3D offset = right * pan.x() + up * pan.y();
50 result.lookAt += offset;
51 result.cameraPos += offset;
52 }
53
54 // View matrix
55 result.view.lookAt(result.cameraPos, result.lookAt, result.upVector);
56
57 // Model matrix: translate to scene center
58 result.model.translate(-m_sceneCenter);
59
60 return result;
61}
62
63//=============================================================================================================
64
66{
67 const QQuaternion preset = perspectivePresetRotation();
68 const QQuaternion effective = m_cameraRotation * preset;
69
70 return computeForRotation(effective, m_zoom, QVector2D(), false, aspectRatio);
71}
72
73//=============================================================================================================
74
75CameraResult CameraController::computeMultiView(const SubView &subView, float aspectRatio) const
76{
77 const int preset = std::clamp(subView.preset, 0, 6);
78 const QQuaternion presetOffset = multiViewPresetOffset(preset);
79
80 QQuaternion effectiveRotation;
81 if (multiViewPresetIsPerspective(preset)) {
82 effectiveRotation = subView.perspectiveRotation * presetOffset;
83 } else {
84 effectiveRotation = presetOffset;
85 }
86
87 const bool isPlanar = !multiViewPresetIsPerspective(preset);
88
89 return computeForRotation(effectiveRotation, subView.zoom, subView.pan,
90 isPlanar, aspectRatio);
91}
92
93//=============================================================================================================
94
95void CameraController::applyMouseRotation(const QPoint &delta,
96 QQuaternion &rotation,
97 float speed)
98{
99 const QQuaternion preset = perspectivePresetRotation();
100 QQuaternion effective = rotation * preset;
101
102 const QVector3D upAxis = effective.rotatedVector(QVector3D(0, 1, 0)).normalized();
103 const QVector3D rightAxis = effective.rotatedVector(QVector3D(1, 0, 0)).normalized();
104
105 QQuaternion yaw = QQuaternion::fromAxisAndAngle(upAxis, -delta.x() * speed);
106 QQuaternion pitch = QQuaternion::fromAxisAndAngle(rightAxis, -delta.y() * speed);
107
108 effective = yaw * pitch * effective;
109 rotation = effective * preset.conjugated();
110 rotation.normalize();
111}
112
113//=============================================================================================================
114
115void CameraController::applyMousePan(const QPoint &delta,
116 QVector2D &pan,
117 float sceneSize)
118{
119 const float panSpeed = sceneSize * 0.002f;
120 pan += QVector2D(-delta.x() * panSpeed, delta.y() * panSpeed);
121}
QQuaternion multiViewPresetOffset(int preset)
bool multiViewPresetIsPerspective(int preset)
QQuaternion perspectivePresetRotation()
Camera state and projection / view / model matrix computation for single- and multi-view layouts.
Viewport subdivision holding its own camera, projection, and scissor rectangle.
Definition viewstate.h:139
QVector2D pan
Definition viewstate.h:149
QQuaternion perspectiveRotation
Definition viewstate.h:150
int preset
Definition viewstate.h:151
float zoom
Definition viewstate.h:148
Computed camera matrices (projection, view, model) and vectors for a single viewport.
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