X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=collision.c;h=305c561245b606455d3d43f8afd8adff24f17b38;hb=f4be0db0317f362626f52d8dafff527fc6856092;hp=50812e5ec78b38ec0ce6144f84955c326c4941d3;hpb=d20775286cd10331bc845b0feac69f300c231524;p=xonotic%2Fdarkplaces.git diff --git a/collision.c b/collision.c index 50812e5e..305c5612 100644 --- a/collision.c +++ b/collision.c @@ -614,13 +614,15 @@ void Collision_TraceBrushBrushFloat(trace_t *trace, const colbrushf_t *thisbrush if (d1 > d2) { // moving into brush - if (d2 > 0) + if (d2 >= collision_enternudge.value) return; if (d1 > 0) { // enter imove = 1 / (d1 - d2); f = (d1 - collision_enternudge.value) * imove; + if (f < 0) + f = 0; // check if this will reduce the collision time range if (enterfrac < f) { @@ -636,7 +638,7 @@ void Collision_TraceBrushBrushFloat(trace_t *trace, const colbrushf_t *thisbrush return; // calculate the nudged fraction and impact normal we'll // need if we accept this collision later - enterfrac2 = f - collision_impactnudge.value * imove; + enterfrac2 = (d1 - collision_impactnudge.value) * imove; VectorLerp(startplane->normal, enterfrac, endplane->normal, newimpactnormal); hitq3surfaceflags = startplane->q3surfaceflags; hittexture = startplane->texture; @@ -652,6 +654,8 @@ void Collision_TraceBrushBrushFloat(trace_t *trace, const colbrushf_t *thisbrush { // leave f = (d1 + collision_leavenudge.value) / (d1 - d2); + if (f > 1) + f = 1; // check if this will reduce the collision time range if (leavefrac > f) { @@ -733,13 +737,15 @@ void Collision_TraceLineBrushFloat(trace_t *trace, const vec3_t linestart, const if (d1 > d2) { // moving into brush - if (d2 > 0) + if (d2 >= collision_enternudge.value) return; if (d1 > 0) { // enter imove = 1 / (d1 - d2); f = (d1 - collision_enternudge.value) * imove; + if (f < 0) + f = 0; // check if this will reduce the collision time range if (enterfrac < f) { @@ -755,7 +761,7 @@ void Collision_TraceLineBrushFloat(trace_t *trace, const vec3_t linestart, const return; // calculate the nudged fraction and impact normal we'll // need if we accept this collision later - enterfrac2 = f - collision_impactnudge.value * imove; + enterfrac2 = (d1 - collision_impactnudge.value) * imove; VectorLerp(startplane->normal, enterfrac, endplane->normal, newimpactnormal); hitq3surfaceflags = startplane->q3surfaceflags; hittexture = startplane->texture; @@ -1456,3 +1462,79 @@ void Collision_BoundingBoxOfBrushTraceSegment(const colbrushf_t *start, const co maxs[2] += 1; } +//=========================================== + +void Collision_ClipToGenericEntity(trace_t *trace, model_t *model, int frame, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask) +{ + float tempnormal[3], starttransformed[3], endtransformed[3]; + + memset(trace, 0, sizeof(*trace)); + trace->fraction = trace->realfraction = 1; + VectorCopy(end, trace->endpos); + + Matrix4x4_Transform(inversematrix, start, starttransformed); + Matrix4x4_Transform(inversematrix, end, endtransformed); +#if COLLISIONPARANOID >= 3 + Con_Printf("trans(%f %f %f -> %f %f %f, %f %f %f -> %f %f %f)", start[0], start[1], start[2], starttransformed[0], starttransformed[1], starttransformed[2], end[0], end[1], end[2], endtransformed[0], endtransformed[1], endtransformed[2]); +#endif + + if (model && model->TraceBox) + model->TraceBox(model, bound(0, frame, (model->numframes - 1)), trace, starttransformed, mins, maxs, endtransformed, hitsupercontentsmask); + else + Collision_ClipTrace_Box(trace, bodymins, bodymaxs, starttransformed, mins, maxs, endtransformed, hitsupercontentsmask, bodysupercontents, 0, NULL); + trace->fraction = bound(0, trace->fraction, 1); + trace->realfraction = bound(0, trace->realfraction, 1); + + if (trace->fraction < 1) + { + VectorLerp(start, trace->fraction, end, trace->endpos); + VectorCopy(trace->plane.normal, tempnormal); + Matrix4x4_Transform3x3(matrix, tempnormal, trace->plane.normal); + // FIXME: should recalc trace->plane.dist + } +} + +void Collision_ClipToWorld(trace_t *trace, model_t *model, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontents) +{ + memset(trace, 0, sizeof(*trace)); + trace->fraction = trace->realfraction = 1; + if (model && model->TraceBox) + model->TraceBox(model, 0, trace, start, mins, maxs, end, hitsupercontents); + trace->fraction = bound(0, trace->fraction, 1); + trace->realfraction = bound(0, trace->realfraction, 1); + VectorLerp(start, trace->fraction, end, trace->endpos); +} + +void Collision_CombineTraces(trace_t *cliptrace, const trace_t *trace, void *touch, qboolean isbmodel) +{ + // take the 'best' answers from the new trace and combine with existing data + if (trace->allsolid) + cliptrace->allsolid = true; + if (trace->startsolid) + { + if (isbmodel) + cliptrace->bmodelstartsolid = true; + cliptrace->startsolid = true; + if (cliptrace->realfraction == 1) + cliptrace->ent = touch; + } + // don't set this except on the world, because it can easily confuse + // monsters underwater if there's a bmodel involved in the trace + // (inopen && inwater is how they check water visibility) + //if (trace->inopen) + // cliptrace->inopen = true; + if (trace->inwater) + cliptrace->inwater = true; + if (trace->realfraction < cliptrace->realfraction) + { + cliptrace->fraction = trace->fraction; + cliptrace->realfraction = trace->realfraction; + VectorCopy(trace->endpos, cliptrace->endpos); + cliptrace->plane = trace->plane; + cliptrace->ent = touch; + cliptrace->hitsupercontents = trace->hitsupercontents; + cliptrace->hitq3surfaceflags = trace->hitq3surfaceflags; + cliptrace->hittexture = trace->hittexture; + } + cliptrace->startsupercontents |= trace->startsupercontents; +}