feat: Animate camera transitions for sketch mode

Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
2026-02-09 18:11:36 -07:00
parent eea8099bd2
commit 7955af77be
2 changed files with 170 additions and 12 deletions

View File

@@ -9,6 +9,8 @@
#include <QPainter> #include <QPainter>
#include <QWheelEvent> #include <QWheelEvent>
#include <QApplication> #include <QApplication>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>
ViewportWidget::ViewportWidget(QWidget *parent) ViewportWidget::ViewportWidget(QWidget *parent)
: QOpenGLWidget(parent) : QOpenGLWidget(parent)
@@ -30,6 +32,51 @@ void ViewportWidget::setDocument(Document* document)
m_featureBrowser->setDocument(document); m_featureBrowser->setDocument(document);
} }
float ViewportWidget::xRotation() const { return xRot; }
void ViewportWidget::setXRotation(float angle)
{
if (angle != xRot) {
xRot = angle;
update();
}
}
float ViewportWidget::yRotation() const { return yRot; }
void ViewportWidget::setYRotation(float angle)
{
if (angle != yRot) {
yRot = angle;
update();
}
}
float ViewportWidget::zoom() const { return zoom; }
void ViewportWidget::setZoom(float value)
{
if (value != zoom) {
zoom = value;
update();
}
}
float ViewportWidget::panX() const { return panX; }
void ViewportWidget::setPanX(float value)
{
if (value != panX) {
panX = value;
update();
}
}
float ViewportWidget::panY() const { return panY; }
void ViewportWidget::setPanY(float value)
{
if (value != panY) {
panY = value;
update();
}
}
void ViewportWidget::initializeGL() void ViewportWidget::initializeGL()
{ {
initializeOpenGLFunctions(); initializeOpenGLFunctions();
@@ -124,33 +171,117 @@ void ViewportWidget::wheelEvent(QWheelEvent *event)
void ViewportWidget::startSketch(SketchPlane plane) void ViewportWidget::startSketch(SketchPlane plane)
{ {
m_currentPlane = plane; m_currentPlane = plane;
panX = 0;
panY = 0;
zoom = -20.0f; // Zoom out to see the grid
m_savedXRot = xRot;
m_savedYRot = yRot;
m_savedPanX = panX;
m_savedPanY = panY;
m_savedZoom = zoom;
float targetXRot = xRot;
float targetYRot = yRot;
switch (plane) { switch (plane) {
case SketchPlane::XY: // Front view case SketchPlane::XY: // Front view
xRot = 0; targetXRot = 0;
yRot = 0; targetYRot = 0;
break; break;
case SketchPlane::XZ: // Top view case SketchPlane::XZ: // Top view
xRot = -90 * 16; targetXRot = -90 * 16;
yRot = 0; targetYRot = 0;
break; break;
case SketchPlane::YZ: // Right view case SketchPlane::YZ: // Right view
xRot = 0; targetXRot = 0;
yRot = 90 * 16; targetYRot = 90 * 16;
break; break;
case SketchPlane::NONE: case SketchPlane::NONE:
break; break;
} }
update();
auto* animGroup = new QParallelAnimationGroup(this);
auto* xRotAnim = new QPropertyAnimation(this, "xRotation");
xRotAnim->setDuration(300);
xRotAnim->setStartValue(xRot);
xRotAnim->setEndValue(targetXRot);
xRotAnim->setEasingCurve(QEasingCurve::InOutQuad);
animGroup->addAnimation(xRotAnim);
auto* yRotAnim = new QPropertyAnimation(this, "yRotation");
yRotAnim->setDuration(300);
yRotAnim->setStartValue(yRot);
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 ViewportWidget::saveSketch() void ViewportWidget::saveSketch()
{ {
auto* animGroup = new QParallelAnimationGroup(this);
auto* xRotAnim = new QPropertyAnimation(this, "xRotation");
xRotAnim->setDuration(300);
xRotAnim->setStartValue(xRot);
xRotAnim->setEndValue(m_savedXRot);
xRotAnim->setEasingCurve(QEasingCurve::InOutQuad);
animGroup->addAnimation(xRotAnim);
auto* yRotAnim = new QPropertyAnimation(this, "yRotation");
yRotAnim->setDuration(300);
yRotAnim->setStartValue(yRot);
yRotAnim->setEndValue(m_savedYRot);
yRotAnim->setEasingCurve(QEasingCurve::InOutQuad);
animGroup->addAnimation(yRotAnim);
auto* panXAnim = new QPropertyAnimation(this, "panX");
panXAnim->setDuration(300);
panXAnim->setStartValue(panX);
panXAnim->setEndValue(m_savedPanX);
panXAnim->setEasingCurve(QEasingCurve::InOutQuad);
animGroup->addAnimation(panXAnim);
auto* panYAnim = new QPropertyAnimation(this, "panY");
panYAnim->setDuration(300);
panYAnim->setStartValue(panY);
panYAnim->setEndValue(m_savedPanY);
panYAnim->setEasingCurve(QEasingCurve::InOutQuad);
animGroup->addAnimation(panYAnim);
auto* zoomAnim = new QPropertyAnimation(this, "zoom");
zoomAnim->setDuration(300);
zoomAnim->setStartValue(zoom);
zoomAnim->setEndValue(m_savedZoom);
zoomAnim->setEasingCurve(QEasingCurve::InOutQuad);
animGroup->addAnimation(zoomAnim);
connect(animGroup, &QParallelAnimationGroup::finished, this, [this]() {
m_currentPlane = SketchPlane::NONE; m_currentPlane = SketchPlane::NONE;
update(); update();
});
animGroup->start(QAbstractAnimation::DeleteWhenStopped);
} }
QVector3D ViewportWidget::project(const QVector3D& worldCoord, const QMatrix4x4& modelView, const QMatrix4x4& projection, const QRect& viewport) QVector3D ViewportWidget::project(const QVector3D& worldCoord, const QMatrix4x4& modelView, const QMatrix4x4& projection, const QRect& viewport)

View File

@@ -17,6 +17,12 @@ class ViewportWidget : public QOpenGLWidget, protected QOpenGLFunctions
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(float xRotation READ xRotation WRITE setXRotation)
Q_PROPERTY(float yRotation READ yRotation WRITE setYRotation)
Q_PROPERTY(float zoom READ zoom WRITE setZoom)
Q_PROPERTY(float panX READ panX WRITE setPanX)
Q_PROPERTY(float panY READ panY WRITE setPanY)
public: public:
enum class SketchPlane { enum class SketchPlane {
NONE, NONE,
@@ -32,6 +38,21 @@ public:
void saveSketch(); void saveSketch();
void setDocument(Document* document); void setDocument(Document* document);
float xRotation() const;
void setXRotation(float angle);
float yRotation() const;
void setYRotation(float angle);
float zoom() const;
void setZoom(float value);
float panX() const;
void setPanX(float value);
float panY() const;
void setPanY(float value);
protected: protected:
void initializeGL() override; void initializeGL() override;
void paintGL() override; void paintGL() override;
@@ -57,6 +78,12 @@ private:
float panX = 0; float panX = 0;
float panY = 0; float panY = 0;
QPoint lastPos; QPoint lastPos;
float m_savedXRot = 0;
float m_savedYRot = 0;
float m_savedZoom = -5.0f;
float m_savedPanX = 0;
float m_savedPanY = 0;
}; };
#endif // VIEWPORTWIDGET_H #endif // VIEWPORTWIDGET_H