From 108503b6fc218025fa4e414636843948acdb87a4 Mon Sep 17 00:00:00 2001 From: havoc Date: Fri, 20 Feb 2009 17:50:03 +0000 Subject: [PATCH] report a proper trace_plane_normal for trace_startsolid cases, this allows QC physics code to nudge objects out of eachother using the shortest vector, only valid if trace_fraction is 1 (works best for stationary overlap tests) properly transform trace_plane_dist rather than returning 0 git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8749 d7cf8633-e32d-0410-b094-e92efae38249 --- collision.c | 17 ++++++++--------- matrixlib.c | 30 ++++++++++++++++++++++++++++++ matrixlib.h | 4 ++++ 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/collision.c b/collision.c index 73a1bd0a..331895ab 100644 --- a/collision.c +++ b/collision.c @@ -698,6 +698,7 @@ void Collision_TraceBrushBrushFloat(trace_t *trace, const colbrushf_t *thisbrush trace->startsolid = true; if (leavefrac < 1) trace->allsolid = true; + VectorCopy(newimpactnormal, trace->plane.normal); } } } @@ -819,6 +820,7 @@ void Collision_TraceLineBrushFloat(trace_t *trace, const vec3_t linestart, const trace->startsolid = true; if (leavefrac < 1) trace->allsolid = true; + VectorCopy(newimpactnormal, trace->plane.normal); } } } @@ -1467,7 +1469,7 @@ void Collision_BoundingBoxOfBrushTraceSegment(const colbrushf_t *start, const co void Collision_ClipToGenericEntity(trace_t *trace, dp_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]; + float starttransformed[3], endtransformed[3]; memset(trace, 0, sizeof(*trace)); trace->fraction = trace->realfraction = 1; @@ -1486,13 +1488,10 @@ void Collision_ClipToGenericEntity(trace_t *trace, dp_model_t *model, int frame, 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 - } + VectorLerp(start, trace->fraction, end, trace->endpos); + // transform plane + // NOTE: this relies on plane.dist being directly after plane.normal + Matrix4x4_TransformPositivePlane(matrix, trace->plane.normal[0], trace->plane.normal[1], trace->plane.normal[2], trace->plane.dist, trace->plane.normal); } void Collision_ClipToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontents) @@ -1526,7 +1525,7 @@ void Collision_CombineTraces(trace_t *cliptrace, const trace_t *trace, void *tou // cliptrace->inopen = true; if (trace->inwater) cliptrace->inwater = true; - if (trace->realfraction < cliptrace->realfraction) + if (trace->realfraction <= cliptrace->realfraction) { cliptrace->fraction = trace->fraction; cliptrace->realfraction = trace->realfraction; diff --git a/matrixlib.c b/matrixlib.c index 7b7bfad6..a0bf9c96 100644 --- a/matrixlib.c +++ b/matrixlib.c @@ -1241,6 +1241,36 @@ void Matrix4x4_Transform3x3 (const matrix4x4_t *in, const float v[3], float out[ #endif } +void Matrix4x4_TransformPositivePlane(const matrix4x4_t *in, float x, float y, float z, float d, float *o) +{ +#ifdef MATRIX4x4_OPENGLORIENTATION + o[0] = x * in->m[0][0] + y * in->m[1][0] + z * in->m[2][0]; + o[1] = x * in->m[0][1] + y * in->m[1][1] + z * in->m[2][1]; + o[2] = x * in->m[0][2] + y * in->m[1][2] + z * in->m[2][2]; + o[3] = d + (x * in->m[3][0] + y * in->m[3][1] + z * in->m[3][2]); +#else + o[0] = x * in->m[0][0] + y * in->m[0][1] + z * in->m[0][2]; + o[1] = x * in->m[1][0] + y * in->m[1][1] + z * in->m[1][2]; + o[2] = x * in->m[2][0] + y * in->m[2][1] + z * in->m[2][2]; + o[3] = d + (x * in->m[0][3] + y * in->m[1][3] + z * in->m[2][3]); +#endif +} + +void Matrix4x4_TransformStandardPlane(const matrix4x4_t *in, float x, float y, float z, float d, float *o) +{ +#ifdef MATRIX4x4_OPENGLORIENTATION + o[0] = x * in->m[0][0] + y * in->m[1][0] + z * in->m[2][0]; + o[1] = x * in->m[0][1] + y * in->m[1][1] + z * in->m[2][1]; + o[2] = x * in->m[0][2] + y * in->m[1][2] + z * in->m[2][2]; + o[3] = d - (x * in->m[3][0] + y * in->m[3][1] + z * in->m[3][2]); +#else + o[0] = x * in->m[0][0] + y * in->m[0][1] + z * in->m[0][2]; + o[1] = x * in->m[1][0] + y * in->m[1][1] + z * in->m[1][2]; + o[2] = x * in->m[2][0] + y * in->m[2][1] + z * in->m[2][2]; + o[3] = d - (x * in->m[0][3] + y * in->m[1][3] + z * in->m[2][3]); +#endif +} + /* void Matrix4x4_SimpleUntransform (const matrix4x4_t *in, const float v[3], float out[3]) { diff --git a/matrixlib.h b/matrixlib.h index 8e1e6537..8ddde538 100644 --- a/matrixlib.h +++ b/matrixlib.h @@ -124,6 +124,10 @@ void Matrix4x4_Transform4 (const matrix4x4_t *in, const float v[4], float out[4] //void Matrix4x4_SimpleUntransform (const matrix4x4_t *in, const float v[3], float out[3]); // transforms a direction vector through the rotation part of a matrix void Matrix4x4_Transform3x3 (const matrix4x4_t *in, const float v[3], float out[3]); +// transforms a positive distance plane (A*x+B*y+C*z-D=0) through a matrix +void Matrix4x4_TransformPositivePlane (const matrix4x4_t *in, float x, float y, float z, float d, float *o); +// transforms a standard plane (A*x+B*y+C*z+D=0) through a matrix +void Matrix4x4_TransformStandardPlane (const matrix4x4_t *in, float x, float y, float z, float d, float *o); // ease of use functions // immediately applies a Translate to the matrix -- 2.39.2