]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - collision.c
Added developer_memorylargerthanmb cvar which dprints notices about very large memory...
[xonotic/darkplaces.git] / collision.c
index 547ad23635501a66778bab3a4d6f20631f9e59e5..827200efa4c8e21c0c1ff4c20193ad3fdbd44403 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);
 }