mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Add code to rebuild the bsp brushes.
Names and locations of declarations are still up in the air, but things seem to be working assuming my test code is correct.
This commit is contained in:
parent
853bf13d9e
commit
d61cb25a44
5 changed files with 333 additions and 33 deletions
|
@ -202,6 +202,7 @@ typedef struct hull_s {
|
||||||
int lastclipnode;
|
int lastclipnode;
|
||||||
vec3_t clip_mins;
|
vec3_t clip_mins;
|
||||||
vec3_t clip_maxs;
|
vec3_t clip_maxs;
|
||||||
|
struct nodeleaf_s *nodeleafs;
|
||||||
} hull_t;
|
} hull_t;
|
||||||
|
|
||||||
// SPRITE MODELS ==============================================================
|
// SPRITE MODELS ==============================================================
|
||||||
|
|
|
@ -118,4 +118,22 @@ hull_t *SV_HullForEntity (struct edict_s *ent, const vec3_t mins,
|
||||||
void MOD_TraceLine (hull_t *hull, int num,
|
void MOD_TraceLine (hull_t *hull, int num,
|
||||||
const vec3_t start, const vec3_t end, trace_t *trace);
|
const vec3_t start, const vec3_t end, trace_t *trace);
|
||||||
|
|
||||||
|
typedef struct clipport_s {
|
||||||
|
int planenum;
|
||||||
|
struct clipport_s *next[2]; ///< front, back
|
||||||
|
struct clipleaf_s *leafs[2]; ///< front, back
|
||||||
|
struct winding_s *winding;
|
||||||
|
} clipport_t;
|
||||||
|
|
||||||
|
typedef struct clipleaf_s {
|
||||||
|
clipport_t *portals;
|
||||||
|
int contents;
|
||||||
|
} clipleaf_t;
|
||||||
|
|
||||||
|
typedef struct nodeleaf_s {
|
||||||
|
clipleaf_t *leafs[2]; ///< front, back. If null, node's child is a node
|
||||||
|
} nodeleaf_t;
|
||||||
|
|
||||||
|
nodeleaf_t *MOD_BuildBrushes (hull_t *hull);
|
||||||
|
|
||||||
#endif // __world_h
|
#endif // __world_h
|
||||||
|
|
|
@ -7,7 +7,7 @@ INCLUDES= -I$(top_srcdir)/include
|
||||||
lib_LTLIBRARIES= libQFmodels.la @VID_MODEL_TARGETS@
|
lib_LTLIBRARIES= libQFmodels.la @VID_MODEL_TARGETS@
|
||||||
EXTRA_LTLIBRARIES= libQFmodels_gl.la libQFmodels_sw.la
|
EXTRA_LTLIBRARIES= libQFmodels_gl.la libQFmodels_sw.la
|
||||||
|
|
||||||
models_sources = clip_hull.c model.c trace.c winding.c
|
models_sources = clip_hull.c model.c portal.c trace.c winding.c
|
||||||
|
|
||||||
libQFmodels_la_LDFLAGS= -version-info $(QUAKE_LIBRARY_VERSION_INFO) -no-undefined
|
libQFmodels_la_LDFLAGS= -version-info $(QUAKE_LIBRARY_VERSION_INFO) -no-undefined
|
||||||
libQFmodels_la_LIBADD= brush/libbrush.la $(top_builddir)/libs/util/libQFutil.la
|
libQFmodels_la_LIBADD= brush/libbrush.la $(top_builddir)/libs/util/libQFutil.la
|
||||||
|
|
181
libs/models/portal.c
Normal file
181
libs/models/portal.c
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
#FILENAME#
|
||||||
|
|
||||||
|
#DESCRIPTION#
|
||||||
|
|
||||||
|
Copyright (C) 2011 Bill Currie <bill@taniwha.org>
|
||||||
|
|
||||||
|
Author: Bill Currie <bill@taniwha.org>
|
||||||
|
Date: 2011/11/14
|
||||||
|
|
||||||
|
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$";
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_STRINGS_H
|
||||||
|
#include <strings.h>
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "QF/model.h"
|
||||||
|
#include "QF/winding.h"
|
||||||
|
|
||||||
|
#include "world.h"
|
||||||
|
|
||||||
|
static clipleaf_t *
|
||||||
|
alloc_leaf (void)
|
||||||
|
{
|
||||||
|
return calloc (1, sizeof (clipleaf_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
static clipport_t *
|
||||||
|
alloc_portal (void)
|
||||||
|
{
|
||||||
|
return calloc (1, sizeof (clipport_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
remove_portal (clipport_t *portal, clipleaf_t *leaf)
|
||||||
|
{
|
||||||
|
clipport_t **p;
|
||||||
|
int side;
|
||||||
|
|
||||||
|
for (p = &leaf->portals; *p; p = &(*p)->next[side]) {
|
||||||
|
side = (*p)->leafs[1] == leaf;
|
||||||
|
if (*p == portal) {
|
||||||
|
*p = portal->next[side];
|
||||||
|
portal->next[side] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_portal (clipport_t *portal, clipleaf_t *front, clipleaf_t *back)
|
||||||
|
{
|
||||||
|
portal->leafs[0] = front;
|
||||||
|
portal->next[0] = front->portals;
|
||||||
|
front->portals = portal;
|
||||||
|
|
||||||
|
portal->leafs[1] = back;
|
||||||
|
portal->next[1] = back->portals;
|
||||||
|
back->portals = portal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static clipleaf_t *
|
||||||
|
carve_leaf (hull_t *hull, nodeleaf_t *nodeleafs, clipleaf_t *leaf, int num)
|
||||||
|
{
|
||||||
|
mclipnode_t *node;
|
||||||
|
plane_t *plane;
|
||||||
|
winding_t *winding, *fw, *bw;
|
||||||
|
clipport_t *portal;
|
||||||
|
clipport_t *new_portal;
|
||||||
|
clipport_t *next_portal;
|
||||||
|
clipleaf_t *other_leaf;
|
||||||
|
clipleaf_t *new_leaf;
|
||||||
|
plane_t clipplane;
|
||||||
|
int side;
|
||||||
|
|
||||||
|
if (num < 0) {
|
||||||
|
// we've hit a leaf. all done
|
||||||
|
leaf->contents = num;
|
||||||
|
return leaf;
|
||||||
|
}
|
||||||
|
node = hull->clipnodes + num;
|
||||||
|
plane = hull->planes + node->planenum;
|
||||||
|
|
||||||
|
winding = BaseWindingForPlane (plane);
|
||||||
|
for (portal = leaf->portals; portal; portal = portal->next[side]) {
|
||||||
|
clipplane = hull->planes[portal->planenum];
|
||||||
|
side = (portal->leafs[1] == leaf);
|
||||||
|
if (side)
|
||||||
|
PlaneFlip (&clipplane, &clipplane);
|
||||||
|
winding = ClipWinding (winding, &clipplane, true);
|
||||||
|
}
|
||||||
|
new_leaf = alloc_leaf ();
|
||||||
|
portal = leaf->portals;
|
||||||
|
leaf->portals = 0;
|
||||||
|
for (; portal; portal = next_portal) {
|
||||||
|
side = (portal->leafs[1] == leaf);
|
||||||
|
next_portal = portal->next[side];
|
||||||
|
other_leaf = portal->leafs[!side];
|
||||||
|
remove_portal (portal, other_leaf);
|
||||||
|
|
||||||
|
DivideWinding (portal->winding, plane, &fw, &bw);
|
||||||
|
if (!fw) {
|
||||||
|
if (side)
|
||||||
|
add_portal (portal, other_leaf, new_leaf);
|
||||||
|
else
|
||||||
|
add_portal (portal, new_leaf, other_leaf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!bw) {
|
||||||
|
if (side)
|
||||||
|
add_portal (portal, other_leaf, leaf);
|
||||||
|
else
|
||||||
|
add_portal (portal, leaf, other_leaf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
new_portal = alloc_portal ();
|
||||||
|
new_portal->planenum = portal->planenum;
|
||||||
|
new_portal->winding = bw;
|
||||||
|
FreeWinding (portal->winding);
|
||||||
|
portal->winding = fw;
|
||||||
|
|
||||||
|
if (side) {
|
||||||
|
add_portal (portal, other_leaf, leaf);
|
||||||
|
add_portal (new_portal, other_leaf, new_leaf);
|
||||||
|
} else {
|
||||||
|
add_portal (portal, leaf, other_leaf);
|
||||||
|
add_portal (new_portal, new_leaf, other_leaf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_portal = alloc_portal ();
|
||||||
|
new_portal->planenum = node->planenum;
|
||||||
|
new_portal->winding = winding;
|
||||||
|
add_portal (new_portal, leaf, new_leaf);
|
||||||
|
|
||||||
|
nodeleafs[num].leafs[0] = carve_leaf (hull, nodeleafs, leaf,
|
||||||
|
node->children[0]);
|
||||||
|
nodeleafs[num].leafs[1] = carve_leaf (hull, nodeleafs, new_leaf,
|
||||||
|
node->children[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeleaf_t *
|
||||||
|
MOD_BuildBrushes (hull_t *hull)
|
||||||
|
{
|
||||||
|
int numnodes = hull->lastclipnode + 1;
|
||||||
|
nodeleaf_t *nodeleafs;
|
||||||
|
clipleaf_t *root; // this will be carved into all the actual leafs
|
||||||
|
|
||||||
|
nodeleafs = calloc (numnodes, sizeof (nodeleaf_t));
|
||||||
|
root = alloc_leaf ();
|
||||||
|
carve_leaf (hull, nodeleafs, root, hull->firstclipnode);
|
||||||
|
return nodeleafs;
|
||||||
|
}
|
|
@ -275,6 +275,7 @@ typedef struct {
|
||||||
qboolean startsolid;
|
qboolean startsolid;
|
||||||
qboolean inopen;
|
qboolean inopen;
|
||||||
qboolean inwater;
|
qboolean inwater;
|
||||||
|
int num_portals;
|
||||||
} expect;
|
} expect;
|
||||||
} test_t;
|
} test_t;
|
||||||
|
|
||||||
|
@ -284,76 +285,76 @@ box_t player = { {16, 16, 28} };
|
||||||
|
|
||||||
test_t tests[] = {
|
test_t tests[] = {
|
||||||
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
||||||
{-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0}},
|
{-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0, 3}},
|
||||||
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
||||||
{ 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0}},
|
{ 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0, 3}},
|
||||||
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
||||||
{ 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0}},
|
{ 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0, 3}},
|
||||||
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
||||||
{ 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0}},
|
{ 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0, 3}},
|
||||||
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
||||||
{ 0, 0, 0}, { 0, 8, 0}, { 1, 1, 1, 0, 0}},
|
{ 0, 0, 0}, { 0, 8, 0}, { 1, 1, 1, 0, 0, 3}},
|
||||||
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
{"Point, Three parallel planes 1", &point, &hull_tpp1,
|
||||||
{ 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 1, 0}},
|
{ 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 1, 0, 3}},
|
||||||
|
|
||||||
{"Point, Three parallel planes 2", &point, &hull_tpp2,
|
{"Point, Three parallel planes 2", &point, &hull_tpp2,
|
||||||
{-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0}},
|
{-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0, 3}},
|
||||||
{"Point, Three parallel planes 2", &point, &hull_tpp2,
|
{"Point, Three parallel planes 2", &point, &hull_tpp2,
|
||||||
{ 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0}},
|
{ 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0, 3}},
|
||||||
{"Point, Three parallel planes 2", &point, &hull_tpp2,
|
{"Point, Three parallel planes 2", &point, &hull_tpp2,
|
||||||
{ 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0}},
|
{ 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0, 3}},
|
||||||
{"Point, Three parallel planes 2", &point, &hull_tpp2,
|
{"Point, Three parallel planes 2", &point, &hull_tpp2,
|
||||||
{ 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0}},
|
{ 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0, 3}},
|
||||||
|
|
||||||
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
||||||
{-64, 0, 0}, { 64, 0, 0}, { 0.875, 0, 1, 1, 1}},
|
{-64, 0, 0}, { 64, 0, 0}, { 0.875, 0, 1, 1, 1, 3}},
|
||||||
{"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, 3}},
|
||||||
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
||||||
{ 40, 0, 0}, {-88, 0, 0}, {0.5625, 0, 0, 1, 1}},
|
{ 40, 0, 0}, {-88, 0, 0}, {0.5625, 0, 0, 1, 1, 3}},
|
||||||
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
||||||
{ 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 0, 1, 1}},
|
{ 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 0, 1, 1, 3}},
|
||||||
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
||||||
{ 0, 0, 0}, { 0, 8, 0}, { 1, 0, 0, 1, 0}},
|
{ 0, 0, 0}, { 0, 8, 0}, { 1, 0, 0, 1, 0, 3}},
|
||||||
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
{"Point, Three parallel planes with water", &point, &hull_tppw,
|
||||||
{ 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 0, 1}},
|
{ 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 0, 1, 3}},
|
||||||
{"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, 3}},
|
||||||
|
|
||||||
{"Point, Step 1", &point, &hull_step1,
|
{"Point, Step 1", &point, &hull_step1,
|
||||||
{ -16, 0, 8}, {16, 0, 24}, { 0.5, 0, 0, 1, 0}},
|
{ -16, 0, 8}, {16, 0, 24}, { 0.5, 0, 0, 1, 0, 5}},
|
||||||
{"Box, Step 1", &box, &hull_step1,
|
{"Box, Step 1", &box, &hull_step1,
|
||||||
{ -16, 0, 8}, {16, 0, 24}, { 0.25, 0, 0, 1, 0}},
|
{ -16, 0, 8}, {16, 0, 24}, { 0.25, 0, 0, 1, 0, 5}},
|
||||||
{"Box, Step 1", &box, &hull_step1,
|
{"Box, Step 1", &box, &hull_step1,
|
||||||
{ -16, 0, 8}, {16, 0, 40}, { 0.25, 0, 0, 1, 0}},
|
{ -16, 0, 8}, {16, 0, 40}, { 0.25, 0, 0, 1, 0, 5}},
|
||||||
{"Box, Step 1", &box, &hull_step1,
|
{"Box, Step 1", &box, &hull_step1,
|
||||||
{ -16, 0, 8}, {16, 0, 135}, { 0.25, 0, 0, 1, 0}},
|
{ -16, 0, 8}, {16, 0, 135}, { 0.25, 0, 0, 1, 0, 5}},
|
||||||
// 136 is a corner case caused by back/front side issues and 0
|
// 136 is a corner case caused by back/front side issues and 0
|
||||||
{"Box, Step 1", &box, &hull_step1,
|
{"Box, Step 1", &box, &hull_step1,
|
||||||
{ -16, 0, 8}, {16, 0, 137}, { 1, 0, 0, 1, 0}},
|
{ -16, 0, 8}, {16, 0, 137}, { 1, 0, 0, 1, 0, 5}},
|
||||||
|
|
||||||
{"Point, Covered Step", &point, &hull_covered_step,
|
{"Point, Covered Step", &point, &hull_covered_step,
|
||||||
{ -24, 0, 8}, {-24, 0, 72}, { 0.5, 0, 0, 1, 0}},
|
{ -24, 0, 8}, {-24, 0, 72}, { 0.5, 0, 0, 1, 0, 9}},
|
||||||
{"Box, Covered Step", &box, &hull_covered_step,
|
{"Box, Covered Step", &box, &hull_covered_step,
|
||||||
{ -32, 0, 8}, {-32, 0, 72}, { 0.375, 0, 0, 1, 0}},
|
{ -32, 0, 8}, {-32, 0, 72}, { 0.375, 0, 0, 1, 0, 9}},
|
||||||
{"Box, Covered Step", &box, &hull_covered_step,
|
{"Box, Covered Step", &box, &hull_covered_step,
|
||||||
{ -24, 0, 8}, {-24, 0, 72}, { 0.375, 0, 0, 1, 0}},
|
{ -24, 0, 8}, {-24, 0, 72}, { 0.375, 0, 0, 1, 0, 9}},
|
||||||
{"Box, Covered Step", &box, &hull_covered_step,
|
{"Box, Covered Step", &box, &hull_covered_step,
|
||||||
{ -25, 0, 8}, {7, 0, 72}, { 0.375, 0, 0, 1, 0}},
|
{ -25, 0, 8}, {7, 0, 72}, { 0.375, 0, 0, 1, 0, 9}},
|
||||||
{"Box, Covered Step", &box, &hull_covered_step,
|
{"Box, Covered Step", &box, &hull_covered_step,
|
||||||
{ -8, 0, 40}, {-16, 0, 40}, { 0.5, 0, 0, 1, 0}},
|
{ -8, 0, 40}, {-16, 0, 40}, { 0.5, 0, 0, 1, 0, 9}},
|
||||||
{"Box, Covered Step", &box, &hull_covered_step,
|
{"Box, Covered Step", &box, &hull_covered_step,
|
||||||
{ -17, 0, 8}, {-1, 0, 72}, { 1, 0, 0, 1, 0}},
|
{ -17, 0, 8}, {-1, 0, 72}, { 1, 0, 0, 1, 0, 9}},
|
||||||
{"Box, Covered Step", &box, &hull_covered_step,
|
{"Box, Covered Step", &box, &hull_covered_step,
|
||||||
{ -8, 0, 40}, {8, 0, 72}, { 1, 0, 0, 1, 0}},
|
{ -8, 0, 40}, {8, 0, 72}, { 1, 0, 0, 1, 0, 9}},
|
||||||
|
|
||||||
{"Box, Step 2", &box, &hull_step2,
|
{"Box, Step 2", &box, &hull_step2,
|
||||||
{ 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0}},
|
{ 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0, 5}},
|
||||||
{"Box, Step 3", &box, &hull_step3,
|
{"Box, Step 3", &box, &hull_step3,
|
||||||
{ 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0}},
|
{ 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0, 5}},
|
||||||
|
|
||||||
{"Box, Ramp", &box, &hull_ramp,
|
{"Box, Ramp", &box, &hull_ramp,
|
||||||
{ 0, 0, 16}, {0, 0, 0}, { 0.5, 0, 0, 1, 0}},
|
{ 0, 0, 16}, {0, 0, 0}, { 0.5, 0, 0, 1, 0, 4}},
|
||||||
};
|
};
|
||||||
#define num_tests (sizeof (tests) / sizeof (tests[0]))
|
#define num_tests (sizeof (tests) / sizeof (tests[0]))
|
||||||
|
|
||||||
|
@ -378,6 +379,30 @@ do_trace (box_t *box, hull_t *hull, vec3_t start, vec3_t end)
|
||||||
return trace;
|
return trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
run_test (test_t *test)
|
run_test (test_t *test)
|
||||||
{
|
{
|
||||||
|
@ -387,6 +412,81 @@ run_test (test_t *test)
|
||||||
char *expect;
|
char *expect;
|
||||||
char *got;
|
char *got;
|
||||||
static int output = 0;
|
static int output = 0;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0, p = portal_list; p; i++, p = p->next)
|
||||||
|
;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
VectorSubtract (test->end, test->start, end);
|
VectorSubtract (test->end, test->start, end);
|
||||||
VectorMultAdd (test->start, test->expect.frac, end, end);
|
VectorMultAdd (test->start, test->expect.frac, end, end);
|
||||||
|
|
Loading…
Reference in a new issue