]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_shared.c
some cleanup of Mod_Alias_GetMesh_Vertex3f
[xonotic/darkplaces.git] / model_shared.c
index 558e0deaba79b3b3a83f45812b01852acfbcfefa..92f7ea5117bb73c6c2088777303d9d84fd755bcd 100644 (file)
@@ -30,16 +30,25 @@ cvar_t r_mipskins = {CVAR_SAVE, "r_mipskins", "0", "mipmaps skins (so they becom
 
 model_t *loadmodel;
 
+#if 0
+// LordHavoc: was 512
+static int mod_numknown = 0;
+static int mod_maxknown = 0;
+static model_t *mod_known = NULL;
+#else
 // LordHavoc: was 512
 #define MAX_MOD_KNOWN (MAX_MODELS + 256)
+static int mod_numknown = 0;
+static int mod_maxknown = MAX_MOD_KNOWN;
 static model_t mod_known[MAX_MOD_KNOWN];
+#endif
 
 static void mod_start(void)
 {
        int i;
        model_t *mod;
 
-       for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++)
+       for (i = 0, mod = mod_known;i < mod_numknown;i++, mod++)
                if (mod->name[0])
                        if (mod->used)
                                Mod_LoadModel(mod, true, false, mod->isworldmodel);
@@ -50,7 +59,7 @@ static void mod_shutdown(void)
        int i;
        model_t *mod;
 
-       for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++)
+       for (i = 0, mod = mod_known;i < mod_numknown;i++, mod++)
                if (mod->loaded)
                        Mod_UnloadModel(mod);
 }
@@ -63,7 +72,7 @@ static void mod_newmap(void)
        if (!cl_stainmaps_clearonload.integer)
                return;
 
-       for (i = 0;i < MAX_MOD_KNOWN;i++)
+       for (i = 0;i < mod_numknown;i++)
        {
                if (mod_known[i].mempool && mod_known[i].data_surfaces)
                {
@@ -160,7 +169,12 @@ model_t *Mod_LoadModel(model_t *mod, qboolean crash, qboolean checkdisk, qboolea
                }
        }
        if (mod->loaded)
-               return mod; // already loaded
+       {
+               // already loaded
+               if (buf)
+                       Mem_Free(buf);
+               return mod;
+       }
 
        Con_DPrintf("loading model %s\n", mod->name);
        // LordHavoc: unload the existing model in this slot (if there is one)
@@ -221,22 +235,13 @@ model_t *Mod_LoadModel(model_t *mod, qboolean crash, qboolean checkdisk, qboolea
        return mod;
 }
 
-/*
-===================
-Mod_ClearAll
-===================
-*/
-void Mod_ClearAll(void)
-{
-}
-
 void Mod_ClearUsed(void)
 {
 #if 0
        int i;
        model_t *mod;
 
-       for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++)
+       for (i = 0, mod = mod_known;i < mod_numknown;i++, mod++)
                if (mod->name[0])
                        mod->used = false;
 #endif
@@ -247,7 +252,7 @@ void Mod_PurgeUnused(void)
        int i;
        model_t *mod;
 
-       for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++)
+       for (i = 0, mod = mod_known;i < mod_numknown;i++, mod++)
                if (mod->name[0])
                        if (!mod->used)
                                Mod_UnloadModel(mod);
@@ -259,7 +264,7 @@ void Mod_RemoveStaleWorldModels(model_t *skip)
        int i;
        model_t *mod;
 
-       for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++)
+       for (i = 0, mod = mod_known;i < mod_numknown;i++, mod++)
        {
                if (mod->isworldmodel && mod->loaded && skip != mod)
                {
@@ -279,38 +284,49 @@ Mod_FindName
 model_t *Mod_FindName(const char *name)
 {
        int i;
-       model_t *mod, *freemod;
+       model_t *mod;
 
        if (!name[0])
                Host_Error ("Mod_ForName: NULL name");
 
 // search the currently loaded models
-       freemod = NULL;
-       for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++)
+       for (i = 0, mod = mod_known;i < mod_numknown;i++, mod++)
        {
-               if (mod->name[0])
+               if (mod->name[0] && !strcmp(mod->name, name))
                {
-                       if (!strcmp (mod->name, name))
-                       {
-                               mod->used = true;
-                               return mod;
-                       }
+                       mod->used = true;
+                       return mod;
                }
-               else if (freemod == NULL)
-                       freemod = mod;
        }
 
-       if (freemod)
+       // no match found, find room for a new one
+       for (i = 0;i < mod_numknown;i++)
+               if (!mod_known[i].name[0])
+                       break;
+
+       if (mod_maxknown == i)
        {
-               mod = freemod;
-               strcpy (mod->name, name);
-               mod->loaded = false;
-               mod->used = true;
-               return mod;
+#if 0
+               model_t *old;
+               mod_maxknown += 256;
+               old = mod_known;
+               mod_known = Mem_Alloc(mod_mempool, mod_maxknown * sizeof(model_t));
+               if (old)
+               {
+                       memcpy(mod_known, old, mod_numknown * sizeof(model_t));
+                       Mem_Free(old);
+               }
+#else
+               Host_Error ("Mod_FindName: ran out of models");
+#endif
        }
-
-       Host_Error ("Mod_FindName: ran out of models");
-       return NULL;
+       if (mod_numknown == i)
+               mod_numknown++;
+       mod = mod_known + i;
+       strcpy (mod->name, name);
+       mod->loaded = false;
+       mod->used = true;
+       return mod;
 }
 
 /*
@@ -345,7 +361,7 @@ static void Mod_Print(void)
        model_t *mod;
 
        Con_Print("Loaded models:\n");
-       for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++)
+       for (i = 0, mod = mod_known;i < mod_numknown;i++, mod++)
                if (mod->name[0])
                        Con_Printf("%4iK %s\n", mod->mempool ? (mod->mempool->totalsize + 1023) / 1024 : 0, mod->name);
 }
@@ -486,19 +502,19 @@ void Mod_BuildTriangleNeighbors(int *neighbors, const int *elements, int numtria
 }
 #endif
 
-void Mod_ValidateElements(int *elements, int numtriangles, int numverts, const char *filename, int fileline)
+void Mod_ValidateElements(int *elements, int numtriangles, int firstvertex, int numverts, const char *filename, int fileline)
 {
-       int i, warned = false;
+       int i, warned = false, endvertex = firstvertex + numverts;
        for (i = 0;i < numtriangles * 3;i++)
        {
-               if ((unsigned int)elements[i] >= (unsigned int)numverts)
+               if (elements[i] < firstvertex || elements[i] >= endvertex)
                {
                        if (!warned)
                        {
                                warned = true;
                                Con_Printf("Mod_ValidateElements: out of bounds elements detected at %s:%d\n", filename, fileline);
                        }
-                       elements[i] = 0;
+                       elements[i] = firstvertex;
                }
        }
 }
@@ -691,34 +707,31 @@ void Mod_BuildTextureVectorsAndNormals(int firstvertex, int numvertices, int num
                        VectorNormalize(v);
 }
 
-surfmesh_t *Mod_AllocSurfMesh(mempool_t *mempool, int numvertices, int numtriangles, qboolean lightmapoffsets, qboolean vertexcolors, qboolean neighbors)
+void Mod_AllocSurfMesh(mempool_t *mempool, int numvertices, int numtriangles, qboolean lightmapoffsets, qboolean vertexcolors, qboolean neighbors)
 {
-       surfmesh_t *mesh;
        unsigned char *data;
-       mesh = (surfmesh_t *)Mem_Alloc(mempool, sizeof(surfmesh_t) + numvertices * (3 + 3 + 3 + 3 + 2 + 2 + (vertexcolors ? 4 : 0)) * sizeof(float) + numvertices * (lightmapoffsets ? 1 : 0) * sizeof(int) + numtriangles * (3 + (neighbors ? 3 : 0)) * sizeof(int));
-       mesh->num_vertices = numvertices;
-       mesh->num_triangles = numtriangles;
-       data = (unsigned char *)(mesh + 1);
-       if (mesh->num_vertices)
+       data = (unsigned char *)Mem_Alloc(mempool, numvertices * (3 + 3 + 3 + 3 + 2 + 2 + (vertexcolors ? 4 : 0)) * sizeof(float) + numvertices * (lightmapoffsets ? 1 : 0) * sizeof(int) + numtriangles * (3 + (neighbors ? 3 : 0)) * sizeof(int));
+       loadmodel->surfmesh.num_vertices = numvertices;
+       loadmodel->surfmesh.num_triangles = numtriangles;
+       if (loadmodel->surfmesh.num_vertices)
        {
-               mesh->data_vertex3f = (float *)data, data += sizeof(float[3]) * mesh->num_vertices;
-               mesh->data_svector3f = (float *)data, data += sizeof(float[3]) * mesh->num_vertices;
-               mesh->data_tvector3f = (float *)data, data += sizeof(float[3]) * mesh->num_vertices;
-               mesh->data_normal3f = (float *)data, data += sizeof(float[3]) * mesh->num_vertices;
-               mesh->data_texcoordtexture2f = (float *)data, data += sizeof(float[2]) * mesh->num_vertices;
-               mesh->data_texcoordlightmap2f = (float *)data, data += sizeof(float[2]) * mesh->num_vertices;
+               loadmodel->surfmesh.data_vertex3f = (float *)data, data += sizeof(float[3]) * loadmodel->surfmesh.num_vertices;
+               loadmodel->surfmesh.data_svector3f = (float *)data, data += sizeof(float[3]) * loadmodel->surfmesh.num_vertices;
+               loadmodel->surfmesh.data_tvector3f = (float *)data, data += sizeof(float[3]) * loadmodel->surfmesh.num_vertices;
+               loadmodel->surfmesh.data_normal3f = (float *)data, data += sizeof(float[3]) * loadmodel->surfmesh.num_vertices;
+               loadmodel->surfmesh.data_texcoordtexture2f = (float *)data, data += sizeof(float[2]) * loadmodel->surfmesh.num_vertices;
+               loadmodel->surfmesh.data_texcoordlightmap2f = (float *)data, data += sizeof(float[2]) * loadmodel->surfmesh.num_vertices;
                if (vertexcolors)
-                       mesh->data_lightmapcolor4f = (float *)data, data += sizeof(float[4]) * mesh->num_vertices;
+                       loadmodel->surfmesh.data_lightmapcolor4f = (float *)data, data += sizeof(float[4]) * loadmodel->surfmesh.num_vertices;
                if (lightmapoffsets)
-                       mesh->data_lightmapoffsets = (int *)data, data += sizeof(int) * mesh->num_vertices;
+                       loadmodel->surfmesh.data_lightmapoffsets = (int *)data, data += sizeof(int) * loadmodel->surfmesh.num_vertices;
        }
-       if (mesh->num_triangles)
+       if (loadmodel->surfmesh.num_triangles)
        {
-               mesh->data_element3i = (int *)data, data += sizeof(int[3]) * mesh->num_triangles;
+               loadmodel->surfmesh.data_element3i = (int *)data, data += sizeof(int[3]) * loadmodel->surfmesh.num_triangles;
                if (neighbors)
-                       mesh->data_neighbor3i = (int *)data, data += sizeof(int[3]) * mesh->num_triangles;
+                       loadmodel->surfmesh.data_neighbor3i = (int *)data, data += sizeof(int[3]) * loadmodel->surfmesh.num_triangles;
        }
-       return mesh;
 }
 
 shadowmesh_t *Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts, int maxtriangles, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, int light, int neighbors, int expandable)
@@ -1031,7 +1044,7 @@ int Mod_LoadSkinFrame_Internal(skinframe_t *skinframe, const char *basename, int
                                        break;
                        if (i < width * height * 4)
                        {
-                               unsigned char *fogpixels = Mem_Alloc(loadmodel->mempool, width * height * 4);
+                               unsigned char *fogpixels = (unsigned char *)Mem_Alloc(loadmodel->mempool, width * height * 4);
                                memcpy(fogpixels, skindata, width * height * 4);
                                for (i = 0;i < width * height * 4;i += 4)
                                        fogpixels[i] = fogpixels[i+1] = fogpixels[i+2] = 255;
@@ -1185,12 +1198,12 @@ tag_torso,
                // If it's the first file we parse
                if (skinfile == NULL)
                {
-                       skinfile = (skinfile_t *)Mem_Alloc(tempmempool, sizeof(skinfile_t));
+                       skinfile = (skinfile_t *)Mem_Alloc(loadmodel->mempool, sizeof(skinfile_t));
                        first = skinfile;
                }
                else
                {
-                       skinfile->next = (skinfile_t *)Mem_Alloc(tempmempool, sizeof(skinfile_t));
+                       skinfile->next = (skinfile_t *)Mem_Alloc(loadmodel->mempool, sizeof(skinfile_t));
                        skinfile = skinfile->next;
                }
                skinfile->next = NULL;
@@ -1223,7 +1236,7 @@ tag_torso,
                                if (words == 3)
                                {
                                        Con_DPrintf("Mod_LoadSkinFiles: parsed mesh \"%s\" shader replacement \"%s\"\n", word[1], word[2]);
-                                       skinfileitem = (skinfileitem_t *)Mem_Alloc(tempmempool, sizeof(skinfileitem_t));
+                                       skinfileitem = (skinfileitem_t *)Mem_Alloc(loadmodel->mempool, sizeof(skinfileitem_t));
                                        skinfileitem->next = skinfile->items;
                                        skinfile->items = skinfileitem;
                                        strlcpy (skinfileitem->name, word[1], sizeof (skinfileitem->name));
@@ -1244,7 +1257,7 @@ tag_torso,
                        {
                                // mesh shader name, like "U_RArm,models/players/Legoman/BikerA1.tga"
                                Con_DPrintf("Mod_LoadSkinFiles: parsed mesh \"%s\" shader replacement \"%s\"\n", word[0], word[2]);
-                               skinfileitem = (skinfileitem_t *)Mem_Alloc(tempmempool, sizeof(skinfileitem_t));
+                               skinfileitem = (skinfileitem_t *)Mem_Alloc(loadmodel->mempool, sizeof(skinfileitem_t));
                                skinfileitem->next = skinfile->items;
                                skinfile->items = skinfileitem;
                                strlcpy (skinfileitem->name, word[0], sizeof (skinfileitem->name));