]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_brush.c
added CVAR_SAVE and CVAR_NOTIFY flags to cvar_t structure (at the beginning), updated...
[xonotic/darkplaces.git] / model_brush.c
index f1f87b8c27e3fa301a8fcc09fbc7bd243e1019f7..d417326f79e8813d09a4c972183cd452a3cb2024 100644 (file)
@@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 See the GNU General Public License for more details.
 
@@ -24,8 +24,9 @@ byte  mod_novis[MAX_MAP_LEAFS/8];
 
 qboolean       hlbsp; // LordHavoc: true if it is a HalfLife BSP file (version 30)
 
-cvar_t gl_subdivide_size = {"gl_subdivide_size", "128", true};
-cvar_t halflifebsp = {"halflifebsp", "0"};
+cvar_t gl_subdivide_size = {CVAR_SAVE, "gl_subdivide_size", "128"};
+cvar_t halflifebsp = {0, "halflifebsp", "0"};
+cvar_t r_novis = {0, "r_novis", "0"};
 
 /*
 ===============
@@ -36,6 +37,7 @@ void Mod_BrushInit (void)
 {
        Cvar_RegisterVariable (&gl_subdivide_size);
        Cvar_RegisterVariable (&halflifebsp);
+       Cvar_RegisterVariable (&r_novis);
        memset (mod_novis, 0xff, sizeof(mod_novis));
 }
 
@@ -52,16 +54,11 @@ mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
 //             Sys_Error ("Mod_PointInLeaf: bad model");
 
        node = model->nodes;
-       if (node->contents < 0)
-               return (mleaf_t *)node;
-       while (1)
-       {
+       do
                node = node->children[(node->plane->type < 3 ? p[node->plane->type] : DotProduct (p,node->plane->normal)) < node->plane->dist];
-               if (node->contents < 0)
-                       return (mleaf_t *)node;
-       }
-       
-       return NULL;    // never reached
+       while (node->contents == 0);
+
+       return (mleaf_t *)node;
 }
 /*
 mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
@@ -102,9 +99,10 @@ byte *Mod_DecompressVis (byte *in, model_t *model)
        byte    *out;
        int             row;
 
-       row = (model->numleafs+7)>>3;   
+       row = (model->numleafs+7)>>3;
        out = decompressed;
 
+       /*
        if (!in)
        {       // no vis info, so make all visible
                while (row)
@@ -114,6 +112,7 @@ byte *Mod_DecompressVis (byte *in, model_t *model)
                }
                return decompressed;            
        }
+       */
 
        do
        {
@@ -137,19 +136,15 @@ byte *Mod_DecompressVis (byte *in, model_t *model)
 
 byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model)
 {
-       if (leaf == model->leafs)
+       if (r_novis.value || leaf == model->leafs || leaf->compressed_vis == NULL)
                return mod_novis;
        return Mod_DecompressVis (leaf->compressed_vis, model);
 }
 
-extern byte    *mod_base;
-
-extern cvar_t r_fullbrights;
-
 rtexture_t *r_notexture;
 texture_t r_notexture_mip;
 
-void Mod_SetupNoTexture()
+void Mod_SetupNoTexture(void)
 {
        int             x, y;
        byte    pix[16][16][4];
@@ -250,6 +245,12 @@ void Mod_LoadTextures (lump_t *l)
                for (;j < 16;j++)
                        tx->name[j] = 0;
 
+               if (!tx->name[0])
+               {
+                       Con_Printf("warning: unnamed texture in %s\n", loadname);
+                       sprintf(tx->name, "unnamed%i", i);
+               }
+
                tx->transparent = false;
                data = loadimagepixels(tx->name, false, 0, 0);
                if (data)
@@ -541,10 +542,6 @@ void Mod_LoadVisibility (lump_t *l)
        memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen);
 }
 
-void CL_ParseEntityLump(char *entdata);
-
-extern qboolean isworldmodel;
-
 /*
 =================
 Mod_LoadEntities
@@ -761,8 +758,6 @@ void CalcSurfaceExtents (msurface_t *s)
 
 void GL_SubdivideSurface (msurface_t *fa);
 
-extern char skyname[];
-
 /*
 =================
 Mod_LoadFaces
@@ -822,7 +817,7 @@ void Mod_LoadFaces (lump_t *l)
                 && (out->texinfo->texture->name[2] == 'y' || out->texinfo->texture->name[2] == 'Y'))
                {
                        // LordHavoc: for consistency reasons, mark sky as fullbright and solid as well
-                       out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED | SURF_DRAWFULLBRIGHT | SURF_DRAWNOALPHA);
+                       out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED | SURF_DRAWFULLBRIGHT | SURF_DRAWNOALPHA | SURF_CLIPSOLID);
                        GL_SubdivideSurface (out);      // cut up polygon for warps
                        continue;
                }
@@ -844,7 +839,8 @@ void Mod_LoadFaces (lump_t *l)
                        GL_SubdivideSurface (out);      // cut up polygon for warps
                        continue;
                }
-
+               
+               out->flags |= SURF_CLIPSOLID;
        }
 }
 
@@ -885,11 +881,11 @@ void Mod_LoadNodes (lump_t *l)
 
        for ( i=0 ; i<count ; i++, in++, out++)
        {
-               for (j=0 ; j<3 ; j++)
-               {
-                       out->mins[j] = LittleShort (in->mins[j]);
-                       out->maxs[j] = LittleShort (in->maxs[j]);
-               }
+//             for (j=0 ; j<3 ; j++)
+//             {
+//                     out->mins[j] = LittleShort (in->mins[j]);
+//                     out->maxs[j] = LittleShort (in->maxs[j]);
+//             }
        
                p = LittleLong(in->planenum);
                out->plane = loadmodel->planes + p;
@@ -950,7 +946,6 @@ void Mod_LoadLeafs (lump_t *l)
                        out->compressed_vis = NULL;
                else
                        out->compressed_vis = loadmodel->visdata + p;
-//             out->efrags = NULL;
                
                for (j=0 ; j<4 ; j++)
                        out->ambient_sound_level[j] = in->ambient_level[j];
@@ -1159,7 +1154,6 @@ void Mod_LoadPlanes (lump_t *l)
        mplane_t        *out;
        dplane_t        *in;
        int                     count;
-       int                     bits;
        
        in = (void *)(mod_base + l->fileofs);
        if (l->filelen % sizeof(*in))
@@ -1172,18 +1166,13 @@ void Mod_LoadPlanes (lump_t *l)
 
        for ( i=0 ; i<count ; i++, in++, out++)
        {
-               bits = 0;
                for (j=0 ; j<3 ; j++)
-               {
                        out->normal[j] = LittleFloat (in->normal[j]);
-//                     if (out->normal[j] < 0)
-//                             bits |= 1<<j;
-               }
 
                out->dist = LittleFloat (in->dist);
-               out->type = LittleLong (in->type);
-//             out->signbits = bits;
-               BoxOnPlaneSideClassify(out);
+               // LordHavoc: recalculated by PlaneClassify, FIXME: validate type and report error if type does not match normal?
+//             out->type = LittleLong (in->type);
+               PlaneClassify(out);
        }
 }
 
@@ -1210,7 +1199,7 @@ winding_t *NewWinding (int points)
                Host_Error("NewWinding: too many points\n");
 
        size = (int)((winding_t *)0)->points[points];
-       w = malloc (size);
+       w = qmalloc (size);
        memset (w, 0, size);
 
        return w;
@@ -1218,7 +1207,7 @@ winding_t *NewWinding (int points)
 
 void FreeWinding (winding_t *w)
 {
-       free (w);
+       qfree (w);
 }
 
 /*
@@ -1486,19 +1475,54 @@ AllocPortal
 portal_t *AllocPortal (void)
 {
        portal_t *p;
-       p = malloc(sizeof(portal_t));
+       p = qmalloc(sizeof(portal_t));
        memset(p, 0, sizeof(portal_t));
        p->chain = portalchain;
        portalchain = p;
        return p;
 }
 
-void Mod_FinalizePortals()
+void Mod_FinalizePortals(void)
 {
        int i, j, numportals, numpoints;
        portal_t *p, *pnext;
        mportal_t *portal;
        mvertex_t *point;
+       mleaf_t *leaf, *endleaf;
+       winding_t *w;
+
+       // recalculate bounding boxes for all leafs (because qbsp is very sloppy)
+       leaf = loadmodel->leafs;
+       endleaf = leaf + loadmodel->numleafs;
+       for (;leaf < endleaf;leaf++)
+       {
+               VectorSet( 2000000000,  2000000000,  2000000000, leaf->mins);
+               VectorSet(-2000000000, -2000000000, -2000000000, leaf->maxs);
+       }
+       p = portalchain;
+       while(p)
+       {
+               if (p->winding)
+               {
+                       for (i = 0;i < 2;i++)
+                       {
+                               leaf = (mleaf_t *)p->nodes[i];
+                               w = p->winding;
+                               for (j = 0;j < w->numpoints;j++)
+                               {
+                                       if (leaf->mins[0] > w->points[j][0]) leaf->mins[0] = w->points[j][0];
+                                       if (leaf->mins[1] > w->points[j][1]) leaf->mins[1] = w->points[j][1];
+                                       if (leaf->mins[2] > w->points[j][2]) leaf->mins[2] = w->points[j][2];
+                                       if (leaf->maxs[0] < w->points[j][0]) leaf->maxs[0] = w->points[j][0];
+                                       if (leaf->maxs[1] < w->points[j][1]) leaf->maxs[1] = w->points[j][1];
+                                       if (leaf->maxs[2] < w->points[j][2]) leaf->maxs[2] = w->points[j][2];
+                               }
+                       }
+               }
+               p = p->chain;
+       }
+
+       // tally up portal and point counts
        p = portalchain;
        numportals = 0;
        numpoints = 0;
@@ -1545,6 +1569,7 @@ void Mod_FinalizePortals()
                                        VectorCopy(p->winding->points[j], point->position);
                                        point++;
                                }
+                               PlaneClassify(&portal->plane);
 
                                // link into leaf's portal chain
                                portal->next = portal->here->portals;
@@ -1566,6 +1591,7 @@ void Mod_FinalizePortals()
                                        VectorCopy(p->winding->points[j], point->position);
                                        point++;
                                }
+                               PlaneClassify(&portal->plane);
 
                                // link into leaf's portal chain
                                portal->next = portal->here->portals;
@@ -1576,7 +1602,7 @@ void Mod_FinalizePortals()
                        }
                        FreeWinding(p->winding);
                }
-               free(p);
+               qfree(p);
                p = pnext;
        }
 }
@@ -1620,7 +1646,7 @@ void RemovePortalFromNodes(portal_t *portal)
        {
                node = portal->nodes[i];
 
-               portalpointer = &node->portals;
+               portalpointer = (void **) &node->portals;
                while (1)
                {
                        t = *portalpointer;
@@ -1645,9 +1671,9 @@ void RemovePortalFromNodes(portal_t *portal)
                        }
 
                        if (t->nodes[0] == node)
-                               portalpointer = &t->next[0];
+                               portalpointer = (void **) &t->next[0];
                        else if (t->nodes[1] == node)
-                               portalpointer = &t->next[1];
+                               portalpointer = (void **) &t->next[1];
                        else
                                Host_Error ("RemovePortalFromNodes: portal not bounding leaf");
                }
@@ -1815,7 +1841,7 @@ void Mod_MakeOutsidePortals(mnode_t *node)
 }
 */
 
-void Mod_MakePortals()
+void Mod_MakePortals(void)
 {
 //     Con_Printf("building portals for %s\n", loadmodel->name);