Make a fresh start on box clipping.

I even have a failing test to fix :)
This commit is contained in:
Bill Currie 2011-10-02 21:06:56 +09:00
parent 268e732b90
commit b4da9241f6
2 changed files with 51 additions and 3 deletions

View file

@ -118,6 +118,33 @@ hull_t hull_tppw = {
{0, 0, 0}, {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 { typedef struct {
vec3_t extents; vec3_t extents;
} box_t; } box_t;
@ -138,6 +165,7 @@ typedef struct {
} test_t; } test_t;
box_t point = { {0, 0, 0} }; box_t point = { {0, 0, 0} };
box_t box = { {8, 8, 8} };
box_t player = { {16, 16, 28} }; box_t player = { {16, 16, 28} };
test_t tests[] = { test_t tests[] = {
@ -177,6 +205,11 @@ test_t tests[] = {
{ 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 0, 1}}, { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 0, 1}},
{"Point, Three parallel planes with water", &point, &hull_tppw, {"Point, Three parallel planes with water", &point, &hull_tppw,
{ 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1}}, { 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])) #define num_tests (sizeof (tests) / sizeof (tests[0]))

View file

@ -61,6 +61,20 @@ typedef struct {
mplane_t *plane; mplane_t *plane;
} tracestack_t; } 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 static inline void
calc_impact (trace_t *trace, const vec3_t start, const vec3_t end, calc_impact (trace_t *trace, const vec3_t start, const vec3_t end,
mplane_t *plane) mplane_t *plane)
@ -92,7 +106,7 @@ MOD_TraceLine (hull_t *hull, int num,
const vec3_t start_point, const vec3_t end_point, const vec3_t start_point, const vec3_t end_point,
trace_t *trace) trace_t *trace)
{ {
vec_t start_dist, end_dist, frac; vec_t start_dist, end_dist, frac, offset;
vec3_t start, end, dist; vec3_t start, end, dist;
int side; int side;
qboolean seen_empty, seen_solid; qboolean seen_empty, seen_solid;
@ -164,13 +178,14 @@ MOD_TraceLine (hull_t *hull, int num,
start_dist = PlaneDiff (start, plane); start_dist = PlaneDiff (start, plane);
end_dist = PlaneDiff (end, 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 // entirely in front of the plane
num = node->children[0]; num = node->children[0];
continue; continue;
} }
if (start_dist < 0 && end_dist < 0) { if (start_dist < offset && end_dist < offset) {
// entirely behind the plane // entirely behind the plane
num = node->children[1]; num = node->children[1];
continue; continue;