mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-21 11:31:41 +00:00
Rewrite changed model rendering code, and change how model skins are handled
This commit is contained in:
parent
b55ffdbfd3
commit
61d68eb2d6
5 changed files with 148 additions and 96 deletions
|
@ -234,6 +234,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FName &value, FName *d
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, FSoundID &sid, FSoundID *def);
|
FSerializer &Serialize(FSerializer &arc, const char *key, FSoundID &sid, FSoundID *def);
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, FString &sid, FString *def);
|
FSerializer &Serialize(FSerializer &arc, const char *key, FString &sid, FString *def);
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, NumericValue &sid, NumericValue *def);
|
FSerializer &Serialize(FSerializer &arc, const char *key, NumericValue &sid, NumericValue *def);
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, struct ModelOverride &sid, struct ModelOverride *def);
|
||||||
|
|
||||||
template <typename T/*, typename = std::enable_if_t<std::is_base_of_v<DObject, T>>*/>
|
template <typename T/*, typename = std::enable_if_t<std::is_base_of_v<DObject, T>>*/>
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, T *&value, T **)
|
FSerializer &Serialize(FSerializer &arc, const char *key, T *&value, T **)
|
||||||
|
@ -244,7 +245,6 @@ FSerializer &Serialize(FSerializer &arc, const char *key, T *&value, T **)
|
||||||
return arc;
|
return arc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T, class TT>
|
template<class T, class TT>
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, TArray<T, TT> &value, TArray<T, TT> *def)
|
FSerializer &Serialize(FSerializer &arc, const char *key, TArray<T, TT> &value, TArray<T, TT> *def)
|
||||||
{
|
{
|
||||||
|
|
|
@ -677,17 +677,22 @@ enum EViewPosFlags // [MC] Flags for SetViewPos.
|
||||||
VPSF_ABSOLUTEPOS = 1 << 2, // Use absolute position.
|
VPSF_ABSOLUTEPOS = 1 << 2, // Use absolute position.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ModelOverride
|
||||||
|
{
|
||||||
|
int modelID;
|
||||||
|
TArray<FTextureID> surfaceSkinIDs;
|
||||||
|
};
|
||||||
|
|
||||||
class DActorModelData : public DObject
|
class DActorModelData : public DObject
|
||||||
{
|
{
|
||||||
DECLARE_CLASS(DActorModelData, DObject);
|
DECLARE_CLASS(DActorModelData, DObject);
|
||||||
public:
|
public:
|
||||||
FName modelDef;
|
FName modelDef;
|
||||||
bool hasModel;
|
bool hasModel;
|
||||||
TArray<int> modelIDs;
|
TArray<ModelOverride> models;
|
||||||
TArray<FTextureID> skinIDs;
|
TArray<FTextureID> skinIDs;
|
||||||
TArray<FTextureID> surfaceSkinIDs;
|
TArray<int> animationIDs;
|
||||||
TArray<int> animationIDs;
|
TArray<int> modelFrameGenerators;
|
||||||
TArray<int> modelFrameGenerators;
|
|
||||||
|
|
||||||
DActorModelData() = default;
|
DActorModelData() = default;
|
||||||
virtual void Serialize(FSerializer& arc) override;
|
virtual void Serialize(FSerializer& arc) override;
|
||||||
|
|
|
@ -5158,18 +5158,16 @@ void ChangeModelNative(
|
||||||
GC::WriteBarrier(mobj, ptr);
|
GC::WriteBarrier(mobj, ptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned skinPosition = skinindex + modelindex * MD3_MAX_SURFACES;
|
|
||||||
|
|
||||||
int queryModel = !(flags & CMDL_HIDEMODEL) ? model != NAME_None ? FindModel(modelpath.GetChars(), model.GetChars()) : -1 : -2;
|
int queryModel = !(flags & CMDL_HIDEMODEL) ? model != NAME_None ? FindModel(modelpath.GetChars(), model.GetChars()) : -1 : -2;
|
||||||
int queryAnimation = animation != NAME_None ? FindModel(animationpath.GetChars(), animation.GetChars()) : -1;
|
int queryAnimation = animation != NAME_None ? FindModel(animationpath.GetChars(), animation.GetChars()) : -1;
|
||||||
|
|
||||||
mobj->modelData->modelDef = modeldef;
|
mobj->modelData->modelDef = modeldef;
|
||||||
|
|
||||||
assert(mobj->modelData->modelIDs.Size() == mobj->modelData->modelFrameGenerators.Size());
|
assert(mobj->modelData->models.Size() == mobj->modelData->modelFrameGenerators.Size());
|
||||||
|
|
||||||
if(mobj->modelData->modelIDs.Size() < modelindex)
|
if(mobj->modelData->models.Size() < modelindex)
|
||||||
{
|
{
|
||||||
mobj->modelData->modelIDs.AppendFill(-1, modelindex - mobj->modelData->modelIDs.Size());
|
mobj->modelData->models.AppendFill({-1, {}}, modelindex - mobj->modelData->models.Size());
|
||||||
mobj->modelData->modelFrameGenerators.AppendFill(-1, modelindex - mobj->modelData->modelFrameGenerators.Size());
|
mobj->modelData->modelFrameGenerators.AppendFill(-1, modelindex - mobj->modelData->modelFrameGenerators.Size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5178,26 +5176,51 @@ void ChangeModelNative(
|
||||||
mobj->modelData->animationIDs.AppendFill(-1, animationindex - mobj->modelData->animationIDs.Size());
|
mobj->modelData->animationIDs.AppendFill(-1, animationindex - mobj->modelData->animationIDs.Size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(flags & CMDL_USESURFACESKIN)
|
auto skindata = skin != NAME_None ? LoadSkin(skinpath.GetChars(), skin.GetChars()) : FNullTextureID();
|
||||||
{
|
|
||||||
if(mobj->modelData->surfaceSkinIDs.Size() < skinPosition)
|
if(!(flags & CMDL_USESURFACESKIN) && mobj->modelData->skinIDs.Size() < skinindex)
|
||||||
{
|
|
||||||
mobj->modelData->surfaceSkinIDs.AppendFill(FNullTextureID(), skinPosition - mobj->modelData->surfaceSkinIDs.Size());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(mobj->modelData->skinIDs.Size() < skinindex)
|
|
||||||
{
|
{
|
||||||
mobj->modelData->skinIDs.AppendFill(FNullTextureID(), skinindex - mobj->modelData->skinIDs.Size());
|
mobj->modelData->skinIDs.AppendFill(FNullTextureID(), skinindex - mobj->modelData->skinIDs.Size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mobj->modelData->modelIDs.Size() == modelindex)
|
if(mobj->modelData->models.Size() == modelindex)
|
||||||
{
|
{
|
||||||
mobj->modelData->modelIDs.Push(queryModel);
|
|
||||||
mobj->modelData->modelFrameGenerators.Push(generatorindex);
|
if(flags & CMDL_USESURFACESKIN && skinindex >= 0)
|
||||||
|
{
|
||||||
|
TArray<FTextureID> surfaceSkins;
|
||||||
|
if(skinindex > 0)
|
||||||
|
{
|
||||||
|
surfaceSkins.AppendFill(FNullTextureID(), skinindex - 1);
|
||||||
|
}
|
||||||
|
surfaceSkins.Push(skindata);
|
||||||
|
mobj->modelData->models.Push({queryModel, std::move(surfaceSkins)});
|
||||||
|
mobj->modelData->modelFrameGenerators.Push(generatorindex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mobj->modelData->models.Push({queryModel, {}});
|
||||||
|
mobj->modelData->modelFrameGenerators.Push(generatorindex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mobj->modelData->modelIDs[modelindex] = queryModel;
|
if(flags & CMDL_USESURFACESKIN && skinindex >= 0)
|
||||||
|
{
|
||||||
|
if(skinindex > mobj->modelData->models[modelindex].surfaceSkinIDs.Size())
|
||||||
|
{
|
||||||
|
mobj->modelData->models[modelindex].surfaceSkinIDs.AppendFill(FNullTextureID(), skinindex - mobj->modelData->models[modelindex].surfaceSkinIDs.Size());
|
||||||
|
}
|
||||||
|
if(skinindex == mobj->modelData->models[modelindex].surfaceSkinIDs.Size())
|
||||||
|
{
|
||||||
|
mobj->modelData->models[modelindex].surfaceSkinIDs.Push(skindata);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mobj->modelData->models[modelindex].surfaceSkinIDs[skinindex] = skindata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mobj->modelData->models[modelindex].modelID = queryModel;
|
||||||
mobj->modelData->modelFrameGenerators[modelindex] = generatorindex;
|
mobj->modelData->modelFrameGenerators[modelindex] = generatorindex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5210,20 +5233,7 @@ void ChangeModelNative(
|
||||||
mobj->modelData->animationIDs[animationindex] = queryAnimation;
|
mobj->modelData->animationIDs[animationindex] = queryAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto skindata = skin != NAME_None ? LoadSkin(skinpath.GetChars(), skin.GetChars()) : FNullTextureID();
|
if (!(flags & CMDL_USESURFACESKIN))
|
||||||
|
|
||||||
if (flags & CMDL_USESURFACESKIN)
|
|
||||||
{
|
|
||||||
if(mobj->modelData->surfaceSkinIDs.Size() == skinPosition)
|
|
||||||
{
|
|
||||||
mobj->modelData->surfaceSkinIDs.Push(skindata);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mobj->modelData->surfaceSkinIDs[skinPosition] = skindata;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if(mobj->modelData->skinIDs.Size() == skinindex)
|
if(mobj->modelData->skinIDs.Size() == skinindex)
|
||||||
{
|
{
|
||||||
|
@ -5286,7 +5296,7 @@ void ChangeModelNative(
|
||||||
if(!found) savedModelFiles.Push(fullName);
|
if(!found) savedModelFiles.Push(fullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mobj->modelData->modelIDs.Size() == 0 && mobj->modelData->modelFrameGenerators.Size() == 0 && mobj->modelData->skinIDs.Size() == 0 && mobj->modelData->surfaceSkinIDs.Size() == 0 && mobj->modelData->animationIDs.Size() == 0 && modeldef == NAME_None)
|
if (mobj->modelData->models.Size() == 0 && mobj->modelData->modelFrameGenerators.Size() == 0 && mobj->modelData->skinIDs.Size() == 0 && mobj->modelData->animationIDs.Size() == 0 && modeldef == NAME_None)
|
||||||
{
|
{
|
||||||
mobj->hasmodel = mobj->modelData->hasModel;
|
mobj->hasmodel = mobj->modelData->hasModel;
|
||||||
mobj->modelData->Destroy();
|
mobj->modelData->Destroy();
|
||||||
|
|
|
@ -1324,13 +1324,22 @@ bool AActor::Massacre ()
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, ModelOverride &sid, ModelOverride *def)
|
||||||
|
{
|
||||||
|
arc.BeginObject(key);
|
||||||
|
arc("modelID", sid.modelID);
|
||||||
|
arc("surfaceSkinIDs", sid.surfaceSkinIDs);
|
||||||
|
arc.EndObject();
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
void DActorModelData::Serialize(FSerializer& arc)
|
void DActorModelData::Serialize(FSerializer& arc)
|
||||||
{
|
{
|
||||||
Super::Serialize(arc);
|
Super::Serialize(arc);
|
||||||
arc("modelDef", modelDef)
|
arc("modelDef", modelDef)
|
||||||
("modelIDs", modelIDs)
|
("models", models)
|
||||||
("skinIDs", skinIDs)
|
("skinIDs", skinIDs)
|
||||||
("surfaceSkinIDs", surfaceSkinIDs)
|
//("surfaceSkinIDs", surfaceSkinIDs)
|
||||||
("animationIDs", animationIDs)
|
("animationIDs", animationIDs)
|
||||||
("modelFrameGenerators", modelFrameGenerators)
|
("modelFrameGenerators", modelFrameGenerators)
|
||||||
("hasModel", hasModel);
|
("hasModel", hasModel);
|
||||||
|
@ -1338,10 +1347,10 @@ void DActorModelData::Serialize(FSerializer& arc)
|
||||||
|
|
||||||
void DActorModelData::OnDestroy()
|
void DActorModelData::OnDestroy()
|
||||||
{
|
{
|
||||||
modelIDs.Reset();
|
models.Reset();
|
||||||
modelFrameGenerators.Reset();
|
modelFrameGenerators.Reset();
|
||||||
skinIDs.Reset();
|
skinIDs.Reset();
|
||||||
surfaceSkinIDs.Reset();
|
//surfaceSkinIDs.Reset();
|
||||||
animationIDs.Reset();
|
animationIDs.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -299,12 +299,12 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int modelsamount = smf->modelsAmount;
|
unsigned modelsamount = smf->modelsAmount;
|
||||||
//[SM] - if we added any models for the frame to also render, then we also need to update modelsAmount for this smf
|
//[SM] - if we added any models for the frame to also render, then we also need to update modelsAmount for this smf
|
||||||
if (actor->modelData != nullptr)
|
if (actor->modelData != nullptr)
|
||||||
{
|
{
|
||||||
if (actor->modelData->modelIDs.Size() > (unsigned)modelsamount)
|
if (actor->modelData->models.Size() > modelsamount)
|
||||||
modelsamount = actor->modelData->modelIDs.Size();
|
modelsamount = actor->modelData->models.Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
TArray<FTextureID> surfaceskinids;
|
TArray<FTextureID> surfaceskinids;
|
||||||
|
@ -313,81 +313,108 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
|
||||||
int boneStartingPosition = 0;
|
int boneStartingPosition = 0;
|
||||||
bool evaluatedSingle = false;
|
bool evaluatedSingle = false;
|
||||||
|
|
||||||
for (int i = 0; i < modelsamount; i++)
|
for (unsigned i = 0; i < modelsamount; i++)
|
||||||
{
|
{
|
||||||
int modelid = -1;
|
int modelid = -1;
|
||||||
int animationid = -1;
|
int animationid = -1;
|
||||||
int modelframe = -1;
|
int modelframe = -1;
|
||||||
int modelframenext = -1;
|
int modelframenext = -1;
|
||||||
FTextureID skinid; skinid.SetInvalid();
|
FTextureID skinid; skinid.SetNull();
|
||||||
|
|
||||||
surfaceskinids.Clear();
|
surfaceskinids.Clear();
|
||||||
|
|
||||||
if (actor->modelData != nullptr)
|
if (actor->modelData != nullptr)
|
||||||
{
|
{
|
||||||
if (i < (int)actor->modelData->modelIDs.Size())
|
//modelID
|
||||||
modelid = actor->modelData->modelIDs[i];
|
if (actor->modelData->models.Size() > i && actor->modelData->models[i].modelID >= 0)
|
||||||
|
{
|
||||||
|
modelid = actor->modelData->models[i].modelID;
|
||||||
|
}
|
||||||
|
else if(smf->modelsAmount > i)
|
||||||
|
{
|
||||||
|
modelid = smf->modelIDs[i];
|
||||||
|
}
|
||||||
|
|
||||||
if (i < (int)actor->modelData->animationIDs.Size())
|
//animationID
|
||||||
|
if (actor->modelData->animationIDs.Size() > i && actor->modelData->animationIDs[i] >= 0)
|
||||||
|
{
|
||||||
animationid = actor->modelData->animationIDs[i];
|
animationid = actor->modelData->animationIDs[i];
|
||||||
|
|
||||||
if (i < (int)actor->modelData->modelFrameGenerators.Size())
|
|
||||||
{
|
|
||||||
//[SM] - We will use this little snippet to allow a modder to specify a model index to clone. It's also pointless to clone something that clones something else in this case. And causes me headaches.
|
|
||||||
if (actor->modelData->modelFrameGenerators[i] >= 0 && actor->modelData->modelFrameGenerators[i] <= modelsamount && smf->modelframes[actor->modelData->modelFrameGenerators[i]] != -1)
|
|
||||||
{
|
|
||||||
modelframe = smf->modelframes[actor->modelData->modelFrameGenerators[i]];
|
|
||||||
if (smfNext) modelframenext = smfNext->modelframes[actor->modelData->modelFrameGenerators[i]];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (i < (int)actor->modelData->skinIDs.Size())
|
else if(smf->modelsAmount > i)
|
||||||
{
|
{
|
||||||
if (actor->modelData->skinIDs[i].isValid())
|
animationid = smf->animationIDs[i];
|
||||||
skinid = actor->modelData->skinIDs[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned sz1 = smf->surfaceskinIDs.Size();
|
//modelFrame
|
||||||
unsigned sz2 = actor->modelData->surfaceSkinIDs.Size();
|
if (actor->modelData->modelFrameGenerators.Size() > i
|
||||||
unsigned end = (i + 1) * MD3_MAX_SURFACES;
|
&& actor->modelData->modelFrameGenerators[i] >= 0
|
||||||
|
&& actor->modelData->modelFrameGenerators[i] < modelsamount
|
||||||
|
&& smf->modelframes[actor->modelData->modelFrameGenerators[i]] >= 0
|
||||||
|
) {
|
||||||
|
modelframe = smf->modelframes[actor->modelData->modelFrameGenerators[i]];
|
||||||
|
|
||||||
if(actor->modelData->surfaceSkinIDs.Size() > 0)
|
if (smfNext)
|
||||||
{
|
|
||||||
long last_ok = -1;
|
|
||||||
surfaceskinids.Resize(actor->modelData->surfaceSkinIDs.Size());
|
|
||||||
for (unsigned surface = i * MD3_MAX_SURFACES; surface < end; surface++)
|
|
||||||
{
|
{
|
||||||
if (surface >= sz2) break;
|
if(smfNext->modelframes[actor->modelData->modelFrameGenerators[i]] >= 0)
|
||||||
|
|
||||||
if (actor->modelData->surfaceSkinIDs[surface].isValid())
|
|
||||||
{
|
{
|
||||||
surfaceskinids[surface] = actor->modelData->surfaceSkinIDs[surface];
|
modelframenext = smfNext->modelframes[actor->modelData->modelFrameGenerators[i]];
|
||||||
last_ok = surface;
|
|
||||||
}
|
|
||||||
else if(surface < sz1)
|
|
||||||
{
|
|
||||||
surfaceskinids[surface] = smf->surfaceskinIDs[surface];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
surfaceskinids[surface].SetInvalid();
|
modelframenext = smfNext->modelframes[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(last_ok >= 0)
|
}
|
||||||
|
else if(smf->modelsAmount > i)
|
||||||
|
{
|
||||||
|
modelframe = smf->modelframes[i];
|
||||||
|
if (smfNext) modelframenext = smfNext->modelframes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
//skinID
|
||||||
|
if (actor->modelData->skinIDs.Size() > i && actor->modelData->skinIDs[i].isValid())
|
||||||
|
{
|
||||||
|
skinid = actor->modelData->skinIDs[i];
|
||||||
|
}
|
||||||
|
else if(smf->modelsAmount > i)
|
||||||
|
{
|
||||||
|
skinid = smf->skinIDs[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
//surfaceSkinIDs
|
||||||
|
if(actor->modelData->models.Size() > i && actor->modelData->models[i].surfaceSkinIDs.Size() > 0)
|
||||||
|
{
|
||||||
|
unsigned sz1 = smf->surfaceskinIDs.Size();
|
||||||
|
unsigned sz2 = actor->modelData->models[i].surfaceSkinIDs.Size();
|
||||||
|
unsigned start = i * MD3_MAX_SURFACES;
|
||||||
|
|
||||||
|
surfaceskinids = actor->modelData->models[i].surfaceSkinIDs;
|
||||||
|
surfaceskinids.Resize(MD3_MAX_SURFACES);
|
||||||
|
|
||||||
|
for (unsigned surface = 0; surface < MD3_MAX_SURFACES; surface++)
|
||||||
{
|
{
|
||||||
surfaceskinids.Resize(max(last_ok + 1, (long)sz1)); // clear out
|
if (sz2 > surface && (actor->modelData->models[i].surfaceSkinIDs[surface].isValid()))
|
||||||
}
|
{
|
||||||
else
|
continue;
|
||||||
{
|
}
|
||||||
surfaceskinids.Clear();
|
if((surface + start) < sz1)
|
||||||
|
{
|
||||||
|
surfaceskinids[surface] = smf->surfaceskinIDs[surface + start];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
surfaceskinids[surface].SetNull();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i < smf->modelsAmount)
|
else
|
||||||
{
|
{
|
||||||
if (modelid == -1) modelid = smf->modelIDs[i];
|
modelid = smf->modelIDs[i];
|
||||||
if (animationid == -1) animationid = smf->animationIDs[i];
|
animationid = smf->animationIDs[i];
|
||||||
if (modelframe == -1) modelframe = smf->modelframes[i];
|
modelframe = smf->modelframes[i];
|
||||||
if (modelframenext == -1 && smfNext) modelframenext = smfNext->modelframes[i];
|
if (smfNext) modelframenext = smfNext->modelframes[i];
|
||||||
if (!skinid.isValid()) skinid = smf->skinIDs[i];
|
skinid = smf->skinIDs[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modelid >= 0)
|
if (modelid >= 0)
|
||||||
|
@ -396,8 +423,9 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
|
||||||
auto tex = skinid.isValid() ? TexMan.GetGameTexture(skinid, true) : nullptr;
|
auto tex = skinid.isValid() ? TexMan.GetGameTexture(skinid, true) : nullptr;
|
||||||
mdl->BuildVertexBuffer(renderer);
|
mdl->BuildVertexBuffer(renderer);
|
||||||
|
|
||||||
auto& ssids = surfaceskinids.Size() > 0 ? surfaceskinids : smf->surfaceskinIDs;
|
auto ssidp = surfaceskinids.Size() > 0
|
||||||
auto ssidp = (unsigned)(i * MD3_MAX_SURFACES) < ssids.Size() ? &ssids[i * MD3_MAX_SURFACES] : nullptr;
|
? surfaceskinids.Data()
|
||||||
|
: (((i * MD3_MAX_SURFACES) < smf->surfaceskinIDs.Size()) ? &smf->surfaceskinIDs[i * MD3_MAX_SURFACES] : nullptr);
|
||||||
|
|
||||||
|
|
||||||
bool nextFrame = smfNext && modelframe != modelframenext;
|
bool nextFrame = smfNext && modelframe != modelframenext;
|
||||||
|
|
Loading…
Reference in a new issue