X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=model_shared.c;h=e7d3228d13f8ed5e1fc377ccaf412ffaa1bea85c;hb=415f1e0e46791994cfa2f6dd3a29f793e3bb9cd9;hp=f4a1a1116b70eb8bc38a2d8a962a2e9c29405c23;hpb=8b6a72238c9e0686395f9849a9c00f8762f3a244;p=xonotic%2Fdarkplaces.git diff --git a/model_shared.c b/model_shared.c index f4a1a111..e7d3228d 100644 --- a/model_shared.c +++ b/model_shared.c @@ -4543,31 +4543,10 @@ msurface_t *Mod_Mesh_AddSurface(model_t *mod, texture_t *tex, qbool batchwithpre return surf; } -static void Mod_Mesh_RebuildHashTable(model_t *mod, msurface_t *surf) +int Mod_Mesh_IndexForVertex(model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a) { int hashindex, h, vnum, mask; surfmesh_t *mesh = &mod->surfmesh; - - // rebuild the hash table - mesh->num_vertexhashsize = 4 * mesh->max_vertices; - mesh->num_vertexhashsize &= ~(mesh->num_vertexhashsize - 1); // round down to pow2 - mesh->data_vertexhash = (int *)Mem_Realloc(mod->mempool, mesh->data_vertexhash, mesh->num_vertexhashsize * sizeof(*mesh->data_vertexhash)); - memset(mesh->data_vertexhash, -1, mesh->num_vertexhashsize * sizeof(*mesh->data_vertexhash)); - mask = mod->surfmesh.num_vertexhashsize - 1; - // no need to hash the vertices for the entire model, the latest surface will suffice. - for (vnum = surf ? surf->num_firstvertex : 0; vnum < mesh->num_vertices; vnum++) - { - // this uses prime numbers intentionally for computing the hash - hashindex = (unsigned int)(mesh->data_vertex3f[vnum * 3 + 0] * 2003 + mesh->data_vertex3f[vnum * 3 + 1] * 4001 + mesh->data_vertex3f[vnum * 3 + 2] * 7919 + mesh->data_normal3f[vnum * 3 + 0] * 4097 + mesh->data_normal3f[vnum * 3 + 1] * 257 + mesh->data_normal3f[vnum * 3 + 2] * 17) & mask; - for (h = hashindex; mesh->data_vertexhash[h] >= 0; h = (h + 1) & mask) - ; // just iterate until we find the terminator - mesh->data_vertexhash[h] = vnum; - } -} - -void Mod_Mesh_CheckResize_Vertex(model_t *mod, msurface_t *surf) -{ - surfmesh_t *mesh = &mod->surfmesh; if (mesh->max_vertices == mesh->num_vertices) { mesh->max_vertices = max(mesh->num_vertices * 2, 256); @@ -4578,15 +4557,36 @@ void Mod_Mesh_CheckResize_Vertex(model_t *mod, msurface_t *surf) mesh->data_texcoordtexture2f = (float *)Mem_Realloc(mod->mempool, mesh->data_texcoordtexture2f, mesh->max_vertices * sizeof(float[2])); mesh->data_texcoordlightmap2f = (float *)Mem_Realloc(mod->mempool, mesh->data_texcoordlightmap2f, mesh->max_vertices * sizeof(float[2])); mesh->data_lightmapcolor4f = (float *)Mem_Realloc(mod->mempool, mesh->data_lightmapcolor4f, mesh->max_vertices * sizeof(float[4])); - Mod_Mesh_RebuildHashTable(mod, surf); + // rebuild the hash table + mesh->num_vertexhashsize = 4 * mesh->max_vertices; + mesh->num_vertexhashsize &= ~(mesh->num_vertexhashsize - 1); // round down to pow2 + mesh->data_vertexhash = (int *)Mem_Realloc(mod->mempool, mesh->data_vertexhash, mesh->num_vertexhashsize * sizeof(*mesh->data_vertexhash)); + memset(mesh->data_vertexhash, -1, mesh->num_vertexhashsize * sizeof(*mesh->data_vertexhash)); + mask = mod->surfmesh.num_vertexhashsize - 1; + // no need to hash the vertices for the entire model, the latest surface will suffice. + for (vnum = surf ? surf->num_firstvertex : 0; vnum < mesh->num_vertices; vnum++) + { + // this uses prime numbers intentionally for computing the hash + hashindex = (unsigned int)(mesh->data_vertex3f[vnum * 3 + 0] * 2003 + mesh->data_vertex3f[vnum * 3 + 1] * 4001 + mesh->data_vertex3f[vnum * 3 + 2] * 7919 + mesh->data_normal3f[vnum * 3 + 0] * 4097 + mesh->data_normal3f[vnum * 3 + 1] * 257 + mesh->data_normal3f[vnum * 3 + 2] * 17) & mask; + for (h = hashindex; mesh->data_vertexhash[h] >= 0; h = (h + 1) & mask) + ; // just iterate until we find the terminator + mesh->data_vertexhash[h] = vnum; + } + } + mask = mod->surfmesh.num_vertexhashsize - 1; + // this uses prime numbers intentionally for computing the hash + hashindex = (unsigned int)(x * 2003 + y * 4001 + z * 7919 + nx * 4097 + ny * 257 + nz * 17) & mask; + // when possible find an identical vertex within the same surface and return it + for(h = hashindex;(vnum = mesh->data_vertexhash[h]) >= 0;h = (h + 1) & mask) + { + if (vnum >= surf->num_firstvertex + && mesh->data_vertex3f[vnum * 3 + 0] == x && mesh->data_vertex3f[vnum * 3 + 1] == y && mesh->data_vertex3f[vnum * 3 + 2] == z + && mesh->data_normal3f[vnum * 3 + 0] == nx && mesh->data_normal3f[vnum * 3 + 1] == ny && mesh->data_normal3f[vnum * 3 + 2] == nz + && mesh->data_texcoordtexture2f[vnum * 2 + 0] == s && mesh->data_texcoordtexture2f[vnum * 2 + 1] == t + && mesh->data_texcoordlightmap2f[vnum * 2 + 0] == u && mesh->data_texcoordlightmap2f[vnum * 2 + 1] == v + && mesh->data_lightmapcolor4f[vnum * 4 + 0] == r && mesh->data_lightmapcolor4f[vnum * 4 + 1] == g && mesh->data_lightmapcolor4f[vnum * 4 + 2] == b && mesh->data_lightmapcolor4f[vnum * 4 + 3] == a) + return vnum; } -} - -int Mod_Mesh_AddVertex(model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a) -{ - int vnum; - surfmesh_t *mesh = &mod->surfmesh; - // add the new vertex vnum = mesh->num_vertices++; if (surf->num_vertices > 0) @@ -4604,6 +4604,7 @@ int Mod_Mesh_AddVertex(model_t *mod, msurface_t *surf, float x, float y, float z VectorSet(surf->maxs, x, y, z); } surf->num_vertices = mesh->num_vertices - surf->num_firstvertex; + mesh->data_vertexhash[h] = vnum; mesh->data_vertex3f[vnum * 3 + 0] = x; mesh->data_vertex3f[vnum * 3 + 1] = y; mesh->data_vertex3f[vnum * 3 + 2] = z; @@ -4621,32 +4622,6 @@ int Mod_Mesh_AddVertex(model_t *mod, msurface_t *surf, float x, float y, float z return vnum; } -int Mod_Mesh_IndexForVertex(model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a) -{ - int hashindex, h, vnum, mask; - surfmesh_t *mesh = &mod->surfmesh; - - Mod_Mesh_CheckResize_Vertex(mod, surf); - - mask = mod->surfmesh.num_vertexhashsize - 1; - // this uses prime numbers intentionally for computing the hash - hashindex = (unsigned int)(x * 2003 + y * 4001 + z * 7919 + nx * 4097 + ny * 257 + nz * 17) & mask; - // when possible find an identical vertex within the same surface and return it - for(h = hashindex;(vnum = mesh->data_vertexhash[h]) >= 0;h = (h + 1) & mask) - { - if (vnum >= surf->num_firstvertex - && mesh->data_vertex3f[vnum * 3 + 0] == x && mesh->data_vertex3f[vnum * 3 + 1] == y && mesh->data_vertex3f[vnum * 3 + 2] == z - && mesh->data_normal3f[vnum * 3 + 0] == nx && mesh->data_normal3f[vnum * 3 + 1] == ny && mesh->data_normal3f[vnum * 3 + 2] == nz - && mesh->data_texcoordtexture2f[vnum * 2 + 0] == s && mesh->data_texcoordtexture2f[vnum * 2 + 1] == t - && mesh->data_texcoordlightmap2f[vnum * 2 + 0] == u && mesh->data_texcoordlightmap2f[vnum * 2 + 1] == v - && mesh->data_lightmapcolor4f[vnum * 4 + 0] == r && mesh->data_lightmapcolor4f[vnum * 4 + 1] == g && mesh->data_lightmapcolor4f[vnum * 4 + 2] == b && mesh->data_lightmapcolor4f[vnum * 4 + 3] == a) - return vnum; - } - vnum = Mod_Mesh_AddVertex(mod, surf, x, y, z, nx, ny, nz, s, t, u, v, r, g, b, a); - mesh->data_vertexhash[h] = vnum; - return vnum; -} - void Mod_Mesh_AddTriangle(model_t *mod, msurface_t *surf, int e0, int e1, int e2) { surfmesh_t *mesh = &mod->surfmesh;