Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add arc-ball mechanism to mouse control #99

Merged
merged 3 commits into from
Jan 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 74 additions & 11 deletions src/canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ const float Canvas::P_ORTHOGRAPHIC = 0.0f;

Canvas::Canvas(const QSurfaceFormat& format, QWidget *parent)
: QOpenGLWidget(parent), mesh(nullptr),
scale(1), zoom(1), tilt(90), yaw(0),
scale(1), zoom(1),
anim(this, "perspective"), status(" "),
meshInfo("")
{
setFormat(format);
QFile styleFile(":/qt/style.qss");
styleFile.open( QFile::ReadOnly );
setStyleSheet(styleFile.readAll());
currentTransform = QMatrix4x4();
currentTransform.setToIdentity();

anim.setDuration(100);
}
Expand Down Expand Up @@ -65,6 +67,16 @@ void Canvas::invert_zoom(bool d)
update();
}

void Canvas::resetTransform() {
currentTransform.setToIdentity();
// apply some rotations to define initial orientation
currentTransform.rotate(-90.0, QVector3D(1, 0, 0));
currentTransform.rotate(180.0 + 15.0, QVector3D(0, 0, 1));
currentTransform.rotate(15.0, QVector3D(1, -sin(M_PI/12), 0));

zoom = 1;
}

void Canvas::load_mesh(Mesh* m, bool is_reload)
{
delete mesh;
Expand All @@ -78,8 +90,7 @@ void Canvas::load_mesh(Mesh* m, bool is_reload)

// Reset other camera parameters
zoom = 1;
yaw = 0;
tilt = 90;
resetTransform();
}
meshInfo = QStringLiteral("Triangles: %1\nX: [%2, %3]\nY: [%4, %5]\nZ: [%6, %7]").arg(m->triCount());
for(int dIdx = 0; dIdx < 3; dIdx++) meshInfo = meshInfo.arg(lower[dIdx]).arg(upper[dIdx]);
Expand Down Expand Up @@ -201,11 +212,7 @@ void Canvas::draw_mesh()
}
QMatrix4x4 Canvas::orient_matrix() const
{
QMatrix4x4 m;
m.rotate(tilt, QVector3D(1, 0, 0));
m.rotate(yaw, QVector3D(0, 0, 1));
//We want the x axis to the right, and the z axis up
m.scale(-1, 1, -1);
QMatrix4x4 m = currentTransform;
return m;
}
QMatrix4x4 Canvas::transform_matrix() const
Expand Down Expand Up @@ -255,16 +262,72 @@ void Canvas::mouseReleaseEvent(QMouseEvent* event)
}
}


// This method change the referential of the mouse point coordinates
// into a referential x=[-1.0,1.0], y=[-1.0,1.0], with 0,0 being the
// center of the widget.
QPointF Canvas::changeMouseCoordinates(QPoint p) {
QPointF pr;
// Change coordinates
double ws2 = this->width() / 2.0;
double hs2 = this->height() / 2.0;
pr.setX(p.x() / ws2 - 1.0);
pr.setY(p.y() / hs2 - 1.0);
return pr;
}

void Canvas::calcArcballTransform(QPointF p1, QPointF p2) {
// Calc z1 & z2
double x1 = p1.x();
double x2 = p2.x();
double y1 = p1.y();
double y2 = p2.y();
double p1sq = x1 * x1 + y1 * y1;
double z1;
if (p1sq <= 1) {
z1 = sqrt(1.0 - p1sq);
} else {
x1 = x1 / sqrt(p1sq);
y1 = y1 / sqrt(p1sq);
z1 = 0.0;
}
double p2sq = x2 * x2 + y2 * y2;
double z2;
if (p2sq <= 1) {
z2 = sqrt(1.0 - p2sq);
} else {
x2 = x2 / sqrt(p2sq);
y2 = y2 / sqrt(p2sq);
z2 = 0.0;
}

// set v1 and v2
QVector3D v1(x1, y1, z1);
QVector3D v2(x2, y2, z2);

// calc v1 cross v2
QVector3D v1xv2 = QVector3D::crossProduct(v1, v2);
QVector3D v1xv2Obj = currentTransform.inverted().mapVector(v1xv2);

// calc angle
double angle = acos(std::min(1.0f,QVector3D::dotProduct(v1, v2))) * 180.0 / M_PI;

// apply transform
currentTransform.rotate(angle,v1xv2Obj);
}

void Canvas::mouseMoveEvent(QMouseEvent* event)
{
auto p = event->pos();
auto d = p - mouse_pos;


if (event->buttons() & Qt::LeftButton)
{
yaw = fmod(yaw - d.x(), 360);
tilt = fmod(tilt - d.y(), 360);
QPointF p1r = changeMouseCoordinates(mouse_pos);
QPointF p2r = changeMouseCoordinates(p);
calcArcballTransform(p1r,p2r);

update();
}
else if (event->buttons() & Qt::RightButton)
Expand Down
6 changes: 4 additions & 2 deletions src/canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ public slots:
QMatrix4x4 transform_matrix() const;
QMatrix4x4 aspect_matrix() const;
QMatrix4x4 view_matrix() const;
void resetTransform();
QPointF changeMouseCoordinates(QPoint p);
void calcArcballTransform(QPointF p1, QPointF p2);

QOpenGLShader* mesh_vertshader;
QOpenGLShaderProgram mesh_shader;
Expand All @@ -66,8 +69,7 @@ public slots:
QVector3D center;
float scale;
float zoom;
float tilt;
float yaw;
QMatrix4x4 currentTransform;

float perspective;
enum DrawMode drawMode;
Expand Down