From: havoc Date: Mon, 24 Oct 2011 09:42:37 +0000 (+0000) Subject: fix Collision_ClipTrace_Line_Sphere calculation of impactdist (had a X-Git-Tag: xonotic-v0.6.0~219 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=3a8a89541fbcbe4280a9b6bcd0c95aa378f2ee53;p=xonotic%2Fdarkplaces.git fix Collision_ClipTrace_Line_Sphere calculation of impactdist (had a discussion about this previously but forgot the solution, now reminded) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11468 d7cf8633-e32d-0410-b094-e92efae38249 ::stable-branch::merge=1e204307ba6b7339554cbf8df223bb015a4f538b --- diff --git a/collision.c b/collision.c index e0cc37dd..5305a94e 100644 --- a/collision.c +++ b/collision.c @@ -1278,7 +1278,7 @@ void Collision_ClipTrace_BrushBox(trace_t *trace, const vec3_t cmins, const vec3 // all the results are correct (impactpoint, impactnormal, and fraction) float Collision_ClipTrace_Line_Sphere(double *linestart, double *lineend, double *sphereorigin, double sphereradius, double *impactpoint, double *impactnormal) { - double dir[3], scale, v[3], deviationdist, impactdist, linelength; + double dir[3], scale, v[3], deviationdist2, impactdist, linelength; // make sure the impactpoint and impactnormal are valid even if there is // no collision VectorCopy(lineend, impactpoint); @@ -1300,13 +1300,12 @@ float Collision_ClipTrace_Line_Sphere(double *linestart, double *lineend, double // of the line from the sphereorigin (deviation, how off-center it is) VectorMA(linestart, impactdist, dir, v); VectorSubtract(v, sphereorigin, v); - deviationdist = VectorLength2(v); - // if outside the radius, it's a miss for sure - // (we do this comparison using squared radius to avoid a sqrt) - if (deviationdist > sphereradius*sphereradius) + deviationdist2 = sphereradius * sphereradius - VectorLength2(v); + // if squared offset length is outside the squared sphere radius, miss + if (deviationdist2 < 0) return 1; // miss (off to the side) // nudge back to find the correct impact distance - impactdist -= sphereradius - deviationdist/sphereradius; + impactdist -= sqrt(deviationdist2); if (impactdist >= linelength) return 1; // miss (not close enough) if (impactdist < 0)