From ce3617100017fff1986c8cbb139ab991beb5d78c Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 11 Mar 2026 01:35:37 -0700 Subject: [PATCH] fix: prefer variationIndex=0 run animation and silence spurious compositeWithRegions warns - character_renderer: playAnimation now prefers the primary variation (variationIndex==0) when multiple sequences share the same animation ID; this fixes hitching on human female run where a variation sequence was selected first before the base cycle - character_renderer: move the compositeWithRegions size-mismatch warning inside the else branch so it only fires when sizes genuinely don't match, not for every successful 1:1 or scaled blit --- src/rendering/character_renderer.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/rendering/character_renderer.cpp b/src/rendering/character_renderer.cpp index 5683af91..82e4ff89 100644 --- a/src/rendering/character_renderer.cpp +++ b/src/rendering/character_renderer.cpp @@ -1327,12 +1327,12 @@ VkTexture* CharacterRenderer::compositeWithRegions(const std::string& basePath, blitOverlay(composite, width, height, overlay, dstX, dstY); } } else { + // Size mismatch — blit at natural size (may clip or leave gap) + core::Logger::getInstance().warning("compositeWithRegions: region ", regionIdx, + " at (", dstX, ",", dstY, ") overlay=", overlay.width, "x", overlay.height, + " expected=", expectedW, "x", expectedH, " from ", rl.second); blitOverlay(composite, width, height, overlay, dstX, dstY); } - - core::Logger::getInstance().warning("compositeWithRegions: region ", regionIdx, - " at (", dstX, ",", dstY, ") overlay=", overlay.width, "x", overlay.height, - " expected=", expectedW, "x", expectedH, " from ", rl.second); } // Upload to GPU via VkTexture @@ -1580,12 +1580,20 @@ void CharacterRenderer::playAnimation(uint32_t instanceId, uint32_t animationId, instance.animationTime = 0.0f; instance.animationLoop = loop; + // Prefer variationIndex==0 (primary animation); fall back to first match + int firstMatch = -1; for (size_t i = 0; i < model.sequences.size(); i++) { if (model.sequences[i].id == animationId) { - instance.currentSequenceIndex = static_cast(i); - break; + if (firstMatch < 0) firstMatch = static_cast(i); + if (model.sequences[i].variationIndex == 0) { + instance.currentSequenceIndex = static_cast(i); + break; + } } } + if (instance.currentSequenceIndex < 0 && firstMatch >= 0) { + instance.currentSequenceIndex = firstMatch; + } if (instance.currentSequenceIndex < 0) { // Fall back to first sequence