-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy patharcballcontroller.cpp
More file actions
94 lines (69 loc) · 2.47 KB
/
Copy patharcballcontroller.cpp
File metadata and controls
94 lines (69 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "arcballcontroller.h"
#include <cmath>
#include <qdebug.h>
static const double PI = 4.0 * std::atan(1.0);
ArcballController::ArcballController(QWidget* parent)
: parent_(parent) {
}
void ArcballController::initModelView(const QMatrix4x4 &mMat, const QMatrix4x4 &vMat) {
rotMat_ = mMat;
lookMat_ = vMat;
update();
}
void ArcballController::update() {
switch (mode_) {
case ArcballMode::Translate:
updateTranslate();
break;
case ArcballMode::Rotate:
updateRotate();
break;
case ArcballMode::Scale:
updateScale();
break;
default:
break;
}
modelMat_ = rotMat_;
modelMat_.scale(1.0 - scroll_ * 0.1);
viewMat_ = lookMat_;
viewMat_.translate(translate_);
}
void ArcballController::updateTranslate() {
const QVector4D u(1.0f, 0.0f, 0.0f, 0.0f);
const QVector4D v(0.0f, 1.0f, 0.0f, 0.0f);
const QMatrix4x4 camera2objMat = lookMat_.inverted();
const QVector3D objspaceU = (camera2objMat * u).toVector3D().normalized();
const QVector3D objspaceV = (camera2objMat * v).toVector3D().normalized();
const double dx = 10.0 * (newPoint_.x() - oldPoint_.x()) / parent_->width();
const double dy = 10.0 * (newPoint_.y() - oldPoint_.y()) / parent_->height();
translate_ += (objspaceU * dx - objspaceV * dy);
}
void ArcballController::updateRotate() {
const QVector3D u = getVector(newPoint_.x(), newPoint_.y());
const QVector3D v = getVector(oldPoint_.x(), oldPoint_.y());
const double angle = std::acos(std::min(1.0f, QVector3D::dotProduct(u, v)));
const QVector3D rotAxis = QVector3D::crossProduct(v, u);
const QMatrix4x4 camera2objMat = rotMat_.inverted();
const QVector3D objSpaceRotAxis = camera2objMat * rotAxis;
QMatrix4x4 temp;
double angleByDegree = 180.0 * angle / PI;
temp.rotate(4.0 * angleByDegree, objSpaceRotAxis);
rotMat_ = rotMat_ * temp;
}
void ArcballController::updateScale() {
const double dy = 20.0 * (newPoint_.y() - oldPoint_.y()) / parent_->height();
scroll_ += dy;
}
QVector3D ArcballController::getVector(int x, int y) const {
QVector3D pt( 2.0 * x / parent_->width() - 1.0,
-2.0 * y / parent_->height() + 1.0,
0.0);
const double xySquared = pt.x() * pt.x() + pt.y() * pt.y();
if (xySquared) {
pt.setZ(std::sqrt(1.0 - xySquared));
} else {
pt.normalized();
}
return pt;
}