Improve particle system animation driver

- Do not automatically restart particle system animation when pressing the
  restart button if the animation is paused.
- Use own QElapsedTimer in AnimationDriver and properly handle animation
  driver pausing.

Change-Id: Ic2924fb66fddffb8878625be8fa766f06219ca61
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Antti Määttä
2021-11-22 13:32:14 +02:00
parent beb167a963
commit eadc9cb0e3
4 changed files with 39 additions and 23 deletions

View File

@@ -31,8 +31,6 @@ AnimationDriver::AnimationDriver(QObject *parent)
{
setProperty("allowNegativeDelta", true);
install();
connect(this, SIGNAL(started()), this, SLOT(startTimer()));
connect(this, SIGNAL(stopped()), this, SLOT(stopTimer()));
}
AnimationDriver::~AnimationDriver()
@@ -49,10 +47,13 @@ void AnimationDriver::timerEvent(QTimerEvent *e)
// Provide same time for all users
if (m_seekerEnabled) {
m_seekerElapsed += (m_seekerPos * 100) / 30;
if (m_seekerElapsed + m_elapsed < -100) // -100 to allow small negative value
m_seekerElapsed = -m_elapsed - 100;
if (m_seekerElapsed + m_elapsed - m_pauseTime < -100) // -100 to allow small negative value
m_seekerElapsed = -(m_elapsed - m_pauseTime) - 100;
} else {
m_elapsed = QAnimationDriver::elapsed();
if (!m_elapsedTimer.isValid())
m_elapsedTimer.restart();
else
m_elapsed = m_elapsedTimer.elapsed();
}
m_delta = elapsed() - old;
advance();
@@ -75,7 +76,7 @@ void AnimationDriver::setSeekerPosition(int position)
return;
if (!m_timer.isActive())
restart();
startTimer();
m_seekerPos = position;
}

View File

@@ -27,6 +27,7 @@
#include <qabstractanimation.h>
#include <QtCore/qbasictimer.h>
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qmath.h>
class AnimationDriver : public QAnimationDriver
@@ -46,17 +47,34 @@ public:
}
void reset()
{
stop();
m_elapsedTimer.invalidate();
m_pauseBegin = 0;
m_pauseTime = 0;
m_elapsed = 0;
m_seekerElapsed = 0;
stopTimer();
}
void restart()
{
start();
m_pauseTime = 0;
m_elapsed = 0;
m_seekerElapsed = 0;
startTimer();
}
void pause()
{
m_pauseBegin = m_elapsedTimer.elapsed();
stopTimer();
}
void play()
{
if (m_elapsedTimer.isValid())
m_pauseTime += m_elapsedTimer.elapsed() - m_pauseBegin;
startTimer();
}
qint64 elapsed() const override
{
return m_elapsed + m_seekerElapsed;
return m_elapsed + m_seekerElapsed - m_pauseTime;
}
void setSeekerPosition(int position);
void setSeekerEnabled(bool enable)
@@ -79,10 +97,13 @@ private:
Q_SLOT void stopTimer();
QBasicTimer m_timer;
QElapsedTimer m_elapsedTimer;
int m_interval = 16;
int m_seekerPos = 0;
bool m_seekerEnabled = false;
qint64 m_elapsed = 0;
qint64 m_seekerElapsed = 0;
qint64 m_delta = 0;
qint64 m_pauseTime = 0;
qint64 m_pauseBegin = 0;
};

View File

@@ -2078,21 +2078,21 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
m_particleAnimationPlaying = command.isEnabled();
updatedState.insert("particlePlay", command.isEnabled());
if (m_particleAnimationPlaying) {
m_particleAnimationDriver->reset();
m_particleAnimationDriver->restart();
m_particleAnimationDriver->play();
m_particleAnimationDriver->setSeekerEnabled(false);
m_particleAnimationDriver->setSeekerPosition(0);
} else {
m_particleAnimationDriver->reset();
m_particleAnimationDriver->pause();
m_particleAnimationDriver->setSeekerEnabled(true);
}
break;
case View3DActionCommand::ParticlesRestart:
resetParticleSystem();
m_particleAnimationPlaying = true;
m_particleAnimationDriver->restart();
m_particleAnimationDriver->setSeekerEnabled(false);
m_particleAnimationDriver->setSeekerPosition(0);
if (m_particleAnimationPlaying) {
m_particleAnimationDriver->restart();
m_particleAnimationDriver->setSeekerEnabled(false);
m_particleAnimationDriver->setSeekerPosition(0);
}
break;
case View3DActionCommand::ParticlesSeek:
m_particleAnimationDriver->setSeekerPosition(static_cast<const View3DSeekActionCommand &>(command).position());

View File

@@ -305,12 +305,6 @@ void Edit3DView::createEdit3DActions()
resetPuppet();
};
SelectionContextOperation particlesRestartTrigger = [this](const SelectionContext &) {
m_particlesPlayAction->action()->setChecked(true);
if (m_seeker)
m_seeker->setEnabled(false);
};
SelectionContextOperation particlesPlayTrigger = [this](const SelectionContext &) {
if (m_seeker)
m_seeker->setEnabled(!m_particlesPlayAction->action()->isChecked());
@@ -334,7 +328,7 @@ void Edit3DView::createEdit3DActions()
QmlDesigner::Constants::EDIT3D_PARTICLES_RESTART, View3DActionCommand::ParticlesRestart,
QCoreApplication::translate("ParticlesRestartAction", "Restart Particles"),
QKeySequence(Qt::Key_E), false, false, Icons::EDIT3D_PARTICLE_RESTART.icon(),
Icons::EDIT3D_PARTICLE_RESTART.icon(), particlesRestartTrigger);
Icons::EDIT3D_PARTICLE_RESTART.icon());
m_particlesPlayAction->action()->setEnabled(particlemode);
m_particlesRestartAction->action()->setEnabled(particlemode);
m_resetAction