-#else
- float d1, d2, d, f, fnudged, impact[3], edgenormal[3], faceplanenormal[3], faceplanedist, edge[3];
-
- // this code is designed for clockwise triangles, conversion to
- // counterclockwise would require swapping some things around...
- // it is easier to simply swap the point0 and point2 parameters to this
- // function when calling it than it is to rewire the internals.
-
- // calculate the unnormalized faceplanenormal of the triangle,
- // this represents the front side
- TriangleNormal(point0, point1, point2, faceplanenormal);
- // there's no point in processing a degenerate triangle
- // (GIGO - Garbage In, Garbage Out)
- if (DotProduct(faceplanenormal, faceplanenormal) < 0.0001f)
- return;
- // calculate the unnormalized distance
- faceplanedist = DotProduct(point0, faceplanenormal);
-
- // calculate the unnormalized start distance
- d1 = DotProduct(faceplanenormal, linestart) - faceplanedist;
- // if start point is on the back side there is no collision
- // (we don't care about traces going through the triangle the wrong way)
- if (d1 <= 0)
- return;
-
- // calculate the unnormalized end distance
- d2 = DotProduct(faceplanenormal, lineend) - faceplanedist;
- // if both are in front, there is no collision
- if (d2 >= 0)
- return;
-
- // from here on we know d1 is >= 0 and d2 is < 0
- // this means the line starts infront and ends behind, passing through it
-
- // calculate the recipricol of the distance delta,
- // so we can use it multiple times cheaply (instead of division)
- d = 1.0f / (d1 - d2);
- // calculate the impact fraction by taking the start distance (> 0)
- // and subtracting the face plane distance (this is the distance of the
- // triangle along that same normal)
- // then multiply by the recipricol distance delta
- f = d1 * d;
- // skip out if this impact is further away than previous ones
- if (f > trace->realfraction)
- return;
- // calculate the perfect impact point for classification of insidedness
- impact[0] = linestart[0] + f * (lineend[0] - linestart[0]);
- impact[1] = linestart[1] + f * (lineend[1] - linestart[1]);
- impact[2] = linestart[2] + f * (lineend[2] - linestart[2]);
-
- // calculate the edge normal and reject if impact is outside triangle
- // (an edge normal faces away from the triangle, to get the desired normal
- // a crossproduct with the faceplanenormal is used, and because of the way
- // the insidedness comparison is written it does not need to be normalized)
-
- VectorSubtract(point2, point0, edge);
- CrossProduct(edge, faceplanenormal, edgenormal);
- if (DotProduct(impact, edgenormal) > DotProduct(point0, edgenormal))
- return;
-
- VectorSubtract(point0, point1, edge);
- CrossProduct(edge, faceplanenormal, edgenormal);
- if (DotProduct(impact, edgenormal) > DotProduct(point1, edgenormal))
- return;
-
- VectorSubtract(point1, point2, edge);
- CrossProduct(edge, faceplanenormal, edgenormal);
- if (DotProduct(impact, edgenormal) > DotProduct(point2, edgenormal))
- return;
-
- // store the new trace fraction
- trace->realfraction = bound(0, f, 1);
-
- // store the new trace plane (because collisions only happen from
- // the front this is always simply the triangle normal, never flipped)
- VectorNormalize(faceplanenormal);
- VectorCopy(faceplanenormal, trace->plane.normal);
- trace->plane.dist = DotProduct(point0, faceplanenormal);
-
- // calculate the normalized start and end distances
- d1 = DotProduct(trace->plane.normal, linestart) - trace->plane.dist;
- d2 = DotProduct(trace->plane.normal, lineend) - trace->plane.dist;
-
- // calculate a nudged fraction to keep it out of the surface
- // (the main fraction remains perfect)
- fnudged = (d1 - collision_impactnudge.value) / (d1 - d2);
- trace->fraction = bound(0, fnudged, 1);
-
- // store the new trace endpos
- // not needed, it's calculated later when the trace is finished
- //trace->endpos[0] = linestart[0] + fnudged * (lineend[0] - linestart[0]);
- //trace->endpos[1] = linestart[1] + fnudged * (lineend[1] - linestart[1]);
- //trace->endpos[2] = linestart[2] + fnudged * (lineend[2] - linestart[2]);
- trace->hitsupercontents = supercontents;
- trace->hitq3surfaceflags = q3surfaceflags;
- trace->hittexture = texture;
-#endif