From 344f13204481d28cb7af2c8a37bfa77ee5ece6a4 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Sun, 17 Mar 2024 14:07:35 +0200 Subject: [PATCH] models: MDX mesh split by subobj value --- src/client/refresh/files/models.c | 121 +++++++++++++++++++++++++++--- src/common/header/files.h | 2 +- 2 files changed, 111 insertions(+), 12 deletions(-) diff --git a/src/client/refresh/files/models.c b/src/client/refresh/files/models.c index 318ff0e4..c89c886d 100644 --- a/src/client/refresh/files/models.c +++ b/src/client/refresh/files/models.c @@ -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); diff --git a/src/common/header/files.h b/src/common/header/files.h index ebdf562f..938855fb 100644 --- a/src/common/header/files.h +++ b/src/common/header/files.h @@ -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;