Surfaceskin modification

- Made it so when rendering a model, it clones an smf to use so that data isn't overwritten
- Reimplemented the skin index property. This changes the behavior of this index if CMDL_USESURFACESKIN is activated
This commit is contained in:
Shiny Metagross 2022-07-05 13:29:47 -07:00 committed by Christoph Oelckers
commit 69ee1eb0a2
7 changed files with 62 additions and 27 deletions

View file

@ -55,7 +55,7 @@ EXTERN_CVAR (Bool, r_drawvoxels)
extern TDeletingArray<FVoxel *> Voxels;
extern TDeletingArray<FVoxelDef *> VoxelDefs;
void RenderFrameModels(FModelRenderer* renderer, FLevelLocals* Level, const FSpriteModelFrame* smf, const FState* curState, const int curTics, const PClass* ti, int translation, AActor* actor);
void RenderFrameModels(FModelRenderer* renderer, FLevelLocals* Level, const FSpriteModelFrame *smf, const FState* curState, const int curTics, const PClass* ti, int translation, AActor* actor);
void RenderModel(FModelRenderer *renderer, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor, double ticFrac)
@ -230,11 +230,13 @@ void RenderHUDModel(FModelRenderer *renderer, DPSprite *psp, float ofsX, float o
void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, int translation, AActor* actor)
{
//[SM] - Create a temporary sprite model frame, which prevents data from being overwritten
FSpriteModelFrame* tempsmf = new FSpriteModelFrame(*smf);
// [BB] Frame interpolation: Find the FSpriteModelFrame smfNext which follows after smf in the animation
// and the scalar value inter ( element of [0,1) ), both necessary to determine the interpolated frame.
FSpriteModelFrame * smfNext = nullptr;
double inter = 0.;
if (gl_interpolate_model_frames && !(smf->flags & MDL_NOINTERPOLATION))
if (gl_interpolate_model_frames && !(tempsmf->flags & MDL_NOINTERPOLATION))
{
FState *nextState = curState->GetNextState();
if (curState != nextState && nextState)
@ -256,7 +258,7 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
{
// [BB] Workaround for actors that use the same frame twice in a row.
// Most of the standard Doom monsters do this in their see state.
if ((smf->flags & MDL_INTERPOLATEDOUBLEDFRAMES))
if ((tempsmf->flags & MDL_INTERPOLATEDOUBLEDFRAMES))
{
const FState *prevState = curState - 1;
if ((curState->sprite == prevState->sprite) && (curState->Frame == prevState->Frame))
@ -276,36 +278,41 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
}
}
//[SM] - these temporary arrays prevent actual smf data from being overwritten, which was the source of my problems
TArray<int> tempModelIDs = smf->modelIDs;
TArray<FTextureID> tempSkinIDs = smf->skinIDs;
for (int i = 0; i < smf->modelsAmount; i++)
for (int i = 0; i < tempsmf->modelsAmount; i++)
{
if (actor->modelData != nullptr)
{
if (i < (int)actor->modelData->modelIDs.Size())
{
if(actor->modelData->modelIDs[i] != -1)
tempModelIDs[i] = actor->modelData->modelIDs[i];
tempsmf->modelIDs[i] = actor->modelData->modelIDs[i];
}
if (i < (int)actor->modelData->skinIDs.Size())
{
if (actor->modelData->skinIDs[i].isValid())
tempSkinIDs[i] = actor->modelData->skinIDs[i];
tempsmf->skinIDs[i] = actor->modelData->skinIDs[i];
}
for (int surface = i * MD3_MAX_SURFACES; surface < (i + 1) * MD3_MAX_SURFACES; surface++)
{
if (surface < (int)actor->modelData->surfaceSkinIDs.Size())
{
if (actor->modelData->surfaceSkinIDs[surface].isValid())
tempsmf->surfaceskinIDs[surface] = actor->modelData->surfaceSkinIDs[surface];
}
}
}
if (tempModelIDs[i] >= 0)
if (tempsmf->modelIDs[i] >= 0)
{
FModel * mdl = Models[tempModelIDs[i]];
auto tex = tempSkinIDs[i].isValid() ? TexMan.GetGameTexture(tempSkinIDs[i], true) : nullptr;
FModel * mdl = Models[tempsmf->modelIDs[i]];
auto tex = tempsmf->skinIDs[i].isValid() ? TexMan.GetGameTexture(tempsmf->skinIDs[i], true) : nullptr;
mdl->BuildVertexBuffer(renderer);
mdl->PushSpriteMDLFrame(smf, i);
mdl->PushSpriteMDLFrame(tempsmf, i);
if (smfNext && smf->modelframes[i] != smfNext->modelframes[i])
mdl->RenderFrame(renderer, tex, smf->modelframes[i], smfNext->modelframes[i], inter, translation);
if (smfNext && tempsmf->modelframes[i] != smfNext->modelframes[i])
mdl->RenderFrame(renderer, tex, tempsmf->modelframes[i], smfNext->modelframes[i], inter, translation);
else
mdl->RenderFrame(renderer, tex, smf->modelframes[i], smf->modelframes[i], 0.f, translation);
mdl->RenderFrame(renderer, tex, tempsmf->modelframes[i], tempsmf->modelframes[i], 0.f, translation);
}
}
}