diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index a29c57888..d4dfd4734 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -118,6 +118,33 @@ hull_t hull_tppw = { {0, 0, 0}, }; +// 2 +// eee|eee +// 0,32+--- 1 +// eee|sss +// ---+--- 0 +// ss0,0ss +mclipnode_t clipnodes_step1[] = { + { 0, { 1, CONTENTS_SOLID}}, + { 1, {CONTENTS_EMPTY, 2}}, + { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, +}; + +mplane_t planes_step1[] = { + {{0, 0, 1}, 0, 2, 0}, + {{0, 0, 1}, 32, 2, 0}, + {{1, 0, 0}, 0, 0, 0}, +}; + +hull_t hull_step1 = { + clipnodes_step1, + planes_step1, + 0, + 2, + {0, 0, 0}, + {0, 0, 0}, +}; + typedef struct { vec3_t extents; } box_t; @@ -138,6 +165,7 @@ typedef struct { } test_t; box_t point = { {0, 0, 0} }; +box_t box = { {8, 8, 8} }; box_t player = { {16, 16, 28} }; test_t tests[] = { @@ -177,6 +205,11 @@ test_t tests[] = { { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 0, 1}}, {"Point, Three parallel planes with water", &point, &hull_tppw, { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1}}, + + {"Point, Step 1", &point, &hull_step1, + { -16, 0, 8}, {16, 0, 24}, { 0.5, 0, 0, 1, 0}}, + {"Box, Step 1", &box, &hull_step1, + { -16, 0, 8}, {16, 0, 24}, { 0.25, 0, 0, 1, 0}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) diff --git a/libs/models/trace.c b/libs/models/trace.c index 1cb02d00a..ded4eab41 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -61,6 +61,20 @@ typedef struct { mplane_t *plane; } tracestack_t; +static inline float +calc_offset (trace_t *trace, mplane_t *plane) +{ + if (trace->isbox) { + if (plane->type < 3) + return trace->extents[plane->type]; + else + return (fabs (trace->extents[0] * plane->normal[0]) + + fabs (trace->extents[1] * plane->normal[1]) + + fabs (trace->extents[2] * plane->normal[2])); + } + return 0; +} + static inline void calc_impact (trace_t *trace, const vec3_t start, const vec3_t end, mplane_t *plane) @@ -92,7 +106,7 @@ MOD_TraceLine (hull_t *hull, int num, const vec3_t start_point, const vec3_t end_point, trace_t *trace) { - vec_t start_dist, end_dist, frac; + vec_t start_dist, end_dist, frac, offset; vec3_t start, end, dist; int side; qboolean seen_empty, seen_solid; @@ -164,13 +178,14 @@ MOD_TraceLine (hull_t *hull, int num, start_dist = PlaneDiff (start, plane); end_dist = PlaneDiff (end, plane); + offset = calc_offset (trace, plane); - if (start_dist >= 0 && end_dist >= 0) { + if (start_dist >= offset && end_dist >= offset) { // entirely in front of the plane num = node->children[0]; continue; } - if (start_dist < 0 && end_dist < 0) { + if (start_dist < offset && end_dist < offset) { // entirely behind the plane num = node->children[1]; continue;