2010-12-06 06:30:56 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include "QF/va.h"
|
|
|
|
|
|
|
|
#include "getopt.h"
|
|
|
|
#include "world.h"
|
|
|
|
|
|
|
|
#undef DIST_EPSILON
|
|
|
|
#define DIST_EPSILON 0
|
|
|
|
|
|
|
|
#ifdef TEST_ID
|
|
|
|
# include "trace-id.c"
|
2011-09-27 08:09:04 +00:00
|
|
|
#elif defined(TEST_QF_BAD)
|
|
|
|
# include "trace-qf-bad.c"
|
2010-12-06 06:30:56 +00:00
|
|
|
#else
|
2011-06-12 07:12:52 +00:00
|
|
|
# include "../trace.c"
|
2010-12-06 06:30:56 +00:00
|
|
|
#endif
|
|
|
|
|
2011-09-27 03:30:21 +00:00
|
|
|
// 0,0
|
|
|
|
// |\ .
|
|
|
|
// |s\ .
|
|
|
|
// |ss\ .
|
|
|
|
// 0 1
|
|
|
|
|
2011-06-12 08:03:51 +00:00
|
|
|
mclipnode_t clipnodes_simple_wedge[] = {
|
2011-09-26 09:52:59 +00:00
|
|
|
{ 0, { 1, CONTENTS_EMPTY}},
|
|
|
|
{ 1, {CONTENTS_EMPTY, CONTENTS_SOLID}},
|
2010-12-06 06:30:56 +00:00
|
|
|
};
|
|
|
|
|
2011-11-14 06:46:39 +00:00
|
|
|
plane_t planes_simple_wedge[] = {
|
2010-12-06 06:30:56 +00:00
|
|
|
{{1, 0, 0}, 0, 0, 0}, // 0
|
|
|
|
{{0.8, 0, 0.6}, 0, 4, 0}, // 1
|
|
|
|
};
|
|
|
|
|
2011-06-12 08:03:51 +00:00
|
|
|
hull_t hull_simple_wedge = {
|
|
|
|
clipnodes_simple_wedge,
|
|
|
|
planes_simple_wedge,
|
2010-12-06 06:30:56 +00:00
|
|
|
0,
|
|
|
|
1,
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
};
|
|
|
|
|
2011-09-27 03:30:21 +00:00
|
|
|
// -32 32 48
|
|
|
|
// sss|sss| |sss
|
|
|
|
// sss|sss| |sss
|
|
|
|
// 0 1 2
|
|
|
|
|
2011-06-12 08:03:51 +00:00
|
|
|
mclipnode_t clipnodes_tpp1[] = {
|
2011-09-26 09:52:59 +00:00
|
|
|
{ 0, { 1, CONTENTS_SOLID}},
|
|
|
|
{ 1, { 2, CONTENTS_SOLID}},
|
|
|
|
{ 2, {CONTENTS_SOLID, CONTENTS_EMPTY}},
|
2010-12-06 06:30:56 +00:00
|
|
|
};
|
|
|
|
|
2011-11-14 06:46:39 +00:00
|
|
|
plane_t planes_tpp1[] = {
|
2010-12-06 06:30:56 +00:00
|
|
|
{{1, 0, 0}, -32, 0, 0},
|
|
|
|
{{1, 0, 0}, 32, 0, 0},
|
|
|
|
{{1, 0, 0}, 48, 0, 0},
|
|
|
|
};
|
|
|
|
|
2011-06-12 08:03:51 +00:00
|
|
|
hull_t hull_tpp1 = {
|
|
|
|
clipnodes_tpp1,
|
|
|
|
planes_tpp1,
|
2010-12-06 06:30:56 +00:00
|
|
|
0,
|
|
|
|
2,
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
};
|
|
|
|
|
2011-09-27 03:30:21 +00:00
|
|
|
// -32 32 48
|
|
|
|
// sss|sss| |sss
|
|
|
|
// sss|sss| |sss
|
|
|
|
// 1 0 2
|
|
|
|
|
2011-06-12 08:03:51 +00:00
|
|
|
mclipnode_t clipnodes_tpp2[] = {
|
2011-09-26 09:52:59 +00:00
|
|
|
{ 0, { 2, 1}},
|
|
|
|
{ 1, {CONTENTS_SOLID, CONTENTS_SOLID}},
|
|
|
|
{ 2, {CONTENTS_SOLID, CONTENTS_EMPTY}},
|
2010-12-06 06:30:56 +00:00
|
|
|
};
|
|
|
|
|
2011-11-14 06:46:39 +00:00
|
|
|
plane_t planes_tpp2[] = {
|
2010-12-06 06:30:56 +00:00
|
|
|
{{1, 0, 0}, 32, 0, 0},
|
|
|
|
{{1, 0, 0}, -32, 0, 0},
|
|
|
|
{{1, 0, 0}, 48, 0, 0},
|
|
|
|
};
|
|
|
|
|
2011-06-12 08:03:51 +00:00
|
|
|
hull_t hull_tpp2 = {
|
|
|
|
clipnodes_tpp2,
|
|
|
|
planes_tpp2,
|
2010-12-06 06:30:56 +00:00
|
|
|
0,
|
|
|
|
2,
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
};
|
|
|
|
|
2011-09-27 03:30:21 +00:00
|
|
|
// -32 32 48
|
|
|
|
// sss| |www|sss
|
|
|
|
// sss| |www|sss
|
|
|
|
// 1 0 2
|
|
|
|
|
2011-06-12 08:03:51 +00:00
|
|
|
mclipnode_t clipnodes_tppw[] = {
|
2011-09-26 12:02:54 +00:00
|
|
|
{ 0, { 2, 1}},
|
2011-09-27 08:11:57 +00:00
|
|
|
{ 1, {CONTENTS_EMPTY, CONTENTS_SOLID}},
|
2011-09-26 12:02:54 +00:00
|
|
|
{ 2, {CONTENTS_SOLID, CONTENTS_WATER}},
|
|
|
|
};
|
|
|
|
|
2011-11-14 06:46:39 +00:00
|
|
|
plane_t planes_tppw[] = {
|
2011-09-26 12:02:54 +00:00
|
|
|
{{1, 0, 0}, 32, 0, 0},
|
|
|
|
{{1, 0, 0}, -32, 0, 0},
|
|
|
|
{{1, 0, 0}, 48, 0, 0},
|
|
|
|
};
|
|
|
|
|
2011-06-12 08:03:51 +00:00
|
|
|
hull_t hull_tppw = {
|
|
|
|
clipnodes_tppw,
|
|
|
|
planes_tppw,
|
2011-09-26 12:02:54 +00:00
|
|
|
0,
|
|
|
|
2,
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
};
|
|
|
|
|
2011-10-02 12:06:56 +00:00
|
|
|
// 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}},
|
|
|
|
};
|
|
|
|
|
2011-11-14 06:46:39 +00:00
|
|
|
plane_t planes_step1[] = {
|
2011-10-02 12:06:56 +00:00
|
|
|
{{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},
|
|
|
|
};
|
|
|
|
|
2011-11-12 12:30:45 +00:00
|
|
|
// 0
|
2011-11-12 11:42:44 +00:00
|
|
|
// eee|eee
|
|
|
|
// 0,32+--- 1
|
|
|
|
// eee|sss
|
2011-11-12 12:30:45 +00:00
|
|
|
// ---+sss 2
|
|
|
|
// ss0,0ss
|
|
|
|
mclipnode_t clipnodes_step2[] = {
|
|
|
|
{ 0, { 1, 2}},
|
|
|
|
{ 1, {CONTENTS_EMPTY, CONTENTS_SOLID}},
|
|
|
|
{ 2, {CONTENTS_EMPTY, CONTENTS_SOLID}},
|
|
|
|
};
|
|
|
|
|
2011-11-14 06:46:39 +00:00
|
|
|
plane_t planes_step2[] = {
|
2011-11-12 12:30:45 +00:00
|
|
|
{{1, 0, 0}, 0, 0, 0},
|
|
|
|
{{0, 0, 1}, 32, 2, 0},
|
|
|
|
{{0, 0, 1}, 0, 2, 0},
|
|
|
|
};
|
|
|
|
|
|
|
|
hull_t hull_step2 = {
|
|
|
|
clipnodes_step2,
|
|
|
|
planes_step2,
|
|
|
|
0,
|
|
|
|
2,
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
};
|
|
|
|
|
|
|
|
// 0
|
|
|
|
// eee|eee
|
|
|
|
// 2---+0,32
|
|
|
|
// sss|eee
|
|
|
|
// sss+--- 1
|
|
|
|
// ss0,0ss
|
|
|
|
mclipnode_t clipnodes_step3[] = {
|
|
|
|
{ 0, { 1, 2}},
|
|
|
|
{ 1, {CONTENTS_EMPTY, CONTENTS_SOLID}},
|
|
|
|
{ 2, {CONTENTS_EMPTY, CONTENTS_SOLID}},
|
|
|
|
};
|
|
|
|
|
2011-11-14 06:46:39 +00:00
|
|
|
plane_t planes_step3[] = {
|
2011-11-12 12:30:45 +00:00
|
|
|
{{1, 0, 0}, 0, 0, 0},
|
|
|
|
{{0, 0, 1}, 0, 2, 0},
|
|
|
|
{{0, 0, 1}, 32, 2, 0},
|
|
|
|
};
|
|
|
|
|
|
|
|
hull_t hull_step3 = {
|
|
|
|
clipnodes_step3,
|
|
|
|
planes_step3,
|
|
|
|
0,
|
|
|
|
2,
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
};
|
|
|
|
|
|
|
|
// 3 2
|
|
|
|
// s|e|eee
|
|
|
|
// 4-+e|-20,40
|
|
|
|
// e|e|eee
|
|
|
|
// 0,32+--- 1
|
|
|
|
// eee|sss
|
2011-11-12 11:42:44 +00:00
|
|
|
// ---+--- 0
|
|
|
|
// ss0,0ss
|
|
|
|
mclipnode_t clipnodes_covered_step[] = {
|
|
|
|
{ 0, { 1, CONTENTS_SOLID}},
|
|
|
|
{ 1, { 3, 2}},
|
|
|
|
{ 2, {CONTENTS_SOLID, CONTENTS_EMPTY}},
|
|
|
|
{ 3, {CONTENTS_EMPTY, 4}},
|
|
|
|
{ 4, {CONTENTS_SOLID, CONTENTS_EMPTY}},
|
|
|
|
};
|
|
|
|
|
2011-11-14 06:46:39 +00:00
|
|
|
plane_t planes_covered_step[] = {
|
2011-11-12 11:42:44 +00:00
|
|
|
{{0, 0, 1}, 0, 2, 0},
|
|
|
|
{{0, 0, 1}, 32, 2, 0},
|
|
|
|
{{1, 0, 0}, 0, 0, 0},
|
|
|
|
{{1, 0, 0}, -20, 0, 0},
|
|
|
|
{{0, 0, 1}, 40, 2, 0},
|
|
|
|
};
|
|
|
|
|
|
|
|
hull_t hull_covered_step = {
|
|
|
|
clipnodes_covered_step,
|
|
|
|
planes_covered_step,
|
|
|
|
0,
|
|
|
|
4,
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
};
|
|
|
|
|
2011-11-14 00:26:31 +00:00
|
|
|
// 0
|
|
|
|
// eee|eee
|
|
|
|
// eee+--- 1
|
|
|
|
// ee/0,0s
|
|
|
|
// 2 ssss
|
|
|
|
mclipnode_t clipnodes_ramp[] = {
|
|
|
|
{ 0, { 1, 2}},
|
|
|
|
{ 1, {CONTENTS_EMPTY, CONTENTS_SOLID}},
|
|
|
|
{ 2, {CONTENTS_EMPTY, CONTENTS_SOLID}},
|
|
|
|
};
|
|
|
|
|
2011-11-14 06:46:39 +00:00
|
|
|
plane_t planes_ramp[] = {
|
2011-11-14 00:26:31 +00:00
|
|
|
{{ 1, 0, 0}, 0, 0, 0},
|
|
|
|
{{ 0, 0, 1}, 0, 2, 0},
|
|
|
|
{{-0.6, 0, 0.8}, 0, 4, 0},
|
|
|
|
};
|
|
|
|
|
|
|
|
hull_t hull_ramp = {
|
|
|
|
clipnodes_ramp,
|
|
|
|
planes_ramp,
|
|
|
|
0,
|
|
|
|
2,
|
|
|
|
{0, 0, 0},
|
|
|
|
{0, 0, 0},
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-12-06 06:30:56 +00:00
|
|
|
typedef struct {
|
|
|
|
vec3_t extents;
|
|
|
|
} box_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
const char *desc;
|
|
|
|
box_t *box;
|
|
|
|
hull_t *hull;
|
|
|
|
vec3_t start;
|
|
|
|
vec3_t end;
|
|
|
|
struct {
|
|
|
|
float frac;
|
|
|
|
qboolean allsolid;
|
|
|
|
qboolean startsolid;
|
|
|
|
qboolean inopen;
|
|
|
|
qboolean inwater;
|
2011-11-15 03:57:08 +00:00
|
|
|
int num_portals;
|
2010-12-06 06:30:56 +00:00
|
|
|
} expect;
|
|
|
|
} test_t;
|
|
|
|
|
|
|
|
box_t point = { {0, 0, 0} };
|
2011-10-02 12:06:56 +00:00
|
|
|
box_t box = { {8, 8, 8} };
|
2010-12-06 06:30:56 +00:00
|
|
|
box_t player = { {16, 16, 28} };
|
|
|
|
|
|
|
|
test_t tests[] = {
|
2011-06-12 08:03:51 +00:00
|
|
|
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
2011-11-15 03:57:08 +00:00
|
|
|
{-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 0, 0, 0}, { 0, 8, 0}, { 1, 1, 1, 0, 0, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 1, 0, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
|
|
|
|
{"Point, Three parallel planes 2", &point, &hull_tpp2,
|
2011-11-15 03:57:08 +00:00
|
|
|
{-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
{"Point, Three parallel planes 2", &point, &hull_tpp2,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
{"Point, Three parallel planes 2", &point, &hull_tpp2,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
{"Point, Three parallel planes 2", &point, &hull_tpp2,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
|
|
|
|
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
2011-11-15 03:57:08 +00:00
|
|
|
{-64, 0, 0}, { 64, 0, 0}, { 0.875, 0, 1, 1, 1, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 40, 0, 0}, {-88, 0, 0}, {0.5625, 0, 0, 1, 1, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 0, 1, 1, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 0, 0, 0}, { 0, 8, 0}, { 1, 0, 0, 1, 0, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 0, 1, 3}},
|
2011-06-12 08:03:51 +00:00
|
|
|
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1, 3}},
|
2011-10-02 12:06:56 +00:00
|
|
|
|
|
|
|
{"Point, Step 1", &point, &hull_step1,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ -16, 0, 8}, {16, 0, 24}, { 0.5, 0, 0, 1, 0, 5}},
|
2011-10-02 12:06:56 +00:00
|
|
|
{"Box, Step 1", &box, &hull_step1,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ -16, 0, 8}, {16, 0, 24}, { 0.25, 0, 0, 1, 0, 5}},
|
2011-11-12 09:12:56 +00:00
|
|
|
{"Box, Step 1", &box, &hull_step1,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ -16, 0, 8}, {16, 0, 40}, { 0.25, 0, 0, 1, 0, 5}},
|
2011-11-12 09:53:05 +00:00
|
|
|
{"Box, Step 1", &box, &hull_step1,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ -16, 0, 8}, {16, 0, 135}, { 0.25, 0, 0, 1, 0, 5}},
|
2011-11-12 09:53:05 +00:00
|
|
|
// 136 is a corner case caused by back/front side issues and 0
|
|
|
|
{"Box, Step 1", &box, &hull_step1,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ -16, 0, 8}, {16, 0, 137}, { 1, 0, 0, 1, 0, 5}},
|
2011-11-12 11:42:44 +00:00
|
|
|
|
|
|
|
{"Point, Covered Step", &point, &hull_covered_step,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ -24, 0, 8}, {-24, 0, 72}, { 0.5, 0, 0, 1, 0, 9}},
|
2011-11-12 11:42:44 +00:00
|
|
|
{"Box, Covered Step", &box, &hull_covered_step,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ -32, 0, 8}, {-32, 0, 72}, { 0.375, 0, 0, 1, 0, 9}},
|
2011-11-12 11:42:44 +00:00
|
|
|
{"Box, Covered Step", &box, &hull_covered_step,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ -24, 0, 8}, {-24, 0, 72}, { 0.375, 0, 0, 1, 0, 9}},
|
2011-11-12 11:42:44 +00:00
|
|
|
{"Box, Covered Step", &box, &hull_covered_step,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ -25, 0, 8}, {7, 0, 72}, { 0.375, 0, 0, 1, 0, 9}},
|
2011-11-12 12:30:45 +00:00
|
|
|
{"Box, Covered Step", &box, &hull_covered_step,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ -8, 0, 40}, {-16, 0, 40}, { 0.5, 0, 0, 1, 0, 9}},
|
2011-11-12 12:30:45 +00:00
|
|
|
{"Box, Covered Step", &box, &hull_covered_step,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ -17, 0, 8}, {-1, 0, 72}, { 1, 0, 0, 1, 0, 9}},
|
2011-11-12 11:42:44 +00:00
|
|
|
{"Box, Covered Step", &box, &hull_covered_step,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ -8, 0, 40}, {8, 0, 72}, { 1, 0, 0, 1, 0, 9}},
|
2011-11-12 12:30:45 +00:00
|
|
|
|
|
|
|
{"Box, Step 2", &box, &hull_step2,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0, 5}},
|
2011-11-12 12:30:45 +00:00
|
|
|
{"Box, Step 3", &box, &hull_step3,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0, 5}},
|
2011-11-14 00:26:31 +00:00
|
|
|
|
|
|
|
{"Box, Ramp", &box, &hull_ramp,
|
2011-11-15 03:57:08 +00:00
|
|
|
{ 0, 0, 16}, {0, 0, 0}, { 0.5, 0, 0, 1, 0, 4}},
|
2010-12-06 06:30:56 +00:00
|
|
|
};
|
|
|
|
#define num_tests (sizeof (tests) / sizeof (tests[0]))
|
|
|
|
|
|
|
|
static int test_enabled[num_tests] = { 0 };
|
|
|
|
|
|
|
|
int verbose = 0;
|
|
|
|
|
|
|
|
static trace_t
|
|
|
|
do_trace (box_t *box, hull_t *hull, vec3_t start, vec3_t end)
|
|
|
|
{
|
|
|
|
trace_t trace;
|
|
|
|
|
|
|
|
trace.allsolid = true;
|
|
|
|
trace.startsolid = false;
|
|
|
|
trace.inopen = false;
|
|
|
|
trace.inwater = false;
|
|
|
|
trace.fraction = 1;
|
|
|
|
VectorCopy (box->extents, trace.extents);
|
2011-11-20 03:02:56 +00:00
|
|
|
// FIXME specify tract type in test spec
|
|
|
|
trace.type = box == &point ? tr_point : tr_box;
|
2010-12-06 06:30:56 +00:00
|
|
|
VectorCopy (end, trace.endpos);
|
|
|
|
MOD_TraceLine (hull, 0, start, end, &trace);
|
|
|
|
return trace;
|
|
|
|
}
|
|
|
|
|
2011-11-15 03:57:08 +00:00
|
|
|
typedef struct portlist_s {
|
|
|
|
struct portlist_s *next;
|
|
|
|
clipport_t *portal;
|
|
|
|
} portlist_t;
|
|
|
|
|
|
|
|
static portlist_t *
|
|
|
|
collect_portals (clipport_t *portal, portlist_t *portal_list)
|
|
|
|
{
|
|
|
|
portlist_t *p;
|
|
|
|
|
|
|
|
if (!portal)
|
|
|
|
return portal_list;
|
|
|
|
for (p = portal_list; p; p = p->next)
|
|
|
|
if (p->portal == portal)
|
|
|
|
return portal_list;
|
|
|
|
p = malloc (sizeof (portlist_t));
|
|
|
|
p->portal = portal;
|
|
|
|
p->next = portal_list;
|
|
|
|
portal_list = p;
|
|
|
|
portal_list = collect_portals (portal->next[0], portal_list);
|
|
|
|
portal_list = collect_portals (portal->next[1], portal_list);
|
|
|
|
return portal_list;
|
|
|
|
}
|
|
|
|
|
2010-12-06 06:30:56 +00:00
|
|
|
static int
|
|
|
|
run_test (test_t *test)
|
|
|
|
{
|
|
|
|
const char *desc;
|
|
|
|
vec3_t end;
|
|
|
|
int res = 0;
|
|
|
|
char *expect;
|
|
|
|
char *got;
|
|
|
|
static int output = 0;
|
2011-11-15 03:57:08 +00:00
|
|
|
portlist_t *portal_list = 0;
|
|
|
|
|
|
|
|
if (!test->hull->nodeleafs) {
|
|
|
|
hull_t *hull = test->hull;
|
|
|
|
int i, j;
|
|
|
|
portlist_t *p;
|
|
|
|
clipport_t *portal;
|
|
|
|
clipleaf_t *leaf;
|
|
|
|
int side;
|
|
|
|
|
|
|
|
hull->nodeleafs = MOD_BuildBrushes (hull);
|
|
|
|
for (i = hull->firstclipnode; i <= hull->lastclipnode; i++) {
|
|
|
|
for (j = 0; j < 2; j++) {
|
|
|
|
if (((hull->clipnodes[i].children[j] >= 0)
|
|
|
|
!= (!hull->nodeleafs[i].leafs[j]))
|
|
|
|
|| (hull->nodeleafs[i].leafs[j]
|
|
|
|
&& (hull->nodeleafs[i].leafs[j]->contents
|
|
|
|
!= hull->clipnodes[i].children[j]))) {
|
|
|
|
printf ("bad nodeleaf %d %d\n", i, j);
|
|
|
|
res = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (hull->nodeleafs[i].leafs[0]
|
|
|
|
&& (hull->nodeleafs[i].leafs[0]
|
|
|
|
== hull->nodeleafs[i].leafs[1])) {
|
|
|
|
printf ("bad nodeleaf %d %d\n", i, j);
|
|
|
|
res = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (res)
|
|
|
|
goto nodeleaf_bail;
|
|
|
|
for (i = hull->firstclipnode; i <= hull->lastclipnode; i++) {
|
|
|
|
for (j = 0; j < 2; j++) {
|
|
|
|
leaf = hull->nodeleafs[i].leafs[j];
|
|
|
|
if (!leaf)
|
|
|
|
continue;
|
|
|
|
portal_list = collect_portals (leaf->portals, portal_list);
|
|
|
|
}
|
|
|
|
}
|
2011-11-15 11:21:49 +00:00
|
|
|
for (i = 0, p = portal_list; p; i++, p = p->next) {
|
|
|
|
if (!p->portal->winding || !p->portal->edges) {
|
|
|
|
res = 1;
|
|
|
|
printf ("portal with missing vertex/edge information\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (res)
|
|
|
|
goto nodeleaf_bail;
|
2011-11-15 03:57:08 +00:00
|
|
|
if (i != test->expect.num_portals) {
|
|
|
|
res = 1;
|
|
|
|
printf ("bad portal count: %d %d\n", test->expect.num_portals, i);
|
|
|
|
goto nodeleaf_bail;
|
|
|
|
}
|
|
|
|
for (p = portal_list; p; p = p->next) {
|
|
|
|
for (j = 0; j < 2; j++) {
|
|
|
|
int found = 0;
|
|
|
|
|
|
|
|
leaf = p->portal->leafs[j];
|
|
|
|
for (portal = leaf->portals; portal;
|
|
|
|
portal = portal->next[side]) {
|
|
|
|
//printf("%p %d %p %p %p\n", p, j, leaf, portal, p->portal);
|
|
|
|
side = portal->leafs[1] == leaf;
|
|
|
|
if (!side && portal->leafs[0] != leaf) {
|
|
|
|
printf ("mislinked portal\n");
|
|
|
|
res = 1;
|
|
|
|
}
|
|
|
|
if (portal == p->portal)
|
|
|
|
found = 1;
|
|
|
|
}
|
|
|
|
if (!found) {
|
|
|
|
printf ("portal unreachable from leaf\n");
|
|
|
|
res = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nodeleaf_bail:
|
|
|
|
while (portal_list) {
|
|
|
|
portlist_t *t = portal_list;
|
|
|
|
portal_list = portal_list->next;
|
|
|
|
free (t);
|
|
|
|
}
|
2010-12-06 06:30:56 +00:00
|
|
|
|
|
|
|
VectorSubtract (test->end, test->start, end);
|
|
|
|
VectorMultAdd (test->start, test->expect.frac, end, end);
|
|
|
|
expect = nva ("expect: (%g %g %g) -> (%g %g %g) => (%g %g %g)"
|
|
|
|
" %3g %d %d %d %d",
|
|
|
|
test->start[0], test->start[1], test->start[2],
|
|
|
|
test->end[0], test->end[1], test->end[2],
|
|
|
|
end[0], end[1], end[2],
|
|
|
|
test->expect.frac,
|
|
|
|
test->expect.allsolid, test->expect.startsolid,
|
|
|
|
test->expect.inopen, test->expect.inwater);
|
|
|
|
trace_t trace = do_trace (test->box, test->hull, test->start, test->end);
|
|
|
|
got = nva (" got: (%g %g %g) -> (%g %g %g) => (%g %g %g)"
|
|
|
|
" %3g %d %d %d %d",
|
|
|
|
test->start[0], test->start[1], test->start[2],
|
|
|
|
test->end[0], test->end[1], test->end[2],
|
|
|
|
trace.endpos[0], trace.endpos[1], trace.endpos[2],
|
|
|
|
trace.fraction,
|
|
|
|
trace.allsolid, trace.startsolid,
|
|
|
|
trace.inopen, trace.inwater);
|
|
|
|
if (VectorCompare (end, trace.endpos)
|
|
|
|
&& test->expect.frac == trace.fraction
|
|
|
|
&& test->expect.allsolid == trace.allsolid
|
|
|
|
&& test->expect.startsolid == trace.startsolid
|
|
|
|
&& test->expect.inopen == trace.inopen
|
|
|
|
&& test->expect.inwater == trace.inwater)
|
|
|
|
res = 1;
|
|
|
|
|
|
|
|
if (test->desc)
|
|
|
|
desc = va ("(%d) %s", (int)(long)(test - tests), test->desc);
|
|
|
|
else
|
|
|
|
desc = va ("test #%d", (int)(long)(test - tests));
|
|
|
|
if (verbose >= 0 || !res) {
|
|
|
|
if (output)
|
|
|
|
puts("");
|
|
|
|
output = 1;
|
|
|
|
puts (expect);
|
|
|
|
puts (got);
|
|
|
|
printf ("%s: %s\n", res ? "PASS" : "FAIL", desc);
|
|
|
|
}
|
|
|
|
free (expect);
|
|
|
|
free (got);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main (int argc, char **argv)
|
|
|
|
{
|
|
|
|
// vec3_t start, end;
|
|
|
|
int c;
|
|
|
|
size_t i, test;
|
|
|
|
int pass = 1;
|
|
|
|
|
|
|
|
while ((c = getopt (argc, argv, "qvt:")) != EOF) {
|
|
|
|
switch (c) {
|
|
|
|
case 'q':
|
|
|
|
verbose--;
|
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
verbose++;
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
test = atoi (optarg);
|
|
|
|
if (test < num_tests) {
|
|
|
|
test_enabled[test] = 1;
|
|
|
|
} else {
|
|
|
|
fprintf (stderr, "Bad test number (0 - %zd)\n", num_tests);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fprintf (stderr, "-q (quiet) -v (verbose) and/or -t TEST "
|
|
|
|
"(test number)\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < num_tests; i++)
|
|
|
|
if (test_enabled[i])
|
|
|
|
break;
|
|
|
|
if (i == num_tests) {
|
|
|
|
for (i = 0; i < num_tests; i++)
|
|
|
|
test_enabled[i] = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (verbose > 0)
|
|
|
|
printf ("start -> end => stop frac allsolid startsolid inopen "
|
|
|
|
"inwater\n");
|
|
|
|
for (i = 0; i < num_tests; i++) {
|
|
|
|
if (!test_enabled[i])
|
|
|
|
continue;
|
|
|
|
pass &= run_test (&tests[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return !pass;
|
|
|
|
}
|