Added developer_memorylargerthanmb cvar which dprints notices about very large memory...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 27 Nov 2016 20:53:09 +0000 (20:53 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 27 Nov 2016 20:53:09 +0000 (20:53 +0000)
Slightly improved the Mem_Alloc out of memory error to include the size of the failed allocation.

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

31 files changed:
cl_collision.c
cl_collision.h
cl_input.c
cl_main.c
cl_particles.c
client.h
clvm_cmds.c
collision.c
collision.h
gl_rmain.c
gl_textures.c
mathlib.c
mathlib.h
model_alias.c
model_brush.c
model_shared.c
model_shared.h
r_explosion.c
r_shadow.c
r_shadow.h
sbar.c
server.h
sv_move.c
sv_phys.c
sv_user.c
svvm_cmds.c
sys_linux.c
sys_sdl.c
view.c
zone.c
zone.h

index d414361..1baac4f 100644 (file)
@@ -18,7 +18,7 @@ float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, ve
        if (hitent)
                *hitent = 0;
        if (cl.worldmodel && cl.worldmodel->TraceLine)
-               cl.worldmodel->TraceLine(cl.worldmodel, NULL, NULL, &trace, start, end, SUPERCONTENTS_SOLID);
+               cl.worldmodel->TraceLine(cl.worldmodel, NULL, NULL, &trace, start, end, SUPERCONTENTS_SOLID, 0);
 
        if (normal)
                VectorCopy(trace.plane.normal, normal);
@@ -50,11 +50,11 @@ float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, ve
                        continue;
                Matrix4x4_Transform(&ent->inversematrix, start, starttransformed);
                Matrix4x4_Transform(&ent->inversematrix, end, endtransformed);
-               Collision_ClipTrace_Box(&trace, ent->model->normalmins, ent->model->normalmaxs, starttransformed, vec3_origin, vec3_origin, endtransformed, SUPERCONTENTS_SOLID, SUPERCONTENTS_SOLID, 0, NULL);
+               Collision_ClipTrace_Box(&trace, ent->model->normalmins, ent->model->normalmaxs, starttransformed, vec3_origin, vec3_origin, endtransformed, SUPERCONTENTS_SOLID, SUPERCONTENTS_SKY, SUPERCONTENTS_SOLID, 0, NULL);
                if (maxfrac < trace.fraction)
                        continue;
 
-               ent->model->TraceLine(ent->model, ent->frameblend, ent->skeleton, &trace, starttransformed, endtransformed, SUPERCONTENTS_SOLID);
+               ent->model->TraceLine(ent->model, ent->frameblend, ent->skeleton, &trace, starttransformed, endtransformed, SUPERCONTENTS_SOLID, 0);
 
                if (maxfrac > trace.fraction)
                {
@@ -203,7 +203,7 @@ int CL_GenericHitSuperContentsMask(const prvm_edict_t *passedict)
 CL_Move
 ==================
 */
-trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities)
+trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities)
 {
        prvm_prog_t *prog = CLVM_prog;
        int i, bodysupercontents;
@@ -239,7 +239,7 @@ trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
 #endif
 
        // clip to world
-       Collision_ClipPointToWorld(&cliptrace, cl.worldmodel, clipstart, hitsupercontentsmask);
+       Collision_ClipPointToWorld(&cliptrace, cl.worldmodel, clipstart, hitsupercontentsmask, skipsupercontentsmask);
        cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
        if (cliptrace.startsolid || cliptrace.fraction < 1)
                cliptrace.ent = prog ? prog->edicts : NULL;
@@ -288,7 +288,7 @@ trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
                        entity_render_t *ent = &cl.entities[cl.brushmodel_entities[i]].render;
                        if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs))
                                continue;
-                       Collision_ClipPointToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, hitsupercontentsmask);
+                       Collision_ClipPointToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, hitsupercontentsmask, skipsupercontentsmask);
                        if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                                *hitnetworkentity = cl.brushmodel_entities[i];
                        Collision_CombineTraces(&cliptrace, &trace, NULL, true);
@@ -336,7 +336,7 @@ trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
                                continue;
                        Matrix4x4_CreateTranslate(&entmatrix, origin[0], origin[1], origin[2]);
                        Matrix4x4_CreateTranslate(&entinversematrix, -origin[0], -origin[1], -origin[2]);
-                       Collision_ClipPointToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, hitsupercontentsmask);
+                       Collision_ClipPointToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, hitsupercontentsmask, skipsupercontentsmask);
                        if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                                *hitnetworkentity = i;
                        Collision_CombineTraces(&cliptrace, &trace, NULL, false);
@@ -400,9 +400,9 @@ skipnetworkplayers:
                VectorCopy(PRVM_clientedictvector(touch, mins), touchmins);
                VectorCopy(PRVM_clientedictvector(touch, maxs), touchmaxs);
                if ((int)PRVM_clientedictfloat(touch, flags) & FL_MONSTER)
-                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipstart, hitsupercontentsmask, 0.0f);
+                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipstart, hitsupercontentsmask, skipsupercontentsmask, 0.0f);
                else
-                       Collision_ClipPointToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, hitsupercontentsmask);
+                       Collision_ClipPointToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, hitsupercontentsmask, skipsupercontentsmask);
 
                if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                        *hitnetworkentity = 0;
@@ -418,7 +418,7 @@ finished:
 CL_TraceLine
 ==================
 */
-trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, float extend, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities, qboolean hitsurfaces)
+trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, float extend, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities, qboolean hitsurfaces)
 {
        prvm_prog_t *prog = CLVM_prog;
        int i, bodysupercontents;
@@ -443,7 +443,7 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
        int numtouchedicts;
        static prvm_edict_t *touchedicts[MAX_EDICTS];
        if (VectorCompare(start, end))
-               return CL_TracePoint(start, type, passedict, hitsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities);
+               return CL_TracePoint(start, type, passedict, hitsupercontentsmask, skipsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities);
 
        if (hitnetworkentity)
                *hitnetworkentity = 0;
@@ -457,7 +457,7 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
 #endif
 
        // clip to world
-       Collision_ClipLineToWorld(&cliptrace, cl.worldmodel, clipstart, clipend, hitsupercontentsmask, extend, hitsurfaces);
+       Collision_ClipLineToWorld(&cliptrace, cl.worldmodel, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask, extend, hitsurfaces);
        cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
        if (cliptrace.startsolid || cliptrace.fraction < 1)
                cliptrace.ent = prog ? prog->edicts : NULL;
@@ -506,7 +506,7 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
                        entity_render_t *ent = &cl.entities[cl.brushmodel_entities[i]].render;
                        if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs))
                                continue;
-                       Collision_ClipLineToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, end, hitsupercontentsmask, extend, hitsurfaces);
+                       Collision_ClipLineToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, end, hitsupercontentsmask, skipsupercontentsmask, extend, hitsurfaces);
                        if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                                *hitnetworkentity = cl.brushmodel_entities[i];
                        Collision_CombineTraces(&cliptrace, &trace, NULL, true);
@@ -554,7 +554,7 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
                                continue;
                        Matrix4x4_CreateTranslate(&entmatrix, origin[0], origin[1], origin[2]);
                        Matrix4x4_CreateTranslate(&entinversematrix, -origin[0], -origin[1], -origin[2]);
-                       Collision_ClipLineToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, end, hitsupercontentsmask, extend, hitsurfaces);
+                       Collision_ClipLineToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, end, hitsupercontentsmask, skipsupercontentsmask, extend, hitsurfaces);
                        if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                                *hitnetworkentity = i;
                        Collision_CombineTraces(&cliptrace, &trace, NULL, false);
@@ -618,9 +618,9 @@ skipnetworkplayers:
                VectorCopy(PRVM_clientedictvector(touch, mins), touchmins);
                VectorCopy(PRVM_clientedictvector(touch, maxs), touchmaxs);
                if (type == MOVE_MISSILE && (int)PRVM_clientedictfloat(touch, flags) & FL_MONSTER)
-                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask, extend);
+                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask, skipsupercontentsmask, extend);
                else
-                       Collision_ClipLineToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask, extend, hitsurfaces);
+                       Collision_ClipLineToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask, extend, hitsurfaces);
 
                if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                        *hitnetworkentity = 0;
@@ -636,7 +636,7 @@ finished:
 CL_Move
 ==================
 */
-trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, float extend, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities)
+trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, float extend, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities)
 {
        prvm_prog_t *prog = CLVM_prog;
        vec3_t hullmins, hullmaxs;
@@ -670,9 +670,9 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
                VectorAdd(start, mins, shiftstart);
                VectorAdd(end, mins, shiftend);
                if (VectorCompare(start, end))
-                       trace = CL_TracePoint(shiftstart, type, passedict, hitsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities);
+                       trace = CL_TracePoint(shiftstart, type, passedict, hitsupercontentsmask, skipsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities);
                else
-                       trace = CL_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask, extend, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities, false);
+                       trace = CL_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask, skipsupercontentsmask, extend, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities, false);
                VectorSubtract(trace.endpos, mins, trace.endpos);
                return trace;
        }
@@ -691,7 +691,7 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
 #endif
 
        // clip to world
-       Collision_ClipToWorld(&cliptrace, cl.worldmodel, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask, extend);
+       Collision_ClipToWorld(&cliptrace, cl.worldmodel, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask, skipsupercontentsmask, extend);
        cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
        if (cliptrace.startsolid || cliptrace.fraction < 1)
                cliptrace.ent = prog ? prog->edicts : NULL;
@@ -751,7 +751,7 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
                        entity_render_t *ent = &cl.entities[cl.brushmodel_entities[i]].render;
                        if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs))
                                continue;
-                       Collision_ClipToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, mins, maxs, end, hitsupercontentsmask, extend);
+                       Collision_ClipToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, mins, maxs, end, hitsupercontentsmask, skipsupercontentsmask, extend);
                        if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                                *hitnetworkentity = cl.brushmodel_entities[i];
                        Collision_CombineTraces(&cliptrace, &trace, NULL, true);
@@ -799,7 +799,7 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
                                continue;
                        Matrix4x4_CreateTranslate(&entmatrix, origin[0], origin[1], origin[2]);
                        Matrix4x4_CreateTranslate(&entinversematrix, -origin[0], -origin[1], -origin[2]);
-                       Collision_ClipToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, mins, maxs, end, hitsupercontentsmask, extend);
+                       Collision_ClipToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, mins, maxs, end, hitsupercontentsmask, skipsupercontentsmask, extend);
                        if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                                *hitnetworkentity = i;
                        Collision_CombineTraces(&cliptrace, &trace, NULL, false);
@@ -863,9 +863,9 @@ skipnetworkplayers:
                VectorCopy(PRVM_clientedictvector(touch, mins), touchmins);
                VectorCopy(PRVM_clientedictvector(touch, maxs), touchmaxs);
                if ((int)PRVM_clientedictfloat(touch, flags) & FL_MONSTER)
-                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask, extend);
+                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask, skipsupercontentsmask, extend);
                else
-                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask, extend);
+                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask, skipsupercontentsmask, extend);
 
                if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                        *hitnetworkentity = 0;
@@ -881,7 +881,7 @@ finished:
 CL_Cache_TraceLine
 ==================
 */
-trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int type, int hitsupercontentsmask)
+trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int type, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        prvm_prog_t *prog = CLVM_prog;
        int i;
@@ -908,7 +908,7 @@ trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int typ
 #endif
 
        // clip to world
-       Collision_Cache_ClipLineToWorldSurfaces(&cliptrace, cl.worldmodel, clipstart, clipend, hitsupercontentsmask);
+       Collision_Cache_ClipLineToWorldSurfaces(&cliptrace, cl.worldmodel, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask);
        cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
        if (cliptrace.startsolid || cliptrace.fraction < 1)
                cliptrace.ent = prog ? prog->edicts : NULL;
@@ -932,7 +932,7 @@ trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int typ
                entity_render_t *ent = &cl.entities[cl.brushmodel_entities[i]].render;
                if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs))
                        continue;
-               Collision_Cache_ClipLineToGenericEntitySurfaces(&trace, ent->model, &ent->matrix, &ent->inversematrix, start, end, hitsupercontentsmask);
+               Collision_Cache_ClipLineToGenericEntitySurfaces(&trace, ent->model, &ent->matrix, &ent->inversematrix, start, end, hitsupercontentsmask, skipsupercontentsmask);
                Collision_CombineTraces(&cliptrace, &trace, NULL, true);
        }
 
@@ -966,7 +966,7 @@ trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int typ
                        continue;
                Matrix4x4_CreateFromQuakeEntity(&matrix, PRVM_clientedictvector(touch, origin)[0], PRVM_clientedictvector(touch, origin)[1], PRVM_clientedictvector(touch, origin)[2], PRVM_clientedictvector(touch, angles)[0], PRVM_clientedictvector(touch, angles)[1], PRVM_clientedictvector(touch, angles)[2], 1);
                Matrix4x4_Invert_Simple(&imatrix, &matrix);
-               Collision_Cache_ClipLineToGenericEntitySurfaces(&trace, model, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask);
+               Collision_Cache_ClipLineToGenericEntitySurfaces(&trace, model, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask);
                Collision_CombineTraces(&cliptrace, &trace, (void *)touch, PRVM_clientedictfloat(touch, solid) == SOLID_BSP);
        }
 
index fb9e87e..5a2e8e1 100644 (file)
@@ -10,10 +10,10 @@ dp_model_t *CL_GetModelFromEdict(prvm_edict_t *ed);
 
 void CL_LinkEdict(prvm_edict_t *ent);
 int CL_GenericHitSuperContentsMask(const prvm_edict_t *edict);
-trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, float extend, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities);
-trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, float extend, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities, qboolean hitsurfaces);
-trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities);
-trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int type, int hitsupercontentsmask);
-#define CL_PointSuperContents(point) (CL_TracePoint((point), sv_gameplayfix_swiminbmodels.integer ? MOVE_NOMONSTERS : MOVE_WORLDONLY, NULL, 0, true, false, NULL, false).startsupercontents)
+trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, float extend, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities);
+trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, float extend, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities, qboolean hitsurfaces);
+trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities);
+trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int type, int hitsupercontentsmask, int skipsupercontentsmask);
+#define CL_PointSuperContents(point) (CL_TracePoint((point), sv_gameplayfix_swiminbmodels.integer ? MOVE_NOMONSTERS : MOVE_WORLDONLY, NULL, 0, 0, true, false, NULL, false).startsupercontents)
 
 #endif
index e55f501..1720898 100644 (file)
@@ -838,7 +838,7 @@ static qboolean CL_ClientMovement_Unstick(cl_clientmovement_state_t *s)
        for (i = 0;i < NUMOFFSETS;i++)
        {
                VectorAdd(offsets[i], s->origin, neworigin);
-               if (!CL_TraceBox(neworigin, cl.playercrouchmins, cl.playercrouchmaxs, neworigin, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, collision_extendmovelength.value, true, true, NULL, true).startsolid)
+               if (!CL_TraceBox(neworigin, cl.playercrouchmins, cl.playercrouchmaxs, neworigin, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, 0, collision_extendmovelength.value, true, true, NULL, true).startsolid)
                {
                        VectorCopy(neworigin, s->origin);
                        return true;
@@ -870,7 +870,7 @@ static void CL_ClientMovement_UpdateStatus(cl_clientmovement_state_t *s)
                // low ceiling first
                if (s->crouched)
                {
-                       trace = CL_TraceBox(s->origin, cl.playerstandmins, cl.playerstandmaxs, s->origin, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, collision_extendmovelength.value, true, true, NULL, true);
+                       trace = CL_TraceBox(s->origin, cl.playerstandmins, cl.playerstandmaxs, s->origin, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, collision_extendmovelength.value, true, true, NULL, true);
                        if (!trace.startsolid)
                                s->crouched = false;
                }
@@ -889,7 +889,7 @@ static void CL_ClientMovement_UpdateStatus(cl_clientmovement_state_t *s)
        // set onground
        VectorSet(origin1, s->origin[0], s->origin[1], s->origin[2] + 1);
        VectorSet(origin2, s->origin[0], s->origin[1], s->origin[2] - 1); // -2 causes clientside doublejump bug at above 150fps, raising that to 300fps :)
-       trace = CL_TraceBox(origin1, s->mins, s->maxs, origin2, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, collision_extendmovelength.value, true, true, NULL, true);
+       trace = CL_TraceBox(origin1, s->mins, s->maxs, origin2, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, collision_extendmovelength.value, true, true, NULL, true);
        if(trace.fraction < 1 && trace.plane.normal[2] > 0.7)
        {
                s->onground = true;
@@ -905,16 +905,16 @@ static void CL_ClientMovement_UpdateStatus(cl_clientmovement_state_t *s)
        // set watertype/waterlevel
        VectorSet(origin1, s->origin[0], s->origin[1], s->origin[2] + s->mins[2] + 1);
        s->waterlevel = WATERLEVEL_NONE;
-       s->watertype = CL_TracePoint(origin1, MOVE_NOMONSTERS, s->self, 0, true, false, NULL, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK;
+       s->watertype = CL_TracePoint(origin1, MOVE_NOMONSTERS, s->self, 0, 0, true, false, NULL, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK;
        if (s->watertype)
        {
                s->waterlevel = WATERLEVEL_WETFEET;
                origin1[2] = s->origin[2] + (s->mins[2] + s->maxs[2]) * 0.5f;
-               if (CL_TracePoint(origin1, MOVE_NOMONSTERS, s->self, 0, true, false, NULL, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK)
+               if (CL_TracePoint(origin1, MOVE_NOMONSTERS, s->self, 0, 0, true, false, NULL, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK)
                {
                        s->waterlevel = WATERLEVEL_SWIMMING;
                        origin1[2] = s->origin[2] + 22;
-                       if (CL_TracePoint(origin1, MOVE_NOMONSTERS, s->self, 0, true, false, NULL, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK)
+                       if (CL_TracePoint(origin1, MOVE_NOMONSTERS, s->self, 0, 0, true, false, NULL, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK)
                                s->waterlevel = WATERLEVEL_SUBMERGED;
                }
        }
@@ -941,20 +941,20 @@ static void CL_ClientMovement_Move(cl_clientmovement_state_t *s)
        for (bump = 0, t = s->cmd.frametime;bump < 8 && VectorLength2(s->velocity) > 0;bump++)
        {
                VectorMA(s->origin, t, s->velocity, neworigin);
-               trace = CL_TraceBox(s->origin, s->mins, s->maxs, neworigin, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, collision_extendmovelength.value, true, true, NULL, true);
+               trace = CL_TraceBox(s->origin, s->mins, s->maxs, neworigin, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, collision_extendmovelength.value, true, true, NULL, true);
                if (trace.fraction < 1 && trace.plane.normal[2] == 0)
                {
                        // may be a step or wall, try stepping up
                        // first move forward at a higher level
                        VectorSet(currentorigin2, s->origin[0], s->origin[1], s->origin[2] + cl.movevars_stepheight);
                        VectorSet(neworigin2, neworigin[0], neworigin[1], s->origin[2] + cl.movevars_stepheight);
-                       trace2 = CL_TraceBox(currentorigin2, s->mins, s->maxs, neworigin2, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, collision_extendmovelength.value, true, true, NULL, true);
+                       trace2 = CL_TraceBox(currentorigin2, s->mins, s->maxs, neworigin2, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, collision_extendmovelength.value, true, true, NULL, true);
                        if (!trace2.startsolid)
                        {
                                // then move down from there
                                VectorCopy(trace2.endpos, currentorigin2);
                                VectorSet(neworigin2, trace2.endpos[0], trace2.endpos[1], s->origin[2]);
-                               trace3 = CL_TraceBox(currentorigin2, s->mins, s->maxs, neworigin2, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, collision_extendmovelength.value, true, true, NULL, true);
+                               trace3 = CL_TraceBox(currentorigin2, s->mins, s->maxs, neworigin2, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, collision_extendmovelength.value, true, true, NULL, true);
                                //Con_Printf("%f %f %f %f : %f %f %f %f : %f %f %f %f\n", trace.fraction, trace.endpos[0], trace.endpos[1], trace.endpos[2], trace2.fraction, trace2.endpos[0], trace2.endpos[1], trace2.endpos[2], trace3.fraction, trace3.endpos[0], trace3.endpos[1], trace3.endpos[2]);
                                // accept the new trace if it made some progress
                                if (fabs(trace3.endpos[0] - trace.endpos[0]) >= 0.03125 || fabs(trace3.endpos[1] - trace.endpos[1]) >= 0.03125)
@@ -1008,10 +1008,10 @@ static void CL_ClientMovement_Physics_Swim(cl_clientmovement_state_t *s)
                AngleVectors(yawangles, forward, NULL, NULL);
                VectorMA(s->origin, 24, forward, spot);
                spot[2] += 8;
-               if (CL_TracePoint(spot, MOVE_NOMONSTERS, s->self, 0, true, false, NULL, false).startsolid)
+               if (CL_TracePoint(spot, MOVE_NOMONSTERS, s->self, 0, 0, true, false, NULL, false).startsolid)
                {
                        spot[2] += 24;
-                       if (!CL_TracePoint(spot, MOVE_NOMONSTERS, s->self, 0, true, false, NULL, false).startsolid)
+                       if (!CL_TracePoint(spot, MOVE_NOMONSTERS, s->self, 0, 0, true, false, NULL, false).startsolid)
                        {
                                VectorScale(forward, 50, s->velocity);
                                s->velocity[2] = 310;
@@ -1354,9 +1354,9 @@ static void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s)
                                VectorSet(neworigin2, s->origin[0] + s->velocity[0]*(16/f), s->origin[1] + s->velocity[1]*(16/f), s->origin[2] + s->mins[2]);
                                VectorSet(neworigin3, neworigin2[0], neworigin2[1], neworigin2[2] - 34);
                                if (cls.protocol == PROTOCOL_QUAKEWORLD)
-                                       trace = CL_TraceBox(neworigin2, s->mins, s->maxs, neworigin3, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, collision_extendmovelength.value, true, true, NULL, true);
+                                       trace = CL_TraceBox(neworigin2, s->mins, s->maxs, neworigin3, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, collision_extendmovelength.value, true, true, NULL, true);
                                else
-                                       trace = CL_TraceLine(neworigin2, neworigin3, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, collision_extendmovelength.value, true, true, NULL, true, false);
+                                       trace = CL_TraceLine(neworigin2, neworigin3, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, collision_extendmovelength.value, true, true, NULL, true, false);
                                if (trace.fraction == 1 && !trace.startsolid)
                                        friction *= cl.movevars_edgefriction;
                        }
index 51a02ff..40ede8f 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -1490,7 +1490,7 @@ static void CL_LinkNetworkEntity(entity_t *e)
                trace_t trace;
                matrix4x4_t tempmatrix;
                Matrix4x4_Transform(&e->render.matrix, muzzleflashorigin, v2);
-               trace = CL_TraceLine(origin, v2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false, false);
+               trace = CL_TraceLine(origin, v2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, 0, collision_extendmovelength.value, true, false, NULL, false, false);
                Matrix4x4_Normalize(&tempmatrix, &e->render.matrix);
                Matrix4x4_SetOrigin(&tempmatrix, trace.endpos[0], trace.endpos[1], trace.endpos[2]);
                Matrix4x4_Scale(&tempmatrix, 150, 1);
index d8fc811..a18d31e 100644 (file)
@@ -771,7 +771,7 @@ particle_t *CL_NewParticle(const vec3_t sortorigin, unsigned short ptypeindex, i
                part->typeindex = pt_spark;
                part->bounce = 0;
                VectorMA(part->org, lifetime, part->vel, endvec);
-               trace = CL_TraceLine(part->org, endvec, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_LIQUIDSMASK, collision_extendmovelength.value, true, false, NULL, false, false);
+               trace = CL_TraceLine(part->org, endvec, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_LIQUIDSMASK, 0, collision_extendmovelength.value, true, false, NULL, false, false);
                part->die = cl.time + lifetime * trace.fraction;
                part2 = CL_NewParticle(endvec, pt_raindecal, pcolor1, pcolor2, tex_rainsplash, part->size, part->size * 20, part->alpha, part->alpha / 0.4, 0, 0, trace.endpos[0] + trace.plane.normal[0], trace.endpos[1] + trace.plane.normal[1], trace.endpos[2] + trace.plane.normal[2], trace.plane.normal[0], trace.plane.normal[1], trace.plane.normal[2], 0, 0, 0, 0, pqualityreduction, 0, 1, PBLEND_ADD, PARTICLE_ORIENTED_DOUBLESIDED, -1, -1, -1, 1, 1, 0, 0, NULL);
                if (part2)
@@ -912,7 +912,7 @@ void CL_SpawnDecalParticleForPoint(const vec3_t org, float maxdist, float size,
        {
                VectorRandom(org2);
                VectorMA(org, maxdist, org2, org2);
-               trace = CL_TraceLine(org, org2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, &hitent, false, true);
+               trace = CL_TraceLine(org, org2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, 0, collision_extendmovelength.value, true, false, &hitent, false, true);
                // take the closest trace result that doesn't end up hitting a NOMARKS
                // surface (sky for example)
                if (bestfrac > trace.fraction && !(trace.hitq3surfaceflags & Q3SURFACEFLAG_NOMARKS))
@@ -1876,7 +1876,7 @@ void CL_ParticleExplosion (const vec3_t org)
                                        {
                                                VectorRandom(v2);
                                                VectorMA(org, 128, v2, v);
-                                               trace = CL_TraceLine(org, v, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, collision_extendmovelength.value, true, false, NULL, false, false);
+                                               trace = CL_TraceLine(org, v, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, 0, collision_extendmovelength.value, true, false, NULL, false, false);
                                        }
                                        while (k < 16 && trace.fraction < 0.1f);
                                        VectorSubtract(trace.endpos, org, v2);
@@ -2985,7 +2985,7 @@ void R_DrawParticles (void)
 //                             if (p->bounce && cl.time >= p->delayedcollisions)
                                if (p->bounce && cl_particles_collisions.integer && VectorLength(p->vel))
                                {
-                                       trace = CL_TraceLine(oldorg, p->org, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | ((p->typeindex == pt_rain || p->typeindex == pt_snow) ? SUPERCONTENTS_LIQUIDSMASK : 0), collision_extendmovelength.value, true, false, &hitent, false, false);
+                                       trace = CL_TraceLine(oldorg, p->org, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | ((p->typeindex == pt_rain || p->typeindex == pt_snow) ? SUPERCONTENTS_LIQUIDSMASK : 0), 0, collision_extendmovelength.value, true, false, &hitent, false, false);
                                        // if the trace started in or hit something of SUPERCONTENTS_NODROP
                                        // or if the trace hit something flagged as NOIMPACT
                                        // then remove the particle
index 4230c6a..aae1c86 100644 (file)
--- a/client.h
+++ b/client.h
@@ -395,8 +395,11 @@ typedef struct rtlight_s
        rtlight_particle_t *particlecache_particles;
 
        /// bouncegrid light info
-       float photoncolor[3];
-       float photons;
+       float bouncegrid_photoncolor[3];
+       float bouncegrid_photons;
+       int bouncegrid_hits;
+       int bouncegrid_traces;
+       float bouncegrid_effectiveradius;
 }
 rtlight_t;
 
index 28e62c2..290cabc 100644 (file)
@@ -302,7 +302,7 @@ static void VM_CL_traceline (prvm_prog_t *prog)
        if (VEC_IS_NAN(v1[0]) || VEC_IS_NAN(v1[1]) || VEC_IS_NAN(v1[2]) || VEC_IS_NAN(v2[0]) || VEC_IS_NAN(v2[1]) || VEC_IS_NAN(v2[2]))
                prog->error_cmd("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
 
-       trace = CL_TraceLine(v1, v2, move, ent, CL_GenericHitSuperContentsMask(ent), collision_extendtracelinelength.value, CL_HitNetworkBrushModels(move), CL_HitNetworkPlayers(move), &svent, true, false);
+       trace = CL_TraceLine(v1, v2, move, ent, CL_GenericHitSuperContentsMask(ent), 0, collision_extendtracelinelength.value, CL_HitNetworkBrushModels(move), CL_HitNetworkPlayers(move), &svent, true, false);
 
        CL_VM_SetTraceGlobals(prog, &trace, svent);
 //     R_TimeReport("traceline");
@@ -342,7 +342,7 @@ static void VM_CL_tracebox (prvm_prog_t *prog)
        if (VEC_IS_NAN(v1[0]) || VEC_IS_NAN(v1[1]) || VEC_IS_NAN(v1[2]) || VEC_IS_NAN(v2[0]) || VEC_IS_NAN(v2[1]) || VEC_IS_NAN(v2[2]))
                prog->error_cmd("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
 
-       trace = CL_TraceBox(v1, m1, m2, v2, move, ent, CL_GenericHitSuperContentsMask(ent), collision_extendtraceboxlength.value, CL_HitNetworkBrushModels(move), CL_HitNetworkPlayers(move), &svent, true);
+       trace = CL_TraceBox(v1, m1, m2, v2, move, ent, CL_GenericHitSuperContentsMask(ent), 0, collision_extendtraceboxlength.value, CL_HitNetworkBrushModels(move), CL_HitNetworkPlayers(move), &svent, true);
 
        CL_VM_SetTraceGlobals(prog, &trace, svent);
 //     R_TimeReport("tracebox");
@@ -378,7 +378,7 @@ static trace_t CL_Trace_Toss (prvm_prog_t *prog, prvm_edict_t *tossent, prvm_edi
                VectorCopy(PRVM_clientedictvector(tossent, origin), start);
                VectorCopy(PRVM_clientedictvector(tossent, mins), mins);
                VectorCopy(PRVM_clientedictvector(tossent, maxs), maxs);
-               trace = CL_TraceBox(start, mins, maxs, end, MOVE_NORMAL, tossent, CL_GenericHitSuperContentsMask(tossent), collision_extendmovelength.value, true, true, NULL, true);
+               trace = CL_TraceBox(start, mins, maxs, end, MOVE_NORMAL, tossent, CL_GenericHitSuperContentsMask(tossent), 0, collision_extendmovelength.value, true, true, NULL, true);
                VectorCopy (trace.endpos, PRVM_clientedictvector(tossent, origin));
 
                if (trace.fraction < 1)
@@ -552,7 +552,7 @@ static void VM_CL_droptofloor (prvm_prog_t *prog)
        VectorCopy(PRVM_clientedictvector(ent, origin), end);
        end[2] -= 256;
 
-       trace = CL_TraceBox(start, mins, maxs, end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), collision_extendmovelength.value, true, true, NULL, true);
+       trace = CL_TraceBox(start, mins, maxs, end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value, true, true, NULL, true);
 
        if (trace.fraction != 1)
        {
@@ -630,7 +630,7 @@ realcheck:
        start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
        start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
        stop[2] = start[2] - 2*sv_stepheight.value;
-       trace = CL_TraceLine(start, stop, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), collision_extendmovelength.value, true, true, NULL, true, false);
+       trace = CL_TraceLine(start, stop, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value, true, true, NULL, true, false);
 
        if (trace.fraction == 1.0)
                return;
@@ -644,7 +644,7 @@ realcheck:
                        start[0] = stop[0] = x ? maxs[0] : mins[0];
                        start[1] = stop[1] = y ? maxs[1] : mins[1];
 
-                       trace = CL_TraceLine(start, stop, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), collision_extendmovelength.value, true, true, NULL, true, false);
+                       trace = CL_TraceLine(start, stop, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value, true, true, NULL, true, false);
 
                        if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
                                bottom = trace.endpos[2];
@@ -3639,7 +3639,7 @@ realcheck:
        start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
        start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
        stop[2] = start[2] - 2*sv_stepheight.value;
-       trace = CL_TraceLine(start, stop, MOVE_NOMONSTERS, ent, CL_GenericHitSuperContentsMask(ent), collision_extendmovelength.value, true, false, NULL, true, false);
+       trace = CL_TraceLine(start, stop, MOVE_NOMONSTERS, ent, CL_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value, true, false, NULL, true, false);
 
        if (trace.fraction == 1.0)
                return false;
@@ -3652,7 +3652,7 @@ realcheck:
                        start[0] = stop[0] = x ? maxs[0] : mins[0];
                        start[1] = stop[1] = y ? maxs[1] : mins[1];
 
-                       trace = CL_TraceLine(start, stop, MOVE_NOMONSTERS, ent, CL_GenericHitSuperContentsMask(ent), collision_extendmovelength.value, true, false, NULL, true, false);
+                       trace = CL_TraceLine(start, stop, MOVE_NOMONSTERS, ent, CL_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value, true, false, NULL, true, false);
 
                        if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
                                bottom = trace.endpos[2];
@@ -3705,7 +3705,7 @@ static qboolean CL_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qb
                                        neworg[2] += 8;
                        }
                        VectorCopy(PRVM_clientedictvector(ent, origin), start);
-                       trace = CL_TraceBox(start, mins, maxs, neworg, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), collision_extendmovelength.value, true, true, &svent, true);
+                       trace = CL_TraceBox(start, mins, maxs, neworg, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value, true, true, &svent, true);
                        if (settrace)
                                CL_VM_SetTraceGlobals(prog, &trace, svent);
 
@@ -3733,14 +3733,14 @@ static qboolean CL_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qb
        VectorCopy (neworg, end);
        end[2] -= sv_stepheight.value*2;
 
-       trace = CL_TraceBox(neworg, mins, maxs, end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), collision_extendmovelength.value, true, true, &svent, true);
+       trace = CL_TraceBox(neworg, mins, maxs, end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value, true, true, &svent, true);
        if (settrace)
                CL_VM_SetTraceGlobals(prog, &trace, svent);
 
        if (trace.startsolid)
        {
                neworg[2] -= sv_stepheight.value;
-               trace = CL_TraceBox(neworg, mins, maxs, end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), collision_extendmovelength.value, true, true, &svent, true);
+               trace = CL_TraceBox(neworg, mins, maxs, end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value, true, true, &svent, true);
                if (settrace)
                        CL_VM_SetTraceGlobals(prog, &trace, svent);
                if (trace.startsolid)
index 547ad23..827200e 100644 (file)
@@ -741,7 +741,7 @@ void Collision_TraceBrushBrushFloat(trace_t *trace, const colbrushf_t *trace_sta
        {
                // started outside, and overlaps, therefore there is a collision here
                // store out the impact information
-               if (trace->hitsupercontentsmask & other_start->supercontents)
+               if ((trace->hitsupercontentsmask & other_start->supercontents) && !(trace->skipsupercontentsmask & other_start->supercontents))
                {
                        trace->hitsupercontents = other_start->supercontents;
                        trace->hitq3surfaceflags = hitq3surfaceflags;
@@ -755,7 +755,7 @@ void Collision_TraceBrushBrushFloat(trace_t *trace, const colbrushf_t *trace_sta
        {
                // started inside, update startsolid and friends
                trace->startsupercontents |= other_start->supercontents;
-               if (trace->hitsupercontentsmask & other_start->supercontents)
+               if ((trace->hitsupercontentsmask & other_start->supercontents) && !(trace->skipsupercontentsmask & other_start->supercontents))
                {
                        trace->startsolid = true;
                        if (leavefrac < 1)
@@ -889,7 +889,7 @@ void Collision_TraceLineBrushFloat(trace_t *trace, const vec3_t linestart, const
        {
                // started outside, and overlaps, therefore there is a collision here
                // store out the impact information
-               if (trace->hitsupercontentsmask & other_start->supercontents)
+               if ((trace->hitsupercontentsmask & other_start->supercontents) && !(trace->skipsupercontentsmask & other_start->supercontents))
                {
                        trace->hitsupercontents = other_start->supercontents;
                        trace->hitq3surfaceflags = hitq3surfaceflags;
@@ -903,7 +903,7 @@ void Collision_TraceLineBrushFloat(trace_t *trace, const vec3_t linestart, const
        {
                // started inside, update startsolid and friends
                trace->startsupercontents |= other_start->supercontents;
-               if (trace->hitsupercontentsmask & other_start->supercontents)
+               if ((trace->hitsupercontentsmask & other_start->supercontents) && !(trace->skipsupercontentsmask & other_start->supercontents))
                {
                        trace->startsolid = true;
                        if (leavefrac < 1)
@@ -938,7 +938,7 @@ void Collision_TracePointBrushFloat(trace_t *trace, const vec3_t point, const co
                return;
 
        trace->startsupercontents |= thatbrush->supercontents;
-       if (trace->hitsupercontentsmask & thatbrush->supercontents)
+       if ((trace->hitsupercontentsmask & thatbrush->supercontents) && !(trace->skipsupercontentsmask & thatbrush->supercontents))
        {
                trace->startsolid = true;
                trace->allsolid = true;
@@ -1309,6 +1309,10 @@ void Collision_TraceLineTriangleFloat(trace_t *trace, const vec3_t linestart, co
 
        // 8 ops (rare)
 
+       // skip if this trace should not be blocked by these contents
+       if (!(supercontents & trace->hitsupercontentsmask) || (supercontents & trace->skipsupercontentsmask))
+               return;
+
        // store the new trace fraction
        trace->fraction = f2;
 
@@ -1408,6 +1412,7 @@ typedef struct collision_cachedtrace_parameters_s
        vec3_t end;
        vec3_t start;
        int hitsupercontentsmask;
+       int skipsupercontentsmask;
        matrix4x4_t matrix;
 }
 collision_cachedtrace_parameters_t;
@@ -1537,7 +1542,7 @@ static unsigned int Collision_Cache_HashIndexForArray(unsigned int *array, unsig
        return hashindex;
 }
 
-static collision_cachedtrace_t *Collision_Cache_Lookup(dp_model_t *model, const matrix4x4_t *matrix, const matrix4x4_t *inversematrix, const vec3_t start, const vec3_t end, int hitsupercontentsmask)
+static collision_cachedtrace_t *Collision_Cache_Lookup(dp_model_t *model, const matrix4x4_t *matrix, const matrix4x4_t *inversematrix, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        int hashindex = 0;
        unsigned int fullhashindex;
@@ -1560,6 +1565,7 @@ static collision_cachedtrace_t *Collision_Cache_Lookup(dp_model_t *model, const
                VectorCopy(start, params.start);
                VectorCopy(end,   params.end);
                params.hitsupercontentsmask = hitsupercontentsmask;
+               params.skipsupercontentsmask = skipsupercontentsmask;
                params.matrix = *matrix;
                fullhashindex = Collision_Cache_HashIndexForArray((unsigned int *)&params, sizeof(params) / sizeof(unsigned int));
                hashindex = (int)(fullhashindex % (unsigned int)collision_cachedtrace_hashsize);
@@ -1577,6 +1583,7 @@ static collision_cachedtrace_t *Collision_Cache_Lookup(dp_model_t *model, const
                         || cached->p.start[1] != params.start[1]
                         || cached->p.start[2] != params.start[2]
                         || cached->p.hitsupercontentsmask != params.hitsupercontentsmask
+                        || cached->p.skipsupercontentsmask != params.skipsupercontentsmask
                         || cached->p.matrix.m[0][0] != params.matrix.m[0][0]
                         || cached->p.matrix.m[0][1] != params.matrix.m[0][1]
                         || cached->p.matrix.m[0][2] != params.matrix.m[0][2]
@@ -1641,30 +1648,30 @@ static collision_cachedtrace_t *Collision_Cache_Lookup(dp_model_t *model, const
        return cached;
 }
 
-void Collision_Cache_ClipLineToGenericEntitySurfaces(trace_t *trace, dp_model_t *model, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t end, int hitsupercontentsmask)
+void Collision_Cache_ClipLineToGenericEntitySurfaces(trace_t *trace, dp_model_t *model, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask)
 {
-       collision_cachedtrace_t *cached = Collision_Cache_Lookup(model, matrix, inversematrix, start, end, hitsupercontentsmask);
+       collision_cachedtrace_t *cached = Collision_Cache_Lookup(model, matrix, inversematrix, start, end, hitsupercontentsmask, skipsupercontentsmask);
        if (cached->valid)
        {
                *trace = cached->result;
                return;
        }
 
-       Collision_ClipLineToGenericEntity(trace, model, NULL, NULL, vec3_origin, vec3_origin, 0, matrix, inversematrix, start, end, hitsupercontentsmask, collision_extendmovelength.value, true);
+       Collision_ClipLineToGenericEntity(trace, model, NULL, NULL, vec3_origin, vec3_origin, 0, matrix, inversematrix, start, end, hitsupercontentsmask, skipsupercontentsmask, collision_extendmovelength.value, true);
 
        cached->result = *trace;
 }
 
-void Collision_Cache_ClipLineToWorldSurfaces(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t end, int hitsupercontents)
+void Collision_Cache_ClipLineToWorldSurfaces(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask)
 {
-       collision_cachedtrace_t *cached = Collision_Cache_Lookup(model, &identitymatrix, &identitymatrix, start, end, hitsupercontents);
+       collision_cachedtrace_t *cached = Collision_Cache_Lookup(model, &identitymatrix, &identitymatrix, start, end, hitsupercontentsmask, skipsupercontentsmask);
        if (cached->valid)
        {
                *trace = cached->result;
                return;
        }
 
-       Collision_ClipLineToWorld(trace, model, start, end, hitsupercontents, collision_extendmovelength.value, true);
+       Collision_ClipLineToWorld(trace, model, start, end, hitsupercontentsmask, skipsupercontentsmask, collision_extendmovelength.value, true);
 
        cached->result = *trace;
 }
@@ -1741,7 +1748,7 @@ static void Collision_ClipExtendFinish(extendtraceinfo_t *extendtraceinfo)
        VectorMA(extendtraceinfo->realstart, trace->fraction, extendtraceinfo->realdelta, trace->endpos);
 }
 
-void Collision_ClipToGenericEntity(trace_t *trace, dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t tstart, const vec3_t mins, const vec3_t maxs, const vec3_t tend, int hitsupercontentsmask, float extend)
+void Collision_ClipToGenericEntity(trace_t *trace, dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t tstart, const vec3_t mins, const vec3_t maxs, const vec3_t tend, int hitsupercontentsmask, int skipsupercontentsmask, float extend)
 {
        vec3_t starttransformed, endtransformed;
        extendtraceinfo_t extendtraceinfo;
@@ -1769,13 +1776,13 @@ void Collision_ClipToGenericEntity(trace_t *trace, dp_model_t *model, const fram
                        Collision_TransformBrush(inversematrix, &thisbrush_end.brush);
                        //Collision_TranslateBrush(starttransformed, &thisbrush_start.brush);
                        //Collision_TranslateBrush(endtransformed, &thisbrush_end.brush);
-                       model->TraceBrush(model, frameblend, skeleton, trace, &thisbrush_start.brush, &thisbrush_end.brush, hitsupercontentsmask);
+                       model->TraceBrush(model, frameblend, skeleton, trace, &thisbrush_start.brush, &thisbrush_end.brush, hitsupercontentsmask, skipsupercontentsmask);
                }
                else // this is only approximate if rotated, quite useless
-                       model->TraceBox(model, frameblend, skeleton, trace, starttransformed, mins, maxs, endtransformed, hitsupercontentsmask);
+                       model->TraceBox(model, frameblend, skeleton, trace, starttransformed, mins, maxs, endtransformed, hitsupercontentsmask, skipsupercontentsmask);
        }
        else // and this requires that the transformation matrix doesn't have angles components, like SV_TraceBox ensures; FIXME may get called if a model is SOLID_BSP but has no TraceBox function
-               Collision_ClipTrace_Box(trace, bodymins, bodymaxs, starttransformed, mins, maxs, endtransformed, hitsupercontentsmask, bodysupercontents, 0, NULL);
+               Collision_ClipTrace_Box(trace, bodymins, bodymaxs, starttransformed, mins, maxs, endtransformed, hitsupercontentsmask, skipsupercontentsmask, bodysupercontents, 0, NULL);
 
        Collision_ClipExtendFinish(&extendtraceinfo);
 
@@ -1784,17 +1791,17 @@ void Collision_ClipToGenericEntity(trace_t *trace, dp_model_t *model, const fram
        Matrix4x4_TransformPositivePlane(matrix, trace->plane.normal[0], trace->plane.normal[1], trace->plane.normal[2], trace->plane.dist, trace->plane.normal_and_dist);
 }
 
-void Collision_ClipToWorld(trace_t *trace, dp_model_t *model, const vec3_t tstart, const vec3_t mins, const vec3_t maxs, const vec3_t tend, int hitsupercontents, float extend)
+void Collision_ClipToWorld(trace_t *trace, dp_model_t *model, const vec3_t tstart, const vec3_t mins, const vec3_t maxs, const vec3_t tend, int hitsupercontentsmask, int skipsupercontentsmask, float extend)
 {
        extendtraceinfo_t extendtraceinfo;
        Collision_ClipExtendPrepare(&extendtraceinfo, trace, tstart, tend, extend);
        // ->TraceBox: TraceBrush not needed here, as worldmodel is never rotated
        if (model && model->TraceBox)
-               model->TraceBox(model, NULL, NULL, trace, extendtraceinfo.extendstart, mins, maxs, extendtraceinfo.extendend, hitsupercontents);
+               model->TraceBox(model, NULL, NULL, trace, extendtraceinfo.extendstart, mins, maxs, extendtraceinfo.extendend, hitsupercontentsmask, skipsupercontentsmask);
        Collision_ClipExtendFinish(&extendtraceinfo);
 }
 
-void Collision_ClipLineToGenericEntity(trace_t *trace, dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t tstart, const vec3_t tend, int hitsupercontentsmask, float extend, qboolean hitsurfaces)
+void Collision_ClipLineToGenericEntity(trace_t *trace, dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t tstart, const vec3_t tend, int hitsupercontentsmask, int skipsupercontentsmask, float extend, qboolean hitsurfaces)
 {
        vec3_t starttransformed, endtransformed;
        extendtraceinfo_t extendtraceinfo;
@@ -1807,11 +1814,11 @@ void Collision_ClipLineToGenericEntity(trace_t *trace, dp_model_t *model, const
 #endif
 
        if (model && model->TraceLineAgainstSurfaces && hitsurfaces)
-               model->TraceLineAgainstSurfaces(model, frameblend, skeleton, trace, starttransformed, endtransformed, hitsupercontentsmask);
+               model->TraceLineAgainstSurfaces(model, frameblend, skeleton, trace, starttransformed, endtransformed, hitsupercontentsmask, skipsupercontentsmask);
        else if (model && model->TraceLine)
-               model->TraceLine(model, frameblend, skeleton, trace, starttransformed, endtransformed, hitsupercontentsmask);
+               model->TraceLine(model, frameblend, skeleton, trace, starttransformed, endtransformed, hitsupercontentsmask, skipsupercontentsmask);
        else
-               Collision_ClipTrace_Box(trace, bodymins, bodymaxs, starttransformed, vec3_origin, vec3_origin, endtransformed, hitsupercontentsmask, bodysupercontents, 0, NULL);
+               Collision_ClipTrace_Box(trace, bodymins, bodymaxs, starttransformed, vec3_origin, vec3_origin, endtransformed, hitsupercontentsmask, skipsupercontentsmask, bodysupercontents, 0, NULL);
 
        Collision_ClipExtendFinish(&extendtraceinfo);
 
@@ -1820,20 +1827,20 @@ void Collision_ClipLineToGenericEntity(trace_t *trace, dp_model_t *model, const
        Matrix4x4_TransformPositivePlane(matrix, trace->plane.normal[0], trace->plane.normal[1], trace->plane.normal[2], trace->plane.dist, trace->plane.normal_and_dist);
 }
 
-void Collision_ClipLineToWorld(trace_t *trace, dp_model_t *model, const vec3_t tstart, const vec3_t tend, int hitsupercontents, float extend, qboolean hitsurfaces)
+void Collision_ClipLineToWorld(trace_t *trace, dp_model_t *model, const vec3_t tstart, const vec3_t tend, int hitsupercontentsmask, int skipsupercontentsmask, float extend, qboolean hitsurfaces)
 {
        extendtraceinfo_t extendtraceinfo;
        Collision_ClipExtendPrepare(&extendtraceinfo, trace, tstart, tend, extend);
 
        if (model && model->TraceLineAgainstSurfaces && hitsurfaces)
-               model->TraceLineAgainstSurfaces(model, NULL, NULL, trace, extendtraceinfo.extendstart, extendtraceinfo.extendend, hitsupercontents);
+               model->TraceLineAgainstSurfaces(model, NULL, NULL, trace, extendtraceinfo.extendstart, extendtraceinfo.extendend, hitsupercontentsmask, skipsupercontentsmask);
        else if (model && model->TraceLine)
-               model->TraceLine(model, NULL, NULL, trace, extendtraceinfo.extendstart, extendtraceinfo.extendend, hitsupercontents);
+               model->TraceLine(model, NULL, NULL, trace, extendtraceinfo.extendstart, extendtraceinfo.extendend, hitsupercontentsmask, skipsupercontentsmask);
 
        Collision_ClipExtendFinish(&extendtraceinfo);
 }
 
-void Collision_ClipPointToGenericEntity(trace_t *trace, dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, int hitsupercontentsmask)
+void Collision_ClipPointToGenericEntity(trace_t *trace, dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        float starttransformed[3];
        memset(trace, 0, sizeof(*trace));
@@ -1845,9 +1852,9 @@ void Collision_ClipPointToGenericEntity(trace_t *trace, dp_model_t *model, const
 #endif
 
        if (model && model->TracePoint)
-               model->TracePoint(model, NULL, NULL, trace, starttransformed, hitsupercontentsmask);
+               model->TracePoint(model, NULL, NULL, trace, starttransformed, hitsupercontentsmask, skipsupercontentsmask);
        else
-               Collision_ClipTrace_Point(trace, bodymins, bodymaxs, starttransformed, hitsupercontentsmask, bodysupercontents, 0, NULL);
+               Collision_ClipTrace_Point(trace, bodymins, bodymaxs, starttransformed, hitsupercontentsmask, skipsupercontentsmask, bodysupercontents, 0, NULL);
 
        VectorCopy(start, trace->endpos);
        // transform plane
@@ -1855,12 +1862,12 @@ void Collision_ClipPointToGenericEntity(trace_t *trace, dp_model_t *model, const
        Matrix4x4_TransformPositivePlane(matrix, trace->plane.normal[0], trace->plane.normal[1], trace->plane.normal[2], trace->plane.dist, trace->plane.normal_and_dist);
 }
 
-void Collision_ClipPointToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, int hitsupercontents)
+void Collision_ClipPointToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        memset(trace, 0, sizeof(*trace));
        trace->fraction = 1;
        if (model && model->TracePoint)
-               model->TracePoint(model, NULL, NULL, trace, start, hitsupercontents);
+               model->TracePoint(model, NULL, NULL, trace, start, hitsupercontentsmask, skipsupercontentsmask);
        VectorCopy(start, trace->endpos);
 }
 
index e077082..d64f16e 100644 (file)
@@ -44,6 +44,8 @@ typedef struct trace_s
        // which SUPERCONTENTS bits to collide with, I.E. to consider solid
        // (this also affects startsolid/allsolid)
        int hitsupercontentsmask;
+       // deliberately skip surfaces matching this mask (e.g. SUPERCONTENTS_SKY allows you to bypass sky surfaces in q1bsp/q2bsp which are SUPERCONTENTS_SKY | SUPERCONTENTS_SOLID)
+       int skipsupercontentsmask;
        // the supercontents mask at the start point
        int startsupercontents;
        // the supercontents of the impacted surface
@@ -63,8 +65,8 @@ typedef struct trace_s
 trace_t;
 
 void Collision_Init(void);
-void Collision_ClipTrace_Box(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, int boxsupercontents, int boxq3surfaceflags, const texture_t *boxtexture);
-void Collision_ClipTrace_Point(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, int hitsupercontentsmask, int boxsupercontents, int boxq3surfaceflags, const texture_t *boxtexture);
+void Collision_ClipTrace_Box(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int boxsupercontents, int boxq3surfaceflags, const texture_t *boxtexture);
+void Collision_ClipTrace_Point(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask, int boxsupercontents, int boxq3surfaceflags, const texture_t *boxtexture);
 
 void Collision_Cache_Reset(qboolean resetlimits);
 void Collision_Cache_Init(mempool_t *mempool);
@@ -163,16 +165,16 @@ void Collision_TraceBrushTriangleFloat(trace_t *trace, const colbrushf_t *thisbr
 // passedict is excluded from clipping checks
 struct frameblend_s;
 struct skeleton_s;
-void Collision_ClipToGenericEntity(trace_t *trace, dp_model_t *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, float extend);
-void Collision_ClipLineToGenericEntity(trace_t *trace, dp_model_t *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t end, int hitsupercontentsmask, float extend, qboolean hitsurfaces);
-void Collision_ClipPointToGenericEntity(trace_t *trace, dp_model_t *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, int hitsupercontentsmask);
+void Collision_ClipToGenericEntity(trace_t *trace, dp_model_t *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, float extend);
+void Collision_ClipLineToGenericEntity(trace_t *trace, dp_model_t *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, float extend, qboolean hitsurfaces);
+void Collision_ClipPointToGenericEntity(trace_t *trace, dp_model_t *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask);
 // like above but does not do a transform and does nothing if model is NULL
-void Collision_ClipToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontents, float extend);
-void Collision_ClipLineToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t end, int hitsupercontents, float extend, qboolean hitsurfaces);
-void Collision_ClipPointToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, int hitsupercontents);
+void Collision_ClipToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, float extend);
+void Collision_ClipLineToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, float extend, qboolean hitsurfaces);
+void Collision_ClipPointToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask);
 // caching surface trace for renderer (NOT THREAD SAFE)
-void Collision_Cache_ClipLineToGenericEntitySurfaces(trace_t *trace, dp_model_t *model, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t end, int hitsupercontentsmask);
-void Collision_Cache_ClipLineToWorldSurfaces(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t end, int hitsupercontents);
+void Collision_Cache_ClipLineToGenericEntitySurfaces(trace_t *trace, dp_model_t *model, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask);
+void Collision_Cache_ClipLineToWorldSurfaces(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask);
 // combines data from two traces:
 // merges contents flags, startsolid, allsolid, inwater
 // updates fraction, endpos, plane and surface info if new fraction is shorter
index 349b78e..8bf14a8 100644 (file)
@@ -4689,7 +4689,13 @@ void *R_FrameData_Alloc(size_t size)
        while (!r_framedata_mem || r_framedata_mem->current + size > r_framedata_mem->size)
        {
                // emergency - we ran out of space, allocate more memory
-               newvalue = bound(0.25f, r_framedatasize.value * 2.0f, 256.0f);
+               // note: this has no upper-bound, we'll fail to allocate memory eventually and just die
+               newvalue = r_framedatasize.value * 2.0f;
+               // upper bound based on architecture - if we try to allocate more than this we could overflow, better to loop until we error out on allocation failure
+               if (sizeof(size_t) >= 8)
+                       newvalue = bound(0.25f, newvalue, (float)(1ll << 42));
+               else
+                       newvalue = bound(0.25f, newvalue, (float)(1 << 10));
                // this might not be a growing it, but we'll allocate another buffer every time
                Cvar_SetValueQuick(&r_framedatasize, newvalue);
                R_FrameData_Resize(true);
index 9e76ac9..fc3d2ec 100644 (file)
@@ -1256,13 +1256,13 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data)
        for (width  = glt->tilewidth;width  < glt->inputwidth ;width  <<= 1);
        for (height = glt->tileheight;height < glt->inputheight;height <<= 1);
        for (depth  = glt->tiledepth;depth  < glt->inputdepth ;depth  <<= 1);
-       R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
 
        if (prevbuffer == NULL)
        {
                width = glt->tilewidth;
                height = glt->tileheight;
                depth = glt->tiledepth;
+//             R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
 //             memset(resizebuffer, 0, width * height * depth * glt->sides * glt->bytesperpixel);
 //             prevbuffer = resizebuffer;
        }
@@ -1271,6 +1271,7 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data)
                if (glt->textype->textype == TEXTYPE_PALETTE)
                {
                        // promote paletted to BGRA, so we only have to worry about BGRA in the rest of this code
+                       R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                        Image_Copy8bitBGRA(prevbuffer, colorconvertbuffer, glt->inputwidth * glt->inputheight * glt->inputdepth * glt->sides, glt->palette);
                        prevbuffer = colorconvertbuffer;
                }
@@ -1278,6 +1279,7 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data)
                {
                        // multiply RGB channels by A channel before uploading
                        int alpha;
+                       R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                        for (i = 0;i < glt->inputwidth*glt->inputheight*glt->inputdepth*4;i += 4)
                        {
                                alpha = prevbuffer[i+3];
@@ -1291,12 +1293,14 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data)
                // scale up to a power of 2 size (if appropriate)
                if (glt->inputwidth != width || glt->inputheight != height || glt->inputdepth != depth)
                {
+                       R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                        Image_Resample32(prevbuffer, glt->inputwidth, glt->inputheight, glt->inputdepth, resizebuffer, width, height, depth, r_lerpimages.integer);
                        prevbuffer = resizebuffer;
                }
                // apply mipmap reduction algorithm to get down to picmip/max_size
                while (width > glt->tilewidth || height > glt->tileheight || depth > glt->tiledepth)
                {
+                       R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                        Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, glt->tilewidth, glt->tileheight, glt->tiledepth);
                        prevbuffer = resizebuffer;
                }
@@ -1339,6 +1343,7 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data)
                                {
                                        while (width > 1 || height > 1 || depth > 1)
                                        {
+                                               R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                                                Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1);
                                                prevbuffer = resizebuffer;
                                                qglTexImage2D(GL_TEXTURE_2D, mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR
@@ -1352,6 +1357,7 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data)
                                {
                                        while (width > 1 || height > 1 || depth > 1)
                                        {
+                                               R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                                                Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1);
                                                prevbuffer = resizebuffer;
                                                qglTexImage3D(GL_TEXTURE_3D, mip++, glt->glinternalformat, width, height, depth, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR
@@ -1369,12 +1375,14 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data)
                                        texturebuffer += glt->inputwidth * glt->inputheight * glt->inputdepth * glt->textype->inputbytesperpixel;
                                        if (glt->inputwidth != width || glt->inputheight != height || glt->inputdepth != depth)
                                        {
+                                               R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                                                Image_Resample32(prevbuffer, glt->inputwidth, glt->inputheight, glt->inputdepth, resizebuffer, width, height, depth, r_lerpimages.integer);
                                                prevbuffer = resizebuffer;
                                        }
                                        // picmip/max_size
                                        while (width > glt->tilewidth || height > glt->tileheight || depth > glt->tiledepth)
                                        {
+                                               R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                                                Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, glt->tilewidth, glt->tileheight, glt->tiledepth);
                                                prevbuffer = resizebuffer;
                                        }
@@ -1384,6 +1392,7 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data)
                                        {
                                                while (width > 1 || height > 1 || depth > 1)
                                                {
+                                                       R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                                                        Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1);
                                                        prevbuffer = resizebuffer;
                                                        qglTexImage2D(cubemapside[i], mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR
@@ -1418,6 +1427,7 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data)
                                {
                                        while (width > 1 || height > 1 || depth > 1)
                                        {
+                                               R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                                                Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1);
                                                prevbuffer = resizebuffer;
                                                if (IDirect3DTexture9_LockRect((IDirect3DTexture9*)glt->d3dtexture, mip, &d3dlockedrect, NULL, 0) == D3D_OK && d3dlockedrect.pBits)
@@ -1441,6 +1451,7 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data)
                                {
                                        while (width > 1 || height > 1 || depth > 1)
                                        {
+                                               R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                                                Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1);
                                                prevbuffer = resizebuffer;
                                                if (IDirect3DVolumeTexture9_LockBox((IDirect3DVolumeTexture9*)glt->d3dtexture, mip, &d3dlockedbox, NULL, 0) == D3D_OK && d3dlockedbox.pBits)
@@ -1463,12 +1474,14 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data)
                                        texturebuffer += glt->inputwidth * glt->inputheight * glt->inputdepth * glt->textype->inputbytesperpixel;
                                        if (glt->inputwidth != width || glt->inputheight != height || glt->inputdepth != depth)
                                        {
+                                               R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                                                Image_Resample32(prevbuffer, glt->inputwidth, glt->inputheight, glt->inputdepth, resizebuffer, width, height, depth, r_lerpimages.integer);
                                                prevbuffer = resizebuffer;
                                        }
                                        // picmip/max_size
                                        while (width > glt->tilewidth || height > glt->tileheight || depth > glt->tiledepth)
                                        {
+                                               R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                                                Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, glt->tilewidth, glt->tileheight, glt->tiledepth);
                                                prevbuffer = resizebuffer;
                                        }
@@ -1483,6 +1496,7 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data)
                                        {
                                                while (width > 1 || height > 1 || depth > 1)
                                                {
+                                                       R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                                                        Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1);
                                                        prevbuffer = resizebuffer;
                                                        if (IDirect3DCubeTexture9_LockRect((IDirect3DCubeTexture9*)glt->d3dtexture, (D3DCUBEMAP_FACES)i, mip, &d3dlockedrect, NULL, 0) == D3D_OK && d3dlockedrect.pBits)
@@ -1559,6 +1573,7 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data)
                case GLTEXTURETYPE_CUBEMAP:
                        if (glt->inputwidth != width || glt->inputheight != height || glt->inputdepth != depth)
                        {
+                               R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                                unsigned char *combinedbuffer = (unsigned char *)Mem_Alloc(tempmempool, glt->tilewidth*glt->tileheight*glt->tiledepth*glt->sides*glt->bytesperpixel);
                                // convert and upload each side in turn,
                                // from a continuous block of input texels
@@ -1570,12 +1585,14 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data)
                                        texturebuffer += glt->inputwidth * glt->inputheight * glt->inputdepth * glt->textype->inputbytesperpixel;
                                        if (glt->inputwidth != width || glt->inputheight != height || glt->inputdepth != depth)
                                        {
+                                               R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                                                Image_Resample32(prevbuffer, glt->inputwidth, glt->inputheight, glt->inputdepth, resizebuffer, width, height, depth, r_lerpimages.integer);
                                                prevbuffer = resizebuffer;
                                        }
                                        // picmip/max_size
                                        while (width > glt->tilewidth || height > glt->tileheight || depth > glt->tiledepth)
                                        {
+                                               R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
                                                Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, glt->tilewidth, glt->tileheight, glt->tiledepth);
                                                prevbuffer = resizebuffer;
                                        }
index 738965a..b228576 100644 (file)
--- a/mathlib.c
+++ b/mathlib.c
@@ -900,3 +900,82 @@ int LoopingFrameNumberFromDouble(double t, int loopframes)
                return (int)t;
 }
 
+static unsigned int mul_Lecuyer[4] = { 0x12e15e35, 0xb500f16e, 0x2e714eb2, 0xb37916a5 };
+
+static void mul128(unsigned int a[], unsigned int b[], unsigned int dest[4])
+{
+       unsigned long long t[4];
+       t[0] = a[0] * b[0];
+       t[1] = a[1] * b[1];
+       t[2] = a[2] * b[2];
+       t[3] = a[3] * b[3];
+
+       // this is complicated because C doesn't have a way to make use of the
+       // cpu status carry flag, so we do it all in reverse order from what
+       // would otherwise make sense, and have to make multiple passes...
+       t[3] += t[2] >> 32; t[2] &= 0xffffffff;
+       t[2] += t[1] >> 32; t[1] &= 0xffffffff;
+       t[1] += t[0] >> 32; t[0] &= 0xffffffff;
+
+       t[3] += t[2] >> 32; t[2] &= 0xffffffff;
+       t[2] += t[1] >> 32; t[1] &= 0xffffffff;
+
+       t[3] += t[2] >> 32; t[2] &= 0xffffffff;
+
+       dest[0] = t[0] & 0xffffffff;
+       dest[1] = t[1] & 0xffffffff;
+       dest[2] = t[2] & 0xffffffff;
+       dest[3] = t[3] & 0xffffffff;
+}
+
+void Math_RandomSeed_Reset(randomseed_t *r)
+{
+       r->s[0] = 1;
+       r->s[1] = 0;
+       r->s[2] = 0;
+       r->s[3] = 0;
+}
+
+void Math_RandomSeed_FromInt(randomseed_t *r, unsigned int n)
+{
+       // if the entire s[] is zero the algorithm would break completely, so make sure it isn't zero by putting a 1 here
+       r->s[0] = 1;
+       r->s[1] = 0;
+       r->s[2] = 0;
+       r->s[3] = n;
+}
+
+unsigned long long Math_rand64(randomseed_t *r)
+{
+       unsigned int o[4];
+       mul128(r->s, mul_Lecuyer, o);
+       r->s[0] = o[0];
+       r->s[1] = o[1];
+       r->s[2] = o[2];
+       r->s[3] = o[3];
+       return ((unsigned long long)o[3] << 32) + o[2];
+}
+
+float Math_randomf(randomseed_t *r)
+{
+       unsigned long long n = Math_rand64(r);
+       return n * (0.25f / 0x80000000 / 0x80000000);
+}
+
+float Math_crandomf(randomseed_t *r)
+{
+       // do this with a signed number and double the result, so we make use of all parts of the cow
+       long long n = (long long)Math_rand64(r);
+       return n * (0.5f / 0x80000000 / 0x80000000);
+}
+
+float Math_randomrangef(randomseed_t *r, float minf, float maxf)
+{
+       return Math_randomf(r) * (maxf - minf) + minf;
+}
+
+int Math_randomrangei(randomseed_t *r, int mini, int maxi)
+{
+       unsigned long long n = Math_rand64(r);
+       return (int)(((n >> 33) * (maxi - mini) + mini) >> 31);
+}
index cb674e5..f32e409 100644 (file)
--- a/mathlib.h
+++ b/mathlib.h
@@ -181,9 +181,10 @@ int PointInfrontOfTriangle(const float *p, const float *a, const float *b, const
 }
 #endif
 
-#define lhcheeserand() (seed = (seed * 987211u) ^ (seed >> 13u) ^ 914867)
-#define lhcheeserandom(MIN,MAX) ((double)(lhcheeserand() + 0.5) / ((double)4096.0*1024.0*1024.0) * ((MAX)-(MIN)) + (MIN))
-#define VectorCheeseRandom(v) do{(v)[0] = lhcheeserandom(-1, 1);(v)[1] = lhcheeserandom(-1, 1);(v)[2] = lhcheeserandom(-1, 1);}while(DotProduct(v, v) > 1)
+#define lhcheeserand(seed) ((seed) = ((seed) * 987211u) ^ ((seed) >> 13u) ^ 914867)
+#define lhcheeserandom(seed,MIN,MAX) ((double)(lhcheeserand(seed) + 0.5) / ((double)4096.0*1024.0*1024.0) * ((MAX)-(MIN)) + (MIN))
+#define VectorCheeseRandom(seed,v) do{(v)[0] = lhcheeserandom(seed,-1, 1);(v)[1] = lhcheeserandom(seed,-1, 1);(v)[2] = lhcheeserandom(seed,-1, 1);}while(DotProduct(v, v) > 1)
+#define VectorLehmerRandom(seed,v) do{(v)[0] = Math_crandomf(seed);(v)[1] = Math_crandomf(seed);(v)[2] = Math_crandomf(seed);}while(DotProduct(v, v) > 1)
 
 /*
 // LordHavoc: quaternion math, untested, don't know if these are correct,
@@ -301,6 +302,22 @@ void BoxFromPoints(vec3_t mins, vec3_t maxs, int numpoints, vec_t *point3f);
 
 int LoopingFrameNumberFromDouble(double t, int loopframes);
 
+// implementation of 128bit Lehmer Random Number Generator with 2^126 period
+// https://en.wikipedia.org/Lehmer_random_number_generator
+typedef struct randomseed_s
+{
+       unsigned int s[4];
+}
+randomseed_t;
+
+void Math_RandomSeed_Reset(randomseed_t *r);
+void Math_RandomSeed_FromInt(randomseed_t *r, unsigned int n);
+unsigned long long Math_rand64(randomseed_t *r);
+float Math_randomf(randomseed_t *r);
+float Math_crandomf(randomseed_t *r);
+float Math_randomrangef(randomseed_t *r, float minf, float maxf);
+int Math_randomrangei(randomseed_t *r, int min, int max);
+
 void Mathlib_Init(void);
 
 #endif
index 68f19b8..2eafadf 100644 (file)
@@ -752,7 +752,7 @@ static void Mod_Alias_MorphMesh_CompileFrames(void)
        }
 }
 
-static void Mod_MDLMD2MD3_TraceLine(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask)
+static void Mod_MDLMD2MD3_TraceLine(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        int i;
        float segmentmins[3], segmentmaxs[3];
@@ -762,6 +762,7 @@ static void Mod_MDLMD2MD3_TraceLine(dp_model_t *model, const frameblend_t *frame
        memset(trace, 0, sizeof(*trace));
        trace->fraction = 1;
        trace->hitsupercontentsmask = hitsupercontentsmask;
+       trace->skipsupercontentsmask = skipsupercontentsmask;
        if (model->surfmesh.num_vertices > 1024)
                vertex3f = (float *)Mem_Alloc(tempmempool, model->surfmesh.num_vertices * sizeof(float[3]));
        segmentmins[0] = min(start[0], end[0]) - 1;
@@ -777,7 +778,7 @@ static void Mod_MDLMD2MD3_TraceLine(dp_model_t *model, const frameblend_t *frame
                Mem_Free(vertex3f);
 }
 
-static void Mod_MDLMD2MD3_TraceBox(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask)
+static void Mod_MDLMD2MD3_TraceBox(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        int i;
        vec3_t shiftstart, shiftend;
@@ -792,7 +793,7 @@ static void Mod_MDLMD2MD3_TraceBox(dp_model_t *model, const frameblend_t *frameb
        {
                VectorAdd(start, boxmins, shiftstart);
                VectorAdd(end, boxmins, shiftend);
-               Mod_MDLMD2MD3_TraceLine(model, frameblend, skeleton, trace, shiftstart, shiftend, hitsupercontentsmask);
+               Mod_MDLMD2MD3_TraceLine(model, frameblend, skeleton, trace, shiftstart, shiftend, hitsupercontentsmask, skipsupercontentsmask);
                VectorSubtract(trace->endpos, boxmins, trace->endpos);
                return;
        }
@@ -801,6 +802,7 @@ static void Mod_MDLMD2MD3_TraceBox(dp_model_t *model, const frameblend_t *frameb
        memset(trace, 0, sizeof(*trace));
        trace->fraction = 1;
        trace->hitsupercontentsmask = hitsupercontentsmask;
+       trace->skipsupercontentsmask = skipsupercontentsmask;
        if (model->surfmesh.num_vertices > 1024)
                vertex3f = (float *)Mem_Alloc(tempmempool, model->surfmesh.num_vertices * sizeof(float[3]));
        segmentmins[0] = min(start[0], end[0]) + boxmins[0] - 1;
index 21838fb..ad41ad3 100644 (file)
@@ -887,7 +887,7 @@ static int Mod_Q1BSP_RecursiveHullCheckPoint(RecursiveHullCheckTraceInfo_t *t, i
 }
 //#endif
 
-static void Mod_Q1BSP_TracePoint(struct model_s *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, int hitsupercontentsmask)
+static void Mod_Q1BSP_TracePoint(struct model_s *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        RecursiveHullCheckTraceInfo_t rhc;
 
@@ -902,22 +902,22 @@ static void Mod_Q1BSP_TracePoint(struct model_s *model, const frameblend_t *fram
        Mod_Q1BSP_RecursiveHullCheckPoint(&rhc, rhc.hull->firstclipnode);
 }
 
-static void Mod_Q1BSP_TraceLineAgainstSurfaces(struct model_s *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask);
+static void Mod_Q1BSP_TraceLineAgainstSurfaces(struct model_s *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask);
 
-static void Mod_Q1BSP_TraceLine(struct model_s *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask)
+static void Mod_Q1BSP_TraceLine(struct model_s *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        RecursiveHullCheckTraceInfo_t rhc;
 
        if (VectorCompare(start, end))
        {
-               Mod_Q1BSP_TracePoint(model, frameblend, skeleton, trace, start, hitsupercontentsmask);
+               Mod_Q1BSP_TracePoint(model, frameblend, skeleton, trace, start, hitsupercontentsmask, skipsupercontentsmask);
                return;
        }
 
        // sometimes we want to traceline against polygons so we can report the texture that was hit rather than merely a contents, but using this method breaks one of negke's maps so it must be a cvar check...
        if (sv_gameplayfix_q1bsptracelinereportstexture.integer)
        {
-               Mod_Q1BSP_TraceLineAgainstSurfaces(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask);
+               Mod_Q1BSP_TraceLineAgainstSurfaces(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask, skipsupercontentsmask);
                return;
        }
 
@@ -925,6 +925,7 @@ static void Mod_Q1BSP_TraceLine(struct model_s *model, const frameblend_t *frame
        memset(trace, 0, sizeof(trace_t));
        rhc.trace = trace;
        rhc.trace->hitsupercontentsmask = hitsupercontentsmask;
+       rhc.trace->skipsupercontentsmask = skipsupercontentsmask;
        rhc.trace->fraction = 1;
        rhc.trace->allsolid = true;
        rhc.hull = &model->brushq1.hulls[0]; // 0x0x0
@@ -942,6 +943,7 @@ static void Mod_Q1BSP_TraceLine(struct model_s *model, const frameblend_t *frame
                memset(&testtrace, 0, sizeof(trace_t));
                rhc.trace = &testtrace;
                rhc.trace->hitsupercontentsmask = hitsupercontentsmask;
+               rhc.trace->skipsupercontentsmask = skipsupercontentsmask;
                rhc.trace->fraction = 1;
                rhc.trace->allsolid = true;
                VectorCopy(test, rhc.start);
@@ -961,7 +963,7 @@ static void Mod_Q1BSP_TraceLine(struct model_s *model, const frameblend_t *frame
 #endif
 }
 
-static void Mod_Q1BSP_TraceBox(struct model_s *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask)
+static void Mod_Q1BSP_TraceBox(struct model_s *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        // this function currently only supports same size start and end
        double boxsize[3];
@@ -970,9 +972,9 @@ static void Mod_Q1BSP_TraceBox(struct model_s *model, const frameblend_t *frameb
        if (VectorCompare(boxmins, boxmaxs))
        {
                if (VectorCompare(start, end))
-                       Mod_Q1BSP_TracePoint(model, frameblend, skeleton, trace, start, hitsupercontentsmask);
+                       Mod_Q1BSP_TracePoint(model, frameblend, skeleton, trace, start, hitsupercontentsmask, skipsupercontentsmask);
                else
-                       Mod_Q1BSP_TraceLine(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask);
+                       Mod_Q1BSP_TraceLine(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask, skipsupercontentsmask);
                return;
        }
 
@@ -980,6 +982,7 @@ static void Mod_Q1BSP_TraceBox(struct model_s *model, const frameblend_t *frameb
        memset(trace, 0, sizeof(trace_t));
        rhc.trace = trace;
        rhc.trace->hitsupercontentsmask = hitsupercontentsmask;
+       rhc.trace->skipsupercontentsmask = skipsupercontentsmask;
        rhc.trace->fraction = 1;
        rhc.trace->allsolid = true;
        VectorSubtract(boxmaxs, boxmins, boxsize);
@@ -1022,6 +1025,7 @@ static void Mod_Q1BSP_TraceBox(struct model_s *model, const frameblend_t *frameb
                memset(&testtrace, 0, sizeof(trace_t));
                rhc.trace = &testtrace;
                rhc.trace->hitsupercontentsmask = hitsupercontentsmask;
+               rhc.trace->skipsupercontentsmask = skipsupercontentsmask;
                rhc.trace->fraction = 1;
                rhc.trace->allsolid = true;
                VectorCopy(test, rhc.start);
@@ -1055,7 +1059,7 @@ static int Mod_Q1BSP_PointSuperContents(struct model_s *model, int frame, const
        return Mod_Q1BSP_SuperContentsFromNativeContents(NULL, num);
 }
 
-void Collision_ClipTrace_Box(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, int boxsupercontents, int boxq3surfaceflags, const texture_t *boxtexture)
+void Collision_ClipTrace_Box(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int boxsupercontents, int boxq3surfaceflags, const texture_t *boxtexture)
 {
 #if 1
        colbrushf_t cbox;
@@ -1090,6 +1094,7 @@ void Collision_ClipTrace_Box(trace_t *trace, const vec3_t cmins, const vec3_t cm
        cbox_planes[5].q3surfaceflags = boxq3surfaceflags;cbox_planes[5].texture = boxtexture;
        memset(trace, 0, sizeof(trace_t));
        trace->hitsupercontentsmask = hitsupercontentsmask;
+       trace->skipsupercontentsmask = skipsupercontentsmask;
        trace->fraction = 1;
        Collision_TraceLineBrushFloat(trace, start, end, &cbox, &cbox);
 #else
@@ -1147,6 +1152,7 @@ void Collision_ClipTrace_Box(trace_t *trace, const vec3_t cmins, const vec3_t cm
        rhc.hull = &box_hull;
        rhc.trace = trace;
        rhc.trace->hitsupercontentsmask = hitsupercontentsmask;
+       rhc.trace->skipsupercontentsmask = skipsupercontentsmask;
        rhc.trace->fraction = 1;
        rhc.trace->allsolid = true;
        VectorCopy(start, rhc.start);
@@ -1159,14 +1165,16 @@ void Collision_ClipTrace_Box(trace_t *trace, const vec3_t cmins, const vec3_t cm
 #endif
 }
 
-void Collision_ClipTrace_Point(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, int hitsupercontentsmask, int boxsupercontents, int boxq3surfaceflags, const texture_t *boxtexture)
+void Collision_ClipTrace_Point(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask, int boxsupercontents, int boxq3surfaceflags, const texture_t *boxtexture)
 {
        memset(trace, 0, sizeof(trace_t));
        trace->fraction = 1;
+       trace->hitsupercontentsmask = hitsupercontentsmask;
+       trace->skipsupercontentsmask = skipsupercontentsmask;
        if (BoxesOverlap(start, start, cmins, cmaxs))
        {
                trace->startsupercontents |= boxsupercontents;
-               if (hitsupercontentsmask & boxsupercontents)
+               if ((hitsupercontentsmask & boxsupercontents) && !(skipsupercontentsmask & boxsupercontents))
                {
                        trace->startsolid = true;
                        trace->allsolid = true;
@@ -1177,7 +1185,7 @@ void Collision_ClipTrace_Point(trace_t *trace, const vec3_t cmins, const vec3_t
 static qboolean Mod_Q1BSP_TraceLineOfSight(struct model_s *model, const vec3_t start, const vec3_t end)
 {
        trace_t trace;
-       Mod_Q1BSP_TraceLine(model, NULL, NULL, &trace, start, end, SUPERCONTENTS_VISBLOCKERMASK);
+       Mod_Q1BSP_TraceLine(model, NULL, NULL, &trace, start, end, SUPERCONTENTS_VISBLOCKERMASK, 0);
        return trace.fraction == 1;
 }
 
@@ -1364,6 +1372,9 @@ static const texture_t *Mod_Q1BSP_TraceLineAgainstSurfacesFindTextureOnNode(Recu
                // skip faces with contents we don't care about
                if (!(t->trace->hitsupercontentsmask & surface->texture->supercontents))
                        continue;
+               // ignore surfaces matching the skipsupercontentsmask (this is rare)
+               if (t->trace->skipsupercontentsmask & surface->texture->supercontents)
+                       continue;
                // get the surface normal - since it is flat we know any vertex normal will suffice
                VectorCopy(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex, normal);
                // skip backfaces
@@ -1494,7 +1505,7 @@ static int Mod_Q1BSP_TraceLineAgainstSurfacesRecursiveBSPNode(RecursiveHullCheck
        }
 }
 
-static void Mod_Q1BSP_TraceLineAgainstSurfaces(struct model_s *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask)
+static void Mod_Q1BSP_TraceLineAgainstSurfaces(struct model_s *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        RecursiveHullCheckTraceInfo_t rhc;
 
@@ -1502,6 +1513,7 @@ static void Mod_Q1BSP_TraceLineAgainstSurfaces(struct model_s *model, const fram
        memset(trace, 0, sizeof(trace_t));
        rhc.trace = trace;
        rhc.trace->hitsupercontentsmask = hitsupercontentsmask;
+       rhc.trace->skipsupercontentsmask = skipsupercontentsmask;
        rhc.trace->fraction = 1;
        rhc.trace->allsolid = true;
        rhc.hull = &model->brushq1.hulls[0]; // 0x0x0
@@ -3787,7 +3799,7 @@ static int Mod_Q1BSP_CreateShadowMesh(dp_model_t *mod)
        return numshadowmeshtriangles;
 }
 
-void Mod_CollisionBIH_TraceLineAgainstSurfaces(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask);
+void Mod_CollisionBIH_TraceLineAgainstSurfaces(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask);
 
 void Mod_Q1BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
 {
@@ -6770,7 +6782,7 @@ static qboolean Mod_Q3BSP_TraceLineOfSight(struct model_s *model, const vec3_t s
        if (model->brush.submodel || mod_q3bsp_tracelineofsight_brushes.integer)
        {
                trace_t trace;
-               model->TraceLine(model, NULL, NULL, &trace, start, end, SUPERCONTENTS_VISBLOCKERMASK);
+               model->TraceLine(model, NULL, NULL, &trace, start, end, SUPERCONTENTS_VISBLOCKERMASK, SUPERCONTENTS_SKY);
                return trace.fraction == 1;
        }
        else
@@ -6782,7 +6794,7 @@ static qboolean Mod_Q3BSP_TraceLineOfSight(struct model_s *model, const vec3_t s
        }
 }
 
-void Mod_CollisionBIH_TracePoint(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, int hitsupercontentsmask)
+void Mod_CollisionBIH_TracePoint(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        const bih_t *bih;
        const bih_leaf_t *leaf;
@@ -6796,6 +6808,7 @@ void Mod_CollisionBIH_TracePoint(dp_model_t *model, const frameblend_t *frameble
        memset(trace, 0, sizeof(*trace));
        trace->fraction = 1;
        trace->hitsupercontentsmask = hitsupercontentsmask;
+       trace->skipsupercontentsmask = skipsupercontentsmask;
 
        bih = &model->collision_bih;
        if(!bih->nodes)
@@ -6846,7 +6859,7 @@ void Mod_CollisionBIH_TracePoint(dp_model_t *model, const frameblend_t *frameble
        }
 }
 
-static void Mod_CollisionBIH_TraceLineShared(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, const bih_t *bih)
+static void Mod_CollisionBIH_TraceLineShared(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, const bih_t *bih)
 {
        const bih_leaf_t *leaf;
        const bih_node_t *node;
@@ -6862,7 +6875,7 @@ static void Mod_CollisionBIH_TraceLineShared(dp_model_t *model, const frameblend
 
        if (VectorCompare(start, end))
        {
-               Mod_CollisionBIH_TracePoint(model, frameblend, skeleton, trace, start, hitsupercontentsmask);
+               Mod_CollisionBIH_TracePoint(model, frameblend, skeleton, trace, start, hitsupercontentsmask, skipsupercontentsmask);
                return;
        }
 
@@ -6871,6 +6884,7 @@ static void Mod_CollisionBIH_TraceLineShared(dp_model_t *model, const frameblend
        memset(trace, 0, sizeof(*trace));
        trace->fraction = 1;
        trace->hitsupercontentsmask = hitsupercontentsmask;
+       trace->skipsupercontentsmask = skipsupercontentsmask;
 
        // push first node
        nodestackline[nodestackpos][0] = start[0];
@@ -6969,17 +6983,17 @@ static void Mod_CollisionBIH_TraceLineShared(dp_model_t *model, const frameblend
        }
 }
 
-void Mod_CollisionBIH_TraceLine(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask)
+void Mod_CollisionBIH_TraceLine(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        if (VectorCompare(start, end))
        {
-               Mod_CollisionBIH_TracePoint(model, frameblend, skeleton, trace, start, hitsupercontentsmask);
+               Mod_CollisionBIH_TracePoint(model, frameblend, skeleton, trace, start, hitsupercontentsmask, skipsupercontentsmask);
                return;
        }
-       Mod_CollisionBIH_TraceLineShared(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask, &model->collision_bih);
+       Mod_CollisionBIH_TraceLineShared(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask, skipsupercontentsmask, &model->collision_bih);
 }
 
-void Mod_CollisionBIH_TraceBrush(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, colbrushf_t *thisbrush_start, colbrushf_t *thisbrush_end, int hitsupercontentsmask)
+void Mod_CollisionBIH_TraceBrush(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, colbrushf_t *thisbrush_start, colbrushf_t *thisbrush_end, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        const bih_t *bih;
        const bih_leaf_t *leaf;
@@ -6995,9 +7009,9 @@ void Mod_CollisionBIH_TraceBrush(dp_model_t *model, const frameblend_t *frameble
        if (mod_q3bsp_optimizedtraceline.integer && VectorCompare(thisbrush_start->mins, thisbrush_start->maxs) && VectorCompare(thisbrush_end->mins, thisbrush_end->maxs))
        {
                if (VectorCompare(thisbrush_start->mins, thisbrush_end->mins))
-                       Mod_CollisionBIH_TracePoint(model, frameblend, skeleton, trace, thisbrush_start->mins, hitsupercontentsmask);
+                       Mod_CollisionBIH_TracePoint(model, frameblend, skeleton, trace, thisbrush_start->mins, hitsupercontentsmask, skipsupercontentsmask);
                else
-                       Mod_CollisionBIH_TraceLine(model, frameblend, skeleton, trace, thisbrush_start->mins, thisbrush_end->mins, hitsupercontentsmask);
+                       Mod_CollisionBIH_TraceLine(model, frameblend, skeleton, trace, thisbrush_start->mins, thisbrush_end->mins, hitsupercontentsmask, skipsupercontentsmask);
                return;
        }
 
@@ -7010,6 +7024,7 @@ void Mod_CollisionBIH_TraceBrush(dp_model_t *model, const frameblend_t *frameble
        memset(trace, 0, sizeof(*trace));
        trace->fraction = 1;
        trace->hitsupercontentsmask = hitsupercontentsmask;
+       trace->skipsupercontentsmask = skipsupercontentsmask;
 
        // calculate tracebox-like parameters for efficient culling
        VectorMAM(0.5f, thisbrush_start->mins, 0.5f, thisbrush_start->maxs, start);
@@ -7122,7 +7137,7 @@ void Mod_CollisionBIH_TraceBrush(dp_model_t *model, const frameblend_t *frameble
        }
 }
 
-void Mod_CollisionBIH_TraceBox(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask)
+void Mod_CollisionBIH_TraceBox(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        colboxbrushf_t thisbrush_start, thisbrush_end;
        vec3_t boxstartmins, boxstartmaxs, boxendmins, boxendmaxs;
@@ -7134,25 +7149,25 @@ void Mod_CollisionBIH_TraceBox(dp_model_t *model, const frameblend_t *frameblend
        VectorAdd(end, boxmaxs, boxendmaxs);
        Collision_BrushForBox(&thisbrush_start, boxstartmins, boxstartmaxs, 0, 0, NULL);
        Collision_BrushForBox(&thisbrush_end, boxendmins, boxendmaxs, 0, 0, NULL);
-       Mod_CollisionBIH_TraceBrush(model, frameblend, skeleton, trace, &thisbrush_start.brush, &thisbrush_end.brush, hitsupercontentsmask);
+       Mod_CollisionBIH_TraceBrush(model, frameblend, skeleton, trace, &thisbrush_start.brush, &thisbrush_end.brush, hitsupercontentsmask, skipsupercontentsmask);
 }
 
 
 int Mod_CollisionBIH_PointSuperContents(struct model_s *model, int frame, const vec3_t point)
 {
        trace_t trace;
-       Mod_CollisionBIH_TracePoint(model, NULL, NULL, &trace, point, 0);
+       Mod_CollisionBIH_TracePoint(model, NULL, NULL, &trace, point, 0, 0);
        return trace.startsupercontents;
 }
 
 qboolean Mod_CollisionBIH_TraceLineOfSight(struct model_s *model, const vec3_t start, const vec3_t end)
 {
        trace_t trace;
-       Mod_CollisionBIH_TraceLine(model, NULL, NULL, &trace, start, end, SUPERCONTENTS_VISBLOCKERMASK);
+       Mod_CollisionBIH_TraceLine(model, NULL, NULL, &trace, start, end, SUPERCONTENTS_VISBLOCKERMASK, 0);
        return trace.fraction == 1;
 }
 
-void Mod_CollisionBIH_TracePoint_Mesh(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, int hitsupercontentsmask)
+void Mod_CollisionBIH_TracePoint_Mesh(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask)
 {
 #if 0
        // broken - needs to be modified to count front faces and backfaces to figure out if it is in solid
@@ -7163,12 +7178,14 @@ void Mod_CollisionBIH_TracePoint_Mesh(dp_model_t *model, const frameblend_t *fra
        memset(trace, 0, sizeof(*trace));
        trace->fraction = 1;
        trace->hitsupercontentsmask = hitsupercontentsmask;
+       trace->skipsupercontentsmask = skipsupercontentsmask;
 #if 0
-       Mod_CollisionBIH_TraceLine(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask);
+       Mod_CollisionBIH_TraceLine(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask, skipsupercontentsmask);
        hitsupercontents = trace->hitsupercontents;
        memset(trace, 0, sizeof(*trace));
        trace->fraction = 1;
        trace->hitsupercontentsmask = hitsupercontentsmask;
+       trace->skipsupercontentsmask = skipsupercontentsmask;
        trace->startsupercontents = hitsupercontents;
 #endif
 }
@@ -7182,8 +7199,9 @@ int Mod_CollisionBIH_PointSuperContents_Mesh(struct model_s *model, int frame, c
        VectorSet(end, start[0], start[1], model->normalmins[2]);
        memset(&trace, 0, sizeof(trace));
        trace.fraction = 1;
-       trace.hitsupercontentsmask = 0;
-       Mod_CollisionBIH_TraceLine(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask);
+       trace.hitsupercontentsmask = hitsupercontentsmask;
+       trace.skipsupercontentsmask = skipsupercontentsmask;
+       Mod_CollisionBIH_TraceLine(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask, skipsupercontentsmask);
        return trace.hitsupercontents;
 #else
        return 0;
@@ -7405,15 +7423,16 @@ static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, dp_model_t *mo
 
 static int markframe = 0;
 
-static void Mod_Q3BSP_TracePoint(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, int hitsupercontentsmask)
+static void Mod_Q3BSP_TracePoint(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        int i;
        q3mbrush_t *brush;
        memset(trace, 0, sizeof(*trace));
        trace->fraction = 1;
        trace->hitsupercontentsmask = hitsupercontentsmask;
+       trace->skipsupercontentsmask = skipsupercontentsmask;
        if (mod_collision_bih.integer)
-               Mod_CollisionBIH_TracePoint(model, frameblend, skeleton, trace, start, hitsupercontentsmask);
+               Mod_CollisionBIH_TracePoint(model, frameblend, skeleton, trace, start, hitsupercontentsmask, skipsupercontentsmask);
        else if (model->brush.submodel)
        {
                for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
@@ -7424,7 +7443,7 @@ static void Mod_Q3BSP_TracePoint(dp_model_t *model, const frameblend_t *frameble
                Mod_Q3BSP_TracePoint_RecursiveBSPNode(trace, model, model->brush.data_nodes, start, ++markframe);
 }
 
-static void Mod_Q3BSP_TraceLine(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask)
+static void Mod_Q3BSP_TraceLine(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        int i;
        float segmentmins[3], segmentmaxs[3];
@@ -7433,13 +7452,14 @@ static void Mod_Q3BSP_TraceLine(dp_model_t *model, const frameblend_t *frameblen
 
        if (VectorCompare(start, end))
        {
-               Mod_Q3BSP_TracePoint(model, frameblend, skeleton, trace, start, hitsupercontentsmask);
+               Mod_Q3BSP_TracePoint(model, frameblend, skeleton, trace, start, hitsupercontentsmask, skipsupercontentsmask);
                return;
        }
 
        memset(trace, 0, sizeof(*trace));
        trace->fraction = 1;
        trace->hitsupercontentsmask = hitsupercontentsmask;
+       trace->skipsupercontentsmask = skipsupercontentsmask;
        segmentmins[0] = min(start[0], end[0]) - 1;
        segmentmins[1] = min(start[1], end[1]) - 1;
        segmentmins[2] = min(start[2], end[2]) - 1;
@@ -7447,7 +7467,7 @@ static void Mod_Q3BSP_TraceLine(dp_model_t *model, const frameblend_t *frameblen
        segmentmaxs[1] = max(start[1], end[1]) + 1;
        segmentmaxs[2] = max(start[2], end[2]) + 1;
        if (mod_collision_bih.integer)
-               Mod_CollisionBIH_TraceLine(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask);
+               Mod_CollisionBIH_TraceLine(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask, skipsupercontentsmask);
        else if (model->brush.submodel)
        {
                for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
@@ -7462,7 +7482,7 @@ static void Mod_Q3BSP_TraceLine(dp_model_t *model, const frameblend_t *frameblen
                Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace, model, model->brush.data_nodes, start, end, 0, 1, start, end, ++markframe, segmentmins, segmentmaxs);
 }
 
-static void Mod_Q3BSP_TraceBrush(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, colbrushf_t *start, colbrushf_t *end, int hitsupercontentsmask)
+static void Mod_Q3BSP_TraceBrush(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, colbrushf_t *start, colbrushf_t *end, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        float segmentmins[3], segmentmaxs[3];
        int i;
@@ -7472,9 +7492,9 @@ static void Mod_Q3BSP_TraceBrush(dp_model_t *model, const frameblend_t *frameble
        if (mod_q3bsp_optimizedtraceline.integer && VectorCompare(start->mins, start->maxs) && VectorCompare(end->mins, end->maxs))
        {
                if (VectorCompare(start->mins, end->mins))
-                       Mod_Q3BSP_TracePoint(model, frameblend, skeleton, trace, start->mins, hitsupercontentsmask);
+                       Mod_Q3BSP_TracePoint(model, frameblend, skeleton, trace, start->mins, hitsupercontentsmask, skipsupercontentsmask);
                else
-                       Mod_Q3BSP_TraceLine(model, frameblend, skeleton, trace, start->mins, end->mins, hitsupercontentsmask);
+                       Mod_Q3BSP_TraceLine(model, frameblend, skeleton, trace, start->mins, end->mins, hitsupercontentsmask, skipsupercontentsmask);
                return;
        }
 
@@ -7482,6 +7502,7 @@ static void Mod_Q3BSP_TraceBrush(dp_model_t *model, const frameblend_t *frameble
        memset(trace, 0, sizeof(*trace));
        trace->fraction = 1;
        trace->hitsupercontentsmask = hitsupercontentsmask;
+       trace->skipsupercontentsmask = skipsupercontentsmask;
        segmentmins[0] = min(start->mins[0], end->mins[0]) - 1;
        segmentmins[1] = min(start->mins[1], end->mins[1]) - 1;
        segmentmins[2] = min(start->mins[2], end->mins[2]) - 1;
@@ -7489,7 +7510,7 @@ static void Mod_Q3BSP_TraceBrush(dp_model_t *model, const frameblend_t *frameble
        segmentmaxs[1] = max(start->maxs[1], end->maxs[1]) + 1;
        segmentmaxs[2] = max(start->maxs[2], end->maxs[2]) + 1;
        if (mod_collision_bih.integer)
-               Mod_CollisionBIH_TraceBrush(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask);
+               Mod_CollisionBIH_TraceBrush(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask, skipsupercontentsmask);
        else if (model->brush.submodel)
        {
                for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
@@ -7504,7 +7525,7 @@ static void Mod_Q3BSP_TraceBrush(dp_model_t *model, const frameblend_t *frameble
                Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, model, model->brush.data_nodes, start, end, ++markframe, segmentmins, segmentmaxs);
 }
 
-static void Mod_Q3BSP_TraceBox(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask)
+static void Mod_Q3BSP_TraceBox(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        colboxbrushf_t thisbrush_start, thisbrush_end;
        vec3_t boxstartmins, boxstartmaxs, boxendmins, boxendmaxs;
@@ -7516,7 +7537,7 @@ static void Mod_Q3BSP_TraceBox(dp_model_t *model, const frameblend_t *frameblend
        VectorAdd(end, boxmaxs, boxendmaxs);
        Collision_BrushForBox(&thisbrush_start, boxstartmins, boxstartmaxs, 0, 0, NULL);
        Collision_BrushForBox(&thisbrush_end, boxendmins, boxendmaxs, 0, 0, NULL);
-       Mod_Q3BSP_TraceBrush(model, frameblend, skeleton, trace, &thisbrush_start.brush, &thisbrush_end.brush, hitsupercontentsmask);
+       Mod_Q3BSP_TraceBrush(model, frameblend, skeleton, trace, &thisbrush_start.brush, &thisbrush_end.brush, hitsupercontentsmask, skipsupercontentsmask);
 }
 
 static int Mod_Q3BSP_PointSuperContents(struct model_s *model, int frame, const vec3_t point)
@@ -7555,9 +7576,9 @@ static int Mod_Q3BSP_PointSuperContents(struct model_s *model, int frame, const
        return supercontents;
 }
 
-void Mod_CollisionBIH_TraceLineAgainstSurfaces(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask)
+void Mod_CollisionBIH_TraceLineAgainstSurfaces(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask)
 {
-       Mod_CollisionBIH_TraceLineShared(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask, &model->render_bih);
+       Mod_CollisionBIH_TraceLineShared(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask, skipsupercontentsmask, &model->render_bih);
 }
 
 
index 2061c03..2be02ff 100644 (file)
@@ -3732,7 +3732,7 @@ static void Mod_GenerateLightmaps_LightPoint(dp_model_t *model, const vec3_t pos
                        continue;
                if (model && model->TraceLine)
                {
-                       model->TraceLine(model, NULL, NULL, &trace, pos, lightorigin, SUPERCONTENTS_VISBLOCKERMASK);
+                       model->TraceLine(model, NULL, NULL, &trace, pos, lightorigin, SUPERCONTENTS_VISBLOCKERMASK, SUPERCONTENTS_SKY);
                        if (trace.fraction < 1)
                                continue;
                }
@@ -3934,7 +3934,7 @@ static void Mod_GenerateLightmaps_SamplePoint(const float *pos, const float *nor
                                if (!normal)
                                {
                                        // for light grid we'd better check visibility of the offset point
-                                       cl.worldmodel->TraceLine(cl.worldmodel, NULL, NULL, &trace, pos, offsetpos, SUPERCONTENTS_VISBLOCKERMASK);
+                                       cl.worldmodel->TraceLine(cl.worldmodel, NULL, NULL, &trace, pos, offsetpos, SUPERCONTENTS_VISBLOCKERMASK, SUPERCONTENTS_SKY);
                                        if (trace.fraction < 1)
                                                VectorLerp(pos, trace.fraction, offsetpos, offsetpos);
                                }
index 834ac4d..93ea942 100644 (file)
@@ -1076,16 +1076,16 @@ typedef struct model_s
        // draw the lighting on a model (through stencil)
        void(*DrawLight)(struct entity_render_s *ent, int numsurfaces, const int *surfacelist, const unsigned char *trispvs);
        // trace a box against this model
-       void (*TraceBox)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask);
-       void (*TraceBrush)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, struct colbrushf_s *start, struct colbrushf_s *end, int hitsupercontentsmask);
+       void (*TraceBox)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask);
+       void (*TraceBrush)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, struct colbrushf_s *start, struct colbrushf_s *end, int hitsupercontentsmask, int skipsupercontentsmask);
        // trace a box against this model
-       void (*TraceLine)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask);
+       void (*TraceLine)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask);
        // trace a point against this model (like PointSuperContents)
-       void (*TracePoint)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, const vec3_t start, int hitsupercontentsmask);
+       void (*TracePoint)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask);
        // find the supercontents value at a point in this model
        int (*PointSuperContents)(struct model_s *model, int frame, const vec3_t point);
        // trace a line against geometry in this model and report correct texture (used by r_shadow_bouncegrid)
-       void (*TraceLineAgainstSurfaces)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask);
+       void (*TraceLineAgainstSurfaces)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask);
        // fields belonging to some types of model
        model_sprite_t  sprite;
        model_brush_t   brush;
@@ -1231,11 +1231,11 @@ void R_Q1BSP_DrawShadowVolume(struct entity_render_s *ent, const vec3_t relative
 void R_Q1BSP_DrawLight(struct entity_render_s *ent, int numsurfaces, const int *surfacelist, const unsigned char *trispvs);
 
 // Collision optimization using Bounding Interval Hierarchy
-void Mod_CollisionBIH_TracePoint(dp_model_t *model, const struct frameblend_s *frameblend, const skeleton_t *skeleton, struct trace_s *trace, const vec3_t start, int hitsupercontentsmask);
-void Mod_CollisionBIH_TraceLine(dp_model_t *model, const struct frameblend_s *frameblend, const skeleton_t *skeleton, struct trace_s *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask);
-void Mod_CollisionBIH_TraceBox(dp_model_t *model, const struct frameblend_s *frameblend, const skeleton_t *skeleton, struct trace_s *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask);
-void Mod_CollisionBIH_TraceBrush(dp_model_t *model, const struct frameblend_s *frameblend, const skeleton_t *skeleton, struct trace_s *trace, struct colbrushf_s *start, struct colbrushf_s *end, int hitsupercontentsmask);
-void Mod_CollisionBIH_TracePoint_Mesh(dp_model_t *model, const struct frameblend_s *frameblend, const skeleton_t *skeleton, struct trace_s *trace, const vec3_t start, int hitsupercontentsmask);
+void Mod_CollisionBIH_TracePoint(dp_model_t *model, const struct frameblend_s *frameblend, const skeleton_t *skeleton, struct trace_s *trace, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask);
+void Mod_CollisionBIH_TraceLine(dp_model_t *model, const struct frameblend_s *frameblend, const skeleton_t *skeleton, struct trace_s *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask);
+void Mod_CollisionBIH_TraceBox(dp_model_t *model, const struct frameblend_s *frameblend, const skeleton_t *skeleton, struct trace_s *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask);
+void Mod_CollisionBIH_TraceBrush(dp_model_t *model, const struct frameblend_s *frameblend, const skeleton_t *skeleton, struct trace_s *trace, struct colbrushf_s *start, struct colbrushf_s *end, int hitsupercontentsmask, int skipsupercontentsmask);
+void Mod_CollisionBIH_TracePoint_Mesh(dp_model_t *model, const struct frameblend_s *frameblend, const skeleton_t *skeleton, struct trace_s *trace, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask);
 qboolean Mod_CollisionBIH_TraceLineOfSight(struct model_s *model, const vec3_t start, const vec3_t end);
 int Mod_CollisionBIH_PointSuperContents(struct model_s *model, int frame, const vec3_t point);
 int Mod_CollisionBIH_PointSuperContents_Mesh(struct model_s *model, int frame, const vec3_t point);
index afd2fd8..63d2f2e 100644 (file)
@@ -189,7 +189,7 @@ void R_NewExplosion(const vec3_t org)
                                // clip start origin
                                if (e->clipping)
                                {
-                                       trace = CL_TraceLine(e->origin, e->vert[j], MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, collision_extendmovelength.value, true, false, NULL, false, false);
+                                       trace = CL_TraceLine(e->origin, e->vert[j], MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, 0, collision_extendmovelength.value, true, false, NULL, false, false);
                                        VectorCopy(trace.endpos, e->vert[i]);
                                }
                        }
@@ -245,7 +245,7 @@ static void R_MoveExplosion(explosion_t *e)
                        VectorMA(e->vert[i], frametime, e->vertvel[i], end);
                        if (e->clipping)
                        {
-                               trace = CL_TraceLine(e->vert[i], end, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, collision_extendmovelength.value, true, false, NULL, false, false);
+                               trace = CL_TraceLine(e->vert[i], end, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, 0, collision_extendmovelength.value, true, false, NULL, false, false);
                                if (trace.fraction < 1)
                                {
                                        // clip velocity against the wall
index f388ce4..d300d50 100644 (file)
@@ -337,6 +337,7 @@ cvar_t r_shadow_texture3d = {0, "r_shadow_texture3d", "1", "use 3D voxel texture
 cvar_t r_shadow_bouncegrid = {CVAR_SAVE, "r_shadow_bouncegrid", "0", "perform particle tracing for indirect lighting (Global Illumination / radiosity) using a 3D texture covering the scene, only active on levels with realtime lights active (r_shadow_realtime_world is usually required for these)"};
 cvar_t r_shadow_bouncegrid_blur = {CVAR_SAVE, "r_shadow_bouncegrid_blur", "1", "apply a 1-radius blur on bouncegrid to denoise it and deal with boundary issues with surfaces"};
 cvar_t r_shadow_bouncegrid_bounceanglediffuse = {CVAR_SAVE, "r_shadow_bouncegrid_bounceanglediffuse", "0", "use random bounce direction rather than true reflection, makes some corner areas dark"};
+cvar_t r_shadow_bouncegrid_dynamic_bounceminimumintensity = { CVAR_SAVE, "r_shadow_bouncegrid_dynamic_bounceminimumintensity", "0.01", "stop bouncing once intensity drops below this fraction of the original particle color" };
 cvar_t r_shadow_bouncegrid_dynamic_culllightpaths = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_culllightpaths", "1", "skip accumulating light in the bouncegrid texture where the light paths are out of view (dynamic mode only)"};
 cvar_t r_shadow_bouncegrid_dynamic_dlightparticlemultiplier = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_dlightparticlemultiplier", "1", "if set to a high value like 16 this can make dlights look great, but 0 is recommended for performance reasons"};
 cvar_t r_shadow_bouncegrid_dynamic_directionalshading = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_directionalshading", "0", "use diffuse shading rather than ambient, 3D texture becomes 8x as many pixels to hold the additional data"};
@@ -359,6 +360,7 @@ cvar_t r_shadow_bouncegrid_particleintensity = {CVAR_SAVE, "r_shadow_bouncegrid_
 cvar_t r_shadow_bouncegrid_sortlightpaths = {CVAR_SAVE, "r_shadow_bouncegrid_sortlightpaths", "1", "sort light paths before accumulating them into the bouncegrid texture, this reduces cpu cache misses"};
 cvar_t r_shadow_bouncegrid_lightpathsize = {CVAR_SAVE, "r_shadow_bouncegrid_lightpathsize", "1", "width of the light path for accumulation of light in the bouncegrid texture"};
 cvar_t r_shadow_bouncegrid_static = {CVAR_SAVE, "r_shadow_bouncegrid_static", "1", "use static radiosity solution (high quality) rather than dynamic (splotchy)"};
+cvar_t r_shadow_bouncegrid_static_bounceminimumintensity = { CVAR_SAVE, "r_shadow_bouncegrid_static_bounceminimumintensity", "0.01", "stop bouncing once intensity drops below this fraction of the original particle color" };
 cvar_t r_shadow_bouncegrid_static_directionalshading = {CVAR_SAVE, "r_shadow_bouncegrid_static_directionalshading", "1", "whether to use directionalshading when in static mode"};
 cvar_t r_shadow_bouncegrid_static_energyperphoton = {CVAR_SAVE, "r_shadow_bouncegrid_static_energyperphoton", "10000", "amount of light that one photon should represent in static mode"};
 cvar_t r_shadow_bouncegrid_static_lightradiusscale = {CVAR_SAVE, "r_shadow_bouncegrid_static_lightradiusscale", "10", "particles stop at this fraction of light radius (can be more than 1) when in static mode"};
@@ -551,7 +553,6 @@ static void r_shadow_start(void)
 {
        // allocate vertex processing arrays
        memset(&r_shadow_bouncegrid_state, 0, sizeof(r_shadow_bouncegrid_state));
-       r_shadow_bouncegrid_state.maxsplatpaths = 16384;
        r_shadow_attenuationgradienttexture = NULL;
        r_shadow_attenuation2dtexture = NULL;
        r_shadow_attenuation3dtexture = NULL;
@@ -653,6 +654,13 @@ static void r_shadow_shutdown(void)
        if (r_shadow_scenelightlist)
                Mem_Free(r_shadow_scenelightlist);
        r_shadow_scenelightlist = NULL;
+       r_shadow_bouncegrid_state.highpixels = NULL;
+       if (r_shadow_bouncegrid_state.blurpixels[0]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[0]); r_shadow_bouncegrid_state.blurpixels[0] = NULL;
+       if (r_shadow_bouncegrid_state.blurpixels[1]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[1]); r_shadow_bouncegrid_state.blurpixels[1] = NULL;
+       if (r_shadow_bouncegrid_state.u8pixels) Mem_Free(r_shadow_bouncegrid_state.u8pixels); r_shadow_bouncegrid_state.u8pixels = NULL;
+       if (r_shadow_bouncegrid_state.fp16pixels) Mem_Free(r_shadow_bouncegrid_state.fp16pixels); r_shadow_bouncegrid_state.fp16pixels = NULL;
+       if (r_shadow_bouncegrid_state.splatpaths) Mem_Free(r_shadow_bouncegrid_state.splatpaths); r_shadow_bouncegrid_state.splatpaths = NULL;
+       r_shadow_bouncegrid_state.maxsplatpaths = 0;
        memset(&r_shadow_bouncegrid_state, 0, sizeof(r_shadow_bouncegrid_state));
        r_shadow_attenuationgradienttexture = NULL;
        r_shadow_attenuation2dtexture = NULL;
@@ -721,6 +729,13 @@ static void r_shadow_shutdown(void)
 
 static void r_shadow_newmap(void)
 {
+       r_shadow_bouncegrid_state.highpixels = NULL;
+       if (r_shadow_bouncegrid_state.blurpixels[0]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[0]); r_shadow_bouncegrid_state.blurpixels[0] = NULL;
+       if (r_shadow_bouncegrid_state.blurpixels[1]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[1]); r_shadow_bouncegrid_state.blurpixels[1] = NULL;
+       if (r_shadow_bouncegrid_state.u8pixels) Mem_Free(r_shadow_bouncegrid_state.u8pixels); r_shadow_bouncegrid_state.u8pixels = NULL;
+       if (r_shadow_bouncegrid_state.fp16pixels) Mem_Free(r_shadow_bouncegrid_state.fp16pixels); r_shadow_bouncegrid_state.fp16pixels = NULL;
+       if (r_shadow_bouncegrid_state.splatpaths) Mem_Free(r_shadow_bouncegrid_state.splatpaths); r_shadow_bouncegrid_state.splatpaths = NULL;
+       r_shadow_bouncegrid_state.maxsplatpaths = 0;
        if (r_shadow_bouncegrid_state.texture)    R_FreeTexture(r_shadow_bouncegrid_state.texture);r_shadow_bouncegrid_state.texture = NULL;
        if (r_shadow_lightcorona)                 R_SkinFrame_MarkUsed(r_shadow_lightcorona);
        if (r_editlights_sprcursor)               R_SkinFrame_MarkUsed(r_editlights_sprcursor);
@@ -789,6 +804,7 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_bouncegrid);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_blur);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_bounceanglediffuse);
+       Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_bounceminimumintensity);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_culllightpaths);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_directionalshading);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_dlightparticlemultiplier);
@@ -811,12 +827,13 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_bouncegrid_particleintensity);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_sortlightpaths);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_static);
-       Cvar_RegisterVariable(&r_shadow_bouncegrid_static_spacing);
+       Cvar_RegisterVariable(&r_shadow_bouncegrid_static_bounceminimumintensity);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_static_directionalshading);
+       Cvar_RegisterVariable(&r_shadow_bouncegrid_static_energyperphoton);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_static_lightradiusscale);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_static_maxbounce);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_static_maxphotons);
-       Cvar_RegisterVariable(&r_shadow_bouncegrid_static_energyperphoton);
+       Cvar_RegisterVariable(&r_shadow_bouncegrid_static_spacing);
        Cvar_RegisterVariable(&r_coronas);
        Cvar_RegisterVariable(&r_coronas_occlusionsizescale);
        Cvar_RegisterVariable(&r_coronas_occlusionquery);
@@ -2464,12 +2481,10 @@ static void R_Shadow_BounceGrid_AddSplatPath(vec3_t originalstart, vec3_t origin
        {
                // double the limit, this will persist from frame to frame so we don't
                // make the same mistake each time
-               r_shadow_bouncegrid_splatpath_t *newpaths;
                r_shadow_bouncegrid_state.maxsplatpaths *= 2;
-               newpaths = (r_shadow_bouncegrid_splatpath_t *)R_FrameData_Alloc(sizeof(r_shadow_bouncegrid_splatpath_t) * r_shadow_bouncegrid_state.maxsplatpaths);
-               if (r_shadow_bouncegrid_state.splatpaths)
-                       memcpy(newpaths, r_shadow_bouncegrid_state.splatpaths, r_shadow_bouncegrid_state.numsplatpaths * sizeof(r_shadow_bouncegrid_splatpath_t));
-               r_shadow_bouncegrid_state.splatpaths = newpaths;
+               if (r_shadow_bouncegrid_state.maxsplatpaths < 16384)
+                       r_shadow_bouncegrid_state.maxsplatpaths = 16384;
+               r_shadow_bouncegrid_state.splatpaths = (r_shadow_bouncegrid_splatpath_t *)Mem_Realloc(r_main_mempool, r_shadow_bouncegrid_state.splatpaths, sizeof(r_shadow_bouncegrid_splatpath_t) * r_shadow_bouncegrid_state.maxsplatpaths);
        }
 
        // divide a series of splats along the length using the maximum axis
@@ -2536,6 +2551,7 @@ static void R_Shadow_BounceGrid_GenerateSettings(r_shadow_bouncegrid_settings_t
 {
        qboolean s = r_shadow_bouncegrid_static.integer != 0;
        float spacing = s ? r_shadow_bouncegrid_static_spacing.value : r_shadow_bouncegrid_dynamic_spacing.value;
+       float bounceminimumintensity = s ? r_shadow_bouncegrid_static_bounceminimumintensity.value : r_shadow_bouncegrid_dynamic_bounceminimumintensity.value;
 
        // prevent any garbage in alignment padded areas as we'll be using memcmp
        memset(settings, 0, sizeof(*settings)); 
@@ -2553,13 +2569,14 @@ static void R_Shadow_BounceGrid_GenerateSettings(r_shadow_bouncegrid_settings_t
        settings->lightradiusscale              = (s ? r_shadow_bouncegrid_static_lightradiusscale.value : r_shadow_bouncegrid_dynamic_lightradiusscale.value);
        settings->maxbounce                     = (s ? r_shadow_bouncegrid_static_maxbounce.integer : r_shadow_bouncegrid_dynamic_maxbounce.integer);
        settings->particlebounceintensity       = r_shadow_bouncegrid_particlebounceintensity.value;
-       settings->particleintensity             = r_shadow_bouncegrid_particleintensity.value * 16384.0f * (settings->directionalshading ? 4.0f : 1.0f) / (spacing * spacing);
+       settings->particleintensity             = r_shadow_bouncegrid_particleintensity.value * (settings->directionalshading ? 4.0f : 1.0f) * 16384 / (spacing * spacing) / 262144.0f;
        settings->maxphotons                    = s ? r_shadow_bouncegrid_static_maxphotons.integer : r_shadow_bouncegrid_dynamic_maxphotons.integer;
-       settings->energyperphoton            = s ? r_shadow_bouncegrid_static_energyperphoton.integer : r_shadow_bouncegrid_dynamic_energyperphoton.integer;
+       settings->energyperphoton               = s ? r_shadow_bouncegrid_static_energyperphoton.value : r_shadow_bouncegrid_dynamic_energyperphoton.value;
        settings->spacing[0]                    = spacing;
        settings->spacing[1]                    = spacing;
        settings->spacing[2]                    = spacing;
        settings->stablerandom                  = s ? 1 : r_shadow_bouncegrid_dynamic_stablerandom.integer;
+       settings->bounceminimumintensity2       = bounceminimumintensity * bounceminimumintensity;
 
        // bound the values for sanity
        settings->maxphotons = bound(1, settings->maxphotons, 25000000);
@@ -2568,6 +2585,13 @@ static void R_Shadow_BounceGrid_GenerateSettings(r_shadow_bouncegrid_settings_t
        settings->spacing[0] = bound(1, settings->spacing[0], 512);
        settings->spacing[1] = bound(1, settings->spacing[1], 512);
        settings->spacing[2] = bound(1, settings->spacing[2], 512);
+
+       // check if the ram requirements for blur would be excessive and disable it (increase lightpathsize to compensate)
+       if (spacing < 32 && settings->blur)
+       {
+               settings->blur = false;
+               settings->lightpathsize += 2;
+       }
 }
 
 static void R_Shadow_BounceGrid_UpdateSpacing(void)
@@ -2680,11 +2704,14 @@ static void R_Shadow_BounceGrid_UpdateSpacing(void)
        numpixels = r_shadow_bouncegrid_state.pixelsperband*r_shadow_bouncegrid_state.pixelbands;
        if (r_shadow_bouncegrid_state.numpixels != numpixels)
        {
-               if (r_shadow_bouncegrid_state.texture)
-               {
-                       R_FreeTexture(r_shadow_bouncegrid_state.texture);
-                       r_shadow_bouncegrid_state.texture = NULL;
-               }
+               if (r_shadow_bouncegrid_state.texture) R_FreeTexture(r_shadow_bouncegrid_state.texture);r_shadow_bouncegrid_state.texture = NULL;
+               r_shadow_bouncegrid_state.highpixels = NULL;
+               if (r_shadow_bouncegrid_state.blurpixels[0]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[0]); r_shadow_bouncegrid_state.blurpixels[0] = NULL;
+               if (r_shadow_bouncegrid_state.blurpixels[1]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[1]); r_shadow_bouncegrid_state.blurpixels[1] = NULL;
+               if (r_shadow_bouncegrid_state.u8pixels) Mem_Free(r_shadow_bouncegrid_state.u8pixels); r_shadow_bouncegrid_state.u8pixels = NULL;
+               if (r_shadow_bouncegrid_state.fp16pixels) Mem_Free(r_shadow_bouncegrid_state.fp16pixels); r_shadow_bouncegrid_state.fp16pixels = NULL;
+               if (r_shadow_bouncegrid_state.splatpaths) Mem_Free(r_shadow_bouncegrid_state.splatpaths); r_shadow_bouncegrid_state.splatpaths = NULL;
+               r_shadow_bouncegrid_state.maxsplatpaths = 0;
                r_shadow_bouncegrid_state.numpixels = numpixels;
        }
 
@@ -2700,17 +2727,16 @@ static void R_Shadow_BounceGrid_UpdateSpacing(void)
        Matrix4x4_FromArrayFloatD3D(&r_shadow_bouncegrid_state.matrix, m);
 }
 
-#define MAXBOUNCEGRIDPARTICLESPERLIGHT 1048576
-
 // enumerate world rtlights and sum the overall amount of light in the world,
 // from that we can calculate a scaling factor to fairly distribute photons
 // to all the lights
 //
 // this modifies rtlight->photoncolor and rtlight->photons
-static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *settings, unsigned int range, unsigned int range1, unsigned int range2, int flag, float *photonscaling)
+static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *settings, unsigned int range, unsigned int range1, unsigned int range2, int flag)
 {
        float normalphotonscaling;
-       float maxphotonscaling;
+       float photonscaling;
+       float photonintensity;
        float photoncount = 0.0f;
        float lightintensity;
        float radius;
@@ -2721,16 +2747,20 @@ static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *se
        unsigned int lightindex;
        dlight_t *light;
        rtlight_t *rtlight;
-       for (lightindex = 0;lightindex < range2;lightindex++)
+       normalphotonscaling = 1.0f / max(0.0001f, settings->energyperphoton);
+       for (lightindex = 0; lightindex < range2; lightindex++)
        {
                if (lightindex < range)
                {
-                       light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+                       light = (dlight_t *)Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
                        if (!light)
                                continue;
                        rtlight = &light->rtlight;
-                       VectorClear(rtlight->photoncolor);
-                       rtlight->photons = 0;
+                       VectorClear(rtlight->bouncegrid_photoncolor);
+                       rtlight->bouncegrid_photons = 0;
+                       rtlight->bouncegrid_hits = 0;
+                       rtlight->bouncegrid_traces = 0;
+                       rtlight->bouncegrid_effectiveradius = 0;
                        if (!(light->flags & flag))
                                continue;
                        if (settings->staticmode)
@@ -2739,12 +2769,17 @@ static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *se
                                if (rtlight->style > 0 && r_shadow_bouncegrid.integer != 2)
                                        continue;
                        }
+                       else if (r_shadow_debuglight.integer >= 0 && (int)lightindex != r_shadow_debuglight.integer)
+                               continue;
                }
                else
                {
                        rtlight = r_refdef.scene.lights[lightindex - range];
-                       VectorClear(rtlight->photoncolor);
-                       rtlight->photons = 0;
+                       VectorClear(rtlight->bouncegrid_photoncolor);
+                       rtlight->bouncegrid_photons = 0;
+                       rtlight->bouncegrid_hits = 0;
+                       rtlight->bouncegrid_traces = 0;
+                       rtlight->bouncegrid_effectiveradius = 0;
                }
                // draw only visible lights (major speedup)
                radius = rtlight->radius * settings->lightradiusscale;
@@ -2760,8 +2795,8 @@ static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *se
                        if (R_CullBox(cullmins, cullmaxs))
                                continue;
                        if (r_refdef.scene.worldmodel
-                        && r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs
-                        && !r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.scene.worldmodel, r_refdef.viewcache.world_leafvisible, cullmins, cullmaxs))
+                               && r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs
+                               && !r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.scene.worldmodel, r_refdef.viewcache.world_leafvisible, cullmins, cullmaxs))
                                continue;
                        if (w * VectorLength2(rtlight->color) == 0.0f)
                                continue;
@@ -2771,9 +2806,9 @@ static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *se
                if (rtlight->radius == 0.0f || VectorLength2(rtlight->color) == 0.0f)
                        continue;
                w *= ((rtlight->style >= 0 && rtlight->style < MAX_LIGHTSTYLES) ? r_refdef.scene.rtlightstylevalue[rtlight->style] : 1);
-               VectorScale(rtlight->color, w, rtlight->photoncolor);
+               VectorScale(rtlight->color, w, rtlight->bouncegrid_photoncolor);
                // skip lights that will emit no photons
-               if (!VectorLength2(rtlight->photoncolor))
+               if (VectorLength2(rtlight->bouncegrid_photoncolor) <= 0.0f)
                        continue;
                // shoot particles from this light
                // use a calculation for the number of particles that will not
@@ -2784,20 +2819,41 @@ static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *se
                lightintensity = VectorLength(rtlight->color) * (rtlight->ambientscale + rtlight->diffusescale + rtlight->specularscale);
                if (lightindex >= range)
                        lightintensity *= settings->dlightparticlemultiplier;
-               rtlight->photons = bound(0.0f, lightintensity * s * s, MAXBOUNCEGRIDPARTICLESPERLIGHT);
-               photoncount += rtlight->photons;
+               rtlight->bouncegrid_photons = lightintensity * s * s * normalphotonscaling;
+               photoncount += rtlight->bouncegrid_photons;
+               VectorScale(rtlight->bouncegrid_photoncolor, settings->particleintensity * settings->energyperphoton, rtlight->bouncegrid_photoncolor);
                // if the lightstyle happens to be off right now, we can skip actually
                // firing the photons, but we did have to count them in the total.
                //if (VectorLength2(rtlight->photoncolor) == 0.0f)
-               //      rtlight->photons = 0;
+               //      rtlight->bouncegrid_photons = 0;
        }
        // the user provided an energyperphoton value which we try to use
        // if that results in too many photons to shoot this frame, then we cap it
        // which causes photons to appear/disappear from frame to frame, so we don't
        // like doing that in the typical case
-       normalphotonscaling = 1.0f / max(0.0001f, settings->energyperphoton);
-       maxphotonscaling = (float)settings->maxphotons / max(1, photoncount);
-       *photonscaling = min(normalphotonscaling, maxphotonscaling);
+       photonscaling = 1.0f;
+       photonintensity = 1.0f;
+       if (photoncount > settings->maxphotons)
+       {
+               photonscaling = settings->maxphotons / photoncount;
+               photonintensity = 1.0f / photonscaling;
+       }
+
+       // modify the lights to reflect our computed scaling
+       for (lightindex = 0; lightindex < range2; lightindex++)
+       {
+               if (lightindex < range)
+               {
+                       light = (dlight_t *)Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+                       if (!light)
+                               continue;
+                       rtlight = &light->rtlight;
+               }
+               else
+                       rtlight = r_refdef.scene.lights[lightindex - range];
+               rtlight->bouncegrid_photons *= photonscaling;
+               VectorScale(rtlight->bouncegrid_photoncolor, photonintensity, rtlight->bouncegrid_photoncolor);
+       }
 }
 
 static int R_Shadow_BounceGrid_SplatPathCompare(const void *pa, const void *pb)
@@ -2815,7 +2871,12 @@ static int R_Shadow_BounceGrid_SplatPathCompare(const void *pa, const void *pb)
 static void R_Shadow_BounceGrid_ClearPixels(void)
 {
        // clear the highpixels array we'll be accumulating into
-       r_shadow_bouncegrid_state.highpixels = (float *)R_FrameData_Alloc(r_shadow_bouncegrid_state.numpixels * sizeof(float[4]));
+       if (r_shadow_bouncegrid_state.blurpixels[0] == NULL)
+               r_shadow_bouncegrid_state.blurpixels[0] = (float *)Mem_Alloc(r_main_mempool, r_shadow_bouncegrid_state.numpixels * sizeof(float[4]));
+       if (r_shadow_bouncegrid_state.settings.blur && r_shadow_bouncegrid_state.blurpixels[1] == NULL)
+               r_shadow_bouncegrid_state.blurpixels[1] = (float *)Mem_Alloc(r_main_mempool, r_shadow_bouncegrid_state.numpixels * sizeof(float[4]));
+       r_shadow_bouncegrid_state.highpixels_index = 0;
+       r_shadow_bouncegrid_state.highpixels = r_shadow_bouncegrid_state.blurpixels[r_shadow_bouncegrid_state.highpixels_index];
        memset(r_shadow_bouncegrid_state.highpixels, 0, r_shadow_bouncegrid_state.numpixels * sizeof(float[4]));
 }
 
@@ -2998,22 +3059,29 @@ static void R_Shadow_BounceGrid_BlurPixelsInDirection(const float *inpixels, flo
 
 static void R_Shadow_BounceGrid_BlurPixels(void)
 {
-       float *highpixels = r_shadow_bouncegrid_state.highpixels;
-       float *temppixels1 = (float *)R_FrameData_Alloc(r_shadow_bouncegrid_state.numpixels * sizeof(float[4]));
-       float *temppixels2 = (float *)R_FrameData_Alloc(r_shadow_bouncegrid_state.numpixels * sizeof(float[4]));
+       float *pixels[4];
        unsigned int resolution[3];
 
-       if (!r_shadow_bouncegrid_blur.integer)
+       if (!r_shadow_bouncegrid_state.settings.blur)
                return;
        
        VectorCopy(r_shadow_bouncegrid_state.resolution, resolution);
 
+       pixels[0] = r_shadow_bouncegrid_state.blurpixels[r_shadow_bouncegrid_state.highpixels_index];
+       pixels[1] = r_shadow_bouncegrid_state.blurpixels[r_shadow_bouncegrid_state.highpixels_index ^ 1];
+       pixels[2] = r_shadow_bouncegrid_state.blurpixels[r_shadow_bouncegrid_state.highpixels_index];
+       pixels[3] = r_shadow_bouncegrid_state.blurpixels[r_shadow_bouncegrid_state.highpixels_index ^ 1];
+
        // blur on X
-       R_Shadow_BounceGrid_BlurPixelsInDirection(highpixels, temppixels1, 4);
+       R_Shadow_BounceGrid_BlurPixelsInDirection(pixels[0], pixels[1], 4);
        // blur on Y
-       R_Shadow_BounceGrid_BlurPixelsInDirection(temppixels1, temppixels2, resolution[0] * 4);
+       R_Shadow_BounceGrid_BlurPixelsInDirection(pixels[1], pixels[2], resolution[0] * 4);
        // blur on Z
-       R_Shadow_BounceGrid_BlurPixelsInDirection(temppixels2, highpixels, resolution[0] * resolution[1] * 4);
+       R_Shadow_BounceGrid_BlurPixelsInDirection(pixels[2], pixels[3], resolution[0] * resolution[1] * 4);
+
+       // toggle the state, highpixels now points to pixels[3] result
+       r_shadow_bouncegrid_state.highpixels_index ^= 1;
+       r_shadow_bouncegrid_state.highpixels = r_shadow_bouncegrid_state.blurpixels[r_shadow_bouncegrid_state.highpixels_index];
 }
 
 static void R_Shadow_BounceGrid_ConvertPixelsAndUpload(void)
@@ -3072,7 +3140,9 @@ static void R_Shadow_BounceGrid_ConvertPixelsAndUpload(void)
        switch (floatcolors)
        {
        case 0:
-               pixelsbgra8 = (unsigned char *)R_FrameData_Alloc(r_shadow_bouncegrid_state.numpixels * sizeof(unsigned char[4]));
+               if (r_shadow_bouncegrid_state.u8pixels == NULL)
+                       r_shadow_bouncegrid_state.u8pixels = (unsigned char *)Mem_Alloc(r_main_mempool, r_shadow_bouncegrid_state.numpixels * sizeof(unsigned char[4]));
+               pixelsbgra8 = r_shadow_bouncegrid_state.u8pixels;
                for (pixelband = 0;pixelband < pixelbands;pixelband++)
                {
                        if (pixelband == 1)
@@ -3124,7 +3194,9 @@ static void R_Shadow_BounceGrid_ConvertPixelsAndUpload(void)
                        r_shadow_bouncegrid_state.texture = R_LoadTexture3D(r_shadow_texturepool, "bouncegrid", resolution[0], resolution[1], resolution[2]*pixelbands, pixelsbgra8, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCELINEAR, 0, NULL);
                break;
        case 1:
-               pixelsrgba16f = (unsigned short *)R_FrameData_Alloc(r_shadow_bouncegrid_state.numpixels * sizeof(unsigned short[4]));
+               if (r_shadow_bouncegrid_state.fp16pixels == NULL)
+                       r_shadow_bouncegrid_state.fp16pixels = (unsigned short *)Mem_Alloc(r_main_mempool, r_shadow_bouncegrid_state.numpixels * sizeof(unsigned short[4]));
+               pixelsrgba16f = r_shadow_bouncegrid_state.fp16pixels;
                memset(pixelsrgba16f, 0, r_shadow_bouncegrid_state.numpixels * sizeof(unsigned short[4]));
                for (z = 1;z < resolution[2]-1;z++)
                {
@@ -3186,19 +3258,23 @@ static void R_Shadow_BounceGrid_ConvertPixelsAndUpload(void)
        r_shadow_bouncegrid_state.lastupdatetime = realtime;
 }
 
-static void R_Shadow_BounceGrid_TracePhotons(r_shadow_bouncegrid_settings_t settings, unsigned int range, unsigned int range1, unsigned int range2, float photonscaling, int flag)
+static void R_Shadow_BounceGrid_TracePhotons(r_shadow_bouncegrid_settings_t settings, unsigned int range, unsigned int range1, unsigned int range2, int flag)
 {
+       vec3_t bouncerandom[10];
        dlight_t *light;
        int bouncecount;
        int hitsupercontentsmask;
+       int skipsupercontentsmask;
        int maxbounce;
        int shootparticles;
        int shotparticles;
+       float bounceminimumintensity2;
        trace_t cliptrace;
        //trace_t cliptrace2;
        //trace_t cliptrace3;
        unsigned int lightindex;
        unsigned int seed = (unsigned int)(realtime * 1000.0f);
+       randomseed_t randomseed;
        vec3_t shotcolor;
        vec3_t baseshotcolor;
        vec3_t surfcolor;
@@ -3209,15 +3285,16 @@ static void R_Shadow_BounceGrid_TracePhotons(r_shadow_bouncegrid_settings_t sett
        vec_t s;
        rtlight_t *rtlight;
 
-       // we'll need somewhere to store these
+       Math_RandomSeed_FromInt(&randomseed, seed);
+
        r_shadow_bouncegrid_state.numsplatpaths = 0;
-       r_shadow_bouncegrid_state.splatpaths = (r_shadow_bouncegrid_splatpath_t *)R_FrameData_Alloc(sizeof(r_shadow_bouncegrid_splatpath_t) * r_shadow_bouncegrid_state.maxsplatpaths);
 
        // figure out what we want to interact with
        if (settings.hitmodels)
                hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY;// | SUPERCONTENTS_LIQUIDSMASK;
        else
                hitsupercontentsmask = SUPERCONTENTS_SOLID;// | SUPERCONTENTS_LIQUIDSMASK;
+       skipsupercontentsmask = SUPERCONTENTS_SKY; // skipsurfaces with this contents, even if they also have SUPERCONTENTS_SOLID (basically this is for e1m5.bsp sky trick)
        maxbounce = settings.maxbounce;
 
        for (lightindex = 0;lightindex < range2;lightindex++)
@@ -3234,40 +3311,89 @@ static void R_Shadow_BounceGrid_TracePhotons(r_shadow_bouncegrid_settings_t sett
                // note that this code used to keep track of residual photons and
                // distribute them evenly to achieve exactly a desired photon count,
                // but that caused unwanted flickering in dynamic mode
-               shootparticles = (int)floor(rtlight->photons * photonscaling);
+               shootparticles = (int)floor(rtlight->bouncegrid_photons);
                // skip if we won't be shooting any photons
                if (!shootparticles)
                        continue;
                radius = rtlight->radius * settings.lightradiusscale;
-               s = settings.particleintensity / shootparticles;
-               VectorScale(rtlight->photoncolor, s, baseshotcolor);
+               //s = settings.particleintensity / shootparticles;
+               //VectorScale(rtlight->bouncegrid_photoncolor, s, baseshotcolor);
+               VectorCopy(rtlight->bouncegrid_photoncolor, baseshotcolor);
+               if (VectorLength2(baseshotcolor) <= 0.0f)
+                       continue;
                r_refdef.stats[r_stat_bouncegrid_lights]++;
                r_refdef.stats[r_stat_bouncegrid_particles] += shootparticles;
+               // we stop caring about bounces once the brightness goes below this fraction of the original intensity
+               bounceminimumintensity2 = VectorLength(baseshotcolor) * settings.bounceminimumintensity2;
+               switch (settings.stablerandom)
+               {
+               default:
+                       break;
+               case 1:
+                       Math_RandomSeed_FromInt(&randomseed, lightindex * 11937);
+                       // prime the random number generator a bit
+                       Math_crandomf(&randomseed);
+                       break;
+               case 2:
+                       seed = lightindex * 11937;
+                       // prime the random number generator a bit
+                       lhcheeserand(seed);
+                       break;
+               }
                for (shotparticles = 0;shotparticles < shootparticles;shotparticles++)
                {
-                       if (settings.stablerandom > 0)
-                               seed = lightindex * 11937 + shotparticles;
                        VectorCopy(baseshotcolor, shotcolor);
                        VectorCopy(rtlight->shadoworigin, clipstart);
-                       if (settings.stablerandom < 0)
+                       switch (settings.stablerandom)
+                       {
+                       default:
+                       case 0:
                                VectorRandom(clipend);
-                       else
-                               VectorCheeseRandom(clipend);
+                               if (settings.bounceanglediffuse)
+                               {
+                                       // we want random to be stable, so we still have to do all the random we would have done
+                                       for (bouncecount = 0; bouncecount < maxbounce; bouncecount++)
+                                               VectorRandom(bouncerandom[bouncecount]);
+                               }
+                               break;
+                       case -1:
+                       case 1:
+                               VectorLehmerRandom(&randomseed, clipend);
+                               if (settings.bounceanglediffuse)
+                               {
+                                       // we want random to be stable, so we still have to do all the random we would have done
+                                       for (bouncecount = 0; bouncecount < maxbounce; bouncecount++)
+                                               VectorLehmerRandom(&randomseed, bouncerandom[bouncecount]);
+                               }
+                               break;
+                       case -2:
+                       case 2:
+                               VectorCheeseRandom(seed, clipend);
+                               if (settings.bounceanglediffuse)
+                               {
+                                       // we want random to be stable, so we still have to do all the random we would have done
+                                       for (bouncecount = 0; bouncecount < maxbounce; bouncecount++)
+                                               VectorCheeseRandom(seed, bouncerandom[bouncecount]);
+                               }
+                               break;
+                       }
                        VectorMA(clipstart, radius, clipend, clipend);
                        for (bouncecount = 0;;bouncecount++)
                        {
                                r_refdef.stats[r_stat_bouncegrid_traces]++;
+                               rtlight->bouncegrid_traces++;
                                //r_refdef.scene.worldmodel->TraceLineAgainstSurfaces(r_refdef.scene.worldmodel, NULL, NULL, &cliptrace, clipstart, clipend, hitsupercontentsmask);
                                //r_refdef.scene.worldmodel->TraceLine(r_refdef.scene.worldmodel, NULL, NULL, &cliptrace2, clipstart, clipend, hitsupercontentsmask);
-                               if (settings.staticmode)
+                               if (settings.staticmode || settings.stablerandom <= 0)
                                {
                                        // static mode fires a LOT of rays but none of them are identical, so they are not cached
-                                       cliptrace = CL_TraceLine(clipstart, clipend, settings.staticmode ? MOVE_WORLDONLY : (settings.hitmodels ? MOVE_HITMODEL : MOVE_NOMONSTERS), NULL, hitsupercontentsmask, collision_extendmovelength.value, true, false, NULL, true, true);
+                                       // non-stable random in dynamic mode also never reuses a direction, so there's no reason to cache it
+                                       cliptrace = CL_TraceLine(clipstart, clipend, settings.staticmode ? MOVE_WORLDONLY : (settings.hitmodels ? MOVE_HITMODEL : MOVE_NOMONSTERS), NULL, hitsupercontentsmask, skipsupercontentsmask, collision_extendmovelength.value, true, false, NULL, true, true);
                                }
                                else
                                {
                                        // dynamic mode fires many rays and most will match the cache from the previous frame
-                                       cliptrace = CL_Cache_TraceLineSurfaces(clipstart, clipend, settings.staticmode ? MOVE_WORLDONLY : (settings.hitmodels ? MOVE_HITMODEL : MOVE_NOMONSTERS), hitsupercontentsmask);
+                                       cliptrace = CL_Cache_TraceLineSurfaces(clipstart, clipend, settings.hitmodels ? MOVE_HITMODEL : MOVE_NOMONSTERS, hitsupercontentsmask, skipsupercontentsmask);
                                }
                                if (bouncecount > 0 || settings.includedirectlighting)
                                {
@@ -3275,9 +3401,13 @@ static void R_Shadow_BounceGrid_TracePhotons(r_shadow_bouncegrid_settings_t sett
                                        VectorCopy(cliptrace.endpos, hitpos);
                                        R_Shadow_BounceGrid_AddSplatPath(clipstart, hitpos, shotcolor);
                                }
+                               s = VectorDistance(rtlight->shadoworigin, cliptrace.endpos);
+                               if (rtlight->bouncegrid_effectiveradius < s)
+                                       rtlight->bouncegrid_effectiveradius = s;
                                if (cliptrace.fraction >= 1.0f)
                                        break;
                                r_refdef.stats[r_stat_bouncegrid_hits]++;
+                               rtlight->bouncegrid_hits++;
                                if (bouncecount >= maxbounce)
                                        break;
                                // scale down shot color by bounce intensity and texture color (or 50% if no texture reported)
@@ -3291,18 +3421,14 @@ static void R_Shadow_BounceGrid_TracePhotons(r_shadow_bouncegrid_settings_t sett
                                surfcolor[1] = min(surfcolor[1], 1.0f);
                                surfcolor[2] = min(surfcolor[2], 1.0f);
                                VectorMultiply(shotcolor, surfcolor, shotcolor);
-                               if (VectorLength2(baseshotcolor) == 0.0f)
+                               if (VectorLength2(shotcolor) <= bounceminimumintensity2)
                                        break;
                                r_refdef.stats[r_stat_bouncegrid_bounces]++;
                                if (settings.bounceanglediffuse)
                                {
                                        // random direction, primarily along plane normal
                                        s = VectorDistance(cliptrace.endpos, clipend);
-                                       if (settings.stablerandom < 0)
-                                               VectorRandom(clipend);
-                                       else
-                                               VectorCheeseRandom(clipend);
-                                       VectorMA(cliptrace.plane.normal, 0.95f, clipend, clipend);
+                                       VectorMA(cliptrace.plane.normal, 0.95f, bouncerandom[bouncecount], clipend);
                                        VectorNormalize(clipend);
                                        VectorScale(clipend, s, clipend);
                                }
@@ -3329,7 +3455,6 @@ void R_Shadow_UpdateBounceGridTexture(void)
        unsigned int range; // number of world lights
        unsigned int range1; // number of dynamic lights (or zero if disabled)
        unsigned int range2; // range+range1
-       float photonscaling;
 
        enable = R_Shadow_BounceGrid_CheckEnable(flag);
        
@@ -3349,6 +3474,13 @@ void R_Shadow_UpdateBounceGridTexture(void)
                        R_FreeTexture(r_shadow_bouncegrid_state.texture);
                        r_shadow_bouncegrid_state.texture = NULL;
                }
+               r_shadow_bouncegrid_state.highpixels = NULL;
+               if (r_shadow_bouncegrid_state.blurpixels[0]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[0]); r_shadow_bouncegrid_state.blurpixels[0] = NULL;
+               if (r_shadow_bouncegrid_state.blurpixels[1]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[1]); r_shadow_bouncegrid_state.blurpixels[1] = NULL;
+               if (r_shadow_bouncegrid_state.u8pixels) Mem_Free(r_shadow_bouncegrid_state.u8pixels); r_shadow_bouncegrid_state.u8pixels = NULL;
+               if (r_shadow_bouncegrid_state.fp16pixels) Mem_Free(r_shadow_bouncegrid_state.fp16pixels); r_shadow_bouncegrid_state.fp16pixels = NULL;
+               if (r_shadow_bouncegrid_state.splatpaths) Mem_Free(r_shadow_bouncegrid_state.splatpaths); r_shadow_bouncegrid_state.splatpaths = NULL;
+               r_shadow_bouncegrid_state.maxsplatpaths = 0;
                r_shadow_bouncegrid_state.numpixels = 0;
                r_shadow_bouncegrid_state.directional = false;
 
@@ -3374,10 +3506,10 @@ void R_Shadow_UpdateBounceGridTexture(void)
        range2 = range + range1;
 
        // calculate weighting factors for distributing photons among the lights
-       R_Shadow_BounceGrid_AssignPhotons(&settings, range, range1, range2, flag, &photonscaling);
+       R_Shadow_BounceGrid_AssignPhotons(&settings, range, range1, range2, flag);
 
        // trace the photons from lights and accumulate illumination
-       R_Shadow_BounceGrid_TracePhotons(settings, range, range1, range2, photonscaling, flag);
+       R_Shadow_BounceGrid_TracePhotons(settings, range, range1, range2, flag);
 
        // clear the texture
        R_Shadow_BounceGrid_ClearPixels();
@@ -3390,6 +3522,18 @@ void R_Shadow_UpdateBounceGridTexture(void)
 
        // convert the pixels to lower precision and upload the texture
        R_Shadow_BounceGrid_ConvertPixelsAndUpload();
+
+       // after we compute the static lighting we don't need to keep the highpixels array around
+       if (settings.staticmode)
+       {
+               r_shadow_bouncegrid_state.highpixels = NULL;
+               if (r_shadow_bouncegrid_state.blurpixels[0]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[0]); r_shadow_bouncegrid_state.blurpixels[0] = NULL;
+               if (r_shadow_bouncegrid_state.blurpixels[1]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[1]); r_shadow_bouncegrid_state.blurpixels[1] = NULL;
+               if (r_shadow_bouncegrid_state.u8pixels) Mem_Free(r_shadow_bouncegrid_state.u8pixels); r_shadow_bouncegrid_state.u8pixels = NULL;
+               if (r_shadow_bouncegrid_state.fp16pixels) Mem_Free(r_shadow_bouncegrid_state.fp16pixels); r_shadow_bouncegrid_state.fp16pixels = NULL;
+               if (r_shadow_bouncegrid_state.splatpaths) Mem_Free(r_shadow_bouncegrid_state.splatpaths); r_shadow_bouncegrid_state.splatpaths = NULL;
+               r_shadow_bouncegrid_state.maxsplatpaths = 0;
+       }
 }
 
 void R_Shadow_RenderMode_VisibleShadowVolumes(void)
@@ -5782,7 +5926,7 @@ static void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale)
        else
        {
                // FIXME: these traces should scan all render entities instead of cl.world
-               if (CL_TraceLine(r_refdef.view.origin, rtlight->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, collision_extendmovelength.value, true, false, NULL, false, true).fraction < 1)
+               if (CL_TraceLine(r_refdef.view.origin, rtlight->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false, true).fraction < 1)
                        return;
        }
        VectorScale(rtlight->currentcolor, cscale, color);
@@ -6115,7 +6259,7 @@ static void R_Shadow_SelectLightInView(void)
                if (rating >= 0.95)
                {
                        rating /= (1 + 0.0625f * sqrt(DotProduct(temp, temp)));
-                       if (bestrating < rating && CL_TraceLine(light->origin, r_refdef.view.origin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, collision_extendmovelength.value, true, false, NULL, false, true).fraction == 1.0f)
+                       if (bestrating < rating && CL_TraceLine(light->origin, r_refdef.view.origin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false, true).fraction == 1.0f)
                        {
                                bestrating = rating;
                                best = light;
@@ -6565,7 +6709,7 @@ static void R_Shadow_SetCursorLocationForView(void)
        vec3_t dest, endpos;
        trace_t trace;
        VectorMA(r_refdef.view.origin, r_editlights_cursordistance.value, r_refdef.view.forward, dest);
-       trace = CL_TraceLine(r_refdef.view.origin, dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, collision_extendmovelength.value, true, false, NULL, false, true);
+       trace = CL_TraceLine(r_refdef.view.origin, dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false, true);
        if (trace.fraction < 1)
        {
                dist = trace.fraction * r_editlights_cursordistance.value;
@@ -7045,7 +7189,7 @@ void R_Shadow_EditLights_DrawSelectedLightProperties(void)
        // draw properties on screen
        if (!r_editlights_drawproperties.integer)
                return;
-       x = vid_conwidth.value - 240;
+       x = vid_conwidth.value - 320;
        y = 5;
        DrawQ_Pic(x-5, y-5, NULL, 250, 155, 0, 0, 0, 0.75, 0);
        lightnumber = -1;
@@ -7080,6 +7224,17 @@ void R_Shadow_EditLights_DrawSelectedLightProperties(void)
        dpsnprintf(temp, sizeof(temp), "Specular     : %.2f\n", r_shadow_selectedlight->specularscale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT);y += 8;
        dpsnprintf(temp, sizeof(temp), "NormalMode   : %s\n", (r_shadow_selectedlight->flags & LIGHTFLAG_NORMALMODE) ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT);y += 8;
        dpsnprintf(temp, sizeof(temp), "RealTimeMode : %s\n", (r_shadow_selectedlight->flags & LIGHTFLAG_REALTIMEMODE) ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT);y += 8;
+       y += 8;
+       dpsnprintf(temp, sizeof(temp), "Render stats\n"); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "Current color: %.3f %.3f %.3f\n", r_shadow_selectedlight->rtlight.currentcolor[0], r_shadow_selectedlight->rtlight.currentcolor[1], r_shadow_selectedlight->rtlight.currentcolor[2]); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "Shadow size  : %ix%ix6\n", r_shadow_selectedlight->rtlight.shadowmapatlassidesize, r_shadow_selectedlight->rtlight.shadowmapatlassidesize); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "World surfs  : %i\n", r_shadow_selectedlight->rtlight.cached_numsurfaces); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "Shadow ents  : %i + %i noself\n", r_shadow_selectedlight->rtlight.cached_numshadowentities, r_shadow_selectedlight->rtlight.cached_numshadowentities_noselfshadow); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "Lit ents     : %i + %i noself\n", r_shadow_selectedlight->rtlight.cached_numlightentities, r_shadow_selectedlight->rtlight.cached_numlightentities_noselfshadow); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "BG photons   : %.3f\n", r_shadow_selectedlight->rtlight.bouncegrid_photons); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "BG radius    : %.0f\n", r_shadow_selectedlight->rtlight.bouncegrid_effectiveradius); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "BG color     : %.3f %.3f %.3f\n", r_shadow_selectedlight->rtlight.bouncegrid_photoncolor[0], r_shadow_selectedlight->rtlight.bouncegrid_photoncolor[1], r_shadow_selectedlight->rtlight.bouncegrid_photoncolor[2]); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "BG stats     : %i traces %i hits\n", r_shadow_selectedlight->rtlight.bouncegrid_traces, r_shadow_selectedlight->rtlight.bouncegrid_hits); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
 }
 
 static void R_Shadow_EditLights_ToggleShadow_f(void)
@@ -7353,7 +7508,7 @@ void R_LightPoint(float *color, const vec3_t p, const int flags)
                        if (f <= 0)
                                continue;
                        // todo: add to both ambient and diffuse
-                       if (!light->shadow || CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, collision_extendmovelength.value, true, false, NULL, false, true).fraction == 1)
+                       if (!light->shadow || CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false, true).fraction == 1)
                                VectorMA(color, f, light->currentcolor, color);
                }
        }
@@ -7374,7 +7529,7 @@ void R_LightPoint(float *color, const vec3_t p, const int flags)
                        if (f <= 0)
                                continue;
                        // todo: add to both ambient and diffuse
-                       if (!light->shadow || CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, collision_extendmovelength.value, true, false, NULL, false, true).fraction == 1)
+                       if (!light->shadow || CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false, true).fraction == 1)
                                VectorMA(color, f, light->color, color);
                }
        }
@@ -7458,7 +7613,7 @@ void R_CompleteLightPoint(vec3_t ambient, vec3_t diffuse, vec3_t lightdir, const
                        intensity = min(1.0f, (1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist)) * r_shadow_lightintensityscale.value;
                        if (intensity <= 0.0f)
                                continue;
-                       if (light->shadow && CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, collision_extendmovelength.value, true, false, NULL, false, true).fraction < 1)
+                       if (light->shadow && CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false, true).fraction < 1)
                                continue;
                        // scale down intensity to add to both ambient and diffuse
                        //intensity *= 0.5f;
@@ -7491,7 +7646,7 @@ void R_CompleteLightPoint(vec3_t ambient, vec3_t diffuse, vec3_t lightdir, const
                        intensity = (1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist) * r_shadow_lightintensityscale.value;
                        if (intensity <= 0.0f)
                                continue;
-                       if (light->shadow && CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, collision_extendmovelength.value, true, false, NULL, false, true).fraction < 1)
+                       if (light->shadow && CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false, true).fraction < 1)
                                continue;
                        // scale down intensity to add to both ambient and diffuse
                        //intensity *= 0.5f;
index 30403f4..10f8e1e 100644 (file)
@@ -57,6 +57,7 @@ typedef struct r_shadow_bouncegrid_settings_s
        float energyperphoton;
        float spacing[3];
        int stablerandom;
+       float bounceminimumintensity2;
 }
 r_shadow_bouncegrid_settings_t;
 
@@ -86,7 +87,11 @@ typedef struct r_shadow_bouncegrid_state_s
        // per-frame data that is very temporary
        int numsplatpaths;
        struct r_shadow_bouncegrid_splatpath_s *splatpaths;
-       float *highpixels;
+       int highpixels_index; // which one is active - this toggles when doing blur
+       float *highpixels; // equals blurpixels[highpixels_index]
+       float *blurpixels[2];
+       unsigned char *u8pixels; // temporary processing buffer when outputting to rgba8 format
+       unsigned short *fp16pixels; // temporary processing buffer when outputting to rgba16f format
 }
 r_shadow_bouncegrid_state_t;
 
diff --git a/sbar.c b/sbar.c
index 9cc3b87..9d8ee63 100644 (file)
--- a/sbar.c
+++ b/sbar.c
@@ -1205,7 +1205,7 @@ void Sbar_ShowFPS(void)
                trace.hittexture = NULL; // to make sure
                // TODO change this trace to be stopped by anything "visible" (i.e. with a drawsurface), but not stuff like weapclip
                // probably needs adding a new SUPERCONTENTS type
-               trace = CL_TraceLine(org, dest, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID, collision_extendmovelength.value, true, false, NULL, true, true);
+               trace = CL_TraceLine(org, dest, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID, 0, collision_extendmovelength.value, true, false, NULL, true, true);
                if(trace.hittexture)
                        strlcpy(texstring, trace.hittexture->name, sizeof(texstring));
                else
index 2d22bdf..e0721ca 100644 (file)
--- a/server.h
+++ b/server.h
@@ -577,9 +577,9 @@ qboolean SV_NudgeOutOfSolid(prvm_edict_t *ent);
 /// calculates hitsupercontentsmask for a generic qc entity
 int SV_GenericHitSuperContentsMask(const prvm_edict_t *edict);
 /// traces a box move against worldmodel and all entities in the specified area
-trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, float extend);
-trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, float extend);
-trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask);
+trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, float extend);
+trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, float extend);
+trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask);
 int SV_EntitiesInBox(const vec3_t mins, const vec3_t maxs, int maxedicts, prvm_edict_t **resultedicts);
 
 qboolean SV_CanSeeBox(int numsamples, vec_t enlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs);
index 6d42e29..54f767d 100644 (file)
--- a/sv_move.c
+++ b/sv_move.c
@@ -71,7 +71,7 @@ realcheck:
        start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
        start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
        stop[2] = start[2] - 2*sv_stepheight.value;
-       trace = SV_TraceLine(start, stop, MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), collision_extendmovelength.value);
+       trace = SV_TraceLine(start, stop, MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value);
 
        if (trace.fraction == 1.0)
                return false;
@@ -84,7 +84,7 @@ realcheck:
                        start[0] = stop[0] = x ? maxs[0] : mins[0];
                        start[1] = stop[1] = y ? maxs[1] : mins[1];
 
-                       trace = SV_TraceLine(start, stop, MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), collision_extendmovelength.value);
+                       trace = SV_TraceLine(start, stop, MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value);
 
                        if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
                                bottom = trace.endpos[2];
@@ -143,7 +143,7 @@ qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean
                                }
                        }
                        VectorCopy(PRVM_serveredictvector(ent, origin), entorigin);
-                       trace = SV_TraceBox(entorigin, entmins, entmaxs, neworg, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), collision_extendmovelength.value);
+                       trace = SV_TraceBox(entorigin, entmins, entmaxs, neworg, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value);
 
                        if (trace.fraction == 1)
                        {
@@ -172,12 +172,12 @@ qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean
        VectorCopy (neworg, end);
        end[2] -= sv_stepheight.value*2;
 
-       trace = SV_TraceBox(neworg, entmins, entmaxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), collision_extendmovelength.value);
+       trace = SV_TraceBox(neworg, entmins, entmaxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value);
 
        if (trace.startsolid)
        {
                neworg[2] -= sv_stepheight.value;
-               trace = SV_TraceBox(neworg, entmins, entmaxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), collision_extendmovelength.value);
+               trace = SV_TraceBox(neworg, entmins, entmaxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value);
                if (trace.startsolid)
                        return false;
        }
index 4ee8aa3..ba15499 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -101,7 +101,7 @@ int SV_GenericHitSuperContentsMask(const prvm_edict_t *passedict)
 SV_TracePoint
 ==================
 */
-trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask)
+trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        prvm_prog_t *prog = SVVM_prog;
        int i, bodysupercontents;
@@ -127,7 +127,7 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
        int numtouchedicts;
        static prvm_edict_t *touchedicts[MAX_EDICTS];
 
-       //return SV_TraceBox(start, vec3_origin, vec3_origin, end, type, passedict, hitsupercontentsmask);
+       //return SV_TraceBox(start, vec3_origin, vec3_origin, end, type, passedict, hitsupercontentsmask, skipsupercontentsmask);
 
        VectorCopy(start, clipstart);
        VectorClear(clipmins2);
@@ -137,7 +137,7 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
 #endif
 
        // clip to world
-       Collision_ClipPointToWorld(&cliptrace, sv.worldmodel, clipstart, hitsupercontentsmask);
+       Collision_ClipPointToWorld(&cliptrace, sv.worldmodel, clipstart, hitsupercontentsmask, skipsupercontentsmask);
        cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
        if (cliptrace.startsolid || cliptrace.fraction < 1)
                cliptrace.ent = prog->edicts;
@@ -231,9 +231,9 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
                VectorCopy(PRVM_serveredictvector(touch, mins), touchmins);
                VectorCopy(PRVM_serveredictvector(touch, maxs), touchmaxs);
                if (type == MOVE_MISSILE && (int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER)
-                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipstart, hitsupercontentsmask, 0.0f);
+                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipstart, hitsupercontentsmask, skipsupercontentsmask, 0.0f);
                else
-                       Collision_ClipPointToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, hitsupercontentsmask);
+                       Collision_ClipPointToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, hitsupercontentsmask, skipsupercontentsmask);
 
                Collision_CombineTraces(&cliptrace, &trace, (void *)touch, PRVM_serveredictfloat(touch, solid) == SOLID_BSP);
        }
@@ -247,7 +247,7 @@ finished:
 SV_TraceLine
 ==================
 */
-trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, float extend)
+trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, float extend)
 {
        prvm_prog_t *prog = SVVM_prog;
        int i, bodysupercontents;
@@ -273,7 +273,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
        int numtouchedicts;
        static prvm_edict_t *touchedicts[MAX_EDICTS];
        if (VectorCompare(start, end))
-               return SV_TracePoint(start, type, passedict, hitsupercontentsmask);
+               return SV_TracePoint(start, type, passedict, hitsupercontentsmask, skipsupercontentsmask);
 
        //return SV_TraceBox(start, vec3_origin, vec3_origin, end, type, passedict, hitsupercontentsmask);
 
@@ -286,7 +286,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
 #endif
 
        // clip to world
-       Collision_ClipLineToWorld(&cliptrace, sv.worldmodel, clipstart, clipend, hitsupercontentsmask, extend, false);
+       Collision_ClipLineToWorld(&cliptrace, sv.worldmodel, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask, extend, false);
        cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
        if (cliptrace.startsolid || cliptrace.fraction < 1)
                cliptrace.ent = prog->edicts;
@@ -380,9 +380,9 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
                VectorCopy(PRVM_serveredictvector(touch, mins), touchmins);
                VectorCopy(PRVM_serveredictvector(touch, maxs), touchmaxs);
                if (type == MOVE_MISSILE && (int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER)
-                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask, extend);
+                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask, skipsupercontentsmask, extend);
                else
-                       Collision_ClipLineToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask, extend, false);
+                       Collision_ClipLineToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask, extend, false);
 
                Collision_CombineTraces(&cliptrace, &trace, (void *)touch, PRVM_serveredictfloat(touch, solid) == SOLID_BSP);
        }
@@ -397,9 +397,9 @@ SV_Move
 ==================
 */
 #if COLLISIONPARANOID >= 1
-trace_t SV_TraceBox_(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, float extend)
+trace_t SV_TraceBox_(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, float extend)
 #else
-trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, float extend)
+trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, float extend)
 #endif
 {
        prvm_prog_t *prog = SVVM_prog;
@@ -435,9 +435,9 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
                VectorAdd(start, mins, shiftstart);
                VectorAdd(end, mins, shiftend);
                if (VectorCompare(start, end))
-                       trace = SV_TracePoint(shiftstart, type, passedict, hitsupercontentsmask);
+                       trace = SV_TracePoint(shiftstart, type, passedict, hitsupercontentsmask, skipsupercontentsmask);
                else
-                       trace = SV_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask, extend);
+                       trace = SV_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask, skipsupercontentsmask, extend);
                VectorSubtract(trace.endpos, mins, trace.endpos);
                return trace;
        }
@@ -453,7 +453,7 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
 #endif
 
        // clip to world
-       Collision_ClipToWorld(&cliptrace, sv.worldmodel, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask, extend);
+       Collision_ClipToWorld(&cliptrace, sv.worldmodel, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask, skipsupercontentsmask, extend);
        cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
        if (cliptrace.startsolid || cliptrace.fraction < 1)
                cliptrace.ent = prog->edicts;
@@ -558,9 +558,9 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
                VectorCopy(PRVM_serveredictvector(touch, mins), touchmins);
                VectorCopy(PRVM_serveredictvector(touch, maxs), touchmaxs);
                if (type == MOVE_MISSILE && (int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER)
-                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask, extend);
+                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask, skipsupercontentsmask, extend);
                else
-                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask, extend);
+                       Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask, skipsupercontentsmask, extend);
 
                Collision_CombineTraces(&cliptrace, &trace, (void *)touch, PRVM_serveredictfloat(touch, solid) == SOLID_BSP);
        }
@@ -570,17 +570,17 @@ finished:
 }
 
 #if COLLISIONPARANOID >= 1
-trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask)
+trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask)
 {
        prvm_prog_t *prog = SVVM_prog;
        int endstuck;
        trace_t trace;
        vec3_t temp;
-       trace = SV_TraceBox_(start, mins, maxs, end, type, passedict, hitsupercontentsmask);
+       trace = SV_TraceBox_(start, mins, maxs, end, type, passedict, hitsupercontentsmask, skipsupercontentsmask);
        if (passedict)
        {
                VectorCopy(trace.endpos, temp);
-               endstuck = SV_TraceBox_(temp, mins, maxs, temp, type, passedict, hitsupercontentsmask).startsolid;
+               endstuck = SV_TraceBox_(temp, mins, maxs, temp, type, passedict, hitsupercontentsmask, skipsupercontentsmask).startsolid;
 #if COLLISIONPARANOID < 3
                if (trace.startsolid || endstuck)
 #endif
@@ -914,7 +914,7 @@ static int SV_TestEntityPosition (prvm_edict_t *ent, vec3_t offset)
        VectorCopy(PRVM_serveredictvector(ent, origin), entorigin);
        VectorCopy(PRVM_serveredictvector(ent, mins), entmins);
        VectorCopy(PRVM_serveredictvector(ent, maxs), entmaxs);
-       trace = SV_TraceBox(org, entmins, entmaxs, entorigin, ((PRVM_serveredictfloat(ent, movetype) == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), ent, contents, collision_extendmovelength.value);
+       trace = SV_TraceBox(org, entmins, entmaxs, entorigin, ((PRVM_serveredictfloat(ent, movetype) == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), ent, contents, 0, collision_extendmovelength.value);
        if (trace.startsupercontents & contents)
                return true;
        else
@@ -953,7 +953,7 @@ static int SV_TestEntityPosition (prvm_edict_t *ent, vec3_t offset)
 #else
                // verify if the endpos is REALLY outside solid
                VectorCopy(trace.endpos, org);
-               trace = SV_TraceBox(org, entmins, entmaxs, org, MOVE_NOMONSTERS, ent, contents, collision_extendmovelength.value);
+               trace = SV_TraceBox(org, entmins, entmaxs, org, MOVE_NOMONSTERS, ent, contents, 0, collision_extendmovelength.value);
                if(trace.startsolid)
                        Con_Printf("SV_TestEntityPosition: trace.endpos detected to be in solid. NOT using it.\n");
                else
@@ -1176,7 +1176,7 @@ If stepnormal is not NULL, the plane normal of any vertical wall hit will be sto
 static float SV_Gravity (prvm_edict_t *ent);
 static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, qboolean dolink);
 #define MAX_CLIP_PLANES 5
-static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, float *stepnormal, int hitsupercontentsmask, float stepheight)
+static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, float *stepnormal, int hitsupercontentsmask, int skipsupercontentsmask, float stepheight)
 {
        prvm_prog_t *prog = SVVM_prog;
        int blocked, bumpcount;
@@ -1393,7 +1393,7 @@ static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, flo
        {
                // LordHavoc: fix the 'fall to your death in a wedge corner' glitch
                // flag ONGROUND if there's ground under it
-               trace = SV_TraceBox(PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), end, MOVE_NORMAL, ent, hitsupercontentsmask);
+               trace = SV_TraceBox(PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), end, MOVE_NORMAL, ent, hitsupercontentsmask, skipsupercontentsmask);
        }
        */
 
@@ -1476,7 +1476,7 @@ static qboolean SV_NudgeOutOfSolid_PivotIsKnownGood(prvm_edict_t *ent, vec3_t pi
                                testorigin[coord] += stuckmins[coord] - goodmins[coord];
                        }
 
-                       stucktrace = SV_TraceBox(stuckorigin, goodmins, goodmaxs, testorigin, MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), collision_extendmovelength.value);
+                       stucktrace = SV_TraceBox(stuckorigin, goodmins, goodmaxs, testorigin, MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value);
                        if (stucktrace.bmodelstartsolid)
                        {
                                // BAD BAD, can't fix that
@@ -1546,7 +1546,7 @@ qboolean SV_NudgeOutOfSolid(prvm_edict_t *ent)
                VectorCopy(PRVM_serveredictvector(ent, origin), stuckorigin);
                for (bump = 0;bump < 10;bump++)
                {
-                       stucktrace = SV_TraceBox(stuckorigin, stuckmins, stuckmaxs, stuckorigin, pass ? MOVE_WORLDONLY : MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), collision_extendmovelength.value);
+                       stucktrace = SV_TraceBox(stuckorigin, stuckmins, stuckmaxs, stuckorigin, pass ? MOVE_WORLDONLY : MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value);
                        if (!stucktrace.bmodelstartsolid || stucktrace.startdepth >= 0)
                        {
                                // found a good location, use it
@@ -1602,7 +1602,7 @@ static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, q
        else
                type = MOVE_NORMAL;
 
-       *trace = SV_TraceBox(start, mins, maxs, end, type, ent, SV_GenericHitSuperContentsMask(ent), collision_extendmovelength.value);
+       *trace = SV_TraceBox(start, mins, maxs, end, type, ent, SV_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value);
        // fail the move if stuck in world
        if (trace->worldstartsolid)
                return true;
@@ -1615,7 +1615,7 @@ static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, q
 
 #if 0
        if(!trace->startsolid)
-       if(SV_TraceBox(PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), PRVM_serveredictvector(ent, origin), type, ent, SV_GenericHitSuperContentsMask(ent)).startsolid)
+       if(SV_TraceBox(PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), PRVM_serveredictvector(ent, origin), type, ent, SV_GenericHitSuperContentsMask(ent), 0).startsolid)
        {
                Con_Printf("something eeeeevil happened\n");
        }
@@ -1828,7 +1828,7 @@ static void SV_PushMove (prvm_edict_t *pusher, float movetime)
                        VectorCopy(PRVM_serveredictvector(check, origin), checkorigin);
                        VectorCopy(PRVM_serveredictvector(check, mins), checkmins);
                        VectorCopy(PRVM_serveredictvector(check, maxs), checkmaxs);
-                       Collision_ClipToGenericEntity(&trace, pushermodel, pusher->priv.server->frameblend, &pusher->priv.server->skeleton, pushermins, pushermaxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, checkorigin, checkmins, checkmaxs, checkorigin, checkcontents, collision_extendmovelength.value);
+                       Collision_ClipToGenericEntity(&trace, pushermodel, pusher->priv.server->frameblend, &pusher->priv.server->skeleton, pushermins, pushermaxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, checkorigin, checkmins, checkmaxs, checkorigin, checkcontents, 0, collision_extendmovelength.value);
                        //trace = SV_TraceBox(PRVM_serveredictvector(check, origin), PRVM_serveredictvector(check, mins), PRVM_serveredictvector(check, maxs), PRVM_serveredictvector(check, origin), MOVE_NOMONSTERS, check, checkcontents);
                        if (!trace.startsolid)
                        {
@@ -1895,7 +1895,7 @@ static void SV_PushMove (prvm_edict_t *pusher, float movetime)
                VectorCopy(PRVM_serveredictvector(check, origin), checkorigin);
                VectorCopy(PRVM_serveredictvector(check, mins), checkmins);
                VectorCopy(PRVM_serveredictvector(check, maxs), checkmaxs);
-               Collision_ClipToGenericEntity(&trace, pushermodel, pusher->priv.server->frameblend, &pusher->priv.server->skeleton, pushermins, pushermaxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, checkorigin, checkmins, checkmaxs, checkorigin, checkcontents, collision_extendmovelength.value);
+               Collision_ClipToGenericEntity(&trace, pushermodel, pusher->priv.server->frameblend, &pusher->priv.server->skeleton, pushermins, pushermaxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, checkorigin, checkmins, checkmaxs, checkorigin, checkcontents, 0, collision_extendmovelength.value);
                if (trace.startsolid)
                {
                        vec3_t move2;
@@ -2248,7 +2248,7 @@ int SV_TryUnstick (prvm_edict_t *ent, vec3_t oldvel)
                PRVM_serveredictvector(ent, velocity)[0] = oldvel[0];
                PRVM_serveredictvector(ent, velocity)[1] = oldvel[1];
                PRVM_serveredictvector(ent, velocity)[2] = 0;
-               clip = SV_FlyMove (ent, 0.1, NULL, SV_GenericHitSuperContentsMask(ent));
+               clip = SV_FlyMove (ent, 0.1, NULL, SV_GenericHitSuperContentsMask(ent), 0);
 
                if (fabs(oldorg[1] - PRVM_serveredictvector(ent, origin)[1]) > 4
                 || fabs(oldorg[0] - PRVM_serveredictvector(ent, origin)[0]) > 4)
@@ -2284,6 +2284,7 @@ static void SV_WalkMove (prvm_edict_t *ent)
        int originalmove_flags;
        int originalmove_groundentity;
        int hitsupercontentsmask;
+       int skipsupercontentsmask;
        int type;
        vec3_t upmove, downmove, start_origin, start_velocity, stepnormal, originalmove_origin, originalmove_velocity, entmins, entmaxs;
        trace_t downtrace, trace;
@@ -2300,6 +2301,7 @@ static void SV_WalkMove (prvm_edict_t *ent)
        applygravity = !SV_CheckWater (ent) && PRVM_serveredictfloat(ent, movetype) == MOVETYPE_WALK && ! ((int)PRVM_serveredictfloat(ent, flags) & FL_WATERJUMP);
 
        hitsupercontentsmask = SV_GenericHitSuperContentsMask(ent);
+       skipsupercontentsmask = 0;
 
        SV_CheckVelocity(ent);
 
@@ -2309,7 +2311,7 @@ static void SV_WalkMove (prvm_edict_t *ent)
        VectorCopy (PRVM_serveredictvector(ent, origin), start_origin);
        VectorCopy (PRVM_serveredictvector(ent, velocity), start_velocity);
 
-       clip = SV_FlyMove (ent, sv.frametime, applygravity, NULL, hitsupercontentsmask, sv_gameplayfix_stepmultipletimes.integer ? sv_stepheight.value : 0);
+       clip = SV_FlyMove (ent, sv.frametime, applygravity, NULL, hitsupercontentsmask, skipsupercontentsmask, sv_gameplayfix_stepmultipletimes.integer ? sv_stepheight.value : 0);
 
        if(sv_gameplayfix_downtracesupportsongroundflag.integer)
        if(!(clip & 1))
@@ -2329,7 +2331,7 @@ static void SV_WalkMove (prvm_edict_t *ent)
                        type = MOVE_NORMAL;
                VectorCopy(PRVM_serveredictvector(ent, mins), entmins);
                VectorCopy(PRVM_serveredictvector(ent, maxs), entmaxs);
-               trace = SV_TraceBox(upmove, entmins, entmaxs, downmove, type, ent, SV_GenericHitSuperContentsMask(ent), collision_extendmovelength.value);
+               trace = SV_TraceBox(upmove, entmins, entmaxs, downmove, type, ent, SV_GenericHitSuperContentsMask(ent), skipsupercontentsmask, collision_extendmovelength.value);
                if(trace.fraction < 1 && trace.plane.normal[2] > 0.7)
                        clip |= 1; // but we HAVE found a floor
        }
@@ -2392,7 +2394,7 @@ static void SV_WalkMove (prvm_edict_t *ent)
 
                // move forward
                PRVM_serveredictvector(ent, velocity)[2] = 0;
-               clip = SV_FlyMove (ent, sv.frametime, applygravity, stepnormal, hitsupercontentsmask, 0);
+               clip = SV_FlyMove (ent, sv.frametime, applygravity, stepnormal, hitsupercontentsmask, skipsupercontentsmask, 0);
                PRVM_serveredictvector(ent, velocity)[2] += start_velocity[2];
                if(clip & 8)
                {
@@ -2765,7 +2767,7 @@ static void SV_Physics_Step (prvm_edict_t *ent)
                        {
                                PRVM_serveredictfloat(ent, flags) -= FL_ONGROUND;
                                SV_CheckVelocity(ent);
-                               SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent), 0);
+                               SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent), 0, 0);
                                SV_LinkEdict(ent);
                                SV_LinkEdict_TouchAreaGrid(ent);
                                ent->priv.server->waterposition_forceupdate = true;
@@ -2777,7 +2779,7 @@ static void SV_Physics_Step (prvm_edict_t *ent)
                        int hitsound = PRVM_serveredictvector(ent, velocity)[2] < sv_gravity.value * -0.1;
 
                        SV_CheckVelocity(ent);
-                       SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent), 0);
+                       SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent), 0, 0);
                        SV_LinkEdict(ent);
                        SV_LinkEdict_TouchAreaGrid(ent);
 
index 1e9050d..991b277 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -59,7 +59,7 @@ void SV_SetIdealPitch (void)
                bottom[1] = top[1];
                bottom[2] = top[2] - 160;
 
-               tr = SV_TraceLine(top, bottom, MOVE_NOMONSTERS, host_client->edict, SUPERCONTENTS_SOLID, collision_extendmovelength.value);
+               tr = SV_TraceLine(top, bottom, MOVE_NOMONSTERS, host_client->edict, SUPERCONTENTS_SOLID, 0, collision_extendmovelength.value);
                // if looking at a wall, leave ideal the way is was
                if (tr.startsolid)
                        return;
@@ -126,7 +126,7 @@ static void SV_UserFriction (void)
        start[2] = PRVM_serveredictvector(host_client->edict, origin)[2] + PRVM_serveredictvector(host_client->edict, mins)[2];
        stop[2] = start[2] - 34;
 
-       trace = SV_TraceLine(start, stop, MOVE_NOMONSTERS, host_client->edict, SV_GenericHitSuperContentsMask(host_client->edict), collision_extendmovelength.value);
+       trace = SV_TraceLine(start, stop, MOVE_NOMONSTERS, host_client->edict, SV_GenericHitSuperContentsMask(host_client->edict), 0, collision_extendmovelength.value);
 
        if (trace.fraction == 1.0)
                friction = sv_friction.value*sv_edgefriction.value;
index c6fe7c8..b5f96a8 100644 (file)
@@ -656,7 +656,7 @@ static void VM_SV_traceline(prvm_prog_t *prog)
        if (VEC_IS_NAN(v1[0]) || VEC_IS_NAN(v1[1]) || VEC_IS_NAN(v1[2]) || VEC_IS_NAN(v2[0]) || VEC_IS_NAN(v2[1]) || VEC_IS_NAN(v2[2]))
                prog->error_cmd("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
 
-       trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent), collision_extendtracelinelength.value);
+       trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent), 0, collision_extendtracelinelength.value);
 
        VM_SetTraceGlobals(prog, &trace);
 }
@@ -695,7 +695,7 @@ static void VM_SV_tracebox(prvm_prog_t *prog)
        if (VEC_IS_NAN(v1[0]) || VEC_IS_NAN(v1[1]) || VEC_IS_NAN(v1[2]) || VEC_IS_NAN(v2[0]) || VEC_IS_NAN(v2[1]) || VEC_IS_NAN(v2[2]))
                prog->error_cmd("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
 
-       trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent), collision_extendtraceboxlength.value);
+       trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent), 0, collision_extendtraceboxlength.value);
 
        VM_SetTraceGlobals(prog, &trace);
 }
@@ -731,7 +731,7 @@ static trace_t SV_Trace_Toss(prvm_prog_t *prog, prvm_edict_t *tossent, prvm_edic
                VectorCopy(PRVM_serveredictvector(tossent, origin), tossentorigin);
                VectorCopy(PRVM_serveredictvector(tossent, mins), tossentmins);
                VectorCopy(PRVM_serveredictvector(tossent, maxs), tossentmaxs);
-               trace = SV_TraceBox(tossentorigin, tossentmins, tossentmaxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent), collision_extendmovelength.value);
+               trace = SV_TraceBox(tossentorigin, tossentmins, tossentmaxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent), 0, collision_extendmovelength.value);
                VectorCopy (trace.endpos, PRVM_serveredictvector(tossent, origin));
                PRVM_serveredictvector(tossent, velocity)[2] -= gravity;
 
@@ -1159,13 +1159,13 @@ static void VM_SV_droptofloor(prvm_prog_t *prog)
        VectorCopy(PRVM_serveredictvector(ent, origin), entorigin);
        VectorCopy(PRVM_serveredictvector(ent, mins), entmins);
        VectorCopy(PRVM_serveredictvector(ent, maxs), entmaxs);
-       trace = SV_TraceBox(entorigin, entmins, entmaxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), collision_extendmovelength.value);
+       trace = SV_TraceBox(entorigin, entmins, entmaxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value);
        if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
        {
                vec3_t offset, org;
                VectorSet(offset, 0.5f * (PRVM_serveredictvector(ent, mins)[0] + PRVM_serveredictvector(ent, maxs)[0]), 0.5f * (PRVM_serveredictvector(ent, mins)[1] + PRVM_serveredictvector(ent, maxs)[1]), PRVM_serveredictvector(ent, mins)[2]);
                VectorAdd(PRVM_serveredictvector(ent, origin), offset, org);
-               trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), collision_extendmovelength.value);
+               trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value);
                VectorSubtract(trace.endpos, offset, trace.endpos);
                if (trace.startsolid)
                {
@@ -1313,7 +1313,7 @@ static void VM_SV_aim(prvm_prog_t *prog)
 // try sending a trace straight
        VectorCopy (PRVM_serverglobalvector(v_forward), dir);
        VectorMA (start, 2048, dir, end);
-       tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY, collision_extendmovelength.value);
+       tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY, 0, collision_extendmovelength.value);
        if (tr.ent && PRVM_serveredictfloat(((prvm_edict_t *)tr.ent), takedamage) == DAMAGE_AIM
        && (!teamplay.integer || PRVM_serveredictfloat(ent, team) <=0 || PRVM_serveredictfloat(ent, team) != PRVM_serveredictfloat(((prvm_edict_t *)tr.ent), team)) )
        {
@@ -1345,7 +1345,7 @@ static void VM_SV_aim(prvm_prog_t *prog)
                dist = DotProduct (dir, PRVM_serverglobalvector(v_forward));
                if (dist < bestdist)
                        continue;       // to far to turn
-               tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY, collision_extendmovelength.value);
+               tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY, 0, collision_extendmovelength.value);
                if (tr.ent == check)
                {       // can shoot at this one
                        bestdist = dist;
index ac2ea61..039466d 100644 (file)
@@ -41,6 +41,10 @@ void Sys_Error (const char *error, ...)
 
        Con_Printf ("Quake Error: %s\n", string);
 
+#ifdef WIN32
+       MessageBox(NULL, string, "Quake Error", MB_OK | MB_SETFOREGROUND | MB_ICONSTOP);
+#endif
+
        Host_Shutdown ();
        exit (1);
 }
index df3e317..d3564ba 100644 (file)
--- a/sys_sdl.c
+++ b/sys_sdl.c
@@ -67,6 +67,10 @@ void Sys_Error (const char *error, ...)
 
        Con_Printf ("Quake Error: %s\n", string);
 
+#ifdef WIN32
+       MessageBox(NULL, string, "Quake Error", MB_OK | MB_SETFOREGROUND | MB_ICONSTOP);
+#endif
+
        Host_Shutdown ();
        exit (1);
 }
diff --git a/view.c b/view.c
index 6f86ac7..450b576 100644 (file)
--- a/view.c
+++ b/view.c
@@ -600,9 +600,9 @@ void V_CalcRefdefUsing (const matrix4x4_t *entrendermatrix, const vec3_t clviewa
 #else
                                // trace from first person view location to our chosen third person view location
 #if 1
-                               trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false, true);
+                               trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, 0, collision_extendmovelength.value, true, false, NULL, false, true);
 #else
-                               trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false);
+                               trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, 0, collision_extendmovelength.value, true, false, NULL, false);
 #endif
                                VectorCopy(trace.endpos, bestvieworg);
                                offset[2] = 0;
@@ -615,9 +615,9 @@ void V_CalcRefdefUsing (const matrix4x4_t *entrendermatrix, const vec3_t clviewa
                                                chase_dest[1] = vieworg[1] - forward[1] * camback + up[1] * camup + offset[1];
                                                chase_dest[2] = vieworg[2] - forward[2] * camback + up[2] * camup + offset[2];
 #if 1
-                                               trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false, true);
+                                               trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, 0, collision_extendmovelength.value, true, false, NULL, false, true);
 #else
-                                               trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false);
+                                               trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, 0, collision_extendmovelength.value, true, false, NULL, false);
 #endif
                                                if (bestvieworg[2] > trace.endpos[2])
                                                        bestvieworg[2] = trace.endpos[2];
@@ -643,7 +643,7 @@ void V_CalcRefdefUsing (const matrix4x4_t *entrendermatrix, const vec3_t clviewa
                                chase_dest[0] = vieworg[0] + forward[0] * dist;
                                chase_dest[1] = vieworg[1] + forward[1] * dist;
                                chase_dest[2] = vieworg[2] + forward[2] * dist + camup;
-                               trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false, true);
+                               trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, 0, collision_extendmovelength.value, true, false, NULL, false, true);
                                VectorMAMAM(1, trace.endpos, 8, forward, 4, trace.plane.normal, vieworg);
                        }
                }
@@ -734,13 +734,13 @@ void V_CalcRefdefUsing (const matrix4x4_t *entrendermatrix, const vec3_t clviewa
                                                bob_height_check_dest[0] = vieworg[0];
                                                bob_height_check_dest[1] = vieworg[1];
                                                bob_height_check_dest[2] = vieworg[2] + cl_bob_limit.value * 1.1f;
-                                               trace = CL_TraceLine(vieworg, bob_height_check_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY | (cl_bob_limit_heightcheck_dontcrosswatersurface.integer ? SUPERCONTENTS_LIQUIDSMASK : 0), collision_extendmovelength.value, true, false, NULL, false, true);
+                                               trace = CL_TraceLine(vieworg, bob_height_check_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY | (cl_bob_limit_heightcheck_dontcrosswatersurface.integer ? SUPERCONTENTS_LIQUIDSMASK : 0), 0, collision_extendmovelength.value, true, false, NULL, false, true);
                                                trace1fraction = trace.fraction;
 
                                                bob_height_check_dest[0] = vieworg[0];
                                                bob_height_check_dest[1] = vieworg[1];
                                                bob_height_check_dest[2] = vieworg[2] + cl_bob_limit.value * -0.5f;
-                                               trace = CL_TraceLine(vieworg, bob_height_check_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY | (cl_bob_limit_heightcheck_dontcrosswatersurface.integer ? SUPERCONTENTS_LIQUIDSMASK : 0), collision_extendmovelength.value, true, false, NULL, false, true);
+                                               trace = CL_TraceLine(vieworg, bob_height_check_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY | (cl_bob_limit_heightcheck_dontcrosswatersurface.integer ? SUPERCONTENTS_LIQUIDSMASK : 0), 0, collision_extendmovelength.value, true, false, NULL, false, true);
                                                trace2fraction = trace.fraction;
 
                                                bob_limit *= min(trace1fraction, trace2fraction);
diff --git a/zone.c b/zone.c
index fe80693..2aa575e 100644 (file)
--- a/zone.c
+++ b/zone.c
@@ -95,6 +95,7 @@ static memclump_t *clumpchain = NULL;
 
 cvar_t developer_memory = {0, "developer_memory", "0", "prints debugging information about memory allocations"};
 cvar_t developer_memorydebug = {0, "developer_memorydebug", "0", "enables memory corruption checks (very slow)"};
+cvar_t developer_memoryreportlargerthanmb = {0, "developer_memorylargerthanmb", "16", "prints debugging information about memory allocations over this size"};
 cvar_t sys_memsize_physical = {CVAR_READONLY, "sys_memsize_physical", "", "physical memory size in MB (or empty if unknown)"};
 cvar_t sys_memsize_virtual = {CVAR_READONLY, "sys_memsize_virtual", "", "virtual memory size in MB (or empty if unknown)"};
 
@@ -390,21 +391,21 @@ void *_Mem_Alloc(mempool_t *pool, void *olddata, size_t size, size_t alignment,
        }
        if (mem_mutex)
                Thread_LockMutex(mem_mutex);
-       if (developer_memory.integer)
-               Con_DPrintf("Mem_Alloc: pool %s, file %s:%i, size %i bytes\n", pool->name, filename, fileline, (int)size);
+       if (developer_memory.integer || size >= developer_memoryreportlargerthanmb.value * 1048576)
+               Con_DPrintf("Mem_Alloc: pool %s, file %s:%i, size %f bytes (%f MB)\n", pool->name, filename, fileline, (double)size, (double)size / 1048576.0f);
        //if (developer.integer > 0 && developer_memorydebug.integer)
        //      _Mem_CheckSentinelsGlobal(filename, fileline);
        pool->totalsize += size;
        realsize = alignment + sizeof(memheader_t) + size + sizeof(sentinel2);
        pool->realsize += realsize;
        base = (unsigned char *)Clump_AllocBlock(realsize);
-       if (base== NULL)
+       if (base == NULL)
        {
                Mem_PrintList(0);
                Mem_PrintStats();
                Mem_PrintList(1<<30);
                Mem_PrintStats();
-               Sys_Error("Mem_Alloc: out of memory (alloc at %s:%i)", filename, fileline);
+               Sys_Error("Mem_Alloc: out of memory (alloc of size %f (%.3fMB) at %s:%i)", (double)realsize, (double)realsize / (1 << 20), filename, fileline);
        }
        // calculate address that aligns the end of the memheader_t to the specified alignment
        mem = (memheader_t*)((((size_t)base + sizeof(memheader_t) + (alignment-1)) & ~(alignment-1)) - sizeof(memheader_t));
@@ -919,6 +920,7 @@ void Memory_Init_Commands (void)
        Cmd_AddCommand ("memlist", MemList_f, "prints memory pool information (or if used as memlist 5 lists individual allocations of 5K or larger, 0 lists all allocations)");
        Cvar_RegisterVariable (&developer_memory);
        Cvar_RegisterVariable (&developer_memorydebug);
+       Cvar_RegisterVariable (&developer_memoryreportlargerthanmb);
        Cvar_RegisterVariable (&sys_memsize_physical);
        Cvar_RegisterVariable (&sys_memsize_virtual);
 
diff --git a/zone.h b/zone.h
index 6caa039..a157bac 100644 (file)
--- a/zone.h
+++ b/zone.h
@@ -139,6 +139,7 @@ extern mempool_t *zonemempool;
 
 extern struct cvar_s developer_memory;
 extern struct cvar_s developer_memorydebug;
+extern struct cvar_s developer_memoryreportlargerthanmb;
 
 #endif