fix(rendering): use separate timer for global sequence bones

Global sequence bones (hair, cape, physics) need time values spanning
their full duration (up to ~968733ms), but animationTime wraps at the
current animation's sequence duration (~2000ms for walk). This caused
vertex spikes projecting from fingers/neck/ponytail as bones got stuck
in the first ~2s of their loop. Add a separate globalSequenceTime
accumulator that is not wrapped at the animation duration.
This commit is contained in:
Kelsi 2026-04-03 22:49:33 -07:00
parent b54458fe6c
commit aeb295e0bb
2 changed files with 18 additions and 11 deletions

View file

@ -158,6 +158,7 @@ private:
uint32_t currentAnimationId = 0;
int currentSequenceIndex = -1; // Index into M2Model::sequences
float animationTime = 0.0f;
float globalSequenceTime = 0.0f; // Separate timer for global sequences (accumulates without wrapping at sequence duration)
bool animationLoop = true;
bool isDead = false; // Prevents movement while in death state
std::vector<glm::mat4> boneMatrices; // Current bone transforms
@ -206,8 +207,8 @@ private:
void calculateBindPose(M2ModelGPU& gpuModel);
void updateAnimation(CharacterInstance& instance, float deltaTime);
void calculateBoneMatrices(CharacterInstance& instance);
glm::mat4 getBoneTransform(const pipeline::M2Bone& bone, float time, int sequenceIndex,
const std::vector<uint32_t>& globalSeqDurations);
glm::mat4 getBoneTransform(const pipeline::M2Bone& bone, float animTime, float globalSeqTime,
int sequenceIndex, const std::vector<uint32_t>& globalSeqDurations);
glm::mat4 getModelMatrix(const CharacterInstance& instance) const;
void destroyModelGPU(M2ModelGPU& gpuModel, bool defer = false);
void destroyInstanceBones(CharacterInstance& inst, bool defer = false);