#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
cvar_t collision_endposnudge = {0, "collision_endposnudge", "0", "workaround to fix trace_endpos sometimes being returned where it would be inside solid by making that collision hit (recommended: values like 1)"};
#endif
+cvar_t collision_debug_tracelineasbox = {0, "collision_debug_tracelineasbox", "0", "workaround for any bugs in Collision_TraceLineBrushFloat by using Collision_TraceBrushBrushFloat"};
void Collision_Init (void)
{
#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
Cvar_RegisterVariable(&collision_endposnudge);
#endif
+ Cvar_RegisterVariable(&collision_debug_tracelineasbox);
}
VectorSubtract(brush->points[i].v, brush->points[j].v, brush->edgedirs[j].v);
}
-colbrushf_t *Collision_NewBrushFromPlanes(mempool_t *mempool, int numoriginalplanes, const colplanef_t *originalplanes, int supercontents, int q3surfaceflags, texture_t *texture, int hasaabbplanes)
+colbrushf_t *Collision_NewBrushFromPlanes(mempool_t *mempool, int numoriginalplanes, const colplanef_t *originalplanes, int supercontents, int q3surfaceflags, const texture_t *texture, int hasaabbplanes)
{
// TODO: planesbuf could be replaced by a remapping table
int j, k, l, m, w, xyzflags;
}
}
-colbrushf_t *Collision_AllocBrushFromPermanentPolygonFloat(mempool_t *mempool, int numpoints, float *points, int supercontents, int q3surfaceflags, texture_t *texture)
+colbrushf_t *Collision_AllocBrushFromPermanentPolygonFloat(mempool_t *mempool, int numpoints, float *points, int supercontents, int q3surfaceflags, const texture_t *texture)
{
colbrushf_t *brush;
brush = (colbrushf_t *)Mem_Alloc(mempool, sizeof(colbrushf_t) + sizeof(colplanef_t) * (numpoints + 2) + sizeof(colpointf_t) * numpoints);
vec4_t startplane;
vec4_t endplane;
vec4_t newimpactplane;
- texture_t *hittexture = NULL;
+ const texture_t *hittexture = NULL;
vec_t startdepth = 1;
vec3_t startdepthnormal;
VectorCopy(startplane, startdepthnormal);
}
- if (startdist >= -collision_impactnudge.value && enddist >= startdist)
- return;
- if (startdist <= 0 && enddist <= 0)
- continue;
if (startdist > enddist)
{
// moving into brush
vec4_t startplane;
vec4_t endplane;
vec4_t newimpactplane;
- texture_t *hittexture = NULL;
+ const texture_t *hittexture = NULL;
vec_t startdepth = 1;
vec3_t startdepthnormal;
+ if (collision_debug_tracelineasbox.integer)
+ {
+ colboxbrushf_t thisbrush_start, thisbrush_end;
+ Collision_BrushForBox(&thisbrush_start, linestart, linestart, 0, 0, NULL);
+ Collision_BrushForBox(&thisbrush_end, lineend, lineend, 0, 0, NULL);
+ Collision_TraceBrushBrushFloat(trace, &thisbrush_start.brush, &thisbrush_end.brush, other_start, other_end);
+ return;
+ }
+
VectorClear(startdepthnormal);
Vector4Clear(newimpactplane);
VectorCopy(startplane, startdepthnormal);
}
- if (startdist >= -collision_impactnudge.value && enddist >= startdist)
- return;
- if (startdist <= 0 && enddist <= 0)
- continue;
if (startdist > enddist)
{
// moving into brush
}
}
-void Collision_TraceBrushTriangleMeshFloat(trace_t *trace, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, int numtriangles, const int *element3i, const float *vertex3f, int stride, float *bbox6f, int supercontents, int q3surfaceflags, texture_t *texture, const vec3_t segmentmins, const vec3_t segmentmaxs)
+void Collision_TraceBrushTriangleMeshFloat(trace_t *trace, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, int numtriangles, const int *element3i, const float *vertex3f, int stride, float *bbox6f, int supercontents, int q3surfaceflags, const texture_t *texture, const vec3_t segmentmins, const vec3_t segmentmaxs)
{
int i;
colpointf_t points[3];
}
}
-void Collision_TraceLineTriangleMeshFloat(trace_t *trace, const vec3_t linestart, const vec3_t lineend, int numtriangles, const int *element3i, const float *vertex3f, int stride, float *bbox6f, int supercontents, int q3surfaceflags, texture_t *texture, const vec3_t segmentmins, const vec3_t segmentmaxs)
+void Collision_TraceLineTriangleMeshFloat(trace_t *trace, const vec3_t linestart, const vec3_t lineend, int numtriangles, const int *element3i, const float *vertex3f, int stride, float *bbox6f, int supercontents, int q3surfaceflags, const texture_t *texture, const vec3_t segmentmins, const vec3_t segmentmaxs)
{
int i;
// FIXME: snap vertices?
}
}
-void Collision_BrushForBox(colboxbrushf_t *boxbrush, const vec3_t mins, const vec3_t maxs, int supercontents, int q3surfaceflags, texture_t *texture)
+void Collision_TraceBrushTriangleFloat(trace_t *trace, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, const float *v0, const float *v1, const float *v2, int supercontents, int q3surfaceflags, const texture_t *texture)
+{
+ int i;
+ colpointf_t points[3];
+ colpointf_t edgedirs[3];
+ colplanef_t planes[5];
+ colbrushf_t brush;
+ memset(&brush, 0, sizeof(brush));
+ brush.isaabb = false;
+ brush.hasaabbplanes = false;
+ brush.numpoints = 3;
+ brush.numedgedirs = 3;
+ brush.numplanes = 5;
+ brush.points = points;
+ brush.edgedirs = edgedirs;
+ brush.planes = planes;
+ brush.supercontents = supercontents;
+ brush.q3surfaceflags = q3surfaceflags;
+ brush.texture = texture;
+ for (i = 0;i < brush.numplanes;i++)
+ {
+ brush.planes[i].q3surfaceflags = q3surfaceflags;
+ brush.planes[i].texture = texture;
+ }
+ VectorCopy(v0, points[0].v);
+ VectorCopy(v1, points[1].v);
+ VectorCopy(v2, points[2].v);
+ Collision_SnapCopyPoints(brush.numpoints, points, points, COLLISION_SNAPSCALE, COLLISION_SNAP);
+ Collision_CalcEdgeDirsForPolygonBrushFloat(&brush);
+ Collision_CalcPlanesForPolygonBrushFloat(&brush);
+ //Collision_PrintBrushAsQHull(&brush, "brush");
+ Collision_TraceBrushBrushFloat(trace, thisbrush_start, thisbrush_end, &brush, &brush);
+}
+
+void Collision_BrushForBox(colboxbrushf_t *boxbrush, const vec3_t mins, const vec3_t maxs, int supercontents, int q3surfaceflags, const texture_t *texture)
{
int i;
memset(boxbrush, 0, sizeof(*boxbrush));
boxbrush->brush.texture = texture;
VectorSet(boxbrush->brush.mins, mins[0] - 1, mins[1] - 1, mins[2] - 1);
VectorSet(boxbrush->brush.maxs, maxs[0] + 1, maxs[1] + 1, maxs[2] + 1);
- Collision_ValidateBrush(&boxbrush->brush);
+ //Collision_ValidateBrush(&boxbrush->brush);
}
void Collision_ClipTrace_BrushBox(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, int supercontents, int q3surfaceflags, texture_t *texture)
return impactdist / linelength;
}
-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)
+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, const texture_t *texture)
{
#if 1
// more optimized
//===========================================
+void Collision_TranslateBrush(const vec3_t shift, colbrushf_t *brush)
+{
+ int i;
+ // now we can transform the data
+ for(i = 0; i < brush->numplanes; ++i)
+ {
+ brush->planes[i].dist += DotProduct(shift, brush->planes[i].normal);
+ }
+ for(i = 0; i < brush->numpoints; ++i)
+ {
+ VectorAdd(brush->points[i].v, shift, brush->points[i].v);
+ }
+ VectorAdd(brush->mins, shift, brush->mins);
+ VectorAdd(brush->maxs, shift, brush->maxs);
+}
+
+void Collision_TransformBrush(const matrix4x4_t *matrix, colbrushf_t *brush)
+{
+ int i;
+ vec3_t v;
+ // we're breaking any AABB properties here...
+ brush->isaabb = false;
+ brush->hasaabbplanes = false;
+ // now we can transform the data
+ for(i = 0; i < brush->numplanes; ++i)
+ {
+ Matrix4x4_TransformPositivePlane(matrix, brush->planes[i].normal[0], brush->planes[i].normal[1], brush->planes[i].normal[2], brush->planes[i].dist, brush->planes[i].normal);
+ }
+ for(i = 0; i < brush->numedgedirs; ++i)
+ {
+ Matrix4x4_Transform(matrix, brush->edgedirs[i].v, v);
+ VectorCopy(v, brush->edgedirs[i].v);
+ }
+ for(i = 0; i < brush->numpoints; ++i)
+ {
+ Matrix4x4_Transform(matrix, brush->points[i].v, v);
+ VectorCopy(v, brush->points[i].v);
+ }
+ VectorCopy(brush->points[0].v, brush->mins);
+ VectorCopy(brush->points[0].v, brush->maxs);
+ for(i = 1; i < brush->numpoints; ++i)
+ {
+ if(brush->points[i].v[0] < brush->mins[0]) brush->mins[0] = brush->points[i].v[0];
+ if(brush->points[i].v[1] < brush->mins[1]) brush->mins[1] = brush->points[i].v[1];
+ if(brush->points[i].v[2] < brush->mins[2]) brush->mins[2] = brush->points[i].v[2];
+ if(brush->points[i].v[0] > brush->maxs[0]) brush->maxs[0] = brush->points[i].v[0];
+ if(brush->points[i].v[1] > brush->maxs[1]) brush->maxs[1] = brush->points[i].v[1];
+ if(brush->points[i].v[2] > brush->maxs[2]) brush->maxs[2] = brush->points[i].v[2];
+ }
+}
+
void Collision_ClipToGenericEntity(trace_t *trace, dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, 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 starttransformed[3], endtransformed[3];
#endif
if (model && model->TraceBox)
- model->TraceBox(model, frameblend, skeleton, trace, starttransformed, mins, maxs, endtransformed, hitsupercontentsmask);
- else
+ {
+ if(model->TraceBrush && (inversematrix->m[0][1] || inversematrix->m[0][2] || inversematrix->m[1][0] || inversematrix->m[1][2] || inversematrix->m[2][0] || inversematrix->m[2][1]))
+ {
+ // we get here if TraceBrush exists, AND we have a rotation component (SOLID_BSP case)
+ // using starttransformed, endtransformed is WRONG in this case!
+ // should rather build a brush and trace using it
+ colboxbrushf_t thisbrush_start, thisbrush_end;
+ Collision_BrushForBox(&thisbrush_start, mins, maxs, 0, 0, NULL);
+ Collision_BrushForBox(&thisbrush_end, mins, maxs, 0, 0, NULL);
+ Collision_TranslateBrush(start, &thisbrush_start.brush);
+ Collision_TranslateBrush(end, &thisbrush_end.brush);
+ Collision_TransformBrush(inversematrix, &thisbrush_start.brush);
+ Collision_TransformBrush(inversematrix, &thisbrush_end.brush);
+ //Collision_TranslateBrush(starttransformed, &thisbrush_start.brush);
+ //Collision_TranslateBrush(endtransformed, &thisbrush_end.brush);
+ model->TraceBrush(model, frameblend, skeleton, trace, &thisbrush_start.brush, &thisbrush_end.brush, hitsupercontentsmask);
+ }
+ else // this is only approximate if rotated, quite useless
+ model->TraceBox(model, frameblend, skeleton, trace, starttransformed, mins, maxs, endtransformed, hitsupercontentsmask);
+ }
+ else // and this requires that the transformation matrix doesn't have angles components, like SV_TraceBox ensures; FIXME may get called if a model is SOLID_BSP but has no TraceBox function
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);
{
memset(trace, 0, sizeof(*trace));
trace->fraction = trace->realfraction = 1;
+ // ->TraceBox: TraceBrush not needed here, as worldmodel is never rotated
if (model && model->TraceBox)
model->TraceBox(model, NULL, NULL, trace, start, mins, maxs, end, hitsupercontents);
trace->fraction = bound(0, trace->fraction, 1);