Skip to content

Commit 9af3d54

Browse files
committed
Fix Decoupled Animation Crash, Interpolation Bugs, Simplify Interpolation code
1 parent 1c3764e commit 9af3d54

File tree

3 files changed

+50
-30
lines changed

3 files changed

+50
-30
lines changed

src/common/models/models_iqm.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -599,14 +599,14 @@ const TArray<VSMatrix> IQMModel::CalculateBones(int frame1, int frame2, float in
599599

600600
if(frame1 >= 0 && (frame1_prev >= 0 || inter1_prev < 0))
601601
{
602-
prev = inter1_prev < 0 ? animationFrames[offset1 + i] : InterpolateBone(animationFrames[offset1_1 + i], animationFrames[offset1 + i], inter1_prev, invt1);
602+
prev = inter1_prev <= 0 ? animationFrames[offset1 + i] : InterpolateBone(animationFrames[offset1_1 + i], animationFrames[offset1 + i], inter1_prev, invt1);
603603
}
604604

605605
TRS next;
606606

607607
if(frame2 >= 0 && (frame2_prev >= 0 || inter2_prev < 0))
608608
{
609-
next = inter2_prev < 0 ? animationFrames[offset2 + i] : InterpolateBone(animationFrames[offset2_1 + i], animationFrames[offset2 + i], inter2_prev, invt2);
609+
next = inter2_prev <= 0 ? animationFrames[offset2 + i] : InterpolateBone(animationFrames[offset2_1 + i], animationFrames[offset2 + i], inter2_prev, invt2);
610610
}
611611

612612
TRS bone;

src/playsim/p_actionfunctions.cpp

+15-13
Original file line numberDiff line numberDiff line change
@@ -5128,6 +5128,8 @@ enum ESetAnimationFlags
51285128
SAF_NOOVERRIDE = 1 << 2,
51295129
};
51305130

5131+
extern double getCurrentFrame(const AnimOverride &anim, double tic);
5132+
51315133
void SetAnimationInternal(AActor * self, FName animName, double framerate, int startFrame, int loopFrame, int endFrame, int interpolateTics, int flags, double ticFrac)
51325134
{
51335135
if(!self) ThrowAbortException(X_READ_NIL, "In function parameter self");
@@ -5152,11 +5154,6 @@ void SetAnimationInternal(AActor * self, FName animName, double framerate, int s
51525154
return;
51535155
}
51545156

5155-
if(!(flags & SAF_INSTANT))
5156-
{
5157-
self->modelData->prevAnim = self->modelData->curAnim;
5158-
}
5159-
51605157
double tic = self->Level->totaltime;
51615158
if ((ConsoleState == c_up || ConsoleState == c_rising) && (menuactive == MENU_Off || menuactive == MENU_OnNoPause) && !self->Level->isFrozen())
51625159
{
@@ -5179,6 +5176,11 @@ void SetAnimationInternal(AActor * self, FName animName, double framerate, int s
51795176
return;
51805177
}
51815178

5179+
if(!(flags & SAF_INSTANT))
5180+
{
5181+
self->modelData->prevAnim = self->modelData->curAnim;
5182+
}
5183+
51825184
int animEnd = mdl->FindLastFrame(animName);
51835185

51845186
if(framerate < 0)
@@ -5217,6 +5219,8 @@ void SetAnimationInternal(AActor * self, FName animName, double framerate, int s
52175219

52185220
if(!(flags & SAF_INSTANT))
52195221
{
5222+
self->modelData->prevAnim.startFrame = getCurrentFrame(self->modelData->prevAnim, tic);
5223+
52205224
self->modelData->curAnim.startTic = floor(tic) + interpolateTics;
52215225
}
52225226
else
@@ -5235,8 +5239,6 @@ void SetAnimationUINative(AActor * self, int i_animName, double framerate, int s
52355239
SetAnimationInternal(self, FName(ENamedName(i_animName)), framerate, startFrame, loopFrame, endFrame, interpolateTics, flags, I_GetTimeFrac());
52365240
}
52375241

5238-
extern double getCurrentFrame(const AnimOverride &anim, double tic);
5239-
52405242
void SetAnimationFrameRateInternal(AActor * self, double framerate, double ticFrac)
52415243
{
52425244
if(!self) ThrowAbortException(X_READ_NIL, "In function parameter self");
@@ -5256,18 +5258,18 @@ void SetAnimationFrameRateInternal(AActor * self, double framerate, double ticFr
52565258
}
52575259

52585260

5259-
if(self->modelData->curAnim.startTic < ticFrac)
5260-
{
5261-
self->modelData->curAnim.framerate = (float)framerate;
5262-
return;
5263-
}
5264-
52655261
double tic = self->Level->totaltime;
52665262
if ((ConsoleState == c_up || ConsoleState == c_rising) && (menuactive == MENU_Off || menuactive == MENU_OnNoPause) && !self->Level->isFrozen())
52675263
{
52685264
tic += ticFrac;
52695265
}
52705266

5267+
if(self->modelData->curAnim.startTic >= tic)
5268+
{
5269+
self->modelData->curAnim.framerate = (float)framerate;
5270+
return;
5271+
}
5272+
52715273
double frame = getCurrentFrame(self->modelData->curAnim, tic);
52725274

52735275
self->modelData->curAnim.startFrame = frame;

src/r_data/models.cpp

+33-15
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,18 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
323323
if(actor->modelData->curAnim.startTic > tic)
324324
{
325325
inter = (tic - actor->modelData->curAnim.switchTic) / (actor->modelData->curAnim.startTic - actor->modelData->curAnim.switchTic);
326-
327-
calcFrame(actor->modelData->curAnim, actor->modelData->curAnim.startTic, inter_next, decoupled_next_prev_frame, decoupled_next_frame);
328-
calcFrame(actor->modelData->prevAnim, actor->modelData->curAnim.switchTic, inter_main, decoupled_main_prev_frame, decoupled_main_frame);
326+
327+
double nextFrame = actor->modelData->curAnim.startFrame;
328+
329+
double prevFrame = actor->modelData->prevAnim.startFrame;
330+
331+
decoupled_next_prev_frame = floor(nextFrame);
332+
decoupled_next_frame = ceil(nextFrame);
333+
inter_next = nextFrame - floor(nextFrame);
334+
335+
decoupled_main_prev_frame = floor(prevFrame);
336+
decoupled_main_frame = ceil(prevFrame);
337+
inter_main = prevFrame - floor(prevFrame);
329338
}
330339
else
331340
{
@@ -1073,22 +1082,31 @@ void ParseModelDefLump(int Lump)
10731082

10741083
FSpriteModelFrame * FindModelFrameRaw(const PClass * ti, int sprite, int frame, bool dropped)
10751084
{
1076-
if (GetDefaultByType(ti)->hasmodel)
1085+
auto def = GetDefaultByType(ti);
1086+
if (def->hasmodel)
10771087
{
1078-
FSpriteModelFrame smf;
1088+
if(def->flags9 & MF9_DECOUPLEDANIMATIONS)
1089+
{
1090+
FSpriteModelFrame * smf = BaseSpriteModelFrames.CheckKey((void*)ti);
1091+
if(smf) return smf;
1092+
}
1093+
else
1094+
{
1095+
FSpriteModelFrame smf;
10791096

1080-
memset(&smf, 0, sizeof(smf));
1081-
smf.type=ti;
1082-
smf.sprite=sprite;
1083-
smf.frame=frame;
1097+
memset(&smf, 0, sizeof(smf));
1098+
smf.type=ti;
1099+
smf.sprite=sprite;
1100+
smf.frame=frame;
10841101

1085-
int hash = SpriteModelHash[ModelFrameHash(&smf) % SpriteModelFrames.Size()];
1102+
int hash = SpriteModelHash[ModelFrameHash(&smf) % SpriteModelFrames.Size()];
10861103

1087-
while (hash>=0)
1088-
{
1089-
FSpriteModelFrame * smff = &SpriteModelFrames[hash];
1090-
if (smff->type==ti && smff->sprite==sprite && smff->frame==frame) return smff;
1091-
hash=smff->hashnext;
1104+
while (hash>=0)
1105+
{
1106+
FSpriteModelFrame * smff = &SpriteModelFrames[hash];
1107+
if (smff->type==ti && smff->sprite==sprite && smff->frame==frame) return smff;
1108+
hash=smff->hashnext;
1109+
}
10921110
}
10931111
}
10941112

0 commit comments

Comments
 (0)