report a proper trace_plane_normal for trace_startsolid cases, this
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 20 Feb 2009 17:50:03 +0000 (17:50 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 20 Feb 2009 17:50:03 +0000 (17:50 +0000)
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
matrixlib.c
matrixlib.h

index 73a1bd0..331895a 100644 (file)
@@ -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;
index 7b7bfad..a0bf9c9 100644 (file)
@@ -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])
 {
index 8e1e653..8ddde53 100644 (file)
@@ -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