X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=cl_collision.c;h=17e7b4f8d2d35273d19340963d76b61c045ffd92;hb=7413525f1f0dcf3dca42f385fb93ffd5a25b8744;hp=3ade5bcf15d54dce4f11fe733af0ed9e0e87aefd;hpb=304f700ebc2837534f108cf2051d3f6224fec8af;p=xonotic%2Fdarkplaces.git diff --git a/cl_collision.c b/cl_collision.c index 3ade5bcf..17e7b4f8 100644 --- a/cl_collision.c +++ b/cl_collision.c @@ -38,7 +38,6 @@ float CL_TraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t n entity_render_t *ent; float tracemins[3], tracemaxs[3]; trace_t trace; - matrix4x4_t matrix, imatrix; float tempnormal[3], starttransformed[3], endtransformed[3]; memset (&trace, 0 , sizeof(trace_t)); @@ -71,15 +70,11 @@ float CL_TraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t n for (n = 0;n < cl_num_brushmodel_entities;n++) { ent = cl_brushmodel_entities[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]) + if (!BoxesOverlap(tracemins, tracemaxs, ent->mins, ent->maxs)) continue; - Matrix4x4_CreateFromQuakeEntity(&matrix, ent->origin[0], ent->origin[1], ent->origin[2], ent->angles[0], ent->angles[1], ent->angles[2], 1); - Matrix4x4_Invert_Simple(&imatrix, &matrix); - Matrix4x4_Transform(&imatrix, start, starttransformed); - Matrix4x4_Transform(&imatrix, end, endtransformed); + Matrix4x4_Transform(&ent->inversematrix, start, starttransformed); + Matrix4x4_Transform(&ent->inversematrix, end, endtransformed); if (ent->model && ent->model->TraceBox) ent->model->TraceBox(ent->model, 0, &trace, starttransformed, starttransformed, endtransformed, endtransformed, hitsupercontentsmask); @@ -94,12 +89,90 @@ float CL_TraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t n if (normal) { VectorCopy(trace.plane.normal, tempnormal); - Matrix4x4_Transform3x3(&matrix, tempnormal, normal); + Matrix4x4_Transform3x3(&ent->matrix, tempnormal, normal); } } } } - if (maxfrac < 0 || maxfrac > 1) Con_Printf("fraction out of bounds %f %s:%d\n", maxfrac, __FILE__, __LINE__); + maxfrac = bound(0, maxfrac, 1); + maxrealfrac = bound(0, maxrealfrac, 1); + //if (maxfrac < 0 || maxfrac > 1) Con_Printf("fraction out of bounds %f %s:%d\n", maxfrac, __FILE__, __LINE__); + if (impact) + VectorLerp(start, maxfrac, end, impact); + return maxfrac; +} + +float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int *hitent, entity_render_t *ignoreent) +{ + float maxfrac, maxrealfrac; + int n; + entity_render_t *ent; + float tracemins[3], tracemaxs[3]; + trace_t trace; + float tempnormal[3], starttransformed[3], endtransformed[3]; + + memset (&trace, 0 , sizeof(trace_t)); + trace.fraction = 1; + trace.realfraction = 1; + VectorCopy (end, trace.endpos); + + if (hitent) + *hitent = 0; + Mod_CheckLoaded(cl.worldmodel); + if (cl.worldmodel && cl.worldmodel->TraceBox) + cl.worldmodel->TraceBox(cl.worldmodel, 0, &trace, start, start, end, end, SUPERCONTENTS_SOLID); + + if (normal) + VectorCopy(trace.plane.normal, normal); + cl_traceline_startsupercontents = trace.startsupercontents; + maxfrac = trace.fraction; + maxrealfrac = trace.realfraction; + + 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 < MAX_EDICTS;n++) + { + if (!cl_entities_active[n]) + continue; + ent = &cl_entities[n].render; + if (!BoxesOverlap(ent->mins, ent->maxs, tracemins, tracemaxs)) + continue; + if (!ent->model || !ent->model->TraceBox) + continue; + // if transparent and not selectable, skip entity + if (!(cl_entities[n].state_current.effects & EF_SELECTABLE) && (ent->alpha < 1 || (ent->effects & (EF_ADDITIVE | EF_NODEPTHTEST)))) + continue; + if (ent == ignoreent) + continue; + Matrix4x4_Transform(&ent->inversematrix, start, starttransformed); + Matrix4x4_Transform(&ent->inversematrix, end, endtransformed); + + if (ent->model && ent->model->TraceBox) + ent->model->TraceBox(ent->model, ent->frameblend[0].frame, &trace, starttransformed, starttransformed, endtransformed, endtransformed, SUPERCONTENTS_SOLID); + + cl_traceline_startsupercontents |= trace.startsupercontents; + if (maxrealfrac > trace.realfraction) + { + if (hitent) + *hitent = n; + maxfrac = trace.fraction; + maxrealfrac = trace.realfraction; + if (normal) + { + VectorCopy(trace.plane.normal, tempnormal); + Matrix4x4_Transform3x3(&ent->matrix, tempnormal, normal); + } + } + } + maxfrac = bound(0, maxfrac, 1); + maxrealfrac = bound(0, maxrealfrac, 1); + //if (maxfrac < 0 || maxfrac > 1) Con_Printf("fraction out of bounds %f %s:%d\n", maxfrac, __FILE__, __LINE__); if (impact) VectorLerp(start, maxfrac, end, impact); return maxfrac;