+ extendtraceinfo->trace = trace;
+ VectorCopy(tstart, extendtraceinfo->realstart);
+ VectorCopy(tend, extendtraceinfo->realend);
+ VectorSubtract(extendtraceinfo->realend, extendtraceinfo->realstart, extendtraceinfo->realdelta);
+ VectorCopy(extendtraceinfo->realstart, extendtraceinfo->extendstart);
+ VectorCopy(extendtraceinfo->realend, extendtraceinfo->extendend);
+ VectorCopy(extendtraceinfo->realdelta, extendtraceinfo->extenddelta);
+ extendtraceinfo->reallength = VectorLength(extendtraceinfo->realdelta);
+ extendtraceinfo->extendlength = extendtraceinfo->reallength;
+ extendtraceinfo->scaletoextend = 1.0f;
+ extendtraceinfo->extend = textend;
+
+ // make the trace longer according to the extend parameter
+ if (extendtraceinfo->reallength && extendtraceinfo->extend)
+ {
+ extendtraceinfo->extendlength = extendtraceinfo->reallength + extendtraceinfo->extend;
+ extendtraceinfo->scaletoextend = extendtraceinfo->extendlength / extendtraceinfo->reallength;
+ VectorMA(extendtraceinfo->realstart, extendtraceinfo->scaletoextend, extendtraceinfo->realdelta, extendtraceinfo->extendend);
+ VectorSubtract(extendtraceinfo->extendend, extendtraceinfo->extendstart, extendtraceinfo->extenddelta);
+ }
+}
+
+static void Collision_ClipExtendFinish(extendtraceinfo_t *extendtraceinfo)
+{
+ trace_t *trace = extendtraceinfo->trace;
+
+ if (trace->fraction != 1.0f)
+ {
+ // undo the extended trace length
+ trace->fraction *= extendtraceinfo->scaletoextend;
+ trace->realfraction *= extendtraceinfo->scaletoextend;
+
+ // if the extended trace hit something that the unextended trace did not hit (even considering the collision_impactnudge), then we have to clear the hit information
+ if (trace->fraction > 1.0f)
+ {
+ // note that ent may refer to either startsolid or fraction<1, we can't restore the startsolid ent unfortunately
+ trace->ent = NULL;
+ trace->hitq3surfaceflags = 0;
+ trace->hitsupercontents = 0;
+ trace->hittexture = NULL;
+ VectorClear(trace->plane.normal);
+ trace->plane.dist = 0.0f;
+ }
+ }
+
+ // clamp things
+ trace->fraction = bound(0, trace->fraction, 1);
+ trace->realfraction = bound(0, trace->realfraction, 1);
+
+ // calculate the end position
+ 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)
+{
+ vec3_t starttransformed, endtransformed;
+ extendtraceinfo_t extendtraceinfo;
+ Collision_ClipExtendPrepare(&extendtraceinfo, trace, tstart, tend, extend);
+
+ Matrix4x4_Transform(inversematrix, extendtraceinfo.extendstart, starttransformed);
+ Matrix4x4_Transform(inversematrix, extendtraceinfo.extendend, endtransformed);