mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Add an old qf version of trace.c
This version is broken (it's the one "fixed" by commit 981622f9
), but it
does behave correctly for hipnotic's bobbing water. The question is, why?
This commit is contained in:
parent
9daa0b7bde
commit
32ff639bf3
1 changed files with 191 additions and 0 deletions
191
libs/models/test/trace-qf-bad.c
Normal file
191
libs/models/test/trace-qf-bad.c
Normal file
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
trace.c
|
||||
|
||||
BSP line tracing
|
||||
|
||||
Copyright (C) 2004 Bill Currie
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2004/9/25
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
static __attribute__ ((used)) const char rcsid[] =
|
||||
"$Id$";
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "QF/model.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "world.h"
|
||||
|
||||
/* LINE TESTING IN HULLS */
|
||||
|
||||
// 1/32 epsilon to keep floating point happy
|
||||
#ifndef DIST_EPSILON
|
||||
#define DIST_EPSILON (0.03125)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
vec3_t end;
|
||||
int side;
|
||||
int num;
|
||||
mplane_t *plane;
|
||||
} tracestack_t;
|
||||
|
||||
static inline void
|
||||
calc_impact (trace_t *trace, const vec3_t start, const vec3_t end,
|
||||
mplane_t *plane)
|
||||
{
|
||||
vec_t t1, t2, frac;
|
||||
vec3_t dist;
|
||||
|
||||
t1 = PlaneDiff (start, plane);
|
||||
t2 = PlaneDiff (end, plane);
|
||||
|
||||
if (t1 < 0) {
|
||||
frac = (t1 + DIST_EPSILON) / (t1 - t2);
|
||||
// invert plane paramterers
|
||||
VectorNegate (plane->normal, trace->plane.normal);
|
||||
trace->plane.dist = -plane->dist;
|
||||
} else {
|
||||
frac = (t1 - DIST_EPSILON) / (t1 - t2);
|
||||
VectorCopy (plane->normal, trace->plane.normal);
|
||||
trace->plane.dist = plane->dist;
|
||||
}
|
||||
frac = bound (0, frac, 1);
|
||||
trace->fraction = frac;
|
||||
VectorSubtract (end, start, dist);
|
||||
VectorMultAdd (start, frac, dist, trace->endpos);
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
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;
|
||||
vec3_t start, end, dist;
|
||||
int side, empty, solid;
|
||||
tracestack_t *tstack;
|
||||
tracestack_t tracestack[256];
|
||||
mclipnode_t *node;
|
||||
mplane_t *plane, *split_plane;
|
||||
|
||||
VectorCopy (start_point, start);
|
||||
VectorCopy (end_point, end);
|
||||
|
||||
tstack = tracestack;
|
||||
empty = 0;
|
||||
solid = 0;
|
||||
split_plane = 0;
|
||||
|
||||
while (1) {
|
||||
while (num < 0) {
|
||||
if (!solid && num != CONTENTS_SOLID) {
|
||||
empty = 1;
|
||||
if (num == CONTENTS_EMPTY)
|
||||
trace->inopen = true;
|
||||
else
|
||||
trace->inwater = true;
|
||||
} else if (!empty && num == CONTENTS_SOLID) {
|
||||
solid = 1;
|
||||
} else if (solid && num != CONTENTS_SOLID) {
|
||||
//FIXME not sure what I want
|
||||
//made it out of the solid and into open space, continue
|
||||
//on as if we were always in empty space
|
||||
empty = 1;
|
||||
solid = 0;
|
||||
trace->startsolid = 1;
|
||||
if (num == CONTENTS_EMPTY)
|
||||
trace->inopen = true;
|
||||
else
|
||||
trace->inwater = true;
|
||||
} else if (empty/* || solid*/) {//FIXME not sure what I want
|
||||
// DONE!
|
||||
trace->allsolid = solid & (num == CONTENTS_SOLID);
|
||||
trace->startsolid = solid;
|
||||
calc_impact (trace, start_point, end_point, split_plane);
|
||||
return;
|
||||
}
|
||||
|
||||
// pop up the stack for a back side
|
||||
if (tstack-- == tracestack) {
|
||||
// we've finished.
|
||||
trace->allsolid = solid & (num == CONTENTS_SOLID);
|
||||
trace->startsolid = solid;
|
||||
return;
|
||||
}
|
||||
|
||||
// set the hit point for this plane
|
||||
VectorCopy (end, start);
|
||||
|
||||
// go down the back side
|
||||
VectorCopy (tstack->end, end);
|
||||
side = tstack->side;
|
||||
split_plane = tstack->plane;
|
||||
|
||||
num = hull->clipnodes[tstack->num].children[side ^ 1];
|
||||
}
|
||||
|
||||
node = hull->clipnodes + num;
|
||||
plane = hull->planes + node->planenum;
|
||||
|
||||
start_dist = PlaneDiff (start, plane);
|
||||
end_dist = PlaneDiff (end, plane);
|
||||
|
||||
if (start_dist >= 0 && end_dist >= 0) {
|
||||
// entirely in front of the plane
|
||||
num = node->children[0];
|
||||
continue;
|
||||
}
|
||||
if (start_dist < 0 && end_dist < 0) {
|
||||
// entirely behind the plane
|
||||
num = node->children[1];
|
||||
continue;
|
||||
}
|
||||
|
||||
side = start_dist < 0;
|
||||
frac = start_dist / (start_dist - end_dist);
|
||||
frac = bound (0, frac, 1);
|
||||
|
||||
tstack->num = num;
|
||||
tstack->side = side;
|
||||
tstack->plane = plane;
|
||||
VectorCopy (end, tstack->end);
|
||||
tstack++;
|
||||
|
||||
VectorSubtract (end, start, dist);
|
||||
VectorMultAdd (start, frac, dist, end);
|
||||
|
||||
num = node->children[side];
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue