+ trace.startcontents = contents;
+ VectorCopy(startd, RecursiveHullCheckInfo.start);
+ VectorSubtract(endd, startd, RecursiveHullCheckInfo.dist);
+ RecursiveHullCheckInfo.hull = cl.worldmodel->hulls;
+ RecursiveHullCheckInfo.trace = &trace;
+ SV_RecursiveHullCheck (0, 0, 1, startd, endd);
+ if (impact)
+ VectorCopy (trace.endpos, impact);
+ if (normal)
+ VectorCopy (trace.plane.normal, normal);
+ traceline_endcontents = trace.endcontents;
+ maxfrac = trace.fraction;
+
+ if (hitbmodels && traceline_entities)
+ {
+ int n;
+ entity_render_t *ent;
+ double start2[3], end2[3], tracemins[3], tracemaxs[3];
+ tracemins[0] = min(start[0], end[0]);
+ tracemaxs[0] = max(start[0], end[0]);
+ tracemins[1] = min(start[1], end[1]);
+ tracemaxs[1] = max(start[1], end[1]);
+ tracemins[2] = min(start[2], end[2]);
+ tracemaxs[2] = max(start[2], end[2]);
+
+ // look for embedded bmodels
+ for (n = 0;n < traceline_entities;n++)
+ {
+ ent = traceline_entity[n];
+ if (ent->mins[0] > tracemaxs[0] || ent->maxs[0] < tracemins[0]
+ || ent->mins[1] > tracemaxs[1] || ent->maxs[1] < tracemins[1]
+ || ent->mins[2] > tracemaxs[2] || ent->maxs[2] < tracemins[2])
+ continue;
+
+ softwaretransformforentity(ent);
+ softwareuntransform(start, start2);
+ softwareuntransform(end, end2);
+
+ memset (&trace, 0, sizeof(trace));
+ VectorCopy (end2, trace.endpos);
+ trace.fraction = 1;
+ trace.startcontents = contents;
+ VectorCopy(start2, RecursiveHullCheckInfo.start);
+ VectorSubtract(end2, start2, RecursiveHullCheckInfo.dist);
+ RecursiveHullCheckInfo.hull = ent->model->hulls;
+ RecursiveHullCheckInfo.trace = &trace;
+ SV_RecursiveHullCheck (ent->model->hulls->firstclipnode, 0, 1, start2, end2);
+
+ if (trace.allsolid || trace.startsolid || trace.fraction < maxfrac)
+ {
+ maxfrac = trace.fraction;
+ if (impact)
+ {
+ softwaretransform(trace.endpos, impact);
+ }
+ if (normal)
+ {
+ softwaretransformdirection(trace.plane.normal, normal);
+ }
+ traceline_endcontents = trace.endcontents;
+ }
+ }
+ }
+ return maxfrac;