From d08f3d223152e9daeac2d32ee39a36be15197715 Mon Sep 17 00:00:00 2001 From: shweet Date: Mon, 11 May 2026 15:57:07 -0400 Subject: [PATCH] touched up animation preview/timeline --- src/imgui/window/animation_preview.cpp | 46 ++++++++++++++++---------- src/imgui/window/timeline.cpp | 18 +++++++--- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/imgui/window/animation_preview.cpp b/src/imgui/window/animation_preview.cpp index 9096773..33a2719 100644 --- a/src/imgui/window/animation_preview.cpp +++ b/src/imgui/window/animation_preview.cpp @@ -380,32 +380,40 @@ namespace anm2ed::imgui auto& isSound = settings.timelineIsSound; auto& isOnlyShowLayers = settings.timelineIsOnlyShowLayers; - if (!manager.isRecording && !anm2.content.sounds.empty() && isSound) + if (!animation) { - if (auto animation = document.animation_get(); - animation && animation->triggers.isVisible && (!isOnlyShowLayers || manager.isRecording)) + playback.isPlaying = false; + playback.isFinished = false; + playback.timing_reset(); + } + else + { + if (!manager.isRecording && !anm2.content.sounds.empty() && isSound) { - if (auto trigger = animation->triggers.frame_generate(playback.time, anm2::TRIGGER); trigger.isVisible) + if (animation->triggers.isVisible && (!isOnlyShowLayers || manager.isRecording)) { - if (!trigger.soundIDs.empty()) + if (auto trigger = animation->triggers.frame_generate(playback.time, anm2::TRIGGER); trigger.isVisible) { - auto soundIndex = trigger.soundIDs.size() > 1 - ? (size_t)math::random_in_range(0.0f, (float)trigger.soundIDs.size()) - : (size_t)0; - soundIndex = std::min(soundIndex, trigger.soundIDs.size() - 1); - auto soundID = trigger.soundIDs[soundIndex]; + if (!trigger.soundIDs.empty()) + { + auto soundIndex = trigger.soundIDs.size() > 1 + ? (size_t)math::random_in_range(0.0f, (float)trigger.soundIDs.size()) + : (size_t)0; + soundIndex = std::min(soundIndex, trigger.soundIDs.size() - 1); + auto soundID = trigger.soundIDs[soundIndex]; - if (anm2.content.sounds.contains(soundID)) anm2.content.sounds[soundID].audio.play(false, mixer); + if (anm2.content.sounds.contains(soundID)) anm2.content.sounds[soundID].audio.play(false, mixer); + } } } } + + auto fps = std::max(anm2.info.fps, 1); + playback.tick(fps, animation->frameNum, (animation->isLoop || settings.playbackIsLoop) && !manager.isRecording, + deltaSeconds); + + frameTime = playback.time; } - - auto fps = std::max(anm2.info.fps, 1); - playback.tick(fps, animation->frameNum, (animation->isLoop || settings.playbackIsLoop) && !manager.isRecording, - deltaSeconds); - - frameTime = playback.time; } if (wasPlaybackPlaying && !playback.isPlaying) stop_all_sounds(); @@ -870,7 +878,9 @@ namespace anm2ed::imgui { if (!nullAnimation.isVisible || isOnlyShowLayers) continue; - auto& isShowRect = anm2.content.nulls[id].isShowRect; + auto nullInfo = anm2.content.nulls.find(id); + if (nullInfo == anm2.content.nulls.end()) continue; + auto& isShowRect = nullInfo->second.isShowRect; auto draw_null = [&](float sampleTime, const glm::mat4& sampleTransform, vec3 sampleColor, float sampleAlpha, bool isOnion) diff --git a/src/imgui/window/timeline.cpp b/src/imgui/window/timeline.cpp index 15814a3..cce6f33 100644 --- a/src/imgui/window/timeline.cpp +++ b/src/imgui/window/timeline.cpp @@ -182,7 +182,7 @@ namespace anm2ed::imgui auto frame_insert = [&](anm2::Item* item) { - if (!item) return; + if (!animation || !item) return; auto behavior = [&, item]() { @@ -229,6 +229,7 @@ namespace anm2ed::imgui auto frames_delete = [&]() { + if (!animation) return; if (auto item = animation->item_get(reference.itemType, reference.itemID); item) { for (auto it = frames.selection.rbegin(); it != frames.selection.rend(); ++it) @@ -460,6 +461,7 @@ namespace anm2ed::imgui auto copy = [&]() { + if (!animation) return; if (frames.selection.empty()) return; if (auto item = animation->item_get(reference.itemType, reference.itemID); item) @@ -486,6 +488,7 @@ namespace anm2ed::imgui auto behavior = [&]() { + if (!animation) return; if (auto item = animation->item_get(reference.itemType, reference.itemID)) { document.snapshot(localize.get(EDIT_PASTE_FRAMES)); @@ -1043,7 +1046,9 @@ namespace anm2ed::imgui for (auto& id : animation->layerOrder | std::views::reverse) { - if (!settings.timelineIsShowUnused && animation->layerAnimations[id].frames.empty()) continue; + auto item = animation->item_get(anm2::LAYER, id); + if (!item) continue; + if (!settings.timelineIsShowUnused && item->frames.empty()) continue; item_child_row(anm2::LAYER, id, index++); } @@ -1194,6 +1199,8 @@ namespace anm2ed::imgui auto frame_child = [&](anm2::Type type, int id, int& index, float width) { auto item = animation ? animation->item_get(type, id) : nullptr; + if (type != anm2::NONE && !item) return; + auto isVisible = item ? item->isVisible : false; auto& isOnlyShowLayers = settings.timelineIsOnlyShowLayers; if (isOnlyShowLayers && type != anm2::LAYER) isVisible = false; @@ -1816,7 +1823,7 @@ namespace anm2ed::imgui ImGui::SameLine(); - auto item = animation->item_get(reference.itemType, reference.itemID); + auto item = animation ? animation->item_get(reference.itemType, reference.itemID) : nullptr; ImGui::BeginDisabled(!item); { @@ -1854,7 +1861,8 @@ namespace anm2ed::imgui auto frameNum = animation ? animation->frameNum : dummy_value(); ImGui::SetNextItemWidth(widgetSize.x); if (input_int_range(localize.get(LABEL_ANIMATION_LENGTH), frameNum, anm2::FRAME_NUM_MIN, anm2::FRAME_NUM_MAX, - STEP, STEP_FAST, !animation ? ImGuiInputTextFlags_DisplayEmptyRefVal : 0)) + STEP, STEP_FAST, !animation ? ImGuiInputTextFlags_DisplayEmptyRefVal : 0) && + animation) DOCUMENT_EDIT(document, localize.get(EDIT_ANIMATION_LENGTH), Document::ANIMATIONS, animation->frameNum = frameNum); ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_ANIMATION_LENGTH)); @@ -1863,7 +1871,7 @@ namespace anm2ed::imgui auto isLoop = animation ? animation->isLoop : dummy_value(); ImGui::SetNextItemWidth(widgetSize.x); - if (ImGui::Checkbox(localize.get(LABEL_LOOP), &isLoop)) + if (ImGui::Checkbox(localize.get(LABEL_LOOP), &isLoop) && animation) DOCUMENT_EDIT(document, localize.get(EDIT_LOOP), Document::ANIMATIONS, animation->isLoop = isLoop); ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_LOOP_ANIMATION)); }