]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_brush.c
sys: work around incomplete POSIX support in MacOS
[xonotic/darkplaces.git] / model_brush.c
index 83645cf378d7d047127867ff040f65bace29908b..a69a7eed152137bc7e331883b19affc9f3b549be 100644 (file)
@@ -61,9 +61,10 @@ cvar_t mod_q3shader_force_terrain_alphaflag = {CF_CLIENT, "mod_q3shader_force_te
 cvar_t mod_q2bsp_littransparentsurfaces = {CF_CLIENT, "mod_q2bsp_littransparentsurfaces", "0", "allows lighting on rain in 3v3gloom3 and other cases of transparent surfaces that have lightmaps that were ignored by quake2"};
 
 cvar_t mod_q1bsp_polygoncollisions = {CF_CLIENT | CF_SERVER, "mod_q1bsp_polygoncollisions", "0", "disables use of precomputed cliphulls and instead collides with polygons (uses Bounding Interval Hierarchy optimizations)"};
 cvar_t mod_q2bsp_littransparentsurfaces = {CF_CLIENT, "mod_q2bsp_littransparentsurfaces", "0", "allows lighting on rain in 3v3gloom3 and other cases of transparent surfaces that have lightmaps that were ignored by quake2"};
 
 cvar_t mod_q1bsp_polygoncollisions = {CF_CLIENT | CF_SERVER, "mod_q1bsp_polygoncollisions", "0", "disables use of precomputed cliphulls and instead collides with polygons (uses Bounding Interval Hierarchy optimizations)"};
+cvar_t mod_q1bsp_traceoutofsolid = {CF_SHARED, "mod_q1bsp_traceoutofsolid", "1", "enables tracebox to move an entity that's stuck in solid brushwork out to empty space, 1 matches FTEQW and QSS and is required by many community maps (items/monsters will be missing otherwise), 0 matches old versions of DP and the original Quake engine (if your map or QC needs 0 it's buggy)"};
 cvar_t mod_q1bsp_zero_hullsize_cutoff = {CF_CLIENT | CF_SERVER, "mod_q1bsp_zero_hullsize_cutoff", "3", "bboxes with an X dimension smaller than this will use the smallest cliphull (0x0x0) instead of being rounded up to the player cliphull (32x32x56) in Q1BSP, or crouching player (32x32x36) in HLBSP"};
 
 cvar_t mod_q1bsp_zero_hullsize_cutoff = {CF_CLIENT | CF_SERVER, "mod_q1bsp_zero_hullsize_cutoff", "3", "bboxes with an X dimension smaller than this will use the smallest cliphull (0x0x0) instead of being rounded up to the player cliphull (32x32x56) in Q1BSP, or crouching player (32x32x36) in HLBSP"};
 
-cvar_t mod_bsp_portalize = {CF_CLIENT, "mod_bsp_portalize", "1", "enables portal generation from BSP tree (may take several seconds per map), used by r_drawportals, r_useportalculling, r_shadow_realtime_dlight_portalculling, r_shadow_realtime_world_compileportalculling"};
+cvar_t mod_bsp_portalize = {CF_CLIENT, "mod_bsp_portalize", "0", "enables portal generation from BSP tree (takes a minute or more and GBs of memory when loading a complex map), used by r_drawportals, r_useportalculling, r_shadow_realtime_dlight_portalculling, r_shadow_realtime_world_compileportalculling"};
 cvar_t mod_recalculatenodeboxes = {CF_CLIENT | CF_SERVER, "mod_recalculatenodeboxes", "1", "enables use of generated node bounding boxes based on BSP tree portal reconstruction, rather than the node boxes supplied by the map compiler"};
 
 cvar_t mod_obj_orientation = {CF_CLIENT | CF_SERVER, "mod_obj_orientation", "1", "fix orientation of OBJ models to the usual conventions (if zero, use coordinates as is)"};
 cvar_t mod_recalculatenodeboxes = {CF_CLIENT | CF_SERVER, "mod_recalculatenodeboxes", "1", "enables use of generated node bounding boxes based on BSP tree portal reconstruction, rather than the node boxes supplied by the map compiler"};
 
 cvar_t mod_obj_orientation = {CF_CLIENT | CF_SERVER, "mod_obj_orientation", "1", "fix orientation of OBJ models to the usual conventions (if zero, use coordinates as is)"};
@@ -112,6 +113,7 @@ void Mod_BrushInit(void)
        Cvar_RegisterVariable(&mod_q3shader_force_addalpha);
        Cvar_RegisterVariable(&mod_q3shader_force_terrain_alphaflag);
        Cvar_RegisterVariable(&mod_q1bsp_polygoncollisions);
        Cvar_RegisterVariable(&mod_q3shader_force_addalpha);
        Cvar_RegisterVariable(&mod_q3shader_force_terrain_alphaflag);
        Cvar_RegisterVariable(&mod_q1bsp_polygoncollisions);
+       Cvar_RegisterVariable(&mod_q1bsp_traceoutofsolid);
        Cvar_RegisterVariable(&mod_q1bsp_zero_hullsize_cutoff);
        Cvar_RegisterVariable(&mod_recalculatenodeboxes);
 
        Cvar_RegisterVariable(&mod_q1bsp_zero_hullsize_cutoff);
        Cvar_RegisterVariable(&mod_recalculatenodeboxes);
 
@@ -760,7 +762,7 @@ static int Mod_Q1BSP_RecursiveHullCheck(RecursiveHullCheckTraceInfo_t *t, int nu
                        // recurse both sides, front side first
                        ret = Mod_Q1BSP_RecursiveHullCheck(t, node->children[p1side], p1f, midf, p1, mid);
                        // if this side is not empty, return what it is (solid or done)
                        // recurse both sides, front side first
                        ret = Mod_Q1BSP_RecursiveHullCheck(t, node->children[p1side], p1f, midf, p1, mid);
                        // if this side is not empty, return what it is (solid or done)
-                       if (ret != HULLCHECKSTATE_EMPTY && !t->trace->allsolid)
+                       if (ret != HULLCHECKSTATE_EMPTY && (!t->trace->allsolid || !mod_q1bsp_traceoutofsolid.integer))
                                return ret;
 
                        ret = Mod_Q1BSP_RecursiveHullCheck(t, node->children[p2side], midf, p2f, mid, p2);
                                return ret;
 
                        ret = Mod_Q1BSP_RecursiveHullCheck(t, node->children[p2side], midf, p2f, mid, p2);
@@ -3820,18 +3822,26 @@ static void Mod_BSP_FatPVS_RecursiveBSPNode(model_t *model, const vec3_t org, ve
 
 //Calculates a PVS that is the inclusive or of all leafs within radius pixels
 //of the given point.
 
 //Calculates a PVS that is the inclusive or of all leafs within radius pixels
 //of the given point.
-static int Mod_BSP_FatPVS(model_t *model, const vec3_t org, vec_t radius, unsigned char *pvsbuffer, int pvsbufferlength, qbool merge)
+static size_t Mod_BSP_FatPVS(model_t *model, const vec3_t org, vec_t radius, unsigned char **pvsbuffer, mempool_t *pool, qbool merge)
 {
 {
-       int bytes = model->brush.num_pvsclusterbytes;
-       bytes = min(bytes, pvsbufferlength);
+       size_t bytes = model->brush.num_pvsclusterbytes;
+
+       if (!*pvsbuffer || bytes != Mem_Size(*pvsbuffer))
+       {
+//             Con_Printf("^4FatPVS: allocating a%s ^4buffer in pool %s, old size %zu new size %zu\n", *pvsbuffer == NULL ? " ^5NEW" : "", pool->name, *pvsbuffer != NULL ? Mem_Size(*pvsbuffer) : 0, bytes);
+               if (*pvsbuffer)
+                       Mem_Free(*pvsbuffer); // don't reuse stale data when the worldmodel changes
+               *pvsbuffer = Mem_AllocType(pool, unsigned char, bytes);
+       }
+
        if (r_novis.integer || r_trippy.integer || !model->brush.num_pvsclusters || !Mod_BSP_GetPVS(model, org))
        {
        if (r_novis.integer || r_trippy.integer || !model->brush.num_pvsclusters || !Mod_BSP_GetPVS(model, org))
        {
-               memset(pvsbuffer, 0xFF, bytes);
+               memset(*pvsbuffer, 0xFF, bytes);
                return bytes;
        }
        if (!merge)
                return bytes;
        }
        if (!merge)
-               memset(pvsbuffer, 0, bytes);
-       Mod_BSP_FatPVS_RecursiveBSPNode(model, org, radius, pvsbuffer, bytes, model->brush.data_nodes + model->brushq1.hulls[0].firstclipnode);
+               memset(*pvsbuffer, 0, bytes);
+       Mod_BSP_FatPVS_RecursiveBSPNode(model, org, radius, *pvsbuffer, bytes, model->brush.data_nodes + model->brushq1.hulls[0].firstclipnode);
        return bytes;
 }
 
        return bytes;
 }
 
@@ -6358,8 +6368,9 @@ static void Mod_Q3BSP_LoadLeafs(lump_t *l)
                for (j = 0;j < 3;j++)
                {
                        // yes the mins/maxs are ints
                for (j = 0;j < 3;j++)
                {
                        // yes the mins/maxs are ints
-                       out->mins[j] = LittleLong(in->mins[j]) - 1;
-                       out->maxs[j] = LittleLong(in->maxs[j]) + 1;
+                       // bones_was_here: the cast prevents signed underflow with poon-wood.bsp
+                       out->mins[j] = (vec_t)LittleLong(in->mins[j]) - 1;
+                       out->maxs[j] = (vec_t)LittleLong(in->maxs[j]) + 1;
                }
                n = LittleLong(in->firstleafface);
                c = LittleLong(in->numleaffaces);
                }
                n = LittleLong(in->firstleafface);
                c = LittleLong(in->numleaffaces);