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