diff --git a/libs/viewer/include/viewer/ViewerGui.h b/libs/viewer/include/viewer/ViewerGui.h index 0130e28c766..6d6926a9aab 100644 --- a/libs/viewer/include/viewer/ViewerGui.h +++ b/libs/viewer/include/viewer/ViewerGui.h @@ -227,7 +227,7 @@ class UTILS_PUBLIC ViewerGui { */ Settings& getSettings() { return mSettings; } - void stopAnimation() { mCurrentAnimation = 0; } + void stopAnimation() { mCurrentAnimation = -1; } int getCurrentCamera() const { return mCurrentCamera; } @@ -256,7 +256,7 @@ class UTILS_PUBLIC ViewerGui { std::function mCustomUI; // Properties that can be changed from the UI. - int mCurrentAnimation = 1; // It is a 1-based index and 0 means not playing animation + int mCurrentAnimation = 0; // -1 means not playing animation and count means plays all of them (0-based index) int mCurrentVariant = 0; bool mEnableWireframe = false; int mVsmMsaaSamplesLog2 = 1; @@ -276,7 +276,7 @@ class UTILS_PUBLIC ViewerGui { // Cross fade animation parameters. float mCrossFadeDuration = 0.5f; // number of seconds to transition between animations - int mPreviousAnimation = 0; // one-based index of the previous animation + int mPreviousAnimation = -1; // zero-based index of the previous animation double mCurrentStartTime = 0.0f; // start time of most recent cross-fade (seconds) double mPreviousStartTime = 0.0f; // start time of previous cross-fade (seconds) bool mResetAnimation = true; // set when building ImGui widgets, honored in applyAnimation diff --git a/libs/viewer/src/ViewerGui.cpp b/libs/viewer/src/ViewerGui.cpp index 11443516209..7d567175eb7 100644 --- a/libs/viewer/src/ViewerGui.cpp +++ b/libs/viewer/src/ViewerGui.cpp @@ -524,19 +524,25 @@ void ViewerGui::applyAnimation(double currentTime, FilamentInstance* instance) { return; } Animator& animator = *instance->getAnimator(); - const size_t numAnimations = animator.getAnimationCount(); + const size_t animationCount = animator.getAnimationCount(); if (mResetAnimation) { mPreviousStartTime = mCurrentStartTime; mCurrentStartTime = currentTime; mResetAnimation = false; } const double elapsedSeconds = currentTime - mCurrentStartTime; - if (numAnimations > 0 && mCurrentAnimation > 0) { - animator.applyAnimation(mCurrentAnimation - 1, elapsedSeconds); - if (elapsedSeconds < mCrossFadeDuration && mPreviousAnimation > 0) { + if (animationCount > 0 && mCurrentAnimation >= 0) { + if (mCurrentAnimation == animationCount) { + for (size_t i = 0; i < animationCount; i++) { + animator.applyAnimation(i, elapsedSeconds); + } + } else { + animator.applyAnimation(mCurrentAnimation, elapsedSeconds); + } + if (elapsedSeconds < mCrossFadeDuration && mPreviousAnimation >= 0 && mPreviousAnimation != animationCount) { const double previousSeconds = currentTime - mPreviousStartTime; const float lerpFactor = elapsedSeconds / mCrossFadeDuration; - animator.applyCrossFade(mPreviousAnimation - 1, previousSeconds, lerpFactor); + animator.applyCrossFade(mPreviousAnimation, previousSeconds, lerpFactor); } } if (mShowingRestPose) { @@ -1106,18 +1112,20 @@ void ViewerGui::updateUserInterface() { } Animator& animator = *mInstance->getAnimator(); - if (animator.getAnimationCount() > 0 && ImGui::CollapsingHeader("Animation")) { + const size_t animationCount = animator.getAnimationCount(); + if (animationCount > 0 && ImGui::CollapsingHeader("Animation")) { ImGui::Indent(); int selectedAnimation = mCurrentAnimation; - ImGui::RadioButton("Disable", &selectedAnimation, 0); + ImGui::RadioButton("Disable", &selectedAnimation, -1); + ImGui::RadioButton("Apply all animations", &selectedAnimation, animationCount); ImGui::SliderFloat("Cross fade", &mCrossFadeDuration, 0.0f, 2.0f, "%4.2f seconds", ImGuiSliderFlags_AlwaysClamp); - for (size_t i = 0, count = animator.getAnimationCount(); i < count; ++i) { + for (size_t i = 0; i < animationCount; ++i) { std::string label = animator.getAnimationName(i); if (label.empty()) { label = "Unnamed " + std::to_string(i); } - ImGui::RadioButton(label.c_str(), &selectedAnimation, i + 1); + ImGui::RadioButton(label.c_str(), &selectedAnimation, i); } if (selectedAnimation != mCurrentAnimation) { mPreviousAnimation = mCurrentAnimation;