private static void CM_TestBoxInBrush(Vector3 p1, ref TraceT trace, BSPBrush brush) { BSPBrushSide[] sides = brush.Sides; BSPPlane plane; float dist, d1; for (int i = 0; i < sides.Length; i++) { plane = sides[i].Plane; dist = Vector3.Dot(trace_offsets[plane.Signbits], plane.normal); dist = plane.distance - dist; d1 = Vector3.Dot(p1, plane.normal) - dist; //completely in front of a face, no intersection if (d1 > 0) { return; } } trace.startsolid = trace.allsolid = true; trace.fraction = 0; trace.contents = brush.contents; }
/// <summary> /// Checks for intersection with a brush during a moving trace. /// </summary> /// <param name="p1">Trace start.</param> /// <param name="p2">Trace end.</param> /// <param name="trace">Data struct.</param> /// <param name="brush">Brush to test against.</param> private static void CM_ClipBoxToBrush(Vector3 p1, Vector3 p2, ref TraceT trace, BSPBrush brush) { int i; BSPPlane plane; BSPPlane clipplane = new BSPPlane(); //initialize this to keep c# happy... float dist; float enterfrac, leavefrac; float d1, d2; bool getout, startout; bool hasclip = false; bool haslead = false; float f; BSPBrushSide leadside = new BSPBrushSide(); //initialize this to keep c# happy... BSPBrushSide[] sides; if (brush.numsides == 0) { return; } sides = brush.Sides; enterfrac = -1; leavefrac = 1; getout = false; //gets out of the brush startout = false; //starts inside the brush for (i = 0; i < brush.numsides; i++) { plane = sides[i].Plane; //we only need plane for each side //get plane to bounds point distance if (!trace_ispoint) { //bounding box trace dist = Vector3.Dot(trace_offsets[plane.Signbits], plane.normal); dist = plane.distance - dist; } else { //point trace dist = plane.distance; } //get distances for start and end of the trace d1 = Vector3.Dot(p1, plane.normal) - dist; //start d2 = Vector3.Dot(p2, plane.normal) - dist; //end if (d2 > 0) { getout = true; //endpoint is not in solid } if (d1 > 0) { startout = true; //starts outside } //if completely in front of a face, no intersection if (d1 > 0 && d2 >= d1) { return; //a single face plane that is not crossed while tracing means that we never hit that brush } //? if (d1 <= 0 && d2 <= 0) { continue; } //crosses face if (d1 > d2) { //enter f = (d1 - DIST_EPSILON) / (d1 - d2); //fraction of the distance covered before hitting a side if (f > enterfrac) { enterfrac = f; clipplane = plane; hasclip = true; //plane clips the trace leadside = sides[i]; haslead = true; //could be combined with hasclip? writes flags for the collided face } } else { //leave f = (d1 + DIST_EPSILON) / (d1 - d2); if (f < leavefrac) { leavefrac = f; } } } //startout wasn't true for any face if (!startout) { //original point was inside brush trace.startsolid = true; if (!getout) { trace.allsolid = true; //map_allsolid_bug trace.fraction = 0; trace.contents = brush.contents; } return; } //after testing all faces we need to see which test went further if (enterfrac < leavefrac) { //only write the test if the brush was closer than any brushes hit before if (enterfrac > -1 && enterfrac < trace.fraction) { if (enterfrac < 0) { enterfrac = 0; } trace.fraction = enterfrac; if (hasclip) { trace.plane = clipplane; } if (haslead) { if (leadside.HasTexInfo) { trace.surface = leadside.TexInfo.Surface; } } trace.contents = brush.contents; } } }