models: md5 tris compress before compress gl commands.

Use ST/Vect lookup of same values.
This commit is contained in:
Denis Pauk 2024-03-13 00:46:40 +02:00
parent b0a0d2e847
commit 0b5babdc53
3 changed files with 131 additions and 47 deletions

View file

@ -417,7 +417,7 @@ Mod_LoadFrames_DKM2(dmdx_t *pheader, const byte *src, size_t inframesize, vec3_t
}
}
static void
void
Mod_LoadFixImages(const char* mod_name, dmdx_t *pheader, qboolean internal)
{
int i;
@ -1038,6 +1038,118 @@ Mod_LoadCmdCompress(const dstvert_t *texcoords, dtriangle_t *triangles, int num_
return numcommands;
}
static int *
Mod_LoadSTLookup(dmdx_t *pheader)
{
const dstvert_t* st;
int *st_lookup;
int k;
st = (dstvert_t*)((byte *)pheader + pheader->ofs_st);
st_lookup = calloc(pheader->num_st, sizeof(int));
for(k = 1; k < pheader->num_st; k++)
{
int j;
st_lookup[k] = k;
for(j = 0; j < k; j++)
{
if ((st[j].s == st[k].s) && (st[j].t == st[k].t))
{
/* same value */
st_lookup[k] = j;
break;
}
}
}
return st_lookup;
}
static qboolean
Mod_LoadFrameVertSame(dmdx_t *pheader, int k, int j)
{
int i;
for(i = 0; i < pheader->num_frames; i ++)
{
daliasxframe_t *frame;
frame = (daliasxframe_t *)(
(byte *)pheader + pheader->ofs_frames + i * pheader->framesize);
if ((frame->verts[k].v[0] != frame->verts[j].v[0]) ||
(frame->verts[k].v[1] != frame->verts[j].v[1]) ||
(frame->verts[k].v[2] != frame->verts[j].v[2]) ||
(frame->verts[k].lightnormalindex != frame->verts[j].lightnormalindex))
{
continue;
}
return true;
}
return false;
}
static int *
Mod_LoadVectLookup(dmdx_t *pheader)
{
int *vect_lookup;
int k;
vect_lookup = calloc(pheader->num_xyz, sizeof(int));
for(k = 1; k < pheader->num_xyz; k++)
{
int j;
vect_lookup[k] = k;
for(j = 0; j < k; j++)
{
if (Mod_LoadFrameVertSame(pheader, k, j))
{
/* same value */
vect_lookup[k] = j;
break;
}
}
}
return vect_lookup;
}
void
Mod_LoadTrisCompress(dmdx_t *pheader)
{
int *st_lookup, *vect_lookup;
dtriangle_t *tris;
int i;
st_lookup = Mod_LoadSTLookup(pheader);
vect_lookup = Mod_LoadVectLookup(pheader);
tris = (dtriangle_t*)((byte *)pheader + pheader->ofs_tris);
for (i = 0; i < pheader->num_tris; i++)
{
int k;
for (k = 0; k < 3; k++)
{
tris->index_xyz[k] = vect_lookup[tris->index_xyz[k]];
tris->index_st[k] = st_lookup[tris->index_st[k]];
}
tris++;
}
free(vect_lookup);
free(st_lookup);
}
/*
=================
Mod_LoadModel_MD3
@ -2211,7 +2323,7 @@ Mod_LoadLimits(const char *mod_name, void *extradata, modtype_t type)
{
R_Printf(PRINT_DEVELOPER, "%s: model %s mesh #%d: %d commands, %d tris\n",
__func__, mod_name, i, mesh_nodes[i].num_glcmds, mesh_nodes[i].num_tris);
num_glcmds += mesh_nodes[i].num_tris;
num_glcmds += mesh_nodes[i].num_glcmds;
}
R_Printf(PRINT_DEVELOPER,
"%s: model %s num tris %d / num vert %d / commands %d of %d\n",

View file

@ -40,7 +40,9 @@ extern void PrepareFrameVertex(dmdx_vert_t *vertexArray, int num_verts,
daliasxframe_t *frame_out);
extern void *Mod_LoadModel_MD5(const char *mod_name, const void *buffer,
int modfilelen, struct image_s ***skins, int *numskins, modtype_t *type);
extern int Mod_LoadCmdCompress(const dstvert_t *texcoords, dtriangle_t *triangles, int num_tris,
int *commands, int skinwidth, int skinheight);
extern int Mod_LoadCmdCompress(const dstvert_t *texcoords, dtriangle_t *triangles,
int num_tris, int *commands, int skinwidth, int skinheight);
extern void Mod_LoadTrisCompress(dmdx_t *pheader);
extern void Mod_LoadFixImages(const char* mod_name, dmdx_t *pheader, qboolean internal);
#endif /* SRC_CLIENT_REFRESH_FILES_MODELS_H_ */

View file

@ -1353,7 +1353,6 @@ Mod_LoadModel_MD5(const char *mod_name, const void *buffer, int modfilelen,
st[i].t = md5file->st[i][1] * pheader->skinheight;
}
num_tris = 0;
num_verts = 0;
@ -1361,10 +1360,6 @@ Mod_LoadModel_MD5(const char *mod_name, const void *buffer, int modfilelen,
{
int j;
mesh_nodes[i].ofs_glcmds = pglcmds - baseglcmds;
mesh_nodes[i].ofs_tris = num_tris;
mesh_nodes[i].num_tris = num_tris + md5file->meshes[i].num_tris;
for (j = 0; j < md5file->meshes[i].num_tris; j++)
{
int k;
@ -1378,36 +1373,21 @@ Mod_LoadModel_MD5(const char *mod_name, const void *buffer, int modfilelen,
tris[num_tris + j].index_st[k] = (num_tris + j) * 3 + k;
}
}
/* write glcmds */
for (j = 0; j < md5file->meshes[i].num_tris * 3; j++)
{
int vert_id;
vert_id = num_verts + md5file->meshes[i].triangles[j / 3].index[j % 3];
/* count */
if ((j % 3) == 0)
{
*pglcmds = 3;
pglcmds++;
num_verts += md5file->meshes[i].num_verts;
num_tris += md5file->meshes[i].num_tris;
}
/* st */
memcpy(pglcmds, &md5file->st[num_tris * 3 + j], sizeof(vec2_t));
pglcmds += 2;
/* index */
*pglcmds = vert_id;
pglcmds++;
}
Mod_LoadTrisCompress(pheader);
/* final zero */
*pglcmds = 0;
pglcmds++;
num_tris = 0;
num_verts = 0;
mesh_nodes[i].num_glcmds = pglcmds - baseglcmds - mesh_nodes[i].ofs_glcmds;
for (i = 0; i < md5file->num_meshes; ++i)
{
mesh_nodes[i].ofs_glcmds = pglcmds - baseglcmds;
mesh_nodes[i].ofs_tris = num_tris;
mesh_nodes[i].num_tris = num_tris + md5file->meshes[i].num_tris;
/*
Comressed version is much slower
mesh_nodes[i].num_glcmds = Mod_LoadCmdCompress(
(dstvert_t*)((byte *)pheader + pheader->ofs_st),
(dtriangle_t*)((byte *)pheader + pheader->ofs_tris) + num_tris,
@ -1416,7 +1396,6 @@ Mod_LoadModel_MD5(const char *mod_name, const void *buffer, int modfilelen,
pheader->skinwidth, pheader->skinheight);
pglcmds += mesh_nodes[i].num_glcmds;
*/
num_verts += md5file->meshes[i].num_verts;
num_tris += md5file->meshes[i].num_tris;
@ -1426,19 +1405,10 @@ Mod_LoadModel_MD5(const char *mod_name, const void *buffer, int modfilelen,
memcpy((char *)pheader + pheader->ofs_skins, md5file->skins,
pheader->num_skins * MAX_SKINNAME);
for (i = 0; i < pheader->num_skins; i++)
{
char *skin;
skin = (char *)pheader + pheader->ofs_skins + i * MAX_SKINNAME;
skin[MAX_SKINNAME - 1] = 0;
R_Printf(PRINT_DEVELOPER, "%s: %s #%d: Should load external '%s'\n",
__func__, mod_name, i, skin);
}
FreeModelMd5(md5file);
Mod_LoadFixImages(mod_name, pheader, false);
*type = mod_alias;
return extradata;