mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-11 13:11:07 +00:00
Dynamic number of models per frame instead of a hard limit of four. (#1298)
* Changed model-related arrays to TArrays. * Update models.cpp Used TArray.Alloc to make TArrays have the correct size depending on the number of models. surfaceSkinIDs was two-dimensional and is now a one-dimensional TArray as well, it's size is now (models * MD3_MAX_SURFACES) surfaceSkinIDs was two-dimensional and is now a one-dimensional TArray as well, elements are accessed via [Row + Column * NumRows], in this case sSurfaceIndex + modelIndex * MD3_MAX_SURFACES] * Edited skinSurfaceIDs access for one-dimensional TArray * Edited skinSurfaceIDs access for one-dimensional TArray * Edited skinSurfaceIDs access for one-dimensional TArray * Changed model-related arrays to TArrays. Also removed MAX_MODELS_PER_FRAME. * Used TArray.Alloc to make TArrays have the correct size depending on the number of models. surfaceSkinIDs was two-dimensional and is now a one-dimensional TArray as well, elements are accessed via [Row + Column * NumRows], in this case surfaceIndex + modelIndex * MD3_MAX_SURFACES] * Used TArray.Alloc to make TArrays have the correct size depending on the number of models. surfaceSkinIDs was two-dimensional and is now a one-dimensional TArray as well, elements are accessed via [Row + Column * NumRows], in this case surfaceIndex + modelIndex * MD3_MAX_SURFACES] * Update models.h * Edited MAX_MODELS_MD3 * Update models_obj.cpp
This commit is contained in:
parent
4d56754171
commit
769d60a64f
6 changed files with 77 additions and 31 deletions
|
@ -15,15 +15,15 @@ void FlushModels();
|
||||||
extern TDeletingArray<FModel*> Models;
|
extern TDeletingArray<FModel*> Models;
|
||||||
extern TArray<FSpriteModelFrame> SpriteModelFrames;
|
extern TArray<FSpriteModelFrame> SpriteModelFrames;
|
||||||
|
|
||||||
#define MAX_MODELS_PER_FRAME 4
|
|
||||||
#define MD3_MAX_SURFACES 32
|
#define MD3_MAX_SURFACES 32
|
||||||
|
|
||||||
struct FSpriteModelFrame
|
struct FSpriteModelFrame
|
||||||
{
|
{
|
||||||
int modelIDs[MAX_MODELS_PER_FRAME];
|
uint8_t modelsAmount = 0;
|
||||||
FTextureID skinIDs[MAX_MODELS_PER_FRAME];
|
TArray<int> modelIDs;
|
||||||
FTextureID surfaceskinIDs[MAX_MODELS_PER_FRAME][MD3_MAX_SURFACES];
|
TArray<FTextureID> skinIDs;
|
||||||
int modelframes[MAX_MODELS_PER_FRAME];
|
TArray<FTextureID> surfaceskinIDs;
|
||||||
|
TArray<int> modelframes;
|
||||||
float xscale, yscale, zscale;
|
float xscale, yscale, zscale;
|
||||||
// [BB] Added zoffset, rotation parameters and flags.
|
// [BB] Added zoffset, rotation parameters and flags.
|
||||||
// Added xoffset, yoffset
|
// Added xoffset, yoffset
|
||||||
|
|
|
@ -306,9 +306,10 @@ void FMD3Model::AddSkins(uint8_t *hitlist)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < Surfaces.Size(); i++)
|
for (unsigned i = 0; i < Surfaces.Size(); i++)
|
||||||
{
|
{
|
||||||
if (curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid())
|
int ssIndex = i + curMDLIndex * MD3_MAX_SURFACES;
|
||||||
|
if (curSpriteMDLFrame->surfaceskinIDs[ssIndex].isValid())
|
||||||
{
|
{
|
||||||
hitlist[curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].GetIndex()] |= FTextureManager::HIT_Flat;
|
hitlist[curSpriteMDLFrame->surfaceskinIDs[ssIndex].GetIndex()] |= FTextureManager::HIT_Flat;
|
||||||
}
|
}
|
||||||
|
|
||||||
MD3Surface * surf = &Surfaces[i];
|
MD3Surface * surf = &Surfaces[i];
|
||||||
|
@ -357,9 +358,10 @@ void FMD3Model::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int f
|
||||||
FGameTexture *surfaceSkin = skin;
|
FGameTexture *surfaceSkin = skin;
|
||||||
if (!surfaceSkin)
|
if (!surfaceSkin)
|
||||||
{
|
{
|
||||||
if (curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid())
|
int ssIndex = i + curMDLIndex * MD3_MAX_SURFACES;
|
||||||
|
if (curSpriteMDLFrame->surfaceskinIDs[ssIndex].isValid())
|
||||||
{
|
{
|
||||||
surfaceSkin = TexMan.GetGameTexture(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i], true);
|
surfaceSkin = TexMan.GetGameTexture(curSpriteMDLFrame->surfaceskinIDs[ssIndex], true);
|
||||||
}
|
}
|
||||||
else if (surf->numSkins > 0 && surf->Skins[0].isValid())
|
else if (surf->numSkins > 0 && surf->Skins[0].isValid())
|
||||||
{
|
{
|
||||||
|
|
|
@ -638,9 +638,10 @@ void FOBJModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int f
|
||||||
FGameTexture *userSkin = skin;
|
FGameTexture *userSkin = skin;
|
||||||
if (!userSkin)
|
if (!userSkin)
|
||||||
{
|
{
|
||||||
if (i < MD3_MAX_SURFACES && curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid())
|
int ssIndex = i + curMDLIndex * MD3_MAX_SURFACES;
|
||||||
|
if (i < MD3_MAX_SURFACES && curSpriteMDLFrame->surfaceskinIDs[ssIndex].isValid())
|
||||||
{
|
{
|
||||||
userSkin = TexMan.GetGameTexture(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i], true);
|
userSkin = TexMan.GetGameTexture(curSpriteMDLFrame->surfaceskinIDs[ssIndex], true);
|
||||||
}
|
}
|
||||||
else if (surf->skin.isValid())
|
else if (surf->skin.isValid())
|
||||||
{
|
{
|
||||||
|
@ -669,13 +670,14 @@ void FOBJModel::AddSkins(uint8_t* hitlist)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < surfaces.Size(); i++)
|
for (size_t i = 0; i < surfaces.Size(); i++)
|
||||||
{
|
{
|
||||||
if (i < MD3_MAX_SURFACES && curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid())
|
size_t ssIndex = i + curMDLIndex * MD3_MAX_SURFACES;
|
||||||
|
if (i < MD3_MAX_SURFACES && curSpriteMDLFrame->surfaceskinIDs[ssIndex].isValid())
|
||||||
{
|
{
|
||||||
// Precache skins manually reassigned by the user.
|
// Precache skins manually reassigned by the user.
|
||||||
// On OBJs with lots of skins, such as Doom map OBJs exported from GZDB,
|
// On OBJs with lots of skins, such as Doom map OBJs exported from GZDB,
|
||||||
// there may be too many skins for the user to manually change, unless
|
// there may be too many skins for the user to manually change, unless
|
||||||
// the limit is bumped or surfaceskinIDs is changed to a TArray<FTextureID>.
|
// the limit is bumped or surfaceskinIDs is changed to a TArray<FTextureID>.
|
||||||
hitlist[curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].GetIndex()] |= FTextureManager::HIT_Flat;
|
hitlist[curSpriteMDLFrame->surfaceskinIDs[ssIndex].GetIndex()] |= FTextureManager::HIT_Flat;
|
||||||
return; // No need to precache skin that was replaced
|
return; // No need to precache skin that was replaced
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -242,8 +242,9 @@ void FUE1Model::RenderFrame( FModelRenderer *renderer, FGameTexture *skin, int f
|
||||||
FGameTexture *sskin = skin;
|
FGameTexture *sskin = skin;
|
||||||
if ( !sskin )
|
if ( !sskin )
|
||||||
{
|
{
|
||||||
if ( curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum].isValid() )
|
int ssIndex = groups[i].texNum + curMDLIndex * MD3_MAX_SURFACES;
|
||||||
sskin = TexMan.GetGameTexture(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum], true);
|
if (curSpriteMDLFrame->surfaceskinIDs[ssIndex].isValid())
|
||||||
|
sskin = TexMan.GetGameTexture(curSpriteMDLFrame->surfaceskinIDs[ssIndex], true);
|
||||||
if ( !sskin )
|
if ( !sskin )
|
||||||
{
|
{
|
||||||
vofs += vsize;
|
vofs += vsize;
|
||||||
|
@ -303,8 +304,12 @@ void FUE1Model::BuildVertexBuffer( FModelRenderer *renderer )
|
||||||
void FUE1Model::AddSkins( uint8_t *hitlist )
|
void FUE1Model::AddSkins( uint8_t *hitlist )
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numGroups; i++)
|
for (int i = 0; i < numGroups; i++)
|
||||||
if ( curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum].isValid() )
|
{
|
||||||
hitlist[curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum].GetIndex()] |= FTextureManager::HIT_Flat;
|
int ssIndex = groups[i].texNum + curMDLIndex * MD3_MAX_SURFACES;
|
||||||
|
if (curSpriteMDLFrame->surfaceskinIDs[ssIndex].isValid())
|
||||||
|
hitlist[curSpriteMDLFrame->surfaceskinIDs[ssIndex].GetIndex()] |= FTextureManager::HIT_Flat;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FUE1Model::~FUE1Model()
|
FUE1Model::~FUE1Model()
|
||||||
|
|
|
@ -267,8 +267,7 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < smf->modelsAmount; i++)
|
||||||
for (int i = 0; i<MAX_MODELS_PER_FRAME; i++)
|
|
||||||
{
|
{
|
||||||
if (smf->modelIDs[i] != -1)
|
if (smf->modelIDs[i] != -1)
|
||||||
{
|
{
|
||||||
|
@ -317,9 +316,17 @@ void InitModels()
|
||||||
FSpriteModelFrame smf;
|
FSpriteModelFrame smf;
|
||||||
memset(&smf, 0, sizeof(smf));
|
memset(&smf, 0, sizeof(smf));
|
||||||
smf.isVoxel = true;
|
smf.isVoxel = true;
|
||||||
smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1;
|
|
||||||
|
smf.modelsAmount = 1;
|
||||||
|
smf.modelframes.Alloc(1);
|
||||||
|
smf.modelframes[0] = -1;
|
||||||
|
|
||||||
|
smf.modelIDs.Alloc(1);
|
||||||
smf.modelIDs[0] = VoxelDefs[i]->Voxel->VoxelIndex;
|
smf.modelIDs[0] = VoxelDefs[i]->Voxel->VoxelIndex;
|
||||||
|
|
||||||
|
smf.skinIDs.Alloc(1);
|
||||||
smf.skinIDs[0] = md->GetPaletteTexture();
|
smf.skinIDs[0] = md->GetPaletteTexture();
|
||||||
|
|
||||||
smf.xscale = smf.yscale = smf.zscale = VoxelDefs[i]->Scale;
|
smf.xscale = smf.yscale = smf.zscale = VoxelDefs[i]->Scale;
|
||||||
smf.angleoffset = VoxelDefs[i]->AngleOffset.Degrees;
|
smf.angleoffset = VoxelDefs[i]->AngleOffset.Degrees;
|
||||||
if (VoxelDefs[i]->PlacedSpin != 0)
|
if (VoxelDefs[i]->PlacedSpin != 0)
|
||||||
|
@ -345,6 +352,7 @@ void InitModels()
|
||||||
}
|
}
|
||||||
SpriteModelFrames.Push(smf);
|
SpriteModelFrames.Push(smf);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Lump;
|
int Lump;
|
||||||
|
@ -370,6 +378,7 @@ void InitModels()
|
||||||
static void ParseModelDefLump(int Lump)
|
static void ParseModelDefLump(int Lump)
|
||||||
{
|
{
|
||||||
FScanner sc(Lump);
|
FScanner sc(Lump);
|
||||||
|
|
||||||
while (sc.GetString())
|
while (sc.GetString())
|
||||||
{
|
{
|
||||||
if (sc.Compare("model"))
|
if (sc.Compare("model"))
|
||||||
|
@ -380,7 +389,6 @@ static void ParseModelDefLump(int Lump)
|
||||||
|
|
||||||
FSpriteModelFrame smf;
|
FSpriteModelFrame smf;
|
||||||
memset(&smf, 0, sizeof(smf));
|
memset(&smf, 0, sizeof(smf));
|
||||||
smf.modelIDs[0] = smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1;
|
|
||||||
smf.xscale=smf.yscale=smf.zscale=1.f;
|
smf.xscale=smf.yscale=smf.zscale=1.f;
|
||||||
|
|
||||||
auto type = PClass::FindClass(sc.String);
|
auto type = PClass::FindClass(sc.String);
|
||||||
|
@ -389,6 +397,32 @@ static void ParseModelDefLump(int Lump)
|
||||||
sc.ScriptError("MODELDEF: Unknown actor type '%s'\n", sc.String);
|
sc.ScriptError("MODELDEF: Unknown actor type '%s'\n", sc.String);
|
||||||
}
|
}
|
||||||
smf.type = type;
|
smf.type = type;
|
||||||
|
|
||||||
|
|
||||||
|
FScanner::SavedPos scPos = sc.SavePos();
|
||||||
|
|
||||||
|
sc.MustGetStringName("{");
|
||||||
|
while (!sc.CheckString("}"))
|
||||||
|
{
|
||||||
|
sc.MustGetString();
|
||||||
|
if (sc.Compare("model"))
|
||||||
|
{
|
||||||
|
sc.MustGetNumber();
|
||||||
|
index = sc.Number;
|
||||||
|
if (index < 0)
|
||||||
|
{
|
||||||
|
sc.ScriptError("Too many models in %s", type->TypeName.GetChars());
|
||||||
|
}
|
||||||
|
smf.modelsAmount = index + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
smf.modelIDs.Alloc(smf.modelsAmount);
|
||||||
|
smf.skinIDs.Alloc(smf.modelsAmount);
|
||||||
|
smf.surfaceskinIDs.Alloc(smf.modelsAmount * MD3_MAX_SURFACES);
|
||||||
|
smf.modelframes.Alloc(smf.modelsAmount);
|
||||||
|
|
||||||
|
sc.RestorePos(scPos);
|
||||||
|
|
||||||
sc.MustGetStringName("{");
|
sc.MustGetStringName("{");
|
||||||
while (!sc.CheckString("}"))
|
while (!sc.CheckString("}"))
|
||||||
{
|
{
|
||||||
|
@ -404,17 +438,19 @@ static void ParseModelDefLump(int Lump)
|
||||||
{
|
{
|
||||||
sc.MustGetNumber();
|
sc.MustGetNumber();
|
||||||
index = sc.Number;
|
index = sc.Number;
|
||||||
if (index < 0 || index >= MAX_MODELS_PER_FRAME)
|
if (index < 0 || index >= smf.modelsAmount)
|
||||||
{
|
{
|
||||||
sc.ScriptError("Too many models in %s", type->TypeName.GetChars());
|
sc.ScriptError("Too many models in %s", type->TypeName.GetChars());
|
||||||
}
|
}
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
FixPathSeperator(sc.String);
|
FixPathSeperator(sc.String);
|
||||||
|
|
||||||
smf.modelIDs[index] = FindModel(path.GetChars(), sc.String);
|
smf.modelIDs[index] = FindModel(path.GetChars(), sc.String);
|
||||||
if (smf.modelIDs[index] == -1)
|
if (smf.modelIDs[index] == -1)
|
||||||
{
|
{
|
||||||
Printf("%s: model not found in %s\n", sc.String, path.GetChars());
|
Printf("%s: model not found in %s\n", sc.String, path.GetChars());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (sc.Compare("scale"))
|
else if (sc.Compare("scale"))
|
||||||
{
|
{
|
||||||
|
@ -529,7 +565,7 @@ static void ParseModelDefLump(int Lump)
|
||||||
{
|
{
|
||||||
sc.MustGetNumber();
|
sc.MustGetNumber();
|
||||||
index=sc.Number;
|
index=sc.Number;
|
||||||
if (index<0 || index>=MAX_MODELS_PER_FRAME)
|
if (index<0 || index>= smf.modelsAmount)
|
||||||
{
|
{
|
||||||
sc.ScriptError("Too many models in %s", type->TypeName.GetChars());
|
sc.ScriptError("Too many models in %s", type->TypeName.GetChars());
|
||||||
}
|
}
|
||||||
|
@ -556,7 +592,7 @@ static void ParseModelDefLump(int Lump)
|
||||||
sc.MustGetNumber();
|
sc.MustGetNumber();
|
||||||
surface = sc.Number;
|
surface = sc.Number;
|
||||||
|
|
||||||
if (index<0 || index >= MAX_MODELS_PER_FRAME)
|
if (index<0 || index >= smf.modelsAmount)
|
||||||
{
|
{
|
||||||
sc.ScriptError("Too many models in %s", type->TypeName.GetChars());
|
sc.ScriptError("Too many models in %s", type->TypeName.GetChars());
|
||||||
}
|
}
|
||||||
|
@ -568,14 +604,15 @@ static void ParseModelDefLump(int Lump)
|
||||||
|
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
FixPathSeperator(sc.String);
|
FixPathSeperator(sc.String);
|
||||||
|
int ssIndex = surface + index * MD3_MAX_SURFACES;
|
||||||
if (sc.Compare(""))
|
if (sc.Compare(""))
|
||||||
{
|
{
|
||||||
smf.surfaceskinIDs[index][surface] = FNullTextureID();
|
smf.surfaceskinIDs[ssIndex] = FNullTextureID();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
smf.surfaceskinIDs[index][surface] = LoadSkin(path.GetChars(), sc.String);
|
smf.surfaceskinIDs[ssIndex] = LoadSkin(path.GetChars(), sc.String);
|
||||||
if (!smf.surfaceskinIDs[index][surface].isValid())
|
if (!smf.surfaceskinIDs[ssIndex].isValid())
|
||||||
{
|
{
|
||||||
Printf("Surface Skin '%s' not found in '%s'\n",
|
Printf("Surface Skin '%s' not found in '%s'\n",
|
||||||
sc.String, type->TypeName.GetChars());
|
sc.String, type->TypeName.GetChars());
|
||||||
|
@ -610,7 +647,7 @@ static void ParseModelDefLump(int Lump)
|
||||||
|
|
||||||
sc.MustGetNumber();
|
sc.MustGetNumber();
|
||||||
index=sc.Number;
|
index=sc.Number;
|
||||||
if (index<0 || index>=MAX_MODELS_PER_FRAME)
|
if (index<0 || index>= smf.modelsAmount)
|
||||||
{
|
{
|
||||||
sc.ScriptError("Too many models in %s", type->TypeName.GetChars());
|
sc.ScriptError("Too many models in %s", type->TypeName.GetChars());
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,7 +162,7 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitl
|
||||||
FSpriteModelFrame * smf = FindModelFrame(cls, state.sprite, state.Frame, false);
|
FSpriteModelFrame * smf = FindModelFrame(cls, state.sprite, state.Frame, false);
|
||||||
if (smf != NULL)
|
if (smf != NULL)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAX_MODELS_PER_FRAME; i++)
|
for (int i = 0; i < smf->modelsAmount; i++)
|
||||||
{
|
{
|
||||||
if (smf->skinIDs[i].isValid())
|
if (smf->skinIDs[i].isValid())
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue