feat: Animate camera transitions for sketch mode
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
@@ -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()
|
||||||
{
|
{
|
||||||
m_currentPlane = SketchPlane::NONE;
|
auto* animGroup = new QParallelAnimationGroup(this);
|
||||||
update();
|
|
||||||
|
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;
|
||||||
|
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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user