added generic collision functions Collision_ClipToGenericEntity, Collision_ClipToWorl...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 18 Feb 2007 12:47:17 +0000 (12:47 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 18 Feb 2007 12:47:17 +0000 (12:47 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6853 d7cf8633-e32d-0410-b094-e92efae38249

collision.c
collision.h

index 50812e5..0ccc1d1 100644 (file)
@@ -1456,3 +1456,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;
+}
index bb539f5..3dd3ba2 100644 (file)
@@ -117,6 +117,26 @@ void Collision_BoundingBoxOfBrushTraceSegment(const colbrushf_t *start, const co
 float Collision_ClipTrace_Line_Sphere(double *linestart, double *lineend, double *sphereorigin, double sphereradius, double *impactpoint, double *impactnormal);
 void Collision_TraceLineTriangleFloat(trace_t *trace, const vec3_t linestart, const vec3_t lineend, const float *point0, const float *point1, const float *point2, int supercontents, int q3surfaceflags, texture_t *texture);
 
+// traces a box move against a single entity
+// mins and maxs are relative
+//
+// if the entire move stays in a single solid brush, trace.allsolid will be set
+//
+// if the starting point is in a solid, it will be allowed to move out to an
+// open area, and trace.startsolid will be set
+//
+// type is one of the MOVE_ values such as MOVE_NOMONSTERS which skips box
+// entities, only colliding with SOLID_BSP entities (doors, lifts)
+//
+// passedict is excluded from clipping checks
+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);
+// like above but does not do a transform and does nothing if model is NULL
+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);
+// combines data from two traces:
+// merges contents flags, startsolid, allsolid, inwater
+// updates fraction, endpos, plane and surface info if new fraction is shorter
+void Collision_CombineTraces(trace_t *cliptrace, const trace_t *trace, void *touch, qboolean isbmodel);
+
 // this enables rather large debugging spew!
 // settings:
 // 0 = no spew