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

New zoom algo #1415

Merged
merged 3 commits into from
Dec 17, 2020
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
27 changes: 1 addition & 26 deletions src/core/StelApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,13 +265,6 @@ StelApp::StelApp(StelMainView *parent)
singleton = this;

moduleMgr = new StelModuleMgr();

wheelEventTimer = new QTimer(this);
wheelEventTimer->setInterval(25);
wheelEventTimer->setSingleShot(true);

// Reset delta accumulators
wheelEventDelta[0] = wheelEventDelta[1] = 0;
}

/*************************************************************************
Expand Down Expand Up @@ -855,31 +848,13 @@ void StelApp::handleClick(QMouseEvent* inputEvent)
}

// Handle mouse wheel.
// This deltaEvent is a work-around for QTBUG-22269
void StelApp::handleWheel(QWheelEvent* event)
{
event->setAccepted(false);

const int deltaIndex = event->orientation() == Qt::Horizontal ? 0 : 1;
wheelEventDelta[deltaIndex] += event->delta();
if (wheelEventTimer->isActive())
{
// Collect the values. If delta is small enough we wait for more values or the end
// of the timer period to process them.
if (qAbs(wheelEventDelta[deltaIndex]) < 120)
return;
}

wheelEventTimer->start();

// Create a new event with the accumulated delta
QWheelEvent deltaEvent(QPoint(qRound(event->pos().x()*devicePixelsPerPixel), qRound(event->pos().y()*devicePixelsPerPixel)),
QPoint(qRound(event->globalPos().x()*devicePixelsPerPixel), qRound(event->globalPos().y()*devicePixelsPerPixel)),
wheelEventDelta[deltaIndex], event->buttons(), event->modifiers(), event->orientation());
event->delta(), event->buttons(), event->modifiers(), event->orientation());
deltaEvent.setAccepted(false);
// Reset the collected values
wheelEventDelta[deltaIndex] = 0;

// Send the event to every StelModule
for (auto* i : moduleMgr->getCallOrders(StelModule::ActionHandleMouseClicks)) {
i->handleMouseWheel(&deltaEvent);
Expand Down
6 changes: 0 additions & 6 deletions src/core/StelApp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,12 +419,6 @@ public slots:
// The scaling ratio to apply on all display elements, like GUI, text etc..
float globalScalingRatio;

// Used to collect wheel events
QTimer * wheelEventTimer;

// Accumulated horizontal and vertical wheel event deltas
int wheelEventDelta[2];

float fps;
int frame;
double frameTimeAccum; // Used for fps counter
Expand Down
62 changes: 34 additions & 28 deletions src/core/StelMovementMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,35 @@
#include <QFont>
#include <QFontMetrics>

double Smoother::getValue() const
{
double k = easingCurve.valueForProgress(progress / duration);
return start * (1 - k) + aim * k;
}

void Smoother::setTarget(double start, double aim, double duration)
{
this->start = start;
this->aim = aim;
this->duration = duration;
this->progress = 0;
// Compute best easing curve depending on the speed of animation.
if (duration >= 1.0)
easingCurve = QEasingCurve(QEasingCurve::InOutQuart);
else
easingCurve = QEasingCurve(QEasingCurve::OutQuad);
}

void Smoother::update(double dt)
{
progress = qMin(progress + dt, duration);
}

bool Smoother::finished() const
{
return progress >= duration;
}

StelMovementMgr::StelMovementMgr(StelCore* acore)
: currentFov(60.)
, initFov(60.)
Expand Down Expand Up @@ -1512,29 +1541,10 @@ void StelMovementMgr::updateAutoZoom(double deltaTime)
{
if (flagAutoZoom)
{
// Use a smooth function
double c;

if( zoomMove.startFov > zoomMove.aimFov )
{
// slow down as we approach final view
c = 1.0 - static_cast<double>((1.0f-zoomMove.coef)*(1.0f-zoomMove.coef)*(1.0f-zoomMove.coef));
}
else
{
// speed up as we leave zoom target
c = static_cast<double>(zoomMove.coef * zoomMove.coef * zoomMove.coef);
}

double newFov=zoomMove.startFov + (zoomMove.aimFov - zoomMove.startFov) * c;

zoomMove.coef+=zoomMove.speed*static_cast<float>(deltaTime)*1000;
if (zoomMove.coef>=1.f)
{
zoomMove.update(deltaTime);
double newFov = zoomMove.getValue();
if (zoomMove.finished())
flagAutoZoom = 0;
newFov=zoomMove.aimFov;
}

setFov(newFov); // updates currentFov->don't use newFov later!

// In case we have offset center, we want object still visible in center.
Expand Down Expand Up @@ -1595,11 +1605,7 @@ void StelMovementMgr::updateAutoZoom(double deltaTime)
void StelMovementMgr::zoomTo(double aim_fov, float zoomDuration)
{
zoomDuration /= movementsSpeedFactor;

zoomMove.aimFov=aim_fov;
zoomMove.startFov=currentFov;
zoomMove.speed=1.f/(zoomDuration*1000);
zoomMove.coef=0.;
zoomMove.setTarget(currentFov, aim_fov, zoomDuration);
flagAutoZoom = true;
}

Expand All @@ -1612,7 +1618,7 @@ void StelMovementMgr::changeFov(double deltaFov)

double StelMovementMgr::getAimFov(void) const
{
return (flagAutoZoom ? zoomMove.aimFov : currentFov);
return (flagAutoZoom ? zoomMove.getAim() : currentFov);
}

void StelMovementMgr::setMaxFov(double max)
Expand Down
39 changes: 23 additions & 16 deletions src/core/StelMovementMgr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,27 @@
#include <QTimeLine>
#include <QTimer>
#include <QCursor>
#include <QEasingCurve>

//! @class Smoother
//! Compute smooth animation for a given float value.
//! Used to smooth out the fov animations.
class Smoother
{
public:
double getValue() const;
double getAim() const { return aim; }
void setTarget(double start, double aim, double duration);
void update(double dt);
bool finished() const;

private:
QEasingCurve easingCurve;
double start;
double aim;
double duration;
double progress;
};

//! @class StelMovementMgr
//! Manages the head movements and zoom operations.
Expand Down Expand Up @@ -515,23 +536,9 @@ private slots:
// Time mouse control
bool dragTimeMode; // Internal flag, true during mouse time motion. This is set true when mouse is moving with ctrl pressed. Set false when releasing ctrl.

//! @internal
//! Store data for auto-zoom.
// Components:
// startFov: field of view at start
// aimFov: intended field of view at end of zoom move
// speed: rate of change. UNITS?
// coef: set to 0 at begin of zoom, will increase to 1 during autozoom motion.
struct AutoZoom
{
double startFov;
double aimFov;
float speed;
float coef;
};
// Internal state for smooth zoom animation.
Smoother zoomMove;

// Automove
AutoZoom zoomMove; // Current auto movement
bool flagAutoZoom; // Define if autozoom is on or off
bool flagAutoZoomOutResetsDirection;

Expand Down