#include "Camera.h" #include "ViewportWidget.h" #include #include #include #include Camera::Camera(QObject *parent) : QObject(parent) { // Set initial view to an isometric angle on the XY plane m_xRot = 30 * 16; m_yRot = -45 * 16; m_zoom = -20.0f; m_panX = 0.0f; m_panY = 0.0f; } void Camera::processMouseMovement(QMouseEvent* event, const QPoint& lastPos) { int dx = event->pos().x() - lastPos.x(); int dy = event->pos().y() - lastPos.y(); if (event->buttons() & Qt::MiddleButton) { if (QApplication::keyboardModifiers() & Qt::ShiftModifier) { // Pan setPanX(m_panX + dx / 100.0f); setPanY(m_panY - dy / 100.0f); } else { // Rotate setXRotation(m_xRot + 8 * dy); setYRotation(m_yRot + 8 * dx); } } } void Camera::processWheel(QWheelEvent* event) { QPoint numDegrees = event->angleDelta() / 8; if (!numDegrees.isNull()) { setZoom(m_zoom + numDegrees.y() / 5.0f); } } QMatrix4x4 Camera::modelViewMatrix() const { QMatrix4x4 model; model.translate(m_panX, m_panY, m_zoom); model.rotate(m_xRot / 16.0f, 1, 0, 0); model.rotate(m_yRot / 16.0f, 0, 1, 0); return model; } float Camera::xRotation() const { return m_xRot; } void Camera::setXRotation(float angle) { if (angle != m_xRot) { m_xRot = angle; emit cameraChanged(); } } float Camera::yRotation() const { return m_yRot; } void Camera::setYRotation(float angle) { if (angle != m_yRot) { m_yRot = angle; emit cameraChanged(); } } float Camera::zoom() const { return m_zoom; } void Camera::setZoom(float value) { if (value != m_zoom) { m_zoom = value; emit cameraChanged(); } } float Camera::panX() const { return m_panX; } void Camera::setPanX(float value) { if (value != m_panX) { m_panX = value; emit cameraChanged(); } } float Camera::panY() const { return m_panY; } void Camera::setPanY(float value) { if (value != m_panY) { m_panY = value; emit cameraChanged(); } } void Camera::saveState() { m_savedXRot = m_xRot; m_savedYRot = m_yRot; m_savedPanX = m_panX; m_savedPanY = m_panY; m_savedZoom = m_zoom; } void Camera::restoreState() { setXRotation(m_savedXRot); setYRotation(m_savedYRot); setPanX(m_savedPanX); setPanY(m_savedPanY); setZoom(m_savedZoom); } void Camera::animateToPlaneView(int plane) { float targetXRot = xRotation(); float targetYRot = yRotation(); switch (static_cast(plane)) { case ViewportWidget::SketchPlane::XY: // Top view targetXRot = 90 * 16; targetYRot = 0; break; case ViewportWidget::SketchPlane::XZ: // Front view targetXRot = 0; targetYRot = 0; break; case ViewportWidget::SketchPlane::YZ: // Right view targetXRot = 0; targetYRot = -90 * 16; break; case ViewportWidget::SketchPlane::NONE: break; } auto* animGroup = new QParallelAnimationGroup(this); auto* xRotAnim = new QPropertyAnimation(this, "xRotation"); xRotAnim->setDuration(300); xRotAnim->setStartValue(xRotation()); xRotAnim->setEndValue(targetXRot); xRotAnim->setEasingCurve(QEasingCurve::InOutQuad); animGroup->addAnimation(xRotAnim); auto* yRotAnim = new QPropertyAnimation(this, "yRotation"); yRotAnim->setDuration(300); yRotAnim->setStartValue(yRotation()); yRotAnim->setEndValue(targetYRot); yRotAnim->setEasingCurve(QEasingCurve::InOutQuad); animGroup->addAnimation(yRotAnim); auto* panXAnim = new QPropertyAnimation(this, "panX"); panXAnim->setDuration(300); panXAnim->setStartValue(panX()); panXAnim->setEndValue(0.0f); panXAnim->setEasingCurve(QEasingCurve::InOutQuad); animGroup->addAnimation(panXAnim); auto* panYAnim = new QPropertyAnimation(this, "panY"); panYAnim->setDuration(300); panYAnim->setStartValue(panY()); panYAnim->setEndValue(0.0f); panYAnim->setEasingCurve(QEasingCurve::InOutQuad); animGroup->addAnimation(panYAnim); auto* zoomAnim = new QPropertyAnimation(this, "zoom"); zoomAnim->setDuration(300); zoomAnim->setStartValue(zoom()); zoomAnim->setEndValue(-20.0f); zoomAnim->setEasingCurve(QEasingCurve::InOutQuad); animGroup->addAnimation(zoomAnim); animGroup->start(QAbstractAnimation::DeleteWhenStopped); } void Camera::animateRestoreState() { auto* animGroup = new QParallelAnimationGroup(this); auto* xRotAnim = new QPropertyAnimation(this, "xRotation"); xRotAnim->setDuration(300); xRotAnim->setStartValue(xRotation()); xRotAnim->setEndValue(savedXRot()); xRotAnim->setEasingCurve(QEasingCurve::InOutQuad); animGroup->addAnimation(xRotAnim); auto* yRotAnim = new QPropertyAnimation(this, "yRotation"); yRotAnim->setDuration(300); yRotAnim->setStartValue(yRotation()); yRotAnim->setEndValue(savedYRot()); yRotAnim->setEasingCurve(QEasingCurve::InOutQuad); animGroup->addAnimation(yRotAnim); auto* panXAnim = new QPropertyAnimation(this, "panX"); panXAnim->setDuration(300); panXAnim->setStartValue(panX()); panXAnim->setEndValue(savedPanX()); panXAnim->setEasingCurve(QEasingCurve::InOutQuad); animGroup->addAnimation(panXAnim); auto* panYAnim = new QPropertyAnimation(this, "panY"); panYAnim->setDuration(300); panYAnim->setStartValue(panY()); panYAnim->setEndValue(savedPanY()); panYAnim->setEasingCurve(QEasingCurve::InOutQuad); animGroup->addAnimation(panYAnim); auto* zoomAnim = new QPropertyAnimation(this, "zoom"); zoomAnim->setDuration(300); zoomAnim->setStartValue(zoom()); zoomAnim->setEndValue(savedZoom()); zoomAnim->setEasingCurve(QEasingCurve::InOutQuad); animGroup->addAnimation(zoomAnim); connect(animGroup, &QParallelAnimationGroup::finished, this, &Camera::restoreStateAnimationFinished); animGroup->start(QAbstractAnimation::DeleteWhenStopped); }