mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
well, it finally seems to work, but q1 maps (especially start's ramp to e3) are not such that they're particulary playable due to being designed for point clipping. so still disabled until something can be sorted out.
This commit is contained in:
parent
0ee9e1cf3e
commit
e15fae264a
2 changed files with 148 additions and 81 deletions
|
@ -65,9 +65,9 @@ static void do_trace (vec3_t start, vec3_t end)
|
|||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
vec3_t start, end;
|
||||
|
||||
#if 1
|
||||
int i;
|
||||
puts ("\nexpect 0.496094, 1 (0 0 1 0), (0 0 1 0)");
|
||||
for (i = 0; i < 2; i++) {
|
||||
start[0] = 0;
|
||||
|
@ -117,5 +117,23 @@ int main (int argc, char **argv)
|
|||
end[2] -= 32;
|
||||
do_trace (start, end);
|
||||
}
|
||||
|
||||
puts ("\nexpect 0 (0 0 1 0)");
|
||||
start[0] = 96;
|
||||
start[1] = -47.9612;
|
||||
start[2] = 56.0312 + 4;
|
||||
end[0] = 96;
|
||||
end[1] = -47.1025;
|
||||
end[2] = 55.8737 + 4;
|
||||
do_trace (start, end);
|
||||
#endif
|
||||
puts ("\nexpect 0 (0 0 1 0)");
|
||||
start[0] = 94.8916;
|
||||
start[1] = -34.8506;
|
||||
start[2] = 56.0312 + 4;
|
||||
end[0] = 94.8146;
|
||||
end[1] = -28.5696;
|
||||
end[2] = 55.5683 + 4;
|
||||
do_trace (start, end);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -84,46 +84,69 @@ calc_impact (trace_t *trace, const vec3_t start, const vec3_t end,
|
|||
VectorMultAdd (start, frac, dist, trace->endpos);
|
||||
}
|
||||
#if 0
|
||||
static inline void
|
||||
check_contents (int num, trace_t *trace)
|
||||
{
|
||||
if (num != CONTENTS_SOLID) {
|
||||
trace->allsolid = false;
|
||||
if (num == CONTENTS_EMPTY)
|
||||
trace->inopen = true;
|
||||
else
|
||||
trace->inwater = true;
|
||||
} else {
|
||||
if (!trace->inwater && !trace->inopen)
|
||||
trace->startsolid = true;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const vec_t *start;
|
||||
const vec_t *end;
|
||||
trace_t trace;
|
||||
const vec_t *extents;
|
||||
qboolean isbox;
|
||||
hull_t hull;
|
||||
mplane_t *plane;
|
||||
mplane_t *impact;
|
||||
float fraction;
|
||||
int flags;
|
||||
} tl_t;
|
||||
|
||||
static inline float
|
||||
calc_offset (trace_t *trace, mplane_t *plane)
|
||||
static inline void
|
||||
check_contents (int num, tl_t *tl)
|
||||
{
|
||||
if (trace->isbox) {
|
||||
if (plane->type < 3)
|
||||
return trace->extents[plane->type];
|
||||
if (num != CONTENTS_SOLID) {
|
||||
tl->flags &= ~1;
|
||||
if (num == CONTENTS_EMPTY)
|
||||
tl->flags |= 4;
|
||||
else
|
||||
return (fabs (trace->extents[0] * plane->normal[0])
|
||||
+ fabs (trace->extents[1] * plane->normal[1])
|
||||
+ fabs (trace->extents[2] * plane->normal[2]));
|
||||
tl->flags |= 8;
|
||||
} else {
|
||||
if (!(tl->flags & 12))
|
||||
tl->flags |= 2;
|
||||
}
|
||||
}
|
||||
|
||||
static inline float
|
||||
calc_offset (tl_t *tl, mplane_t *plane)
|
||||
{
|
||||
if (tl->isbox) {
|
||||
if (plane->type < 3)
|
||||
return tl->extents[plane->type];
|
||||
else
|
||||
return (fabs (tl->extents[0] * plane->normal[0])
|
||||
+ fabs (tl->extents[1] * plane->normal[1])
|
||||
+ fabs (tl->extents[2] * plane->normal[2]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
impact (tl_t *tl)
|
||||
{
|
||||
float t1, t2, offset, frac;
|
||||
t1 = PlaneDiff (tl->start, tl->plane);
|
||||
t2 = PlaneDiff (tl->end, tl->plane);
|
||||
offset = calc_offset (tl, tl->plane);
|
||||
if (t1 < t2) {
|
||||
frac = (t1 + offset) / (t1 - t2);
|
||||
} else if (t1 > t2) {
|
||||
frac = (t1 - offset) / (t1 - t2);
|
||||
} else {
|
||||
frac = 0;
|
||||
Sys_Printf ("help! help! the world is falling apart!\n");
|
||||
}
|
||||
if (frac >= 0) {
|
||||
tl->fraction = frac;
|
||||
tl->impact = tl->plane;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
traceline (int num, float p1f, float p2f, const vec3_t p1, const vec3_t p2,
|
||||
tl_t *tl)
|
||||
{
|
||||
|
@ -132,7 +155,7 @@ traceline (int num, float p1f, float p2f, const vec3_t p1, const vec3_t p2,
|
|||
float t1, t2, frac, frac2, midf, offset;
|
||||
int side;
|
||||
vec3_t mid;
|
||||
mplane_t *op;
|
||||
int c1, c2;
|
||||
|
||||
while (num >= 0) {
|
||||
node = tl->hull.clipnodes + num;
|
||||
|
@ -140,70 +163,82 @@ traceline (int num, float p1f, float p2f, const vec3_t p1, const vec3_t p2,
|
|||
|
||||
t1 = PlaneDiff (p1, plane);
|
||||
t2 = PlaneDiff (p2, plane);
|
||||
offset = calc_offset (&tl->trace, plane);
|
||||
offset = calc_offset (tl, plane);
|
||||
|
||||
if (t1 >= offset && t2 >= offset) {
|
||||
num = node->children[0];
|
||||
} if (t1 < -offset && t2 < -offset) {
|
||||
} else if (t1 < -offset && t2 < -offset) {
|
||||
num = node->children[1];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (num < 0) {
|
||||
check_contents (num, &tl->trace);
|
||||
t1 = t2 = -3.14;
|
||||
if (num == CONTENTS_SOLID) {
|
||||
if (tl->plane) {
|
||||
tl->impact = tl->plane;
|
||||
t1 = PlaneDiff (tl->start, tl->plane);
|
||||
t2 = PlaneDiff (tl->end, tl->plane);
|
||||
offset = calc_offset (&tl->trace, tl->plane);
|
||||
if (t1 < t2) {
|
||||
tl->fraction = (t1 + offset + DIST_EPSILON) / (t1 - t2);
|
||||
} else if (t1 > t2) {
|
||||
tl->fraction = (t1 - offset - DIST_EPSILON) / (t1 - t2);
|
||||
} else {
|
||||
tl->fraction = p1f;
|
||||
Sys_Printf ("help! help! the world is falling apart!\n");
|
||||
}
|
||||
if (num < 0)
|
||||
return num;
|
||||
|
||||
// if (t1 == t2) {
|
||||
if (t1 >= -offset && t1 < offset && t2 >= -offset && t2 < offset) {
|
||||
c1 = c2 = traceline (node->children[0], p1f, p2f, p1, p2, tl);
|
||||
if (c1 != CONTENTS_SOLID)
|
||||
c2 = traceline (node->children[1], p1f, p2f, p1, p2, tl);
|
||||
if (c1 == CONTENTS_SOLID || c2 == CONTENTS_SOLID) {
|
||||
if (!p1f) {
|
||||
tl->flags &= 3;
|
||||
tl->flags |= 2;
|
||||
}
|
||||
if (tl->plane)
|
||||
impact (tl);
|
||||
return CONTENTS_SOLID;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (t1 < t2) {
|
||||
side = 1;
|
||||
frac = (t1 - offset) / (t1 - t2);
|
||||
frac2 = (t1 + offset) / (t1 - t2);
|
||||
} else if (t1 > t2) {
|
||||
side = 0;
|
||||
frac = (t1 + offset) / (t1 - t2);
|
||||
frac2 = (t1 - offset) / (t1 - t2);
|
||||
if (c1 == CONTENTS_EMPTY && c2 == CONTENTS_EMPTY) {
|
||||
tl->flags &= ~1;
|
||||
tl->flags |= 4;
|
||||
} else {
|
||||
tl->flags &= ~1;
|
||||
tl->flags |= 8;
|
||||
}
|
||||
return min (c1, c2); //FIXME correct?
|
||||
} else {
|
||||
side = 0;
|
||||
frac = 1;
|
||||
frac2 = 0;
|
||||
plane = tl->plane;
|
||||
}
|
||||
if (t1 < t2) {
|
||||
side = 1;
|
||||
frac = (t1 - offset) / (t1 - t2);
|
||||
frac2 = (t1 + offset) / (t1 - t2);
|
||||
} else if (t1 > t2) {
|
||||
side = 0;
|
||||
frac = (t1 + offset) / (t1 - t2);
|
||||
frac2 = (t1 - offset) / (t1 - t2);
|
||||
}
|
||||
|
||||
op = tl->plane;
|
||||
|
||||
frac = bound (0, frac, 1);
|
||||
midf = p1f + (p2f - p1f) * frac;
|
||||
VectorSubtract (p2, p1, mid);
|
||||
VectorMultAdd (p1, frac, mid, mid);
|
||||
traceline (node->children[side], p1f, midf, p1, mid, tl);
|
||||
|
||||
frac2 = bound (0, frac2, 1);
|
||||
midf = p1f + (p2f - p1f) * frac2;
|
||||
if (!tl->impact || midf <= tl->fraction) {
|
||||
frac = bound (0, frac, 1);
|
||||
midf = p1f + (p2f - p1f) * frac;
|
||||
VectorSubtract (p2, p1, mid);
|
||||
VectorMultAdd (p1, frac2, mid, mid);
|
||||
VectorMultAdd (p1, frac, mid, mid);
|
||||
c1 = c2 = traceline (node->children[side], p1f, midf, p1, mid, tl);
|
||||
|
||||
frac2 = bound (0, frac2, 1);
|
||||
midf = p1f + (p2f - p1f) * frac2;
|
||||
if (!tl->impact || midf <= tl->fraction) {
|
||||
VectorSubtract (p2, p1, mid);
|
||||
VectorMultAdd (p1, frac2, mid, mid);
|
||||
tl->plane = plane;
|
||||
c2 = traceline (node->children[side ^ 1], midf, p2f, mid, p2, tl);
|
||||
}
|
||||
tl->plane = plane;
|
||||
traceline (node->children[side ^ 1], midf, p2f, mid, p2, tl);
|
||||
if (c1 != CONTENTS_SOLID && c2 == CONTENTS_SOLID)
|
||||
impact (tl);
|
||||
if (c1 == CONTENTS_SOLID && !(tl->flags & 0xc))
|
||||
tl->flags |= 2;
|
||||
if (c1 == CONTENTS_EMPTY || c2 == CONTENTS_EMPTY) {
|
||||
tl->flags &= ~1;
|
||||
tl->flags |= 4;
|
||||
}
|
||||
if (c1 < CONTENTS_SOLID || c2 < CONTENTS_SOLID) {
|
||||
tl->flags &= ~1;
|
||||
tl->flags |= 8;
|
||||
}
|
||||
|
||||
return frac2 ? c1 : c2;
|
||||
}
|
||||
tl->plane = op;
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
|
@ -212,18 +247,32 @@ MOD_TraceLine (hull_t *hull, int num,
|
|||
trace_t *trace)
|
||||
{
|
||||
tl_t tl;
|
||||
int c;
|
||||
|
||||
tl.start = start_point;
|
||||
tl.end = end_point;
|
||||
tl.trace = *trace;
|
||||
tl.hull = *hull;
|
||||
tl.fraction = 1;
|
||||
tl.plane = tl.impact = 0;
|
||||
traceline (num, 0, 1, start_point, end_point, &tl);
|
||||
if (tl.fraction < 1) {
|
||||
calc_impact (&tl.trace, start_point, end_point, tl.impact);
|
||||
tl.flags = 1;
|
||||
tl.isbox = trace->isbox;
|
||||
tl.extents = trace->extents;
|
||||
c = traceline (num, 0, 1, start_point, end_point, &tl);
|
||||
if (c == CONTENTS_EMPTY) {
|
||||
tl.flags &= ~1;
|
||||
tl.flags |= 4;
|
||||
}
|
||||
*trace = tl.trace;
|
||||
if (c < CONTENTS_SOLID) {
|
||||
tl.flags &= ~1;
|
||||
tl.flags |= 8;
|
||||
}
|
||||
if (tl.fraction < 1) {
|
||||
calc_impact (trace, start_point, end_point, tl.impact);
|
||||
}
|
||||
trace->allsolid = (tl.flags & 1) != 0;
|
||||
trace->startsolid = (tl.flags & 2) != 0;
|
||||
trace->inopen = (tl.flags & 4) != 0;
|
||||
trace->inwater = (tl.flags & 8) != 0;
|
||||
}
|
||||
#else
|
||||
typedef struct {
|
||||
|
|
Loading…
Reference in a new issue