X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=collision.c;h=7bfc9c25d0168d9fc4f3a07f93f7b8ae53314c0b;hb=7857d388ddfb0152d67d0e808d630f515e523740;hp=50812e5ec78b38ec0ce6144f84955c326c4941d3;hpb=d20775286cd10331bc845b0feac69f300c231524;p=xonotic%2Fdarkplaces.git diff --git a/collision.c b/collision.c index 50812e5e..7bfc9c25 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; @@ -883,12 +889,7 @@ void Collision_TraceBrushTriangleMeshFloat(trace_t *trace, const colbrushf_t *th } for (i = 0;i < numtriangles;i++, element3i += 3) { - if (segmentmaxs[0] >= min(vertex3f[element3i[0]*3+0], min(vertex3f[element3i[1]*3+0], vertex3f[element3i[2]*3+0])) - && segmentmins[0] <= max(vertex3f[element3i[0]*3+0], max(vertex3f[element3i[1]*3+0], vertex3f[element3i[2]*3+0])) - && segmentmaxs[1] >= min(vertex3f[element3i[0]*3+1], min(vertex3f[element3i[1]*3+1], vertex3f[element3i[2]*3+1])) - && segmentmins[1] <= max(vertex3f[element3i[0]*3+1], max(vertex3f[element3i[1]*3+1], vertex3f[element3i[2]*3+1])) - && segmentmaxs[2] >= min(vertex3f[element3i[0]*3+2], min(vertex3f[element3i[1]*3+2], vertex3f[element3i[2]*3+2])) - && segmentmins[2] <= max(vertex3f[element3i[0]*3+2], max(vertex3f[element3i[1]*3+2], vertex3f[element3i[2]*3+2]))) + if (TriangleOverlapsBox(vertex3f + element3i[0]*3, vertex3f + element3i[1]*3, vertex3f + element3i[2]*3, segmentmins, segmentmaxs)) { VectorCopy(vertex3f + element3i[0] * 3, polyf_points[0].v); VectorCopy(vertex3f + element3i[1] * 3, polyf_points[1].v); @@ -941,12 +942,7 @@ void Collision_TraceLineTriangleMeshFloat(trace_t *trace, const vec3_t linestart } for (i = 0;i < numtriangles;i++, element3i += 3) { - if (segmentmaxs[0] >= min(vertex3f[element3i[0]*3+0], min(vertex3f[element3i[1]*3+0], vertex3f[element3i[2]*3+0])) - && segmentmins[0] <= max(vertex3f[element3i[0]*3+0], max(vertex3f[element3i[1]*3+0], vertex3f[element3i[2]*3+0])) - && segmentmaxs[1] >= min(vertex3f[element3i[0]*3+1], min(vertex3f[element3i[1]*3+1], vertex3f[element3i[2]*3+1])) - && segmentmins[1] <= max(vertex3f[element3i[0]*3+1], max(vertex3f[element3i[1]*3+1], vertex3f[element3i[2]*3+1])) - && segmentmaxs[2] >= min(vertex3f[element3i[0]*3+2], min(vertex3f[element3i[1]*3+2], vertex3f[element3i[2]*3+2])) - && segmentmins[2] <= max(vertex3f[element3i[0]*3+2], max(vertex3f[element3i[1]*3+2], vertex3f[element3i[2]*3+2]))) + if (TriangleOverlapsBox(vertex3f + element3i[0]*3, vertex3 + [element3i[1]*3, vertex3f + element3i[2]*3, segmentmins, segmentmaxs)) { VectorCopy(vertex3f + element3i[0] * 3, polyf_points[0].v); VectorCopy(vertex3f + element3i[1] * 3, polyf_points[1].v); @@ -1149,7 +1145,7 @@ float Collision_ClipTrace_Line_Sphere(double *linestart, double *lineend, double if (deviationdist > sphereradius*sphereradius) return 1; // miss (off to the side) // nudge back to find the correct impact distance - impactdist += deviationdist - sphereradius; + impactdist -= sphereradius - deviationdist/sphereradius; if (impactdist >= linelength) return 1; // miss (not close enough) if (impactdist < 0) @@ -1456,3 +1452,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; +}