]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
Replaced some model fields and changed their purpose slightly to simplify a lot of...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 19 Dec 2020 10:19:47 +0000 (10:19 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 19 Dec 2020 10:19:47 +0000 (10:19 +0000)
model->firstmodelsurface : model->submodelsurfaces_start
model->nummodelsurfaces : replaced with model->submodelsurfaces_end
model->sortedmodelsurfaces : replaced with model->modelsurfaces_sorted (which starts at surface 0, not firstmodelsurface).

Changed the implementation of MakeSortedSurfaces so that it now sorts by effect, texture, lightmap, previously it didn't care about lightmap or effect.

No behavior changes.

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@13072 d7cf8633-e32d-0410-b094-e92efae38249

gl_rmain.c
gl_rsurf.c
model_alias.c
model_brush.c
model_shared.c
model_shared.h
prvm_cmds.c
r_shadow.c
world.c

index e348e3e9427b4229ed84b7b51bf90f563cec5a16..5482cc5b234c9e1b493b07d1d97f038d2fd0e81f 100644 (file)
@@ -9315,11 +9315,8 @@ static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldor
        model_t *model;
        const msurface_t *surface;
        const msurface_t *surfaces;
-       const int *surfacelist;
        const texture_t *texture;
        int numtriangles;
-       int numsurfacelist;
-       int surfacelistindex;
        int surfaceindex;
        int triangleindex;
        float localorigin[3];
@@ -9412,8 +9409,6 @@ static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldor
 #endif
 
        dynamic = model->surfmesh.isanimated;
-       numsurfacelist = model->nummodelsurfaces;
-       surfacelist = model->sortedmodelsurfaces;
        surfaces = model->data_surfaces;
 
        bih = NULL;
@@ -9449,9 +9444,8 @@ static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldor
        }
        else
        {
-               for (surfacelistindex = 0;surfacelistindex < numsurfacelist;surfacelistindex++)
+               for (surfaceindex = model->submodelsurfaces_start;surfaceindex < model->submodelsurfaces_end;surfaceindex++)
                {
-                       surfaceindex = surfacelist[surfacelistindex];
                        surface = surfaces + surfaceindex;
                        // check cull box first because it rejects more than any other check
                        if (!dynamic && !BoxesOverlap(surface->mins, surface->maxs, localmins, localmaxs))
@@ -9777,7 +9771,7 @@ static void R_DrawModelDecals(void)
 static void R_DrawDebugModel(void)
 {
        entity_render_t *ent = rsurface.entity;
-       int i, j, flagsmask;
+       int j, flagsmask;
        const msurface_t *surface;
        model_t *model = ent->model;
 
@@ -9793,10 +9787,11 @@ static void R_DrawDebugModel(void)
                GL_DepthMask(false);
                GL_DepthRange(0, 1);
                GL_BlendFunc(GL_ONE, GL_ONE);
-               for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
+               for (j = model->submodelsurfaces_start;j < model->submodelsurfaces_end;j++)
                {
                        if (ent == r_refdef.scene.worldentity && !r_refdef.viewcache.world_surfacevisible[j])
                                continue;
+                       surface = model->data_surfaces + j;
                        rsurface.texture = R_GetCurrentTexture(surface->texture);
                        if ((rsurface.texture->currentmaterialflags & flagsmask) && surface->num_triangles)
                        {
@@ -9887,10 +9882,11 @@ static void R_DrawDebugModel(void)
                        GL_DepthMask(true);
                }
                qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);CHECKGLERROR
-               for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
+               for (j = model->submodelsurfaces_start; j < model->submodelsurfaces_end; j++)
                {
                        if (ent == r_refdef.scene.worldentity && !r_refdef.viewcache.world_surfacevisible[j])
                                continue;
+                       surface = model->data_surfaces + j;
                        rsurface.texture = R_GetCurrentTexture(surface->texture);
                        if ((rsurface.texture->currentmaterialflags & flagsmask) && surface->num_triangles)
                        {
@@ -9925,10 +9921,11 @@ static void R_DrawDebugModel(void)
                        GL_BlendFunc(GL_ONE, GL_ZERO);
                        GL_DepthMask(true);
                }
-               for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
+               for (j = model->submodelsurfaces_start; j < model->submodelsurfaces_end; j++)
                {
                        if (ent == r_refdef.scene.worldentity && !r_refdef.viewcache.world_surfacevisible[j])
                                continue;
+                       surface = model->data_surfaces + j;
                        rsurface.texture = R_GetCurrentTexture(surface->texture);
                        if ((rsurface.texture->currentmaterialflags & flagsmask) && surface->num_triangles)
                        {
@@ -10034,7 +10031,7 @@ void R_DrawModelSurfaces(entity_render_t *ent, qbool skysurfaces, qbool writedep
        }
 
        // check if this is an empty model
-       if (model->nummodelsurfaces == 0)
+       if (model->submodelsurfaces_start >= model->submodelsurfaces_end)
                return;
 
        rsurface.lightmaptexture = NULL;
@@ -10048,9 +10045,9 @@ void R_DrawModelSurfaces(entity_render_t *ent, qbool skysurfaces, qbool writedep
        if (ent == r_refdef.scene.worldentity)
        {
                // for the world entity, check surfacevisible
-               for (i = 0;i < model->nummodelsurfaces;i++)
+               for (i = model->submodelsurfaces_start;i < model->submodelsurfaces_end;i++)
                {
-                       j = model->sortedmodelsurfaces[i];
+                       j = model->modelsurfaces_sorted[i];
                        if (r_refdef.viewcache.world_surfacevisible[j])
                                r_surfacelist[numsurfacelist++] = surfaces + j;
                }
@@ -10065,14 +10062,14 @@ void R_DrawModelSurfaces(entity_render_t *ent, qbool skysurfaces, qbool writedep
        else if (ui)
        {
                // for ui we have to preserve the order of surfaces (not using sortedmodelsurfaces)
-               for (i = 0; i < model->nummodelsurfaces; i++)
-                       r_surfacelist[numsurfacelist++] = surfaces + model->firstmodelsurface + i;
+               for (i = model->submodelsurfaces_start; i < model->submodelsurfaces_end; i++)
+                       r_surfacelist[numsurfacelist++] = surfaces + i;
        }
        else
        {
                // add all surfaces
-               for (i = 0; i < model->nummodelsurfaces; i++)
-                       r_surfacelist[numsurfacelist++] = surfaces + model->sortedmodelsurfaces[i];
+               for (i = model->submodelsurfaces_start; i < model->submodelsurfaces_end; i++)
+                       r_surfacelist[numsurfacelist++] = surfaces + model->modelsurfaces_sorted[i];
        }
 
        /*
index 512b94919a0b975848bcc8c2f51676578c340463..603666a3ee4a99eda55e1da4968ac31df9b1da39 100644 (file)
@@ -411,8 +411,6 @@ void R_DrawPortals(void)
 static void R_View_WorldVisibility_CullSurfaces(void)
 {
        int surfaceindex;
-       int surfaceindexstart;
-       int surfaceindexend;
        unsigned char *surfacevisible;
        msurface_t *surfaces;
        model_t *model = r_refdef.scene.worldmodel;
@@ -422,11 +420,9 @@ static void R_View_WorldVisibility_CullSurfaces(void)
                return;
        if (r_usesurfaceculling.integer < 1)
                return;
-       surfaceindexstart = model->firstmodelsurface;
-       surfaceindexend = surfaceindexstart + model->nummodelsurfaces;
        surfaces = model->data_surfaces;
        surfacevisible = r_refdef.viewcache.world_surfacevisible;
-       for (surfaceindex = surfaceindexstart; surfaceindex < surfaceindexend; surfaceindex++)
+       for (surfaceindex = model->submodelsurfaces_start; surfaceindex < model->submodelsurfaces_end; surfaceindex++)
        {
                if (surfacevisible[surfaceindex])
                {
@@ -620,9 +616,9 @@ void R_Mod_DrawAddWaterPlanes(entity_render_t *ent)
        // add visible surfaces to draw list
        if (ent == r_refdef.scene.worldentity)
        {
-               for (i = 0;i < model->nummodelsurfaces;i++)
+               for (i = model->submodelsurfaces_start;i < model->submodelsurfaces_end;i++)
                {
-                       j = model->sortedmodelsurfaces[i];
+                       j = model->modelsurfaces_sorted[i];
                        if (r_refdef.viewcache.world_surfacevisible[j])
                                if (surfaces[j].texture->basematerialflags & flagsmask)
                                        R_Water_AddWaterPlane(surfaces + j, 0);
@@ -634,9 +630,9 @@ void R_Mod_DrawAddWaterPlanes(entity_render_t *ent)
                        n = ent->entitynumber;
                else
                        n = 0;
-               for (i = 0;i < model->nummodelsurfaces;i++)
+               for (i = model->submodelsurfaces_start;i < model->submodelsurfaces_end;i++)
                {
-                       j = model->sortedmodelsurfaces[i];
+                       j = model->modelsurfaces_sorted[i];
                        if (surfaces[j].texture->basematerialflags & flagsmask)
                                R_Water_AddWaterPlane(surfaces + j, n);
                }
@@ -1140,7 +1136,7 @@ static void R_Q1BSP_CallRecursiveGetLightInfo(r_q1bsp_getlightinfo_t *info, qboo
                info->outnumleafs = 0;
                info->outnumsurfaces = 0;
                memset(info->outleafpvs, 0, (info->model->brush.num_leafs + 7) >> 3);
-               memset(info->outsurfacepvs, 0, (info->model->nummodelsurfaces + 7) >> 3);
+               memset(info->outsurfacepvs, 0, (info->model->num_surfaces + 7) >> 3);
                memset(info->outshadowtrispvs, 0, (info->model->surfmesh.num_triangles + 7) >> 3);
                memset(info->outlighttrispvs, 0, (info->model->surfmesh.num_triangles + 7) >> 3);
        }
@@ -1246,7 +1242,7 @@ void R_Mod_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, float
        VectorCopy(info.relativelightorigin, info.outmaxs);
        memset(visitingleafpvs, 0, (info.model->brush.num_leafs + 7) >> 3);
        memset(outleafpvs, 0, (info.model->brush.num_leafs + 7) >> 3);
-       memset(outsurfacepvs, 0, (info.model->nummodelsurfaces + 7) >> 3);
+       memset(outsurfacepvs, 0, (info.model->num_surfaces + 7) >> 3);
        memset(outshadowtrispvs, 0, (info.model->surfmesh.num_triangles + 7) >> 3);
        memset(outlighttrispvs, 0, (info.model->surfmesh.num_triangles + 7) >> 3);
        if (info.model->brush.GetPVS && !info.noocclusion)
index 95f61ab79cbd33d8b1efac4f56887c6d5570493a..f438da4b148e329311cfe162e91a3052597efd45 100644 (file)
@@ -1020,11 +1020,12 @@ void Mod_IDP0_Load(model_t *mod, void *buffer, void *bufferend)
        loadmodel->AnimateVertices = Mod_MDL_AnimateVertices;
 
        loadmodel->num_surfaces = 1;
-       loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
+       loadmodel->submodelsurfaces_start = 0;
+       loadmodel->submodelsurfaces_end = loadmodel->num_surfaces;
        data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int));
        loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
-       loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
-       loadmodel->sortedmodelsurfaces[0] = 0;
+       loadmodel->modelsurfaces_sorted = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
+       loadmodel->modelsurfaces_sorted[0] = 0;
 
        loadmodel->numskins = LittleLong(pinmodel->numskins);
        BOUNDI(loadmodel->numskins,0,65536);
@@ -1411,11 +1412,12 @@ void Mod_IDP2_Load(model_t *mod, void *buffer, void *bufferend)
        iskinheight = 1.0f / skinheight;
 
        loadmodel->num_surfaces = 1;
-       loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
+       loadmodel->submodelsurfaces_start = 0;
+       loadmodel->submodelsurfaces_end = loadmodel->num_surfaces;
        data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->numframes * sizeof(animscene_t) + loadmodel->numframes * sizeof(float[6]) + loadmodel->surfmesh.num_triangles * sizeof(int[3]));
        loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
-       loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
-       loadmodel->sortedmodelsurfaces[0] = 0;
+       loadmodel->modelsurfaces_sorted = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
+       loadmodel->modelsurfaces_sorted[0] = 0;
        loadmodel->animscenes = (animscene_t *)data;data += loadmodel->numframes * sizeof(animscene_t);
        loadmodel->surfmesh.data_morphmd2framesize6f = (float *)data;data += loadmodel->numframes * sizeof(float[6]);
        loadmodel->surfmesh.data_element3i = (int *)data;data += loadmodel->surfmesh.num_triangles * sizeof(int[3]);
@@ -1692,12 +1694,13 @@ void Mod_IDP3_Load(model_t *mod, void *buffer, void *bufferend)
                meshtriangles += LittleLong(pinmesh->num_triangles);
        }
 
-       loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
+       loadmodel->submodelsurfaces_start = 0;
+       loadmodel->submodelsurfaces_end = loadmodel->num_surfaces;
        loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
        loadmodel->num_texturesperskin = loadmodel->num_surfaces;
        data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshvertices * sizeof(float[2]) + meshvertices * loadmodel->numframes * sizeof(md3vertex_t));
        loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
-       loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
+       loadmodel->modelsurfaces_sorted = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
        loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
        loadmodel->surfmesh.num_vertices = meshvertices;
        loadmodel->surfmesh.num_triangles = meshtriangles;
@@ -1717,7 +1720,7 @@ void Mod_IDP3_Load(model_t *mod, void *buffer, void *bufferend)
        {
                if (memcmp(pinmesh->identifier, "IDP3", 4))
                        Host_Error("Mod_IDP3_Load: invalid mesh identifier (not IDP3)");
-               loadmodel->sortedmodelsurfaces[i] = i;
+               loadmodel->modelsurfaces_sorted[i] = i;
                surface = loadmodel->data_surfaces + i;
                surface->texture = loadmodel->data_textures + i;
                surface->num_firsttriangle = meshtriangles;
@@ -1959,12 +1962,13 @@ void Mod_ZYMOTICMODEL_Load(model_t *mod, void *buffer, void *bufferend)
        meshvertices = pheader->numverts;
        meshtriangles = pheader->numtris;
 
-       loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
+       loadmodel->submodelsurfaces_start = 0;
+       loadmodel->submodelsurfaces_end = loadmodel->num_surfaces;
        loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
        loadmodel->num_texturesperskin = loadmodel->num_surfaces;
        data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshvertices * (sizeof(float[14]) + sizeof(unsigned short) + sizeof(unsigned char[2][4])) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[7]) + loadmodel->num_bones * sizeof(float[12]));
        loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
-       loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
+       loadmodel->modelsurfaces_sorted = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
        loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
        loadmodel->surfmesh.num_vertices = meshvertices;
        loadmodel->surfmesh.num_triangles = meshtriangles;
@@ -2107,7 +2111,7 @@ void Mod_ZYMOTICMODEL_Load(model_t *mod, void *buffer, void *bufferend)
                if (renderlist + count * 3 > renderlistend || (i == pheader->numshaders - 1 && renderlist + count * 3 != renderlistend))
                        Host_Error("%s corrupt renderlist (wrong size)", loadmodel->name);
 
-               loadmodel->sortedmodelsurfaces[i] = i;
+               loadmodel->modelsurfaces_sorted[i] = i;
                surface = loadmodel->data_surfaces + i;
                surface->texture = loadmodel->data_textures + i;
                surface->num_firsttriangle = meshtriangles;
@@ -2283,13 +2287,14 @@ void Mod_DARKPLACESMODEL_Load(model_t *mod, void *buffer, void *bufferend)
        loadmodel->numframes = pheader->num_frames;
        loadmodel->num_bones = pheader->num_bones;
        loadmodel->num_poses = loadmodel->numframes;
-       loadmodel->nummodelsurfaces = loadmodel->num_surfaces = pheader->num_meshs;
+       loadmodel->submodelsurfaces_start = 0;
+       loadmodel->submodelsurfaces_end = loadmodel->num_surfaces = pheader->num_meshs;
        loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
        loadmodel->num_texturesperskin = loadmodel->num_surfaces;
        // do most allocations as one merged chunk
        data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshvertices * (sizeof(float[14]) + sizeof(unsigned short) + sizeof(unsigned char[2][4])) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[7]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t));
        loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
-       loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
+       loadmodel->modelsurfaces_sorted = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
        loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
        loadmodel->surfmesh.num_vertices = meshvertices;
        loadmodel->surfmesh.num_triangles = meshtriangles;
@@ -2413,7 +2418,7 @@ void Mod_DARKPLACESMODEL_Load(model_t *mod, void *buffer, void *bufferend)
                const float *intexcoord;
                msurface_t *surface;
 
-               loadmodel->sortedmodelsurfaces[i] = i;
+               loadmodel->modelsurfaces_sorted[i] = i;
                surface = loadmodel->data_surfaces + i;
                surface->texture = loadmodel->data_textures + i;
                surface->num_firsttriangle = meshtriangles;
@@ -2944,7 +2949,8 @@ void Mod_PSKMODEL_Load(model_t *mod, void *buffer, void *bufferend)
                loadmodel->numskins = 1;
        loadmodel->num_bones = numbones;
        loadmodel->num_poses = loadmodel->numframes;
-       loadmodel->nummodelsurfaces = loadmodel->num_surfaces = nummatts;
+       loadmodel->submodelsurfaces_start = 0;
+       loadmodel->submodelsurfaces_end = loadmodel->num_surfaces = nummatts;
        loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
        loadmodel->num_texturesperskin = loadmodel->num_surfaces;
        loadmodel->surfmesh.num_vertices = meshvertices;
@@ -2953,7 +2959,7 @@ void Mod_PSKMODEL_Load(model_t *mod, void *buffer, void *bufferend)
        size = loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + loadmodel->surfmesh.num_triangles * sizeof(int[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[2]) + loadmodel->surfmesh.num_vertices * sizeof(unsigned char[4]) + loadmodel->surfmesh.num_vertices * sizeof(unsigned char[4]) + loadmodel->surfmesh.num_vertices * sizeof(unsigned short) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[7]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t) + ((loadmodel->surfmesh.num_vertices <= 65536) ? (loadmodel->surfmesh.num_triangles * sizeof(unsigned short[3])) : 0);
        data = (unsigned char *)Mem_Alloc(loadmodel->mempool, size);
        loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
-       loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
+       loadmodel->modelsurfaces_sorted = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
        loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
        loadmodel->surfmesh.data_element3i = (int *)data;data += loadmodel->surfmesh.num_triangles * sizeof(int[3]);
        loadmodel->surfmesh.data_vertex3f = (float *)data;data += loadmodel->surfmesh.num_vertices * sizeof(float[3]);
@@ -2989,7 +2995,7 @@ void Mod_PSKMODEL_Load(model_t *mod, void *buffer, void *bufferend)
        {
                // since psk models do not have named sections, reuse their shader name as the section name
                Mod_BuildAliasSkinsFromSkinFiles(loadmodel->data_textures + index, skinfiles, matts[index].name, matts[index].name);
-               loadmodel->sortedmodelsurfaces[index] = index;
+               loadmodel->modelsurfaces_sorted[index] = index;
                loadmodel->data_surfaces[index].texture = loadmodel->data_textures + index;
                loadmodel->data_surfaces[index].num_firstvertex = 0;
                loadmodel->data_surfaces[index].num_vertices = loadmodel->surfmesh.num_vertices;
@@ -3429,7 +3435,8 @@ void Mod_INTERQUAKEMODEL_Load(model_t *mod, void *buffer, void *bufferend)
        loadmodel->numframes = max(header.num_anims, 1);
        loadmodel->num_bones = header.num_joints;
        loadmodel->num_poses = max(header.num_frames, 1);
-       loadmodel->nummodelsurfaces = loadmodel->num_surfaces = header.num_meshes;
+       loadmodel->submodelsurfaces_start = 0;
+       loadmodel->submodelsurfaces_end = loadmodel->num_surfaces = header.num_meshes;
        loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
        loadmodel->num_texturesperskin = loadmodel->num_surfaces;
 
@@ -3439,7 +3446,7 @@ void Mod_INTERQUAKEMODEL_Load(model_t *mod, void *buffer, void *bufferend)
        // do most allocations as one merged chunk
        data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshvertices * (sizeof(float[14]) + (vcolor4f || vcolor4ub ? sizeof(float[4]) : 0)) + (vblendindexes && vblendweights ? meshvertices * (sizeof(unsigned short) + sizeof(unsigned char[2][4])) : 0) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[7]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t));
        loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
-       loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
+       loadmodel->modelsurfaces_sorted = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
        loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
        loadmodel->surfmesh.num_vertices = meshvertices;
        loadmodel->surfmesh.num_triangles = meshtriangles;
@@ -3922,7 +3929,7 @@ void Mod_INTERQUAKEMODEL_Load(model_t *mod, void *buffer, void *bufferend)
                mesh.first_triangle = LittleLong(meshes[i].first_triangle);
                mesh.num_triangles = LittleLong(meshes[i].num_triangles);
 
-               loadmodel->sortedmodelsurfaces[i] = i;
+               loadmodel->modelsurfaces_sorted[i] = i;
                surface = loadmodel->data_surfaces + i;
                surface->texture = loadmodel->data_textures + i;
                surface->num_firsttriangle = mesh.first_triangle;
index cc52e72e2111fd90a4a1c6e0183c201a7db2037f..a40c8687132880be87500fdc9f5fe9afae57cedd 100644 (file)
@@ -3246,12 +3246,13 @@ static void Mod_Q1BSP_LoadPlanes(sizebuf_t *sb)
 // fixes up sky surfaces that have SKY contents behind them, so that they do not cast shadows (e1m5 logo shadow trick).
 static void Mod_Q1BSP_AssignNoShadowSkySurfaces(model_t *mod)
 {
-       int i;
+       int surfaceindex;
        msurface_t *surface;
        vec3_t center;
        int contents;
-       for (i = 0, surface = mod->data_surfaces + mod->firstmodelsurface; i < mod->nummodelsurfaces; i++, surface++)
+       for (surfaceindex = mod->submodelsurfaces_start; surfaceindex < mod->submodelsurfaces_end;surfaceindex++)
        {
+               surface = mod->data_surfaces + surfaceindex;
                if (surface->texture->basematerialflags & MATERIALFLAG_SKY)
                {
                        // check if the point behind the surface polygon is SOLID or SKY contents
@@ -4049,6 +4050,7 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
                }
        }
        datapointer = (unsigned char *)Mem_Alloc(mod->mempool, mod->num_surfaces * sizeof(int) + totalstyles * sizeof(model_brush_lightstyleinfo_t) + totalstylesurfaces * sizeof(int *));
+       mod->modelsurfaces_sorted = (int*)datapointer;datapointer += mod->num_surfaces * sizeof(int);
        for (i = 0;i < mod->brush.numsubmodels;i++)
        {
                // LadyHavoc: this code was originally at the end of this loop, but
@@ -4092,8 +4094,8 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
                        mod->brushq1.hulls[j].lastclipnode = mod->brushq1.numclipnodes - 1;
                }
 
-               mod->firstmodelsurface = bm->firstface;
-               mod->nummodelsurfaces = bm->numfaces;
+               mod->submodelsurfaces_start = bm->firstface;
+               mod->submodelsurfaces_end = bm->firstface + bm->numfaces;
 
                // set node/leaf parents for this submodel
                Mod_BSP_LoadNodes_RecursiveSetParent(mod->brush.data_nodes + mod->brushq1.hulls[0].firstclipnode, NULL);
@@ -4101,10 +4103,6 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
                // this has to occur after hull info has been set, as it uses Mod_Q1BSP_PointSuperContents
                Mod_Q1BSP_AssignNoShadowSkySurfaces(mod);
 
-               // make the model surface list (used by shadowing/lighting)
-               mod->sortedmodelsurfaces = (int *)datapointer;datapointer += mod->nummodelsurfaces * sizeof(int);
-               Mod_MakeSortedSurfaces(mod);
-
                // copy the submodel bounds, then enlarge the yaw and rotated bounds according to radius
                // (previously this code measured the radius of the vertices of surfaces in the submodel, but that broke submodels that contain only CLIP brushes, which do not produce surfaces)
                VectorCopy(bm->mins, mod->normalmins);
@@ -4131,30 +4129,27 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
 
                // scan surfaces for sky and water and flag the submodel as possessing these features or not
                // build lightstyle lists for quick marking of dirty lightmaps when lightstyles flicker
-               if (mod->nummodelsurfaces)
+               if (mod->submodelsurfaces_start < mod->submodelsurfaces_end)
                {
-                       for (j = 0, surface = &mod->data_surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surface++)
-                               if (surface->texture->basematerialflags & MATERIALFLAG_SKY)
+                       for (j = mod->submodelsurfaces_start; j < mod->submodelsurfaces_end; j++)
+                               if (mod->data_surfaces[j].texture->basematerialflags & MATERIALFLAG_SKY)
                                        break;
-                       if (j < mod->nummodelsurfaces)
+                       if (j < mod->submodelsurfaces_end)
                                mod->DrawSky = R_Mod_DrawSky;
 
-                       for (j = 0, surface = &mod->data_surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surface++)
-                               if (surface->texture && surface->texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
+                       for (j = mod->submodelsurfaces_start;j < mod->submodelsurfaces_end;j++)
+                               if (mod->data_surfaces[j].texture && mod->data_surfaces[j].texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
                                        break;
-                       if (j < mod->nummodelsurfaces)
+                       if (j < mod->submodelsurfaces_end)
                                mod->DrawAddWaterPlanes = R_Mod_DrawAddWaterPlanes;
 
                        // build lightstyle update chains
                        // (used to rapidly mark lightmapupdateflags on many surfaces
                        // when d_lightstylevalue changes)
                        memset(stylecounts, 0, sizeof(stylecounts));
-                       for (k = 0;k < mod->nummodelsurfaces;k++)
-                       {
-                               surface = mod->data_surfaces + mod->firstmodelsurface + k;
+                       for (k = mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
                                for (j = 0;j < MAXLIGHTMAPS;j++)
-                                       stylecounts[surface->lightmapinfo->styles[j]]++;
-                       }
+                                       stylecounts[mod->data_surfaces[k].lightmapinfo->styles[j]]++;
                        mod->brushq1.num_lightstyles = 0;
                        for (k = 0;k < 255;k++)
                        {
@@ -4168,15 +4163,15 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
                                        mod->brushq1.num_lightstyles++;
                                }
                        }
-                       for (k = 0;k < mod->nummodelsurfaces;k++)
+                       for (k = mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
                        {
-                               surface = mod->data_surfaces + mod->firstmodelsurface + k;
+                               surface = mod->data_surfaces + k;
                                for (j = 0;j < MAXLIGHTMAPS;j++)
                                {
                                        if (surface->lightmapinfo->styles[j] != 255)
                                        {
                                                int r = remapstyles[surface->lightmapinfo->styles[j]];
-                                               styleinfo[r].surfacelist[styleinfo[r].numsurfaces++] = mod->firstmodelsurface + k;
+                                               styleinfo[r].surfacelist[styleinfo[r].numsurfaces++] = k;
                                        }
                                }
                        }
@@ -4211,6 +4206,10 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
                        //Mod_Q1BSP_ProcessLightList();
                }
        }
+       mod = loadmodel;
+
+       // make the model surface list (used by shadowing/lighting)
+       Mod_MakeSortedSurfaces(loadmodel);
 
        Con_DPrintf("Stats for q1bsp model \"%s\": %i faces, %i nodes, %i leafs, %i visleafs, %i visleafportals, mesh: %i vertices, %i triangles, %i surfaces\n", loadmodel->name, loadmodel->num_surfaces, loadmodel->brush.num_nodes, loadmodel->brush.num_leafs, mod->brush.num_pvsclusters, loadmodel->brush.num_portals, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->num_surfaces);
 }
@@ -4984,6 +4983,7 @@ static void Mod_Q2BSP_Load(model_t *mod, void *buffer, void *bufferend)
                }
        }
        datapointer = (unsigned char *)Mem_Alloc(mod->mempool, mod->num_surfaces * sizeof(int) + totalstyles * sizeof(model_brush_lightstyleinfo_t) + totalstylesurfaces * sizeof(int *));
+       mod->modelsurfaces_sorted = (int*)datapointer; datapointer += mod->num_surfaces * sizeof(int);
        // set up the world model, then on each submodel copy from the world model
        // and set up the submodel with the respective model info.
        mod = loadmodel;
@@ -5023,8 +5023,8 @@ static void Mod_Q2BSP_Load(model_t *mod, void *buffer, void *bufferend)
                // we store the headnode (there's only one in Q2BSP) as if it were the first hull
                mod->brushq1.hulls[0].firstclipnode = bm->headnode[0];
 
-               mod->firstmodelsurface = bm->firstface;
-               mod->nummodelsurfaces = bm->numfaces;
+               mod->submodelsurfaces_start = bm->firstface;
+               mod->submodelsurfaces_end = bm->firstface + bm->numfaces;
 
                // set node/leaf parents for this submodel
                // note: if the root of this submodel is a leaf (headnode[0] < 0) then there is nothing to do...
@@ -5036,7 +5036,6 @@ static void Mod_Q2BSP_Load(model_t *mod, void *buffer, void *bufferend)
                Mod_BSP_LoadNodes_RecursiveSetParent(rootnode, NULL);
 
                // make the model surface list (used by shadowing/lighting)
-               mod->sortedmodelsurfaces = (int *)datapointer;datapointer += mod->nummodelsurfaces * sizeof(int);
                Mod_Q2BSP_FindSubmodelBrushRange_r(mod, rootnode, &firstbrush, &lastbrush);
                if (firstbrush <= lastbrush)
                {
@@ -5048,7 +5047,6 @@ static void Mod_Q2BSP_Load(model_t *mod, void *buffer, void *bufferend)
                        mod->firstmodelbrush = 0;
                        mod->nummodelbrushes = 0;
                }
-               Mod_MakeSortedSurfaces(mod);
 
                VectorCopy(bm->mins, mod->normalmins);
                VectorCopy(bm->maxs, mod->normalmaxs);
@@ -5074,30 +5072,27 @@ static void Mod_Q2BSP_Load(model_t *mod, void *buffer, void *bufferend)
 
                // scan surfaces for sky and water and flag the submodel as possessing these features or not
                // build lightstyle lists for quick marking of dirty lightmaps when lightstyles flicker
-               if (mod->nummodelsurfaces)
+               if (mod->submodelsurfaces_start < mod->submodelsurfaces_end)
                {
-                       for (j = 0, surface = &mod->data_surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surface++)
-                               if (surface->texture->basematerialflags & MATERIALFLAG_SKY)
+                       for (j = mod->submodelsurfaces_start;j < mod->submodelsurfaces_end;j++)
+                               if (mod->data_surfaces[j].texture && (mod->data_surfaces[j].texture->basematerialflags & MATERIALFLAG_SKY))
                                        break;
-                       if (j < mod->nummodelsurfaces)
+                       if (j < mod->submodelsurfaces_end)
                                mod->DrawSky = R_Mod_DrawSky;
 
-                       for (j = 0, surface = &mod->data_surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surface++)
-                               if (surface->texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
+                       for (j = mod->submodelsurfaces_start;j < mod->submodelsurfaces_end;j++)
+                               if (mod->data_surfaces[j].texture && (mod->data_surfaces[j].texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA)))
                                        break;
-                       if (j < mod->nummodelsurfaces)
+                       if (j < mod->submodelsurfaces_end)
                                mod->DrawAddWaterPlanes = R_Mod_DrawAddWaterPlanes;
 
                        // build lightstyle update chains
                        // (used to rapidly mark lightmapupdateflags on many surfaces
                        // when d_lightstylevalue changes)
                        memset(stylecounts, 0, sizeof(stylecounts));
-                       for (k = 0;k < mod->nummodelsurfaces;k++)
-                       {
-                               surface = mod->data_surfaces + mod->firstmodelsurface + k;
+                       for (k = mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
                                for (j = 0;j < MAXLIGHTMAPS;j++)
-                                       stylecounts[surface->lightmapinfo->styles[j]]++;
-                       }
+                                       stylecounts[mod->data_surfaces[k].lightmapinfo->styles[j]]++;
                        mod->brushq1.num_lightstyles = 0;
                        for (k = 0;k < 255;k++)
                        {
@@ -5111,15 +5106,15 @@ static void Mod_Q2BSP_Load(model_t *mod, void *buffer, void *bufferend)
                                        mod->brushq1.num_lightstyles++;
                                }
                        }
-                       for (k = 0;k < mod->nummodelsurfaces;k++)
+                       for (k = mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
                        {
-                               surface = mod->data_surfaces + mod->firstmodelsurface + k;
+                               surface = mod->data_surfaces + k;
                                for (j = 0;j < MAXLIGHTMAPS;j++)
                                {
                                        if (surface->lightmapinfo->styles[j] != 255)
                                        {
                                                int r = remapstyles[surface->lightmapinfo->styles[j]];
-                                               styleinfo[r].surfacelist[styleinfo[r].numsurfaces++] = mod->firstmodelsurface + k;
+                                               styleinfo[r].surfacelist[styleinfo[r].numsurfaces++] = k;
                                        }
                                }
                        }
@@ -5144,6 +5139,9 @@ static void Mod_Q2BSP_Load(model_t *mod, void *buffer, void *bufferend)
        }
        mod = loadmodel;
 
+       // make the model surface list (used by shadowing/lighting)
+       Mod_MakeSortedSurfaces(loadmodel);
+
        Con_DPrintf("Stats for q2bsp model \"%s\": %i faces, %i nodes, %i leafs, %i clusters, %i clusterportals, mesh: %i vertices, %i triangles, %i surfaces\n", loadmodel->name, loadmodel->num_surfaces, loadmodel->brush.num_nodes, loadmodel->brush.num_leafs, mod->brush.num_pvsclusters, loadmodel->brush.num_portals, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->num_surfaces);
 }
 
@@ -7227,7 +7225,6 @@ bih_t *Mod_MakeCollisionBIH(model_t *model, qbool userendersurfaces, bih_t *out)
        int triangleindex;
        int bihleafindex;
        int nummodelbrushes = model->nummodelbrushes;
-       int nummodelsurfaces = model->nummodelsurfaces;
        const int *e;
        const int *collisionelement3i;
        const float *collisionvertex3f;
@@ -7244,20 +7241,20 @@ bih_t *Mod_MakeCollisionBIH(model_t *model, qbool userendersurfaces, bih_t *out)
        bihnumleafs = 0;
        if (userendersurfaces)
        {
-               for (j = 0, surface = model->data_surfaces + model->firstmodelsurface;j < nummodelsurfaces;j++, surface++)
-                       bihnumleafs += surface->num_triangles;
+               for (j = model->submodelsurfaces_start;j < model->submodelsurfaces_end;j++)
+                       bihnumleafs += model->data_surfaces[j].num_triangles;
        }
        else
        {
                for (brushindex = 0, brush = model->brush.data_brushes + brushindex+model->firstmodelbrush;brushindex < nummodelbrushes;brushindex++, brush++)
                        if (brush->colbrushf)
                                bihnumleafs++;
-               for (j = 0, surface = model->data_surfaces + model->firstmodelsurface;j < nummodelsurfaces;j++, surface++)
+               for (j = model->submodelsurfaces_start;j < model->submodelsurfaces_end;j++)
                {
-                       if (surface->texture->basematerialflags & MATERIALFLAG_MESHCOLLISIONS)
-                               bihnumleafs += surface->num_triangles + surface->num_collisiontriangles;
+                       if (model->data_surfaces[j].texture->basematerialflags & MATERIALFLAG_MESHCOLLISIONS)
+                               bihnumleafs += model->data_surfaces[j].num_triangles + model->data_surfaces[j].num_collisiontriangles;
                        else
-                               bihnumleafs += surface->num_collisiontriangles;
+                               bihnumleafs += model->data_surfaces[j].num_collisiontriangles;
                }
        }
 
@@ -7273,8 +7270,9 @@ bih_t *Mod_MakeCollisionBIH(model_t *model, qbool userendersurfaces, bih_t *out)
        // add render surfaces
        renderelement3i = model->surfmesh.data_element3i;
        rendervertex3f = model->surfmesh.data_vertex3f;
-       for (j = 0, surface = model->data_surfaces + model->firstmodelsurface;j < nummodelsurfaces;j++, surface++)
+       for (j = model->submodelsurfaces_start; j < model->submodelsurfaces_end; j++)
        {
+               surface = model->data_surfaces + j;
                for (triangleindex = 0, e = renderelement3i + 3*surface->num_firsttriangle;triangleindex < surface->num_triangles;triangleindex++, e += 3)
                {
                        if (!userendersurfaces && !(surface->texture->basematerialflags & MATERIALFLAG_MESHCOLLISIONS))
@@ -7312,8 +7310,9 @@ bih_t *Mod_MakeCollisionBIH(model_t *model, qbool userendersurfaces, bih_t *out)
                // add collision surfaces
                collisionelement3i = model->brush.data_collisionelement3i;
                collisionvertex3f = model->brush.data_collisionvertex3f;
-               for (j = 0, surface = model->data_surfaces + model->firstmodelsurface;j < nummodelsurfaces;j++, surface++)
+               for (j = model->submodelsurfaces_start; j < model->submodelsurfaces_end; j++)
                {
+                       surface = model->data_surfaces + j;
                        for (triangleindex = 0, e = collisionelement3i + 3*surface->num_firstcollisiontriangle;triangleindex < surface->num_collisiontriangles;triangleindex++, e += 3)
                        {
                                bihleafs[bihleafindex].type = BIH_COLLISIONTRIANGLE;
@@ -7595,12 +7594,11 @@ static void Mod_Q3BSP_Load(model_t *mod, void *buffer, void *bufferend)
                        loadmodel->brush.submodels[i] = mod;
 
                // make the model surface list (used by shadowing/lighting)
-               mod->firstmodelsurface = mod->brushq3.data_models[i].firstface;
-               mod->nummodelsurfaces = mod->brushq3.data_models[i].numfaces;
+               mod->submodelsurfaces_start = mod->brushq3.data_models[i].firstface;
+               mod->submodelsurfaces_end = mod->brushq3.data_models[i].firstface + mod->brushq3.data_models[i].numfaces;
                mod->firstmodelbrush = mod->brushq3.data_models[i].firstbrush;
                mod->nummodelbrushes = mod->brushq3.data_models[i].numbrushes;
-               mod->sortedmodelsurfaces = (int *)Mem_Alloc(loadmodel->mempool, mod->nummodelsurfaces * sizeof(*mod->sortedmodelsurfaces));
-               Mod_MakeSortedSurfaces(mod);
+               mod->modelsurfaces_sorted = (int *)Mem_Alloc(loadmodel->mempool, mod->num_surfaces * sizeof(*mod->modelsurfaces_sorted));
 
                VectorCopy(mod->brushq3.data_models[i].mins, mod->normalmins);
                VectorCopy(mod->brushq3.data_models[i].maxs, mod->normalmaxs);
@@ -7610,9 +7608,9 @@ static void Mod_Q3BSP_Load(model_t *mod, void *buffer, void *bufferend)
                // outside the level - an unimportant concern)
 
                //printf("Editing model %d... BEFORE re-bounding: %f %f %f - %f %f %f\n", i, mod->normalmins[0], mod->normalmins[1], mod->normalmins[2], mod->normalmaxs[0], mod->normalmaxs[1], mod->normalmaxs[2]);
-               for (j = 0;j < mod->nummodelsurfaces;j++)
+               for (j = mod->submodelsurfaces_start;j < mod->submodelsurfaces_end;j++)
                {
-                       const msurface_t *surface = mod->data_surfaces + j + mod->firstmodelsurface;
+                       const msurface_t *surface = mod->data_surfaces + j + mod->submodelsurfaces_start;
                        const float *v = mod->surfmesh.data_vertex3f + 3 * surface->num_firstvertex;
                        int k;
                        if (!surface->num_vertices)
@@ -7646,16 +7644,16 @@ static void Mod_Q3BSP_Load(model_t *mod, void *buffer, void *bufferend)
                mod->DrawSky = NULL;
                mod->DrawAddWaterPlanes = NULL;
 
-               for (j = 0;j < mod->nummodelsurfaces;j++)
-                       if (mod->data_surfaces[j + mod->firstmodelsurface].texture->basematerialflags & MATERIALFLAG_SKY)
+               for (j = mod->submodelsurfaces_start;j < mod->submodelsurfaces_end;j++)
+                       if (mod->data_surfaces[j].texture && mod->data_surfaces[j].texture->basematerialflags & MATERIALFLAG_SKY)
                                break;
-               if (j < mod->nummodelsurfaces)
+               if (j < mod->submodelsurfaces_end)
                        mod->DrawSky = R_Mod_DrawSky;
 
-               for (j = 0;j < mod->nummodelsurfaces;j++)
-                       if (mod->data_surfaces[j + mod->firstmodelsurface].texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
+               for (j = mod->submodelsurfaces_start; j < mod->submodelsurfaces_end; j++)
+                       if (mod->data_surfaces[j].texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
                                break;
-               if (j < mod->nummodelsurfaces)
+               if (j < mod->submodelsurfaces_end)
                        mod->DrawAddWaterPlanes = R_Mod_DrawAddWaterPlanes;
 
                Mod_MakeCollisionBIH(mod, false, &mod->collision_bih);
@@ -7665,6 +7663,10 @@ static void Mod_Q3BSP_Load(model_t *mod, void *buffer, void *bufferend)
                if (i == 0)
                        Mod_BuildVBOs();
        }
+       mod = loadmodel;
+
+       // make the model surface list (used by shadowing/lighting)
+       Mod_MakeSortedSurfaces(loadmodel);
 
        if (mod_q3bsp_sRGBlightmaps.integer)
        {
@@ -8137,7 +8139,7 @@ void Mod_OBJ_Load(model_t *mod, void *buffer, void *bufferend)
        loadmodel->num_texturesperskin = numtextures;
        data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + numtriangles * sizeof(int[3]) + (numvertices <= 65536 ? numtriangles * sizeof(unsigned short[3]) : 0) + numvertices * sizeof(float[14]) + loadmodel->brush.numsubmodels * sizeof(model_t *));
        loadmodel->brush.submodels = (model_t **)data;data += loadmodel->brush.numsubmodels * sizeof(model_t *);
-       loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
+       loadmodel->modelsurfaces_sorted = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
        loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
        loadmodel->surfmesh.num_vertices = numvertices;
        loadmodel->surfmesh.num_triangles = numtriangles;
@@ -8198,7 +8200,7 @@ void Mod_OBJ_Load(model_t *mod, void *buffer, void *bufferend)
        loadmodel->brush.data_pvsclusters = nobsp_pvs;
        //if (loadmodel->num_nodes) loadmodel->data_nodes = (mnode_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_nodes * sizeof(mnode_t));
        //loadmodel->data_leafsurfaces = (int *)Mem_Alloc(loadmodel->mempool, loadmodel->num_leafsurfaces * sizeof(int));
-       loadmodel->brush.data_leafsurfaces = loadmodel->sortedmodelsurfaces;
+       loadmodel->brush.data_leafsurfaces = loadmodel->modelsurfaces_sorted;
        VectorCopy(loadmodel->normalmins, loadmodel->brush.data_leafs->mins);
        VectorCopy(loadmodel->normalmaxs, loadmodel->brush.data_leafs->maxs);
        loadmodel->brush.data_leafs->combinedsupercontents = 0; // FIXME?
@@ -8244,19 +8246,17 @@ void Mod_OBJ_Load(model_t *mod, void *buffer, void *bufferend)
                        loadmodel->brush.submodels[i] = mod;
 
                // make the model surface list (used by shadowing/lighting)
-               mod->firstmodelsurface = submodelfirstsurface[i];
-               mod->nummodelsurfaces = submodelfirstsurface[i+1] - submodelfirstsurface[i];
+               mod->submodelsurfaces_start = submodelfirstsurface[i];
+               mod->submodelsurfaces_end = submodelfirstsurface[i+1];
                mod->firstmodelbrush = 0;
                mod->nummodelbrushes = 0;
-               mod->sortedmodelsurfaces = loadmodel->sortedmodelsurfaces + mod->firstmodelsurface;
-               Mod_MakeSortedSurfaces(mod);
 
                VectorClear(mod->normalmins);
                VectorClear(mod->normalmaxs);
                l = false;
-               for (j = 0;j < mod->nummodelsurfaces;j++)
+               for (j = mod->submodelsurfaces_start;j < mod->submodelsurfaces_end;j++)
                {
-                       const msurface_t *surface = mod->data_surfaces + j + mod->firstmodelsurface;
+                       const msurface_t *surface = mod->data_surfaces + j;
                        const float *v3f = mod->surfmesh.data_vertex3f + 3 * surface->num_firstvertex;
                        int k;
                        if (!surface->num_vertices)
@@ -8295,16 +8295,16 @@ void Mod_OBJ_Load(model_t *mod, void *buffer, void *bufferend)
                mod->DrawSky = NULL;
                mod->DrawAddWaterPlanes = NULL;
 
-               for (j = 0;j < mod->nummodelsurfaces;j++)
-                       if (mod->data_surfaces[j + mod->firstmodelsurface].texture->basematerialflags & MATERIALFLAG_SKY)
+               for (j = mod->submodelsurfaces_start; j < mod->submodelsurfaces_end; j++)
+                       if (mod->data_surfaces[j].texture->basematerialflags & MATERIALFLAG_SKY)
                                break;
-               if (j < mod->nummodelsurfaces)
+               if (j < mod->submodelsurfaces_end)
                        mod->DrawSky = R_Mod_DrawSky;
 
-               for (j = 0;j < mod->nummodelsurfaces;j++)
-                       if (mod->data_surfaces[j + mod->firstmodelsurface].texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
+               for (j = mod->submodelsurfaces_start; j < mod->submodelsurfaces_end; j++)
+                       if (mod->data_surfaces[j].texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
                                break;
-               if (j < mod->nummodelsurfaces)
+               if (j < mod->submodelsurfaces_end)
                        mod->DrawAddWaterPlanes = R_Mod_DrawAddWaterPlanes;
 
                Mod_MakeCollisionBIH(mod, true, &mod->collision_bih);
@@ -8317,5 +8317,8 @@ void Mod_OBJ_Load(model_t *mod, void *buffer, void *bufferend)
        mod = loadmodel;
        Mem_Free(submodelfirstsurface);
 
+       // make the model surface list (used by shadowing/lighting)
+       Mod_MakeSortedSurfaces(loadmodel);
+
        Con_DPrintf("Stats for obj model \"%s\": %i faces, %i nodes, %i leafs, %i clusters, %i clusterportals, mesh: %i vertices, %i triangles, %i surfaces\n", loadmodel->name, loadmodel->num_surfaces, loadmodel->brush.num_nodes, loadmodel->brush.num_leafs, mod->brush.num_pvsclusters, loadmodel->brush.num_portals, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->num_surfaces);
 }
index 55b4673ea351138c79d11f01c6998a9856e21831..f43229ca3d48837c8387cab79e1a634bee237651 100644 (file)
@@ -1197,9 +1197,9 @@ void Mod_CreateCollisionMesh(model_t *mod)
        // make a single combined collision mesh for physics engine use
        // TODO rewrite this to use the collision brushes as source, to fix issues with e.g. common/caulk which creates no drawsurface
        numcollisionmeshtriangles = 0;
-       for (k = 0;k < mod->nummodelsurfaces;k++)
+       for (k = mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
        {
-               surface = mod->data_surfaces + mod->firstmodelsurface + k;
+               surface = mod->data_surfaces + k;
                if (!strcmp(surface->texture->name, "collision") || !strcmp(surface->texture->name, "collisionconvex")) // found collision mesh
                {
                        usesinglecollisionmesh = true;
@@ -1215,9 +1215,9 @@ void Mod_CreateCollisionMesh(model_t *mod)
                Mod_ShadowMesh_AddMesh(mod->brush.collisionmesh, mod->surfmesh.data_vertex3f, surface->num_triangles, (mod->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
        else
        {
-               for (k = 0;k < mod->nummodelsurfaces;k++)
+               for (k = mod->submodelsurfaces_start; k < mod->submodelsurfaces_end; k++)
                {
-                       surface = mod->data_surfaces + mod->firstmodelsurface + k;
+                       surface = mod->data_surfaces + k;
                        if (!(surface->texture->supercontents & SUPERCONTENTS_SOLID))
                                continue;
                        Mod_ShadowMesh_AddMesh(mod->brush.collisionmesh, mod->surfmesh.data_vertex3f, surface->num_triangles, (mod->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
@@ -2881,41 +2881,65 @@ void Mod_VertexRangeFromElements(int numelements, const int *elements, int *firs
                *lastvertexpointer = lastvertex;
 }
 
+typedef struct Mod_MakeSortedSurfaces_qsortsurface_s
+{
+       int submodel;
+       int surfaceindex;
+       q3deffect_t* effect;
+       texture_t* texture;
+       rtexture_t* lightmaptexture;
+}
+Mod_MakeSortedSurfaces_qsortsurface_t;
+
+int Mod_MakeSortedSurfaces_qsortfunc(const void *a, const void *b)
+{
+       const Mod_MakeSortedSurfaces_qsortsurface_t* l = (Mod_MakeSortedSurfaces_qsortsurface_t*)a;
+       const Mod_MakeSortedSurfaces_qsortsurface_t* r = (Mod_MakeSortedSurfaces_qsortsurface_t*)b;
+       if (l->submodel < r->submodel)
+               return -1;
+       if (l->submodel > r->submodel)
+               return 1;
+       if (l->effect < r->effect)
+               return -1;
+       if (l->effect > r->effect)
+               return 1;
+       if (l->texture < r->texture)
+               return -1;
+       if (l->texture > r->texture)
+               return 1;
+       if (l->lightmaptexture < r->lightmaptexture)
+               return -1;
+       if (l->lightmaptexture > r->lightmaptexture)
+               return 1;
+       if (l->surfaceindex < r->surfaceindex)
+               return -1;
+       if (l->surfaceindex > r->surfaceindex)
+               return 1;
+       return 0;
+}
+
 void Mod_MakeSortedSurfaces(model_t *mod)
 {
        // make an optimal set of texture-sorted batches to draw...
-       int j, t;
-       int *firstsurfacefortexture;
-       int *numsurfacesfortexture;
-       if (!mod->sortedmodelsurfaces)
-               mod->sortedmodelsurfaces = (int *) Mem_Alloc(loadmodel->mempool, mod->nummodelsurfaces * sizeof(*mod->sortedmodelsurfaces));
-       firstsurfacefortexture = (int *) Mem_Alloc(tempmempool, mod->num_textures * sizeof(*firstsurfacefortexture));
-       numsurfacesfortexture = (int *) Mem_Alloc(tempmempool, mod->num_textures * sizeof(*numsurfacesfortexture));
-       memset(numsurfacesfortexture, 0, mod->num_textures * sizeof(*numsurfacesfortexture));
-       for (j = 0;j < mod->nummodelsurfaces;j++)
+       int j, k;
+       Mod_MakeSortedSurfaces_qsortsurface_t *info = (Mod_MakeSortedSurfaces_qsortsurface_t*)R_FrameData_Alloc(mod->num_surfaces * sizeof(*info));
+       if (!mod->modelsurfaces_sorted)
+               mod->modelsurfaces_sorted = (int *) Mem_Alloc(loadmodel->mempool, mod->num_surfaces * sizeof(*mod->modelsurfaces_sorted));
+       // the goal is to sort by submodel (can't change which submodel a surface belongs to), and then by effects and textures
+       for (j = 0; j < mod->num_surfaces; j++)
        {
-               const msurface_t *surface = mod->data_surfaces + j + mod->firstmodelsurface;
-               if(!surface->texture)
-                       continue;
-               t = (int)(surface->texture - mod->data_textures);
-               numsurfacesfortexture[t]++;
+               info[j].submodel = 0;
+               info[j].surfaceindex = j;
+               info[j].effect = mod->data_surfaces[j].effect;
+               info[j].texture = mod->data_surfaces[j].texture;
+               info[j].lightmaptexture = mod->data_surfaces[j].lightmaptexture;
        }
-       j = 0;
-       for (t = 0;t < mod->num_textures;t++)
-       {
-               firstsurfacefortexture[t] = j;
-               j += numsurfacesfortexture[t];
-       }
-       for (j = 0;j < mod->nummodelsurfaces;j++)
-       {
-               const msurface_t *surface = mod->data_surfaces + j + mod->firstmodelsurface;
-               if (!surface->texture)
-                       continue;
-               t = (int)(surface->texture - mod->data_textures);
-               mod->sortedmodelsurfaces[firstsurfacefortexture[t]++] = j + mod->firstmodelsurface;
-       }
-       Mem_Free(firstsurfacefortexture);
-       Mem_Free(numsurfacesfortexture);
+       for (k = 0; k < mod->brush.numsubmodels; k++)
+               for (j = mod->brush.submodels[k]->submodelsurfaces_start; j < mod->brush.submodels[k]->submodelsurfaces_end; j++)
+                       info[j].submodel = k;
+       qsort(info, mod->num_surfaces, sizeof(*info), Mod_MakeSortedSurfaces_qsortfunc);
+       for (j = 0; j < mod->num_surfaces; j++)
+               mod->modelsurfaces_sorted[j] = info[j].surfaceindex;
 }
 
 void Mod_BuildVBOs(void)
@@ -3068,9 +3092,9 @@ static void Mod_Decompile_OBJ(model_t *model, const char *filename, const char *
                if (l > 0)
                        outbufferpos += l;
                submodel = model->brush.numsubmodels ? model->brush.submodels[submodelindex] : model;
-               for (surfaceindex = 0;surfaceindex < submodel->nummodelsurfaces;surfaceindex++)
+               for (surfaceindex = submodel->submodelsurfaces_start;surfaceindex < submodel->submodelsurfaces_end;surfaceindex++)
                {
-                       surface = model->data_surfaces + submodel->sortedmodelsurfaces[surfaceindex];
+                       surface = model->data_surfaces + surfaceindex;
                        l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "usemtl %s\n", (surface->texture && surface->texture->name[0]) ? surface->texture->name : "default");
                        if (l > 0)
                                outbufferpos += l;
@@ -3614,8 +3638,9 @@ static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP_InsertSurfaces(const
        const int *element3i = model->surfmesh.data_element3i;
        const int *e;
        float v2[3][3];
-       for (surfaceindex = 0, surface = model->data_surfaces;surfaceindex < model->nummodelsurfaces;surfaceindex++, surface++)
+       for (surfaceindex = model->submodelsurfaces_start;surfaceindex < model->submodelsurfaces_end;surfaceindex++)
        {
+               surface = model->data_surfaces + surfaceindex;
                if (!BoxesOverlap(surface->mins, surface->maxs, mins, maxs))
                        continue;
                if (surface->texture->basematerialflags & MATERIALFLAG_NOSHADOW)
@@ -4491,7 +4516,7 @@ msurface_t *Mod_Mesh_AddSurface(model_t *mod, texture_t *tex, qbool batchwithpre
        {
                mod->max_surfaces = 2 * max(mod->num_surfaces, 64);
                mod->data_surfaces = (msurface_t *)Mem_Realloc(mod->mempool, mod->data_surfaces, mod->max_surfaces * sizeof(*mod->data_surfaces));
-               mod->sortedmodelsurfaces = (int *)Mem_Realloc(mod->mempool, mod->sortedmodelsurfaces, mod->max_surfaces * sizeof(*mod->sortedmodelsurfaces));
+               mod->modelsurfaces_sorted = (int *)Mem_Realloc(mod->mempool, mod->modelsurfaces_sorted, mod->max_surfaces * sizeof(*mod->modelsurfaces_sorted));
        }
        surf = mod->data_surfaces + mod->num_surfaces;
        mod->num_surfaces++;
@@ -4633,29 +4658,26 @@ static void Mod_Mesh_MakeSortedSurfaces(model_t *mod)
 {
        int i, j;
        texture_t *tex;
-       msurface_t *surf, *surf2;
+       unsigned char* included = R_FrameData_Alloc(mod->num_surfaces * sizeof(unsigned char));
 
        // build the sorted surfaces list properly to reduce material setup
        // this is easy because we're just sorting on texture and don't care about the order of textures
-       mod->nummodelsurfaces = 0;
+       mod->submodelsurfaces_start = 0;
+       mod->submodelsurfaces_end = 0;
        for (i = 0; i < mod->num_surfaces; i++)
-               mod->data_surfaces[i].included = false;
+               included[i] = 0;
        for (i = 0; i < mod->num_surfaces; i++)
        {
-               surf = mod->data_surfaces + i;
-               if (surf->included)
+               if (included[i])
                        continue;
-               tex = surf->texture;
+               tex = mod->data_surfaces[i].texture;
                // j = i is intentional
                for (j = i; j < mod->num_surfaces; j++)
                {
-                       surf2 = mod->data_surfaces + j;
-                       if (surf2->included)
-                               continue;
-                       if (surf2->texture == tex)
+                       if (!included[j] && mod->data_surfaces[j].texture == tex)
                        {
-                               surf2->included = true;
-                               mod->sortedmodelsurfaces[mod->nummodelsurfaces++] = j;
+                               included[j] = 1;
+                               mod->modelsurfaces_sorted[mod->submodelsurfaces_end++] = j;
                        }
                }
        }
index 6b0530a889c43c09e0955c74b32e6672d9898da0..b5312b8c6f37322dd55ca57452357cfb55abe655 100644 (file)
@@ -370,36 +370,40 @@ typedef struct msurface_lightmapinfo_s
 msurface_lightmapinfo_t;
 
 struct q3deffect_s;
+
+/// <summary>
+///  describes the textures to use on a range of triangles in the model, and mins/maxs (AABB) for culling.
+/// </summary>
 typedef struct msurface_s
 {
-       // bounding box for onscreen checks
-       vec3_t mins;
-       vec3_t maxs;
-       // the texture to use on the surface
+       /// range of triangles and vertices in model->surfmesh
+       int num_triangles; // triangles
+       int num_firsttriangle; // first element is this *3
+       int num_vertices; // length of the range referenced by elements
+       int num_firstvertex; // min vertex referenced by elements
+
+       /// the texture to use on the surface
        texture_t *texture;
-       // the lightmap texture fragment to use on the rendering mesh
+       /// the lightmap texture fragment to use on the rendering mesh
        struct rtexture_s *lightmaptexture;
-       // the lighting direction texture fragment to use on the rendering mesh
+       /// the lighting direction texture fragment to use on the rendering mesh
        struct rtexture_s *deluxemaptexture;
-       // lightmaptexture rebuild information not used in q3bsp
-       msurface_lightmapinfo_t *lightmapinfo; // q1bsp
-       // fog volume info in q3bsp
-       struct q3deffect_s *effect; // q3bsp
-       // mesh information for collisions (only used by q3bsp curves)
-       int num_firstcollisiontriangle;
-
-       // surfaces own ranges of vertices and triangles in the model->surfmesh
-       int num_triangles; // number of triangles
-       int num_firsttriangle; // first triangle
-       int num_vertices; // number of vertices
-       int num_firstvertex; // first vertex
-
-       // mesh information for collisions (only used by q3bsp curves)
-       int num_collisiontriangles; // q3bsp
-       int num_collisionvertices; // q3bsp
-
-       // used by Mod_Mesh_Finalize when building sortedmodelsurfaces
-       qbool included;
+
+       // the following fields are used situationally and are not part of rendering in typical usage
+
+       /// bounding box for onscreen checks
+       vec3_t mins;
+       vec3_t maxs;
+
+       /// lightmaptexture rebuild information not used in q3bsp
+       msurface_lightmapinfo_t* lightmapinfo; // q1bsp
+       /// fog volume info in q3bsp
+       struct q3deffect_s* effect; // q3bsp
+
+       /// mesh information for collisions (only used by q3bsp curves)
+       int num_firstcollisiontriangle; // q3bsp only
+       int num_collisiontriangles; // number of triangles (if surface has collisions enabled)
+       int num_collisionvertices; // number of vertices referenced by collision triangles (if surface has collisions enabled)
 }
 msurface_t;
 
@@ -455,10 +459,11 @@ typedef struct model_s
        animscene_t             *skinscenes; // [numskins]
        // skin animation info
        animscene_t             *animscenes; // [numframes]
-       // range of surface numbers in this (sub)model
-       int                             firstmodelsurface;
-       int                             nummodelsurfaces;
-       int                             *sortedmodelsurfaces;
+       // range of surface numbers in this model
+       int                             submodelsurfaces_start;
+       int                             submodelsurfaces_end;
+       /// surface indices of model in an optimal draw order (submodelindex -> texture -> lightmap -> index)
+       int                             *modelsurfaces_sorted; // same size as num_surfaces
        // range of collision brush numbers in this (sub)model
        int                             firstmodelbrush;
        int                             nummodelbrushes;
index 4990834d914fc12e66cea78203edbb1a0ec45976..c83598b6479280bccfe204c90a7030a76c81e30b 100644 (file)
@@ -6122,9 +6122,9 @@ static void clippointtosurface(prvm_prog_t *prog, prvm_edict_t *ed, model_t *mod
 
 static msurface_t *getsurface(model_t *model, int surfacenum)
 {
-       if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
+       if (surfacenum < 0 || surfacenum >= model->submodelsurfaces_end - model->submodelsurfaces_start)
                return NULL;
-       return model->data_surfaces + surfacenum + model->firstmodelsurface;
+       return model->data_surfaces + surfacenum + model->submodelsurfaces_start;
 }
 
 
@@ -6299,9 +6299,9 @@ void VM_getsurfacenearpoint(prvm_prog_t *prog)
        applytransform_inverted(prog, point, ed, p);
        best = -1;
        bestdist = 1000000000;
-       for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
+       for (surfacenum = model->submodelsurfaces_start;surfacenum < model->submodelsurfaces_end;surfacenum++)
        {
-               surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
+               surface = model->data_surfaces + surfacenum;
                // first see if the nearest point on the surface's box is closer than the previous match
                clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
                clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
@@ -6316,7 +6316,7 @@ void VM_getsurfacenearpoint(prvm_prog_t *prog)
                        if (dist < bestdist)
                        {
                                // that's closer too, store it as the best match
-                               best = surfacenum;
+                               best = surfacenum - model->submodelsurfaces_start;
                                bestdist = dist;
                        }
                }
index 884e07a7383915edb8ae689b6b93df58cb534e9f..dcb5104d82db9f2ef42d639fd2fc1329237f1a58 100644 (file)
@@ -3376,7 +3376,7 @@ static void R_Shadow_DrawEntityShadow(entity_render_t *ent)
        relativeshadowmaxs[0] = relativeshadoworigin[0] + relativeshadowradius;
        relativeshadowmaxs[1] = relativeshadoworigin[1] + relativeshadowradius;
        relativeshadowmaxs[2] = relativeshadoworigin[2] + relativeshadowradius;
-       ent->model->DrawShadowMap(r_shadow_shadowmapside, ent, relativeshadoworigin, NULL, relativeshadowradius, ent->model->nummodelsurfaces, ent->model->sortedmodelsurfaces, NULL, relativeshadowmins, relativeshadowmaxs);
+       ent->model->DrawShadowMap(r_shadow_shadowmapside, ent, relativeshadoworigin, NULL, relativeshadowradius, ent->model->submodelsurfaces_end - ent->model->submodelsurfaces_start, ent->model->modelsurfaces_sorted + ent->model->submodelsurfaces_start, NULL, relativeshadowmins, relativeshadowmaxs);
        rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity
 }
 
@@ -3415,7 +3415,7 @@ static void R_Shadow_DrawEntityLight(entity_render_t *ent)
 
        R_Shadow_SetupEntityLight(ent);
 
-       model->DrawLight(ent, model->nummodelsurfaces, model->sortedmodelsurfaces, NULL);
+       model->DrawLight(ent, model->submodelsurfaces_end - model->submodelsurfaces_start, model->modelsurfaces_sorted + model->submodelsurfaces_start, NULL);
 
        rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity
 }
@@ -4431,7 +4431,7 @@ static void R_Shadow_DrawModelShadowMaps(void)
                relativeshadowmaxs[1] = relativelightorigin[1] + r_shadows_throwdistance.value * fabs(relativelightdirection[1]) + radius * (fabs(relativeforward[1]) + fabs(relativeright[1]));
                relativeshadowmaxs[2] = relativelightorigin[2] + r_shadows_throwdistance.value * fabs(relativelightdirection[2]) + radius * (fabs(relativeforward[2]) + fabs(relativeright[2]));
                RSurf_ActiveModelEntity(ent, false, false, false);
-               ent->model->DrawShadowMap(0, ent, relativelightorigin, relativelightdirection, relativethrowdistance, ent->model->nummodelsurfaces, ent->model->sortedmodelsurfaces, NULL, relativeshadowmins, relativeshadowmaxs);
+               ent->model->DrawShadowMap(0, ent, relativelightorigin, relativelightdirection, relativethrowdistance, ent->model->submodelsurfaces_end - ent->model->submodelsurfaces_start, ent->model->modelsurfaces_sorted + ent->model->submodelsurfaces_start, NULL, relativeshadowmins, relativeshadowmaxs);
                rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity
        }
 
diff --git a/world.c b/world.c
index 9a20fd72817d18feb8e056eccdf98d312d385673..42ed670d05665b3c6d4ee13de09e192fbb2e34c4 100644 (file)
--- a/world.c
+++ b/world.c
@@ -2290,9 +2290,9 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
 
                        // check if trimesh can be defined with convex
                        convex_compatible = false;
-                       for (i = 0;i < model->nummodelsurfaces;i++)
+                       for (i = model->submodelsurfaces_start;i < model->submodelsurfaces_end;i++)
                        {
-                               if (!strcmp(((msurface_t *)(model->data_surfaces + model->firstmodelsurface + i))->texture->name, "collisionconvex"))
+                               if (!strcmp(model->data_surfaces[i].texture->name, "collisionconvex"))
                                {
                                        convex_compatible = true;
                                        break;