]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_brush.c
make DP compile with C++ again
[xonotic/darkplaces.git] / model_brush.c
index 69d66f57fb8bbbc647667416d6962b08d893ef43..dbd2708797856e43ef651a0445a1fe4a8b161559 100644 (file)
@@ -3383,7 +3383,7 @@ void Mod_Q1BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
        dheader_t *header;
        dmodel_t *bm;
        mempool_t *mainmempool;
-       float dist, modelyawradius, modelradius, *vec;
+       float dist, modelyawradius, modelradius;
        msurface_t *surface;
        int numshadowmeshtriangles;
        hullinfo_t hullinfo;
@@ -3620,17 +3620,31 @@ void Mod_Q1BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
                        mod->brush.LightPoint = NULL;
                        mod->brush.AmbientSoundLevelsForPoint = NULL;
                }
+
                // 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);
                VectorCopy(bm->maxs, mod->normalmaxs);
-               VectorCopy(bm->mins, mod->yawmins);
-               VectorCopy(bm->maxs, mod->yawmaxs);
-               VectorCopy(bm->mins, mod->rotatedmins);
-               VectorCopy(bm->maxs, mod->rotatedmaxs);
+               dist = max(fabs(mod->normalmins[0]), fabs(mod->normalmaxs[0]));
+               modelyawradius = max(fabs(mod->normalmins[1]), fabs(mod->normalmaxs[1]));
+               modelyawradius = dist*dist+modelyawradius*modelyawradius;
+               modelradius = max(fabs(mod->normalmins[2]), fabs(mod->normalmaxs[2]));
+               modelradius = modelyawradius + modelradius * modelradius;
+               modelyawradius = sqrt(modelyawradius);
+               modelradius = sqrt(modelradius);
+               mod->yawmins[0] = mod->yawmins[1] = -modelyawradius;
+               mod->yawmins[2] = mod->normalmins[2];
+               mod->yawmaxs[0] = mod->yawmaxs[1] =  modelyawradius;
+               mod->yawmaxs[2] = mod->normalmaxs[2];
+               mod->rotatedmins[0] = mod->rotatedmins[1] = mod->rotatedmins[2] = -modelradius;
+               mod->rotatedmaxs[0] = mod->rotatedmaxs[1] = mod->rotatedmaxs[2] =  modelradius;
+               mod->radius = modelradius;
+               mod->radius2 = modelradius * modelradius;
+
+               // 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)
                {
-                       modelyawradius = 0;
-                       modelradius = 0;
                        for (j = 0, surface = &mod->data_surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surface++)
                        {
                                // we only need to have a drawsky function if it is used(usually only on world model)
@@ -3638,31 +3652,7 @@ void Mod_Q1BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
                                        mod->DrawSky = R_Q1BSP_DrawSky;
                                if (surface->texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION))
                                        mod->DrawAddWaterPlanes = R_Q1BSP_DrawAddWaterPlanes;
-                               // calculate bounding shapes
-                               for (k = 0, vec = (loadmodel->surfmesh.data_vertex3f + 3 * surface->num_firstvertex);k < surface->num_vertices;k++, vec += 3)
-                               {
-                                       dist = vec[0]*vec[0]+vec[1]*vec[1];
-                                       if (modelyawradius < dist)
-                                               modelyawradius = dist;
-                                       dist += vec[2]*vec[2];
-                                       if (modelradius < dist)
-                                               modelradius = dist;
-                               }
                        }
-                       modelyawradius = sqrt(modelyawradius);
-                       modelradius = sqrt(modelradius);
-                       mod->yawmins[0] = min(mod->yawmins[0], -modelyawradius);
-                       mod->yawmaxs[0] = min(mod->yawmaxs[0], -modelyawradius);
-                       mod->yawmins[1] = min(mod->yawmins[1],  modelyawradius);
-                       mod->yawmaxs[1] = min(mod->yawmaxs[1],  modelyawradius);
-                       mod->rotatedmins[0] = min(mod->rotatedmins[0], -modelradius);
-                       mod->rotatedmaxs[0] = min(mod->rotatedmaxs[0],  modelradius);
-                       mod->rotatedmins[1] = min(mod->rotatedmins[1], -modelradius);
-                       mod->rotatedmaxs[1] = min(mod->rotatedmaxs[1],  modelradius);
-                       mod->rotatedmins[2] = min(mod->rotatedmins[2], -modelradius);
-                       mod->rotatedmaxs[2] = min(mod->rotatedmaxs[2],  modelradius);
-                       mod->radius = modelradius;
-                       mod->radius2 = modelradius * modelradius;
 
                        // build lightstyle update chains
                        // (used to rapidly mark lightmapupdateflags on many surfaces
@@ -4536,7 +4526,7 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump)
                }
        }
 
-       convertedpixels = Mem_Alloc(tempmempool, size*size*4);
+       convertedpixels = (unsigned char *) Mem_Alloc(tempmempool, size*size*4);
        loadmodel->brushq3.lightmapsize = size;
        loadmodel->brushq3.num_originallightmaps = count;
 
@@ -4696,6 +4686,16 @@ typedef struct patchtess_s
 }
 patchtess_t;
 
+#define PATCHTESS_SAME_LODGROUP(a,b) \
+       ( \
+               (a).lodgroup[0] == (b).lodgroup[0] && \
+               (a).lodgroup[1] == (b).lodgroup[1] && \
+               (a).lodgroup[2] == (b).lodgroup[2] && \
+               (a).lodgroup[3] == (b).lodgroup[3] && \
+               (a).lodgroup[4] == (b).lodgroup[4] && \
+               (a).lodgroup[5] == (b).lodgroup[5] \
+       )
+
 static void Mod_Q3BSP_LoadFaces(lump_t *l)
 {
        q3dface_t *in, *oldin;
@@ -4725,7 +4725,7 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l)
        loadmodel->num_surfaces = count;
 
        if(count > 0)
-               patchtess = Mem_Alloc(tempmempool, count * sizeof(*patchtess));
+               patchtess = (patchtess_t*) Mem_Alloc(tempmempool, count * sizeof(*patchtess));
 
        i = 0;
        oldi = i;
@@ -4836,11 +4836,11 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l)
                        cxtess = Q3PatchTesselationOnX(patchsize[0], patchsize[1], 3, originalvertex3f, r_subdivisions_collision_tolerance.value);
                        cytess = Q3PatchTesselationOnY(patchsize[0], patchsize[1], 3, originalvertex3f, r_subdivisions_collision_tolerance.value);
                        // bound to user settings
-                       cxtess = bound(r_subdivisions_mintess.integer, xtess, r_subdivisions_collision_maxtess.integer);
-                       cytess = bound(r_subdivisions_mintess.integer, ytess, r_subdivisions_collision_maxtess.integer);
+                       cxtess = bound(r_subdivisions_collision_mintess.integer, cxtess, r_subdivisions_collision_maxtess.integer);
+                       cytess = bound(r_subdivisions_collision_mintess.integer, cytess, r_subdivisions_collision_maxtess.integer);
                        // bound to sanity settings
-                       cxtess = bound(1, xtess, 1024);
-                       cytess = bound(1, ytess, 1024);
+                       cxtess = bound(1, cxtess, 1024);
+                       cytess = bound(1, cytess, 1024);
 
                        // store it for the LOD grouping step
                        patchtess[patchtesscount].surface_id = i;
@@ -4856,8 +4856,8 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l)
                        patchtess[patchtesscount].lodgroup[4] = in->specific.patch.maxs[1];
                        patchtess[patchtesscount].lodgroup[5] = in->specific.patch.maxs[2];
 
-                       patchtess[patchtesscount].cxtess = xtess;
-                       patchtess[patchtesscount].cytess = ytess;
+                       patchtess[patchtesscount].cxtess = cxtess;
+                       patchtess[patchtesscount].cytess = cytess;
                        ++patchtesscount;
                        break;
                case Q3FACETYPE_FLARE:
@@ -4885,7 +4885,7 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l)
                {
                        if(patchtess[j].grouped) // already grouped
                                continue;
-                       if(memcmp(patchtess[i].lodgroup, patchtess[j].lodgroup, sizeof(patchtess[i].lodgroup)))
+                       if(!PATCHTESS_SAME_LODGROUP(patchtess[i], patchtess[j]))
                                continue;
                        if(patchtess[j].xtess > xtess)
                                xtess = patchtess[j].xtess;
@@ -4914,7 +4914,7 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l)
                        {
                                if(patchtess[j].grouped) // already grouped
                                        continue;
-                               if(memcmp(patchtess[i].lodgroup, patchtess[j].lodgroup, sizeof(patchtess[i].lodgroup)))
+                               if(!PATCHTESS_SAME_LODGROUP(patchtess[i], patchtess[j]))
                                        continue;
 
                                finalwidth = (patchtess[j].xsize - 1) * xtess + 1;
@@ -4948,7 +4948,7 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l)
                        {
                                if(patchtess[j].grouped) // already grouped
                                        continue;
-                               if(memcmp(patchtess[i].lodgroup, patchtess[j].lodgroup, sizeof(patchtess[i].lodgroup)))
+                               if(!PATCHTESS_SAME_LODGROUP(patchtess[i], patchtess[j]))
                                        continue;
 
                                finalwidth = (patchtess[j].xsize - 1) * cxtess + 1;
@@ -4976,7 +4976,7 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l)
                {
                        if(patchtess[j].grouped) // already grouped
                                continue;
-                       if(memcmp(patchtess[i].lodgroup, patchtess[j].lodgroup, sizeof(patchtess[i].lodgroup)))
+                       if(!PATCHTESS_SAME_LODGROUP(patchtess[i], patchtess[j]))
                                continue;
 
                        finalwidth = (patchtess[j].xsize - 1) * xtess + 1;
@@ -5174,6 +5174,18 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l)
                //out->lightmapinfo->styles[3] = 255;
        }
 
+       i = oldi;
+       out = oldout;
+       for (;i < count;i++, out++)
+       {
+               if(out->num_vertices && out->num_triangles)
+                       continue;
+               if(out->num_vertices == 0)
+                       Con_Printf("Mod_Q3BSP_LoadFaces: surface %d has no vertices, ignoring\n", i);
+               if(out->num_triangles == 0)
+                       Con_Printf("Mod_Q3BSP_LoadFaces: surface %d has no triangles, ignoring\n", i);
+       }
+
        // for per pixel lighting
        Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, true);