Skip to content

Commit

Permalink
replace naive interpolation logic with more exact logic
Browse files Browse the repository at this point in the history
  • Loading branch information
RicardoLuis0 committed Sep 11, 2024
1 parent aacc4d7 commit 7f9cf48
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/playsim/actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -702,8 +702,8 @@ enum EViewPosFlags // [MC] Flags for SetViewPos.

enum EAnimOverrideFlags
{
ANIMOVERRIDE_NONE = 1 << 0, // no animation
ANIMOVERRIDE_LOOP = 1 << 1, // animation loops, otherwise it stays on the last frame once it ends
ANIMOVERRIDE_NONE = 1 << 0, // no animation
ANIMOVERRIDE_LOOP = 1 << 1, // animation loops, otherwise it stays on the last frame once it ends
};

struct AnimOverride
Expand Down
12 changes: 9 additions & 3 deletions src/playsim/p_actionfunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5128,7 +5128,7 @@ enum ESetAnimationFlags
SAF_NOOVERRIDE = 1 << 2,
};

extern double getCurrentFrame(const AnimOverride &anim, double tic);
extern double getCurrentFrame(const AnimOverride &anim, double tic, bool *looped);

void SetAnimationInternal(AActor * self, FName animName, double framerate, int startFrame, int loopFrame, int endFrame, int interpolateTics, int flags, double ticFrac)
{
Expand Down Expand Up @@ -5218,7 +5218,13 @@ void SetAnimationInternal(AActor * self, FName animName, double framerate, int s

if(!(flags & SAF_INSTANT))
{
self->modelData->prevAnim.startFrame = getCurrentFrame(self->modelData->prevAnim, tic);
bool looped = false;
self->modelData->prevAnim.startFrame = getCurrentFrame(self->modelData->prevAnim, tic, &looped);

if(!looped)
{
self->modelData->prevAnim.flags &= ~ANIMOVERRIDE_LOOP;
}

int startTic = floor(tic) + interpolateTics;
self->modelData->curAnim.startTic = startTic;
Expand Down Expand Up @@ -5272,7 +5278,7 @@ void SetAnimationFrameRateInternal(AActor * self, double framerate, double ticFr
return;
}

double frame = getCurrentFrame(self->modelData->curAnim, tic);
double frame = getCurrentFrame(self->modelData->curAnim, tic, nullptr);

self->modelData->curAnim.startFrame = frame;
self->modelData->curAnim.startTic = tic;
Expand Down
33 changes: 18 additions & 15 deletions src/r_data/models.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ void RenderHUDModel(FModelRenderer *renderer, DPSprite *psp, FVector3 translatio
renderer->EndDrawHUDModel(playermo->RenderStyle, smf_flags);
}

double getCurrentFrame(const AnimOverride &anim, double tic)
double getCurrentFrame(const AnimOverride &anim, double tic, bool *looped)
{
if(anim.framerate <= 0) return anim.startFrame;

Expand All @@ -268,6 +268,7 @@ double getCurrentFrame(const AnimOverride &anim, double tic)

if((anim.flags & ANIMOVERRIDE_LOOP) && frame >= duration)
{
if(looped) *looped = true;
frame = frame - duration;
return fmod(frame, anim.lastFrame - anim.loopFrame) + anim.loopFrame;
}
Expand All @@ -277,15 +278,26 @@ double getCurrentFrame(const AnimOverride &anim, double tic)
}
}

static void calcFrame(const AnimOverride &anim, double tic, double &inter, int &prev, int &next)
static void fixFrame(const AnimOverride &anim, double frame, double &inter, int &prev, int &next, bool looped)
{
double frame = getCurrentFrame(anim, tic);

prev = int(floor(frame));

int startFrame = (looped ? anim.startFrame : anim.loopFrame);

if(prev < startFrame) prev = anim.lastFrame;

inter = frame - prev;

next = int(ceil(frame));

if(next > anim.lastFrame) next = startFrame;
}

static void calcFrame(const AnimOverride &anim, double tic, double &inter, int &prev, int &next)
{
bool looped = false;
double frame = getCurrentFrame(anim, tic, &looped);
fixFrame(anim, frame, inter, prev, next, looped);
}

void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpriteModelFrame *smf, const FState *curState, const int curTics, FTranslationID translation, AActor* actor)
Expand Down Expand Up @@ -325,17 +337,8 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
{
inter = (tic - (actor->modelData->curAnim.startTic - actor->modelData->curAnim.switchOffset)) / actor->modelData->curAnim.switchOffset;

double nextFrame = actor->modelData->curAnim.startFrame;

double prevFrame = actor->modelData->prevAnim.startFrame;

decoupled_next_prev_frame = floor(nextFrame);
decoupled_next_frame = ceil(nextFrame);
inter_next = nextFrame - floor(nextFrame);

decoupled_main_prev_frame = floor(prevFrame);
decoupled_main_frame = ceil(prevFrame);
inter_main = prevFrame - floor(prevFrame);
fixFrame(actor->modelData->curAnim, actor->modelData->curAnim.startFrame, inter_next, decoupled_next_prev_frame, decoupled_next_frame, false);
fixFrame(actor->modelData->prevAnim, actor->modelData->prevAnim.startFrame, inter_main, decoupled_main_prev_frame, decoupled_main_frame, actor->modelData->prevAnim.flags & ANIMOVERRIDE_LOOP);
}
else
{
Expand Down

0 comments on commit 7f9cf48

Please sign in to comment.