models: md3 compress commands

This commit is contained in:
Denis Pauk 2024-03-10 12:38:25 +02:00
parent b3eb00673b
commit 9952521af3

View file

@ -422,6 +422,11 @@ Mod_LoadFixImages(const char* mod_name, dmdx_t *pheader, qboolean internal)
{ {
int i; int i;
if (!pheader)
{
return;
}
for (i = 0; i < pheader->num_skins; i++) for (i = 0; i < pheader->num_skins; i++)
{ {
char *skin; char *skin;
@ -766,7 +771,6 @@ static int *used;
static int strip_xyz[128]; static int strip_xyz[128];
static int strip_st[128]; static int strip_st[128];
static int strip_tris[128]; static int strip_tris[128];
static int stripcount;
static int static int
md2_strip_length(int starttri, int startv, dtriangle_t *triangles, int num_tris) md2_strip_length(int starttri, int startv, dtriangle_t *triangles, int num_tris)
@ -776,6 +780,7 @@ md2_strip_length(int starttri, int startv, dtriangle_t *triangles, int num_tris)
int j; int j;
dtriangle_t *last, *check; dtriangle_t *last, *check;
int k; int k;
int stripcount;
used[starttri] = 2; used[starttri] = 2;
@ -802,20 +807,21 @@ nexttri:
{ {
for (k = 0; k < 3; k++) for (k = 0; k < 3; k++)
{ {
if (check->index_xyz[k] != m1) if ((check->index_xyz[k] != m1) ||
continue; (check->index_st[k] != st1) ||
if (check->index_st[k] != st1) (check->index_xyz[(k+1)%3] != m2) ||
continue; (check->index_st[(k+1)%3] != st2))
if (check->index_xyz[(k+1)%3] != m2) {
continue;
if (check->index_st[(k+1)%3] != st2)
continue; continue;
}
/* this is the next part of the fan */ /* this is the next part of the fan */
/* if we can't use this triangle, this tristrip is done */ /* if we can't use this triangle, this tristrip is done */
if (used[j]) if (used[j])
{
goto done; goto done;
}
/* the new edge */ /* the new edge */
if (stripcount & 1) if (stripcount & 1)
@ -842,8 +848,12 @@ done:
/* clear the temp used flags */ /* clear the temp used flags */
for (j = starttri + 1; j < num_tris; j++) for (j = starttri + 1; j < num_tris; j++)
{
if (used[j] == 2) if (used[j] == 2)
{
used[j] = 0; used[j] = 0;
}
}
return stripcount; return stripcount;
} }
@ -856,6 +866,7 @@ md2_fan_length(int starttri, int startv, dtriangle_t *triangles, int num_tris)
int j; int j;
dtriangle_t *last, *check; dtriangle_t *last, *check;
int k; int k;
int stripcount;
used[starttri] = 2; used[starttri] = 2;
@ -883,20 +894,21 @@ nexttri:
{ {
for (k = 0; k < 3; k++) for (k = 0; k < 3; k++)
{ {
if (check->index_xyz[k] != m1) if ((check->index_xyz[k] != m1) ||
continue; (check->index_st[k] != st1) ||
if (check->index_st[k] != st1) (check->index_xyz[(k+1)%3] != m2) ||
continue; (check->index_st[(k+1)%3] != st2))
if (check->index_xyz[(k+1)%3] != m2) {
continue;
if (check->index_st[(k+1)%3] != st2)
continue; continue;
}
/* this is the next part of the fan */ /* this is the next part of the fan */
/* if we can't use this triangle, this tristrip is done */ /* if we can't use this triangle, this tristrip is done */
if (used[j]) if (used[j])
{
goto done; goto done;
}
/* the new edge */ /* the new edge */
m2 = check->index_xyz[(k+2)%3]; m2 = check->index_xyz[(k+2)%3];
@ -915,8 +927,12 @@ done:
/* clear the temp used flags */ /* clear the temp used flags */
for (j = starttri + 1; j < num_tris; j++) for (j = starttri + 1; j < num_tris; j++)
{
if (used[j] == 2) if (used[j] == 2)
{
used[j] = 0; used[j] = 0;
}
}
return stripcount; return stripcount;
} }
@ -940,7 +956,9 @@ md2_build_glcmds(const dstvert_t *texcoords, dtriangle_t *triangles, int num_tri
{ {
/* pick an unused triangle and start the trifan */ /* pick an unused triangle and start the trifan */
if (used[i]) if (used[i])
{
continue; continue;
}
bestlen = 0; bestlen = 0;
for (type = 0; type < 2; type++) for (type = 0; type < 2; type++)
@ -948,41 +966,59 @@ md2_build_glcmds(const dstvert_t *texcoords, dtriangle_t *triangles, int num_tri
for (startv = 0; startv < 3; startv++) for (startv = 0; startv < 3; startv++)
{ {
if (type == 1) if (type == 1)
{
len = md2_strip_length(i, startv, triangles, num_tris); len = md2_strip_length(i, startv, triangles, num_tris);
}
else else
{
len = md2_fan_length(i, startv, triangles, num_tris); len = md2_fan_length(i, startv, triangles, num_tris);
}
if (len > bestlen) if (len > bestlen)
{ {
besttype = type; besttype = type;
bestlen = len; bestlen = len;
for (j = 0; j < bestlen + 2; j++) for (j = 0; j < bestlen + 2; j++)
{ {
best_st[j] = strip_st[j]; best_st[j] = strip_st[j];
best_xyz[j] = strip_xyz[j]; best_xyz[j] = strip_xyz[j];
} }
for (j = 0; j < bestlen; j++) for (j = 0; j < bestlen; j++)
{
best_tris[j] = strip_tris[j]; best_tris[j] = strip_tris[j];
} }
} }
} }
}
/* mark the tris on the best strip/fan as used */ /* mark the tris on the best strip/fan as used */
for (j = 0; j < bestlen; j++) for (j = 0; j < bestlen; j++)
{
used[best_tris[j]] = 1; used[best_tris[j]] = 1;
}
if (besttype == 1) if (besttype == 1)
{
commands[numcommands++] = (bestlen+2); commands[numcommands++] = (bestlen+2);
}
else else
{
commands[numcommands++] = -(bestlen+2); commands[numcommands++] = -(bestlen+2);
}
for (j = 0; j < bestlen + 2; j++) for (j = 0; j < bestlen + 2; j++)
{ {
union { float f; int i; } u; vec2_t cmdst;
u.f = (texcoords[best_st[j]].s + 0.5f) / skinwidth;
commands[numcommands++] = u.i; /* st */
u.f = (texcoords[best_st[j]].t + 0.5f) / skinheight; cmdst[0] = (texcoords[best_st[j]].s + 0.5f) / skinwidth;
commands[numcommands++] = u.i; cmdst[1] = (texcoords[best_st[j]].t + 0.5f) / skinheight;
memcpy(commands + numcommands, &cmdst, sizeof(cmdst));
numcommands += 2;
/* vert id */
commands[numcommands++] = best_xyz[j]; commands[numcommands++] = best_xyz[j];
} }
} }
@ -1004,7 +1040,7 @@ Mod_LoadModel_MD3(const char *mod_name, const void *buffer, int modfilelen,
struct image_s ***skins, int *numskins, modtype_t *type) struct image_s ***skins, int *numskins, modtype_t *type)
{ {
dmdx_t *pheader = NULL; dmdx_t *pheader = NULL;
int *baseglcmds; const int *baseglcmds;
md3_header_t pinmodel; md3_header_t pinmodel;
void *extradata; void *extradata;
int *pglcmds; int *pglcmds;
@ -1078,7 +1114,7 @@ Mod_LoadModel_MD3(const char *mod_name, const void *buffer, int modfilelen,
int ofs_skins = sizeof(dmdx_t); int ofs_skins = sizeof(dmdx_t);
int ofs_frames = ofs_skins + num_skins * MAX_SKINNAME; int ofs_frames = ofs_skins + num_skins * MAX_SKINNAME;
int ofs_glcmds = ofs_frames + framesize * pinmodel.num_frames; int ofs_glcmds = ofs_frames + framesize * pinmodel.num_frames;
int ofs_meshes = ofs_glcmds + num_glcmds * sizeof(int) * pinmodel.num_meshes; int ofs_meshes = ofs_glcmds + num_glcmds * sizeof(int);
int ofs_tris = ofs_meshes + pinmodel.num_meshes * sizeof(dmdxmesh_t); int ofs_tris = ofs_meshes + pinmodel.num_meshes * sizeof(dmdxmesh_t);
int ofs_st = ofs_tris + num_tris * sizeof(dtriangle_t); int ofs_st = ofs_tris + num_tris * sizeof(dtriangle_t);
int ofs_end = ofs_st + num_tris * 3 * sizeof(dstvert_t); int ofs_end = ofs_st + num_tris * 3 * sizeof(dstvert_t);
@ -1119,9 +1155,14 @@ Mod_LoadModel_MD3(const char *mod_name, const void *buffer, int modfilelen,
meshofs = pinmodel.ofs_meshes; meshofs = pinmodel.ofs_meshes;
for (i = 0; i < pinmodel.num_meshes; i++) for (i = 0; i < pinmodel.num_meshes; i++)
{ {
const md3_mesh_t *md3_mesh = (md3_mesh_t*)((byte*)buffer + meshofs); const md3_mesh_t *md3_mesh;
const float *fst = (const float*)((byte*)buffer + meshofs + LittleLong(md3_mesh->ofs_st)); md3_vertex_t *md3_vertex;
int j; const float *fst;
const int *p;
int j, k;
md3_mesh = (md3_mesh_t*)((byte*)buffer + meshofs);
fst = (const float*)((byte*)buffer + meshofs + LittleLong(md3_mesh->ofs_st));
/* load shaders */ /* load shaders */
for (j = 0; j < LittleLong(md3_mesh->num_shaders); j++) for (j = 0; j < LittleLong(md3_mesh->num_shaders); j++)
@ -1139,7 +1180,7 @@ Mod_LoadModel_MD3(const char *mod_name, const void *buffer, int modfilelen,
} }
/* load triangles */ /* load triangles */
const int *p = (const int*)((byte*)buffer + meshofs + LittleLong(md3_mesh->ofs_tris)); p = (const int*)((byte*)buffer + meshofs + LittleLong(md3_mesh->ofs_tris));
mesh_nodes[i].start = pglcmds - baseglcmds; mesh_nodes[i].start = pglcmds - baseglcmds;
@ -1153,53 +1194,17 @@ Mod_LoadModel_MD3(const char *mod_name, const void *buffer, int modfilelen,
tris[num_tris + j / 3].index_st[j % 3] = vert_id; tris[num_tris + j / 3].index_st[j % 3] = vert_id;
} }
if (1)
{
for (j = 0; j < LittleLong(md3_mesh->num_tris) * 3; j++)
{
int vert_id;
vec2_t cmdst;
/* count */
if ((j % 3) == 0)
{
*pglcmds = 3;
pglcmds++;
}
/* st */
cmdst[0] = LittleFloat(fst[LittleLong(p[j]) * 2 + 0]);
cmdst[1] = LittleFloat(fst[LittleLong(p[j]) * 2 + 1]);
memcpy(pglcmds, &cmdst, sizeof(cmdst));
pglcmds += 2;
/* index */
vert_id = LittleLong(p[j]) + num_xyz;
*pglcmds = vert_id;
pglcmds++;
}
/* final zero */
*pglcmds = 0;
pglcmds++;
mesh_nodes[i].num = pglcmds - baseglcmds - mesh_nodes[i].start;
}
else
{
/* write glcmds */ /* write glcmds */
mesh_nodes[i].num = md2_build_glcmds( mesh_nodes[i].num = md2_build_glcmds(
(dstvert_t*)((byte *)pheader + pheader->ofs_st), (dstvert_t*)((byte *)pheader + pheader->ofs_st),
(dtriangle_t*)((byte *)pheader + pheader->ofs_tris), (dtriangle_t*)((byte *)pheader + pheader->ofs_tris) + num_tris,
num_tris + LittleLong(md3_mesh->num_tris), LittleLong(md3_mesh->num_tris),
baseglcmds + mesh_nodes[i].start, pglcmds,
pheader->skinwidth, pheader->skinheight); pheader->skinwidth, pheader->skinheight);
pglcmds = baseglcmds + mesh_nodes[i].start + mesh_nodes[i].num; pglcmds += mesh_nodes[i].num;
}
md3_vertex_t *md3_vertex = (md3_vertex_t*)((byte*)buffer + meshofs + LittleLong(md3_mesh->ofs_verts)); md3_vertex = (md3_vertex_t*)((byte*)buffer + meshofs + LittleLong(md3_mesh->ofs_verts));
int k;
for (k = 0; k < pinmodel.num_frames; k ++) for (k = 0; k < pinmodel.num_frames; k ++)
{ {