/* ================== SV_ClipMoveToEntity Handles selection or creation of a clipping hull, and offseting (and eventually rotation) of the end points ================== */ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end) { trace_t trace; vec3_t offset; vec3_t start_l, end_l; hull_t *hull; // get the clipping hull hull = SV_HullForEntity (ent, mins, maxs, offset); VectorSubtract (start, offset, start_l); VectorSubtract (end, offset, end_l); // trace a line through the apropriate clipping hull trace = CM_HullTrace (hull, start_l, end_l); // fix trace up by the offset VectorAdd (trace.endpos, offset, trace.endpos); // did we clip the move? if (trace.fraction < 1 || trace.startsolid ) trace.e.ent = ent; return trace; }
/* ================ PM_TraceLine ================ */ trace_t PM_TraceLine (playermove_t *pm, vec3_t start, vec3_t end) { trace_t trace, total; vec3_t offset; vec3_t start_l, end_l; hull_t *hull; int i; physent_t *pe; // fill in a default trace memset (&total, 0, sizeof(trace_t)); total.fraction = 1; total.e.entnum = -1; VectorCopy (end, total.endpos); for (i=0 ; i< pm->numphysent ; i++) { pe = &pm->physents[i]; // get the clipping hull if (pe->model) hull = &pm->physents[i].model->hulls[0]; else hull = CM_HullForBox (pe->mins, pe->maxs); // PM_HullForEntity (ent, mins, maxs, offset); VectorCopy (pe->origin, offset); VectorSubtract (start, offset, start_l); VectorSubtract (end, offset, end_l); // trace a line through the apropriate clipping hull trace = CM_HullTrace (hull, start_l, end_l); // fix trace up by the offset VectorAdd (trace.endpos, offset, trace.endpos); if (trace.allsolid) trace.startsolid = true; if (trace.startsolid) trace.fraction = 0; // did we clip the move? if (trace.fraction < total.fraction) { total = trace; total.e.entnum = i; } } return total; }
/* ================ PM_PlayerTrace ================ */ trace_t PM_PlayerTrace (playermove_t *pm, vec3_t start, vec3_t end) { trace_t trace, total; vec3_t offset; vec3_t start_l, end_l; hull_t *hull; int i; physent_t *pe; vec3_t mins, maxs, tracemins, tracemaxs; // fill in a default trace memset (&total, 0, sizeof(trace_t)); total.fraction = 1; total.e.entnum = -1; VectorCopy (end, total.endpos); PM_TraceBounds(start, end, tracemins, tracemaxs); for (i=0 ; i< pm->numphysent ; i++) { pe = &pm->physents[i]; // get the clipping hull if (pe->model) { hull = &pm->physents[i].model->hulls[1]; if (i > 0 && PM_CullTraceBox(tracemins, tracemaxs, pe->origin, pe->model->mins, pe->model->maxs, hull->clip_mins, hull->clip_maxs)) continue; VectorSubtract (hull->clip_mins, player_mins, offset); VectorAdd (offset, pe->origin, offset); } else { VectorSubtract (pe->mins, player_maxs, mins); VectorSubtract (pe->maxs, player_mins, maxs); if (PM_CullTraceBox(tracemins, tracemaxs, pe->origin, mins, maxs, vec3_origin, vec3_origin)) continue; hull = CM_HullForBox (mins, maxs); VectorCopy (pe->origin, offset); } VectorSubtract (start, offset, start_l); VectorSubtract (end, offset, end_l); // rotate start and end into the models frame of reference if (pe->solid == 4 /*SOLID_BSP*/ && (pe->angles[0] || pe->angles[1] || pe->angles[2])) { vec3_t forward, right, up; vec3_t temp; AngleVectors (pe->angles, forward, right, up); VectorCopy (start_l, temp); start_l[0] = DotProduct (temp, forward); start_l[1] = -DotProduct (temp, right); start_l[2] = DotProduct (temp, up); VectorCopy (end_l, temp); end_l[0] = DotProduct (temp, forward); end_l[1] = -DotProduct (temp, right); end_l[2] = DotProduct (temp, up); } // trace a line through the apropriate clipping hull trace = CM_HullTrace (hull, start_l, end_l); // rotate endpos back to world frame of reference if (pe->solid == 4 /*SOLID_BSP*/ && (pe->angles[0] || pe->angles[1] || pe->angles[2])) { vec3_t a; vec3_t forward, right, up; vec3_t temp; if (trace.fraction != 1) { VectorSubtract (vec3_origin, pe->angles, a); AngleVectors (a, forward, right, up); VectorCopy (trace.endpos, temp); trace.endpos[0] = DotProduct (temp, forward); trace.endpos[1] = -DotProduct (temp, right); trace.endpos[2] = DotProduct (temp, up); VectorCopy (trace.plane.normal, temp); trace.plane.normal[0] = DotProduct (temp, forward); trace.plane.normal[1] = -DotProduct (temp, right); trace.plane.normal[2] = DotProduct (temp, up); } } // fix trace up by the offset VectorAdd (trace.endpos, offset, trace.endpos); if (trace.allsolid) trace.startsolid = true; if (trace.startsolid) trace.fraction = 0; // did we clip the move? if (trace.fraction < total.fraction) { total = trace; total.e.entnum = i; } } return total; }