This commit is contained in:
nashmuhandes 2024-09-24 15:31:08 +08:00
commit 1fae4b9d4a
27 changed files with 714 additions and 116 deletions

View file

@ -275,7 +275,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 ModelAnim &anim, double tic, bool *looped)
{
if(anim.framerate <= 0) return anim.startFrame;
@ -283,8 +283,9 @@ double getCurrentFrame(const AnimOverride &anim, double tic)
double duration = double(anim.lastFrame) - anim.startFrame;
if((anim.flags & ANIMOVERRIDE_LOOP) && frame >= duration)
if((anim.flags & MODELANIM_LOOP) && frame >= duration)
{
if(looped) *looped = true;
frame = frame - duration;
return fmod(frame, anim.lastFrame - anim.loopFrame) + anim.loopFrame;
}
@ -294,15 +295,37 @@ double getCurrentFrame(const AnimOverride &anim, double tic)
}
}
static void calcFrame(const AnimOverride &anim, double tic, double &inter, int &prev, int &next)
void calcFrame(const ModelAnim &anim, double tic, ModelAnimFrameInterp &inter)
{
double frame = getCurrentFrame(anim, tic);
bool looped = false;
prev = int(floor(frame));
double frame = getCurrentFrame(anim, tic, &looped);
inter = frame - prev;
inter.frame1 = int(floor(frame));
next = int(ceil(frame));
inter.inter = frame - inter.frame1;
inter.frame2 = int(ceil(frame));
int startFrame = (looped ? anim.loopFrame : anim.startFrame);
if(inter.frame1 < startFrame) inter.frame1 = anim.lastFrame;
if(inter.frame2 > anim.lastFrame) inter.frame2 = startFrame;
}
void calcFrames(const ModelAnim &curAnim, double tic, ModelAnimFrameInterp &to, float &inter)
{
if(curAnim.startTic > tic)
{
inter = (tic - (curAnim.startTic - curAnim.switchOffset)) / curAnim.switchOffset;
calcFrame(curAnim, curAnim.startTic, to);
}
else
{
inter = -1.0f;
calcFrame(curAnim, tic, to);
}
}
void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpriteModelFrame *smf, const FState *curState, const int curTics, FTranslationID translation, AActor* actor)
@ -313,17 +336,11 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
int smf_flags = smf->getFlags(actor->modelData);
const FSpriteModelFrame * smfNext = nullptr;
double inter = 0.;
double inter_main = -1.f;
double inter_next = -1.f;
float inter = 0.;
bool is_decoupled = (actor->flags9 & MF9_DECOUPLEDANIMATIONS);
int decoupled_main_prev_frame = -1;
int decoupled_next_prev_frame = -1;
int decoupled_main_frame = -1;
int decoupled_next_frame = -1;
ModelAnimFrameInterp decoupled_frame;
// if prev_frame == -1: interpolate(main_frame, next_frame, inter), else: interpolate(interpolate(main_prev_frame, main_frame, inter_main), interpolate(next_prev_frame, next_frame, inter_next), inter)
// 4-way interpolation is needed to interpolate animation switches between animations that aren't 35hz
@ -331,33 +348,15 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
if(is_decoupled)
{
smfNext = smf = &BaseSpriteModelFrames[actor->GetClass()];
if(actor->modelData && !(actor->modelData->curAnim.flags & ANIMOVERRIDE_NONE))
if(actor->modelData && !(actor->modelData->curAnim.flags & MODELANIM_NONE))
{
double tic = actor->Level->totaltime;
if ((ConsoleState == c_up || ConsoleState == c_rising) && (menuactive == MENU_Off || menuactive == MENU_OnNoPause) && !actor->isFrozen())
{
tic += I_GetTimeFrac();
}
if(actor->modelData->curAnim.startTic > tic)
{
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);
}
else
{
calcFrame(actor->modelData->curAnim, tic, inter, decoupled_main_frame, decoupled_next_frame);
}
calcFrames(actor->modelData->curAnim, tic, decoupled_frame, inter);
}
}
else if (gl_interpolate_model_frames && !(smf_flags & MDL_NOINTERPOLATION))
@ -548,43 +547,30 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
}
// [RL0] while per-model animations aren't done, DECOUPLEDANIMATIONS does the same as MODELSAREATTACHMENTS
if ((!(smf_flags & MDL_MODELSAREATTACHMENTS) && !is_decoupled) || !evaluatedSingle)
if(!evaluatedSingle)
{
FModel* animation = mdl;
const TArray<TRS>* animationData = nullptr;
if (animationid >= 0)
{
FModel* animation = Models[animationid];
animation = Models[animationid];
const TArray<TRS>* animationData = animation->AttachAnimationData();
}
if(is_decoupled)
if(is_decoupled)
{
if(decoupled_frame.frame1 != -1)
{
if(decoupled_main_frame != -1)
{
boneData = animation->CalculateBones(decoupled_main_frame, decoupled_next_frame, inter, decoupled_main_prev_frame, inter_main, decoupled_next_prev_frame, inter_next, animationData, actor->boneComponentData, i);
}
boneData = animation->CalculateBones(actor->modelData->prevAnim, decoupled_frame, inter, animationData, actor->boneComponentData, i);
}
else
{
boneData = animation->CalculateBones(modelframe, modelframenext, nextFrame ? inter : -1.f, 0, -1.f, 0, -1.f, animationData, actor->boneComponentData, i);
}
boneStartingPosition = renderer->SetupFrame(animation, 0, 0, 0, boneData, -1);
evaluatedSingle = true;
}
else
{
if(is_decoupled)
{
if(decoupled_main_frame != -1)
{
boneData = mdl->CalculateBones(decoupled_main_frame, decoupled_next_frame, inter, decoupled_main_prev_frame, inter_main, decoupled_next_prev_frame, inter_next, nullptr, actor->boneComponentData, i);
}
}
else
{
boneData = mdl->CalculateBones(modelframe, modelframenext, nextFrame ? inter : -1.f, 0, -1.f, 0, -1.f, nullptr, actor->boneComponentData, i);
}
boneStartingPosition = renderer->SetupFrame(mdl, 0, 0, 0, boneData, -1);
evaluatedSingle = true;
boneData = animation->CalculateBones(nullptr, {nextFrame ? inter : -1.0f, modelframe, modelframenext}, -1.0f, animationData, actor->boneComponentData, i);
}
boneStartingPosition = renderer->SetupFrame(animation, 0, 0, 0, boneData, -1);
evaluatedSingle = (smf_flags & MDL_MODELSAREATTACHMENTS) || is_decoupled;
}
mdl->RenderFrame(renderer, tex, modelframe, nextFrame ? modelframenext : modelframe, nextFrame ? inter : -1.f, translation, ssidp, boneData, boneStartingPosition);