From 7914056f3d8d10669d46fb991ab550084c9c5b5a Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sat, 20 Jul 2024 07:34:24 -0500 Subject: [PATCH] Add Repeat button to animation mode A repeat button was added so that the loop option doesn't affect whether a played animation in the editor repeats. --- doc/html/olh_animwin.htm | 24 ++++++++++++++++-------- src/implui/animwidget.cc | 24 +++++++++++++++++++++++- src/implui/animwidget.h | 2 ++ src/libmm3d/model_anim.cc | 17 +++++++---------- src/qtui/animwidget.ui | 23 +++++++++++++++++++++++ 5 files changed, 71 insertions(+), 19 deletions(-) diff --git a/doc/html/olh_animwin.htm b/doc/html/olh_animwin.htm index 9d7ac790..35395139 100644 --- a/doc/html/olh_animwin.htm +++ b/doc/html/olh_animwin.htm @@ -122,11 +122,15 @@

FPS Text Box

Loop Checkbox

- The Loop Checkbox will change whether the current animation loops when it - completes or not. If the animation completes and the Loop Checkbox - is checked, the animation will restart from the first frame. If the animation - completes and the Loop Checkbox is not checked, the animation - will stop. + The Loop Checkbox is used to mark that the animation is intend to repeat + and to interpolate skeletal joints around ends of the animation. + However it does not affect playing the animation in Maverick. + The Repeat button is used to view the animation playing continuously. +

+ +

+ Animations with loop checked are marked as repeating when exported to + MD3 animations.cfg and IQE format.

@@ -163,7 +167,7 @@

Previous

Play / Pause

- The Play button runs the current animation at its specified + The Play button runs the current animation once at its specified frame rate. The Play button becomes a Pause during playback so that you can pause an animation and resume it later. Paused animations resume from the time at which they were paused. @@ -171,8 +175,6 @@

Play / Pause

Use the Stop button to stop an animation completely. - Use the Loop Checkbox to control whether the animation should - start from the beginning again when it completes.

@@ -181,6 +183,12 @@

Play / Pause

reasons, and may become a configurable option at a later time.

+

Repeat

+ +

+ The Repeat button will play the animation and continuously repeat it. +

+

Stop

diff --git a/src/implui/animwidget.cc b/src/implui/animwidget.cc index 4790e834..fe5fecf1 100644 --- a/src/implui/animwidget.cc +++ b/src/implui/animwidget.cc @@ -619,6 +619,21 @@ void AnimWidget::nextClicked() void AnimWidget::playClicked() { + m_repeating = false; + if ( m_playing ) + { + doPause(); + } + else + { + doPlay(); + } + m_stop->setEnabled( true ); +} + +void AnimWidget::repeatClicked() +{ + m_repeating = true; if ( m_playing ) { doPause(); @@ -635,6 +650,7 @@ void AnimWidget::stopClicked() m_currentTime = 0; m_stop->setEnabled( false ); m_play->setEnabled(true); + m_repeat->setEnabled(true); m_previous->setEnabled(true); m_next->setEnabled(true); m_frameCount->setEnabled(true); @@ -666,6 +682,7 @@ void AnimWidget::doPlay() return; } m_play->setEnabled(false); + m_repeat->setEnabled(false); m_previous->setEnabled(false); m_next->setEnabled(false); m_frameCount->setEnabled(false); @@ -687,6 +704,7 @@ void AnimWidget::doPause() { m_playing = false; m_play->setEnabled(true); + m_repeat->setEnabled(true); m_animTimer->stop(); } @@ -697,7 +715,7 @@ void AnimWidget::timeElapsed() unsigned t = (tv.tv_sec - m_startTime.tv_sec) * 1000 + (tv.tv_msec - m_startTime.tv_msec); m_currentTime = ((double) t) / 1000.0; - if ( m_model->setCurrentAnimationTime( m_currentTime ) ) + if ( m_model->setCurrentAnimationTime( m_currentTime ) || m_repeating ) { //log_debug( "animation time: %f (%d)\n", m_currentTime, t ); } @@ -812,6 +830,7 @@ void AnimWidget::refreshPage() m_fps->setEnabled( true ); m_animName->setEnabled( true ); m_play->setEnabled( true ); + m_repeat->setEnabled( true ); m_loop->setEnabled( true ); unsigned count = m_model->getAnimFrameCount( mode, index ); @@ -842,6 +861,7 @@ void AnimWidget::refreshPage() m_previous->setEnabled( false ); m_next->setEnabled( false ); m_play->setEnabled( false ); + m_repeat->setEnabled( false ); m_stop->setEnabled( false ); m_loop->setEnabled( false ); @@ -879,6 +899,7 @@ void AnimWidget::refreshPage() } m_fps->setEnabled( true ); m_play->setEnabled( true ); + m_repeat->setEnabled( true ); m_stop->setEnabled( true ); m_loop->setEnabled( true ); } @@ -891,6 +912,7 @@ void AnimWidget::refreshPage() m_previous->setEnabled( false ); m_next->setEnabled( false ); m_play->setEnabled( false ); + m_repeat->setEnabled( false ); m_stop->setEnabled( false ); m_loop->setEnabled( false ); diff --git a/src/implui/animwidget.h b/src/implui/animwidget.h index 823a28d9..da2de00e 100644 --- a/src/implui/animwidget.h +++ b/src/implui/animwidget.h @@ -68,6 +68,7 @@ class AnimWidget : public QWidget, public Ui::AnimWidgetBase void previousClicked(); void nextClicked(); void playClicked(); + void repeatClicked(); void stopClicked(); void loopToggled(bool); @@ -90,6 +91,7 @@ class AnimWidget : public QWidget, public Ui::AnimWidgetBase Model * m_model; bool m_playing; + bool m_repeating; double m_timeInterval; double m_currentTime; unsigned m_skelAnimCount; diff --git a/src/libmm3d/model_anim.cc b/src/libmm3d/model_anim.cc index e2435f43..ab79a865 100644 --- a/src/libmm3d/model_anim.cc +++ b/src/libmm3d/model_anim.cc @@ -1832,6 +1832,7 @@ bool Model::setCurrentAnimationTime( double frameTime ) } size_t totalFrames = m_frameAnims[m_currentAnim]->m_frameData.size(); + bool rtnval = true; if ( totalFrames > 0 ) { @@ -1839,10 +1840,7 @@ bool Model::setCurrentAnimationTime( double frameTime ) double totalTime = spf * m_frameAnims[m_currentAnim]->m_frameData.size(); while ( frameTime >= totalTime ) { - if ( !m_frameAnims[m_currentAnim]->m_loop ) - { - return false; - } + rtnval = false; frameTime -= totalTime; } m_currentFrame = (unsigned) (frameTime / spf); @@ -1856,22 +1854,21 @@ bool Model::setCurrentAnimationTime( double frameTime ) m_currentTime = frameTime; updateObservers(); - return true; + return rtnval; } else if ( m_animationMode == ANIMMODE_SKELETAL && m_currentAnim < m_skelAnims.size() && m_skelAnims[m_currentAnim]->m_frameCount > 0 ) { LOG_PROFILE(); + bool rtnval = true; + SkelAnim * sa = m_skelAnims[m_currentAnim]; if ( sa->m_frameCount > 0 ) { double totalTime = sa->m_spf * sa->m_frameCount; while ( frameTime > totalTime ) { - if ( !sa->m_loop ) - { - return false; - } + rtnval = false; frameTime -= totalTime; } } @@ -2161,7 +2158,7 @@ bool Model::setCurrentAnimationTime( double frameTime ) } updateObservers(); - return true; + return rtnval; } else { diff --git a/src/qtui/animwidget.ui b/src/qtui/animwidget.ui index 194bc3c0..411bf6e9 100644 --- a/src/qtui/animwidget.ui +++ b/src/qtui/animwidget.ui @@ -201,6 +201,13 @@ + + + + Repeat + + + @@ -321,6 +328,22 @@ + + m_repeat + clicked() + AnimWidgetBase + repeatClicked() + + + 20 + 20 + + + 20 + 20 + + + m_stop clicked()