models: MDX mesh split by subobj value

This commit is contained in:
Denis Pauk 2024-03-17 14:07:35 +02:00
parent bb3ac6ef9c
commit 344f132044
2 changed files with 111 additions and 12 deletions

View file

@ -284,6 +284,111 @@ Mod_LoadMD2TriangleList(dmdx_t *pheader, const dtriangle_t *pintri)
}
}
/*
=================
Mod_LoadMDXTriangleList
Load MDX triangle lists
=================
*/
static void
Mod_LoadMDXTriangleList(const char *mod_name, dmdx_t *pheader, const dtriangle_t *pintri,
const int *glcmds, int num_glcmds)
{
const dtriangle_t *pouttriofs;
dmdxmesh_t *mesh_nodes;
dtriangle_t *pouttri;
const int *glcmds_end;
dstvert_t *stvert;
int m, *mesh_ids;
pouttriofs = pouttri = (dtriangle_t *) ((char *)pheader + pheader->ofs_tris);
mesh_nodes = (dmdxmesh_t *)((char *)pheader + pheader->ofs_meshes);
pouttri = (dtriangle_t *) ((byte *)pheader + pheader->ofs_tris);
stvert = (dstvert_t *)((byte *)pheader + pheader->ofs_st);
mesh_ids = (int *)calloc(pheader->num_xyz, sizeof(int));
glcmds_end = glcmds + num_glcmds;
while (1)
{
int count, mesh_id;
/* get the vertex count and primitive type */
count = LittleLong(*glcmds++);
if (!count || glcmds >= glcmds_end)
{
break; /* done */
}
if (count < 0)
{
count = -count;
}
/* num meshes should be same as subobjects */
mesh_id = LittleLong(*glcmds++) % pheader->num_meshes;
do
{
int index_xyz;
vec2_t st;
memcpy(&st, glcmds, sizeof(st));
index_xyz = LittleLong(glcmds[2]);
mesh_ids[index_xyz] = mesh_id;
stvert[index_xyz].s = LittleFloat(st[0]) * pheader->skinwidth;
stvert[index_xyz].t = LittleFloat(st[1]) * pheader->skinheight;
glcmds += 3;
}
while (--count);
}
for (m = 0; m < pheader->num_meshes; m++)
{
int i;
mesh_nodes[m].ofs_tris = pouttri - pouttriofs;
for (i = 0; i < pheader->num_tris; i++)
{
int j, index[3];
for (j = 0; j < 3; j++)
{
index[j] = LittleShort(pintri[i].index_xyz[j]);
}
/* sanity check for verts */
if (mesh_ids[index[0]] != mesh_ids[index[1]] ||
mesh_ids[index[1]] != mesh_ids[index[2]])
{
R_Printf(PRINT_DEVELOPER,
"%s: %s: Mesh detect could be wrong (%d != %d != %d)\n",
__func__, mod_name,
mesh_ids[index[0]], mesh_ids[index[1]], mesh_ids[index[2]]);
}
/* use only first vert for mesh detect */
if (mesh_ids[LittleShort(pintri[i].index_xyz[0])] == m)
{
for (j = 0; j < 3; j++)
{
pouttri->index_xyz[j] = index[j];
/* ST is always zero in input */
pouttri->index_st[j] = index[j];
}
pouttri++;
}
}
mesh_nodes[m].num_tris = pouttri - pouttriofs - mesh_nodes[m].ofs_tris;
}
free(mesh_ids);
}
/*
=================
Mod_LoadMD2TriangleList
@ -2333,7 +2438,6 @@ Mod_LoadModel_MDX(const char *mod_name, const void *buffer, int modfilelen,
dmdx_t dmdxheader, *pheader = NULL;
vec3_t translate = {0, 0, 0};
mdx_header_t header = {0};
dmdxmesh_t *mesh_nodes;
void *extradata = NULL;
int i;
@ -2377,7 +2481,7 @@ Mod_LoadModel_MDX(const char *mod_name, const void *buffer, int modfilelen,
dmdxheader.framesize = sizeof(daliasxframe_t) - sizeof(dxtrivertx_t);
dmdxheader.framesize += header.num_xyz * sizeof(dxtrivertx_t);
dmdxheader.num_meshes = 1;
dmdxheader.num_meshes = header.num_subobj;
dmdxheader.num_skins = header.num_skins;
dmdxheader.num_xyz = header.num_xyz;
dmdxheader.num_st = header.num_xyz;
@ -2402,19 +2506,14 @@ Mod_LoadModel_MDX(const char *mod_name, const void *buffer, int modfilelen,
memcpy(pheader, &dmdxheader, sizeof(dmdxheader));
/* create single mesh */
mesh_nodes = (dmdxmesh_t *)((char *)pheader + pheader->ofs_meshes);
mesh_nodes[0].ofs_tris = 0;
mesh_nodes[0].num_tris = pheader->num_tris;
memcpy((byte*)pheader + pheader->ofs_skins, (byte *)buffer + header.ofs_skins,
pheader->num_skins * MAX_SKINNAME);
Mod_LoadSTvertList(pheader,
(dstvert_t *)((byte *)buffer + header.ofs_st));
Mod_LoadMDXTriangleList(mod_name, pheader,
(dtriangle_t *)((byte *)buffer + header.ofs_tris),
(int*)((byte *)buffer + header.ofs_glcmds),
header.num_glcmds);
Mod_LoadFrames_MD2(pheader, (byte *)buffer + header.ofs_frames,
header.framesize, translate);
Mod_LoadMD2TriangleList(pheader,
(dtriangle_t *)((byte *)buffer + header.ofs_tris));
Mod_LoadCmdGenerate(pheader);
Mod_LoadFixImages(mod_name, pheader, false);

View file

@ -309,7 +309,7 @@ typedef struct mdx_header_s
int ofs_tris; /* offset for dtriangles */
int ofs_frames; /* offset for first frame */
int ofs_glcmds;
int ofs_st;
int ofs_verts; /* link vert to subobj */
int ofs_sfxdef;
int ofs_sfxent;
int ofs_bbox;