mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-31 05:00:35 +00:00
Remove the hard-coded bsp maximum depths.
The depth limits in the gl and glsl renderers and in the trace code really bothered me, but then the fix hit me: at load-time, recurse the trees normally and record the depth in the appropriate place. The node stacks can then be allocated as necessary (I chose to add a paranoia buffer of 2, but I expect the maximum depth will rarely be used).
This commit is contained in:
parent
7c3ad46b48
commit
a12eb940f1
6 changed files with 76 additions and 15 deletions
|
@ -230,6 +230,7 @@ typedef struct hull_s {
|
|||
vec3_t clip_mins;
|
||||
vec3_t clip_maxs;
|
||||
struct nodeleaf_s *nodeleafs;
|
||||
int depth; ///< maximum depth of the tree
|
||||
} hull_t;
|
||||
|
||||
// SPRITE MODELS ==============================================================
|
||||
|
@ -393,6 +394,7 @@ typedef struct model_s {
|
|||
|
||||
int numnodes;
|
||||
mnode_t *nodes;
|
||||
int depth; ///< maximum depth of the tree
|
||||
|
||||
int numtexinfo;
|
||||
mtexinfo_t *texinfo;
|
||||
|
@ -449,6 +451,7 @@ void *Mod_LoadAliasFrame (void *pin, int *posenum, maliasframedesc_t *frame,
|
|||
void *Mod_LoadAliasGroup (void *pin, int *posenum, maliasframedesc_t *frame,
|
||||
int extra);
|
||||
|
||||
void Mod_FindClipDepth (hull_t *hull);
|
||||
void Mod_LoadBrushModel (model_t *mod, void *buffer);
|
||||
void Mod_FloodFillSkin (byte * skin, int skinwidth, int skinheight);
|
||||
|
||||
|
|
|
@ -880,6 +880,48 @@ do_checksums (const bsp_t *bsp, void *_mod)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recurse_draw_tree (mnode_t *node, int depth)
|
||||
{
|
||||
if (!node || node->contents < 0) {
|
||||
if (depth > loadmodel->depth)
|
||||
loadmodel->depth = depth;
|
||||
return;
|
||||
}
|
||||
recurse_draw_tree (node->children[0], depth + 1);
|
||||
recurse_draw_tree (node->children[1], depth + 1);
|
||||
}
|
||||
|
||||
static void
|
||||
Mod_FindDrawDepth (void)
|
||||
{
|
||||
loadmodel->depth = 0;
|
||||
recurse_draw_tree (loadmodel->nodes, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
recurse_clip_tree (hull_t *hull, int num, int depth)
|
||||
{
|
||||
mclipnode_t *node;
|
||||
|
||||
if (num < 0) {
|
||||
if (depth > hull->depth)
|
||||
hull->depth = depth;
|
||||
return;
|
||||
}
|
||||
node = hull->clipnodes + num;
|
||||
recurse_clip_tree (hull, node->children[0], depth + 1);
|
||||
recurse_clip_tree (hull, node->children[1], depth + 1);
|
||||
}
|
||||
|
||||
void
|
||||
Mod_FindClipDepth (hull_t *hull)
|
||||
{
|
||||
hull->depth = 0;
|
||||
if (hull->clipnodes) // no hull 3?
|
||||
recurse_clip_tree (hull, hull->firstclipnode, 1);
|
||||
}
|
||||
|
||||
void
|
||||
Mod_LoadBrushModel (model_t *mod, void *buffer)
|
||||
{
|
||||
|
@ -913,6 +955,10 @@ Mod_LoadBrushModel (model_t *mod, void *buffer)
|
|||
|
||||
Mod_MakeHull0 ();
|
||||
|
||||
Mod_FindDrawDepth ();
|
||||
for (i = 0; i < MAX_MAP_HULLS; i++)
|
||||
Mod_FindClipDepth (&mod->hulls[i]);
|
||||
|
||||
mod->numframes = 2; // regular and alternate animation
|
||||
|
||||
// set up the submodels (FIXME: this is confusing)
|
||||
|
|
|
@ -255,6 +255,8 @@ run_test (test_t *test)
|
|||
static int output = 0;
|
||||
portlist_t *portal_list = 0;
|
||||
|
||||
if (!test->hull->depth)
|
||||
Mod_FindClipDepth (test->hull);
|
||||
if (!test->hull->nodeleafs) {
|
||||
hull_t *hull = test->hull;
|
||||
int i, j;
|
||||
|
|
|
@ -783,12 +783,16 @@ MOD_TraceLine (hull_t *hull, int num,
|
|||
vec3_t start, end, dist;
|
||||
int side;
|
||||
tracestack_t *tstack;
|
||||
tracestack_t tracestack[256];
|
||||
tracestack_t *tracestack;
|
||||
mclipnode_t *node;
|
||||
plane_t *plane;
|
||||
clipleaf_t *leaf;
|
||||
trace_state_t trace_state;
|
||||
|
||||
if (!hull->depth)
|
||||
Sys_Error ("hull depth not set");
|
||||
// +2 for paranoia
|
||||
tracestack = alloca ((hull->depth + 2) * sizeof (tracestack_t));
|
||||
VectorCopy (start_point, start);
|
||||
VectorCopy (end_point, end);
|
||||
VectorSubtract (end, start, trace_state.dist);
|
||||
|
|
|
@ -652,16 +652,21 @@ test_node (mnode_t *node)
|
|||
}
|
||||
|
||||
static void
|
||||
R_VisitWorldNodes (mnode_t *node)
|
||||
R_VisitWorldNodes (model_t *model)
|
||||
{
|
||||
#define NODE_STACK 1024
|
||||
struct {
|
||||
typedef struct {
|
||||
mnode_t *node;
|
||||
int side;
|
||||
} *node_ptr, node_stack[NODE_STACK];
|
||||
} rstack_t;
|
||||
rstack_t *node_ptr;
|
||||
rstack_t *node_stack;
|
||||
mnode_t *node;
|
||||
mnode_t *front;
|
||||
int side;
|
||||
|
||||
node = model->nodes;
|
||||
// +2 for paranoia
|
||||
node_stack = alloca ((model->depth + 2) * sizeof (rstack_t));
|
||||
node_ptr = node_stack;
|
||||
|
||||
while (1) {
|
||||
|
@ -669,8 +674,6 @@ R_VisitWorldNodes (mnode_t *node)
|
|||
side = get_side (node);
|
||||
front = node->children[side];
|
||||
if (test_node (front)) {
|
||||
if (node_ptr - node_stack == NODE_STACK)
|
||||
Sys_Error ("node_stack overflow");
|
||||
node_ptr->node = node;
|
||||
node_ptr->side = side;
|
||||
node_ptr++;
|
||||
|
@ -716,7 +719,7 @@ gl_R_DrawWorld (void)
|
|||
gl_R_DrawSky ();
|
||||
}
|
||||
|
||||
R_VisitWorldNodes (r_worldentity.model->nodes);
|
||||
R_VisitWorldNodes (r_worldentity.model);
|
||||
if (r_drawentities->int_val) {
|
||||
entity_t *ent;
|
||||
for (ent = r_ent_queue; ent; ent = ent->next) {
|
||||
|
|
|
@ -743,16 +743,21 @@ test_node (mnode_t *node)
|
|||
}
|
||||
|
||||
static void
|
||||
R_VisitWorldNodes (mnode_t *node)
|
||||
R_VisitWorldNodes (model_t *model)
|
||||
{
|
||||
#define NODE_STACK 1024
|
||||
struct {
|
||||
typedef struct {
|
||||
mnode_t *node;
|
||||
int side;
|
||||
} *node_ptr, node_stack[NODE_STACK];
|
||||
} rstack_t;
|
||||
rstack_t *node_ptr;
|
||||
rstack_t *node_stack;
|
||||
mnode_t *node;
|
||||
mnode_t *front;
|
||||
int side;
|
||||
|
||||
node = model->nodes;
|
||||
// +2 for paranoia
|
||||
node_stack = alloca ((model->depth + 2) * sizeof (rstack_t));
|
||||
node_ptr = node_stack;
|
||||
|
||||
while (1) {
|
||||
|
@ -760,8 +765,6 @@ R_VisitWorldNodes (mnode_t *node)
|
|||
side = get_side (node);
|
||||
front = node->children[side];
|
||||
if (test_node (front)) {
|
||||
if (node_ptr - node_stack == NODE_STACK)
|
||||
Sys_Error ("node_stack overflow");
|
||||
node_ptr->node = node;
|
||||
node_ptr->side = side;
|
||||
node_ptr++;
|
||||
|
@ -1097,7 +1100,7 @@ glsl_R_DrawWorld (void)
|
|||
|
||||
currententity = &worldent;
|
||||
|
||||
R_VisitWorldNodes (worldent.model->nodes);
|
||||
R_VisitWorldNodes (worldent.model);
|
||||
if (r_drawentities->int_val) {
|
||||
entity_t *ent;
|
||||
for (ent = r_ent_queue; ent; ent = ent->next) {
|
||||
|
|
Loading…
Reference in a new issue