mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-07 00:11:39 +00:00
enough whitespace to crush a shambler
This commit is contained in:
parent
afa0b21336
commit
4d520d588d
13 changed files with 2351 additions and 2552 deletions
|
@ -39,7 +39,9 @@ int numbrushplanes;
|
||||||
plane_t planes[MAX_MAP_PLANES];
|
plane_t planes[MAX_MAP_PLANES];
|
||||||
|
|
||||||
int numbrushfaces;
|
int numbrushfaces;
|
||||||
mface_t faces[128]; // beveled clipping hull can generate many extra
|
mface_t faces[128]; // beveled clipping hull can generate
|
||||||
|
|
||||||
|
// many extra
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -49,7 +51,8 @@ CheckFace
|
||||||
Note: this will not catch 0 area polygons
|
Note: this will not catch 0 area polygons
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void CheckFace (face_t *f)
|
void
|
||||||
|
CheckFace (face_t * f)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
vec_t *p1, *p2;
|
vec_t *p1, *p2;
|
||||||
|
@ -57,26 +60,26 @@ void CheckFace (face_t *f)
|
||||||
vec3_t dir, edgenormal, facenormal;
|
vec3_t dir, edgenormal, facenormal;
|
||||||
|
|
||||||
if (f->numpoints < 3)
|
if (f->numpoints < 3)
|
||||||
Sys_Error ("CheckFace: %i points",f->numpoints);
|
Sys_Error ("CheckFace: %i points", f->numpoints);
|
||||||
|
|
||||||
VectorCopy (planes[f->planenum].normal, facenormal);
|
VectorCopy (planes[f->planenum].normal, facenormal);
|
||||||
if (f->planeside)
|
if (f->planeside) {
|
||||||
{
|
|
||||||
VectorSubtract (vec3_origin, facenormal, facenormal);
|
VectorSubtract (vec3_origin, facenormal, facenormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0 ; i<f->numpoints ; i++)
|
for (i = 0; i < f->numpoints; i++) {
|
||||||
{
|
|
||||||
p1 = f->pts[i];
|
p1 = f->pts[i];
|
||||||
|
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j = 0; j < 3; j++)
|
||||||
if (p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE)
|
if (p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE)
|
||||||
Sys_Error ("CheckFace: BUGUS_RANGE: %f",p1[j]);
|
Sys_Error ("CheckFace: BUGUS_RANGE: %f", p1[j]);
|
||||||
|
|
||||||
j = i+1 == f->numpoints ? 0 : i+1;
|
j = i + 1 == f->numpoints ? 0 : i + 1;
|
||||||
|
|
||||||
// check the point is on the face plane
|
// check the point is on the face plane
|
||||||
d = DotProduct (p1, planes[f->planenum].normal) - planes[f->planenum].dist;
|
d =
|
||||||
|
DotProduct (p1,
|
||||||
|
planes[f->planenum].normal) - planes[f->planenum].dist;
|
||||||
if (d < -ON_EPSILON || d > ON_EPSILON)
|
if (d < -ON_EPSILON || d > ON_EPSILON)
|
||||||
Sys_Error ("CheckFace: point off plane");
|
Sys_Error ("CheckFace: point off plane");
|
||||||
|
|
||||||
|
@ -93,8 +96,7 @@ void CheckFace (face_t *f)
|
||||||
edgedist += ON_EPSILON;
|
edgedist += ON_EPSILON;
|
||||||
|
|
||||||
// all other points must be on front side
|
// all other points must be on front side
|
||||||
for (j=0 ; j<f->numpoints ; j++)
|
for (j = 0; j < f->numpoints; j++) {
|
||||||
{
|
|
||||||
if (j == i)
|
if (j == i)
|
||||||
continue;
|
continue;
|
||||||
d = DotProduct (f->pts[j], edgenormal);
|
d = DotProduct (f->pts[j], edgenormal);
|
||||||
|
@ -112,13 +114,13 @@ void CheckFace (face_t *f)
|
||||||
ClearBounds
|
ClearBounds
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void ClearBounds (brushset_t *bs)
|
void
|
||||||
|
ClearBounds (brushset_t * bs)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
for (j=0 ; j<NUM_HULLS ; j++)
|
for (j = 0; j < NUM_HULLS; j++)
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
{
|
|
||||||
bs->mins[i] = 99999;
|
bs->mins[i] = 99999;
|
||||||
bs->maxs[i] = -99999;
|
bs->maxs[i] = -99999;
|
||||||
}
|
}
|
||||||
|
@ -129,12 +131,12 @@ void ClearBounds (brushset_t *bs)
|
||||||
AddToBounds
|
AddToBounds
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void AddToBounds (brushset_t *bs, vec3_t v)
|
void
|
||||||
|
AddToBounds (brushset_t * bs, vec3_t v)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
{
|
|
||||||
if (v[i] < bs->mins[i])
|
if (v[i] < bs->mins[i])
|
||||||
bs->mins[i] = v[i];
|
bs->mins[i] = v[i];
|
||||||
if (v[i] > bs->maxs[i])
|
if (v[i] > bs->maxs[i])
|
||||||
|
@ -144,7 +146,8 @@ void AddToBounds (brushset_t *bs, vec3_t v)
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
int PlaneTypeForNormal (vec3_t normal)
|
int
|
||||||
|
PlaneTypeForNormal (vec3_t normal)
|
||||||
{
|
{
|
||||||
float ax, ay, az;
|
float ax, ay, az;
|
||||||
|
|
||||||
|
@ -155,14 +158,12 @@ int PlaneTypeForNormal (vec3_t normal)
|
||||||
return PLANE_Y;
|
return PLANE_Y;
|
||||||
if (normal[2] == 1.0)
|
if (normal[2] == 1.0)
|
||||||
return PLANE_Z;
|
return PLANE_Z;
|
||||||
if (normal[0] == -1.0 ||
|
if (normal[0] == -1.0 || normal[1] == -1.0 || normal[2] == -1.0)
|
||||||
normal[1] == -1.0 ||
|
|
||||||
normal[2] == -1.0)
|
|
||||||
Sys_Error ("PlaneTypeForNormal: not a canonical vector");
|
Sys_Error ("PlaneTypeForNormal: not a canonical vector");
|
||||||
|
|
||||||
ax = fabs(normal[0]);
|
ax = fabs (normal[0]);
|
||||||
ay = fabs(normal[1]);
|
ay = fabs (normal[1]);
|
||||||
az = fabs(normal[2]);
|
az = fabs (normal[2]);
|
||||||
|
|
||||||
if (ax >= ay && ax >= az)
|
if (ax >= ay && ax >= az)
|
||||||
return PLANE_ANYX;
|
return PLANE_ANYX;
|
||||||
|
@ -174,45 +175,40 @@ int PlaneTypeForNormal (vec3_t normal)
|
||||||
#define DISTEPSILON 0.01
|
#define DISTEPSILON 0.01
|
||||||
#define ANGLEEPSILON 0.00001
|
#define ANGLEEPSILON 0.00001
|
||||||
|
|
||||||
void NormalizePlane (plane_t *dp)
|
void
|
||||||
|
NormalizePlane (plane_t *dp)
|
||||||
{
|
{
|
||||||
vec_t ax, ay, az;
|
vec_t ax, ay, az;
|
||||||
|
|
||||||
if (dp->normal[0] == -1.0)
|
if (dp->normal[0] == -1.0) {
|
||||||
{
|
|
||||||
dp->normal[0] = 1.0;
|
dp->normal[0] = 1.0;
|
||||||
dp->dist = -dp->dist;
|
dp->dist = -dp->dist;
|
||||||
}
|
}
|
||||||
if (dp->normal[1] == -1.0)
|
if (dp->normal[1] == -1.0) {
|
||||||
{
|
|
||||||
dp->normal[1] = 1.0;
|
dp->normal[1] = 1.0;
|
||||||
dp->dist = -dp->dist;
|
dp->dist = -dp->dist;
|
||||||
}
|
}
|
||||||
if (dp->normal[2] == -1.0)
|
if (dp->normal[2] == -1.0) {
|
||||||
{
|
|
||||||
dp->normal[2] = 1.0;
|
dp->normal[2] = 1.0;
|
||||||
dp->dist = -dp->dist;
|
dp->dist = -dp->dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dp->normal[0] == 1.0)
|
if (dp->normal[0] == 1.0) {
|
||||||
{
|
|
||||||
dp->type = PLANE_X;
|
dp->type = PLANE_X;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (dp->normal[1] == 1.0)
|
if (dp->normal[1] == 1.0) {
|
||||||
{
|
|
||||||
dp->type = PLANE_Y;
|
dp->type = PLANE_Y;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (dp->normal[2] == 1.0)
|
if (dp->normal[2] == 1.0) {
|
||||||
{
|
|
||||||
dp->type = PLANE_Z;
|
dp->type = PLANE_Z;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ax = fabs(dp->normal[0]);
|
ax = fabs (dp->normal[0]);
|
||||||
ay = fabs(dp->normal[1]);
|
ay = fabs (dp->normal[1]);
|
||||||
az = fabs(dp->normal[2]);
|
az = fabs (dp->normal[2]);
|
||||||
|
|
||||||
if (ax >= ay && ax >= az)
|
if (ax >= ay && ax >= az)
|
||||||
dp->type = PLANE_ANYX;
|
dp->type = PLANE_ANYX;
|
||||||
|
@ -220,8 +216,7 @@ void NormalizePlane (plane_t *dp)
|
||||||
dp->type = PLANE_ANYY;
|
dp->type = PLANE_ANYY;
|
||||||
else
|
else
|
||||||
dp->type = PLANE_ANYZ;
|
dp->type = PLANE_ANYZ;
|
||||||
if (dp->normal[dp->type-PLANE_ANYX] < 0)
|
if (dp->normal[dp->type - PLANE_ANYX] < 0) {
|
||||||
{
|
|
||||||
VectorSubtract (vec3_origin, dp->normal, dp->normal);
|
VectorSubtract (vec3_origin, dp->normal, dp->normal);
|
||||||
dp->dist = -dp->dist;
|
dp->dist = -dp->dist;
|
||||||
}
|
}
|
||||||
|
@ -235,30 +230,29 @@ FindPlane
|
||||||
Returns a global plane number and the side that will be the front
|
Returns a global plane number and the side that will be the front
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
int FindPlane (plane_t *dplane, int *side)
|
int
|
||||||
|
FindPlane (plane_t *dplane, int *side)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
plane_t *dp, pl;
|
plane_t *dp, pl;
|
||||||
vec_t dot;
|
vec_t dot;
|
||||||
|
|
||||||
dot = VectorLength(dplane->normal);
|
dot = VectorLength (dplane->normal);
|
||||||
if (dot < 1.0 - ANGLEEPSILON || dot > 1.0 + ANGLEEPSILON)
|
if (dot < 1.0 - ANGLEEPSILON || dot > 1.0 + ANGLEEPSILON)
|
||||||
Sys_Error ("FindPlane: normalization error");
|
Sys_Error ("FindPlane: normalization error");
|
||||||
|
|
||||||
pl = *dplane;
|
pl = *dplane;
|
||||||
NormalizePlane (&pl);
|
NormalizePlane (&pl);
|
||||||
if (DotProduct(pl.normal, dplane->normal) > 0)
|
if (DotProduct (pl.normal, dplane->normal) > 0)
|
||||||
*side = 0;
|
*side = 0;
|
||||||
else
|
else
|
||||||
*side = 1;
|
*side = 1;
|
||||||
|
|
||||||
dp = planes;
|
dp = planes;
|
||||||
for (i=0 ; i<numbrushplanes;i++, dp++)
|
for (i = 0; i < numbrushplanes; i++, dp++) {
|
||||||
{
|
|
||||||
dot = DotProduct (dp->normal, pl.normal);
|
dot = DotProduct (dp->normal, pl.normal);
|
||||||
if (dot > 1.0 - ANGLEEPSILON
|
if (dot > 1.0 - ANGLEEPSILON && fabs (dp->dist - pl.dist) < DISTEPSILON) { // regular
|
||||||
&& fabs(dp->dist - pl.dist) < DISTEPSILON )
|
// match
|
||||||
{ // regular match
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,7 +264,7 @@ int FindPlane (plane_t *dplane, int *side)
|
||||||
|
|
||||||
numbrushplanes++;
|
numbrushplanes++;
|
||||||
|
|
||||||
return numbrushplanes-1;
|
return numbrushplanes - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -281,30 +275,29 @@ FindPlane_old
|
||||||
Returns a global plane number and the side that will be the front
|
Returns a global plane number and the side that will be the front
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
int FindPlane_old (plane_t *dplane, int *side)
|
int
|
||||||
|
FindPlane_old (plane_t *dplane, int *side)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
plane_t *dp;
|
plane_t *dp;
|
||||||
vec_t dot, ax, ay, az;
|
vec_t dot, ax, ay, az;
|
||||||
|
|
||||||
dot = VectorLength(dplane->normal);
|
dot = VectorLength (dplane->normal);
|
||||||
if (dot < 1.0 - ANGLEEPSILON || dot > 1.0 + ANGLEEPSILON)
|
if (dot < 1.0 - ANGLEEPSILON || dot > 1.0 + ANGLEEPSILON)
|
||||||
Sys_Error ("FindPlane: normalization error");
|
Sys_Error ("FindPlane: normalization error");
|
||||||
|
|
||||||
dp = planes;
|
dp = planes;
|
||||||
|
|
||||||
for (i=0 ; i<numbrushplanes;i++, dp++)
|
for (i = 0; i < numbrushplanes; i++, dp++) {
|
||||||
{
|
|
||||||
dot = DotProduct (dplane->normal, dp->normal);
|
dot = DotProduct (dplane->normal, dp->normal);
|
||||||
if (dot > 1.0 - ANGLEEPSILON
|
if (dot > 1.0 - ANGLEEPSILON && fabs (dplane->dist - dp->dist) < DISTEPSILON) { // regular
|
||||||
&& fabs(dplane->dist - dp->dist) < DISTEPSILON )
|
// match
|
||||||
{ // regular match
|
|
||||||
*side = 0;
|
*side = 0;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
if (dot < -1.0+ANGLEEPSILON
|
if (dot < -1.0 + ANGLEEPSILON && fabs (dplane->dist + dp->dist) < DISTEPSILON) { // inverse
|
||||||
&& fabs(dplane->dist + dp->dist) < DISTEPSILON )
|
// of
|
||||||
{ // inverse of vector
|
// vector
|
||||||
*side = 1;
|
*side = 1;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -327,32 +320,25 @@ int FindPlane_old (plane_t *dplane, int *side)
|
||||||
dp->type = PLANE_Y;
|
dp->type = PLANE_Y;
|
||||||
else if (dplane->normal[2] == 1.0)
|
else if (dplane->normal[2] == 1.0)
|
||||||
dp->type = PLANE_Z;
|
dp->type = PLANE_Z;
|
||||||
else if (dplane->normal[0] == -1.0)
|
else if (dplane->normal[0] == -1.0) {
|
||||||
{
|
|
||||||
dp->type = PLANE_X;
|
dp->type = PLANE_X;
|
||||||
dp->normal[0] = 1.0;
|
dp->normal[0] = 1.0;
|
||||||
dp->dist = -dp->dist;
|
dp->dist = -dp->dist;
|
||||||
*side = 1;
|
*side = 1;
|
||||||
}
|
} else if (dplane->normal[1] == -1.0) {
|
||||||
else if (dplane->normal[1] == -1.0)
|
|
||||||
{
|
|
||||||
dp->type = PLANE_Y;
|
dp->type = PLANE_Y;
|
||||||
dp->normal[1] = 1.0;
|
dp->normal[1] = 1.0;
|
||||||
dp->dist = -dp->dist;
|
dp->dist = -dp->dist;
|
||||||
*side = 1;
|
*side = 1;
|
||||||
}
|
} else if (dplane->normal[2] == -1.0) {
|
||||||
else if (dplane->normal[2] == -1.0)
|
|
||||||
{
|
|
||||||
dp->type = PLANE_Z;
|
dp->type = PLANE_Z;
|
||||||
dp->normal[2] = 1.0;
|
dp->normal[2] = 1.0;
|
||||||
dp->dist = -dp->dist;
|
dp->dist = -dp->dist;
|
||||||
*side = 1;
|
*side = 1;
|
||||||
}
|
} else {
|
||||||
else
|
ax = fabs (dplane->normal[0]);
|
||||||
{
|
ay = fabs (dplane->normal[1]);
|
||||||
ax = fabs(dplane->normal[0]);
|
az = fabs (dplane->normal[2]);
|
||||||
ay = fabs(dplane->normal[1]);
|
|
||||||
az = fabs(dplane->normal[2]);
|
|
||||||
|
|
||||||
if (ax >= ay && ax >= az)
|
if (ax >= ay && ax >= az)
|
||||||
dp->type = PLANE_ANYX;
|
dp->type = PLANE_ANYX;
|
||||||
|
@ -360,8 +346,7 @@ int FindPlane_old (plane_t *dplane, int *side)
|
||||||
dp->type = PLANE_ANYY;
|
dp->type = PLANE_ANYY;
|
||||||
else
|
else
|
||||||
dp->type = PLANE_ANYZ;
|
dp->type = PLANE_ANYZ;
|
||||||
if (dplane->normal[dp->type-PLANE_ANYX] < 0)
|
if (dplane->normal[dp->type - PLANE_ANYX] < 0) {
|
||||||
{
|
|
||||||
VectorSubtract (vec3_origin, dp->normal, dp->normal);
|
VectorSubtract (vec3_origin, dp->normal, dp->normal);
|
||||||
dp->dist = -dp->dist;
|
dp->dist = -dp->dist;
|
||||||
*side = 1;
|
*side = 1;
|
||||||
|
@ -390,9 +375,10 @@ CreateBrushFaces
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
#define ZERO_EPSILON 0.001
|
#define ZERO_EPSILON 0.001
|
||||||
void CreateBrushFaces (void)
|
void
|
||||||
|
CreateBrushFaces (void)
|
||||||
{
|
{
|
||||||
int i,j, k;
|
int i, j, k;
|
||||||
vec_t r;
|
vec_t r;
|
||||||
face_t *f;
|
face_t *f;
|
||||||
winding_t *w;
|
winding_t *w;
|
||||||
|
@ -404,18 +390,16 @@ void CreateBrushFaces (void)
|
||||||
|
|
||||||
brush_faces = NULL;
|
brush_faces = NULL;
|
||||||
|
|
||||||
for (i=0 ; i<numbrushfaces ; i++)
|
for (i = 0; i < numbrushfaces; i++) {
|
||||||
{
|
|
||||||
mf = &faces[i];
|
mf = &faces[i];
|
||||||
|
|
||||||
w = BaseWindingForPlane (&mf->plane);
|
w = BaseWindingForPlane (&mf->plane);
|
||||||
|
|
||||||
for (j=0 ; j<numbrushfaces && w ; j++)
|
for (j = 0; j < numbrushfaces && w; j++) {
|
||||||
{
|
|
||||||
if (j == i)
|
if (j == i)
|
||||||
continue;
|
continue;
|
||||||
// flip the plane, because we want to keep the back side
|
// flip the plane, because we want to keep the back side
|
||||||
VectorSubtract (vec3_origin,faces[j].plane.normal, plane.normal);
|
VectorSubtract (vec3_origin, faces[j].plane.normal, plane.normal);
|
||||||
plane.dist = -faces[j].plane.dist;
|
plane.dist = -faces[j].plane.dist;
|
||||||
|
|
||||||
w = ClipWinding (w, &plane, false);
|
w = ClipWinding (w, &plane, false);
|
||||||
|
@ -430,12 +414,10 @@ void CreateBrushFaces (void)
|
||||||
if (f->numpoints > MAXEDGES)
|
if (f->numpoints > MAXEDGES)
|
||||||
Sys_Error ("f->numpoints > MAXEDGES");
|
Sys_Error ("f->numpoints > MAXEDGES");
|
||||||
|
|
||||||
for (j=0 ; j<w->numpoints ; j++)
|
for (j = 0; j < w->numpoints; j++) {
|
||||||
{
|
for (k = 0; k < 3; k++) {
|
||||||
for (k=0 ; k<3 ; k++)
|
|
||||||
{
|
|
||||||
r = (int) (w->points[j][k] + 0.5);
|
r = (int) (w->points[j][k] + 0.5);
|
||||||
if ( fabs(w->points[j][k] - r) < ZERO_EPSILON)
|
if (fabs (w->points[j][k] - r) < ZERO_EPSILON)
|
||||||
f->pts[j][k] = r;
|
f->pts[j][k] = r;
|
||||||
else
|
else
|
||||||
f->pts[j][k] = w->points[j][k];
|
f->pts[j][k] = w->points[j][k];
|
||||||
|
@ -468,9 +450,9 @@ This is done by brute force, and could easily get a lot faster if anyone cares.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vec3_t hull_size[3][2] = {
|
vec3_t hull_size[3][2] = {
|
||||||
{ {0, 0, 0}, {0, 0, 0} },
|
{{0, 0, 0}, {0, 0, 0}},
|
||||||
{ {-16,-16,-32}, {16,16,24} },
|
{{-16, -16, -32}, {16, 16, 24}},
|
||||||
{ {-32,-32,-64}, {32,32,24} }
|
{{-32, -32, -64}, {32, 32, 24}}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -479,7 +461,7 @@ vec3_t hull_size[3][2] = {
|
||||||
|
|
||||||
int num_hull_points;
|
int num_hull_points;
|
||||||
vec3_t hull_points[MAX_HULL_POINTS];
|
vec3_t hull_points[MAX_HULL_POINTS];
|
||||||
vec3_t hull_corners[MAX_HULL_POINTS*8];
|
vec3_t hull_corners[MAX_HULL_POINTS * 8];
|
||||||
int num_hull_edges;
|
int num_hull_edges;
|
||||||
int hull_edges[MAX_HULL_EDGES][2];
|
int hull_edges[MAX_HULL_EDGES][2];
|
||||||
|
|
||||||
|
@ -488,7 +470,8 @@ int hull_edges[MAX_HULL_EDGES][2];
|
||||||
AddBrushPlane
|
AddBrushPlane
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
void AddBrushPlane (plane_t *plane)
|
void
|
||||||
|
AddBrushPlane (plane_t *plane)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
plane_t *pl;
|
plane_t *pl;
|
||||||
|
@ -500,11 +483,10 @@ void AddBrushPlane (plane_t *plane)
|
||||||
if (l < 0.999 || l > 1.001)
|
if (l < 0.999 || l > 1.001)
|
||||||
Sys_Error ("AddBrushPlane: bad normal");
|
Sys_Error ("AddBrushPlane: bad normal");
|
||||||
|
|
||||||
for (i=0 ; i<numbrushfaces ; i++)
|
for (i = 0; i < numbrushfaces; i++) {
|
||||||
{
|
|
||||||
pl = &faces[i].plane;
|
pl = &faces[i].plane;
|
||||||
if (VectorCompare (pl->normal, plane->normal)
|
if (VectorCompare (pl->normal, plane->normal)
|
||||||
&& fabs(pl->dist - plane->dist) < ON_EPSILON )
|
&& fabs (pl->dist - plane->dist) < ON_EPSILON)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
faces[i].plane = *plane;
|
faces[i].plane = *plane;
|
||||||
|
@ -521,7 +503,8 @@ Adds the given plane to the brush description if all of the original brush
|
||||||
vertexes can be put on the front side
|
vertexes can be put on the front side
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
void TestAddPlane (plane_t *plane)
|
void
|
||||||
|
TestAddPlane (plane_t *plane)
|
||||||
{
|
{
|
||||||
int i, c;
|
int i, c;
|
||||||
vec_t d;
|
vec_t d;
|
||||||
|
@ -532,14 +515,14 @@ void TestAddPlane (plane_t *plane)
|
||||||
plane_t *pl;
|
plane_t *pl;
|
||||||
|
|
||||||
// see if the plane has allready been added
|
// see if the plane has allready been added
|
||||||
for (i=0 ; i<numbrushfaces ; i++)
|
for (i = 0; i < numbrushfaces; i++) {
|
||||||
{
|
|
||||||
pl = &faces[i].plane;
|
pl = &faces[i].plane;
|
||||||
if (VectorCompare (plane->normal, pl->normal) && fabs(plane->dist - pl->dist) < ON_EPSILON)
|
if (VectorCompare (plane->normal, pl->normal)
|
||||||
|
&& fabs (plane->dist - pl->dist) < ON_EPSILON)
|
||||||
return;
|
return;
|
||||||
VectorSubtract (vec3_origin, plane->normal, inv);
|
VectorSubtract (vec3_origin, plane->normal, inv);
|
||||||
if (VectorCompare (inv, pl->normal) && fabs(plane->dist + pl->dist) < ON_EPSILON)
|
if (VectorCompare (inv, pl->normal)
|
||||||
return;
|
&& fabs (plane->dist + pl->dist) < ON_EPSILON) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check all the corner points
|
// check all the corner points
|
||||||
|
@ -547,29 +530,23 @@ void TestAddPlane (plane_t *plane)
|
||||||
c = num_hull_points * 8;
|
c = num_hull_points * 8;
|
||||||
|
|
||||||
corner = hull_corners[0];
|
corner = hull_corners[0];
|
||||||
for (i=0 ; i<c ; i++, corner += 3)
|
for (i = 0; i < c; i++, corner += 3) {
|
||||||
{
|
|
||||||
d = DotProduct (corner, plane->normal) - plane->dist;
|
d = DotProduct (corner, plane->normal) - plane->dist;
|
||||||
if (d < -ON_EPSILON)
|
if (d < -ON_EPSILON) {
|
||||||
{
|
|
||||||
if (counts[0])
|
if (counts[0])
|
||||||
return;
|
return;
|
||||||
counts[1]++;
|
counts[1]++;
|
||||||
}
|
} else if (d > ON_EPSILON) {
|
||||||
else if (d > ON_EPSILON)
|
|
||||||
{
|
|
||||||
if (counts[1])
|
if (counts[1])
|
||||||
return;
|
return;
|
||||||
counts[0]++;
|
counts[0]++;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
counts[2]++;
|
counts[2]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the plane is a seperator
|
// the plane is a seperator
|
||||||
|
|
||||||
if (counts[0])
|
if (counts[0]) {
|
||||||
{
|
|
||||||
VectorSubtract (vec3_origin, plane->normal, flip.normal);
|
VectorSubtract (vec3_origin, plane->normal, flip.normal);
|
||||||
flip.dist = -plane->dist;
|
flip.dist = -plane->dist;
|
||||||
plane = &flip;
|
plane = &flip;
|
||||||
|
@ -585,24 +562,24 @@ AddHullPoint
|
||||||
Doesn't add if duplicated
|
Doesn't add if duplicated
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
int AddHullPoint (vec3_t p, int hullnum)
|
int
|
||||||
|
AddHullPoint (vec3_t p, int hullnum)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
vec_t *c;
|
vec_t *c;
|
||||||
int x,y,z;
|
int x, y, z;
|
||||||
|
|
||||||
for (i=0 ; i<num_hull_points ; i++)
|
for (i = 0; i < num_hull_points; i++)
|
||||||
if (VectorCompare (p, hull_points[i]))
|
if (VectorCompare (p, hull_points[i]))
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
VectorCopy (p, hull_points[num_hull_points]);
|
VectorCopy (p, hull_points[num_hull_points]);
|
||||||
|
|
||||||
c = hull_corners[i*8];
|
c = hull_corners[i * 8];
|
||||||
|
|
||||||
for (x=0 ; x<2 ; x++)
|
for (x = 0; x < 2; x++)
|
||||||
for (y=0 ; y<2 ; y++)
|
for (y = 0; y < 2; y++)
|
||||||
for (z=0; z<2 ; z++)
|
for (z = 0; z < 2; z++) {
|
||||||
{
|
|
||||||
c[0] = p[0] + hull_size[hullnum][x][0];
|
c[0] = p[0] + hull_size[hullnum][x][0];
|
||||||
c[1] = p[1] + hull_size[hullnum][y][1];
|
c[1] = p[1] + hull_size[hullnum][y][1];
|
||||||
c[2] = p[2] + hull_size[hullnum][z][2];
|
c[2] = p[2] + hull_size[hullnum][z][2];
|
||||||
|
@ -625,7 +602,8 @@ AddHullEdge
|
||||||
Creates all of the hull planes around the given edge, if not done allready
|
Creates all of the hull planes around the given edge, if not done allready
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
void AddHullEdge (vec3_t p1, vec3_t p2, int hullnum)
|
void
|
||||||
|
AddHullEdge (vec3_t p1, vec3_t p2, int hullnum)
|
||||||
{
|
{
|
||||||
int pt1, pt2;
|
int pt1, pt2;
|
||||||
int i;
|
int i;
|
||||||
|
@ -637,9 +615,9 @@ void AddHullEdge (vec3_t p1, vec3_t p2, int hullnum)
|
||||||
pt1 = AddHullPoint (p1, hullnum);
|
pt1 = AddHullPoint (p1, hullnum);
|
||||||
pt2 = AddHullPoint (p2, hullnum);
|
pt2 = AddHullPoint (p2, hullnum);
|
||||||
|
|
||||||
for (i=0 ; i<num_hull_edges ; i++)
|
for (i = 0; i < num_hull_edges; i++)
|
||||||
if ( (hull_edges[i][0] == pt1 && hull_edges[i][1] == pt2)
|
if ((hull_edges[i][0] == pt1 && hull_edges[i][1] == pt2)
|
||||||
|| (hull_edges[i][0] == pt2 && hull_edges[i][1] == pt1) )
|
|| (hull_edges[i][0] == pt2 && hull_edges[i][1] == pt1))
|
||||||
return; // allread added
|
return; // allread added
|
||||||
|
|
||||||
if (num_hull_edges == MAX_HULL_EDGES)
|
if (num_hull_edges == MAX_HULL_EDGES)
|
||||||
|
@ -652,13 +630,11 @@ void AddHullEdge (vec3_t p1, vec3_t p2, int hullnum)
|
||||||
VectorSubtract (p1, p2, edgevec);
|
VectorSubtract (p1, p2, edgevec);
|
||||||
VectorNormalize (edgevec);
|
VectorNormalize (edgevec);
|
||||||
|
|
||||||
for (a=0 ; a<3 ; a++)
|
for (a = 0; a < 3; a++) {
|
||||||
{
|
b = (a + 1) % 3;
|
||||||
b = (a+1)%3;
|
c = (a + 2) % 3;
|
||||||
c = (a+2)%3;
|
for (d = 0; d <= 1; d++)
|
||||||
for (d=0 ; d<=1 ; d++)
|
for (e = 0; e <= 1; e++) {
|
||||||
for (e=0 ; e<=1 ; e++)
|
|
||||||
{
|
|
||||||
VectorCopy (p1, planeorg);
|
VectorCopy (p1, planeorg);
|
||||||
planeorg[b] += hull_size[hullnum][d][b];
|
planeorg[b] += hull_size[hullnum][d][b];
|
||||||
planeorg[c] += hull_size[hullnum][e][c];
|
planeorg[c] += hull_size[hullnum][e][c];
|
||||||
|
@ -668,7 +644,7 @@ void AddHullEdge (vec3_t p1, vec3_t p2, int hullnum)
|
||||||
|
|
||||||
CrossProduct (planevec, edgevec, plane.normal);
|
CrossProduct (planevec, edgevec, plane.normal);
|
||||||
l = VectorLength (plane.normal);
|
l = VectorLength (plane.normal);
|
||||||
if (l < 1-ANGLEEPSILON || l > 1+ANGLEEPSILON)
|
if (l < 1 - ANGLEEPSILON || l > 1 + ANGLEEPSILON)
|
||||||
continue;
|
continue;
|
||||||
plane.dist = DotProduct (planeorg, plane.normal);
|
plane.dist = DotProduct (planeorg, plane.normal);
|
||||||
TestAddPlane (&plane);
|
TestAddPlane (&plane);
|
||||||
|
@ -683,7 +659,8 @@ void AddHullEdge (vec3_t p1, vec3_t p2, int hullnum)
|
||||||
ExpandBrush
|
ExpandBrush
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
void ExpandBrush (int hullnum)
|
void
|
||||||
|
ExpandBrush (int hullnum)
|
||||||
{
|
{
|
||||||
int i, x, s;
|
int i, x, s;
|
||||||
vec3_t corner;
|
vec3_t corner;
|
||||||
|
@ -694,17 +671,15 @@ void ExpandBrush (int hullnum)
|
||||||
num_hull_edges = 0;
|
num_hull_edges = 0;
|
||||||
|
|
||||||
// create all the hull points
|
// create all the hull points
|
||||||
for (f=brush_faces ; f ; f=f->next)
|
for (f = brush_faces; f; f = f->next)
|
||||||
for (i=0 ; i<f->numpoints ; i++)
|
for (i = 0; i < f->numpoints; i++)
|
||||||
AddHullPoint (f->pts[i], hullnum);
|
AddHullPoint (f->pts[i], hullnum);
|
||||||
|
|
||||||
// expand all of the planes
|
// expand all of the planes
|
||||||
for (i=0 ; i<numbrushfaces ; i++)
|
for (i = 0; i < numbrushfaces; i++) {
|
||||||
{
|
|
||||||
p = &faces[i].plane;
|
p = &faces[i].plane;
|
||||||
VectorCopy (vec3_origin, corner);
|
VectorCopy (vec3_origin, corner);
|
||||||
for (x=0 ; x<3 ; x++)
|
for (x = 0; x < 3; x++) {
|
||||||
{
|
|
||||||
if (p->normal[x] > 0)
|
if (p->normal[x] > 0)
|
||||||
corner[x] = hull_size[hullnum][1][x];
|
corner[x] = hull_size[hullnum][1][x];
|
||||||
else if (p->normal[x] < 0)
|
else if (p->normal[x] < 0)
|
||||||
|
@ -714,9 +689,8 @@ void ExpandBrush (int hullnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add any axis planes not contained in the brush to bevel off corners
|
// add any axis planes not contained in the brush to bevel off corners
|
||||||
for (x=0 ; x<3 ; x++)
|
for (x = 0; x < 3; x++)
|
||||||
for (s=-1 ; s<=1 ; s+=2)
|
for (s = -1; s <= 1; s += 2) {
|
||||||
{
|
|
||||||
// add the plane
|
// add the plane
|
||||||
VectorCopy (vec3_origin, plane.normal);
|
VectorCopy (vec3_origin, plane.normal);
|
||||||
plane.normal[x] = s;
|
plane.normal[x] = s;
|
||||||
|
@ -728,9 +702,9 @@ void ExpandBrush (int hullnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add all of the edge bevels
|
// add all of the edge bevels
|
||||||
for (f=brush_faces ; f ; f=f->next)
|
for (f = brush_faces; f; f = f->next)
|
||||||
for (i=0 ; i<f->numpoints ; i++)
|
for (i = 0; i < f->numpoints; i++)
|
||||||
AddHullEdge (f->pts[i], f->pts[(i+1)%f->numpoints], hullnum);
|
AddHullEdge (f->pts[i], f->pts[(i + 1) % f->numpoints], hullnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
@ -743,7 +717,8 @@ LoadBrush
|
||||||
Converts a mapbrush to a bsp brush
|
Converts a mapbrush to a bsp brush
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
brush_t *LoadBrush (mbrush_t *mb, int hullnum)
|
brush_t *
|
||||||
|
LoadBrush (mbrush_t * mb, int hullnum)
|
||||||
{
|
{
|
||||||
brush_t *b;
|
brush_t *b;
|
||||||
int contents;
|
int contents;
|
||||||
|
@ -755,25 +730,26 @@ brush_t *LoadBrush (mbrush_t *mb, int hullnum)
|
||||||
//
|
//
|
||||||
name = miptex[bsp->texinfo[mb->faces->texinfo].miptex];
|
name = miptex[bsp->texinfo[mb->faces->texinfo].miptex];
|
||||||
|
|
||||||
if (!strcasecmp(name, "clip") && hullnum == 0)
|
if (!strcasecmp (name, "clip") && hullnum == 0)
|
||||||
return NULL; // "clip" brushes don't show up in the draw hull
|
return NULL; // "clip" brushes don't show up in
|
||||||
|
// the draw hull
|
||||||
|
|
||||||
if (name[0] == '*' && worldmodel) // entities never use water merging
|
if (name[0] == '*' && worldmodel) // entities never use water merging
|
||||||
{
|
{
|
||||||
if (!strncasecmp(name+1,"lava",4))
|
if (!strncasecmp (name + 1, "lava", 4))
|
||||||
contents = CONTENTS_LAVA;
|
contents = CONTENTS_LAVA;
|
||||||
else if (!strncasecmp(name+1,"slime",5))
|
else if (!strncasecmp (name + 1, "slime", 5))
|
||||||
contents = CONTENTS_SLIME;
|
contents = CONTENTS_SLIME;
|
||||||
else
|
else
|
||||||
contents = CONTENTS_WATER;
|
contents = CONTENTS_WATER;
|
||||||
}
|
} else if (!strncasecmp (name, "sky", 3) && worldmodel && hullnum == 0)
|
||||||
else if (!strncasecmp (name, "sky",3) && worldmodel && hullnum == 0)
|
|
||||||
contents = CONTENTS_SKY;
|
contents = CONTENTS_SKY;
|
||||||
else
|
else
|
||||||
contents = CONTENTS_SOLID;
|
contents = CONTENTS_SOLID;
|
||||||
|
|
||||||
if (hullnum && contents != CONTENTS_SOLID && contents != CONTENTS_SKY)
|
if (hullnum && contents != CONTENTS_SOLID && contents != CONTENTS_SKY)
|
||||||
return NULL; // water brushes don't show up in clipping hulls
|
return NULL; // water brushes don't show up in
|
||||||
|
// clipping hulls
|
||||||
|
|
||||||
// no seperate textures on clip hull
|
// no seperate textures on clip hull
|
||||||
|
|
||||||
|
@ -783,8 +759,7 @@ brush_t *LoadBrush (mbrush_t *mb, int hullnum)
|
||||||
brush_faces = NULL;
|
brush_faces = NULL;
|
||||||
|
|
||||||
numbrushfaces = 0;
|
numbrushfaces = 0;
|
||||||
for (f=mb->faces ; f ; f=f->next)
|
for (f = mb->faces; f; f = f->next) {
|
||||||
{
|
|
||||||
faces[numbrushfaces] = *f;
|
faces[numbrushfaces] = *f;
|
||||||
if (hullnum)
|
if (hullnum)
|
||||||
faces[numbrushfaces].texinfo = 0;
|
faces[numbrushfaces].texinfo = 0;
|
||||||
|
@ -793,18 +768,15 @@ brush_t *LoadBrush (mbrush_t *mb, int hullnum)
|
||||||
|
|
||||||
CreateBrushFaces ();
|
CreateBrushFaces ();
|
||||||
|
|
||||||
if (!brush_faces)
|
if (!brush_faces) {
|
||||||
{
|
|
||||||
printf ("WARNING: couldn't create brush faces\n");
|
printf ("WARNING: couldn't create brush faces\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hullnum)
|
if (hullnum) {
|
||||||
{
|
|
||||||
ExpandBrush (hullnum);
|
ExpandBrush (hullnum);
|
||||||
CreateBrushFaces ();
|
CreateBrushFaces ();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// create the brush
|
// create the brush
|
||||||
//
|
//
|
||||||
|
@ -827,13 +799,14 @@ Brush_DrawAll
|
||||||
|
|
||||||
============
|
============
|
||||||
*/
|
*/
|
||||||
void Brush_DrawAll (brushset_t *bs)
|
void
|
||||||
|
Brush_DrawAll (brushset_t * bs)
|
||||||
{
|
{
|
||||||
brush_t *b;
|
brush_t *b;
|
||||||
face_t *f;
|
face_t *f;
|
||||||
|
|
||||||
for (b=bs->brushes ; b ; b=b->next)
|
for (b = bs->brushes; b; b = b->next)
|
||||||
for (f=b->faces ; f ; f=f->next)
|
for (f = b->faces; f; f = f->next)
|
||||||
Draw_DrawFace (f);
|
Draw_DrawFace (f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -843,15 +816,16 @@ void Brush_DrawAll (brushset_t *bs)
|
||||||
Brush_LoadEntity
|
Brush_LoadEntity
|
||||||
============
|
============
|
||||||
*/
|
*/
|
||||||
brushset_t *Brush_LoadEntity (entity_t *ent, int hullnum)
|
brushset_t *
|
||||||
|
Brush_LoadEntity (entity_t *ent, int hullnum)
|
||||||
{
|
{
|
||||||
brush_t *b, *next, *water, *other;
|
brush_t *b, *next, *water, *other;
|
||||||
mbrush_t *mbr;
|
mbrush_t *mbr;
|
||||||
int numbrushes;
|
int numbrushes;
|
||||||
brushset_t *bset;
|
brushset_t *bset;
|
||||||
|
|
||||||
bset = malloc (sizeof(brushset_t));
|
bset = malloc (sizeof (brushset_t));
|
||||||
memset (bset, 0, sizeof(brushset_t));
|
memset (bset, 0, sizeof (brushset_t));
|
||||||
ClearBounds (bset);
|
ClearBounds (bset);
|
||||||
|
|
||||||
numbrushes = 0;
|
numbrushes = 0;
|
||||||
|
@ -859,21 +833,17 @@ brushset_t *Brush_LoadEntity (entity_t *ent, int hullnum)
|
||||||
|
|
||||||
qprintf ("--- Brush_LoadEntity ---\n");
|
qprintf ("--- Brush_LoadEntity ---\n");
|
||||||
|
|
||||||
for (mbr = ent->brushes ; mbr ; mbr=mbr->next)
|
for (mbr = ent->brushes; mbr; mbr = mbr->next) {
|
||||||
{
|
|
||||||
b = LoadBrush (mbr, hullnum);
|
b = LoadBrush (mbr, hullnum);
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
numbrushes++;
|
numbrushes++;
|
||||||
|
|
||||||
if (b->contents != CONTENTS_SOLID)
|
if (b->contents != CONTENTS_SOLID) {
|
||||||
{
|
|
||||||
b->next = water;
|
b->next = water;
|
||||||
water = b;
|
water = b;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
b->next = other;
|
b->next = other;
|
||||||
other = b;
|
other = b;
|
||||||
}
|
}
|
||||||
|
@ -883,8 +853,7 @@ brushset_t *Brush_LoadEntity (entity_t *ent, int hullnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add all of the water textures at the start
|
// add all of the water textures at the start
|
||||||
for (b=water ; b ; b=next)
|
for (b = water; b; b = next) {
|
||||||
{
|
|
||||||
next = b->next;
|
next = b->next;
|
||||||
b->next = other;
|
b->next = other;
|
||||||
other = b;
|
other = b;
|
||||||
|
@ -895,9 +864,7 @@ brushset_t *Brush_LoadEntity (entity_t *ent, int hullnum)
|
||||||
brushset = bset;
|
brushset = bset;
|
||||||
Brush_DrawAll (bset);
|
Brush_DrawAll (bset);
|
||||||
|
|
||||||
qprintf ("%i brushes read\n",numbrushes);
|
qprintf ("%i brushes read\n", numbrushes);
|
||||||
|
|
||||||
return bset;
|
return bset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,10 @@ int brushfaces;
|
||||||
int csgfaces;
|
int csgfaces;
|
||||||
int csgmergefaces;
|
int csgmergefaces;
|
||||||
|
|
||||||
void DrawList (face_t *list)
|
void
|
||||||
|
DrawList (face_t * list)
|
||||||
{
|
{
|
||||||
for ( ; list ; list=list->next)
|
for (; list; list = list->next)
|
||||||
Draw_DrawFace (list);
|
Draw_DrawFace (list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +59,8 @@ Duplicates the non point information of a face, used by SplitFace and
|
||||||
MergeFace.
|
MergeFace.
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
face_t *NewFaceFromFace (face_t *in)
|
face_t *
|
||||||
|
NewFaceFromFace (face_t * in)
|
||||||
{
|
{
|
||||||
face_t *newf;
|
face_t *newf;
|
||||||
|
|
||||||
|
@ -81,10 +83,11 @@ SplitFace
|
||||||
|
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void SplitFace (face_t *in, plane_t *split, face_t **front, face_t **back)
|
void
|
||||||
|
SplitFace (face_t * in, plane_t *split, face_t ** front, face_t ** back)
|
||||||
{
|
{
|
||||||
vec_t dists[MAXEDGES+1];
|
vec_t dists[MAXEDGES + 1];
|
||||||
int sides[MAXEDGES+1];
|
int sides[MAXEDGES + 1];
|
||||||
int counts[3];
|
int counts[3];
|
||||||
vec_t dot;
|
vec_t dot;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
@ -97,8 +100,7 @@ void SplitFace (face_t *in, plane_t *split, face_t **front, face_t **back)
|
||||||
counts[0] = counts[1] = counts[2] = 0;
|
counts[0] = counts[1] = counts[2] = 0;
|
||||||
|
|
||||||
// determine sides for each point
|
// determine sides for each point
|
||||||
for (i=0 ; i<in->numpoints ; i++)
|
for (i = 0; i < in->numpoints; i++) {
|
||||||
{
|
|
||||||
dot = DotProduct (in->pts[i], split->normal);
|
dot = DotProduct (in->pts[i], split->normal);
|
||||||
dot -= split->dist;
|
dot -= split->dist;
|
||||||
dists[i] = dot;
|
dists[i] = dot;
|
||||||
|
@ -113,14 +115,12 @@ void SplitFace (face_t *in, plane_t *split, face_t **front, face_t **back)
|
||||||
sides[i] = sides[0];
|
sides[i] = sides[0];
|
||||||
dists[i] = dists[0];
|
dists[i] = dists[0];
|
||||||
|
|
||||||
if (!counts[0])
|
if (!counts[0]) {
|
||||||
{
|
|
||||||
*front = NULL;
|
*front = NULL;
|
||||||
*back = in;
|
*back = in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!counts[1])
|
if (!counts[1]) {
|
||||||
{
|
|
||||||
*front = in;
|
*front = in;
|
||||||
*back = NULL;
|
*back = NULL;
|
||||||
return;
|
return;
|
||||||
|
@ -131,15 +131,13 @@ void SplitFace (face_t *in, plane_t *split, face_t **front, face_t **back)
|
||||||
|
|
||||||
// distribute the points and generate splits
|
// distribute the points and generate splits
|
||||||
|
|
||||||
for (i=0 ; i<in->numpoints ; i++)
|
for (i = 0; i < in->numpoints; i++) {
|
||||||
{
|
|
||||||
if (newf->numpoints > MAXEDGES || new2->numpoints > MAXEDGES)
|
if (newf->numpoints > MAXEDGES || new2->numpoints > MAXEDGES)
|
||||||
Sys_Error ("SplitFace: numpoints > MAXEDGES");
|
Sys_Error ("SplitFace: numpoints > MAXEDGES");
|
||||||
|
|
||||||
p1 = in->pts[i];
|
p1 = in->pts[i];
|
||||||
|
|
||||||
if (sides[i] == SIDE_ON)
|
if (sides[i] == SIDE_ON) {
|
||||||
{
|
|
||||||
VectorCopy (p1, newf->pts[newf->numpoints]);
|
VectorCopy (p1, newf->pts[newf->numpoints]);
|
||||||
newf->numpoints++;
|
newf->numpoints++;
|
||||||
VectorCopy (p1, new2->pts[new2->numpoints]);
|
VectorCopy (p1, new2->pts[new2->numpoints]);
|
||||||
|
@ -147,32 +145,29 @@ void SplitFace (face_t *in, plane_t *split, face_t **front, face_t **back)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sides[i] == SIDE_FRONT)
|
if (sides[i] == SIDE_FRONT) {
|
||||||
{
|
|
||||||
VectorCopy (p1, new2->pts[new2->numpoints]);
|
VectorCopy (p1, new2->pts[new2->numpoints]);
|
||||||
new2->numpoints++;
|
new2->numpoints++;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
VectorCopy (p1, newf->pts[newf->numpoints]);
|
VectorCopy (p1, newf->pts[newf->numpoints]);
|
||||||
newf->numpoints++;
|
newf->numpoints++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
|
if (sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// generate a split point
|
// generate a split point
|
||||||
p2 = in->pts[(i+1)%in->numpoints];
|
p2 = in->pts[(i + 1) % in->numpoints];
|
||||||
|
|
||||||
dot = dists[i] / (dists[i]-dists[i+1]);
|
dot = dists[i] / (dists[i] - dists[i + 1]);
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j = 0; j < 3; j++) { // avoid round off error when
|
||||||
{ // avoid round off error when possible
|
// possible
|
||||||
if (split->normal[j] == 1)
|
if (split->normal[j] == 1)
|
||||||
mid[j] = split->dist;
|
mid[j] = split->dist;
|
||||||
else if (split->normal[j] == -1)
|
else if (split->normal[j] == -1)
|
||||||
mid[j] = -split->dist;
|
mid[j] = -split->dist;
|
||||||
else
|
else
|
||||||
mid[j] = p1[j] + dot*(p2[j]-p1[j]);
|
mid[j] = p1[j] + dot * (p2[j] - p1[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorCopy (mid, newf->pts[newf->numpoints]);
|
VectorCopy (mid, newf->pts[newf->numpoints]);
|
||||||
|
@ -185,8 +180,8 @@ void SplitFace (face_t *in, plane_t *split, face_t **front, face_t **back)
|
||||||
Sys_Error ("SplitFace: numpoints > MAXEDGES");
|
Sys_Error ("SplitFace: numpoints > MAXEDGES");
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
CheckFace (newf);
|
CheckFace (newf);
|
||||||
CheckFace (new2);
|
CheckFace (new2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// free the original face now that is is represented by the fragments
|
// free the original face now that is is represented by the fragments
|
||||||
|
@ -205,7 +200,8 @@ Faces exactly on the plane will stay inside unless overdrawn by later brush
|
||||||
frontside is the side of the plane that holds the outside list
|
frontside is the side of the plane that holds the outside list
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void ClipInside (int splitplane, int frontside, qboolean precedence)
|
void
|
||||||
|
ClipInside (int splitplane, int frontside, qboolean precedence)
|
||||||
{
|
{
|
||||||
face_t *f, *next;
|
face_t *f, *next;
|
||||||
face_t *frags[2];
|
face_t *frags[2];
|
||||||
|
@ -215,35 +211,28 @@ void ClipInside (int splitplane, int frontside, qboolean precedence)
|
||||||
split = &planes[splitplane];
|
split = &planes[splitplane];
|
||||||
|
|
||||||
insidelist = NULL;
|
insidelist = NULL;
|
||||||
for (f=inside ; f ; f=next)
|
for (f = inside; f; f = next) {
|
||||||
{
|
|
||||||
next = f->next;
|
next = f->next;
|
||||||
|
|
||||||
if (f->planenum == splitplane)
|
if (f->planenum == splitplane) { // exactly on, handle special
|
||||||
{ // exactly on, handle special
|
if (frontside != f->planeside || precedence) { // allways clip
|
||||||
if ( frontside != f->planeside || precedence )
|
// off opposite
|
||||||
{ // allways clip off opposite faceing
|
// faceing
|
||||||
frags[frontside] = NULL;
|
frags[frontside] = NULL;
|
||||||
frags[!frontside] = f;
|
frags[!frontside] = f;
|
||||||
}
|
} else { // leave it on the outside
|
||||||
else
|
|
||||||
{ // leave it on the outside
|
|
||||||
frags[frontside] = f;
|
frags[frontside] = f;
|
||||||
frags[!frontside] = NULL;
|
frags[!frontside] = NULL;
|
||||||
}
|
}
|
||||||
}
|
} else { // proper split
|
||||||
else
|
|
||||||
{ // proper split
|
|
||||||
SplitFace (f, split, &frags[0], &frags[1]);
|
SplitFace (f, split, &frags[0], &frags[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frags[frontside])
|
if (frags[frontside]) {
|
||||||
{
|
|
||||||
frags[frontside]->next = outside;
|
frags[frontside]->next = outside;
|
||||||
outside = frags[frontside];
|
outside = frags[frontside];
|
||||||
}
|
}
|
||||||
if (frags[!frontside])
|
if (frags[!frontside]) {
|
||||||
{
|
|
||||||
frags[!frontside]->next = insidelist;
|
frags[!frontside]->next = insidelist;
|
||||||
insidelist = frags[!frontside];
|
insidelist = frags[!frontside];
|
||||||
}
|
}
|
||||||
|
@ -260,21 +249,20 @@ SaveOutside
|
||||||
Saves all of the faces in the outside list to the bsp plane list
|
Saves all of the faces in the outside list to the bsp plane list
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void SaveOutside (qboolean mirror)
|
void
|
||||||
|
SaveOutside (qboolean mirror)
|
||||||
{
|
{
|
||||||
face_t *f , *next, *newf;
|
face_t *f, *next, *newf;
|
||||||
int i;
|
int i;
|
||||||
int planenum;
|
int planenum;
|
||||||
|
|
||||||
for (f=outside ; f ; f=next)
|
for (f = outside; f; f = next) {
|
||||||
{
|
|
||||||
next = f->next;
|
next = f->next;
|
||||||
csgfaces++;
|
csgfaces++;
|
||||||
Draw_DrawFace (f);
|
Draw_DrawFace (f);
|
||||||
planenum = f->planenum;
|
planenum = f->planenum;
|
||||||
|
|
||||||
if (mirror)
|
if (mirror) {
|
||||||
{
|
|
||||||
newf = NewFaceFromFace (f);
|
newf = NewFaceFromFace (f);
|
||||||
|
|
||||||
newf->numpoints = f->numpoints;
|
newf->numpoints = f->numpoints;
|
||||||
|
@ -282,17 +270,16 @@ void SaveOutside (qboolean mirror)
|
||||||
newf->contents[0] = f->contents[1];
|
newf->contents[0] = f->contents[1];
|
||||||
newf->contents[1] = f->contents[0];
|
newf->contents[1] = f->contents[0];
|
||||||
|
|
||||||
for (i=0 ; i<f->numpoints ; i++) // add points backwards
|
for (i = 0; i < f->numpoints; i++) // add points backwards
|
||||||
{
|
{
|
||||||
VectorCopy (f->pts[f->numpoints-1-i], newf->pts[i]);
|
VectorCopy (f->pts[f->numpoints - 1 - i], newf->pts[i]);
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
newf = NULL;
|
newf = NULL;
|
||||||
|
|
||||||
validfaces[planenum] = MergeFaceToList(f, validfaces[planenum]);
|
validfaces[planenum] = MergeFaceToList (f, validfaces[planenum]);
|
||||||
if (newf)
|
if (newf)
|
||||||
validfaces[planenum] = MergeFaceToList(newf, validfaces[planenum]);
|
validfaces[planenum] = MergeFaceToList (newf, validfaces[planenum]);
|
||||||
|
|
||||||
validfaces[planenum] = FreeMergeListScraps (validfaces[planenum]);
|
validfaces[planenum] = FreeMergeListScraps (validfaces[planenum]);
|
||||||
}
|
}
|
||||||
|
@ -305,21 +292,19 @@ FreeInside
|
||||||
Free all the faces that got clipped out
|
Free all the faces that got clipped out
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void FreeInside (int contents)
|
void
|
||||||
|
FreeInside (int contents)
|
||||||
{
|
{
|
||||||
face_t *f, *next;
|
face_t *f, *next;
|
||||||
|
|
||||||
for (f=inside ; f ; f=next)
|
for (f = inside; f; f = next) {
|
||||||
{
|
|
||||||
next = f->next;
|
next = f->next;
|
||||||
|
|
||||||
if (contents != CONTENTS_SOLID)
|
if (contents != CONTENTS_SOLID) {
|
||||||
{
|
|
||||||
f->contents[0] = contents;
|
f->contents[0] = contents;
|
||||||
f->next = outside;
|
f->next = outside;
|
||||||
outside = f;
|
outside = f;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
FreeFace (f);
|
FreeFace (f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -335,7 +320,8 @@ Returns a chain of all the external surfaces with one or more visible
|
||||||
faces.
|
faces.
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
surface_t *BuildSurfaces (void)
|
surface_t *
|
||||||
|
BuildSurfaces (void)
|
||||||
{
|
{
|
||||||
face_t **f;
|
face_t **f;
|
||||||
face_t *count;
|
face_t *count;
|
||||||
|
@ -346,8 +332,7 @@ surface_t *BuildSurfaces (void)
|
||||||
surfhead = NULL;
|
surfhead = NULL;
|
||||||
|
|
||||||
f = validfaces;
|
f = validfaces;
|
||||||
for (i=0 ; i<numbrushplanes ; i++, f++)
|
for (i = 0; i < numbrushplanes; i++, f++) {
|
||||||
{
|
|
||||||
if (!*f)
|
if (!*f)
|
||||||
continue; // nothing left on this plane
|
continue; // nothing left on this plane
|
||||||
|
|
||||||
|
@ -357,7 +342,7 @@ surface_t *BuildSurfaces (void)
|
||||||
s->next = surfhead;
|
s->next = surfhead;
|
||||||
surfhead = s;
|
surfhead = s;
|
||||||
s->faces = *f;
|
s->faces = *f;
|
||||||
for (count = s->faces ; count ; count=count->next)
|
for (count = s->faces; count; count = count->next)
|
||||||
csgmergefaces++;
|
csgmergefaces++;
|
||||||
CalcSurfaceInfo (s); // bounding box and flags
|
CalcSurfaceInfo (s); // bounding box and flags
|
||||||
}
|
}
|
||||||
|
@ -372,23 +357,24 @@ surface_t *BuildSurfaces (void)
|
||||||
CopyFacesToOutside
|
CopyFacesToOutside
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void CopyFacesToOutside (brush_t *b)
|
void
|
||||||
|
CopyFacesToOutside (brush_t * b)
|
||||||
{
|
{
|
||||||
face_t *f, *newf;
|
face_t *f, *newf;
|
||||||
|
|
||||||
outside = NULL;
|
outside = NULL;
|
||||||
|
|
||||||
for (f=b->faces ; f ; f=f->next)
|
for (f = b->faces; f; f = f->next) {
|
||||||
{
|
|
||||||
brushfaces++;
|
brushfaces++;
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0 ; i<f->numpoints ; i++)
|
for (i = 0; i < f->numpoints; i++)
|
||||||
printf ("(%f,%f,%f) ",f->pts[i][0], f->pts[i][1], f->pts[i][2]);
|
printf ("(%f,%f,%f) ", f->pts[i][0], f->pts[i][1],
|
||||||
|
f->pts[i][2]);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
newf = AllocFace ();
|
newf = AllocFace ();
|
||||||
*newf = *f;
|
*newf = *f;
|
||||||
|
@ -407,7 +393,8 @@ CSGFaces
|
||||||
Returns a list of surfaces containing aall of the faces
|
Returns a list of surfaces containing aall of the faces
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
surface_t *CSGFaces (brushset_t *bs)
|
surface_t *
|
||||||
|
CSGFaces (brushset_t * bs)
|
||||||
{
|
{
|
||||||
brush_t *b1, *b2;
|
brush_t *b1, *b2;
|
||||||
int i;
|
int i;
|
||||||
|
@ -417,7 +404,7 @@ surface_t *CSGFaces (brushset_t *bs)
|
||||||
|
|
||||||
qprintf ("---- CSGFaces ----\n");
|
qprintf ("---- CSGFaces ----\n");
|
||||||
|
|
||||||
memset (validfaces, 0, sizeof(validfaces));
|
memset (validfaces, 0, sizeof (validfaces));
|
||||||
|
|
||||||
csgfaces = brushfaces = csgmergefaces = 0;
|
csgfaces = brushfaces = csgmergefaces = 0;
|
||||||
|
|
||||||
|
@ -426,28 +413,24 @@ surface_t *CSGFaces (brushset_t *bs)
|
||||||
//
|
//
|
||||||
// do the solid faces
|
// do the solid faces
|
||||||
//
|
//
|
||||||
for (b1=bs->brushes ; b1 ; b1 = b1->next)
|
for (b1 = bs->brushes; b1; b1 = b1->next) {
|
||||||
{
|
|
||||||
// set outside to a copy of the brush's faces
|
// set outside to a copy of the brush's faces
|
||||||
CopyFacesToOutside (b1);
|
CopyFacesToOutside (b1);
|
||||||
|
|
||||||
overwrite = false;
|
overwrite = false;
|
||||||
|
|
||||||
for (b2=bs->brushes ; b2 ; b2 = b2->next)
|
for (b2 = bs->brushes; b2; b2 = b2->next) {
|
||||||
{
|
|
||||||
// see if b2 needs to clip a chunk out of b1
|
// see if b2 needs to clip a chunk out of b1
|
||||||
|
|
||||||
if (b1==b2)
|
if (b1 == b2) {
|
||||||
{
|
|
||||||
overwrite = true; // later brushes now overwrite
|
overwrite = true; // later brushes now overwrite
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check bounding box first
|
// check bounding box first
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i = 0; i < 3; i++)
|
||||||
if (b1->mins[i] > b2->maxs[i] || b1->maxs[i] < b2->mins[i])
|
if (b1->mins[i] > b2->maxs[i] || b1->maxs[i] < b2->mins[i])
|
||||||
break;
|
break;
|
||||||
if (i<3)
|
if (i < 3)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// divide faces by the planes of the new brush
|
// divide faces by the planes of the new brush
|
||||||
|
@ -455,12 +438,12 @@ surface_t *CSGFaces (brushset_t *bs)
|
||||||
inside = outside;
|
inside = outside;
|
||||||
outside = NULL;
|
outside = NULL;
|
||||||
|
|
||||||
for (f=b2->faces ; f ; f=f->next)
|
for (f = b2->faces; f; f = f->next)
|
||||||
ClipInside (f->planenum, f->planeside, overwrite);
|
ClipInside (f->planenum, f->planeside, overwrite);
|
||||||
|
|
||||||
// these faces are continued in another brush, so get rid of them
|
// these faces are continued in another brush, so get rid of them
|
||||||
if (b1->contents == CONTENTS_SOLID && b2->contents <= CONTENTS_WATER)
|
if (b1->contents == CONTENTS_SOLID
|
||||||
FreeInside (b2->contents);
|
&& b2->contents <= CONTENTS_WATER) FreeInside (b2->contents);
|
||||||
else
|
else
|
||||||
FreeInside (CONTENTS_SOLID);
|
FreeInside (CONTENTS_SOLID);
|
||||||
}
|
}
|
||||||
|
@ -485,5 +468,3 @@ surface_t *CSGFaces (brushset_t *bs)
|
||||||
|
|
||||||
return surfhead;
|
return surfhead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -52,12 +52,12 @@ FindMiptex
|
||||||
|
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
int FindMiptex (char *name)
|
int
|
||||||
|
FindMiptex (char *name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0 ; i<nummiptex ; i++)
|
for (i = 0; i < nummiptex; i++) {
|
||||||
{
|
|
||||||
if (!strcmp (name, miptex[i]))
|
if (!strcmp (name, miptex[i]))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -75,26 +75,25 @@ FindTexinfo
|
||||||
Returns a global texinfo number
|
Returns a global texinfo number
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
int FindTexinfo (texinfo_t *t)
|
int
|
||||||
|
FindTexinfo (texinfo_t *t)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
texinfo_t *tex;
|
texinfo_t *tex;
|
||||||
|
|
||||||
// set the special flag
|
// set the special flag
|
||||||
if (miptex[t->miptex][0] == '*'
|
if (miptex[t->miptex][0] == '*'
|
||||||
|| !strncasecmp (miptex[t->miptex], "sky",3) )
|
|| !strncasecmp (miptex[t->miptex], "sky", 3)) t->flags |= TEX_SPECIAL;
|
||||||
t->flags |= TEX_SPECIAL;
|
|
||||||
|
|
||||||
|
|
||||||
tex = bsp->texinfo;
|
tex = bsp->texinfo;
|
||||||
for (i=0 ; i<bsp->numtexinfo;i++, tex++)
|
for (i = 0; i < bsp->numtexinfo; i++, tex++) {
|
||||||
{
|
|
||||||
if (t->miptex != tex->miptex)
|
if (t->miptex != tex->miptex)
|
||||||
continue;
|
continue;
|
||||||
if (t->flags != tex->flags)
|
if (t->flags != tex->flags)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (j=0 ; j<8 ; j++)
|
for (j = 0; j < 8; j++)
|
||||||
if (t->vecs[0][j] != tex->vecs[0][j])
|
if (t->vecs[0][j] != tex->vecs[0][j])
|
||||||
break;
|
break;
|
||||||
if (j != 8)
|
if (j != 8)
|
||||||
|
@ -122,14 +121,16 @@ qboolean unget;
|
||||||
char *script_p;
|
char *script_p;
|
||||||
int scriptline;
|
int scriptline;
|
||||||
|
|
||||||
void StartTokenParsing (char *data)
|
void
|
||||||
|
StartTokenParsing (char *data)
|
||||||
{
|
{
|
||||||
scriptline = 1;
|
scriptline = 1;
|
||||||
script_p = data;
|
script_p = data;
|
||||||
unget = false;
|
unget = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean GetToken (qboolean crossline)
|
qboolean
|
||||||
|
GetToken (qboolean crossline)
|
||||||
{
|
{
|
||||||
char *token_p;
|
char *token_p;
|
||||||
|
|
||||||
|
@ -139,19 +140,16 @@ qboolean GetToken (qboolean crossline)
|
||||||
//
|
//
|
||||||
// skip space
|
// skip space
|
||||||
//
|
//
|
||||||
skipspace:
|
skipspace:
|
||||||
while (*script_p <= 32)
|
while (*script_p <= 32) {
|
||||||
{
|
if (!*script_p) {
|
||||||
if (!*script_p)
|
|
||||||
{
|
|
||||||
if (!crossline)
|
if (!crossline)
|
||||||
Sys_Error ("Line %i is incomplete",scriptline);
|
Sys_Error ("Line %i is incomplete", scriptline);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (*script_p++ == '\n')
|
if (*script_p++ == '\n') {
|
||||||
{
|
|
||||||
if (!crossline)
|
if (!crossline)
|
||||||
Sys_Error ("Line %i is incomplete",scriptline);
|
Sys_Error ("Line %i is incomplete", scriptline);
|
||||||
scriptline++;
|
scriptline++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,40 +157,35 @@ skipspace:
|
||||||
if (script_p[0] == '/' && script_p[1] == '/') // comment field
|
if (script_p[0] == '/' && script_p[1] == '/') // comment field
|
||||||
{
|
{
|
||||||
if (!crossline)
|
if (!crossline)
|
||||||
Sys_Error ("Line %i is incomplete\n",scriptline);
|
Sys_Error ("Line %i is incomplete\n", scriptline);
|
||||||
while (*script_p++ != '\n')
|
while (*script_p++ != '\n')
|
||||||
if (!*script_p)
|
if (!*script_p) {
|
||||||
{
|
|
||||||
if (!crossline)
|
if (!crossline)
|
||||||
Sys_Error ("Line %i is incomplete",scriptline);
|
Sys_Error ("Line %i is incomplete", scriptline);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
goto skipspace;
|
goto skipspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// copy token
|
// copy token
|
||||||
//
|
//
|
||||||
token_p = token;
|
token_p = token;
|
||||||
|
|
||||||
if (*script_p == '"')
|
if (*script_p == '"') {
|
||||||
{
|
|
||||||
script_p++;
|
script_p++;
|
||||||
while ( *script_p != '"' )
|
while (*script_p != '"') {
|
||||||
{
|
|
||||||
if (!*script_p)
|
if (!*script_p)
|
||||||
Sys_Error ("EOF inside quoted token");
|
Sys_Error ("EOF inside quoted token");
|
||||||
*token_p++ = *script_p++;
|
*token_p++ = *script_p++;
|
||||||
if (token_p > &token[MAXTOKEN-1])
|
if (token_p > &token[MAXTOKEN - 1])
|
||||||
Sys_Error ("Token too large on line %i",scriptline);
|
Sys_Error ("Token too large on line %i", scriptline);
|
||||||
}
|
}
|
||||||
script_p++;
|
script_p++;
|
||||||
}
|
} else
|
||||||
else while ( *script_p > 32 )
|
while (*script_p > 32) {
|
||||||
{
|
|
||||||
*token_p++ = *script_p++;
|
*token_p++ = *script_p++;
|
||||||
if (token_p > &token[MAXTOKEN-1])
|
if (token_p > &token[MAXTOKEN - 1])
|
||||||
Sys_Error ("Token too large on line %i",scriptline);
|
Sys_Error ("Token too large on line %i", scriptline);
|
||||||
}
|
}
|
||||||
|
|
||||||
*token_p = 0;
|
*token_p = 0;
|
||||||
|
@ -200,7 +193,8 @@ skipspace:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UngetToken ()
|
void
|
||||||
|
UngetToken ()
|
||||||
{
|
{
|
||||||
unget = true;
|
unget = true;
|
||||||
}
|
}
|
||||||
|
@ -215,20 +209,21 @@ entity_t *mapent;
|
||||||
ParseEpair
|
ParseEpair
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void ParseEpair (void)
|
void
|
||||||
|
ParseEpair (void)
|
||||||
{
|
{
|
||||||
epair_t *e;
|
epair_t *e;
|
||||||
|
|
||||||
e = malloc (sizeof(epair_t));
|
e = malloc (sizeof (epair_t));
|
||||||
memset (e, 0, sizeof(epair_t));
|
memset (e, 0, sizeof (epair_t));
|
||||||
e->next = mapent->epairs;
|
e->next = mapent->epairs;
|
||||||
mapent->epairs = e;
|
mapent->epairs = e;
|
||||||
|
|
||||||
if (strlen(token) >= MAX_KEY-1)
|
if (strlen (token) >= MAX_KEY - 1)
|
||||||
Sys_Error ("ParseEpar: token too long");
|
Sys_Error ("ParseEpar: token too long");
|
||||||
e->key = strdup (token);
|
e->key = strdup (token);
|
||||||
GetToken (false);
|
GetToken (false);
|
||||||
if (strlen(token) >= MAX_VALUE-1)
|
if (strlen (token) >= MAX_VALUE - 1)
|
||||||
Sys_Error ("ParseEpar: token too long");
|
Sys_Error ("ParseEpar: token too long");
|
||||||
e->value = strdup (token);
|
e->value = strdup (token);
|
||||||
}
|
}
|
||||||
|
@ -241,37 +236,35 @@ void ParseEpair (void)
|
||||||
textureAxisFromPlane
|
textureAxisFromPlane
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
vec3_t baseaxis[18] =
|
vec3_t baseaxis[18] = {
|
||||||
{
|
{0, 0, 1}, {1, 0, 0}, {0, -1, 0}, // floor
|
||||||
{0,0,1}, {1,0,0}, {0,-1,0}, // floor
|
{0, 0, -1}, {1, 0, 0}, {0, -1, 0}, // ceiling
|
||||||
{0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling
|
{1, 0, 0}, {0, 1, 0}, {0, 0, -1}, // west wall
|
||||||
{1,0,0}, {0,1,0}, {0,0,-1}, // west wall
|
{-1, 0, 0}, {0, 1, 0}, {0, 0, -1}, // east wall
|
||||||
{-1,0,0}, {0,1,0}, {0,0,-1}, // east wall
|
{0, 1, 0}, {1, 0, 0}, {0, 0, -1}, // south wall
|
||||||
{0,1,0}, {1,0,0}, {0,0,-1}, // south wall
|
{0, -1, 0}, {1, 0, 0}, {0, 0, -1} // north wall
|
||||||
{0,-1,0}, {1,0,0}, {0,0,-1} // north wall
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv)
|
void
|
||||||
|
TextureAxisFromPlane (plane_t *pln, vec3_t xv, vec3_t yv)
|
||||||
{
|
{
|
||||||
int bestaxis;
|
int bestaxis;
|
||||||
float dot,best;
|
float dot, best;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
best = 0;
|
best = 0;
|
||||||
bestaxis = 0;
|
bestaxis = 0;
|
||||||
|
|
||||||
for (i=0 ; i<6 ; i++)
|
for (i = 0; i < 6; i++) {
|
||||||
{
|
dot = DotProduct (pln->normal, baseaxis[i * 3]);
|
||||||
dot = DotProduct (pln->normal, baseaxis[i*3]);
|
if (dot > best) {
|
||||||
if (dot > best)
|
|
||||||
{
|
|
||||||
best = dot;
|
best = dot;
|
||||||
bestaxis = i;
|
bestaxis = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorCopy (baseaxis[bestaxis*3+1], xv);
|
VectorCopy (baseaxis[bestaxis * 3 + 1], xv);
|
||||||
VectorCopy (baseaxis[bestaxis*3+2], yv);
|
VectorCopy (baseaxis[bestaxis * 3 + 2], yv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -283,13 +276,14 @@ void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv)
|
||||||
ParseBrush
|
ParseBrush
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void ParseBrush (void)
|
void
|
||||||
|
ParseBrush (void)
|
||||||
{
|
{
|
||||||
mbrush_t *b;
|
mbrush_t *b;
|
||||||
mface_t *f, *f2;
|
mface_t *f, *f2;
|
||||||
vec3_t planepts[3];
|
vec3_t planepts[3];
|
||||||
vec3_t t1, t2, t3;
|
vec3_t t1, t2, t3;
|
||||||
int i,j;
|
int i, j;
|
||||||
texinfo_t tx;
|
texinfo_t tx;
|
||||||
vec_t d;
|
vec_t d;
|
||||||
float shift[2], rotate, scale[2];
|
float shift[2], rotate, scale[2];
|
||||||
|
@ -299,82 +293,74 @@ void ParseBrush (void)
|
||||||
b->next = mapent->brushes;
|
b->next = mapent->brushes;
|
||||||
mapent->brushes = b;
|
mapent->brushes = b;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
if (!GetToken (true))
|
if (!GetToken (true))
|
||||||
break;
|
break;
|
||||||
if (!strcmp (token, "}") )
|
if (!strcmp (token, "}"))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// read the three point plane definition
|
// read the three point plane definition
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
{
|
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
GetToken (true);
|
GetToken (true);
|
||||||
if (strcmp (token, "(") )
|
if (strcmp (token, "("))
|
||||||
Sys_Error ("parsing brush");
|
Sys_Error ("parsing brush");
|
||||||
|
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j = 0; j < 3; j++) {
|
||||||
{
|
|
||||||
GetToken (false);
|
GetToken (false);
|
||||||
planepts[i][j] = atoi(token);
|
planepts[i][j] = atoi (token);
|
||||||
}
|
}
|
||||||
|
|
||||||
GetToken (false);
|
GetToken (false);
|
||||||
if (strcmp (token, ")") )
|
if (strcmp (token, ")"))
|
||||||
Sys_Error ("parsing brush");
|
Sys_Error ("parsing brush");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the texturedef
|
// read the texturedef
|
||||||
memset (&tx, 0, sizeof(tx));
|
memset (&tx, 0, sizeof (tx));
|
||||||
GetToken (false);
|
GetToken (false);
|
||||||
tx.miptex = FindMiptex (token);
|
tx.miptex = FindMiptex (token);
|
||||||
GetToken (false);
|
GetToken (false);
|
||||||
shift[0] = atoi(token);
|
shift[0] = atoi (token);
|
||||||
GetToken (false);
|
GetToken (false);
|
||||||
shift[1] = atoi(token);
|
shift[1] = atoi (token);
|
||||||
GetToken (false);
|
GetToken (false);
|
||||||
rotate = atoi(token);
|
rotate = atoi (token);
|
||||||
GetToken (false);
|
GetToken (false);
|
||||||
scale[0] = atof(token);
|
scale[0] = atof (token);
|
||||||
GetToken (false);
|
GetToken (false);
|
||||||
scale[1] = atof(token);
|
scale[1] = atof (token);
|
||||||
|
|
||||||
// if the three points are all on a previous plane, it is a
|
// if the three points are all on a previous plane, it is a
|
||||||
// duplicate plane
|
// duplicate plane
|
||||||
for (f2 = b->faces ; f2 ; f2=f2->next)
|
for (f2 = b->faces; f2; f2 = f2->next) {
|
||||||
{
|
for (i = 0; i < 3; i++) {
|
||||||
for (i=0 ; i<3 ; i++)
|
d = DotProduct (planepts[i], f2->plane.normal) - f2->plane.dist;
|
||||||
{
|
|
||||||
d = DotProduct(planepts[i],f2->plane.normal) - f2->plane.dist;
|
|
||||||
if (d < -ON_EPSILON || d > ON_EPSILON)
|
if (d < -ON_EPSILON || d > ON_EPSILON)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i==3)
|
if (i == 3)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (f2)
|
if (f2) {
|
||||||
{
|
|
||||||
printf ("WARNING: brush with duplicate plane\n");
|
printf ("WARNING: brush with duplicate plane\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
f = malloc(sizeof(mface_t));
|
f = malloc (sizeof (mface_t));
|
||||||
f->next = b->faces;
|
f->next = b->faces;
|
||||||
b->faces = f;
|
b->faces = f;
|
||||||
|
|
||||||
// convert to a vector / dist plane
|
// convert to a vector / dist plane
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j = 0; j < 3; j++) {
|
||||||
{
|
|
||||||
t1[j] = planepts[0][j] - planepts[1][j];
|
t1[j] = planepts[0][j] - planepts[1][j];
|
||||||
t2[j] = planepts[2][j] - planepts[1][j];
|
t2[j] = planepts[2][j] - planepts[1][j];
|
||||||
t3[j] = planepts[1][j];
|
t3[j] = planepts[1][j];
|
||||||
}
|
}
|
||||||
|
|
||||||
CrossProduct(t1,t2, f->plane.normal);
|
CrossProduct (t1, t2, f->plane.normal);
|
||||||
if (VectorCompare (f->plane.normal, vec3_origin))
|
if (VectorCompare (f->plane.normal, vec3_origin)) {
|
||||||
{
|
|
||||||
printf ("WARNING: brush plane with no normal\n");
|
printf ("WARNING: brush plane with no normal\n");
|
||||||
b->faces = f->next;
|
b->faces = f->next;
|
||||||
free (f);
|
free (f);
|
||||||
|
@ -392,7 +378,7 @@ void ParseBrush (void)
|
||||||
float ang, sinv, cosv;
|
float ang, sinv, cosv;
|
||||||
float ns, nt;
|
float ns, nt;
|
||||||
|
|
||||||
TextureAxisFromPlane(&f->plane, vecs[0], vecs[1]);
|
TextureAxisFromPlane (&f->plane, vecs[0], vecs[1]);
|
||||||
|
|
||||||
if (!scale[0])
|
if (!scale[0])
|
||||||
scale[0] = 1;
|
scale[0] = 1;
|
||||||
|
@ -401,19 +387,22 @@ void ParseBrush (void)
|
||||||
|
|
||||||
|
|
||||||
// rotate axis
|
// rotate axis
|
||||||
if (rotate == 0)
|
if (rotate == 0) {
|
||||||
{ sinv = 0 ; cosv = 1; }
|
sinv = 0;
|
||||||
else if (rotate == 90)
|
cosv = 1;
|
||||||
{ sinv = 1 ; cosv = 0; }
|
} else if (rotate == 90) {
|
||||||
else if (rotate == 180)
|
sinv = 1;
|
||||||
{ sinv = 0 ; cosv = -1; }
|
cosv = 0;
|
||||||
else if (rotate == 270)
|
} else if (rotate == 180) {
|
||||||
{ sinv = -1 ; cosv = 0; }
|
sinv = 0;
|
||||||
else
|
cosv = -1;
|
||||||
{
|
} else if (rotate == 270) {
|
||||||
|
sinv = -1;
|
||||||
|
cosv = 0;
|
||||||
|
} else {
|
||||||
ang = rotate / 180 * M_PI;
|
ang = rotate / 180 * M_PI;
|
||||||
sinv = sin(ang);
|
sinv = sin (ang);
|
||||||
cosv = cos(ang);
|
cosv = cos (ang);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vecs[0][0])
|
if (vecs[0][0])
|
||||||
|
@ -430,16 +419,15 @@ void ParseBrush (void)
|
||||||
else
|
else
|
||||||
tv = 2;
|
tv = 2;
|
||||||
|
|
||||||
for (i=0 ; i<2 ; i++)
|
for (i = 0; i < 2; i++) {
|
||||||
{
|
|
||||||
ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
|
ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
|
||||||
nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
|
nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
|
||||||
vecs[i][sv] = ns;
|
vecs[i][sv] = ns;
|
||||||
vecs[i][tv] = nt;
|
vecs[i][tv] = nt;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0 ; i<2 ; i++)
|
for (i = 0; i < 2; i++)
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j = 0; j < 3; j++)
|
||||||
tx.vecs[i][j] = vecs[i][j] / scale[i];
|
tx.vecs[i][j] = vecs[i][j] / scale[i];
|
||||||
|
|
||||||
tx.vecs[0][3] = shift[0];
|
tx.vecs[0][3] = shift[0];
|
||||||
|
@ -456,12 +444,13 @@ void ParseBrush (void)
|
||||||
ParseEntity
|
ParseEntity
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
qboolean ParseEntity (void)
|
qboolean
|
||||||
|
ParseEntity (void)
|
||||||
{
|
{
|
||||||
if (!GetToken (true))
|
if (!GetToken (true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (strcmp (token, "{") )
|
if (strcmp (token, "{"))
|
||||||
Sys_Error ("ParseEntity: { not found");
|
Sys_Error ("ParseEntity: { not found");
|
||||||
|
|
||||||
if (num_entities == MAX_MAP_ENTITIES)
|
if (num_entities == MAX_MAP_ENTITIES)
|
||||||
|
@ -470,13 +459,12 @@ qboolean ParseEntity (void)
|
||||||
mapent = &entities[num_entities];
|
mapent = &entities[num_entities];
|
||||||
num_entities++;
|
num_entities++;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
if (!GetToken (true))
|
if (!GetToken (true))
|
||||||
Sys_Error ("ParseEntity: EOF without closing brace");
|
Sys_Error ("ParseEntity: EOF without closing brace");
|
||||||
if (!strcmp (token, "}") )
|
if (!strcmp (token, "}"))
|
||||||
break;
|
break;
|
||||||
if (!strcmp (token, "{") )
|
if (!strcmp (token, "{"))
|
||||||
ParseBrush ();
|
ParseBrush ();
|
||||||
else
|
else
|
||||||
ParseEpair ();
|
ParseEpair ();
|
||||||
|
@ -491,7 +479,8 @@ qboolean ParseEntity (void)
|
||||||
LoadMapFile
|
LoadMapFile
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void LoadMapFile (char *filename)
|
void
|
||||||
|
LoadMapFile (char *filename)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
|
@ -501,8 +490,7 @@ void LoadMapFile (char *filename)
|
||||||
|
|
||||||
num_entities = 0;
|
num_entities = 0;
|
||||||
|
|
||||||
while (ParseEntity ())
|
while (ParseEntity ()) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free (buf);
|
free (buf);
|
||||||
|
@ -515,52 +503,56 @@ void LoadMapFile (char *filename)
|
||||||
qprintf ("%5i texinfo\n", bsp->numtexinfo);
|
qprintf ("%5i texinfo\n", bsp->numtexinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintEntity (entity_t *ent)
|
void
|
||||||
|
PrintEntity (entity_t *ent)
|
||||||
{
|
{
|
||||||
epair_t *ep;
|
epair_t *ep;
|
||||||
|
|
||||||
for (ep=ent->epairs ; ep ; ep=ep->next)
|
for (ep = ent->epairs; ep; ep = ep->next)
|
||||||
printf ("%20s : %s\n", ep->key, ep->value);
|
printf ("%20s : %s\n", ep->key, ep->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *ValueForKey (entity_t *ent, char *key)
|
char *
|
||||||
|
ValueForKey (entity_t *ent, char *key)
|
||||||
{
|
{
|
||||||
epair_t *ep;
|
epair_t *ep;
|
||||||
|
|
||||||
for (ep=ent->epairs ; ep ; ep=ep->next)
|
for (ep = ent->epairs; ep; ep = ep->next)
|
||||||
if (!strcmp (ep->key, key) )
|
if (!strcmp (ep->key, key))
|
||||||
return ep->value;
|
return ep->value;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetKeyValue (entity_t *ent, char *key, char *value)
|
void
|
||||||
|
SetKeyValue (entity_t *ent, char *key, char *value)
|
||||||
{
|
{
|
||||||
epair_t *ep;
|
epair_t *ep;
|
||||||
|
|
||||||
for (ep=ent->epairs ; ep ; ep=ep->next)
|
for (ep = ent->epairs; ep; ep = ep->next)
|
||||||
if (!strcmp (ep->key, key) )
|
if (!strcmp (ep->key, key)) {
|
||||||
{
|
|
||||||
free (ep->value);
|
free (ep->value);
|
||||||
ep->value = strdup (value);
|
ep->value = strdup (value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ep = malloc (sizeof(*ep));
|
ep = malloc (sizeof (*ep));
|
||||||
ep->next = ent->epairs;
|
ep->next = ent->epairs;
|
||||||
ent->epairs = ep;
|
ent->epairs = ep;
|
||||||
ep->key = strdup (key);
|
ep->key = strdup (key);
|
||||||
ep->value = strdup (value);
|
ep->value = strdup (value);
|
||||||
}
|
}
|
||||||
|
|
||||||
float FloatForKey (entity_t *ent, char *key)
|
float
|
||||||
|
FloatForKey (entity_t *ent, char *key)
|
||||||
{
|
{
|
||||||
char *k;
|
char *k;
|
||||||
|
|
||||||
k = ValueForKey (ent, key);
|
k = ValueForKey (ent, key);
|
||||||
return atof(k);
|
return atof (k);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
|
void
|
||||||
|
GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
|
||||||
{
|
{
|
||||||
char *k;
|
char *k;
|
||||||
double v1, v2, v3;
|
double v1, v2, v3;
|
||||||
|
@ -575,7 +567,8 @@ void GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WriteEntitiesToString (void)
|
void
|
||||||
|
WriteEntitiesToString (void)
|
||||||
{
|
{
|
||||||
char *buf, *end;
|
char *buf, *end;
|
||||||
epair_t *ep;
|
epair_t *ep;
|
||||||
|
@ -586,22 +579,20 @@ void WriteEntitiesToString (void)
|
||||||
end = buf;
|
end = buf;
|
||||||
*end = 0;
|
*end = 0;
|
||||||
|
|
||||||
for (i=0 ; i<num_entities ; i++)
|
for (i = 0; i < num_entities; i++) {
|
||||||
{
|
|
||||||
ep = entities[i].epairs;
|
ep = entities[i].epairs;
|
||||||
if (!ep)
|
if (!ep)
|
||||||
continue; // ent got removed
|
continue; // ent got removed
|
||||||
|
|
||||||
strcat (end,"{\n");
|
strcat (end, "{\n");
|
||||||
end += 2;
|
end += 2;
|
||||||
|
|
||||||
for (ep = entities[i].epairs ; ep ; ep=ep->next)
|
for (ep = entities[i].epairs; ep; ep = ep->next) {
|
||||||
{
|
|
||||||
sprintf (line, "\"%s\" \"%s\"\n", ep->key, ep->value);
|
sprintf (line, "\"%s\" \"%s\"\n", ep->key, ep->value);
|
||||||
strcat (end, line);
|
strcat (end, line);
|
||||||
end += strlen(line);
|
end += strlen (line);
|
||||||
}
|
}
|
||||||
strcat (end,"}\n");
|
strcat (end, "}\n");
|
||||||
end += 2;
|
end += 2;
|
||||||
|
|
||||||
if (end > buf + MAX_MAP_ENTSTRING)
|
if (end > buf + MAX_MAP_ENTSTRING)
|
||||||
|
@ -609,4 +600,3 @@ void WriteEntitiesToString (void)
|
||||||
}
|
}
|
||||||
bsp->entdatasize = end - buf + 1;
|
bsp->entdatasize = end - buf + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,13 +36,13 @@ CheckColinear
|
||||||
|
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void CheckColinear (face_t *f)
|
void
|
||||||
|
CheckColinear (face_t * f)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
vec3_t v1, v2;
|
vec3_t v1, v2;
|
||||||
|
|
||||||
for (i=0 ; i<f->numpoints ;i++)
|
for (i = 0; i < f->numpoints; i++) {
|
||||||
{
|
|
||||||
// skip the point if the vector from the previous point is the same
|
// skip the point if the vector from the previous point is the same
|
||||||
// as the vector to the next point
|
// as the vector to the next point
|
||||||
j = (i - 1 < 0) ? f->numpoints - 1 : i - 1;
|
j = (i - 1 < 0) ? f->numpoints - 1 : i - 1;
|
||||||
|
@ -71,7 +71,8 @@ Returns NULL if the faces couldn't be merged, or the new face.
|
||||||
The originals will NOT be freed.
|
The originals will NOT be freed.
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
face_t *TryMerge (face_t *f1, face_t *f2)
|
face_t *
|
||||||
|
TryMerge (face_t * f1, face_t * f2)
|
||||||
{
|
{
|
||||||
vec_t *p1, *p2, *p3, *p4, *back;
|
vec_t *p1, *p2, *p3, *p4, *back;
|
||||||
face_t *newf;
|
face_t *newf;
|
||||||
|
@ -98,22 +99,19 @@ face_t *TryMerge (face_t *f1, face_t *f2)
|
||||||
p1 = p2 = NULL; // stop compiler warning
|
p1 = p2 = NULL; // stop compiler warning
|
||||||
j = 0; //
|
j = 0; //
|
||||||
|
|
||||||
for (i=0 ; i<f1->numpoints ; i++)
|
for (i = 0; i < f1->numpoints; i++) {
|
||||||
{
|
|
||||||
p1 = f1->pts[i];
|
p1 = f1->pts[i];
|
||||||
p2 = f1->pts[(i+1)%f1->numpoints];
|
p2 = f1->pts[(i + 1) % f1->numpoints];
|
||||||
for (j=0 ; j<f2->numpoints ; j++)
|
for (j = 0; j < f2->numpoints; j++) {
|
||||||
{
|
|
||||||
p3 = f2->pts[j];
|
p3 = f2->pts[j];
|
||||||
p4 = f2->pts[(j+1)%f2->numpoints];
|
p4 = f2->pts[(j + 1) % f2->numpoints];
|
||||||
for (k=0 ; k<3 ; k++)
|
for (k = 0; k < 3; k++) {
|
||||||
{
|
if (fabs (p1[k] - p4[k]) > EQUAL_EPSILON)
|
||||||
if (fabs(p1[k] - p4[k]) > EQUAL_EPSILON)
|
|
||||||
break;
|
break;
|
||||||
if (fabs(p2[k] - p3[k]) > EQUAL_EPSILON)
|
if (fabs (p2[k] - p3[k]) > EQUAL_EPSILON)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (k==3)
|
if (k == 3)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (j < f2->numpoints)
|
if (j < f2->numpoints)
|
||||||
|
@ -132,24 +130,24 @@ face_t *TryMerge (face_t *f1, face_t *f2)
|
||||||
if (f1->planeside)
|
if (f1->planeside)
|
||||||
VectorSubtract (vec3_origin, planenormal, planenormal);
|
VectorSubtract (vec3_origin, planenormal, planenormal);
|
||||||
|
|
||||||
back = f1->pts[(i+f1->numpoints-1)%f1->numpoints];
|
back = f1->pts[(i + f1->numpoints - 1) % f1->numpoints];
|
||||||
VectorSubtract (p1, back, delta);
|
VectorSubtract (p1, back, delta);
|
||||||
CrossProduct (planenormal, delta, normal);
|
CrossProduct (planenormal, delta, normal);
|
||||||
VectorNormalize (normal);
|
VectorNormalize (normal);
|
||||||
|
|
||||||
back = f2->pts[(j+2)%f2->numpoints];
|
back = f2->pts[(j + 2) % f2->numpoints];
|
||||||
VectorSubtract (back, p1, delta);
|
VectorSubtract (back, p1, delta);
|
||||||
dot = DotProduct (delta, normal);
|
dot = DotProduct (delta, normal);
|
||||||
if (dot > CONTINUOUS_EPSILON)
|
if (dot > CONTINUOUS_EPSILON)
|
||||||
return NULL; // not a convex polygon
|
return NULL; // not a convex polygon
|
||||||
keep1 = dot < -CONTINUOUS_EPSILON;
|
keep1 = dot < -CONTINUOUS_EPSILON;
|
||||||
|
|
||||||
back = f1->pts[(i+2)%f1->numpoints];
|
back = f1->pts[(i + 2) % f1->numpoints];
|
||||||
VectorSubtract (back, p2, delta);
|
VectorSubtract (back, p2, delta);
|
||||||
CrossProduct (planenormal, delta, normal);
|
CrossProduct (planenormal, delta, normal);
|
||||||
VectorNormalize (normal);
|
VectorNormalize (normal);
|
||||||
|
|
||||||
back = f2->pts[(j+f2->numpoints-1)%f2->numpoints];
|
back = f2->pts[(j + f2->numpoints - 1) % f2->numpoints];
|
||||||
VectorSubtract (back, p2, delta);
|
VectorSubtract (back, p2, delta);
|
||||||
dot = DotProduct (delta, normal);
|
dot = DotProduct (delta, normal);
|
||||||
if (dot > CONTINUOUS_EPSILON)
|
if (dot > CONTINUOUS_EPSILON)
|
||||||
|
@ -159,8 +157,7 @@ face_t *TryMerge (face_t *f1, face_t *f2)
|
||||||
//
|
//
|
||||||
// build the new polygon
|
// build the new polygon
|
||||||
//
|
//
|
||||||
if (f1->numpoints + f2->numpoints > MAXEDGES)
|
if (f1->numpoints + f2->numpoints > MAXEDGES) {
|
||||||
{
|
|
||||||
// Sys_Error ("TryMerge: too many edges!");
|
// Sys_Error ("TryMerge: too many edges!");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -168,9 +165,8 @@ face_t *TryMerge (face_t *f1, face_t *f2)
|
||||||
newf = NewFaceFromFace (f1);
|
newf = NewFaceFromFace (f1);
|
||||||
|
|
||||||
// copy first polygon
|
// copy first polygon
|
||||||
for (k=(i+1)%f1->numpoints ; k != i ; k=(k+1)%f1->numpoints)
|
for (k = (i + 1) % f1->numpoints; k != i; k = (k + 1) % f1->numpoints) {
|
||||||
{
|
if (k == (i + 1) % f1->numpoints && !keep2)
|
||||||
if (k==(i+1)%f1->numpoints && !keep2)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
VectorCopy (f1->pts[k], newf->pts[newf->numpoints]);
|
VectorCopy (f1->pts[k], newf->pts[newf->numpoints]);
|
||||||
|
@ -178,9 +174,8 @@ face_t *TryMerge (face_t *f1, face_t *f2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy second polygon
|
// copy second polygon
|
||||||
for (l= (j+1)%f2->numpoints ; l != j ; l=(l+1)%f2->numpoints)
|
for (l = (j + 1) % f2->numpoints; l != j; l = (l + 1) % f2->numpoints) {
|
||||||
{
|
if (l == (j + 1) % f2->numpoints && !keep1)
|
||||||
if (l==(j+1)%f2->numpoints && !keep1)
|
|
||||||
continue;
|
continue;
|
||||||
VectorCopy (f2->pts[l], newf->pts[newf->numpoints]);
|
VectorCopy (f2->pts[l], newf->pts[newf->numpoints]);
|
||||||
newf->numpoints++;
|
newf->numpoints++;
|
||||||
|
@ -196,20 +191,19 @@ MergeFaceToList
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
qboolean mergedebug;
|
qboolean mergedebug;
|
||||||
face_t *MergeFaceToList (face_t *face, face_t *list)
|
face_t *
|
||||||
|
MergeFaceToList (face_t * face, face_t * list)
|
||||||
{
|
{
|
||||||
face_t *newf, *f;
|
face_t *newf, *f;
|
||||||
|
|
||||||
for (f=list ; f ; f=f->next)
|
for (f = list; f; f = f->next) {
|
||||||
{
|
|
||||||
//CheckColinear (f);
|
//CheckColinear (f);
|
||||||
if (mergedebug)
|
if (mergedebug) {
|
||||||
{
|
Draw_ClearWindow ();
|
||||||
Draw_ClearWindow ();
|
Draw_DrawFace (face);
|
||||||
Draw_DrawFace (face);
|
Draw_DrawFace (f);
|
||||||
Draw_DrawFace (f);
|
Draw_SetBlack ();
|
||||||
Draw_SetBlack ();
|
}
|
||||||
}
|
|
||||||
newf = TryMerge (face, f);
|
newf = TryMerge (face, f);
|
||||||
if (!newf)
|
if (!newf)
|
||||||
continue;
|
continue;
|
||||||
|
@ -229,18 +223,17 @@ Draw_SetBlack ();
|
||||||
FreeMergeListScraps
|
FreeMergeListScraps
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
face_t *FreeMergeListScraps (face_t *merged)
|
face_t *
|
||||||
|
FreeMergeListScraps (face_t * merged)
|
||||||
{
|
{
|
||||||
face_t *head, *next;
|
face_t *head, *next;
|
||||||
|
|
||||||
head = NULL;
|
head = NULL;
|
||||||
for ( ; merged ; merged = next)
|
for (; merged; merged = next) {
|
||||||
{
|
|
||||||
next = merged->next;
|
next = merged->next;
|
||||||
if (merged->numpoints == -1)
|
if (merged->numpoints == -1)
|
||||||
FreeFace (merged);
|
FreeFace (merged);
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
merged->next = head;
|
merged->next = head;
|
||||||
head = merged;
|
head = merged;
|
||||||
}
|
}
|
||||||
|
@ -255,15 +248,15 @@ face_t *FreeMergeListScraps (face_t *merged)
|
||||||
MergePlaneFaces
|
MergePlaneFaces
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
void MergePlaneFaces (surface_t *plane)
|
void
|
||||||
|
MergePlaneFaces (surface_t * plane)
|
||||||
{
|
{
|
||||||
face_t *f1, *next;
|
face_t *f1, *next;
|
||||||
face_t *merged;
|
face_t *merged;
|
||||||
|
|
||||||
merged = NULL;
|
merged = NULL;
|
||||||
|
|
||||||
for (f1 = plane->faces ; f1 ; f1 = next)
|
for (f1 = plane->faces; f1; f1 = next) {
|
||||||
{
|
|
||||||
next = f1->next;
|
next = f1->next;
|
||||||
merged = MergeFaceToList (f1, merged);
|
merged = MergeFaceToList (f1, merged);
|
||||||
}
|
}
|
||||||
|
@ -278,7 +271,8 @@ void MergePlaneFaces (surface_t *plane)
|
||||||
MergeAll
|
MergeAll
|
||||||
============
|
============
|
||||||
*/
|
*/
|
||||||
void MergeAll (surface_t *surfhead)
|
void
|
||||||
|
MergeAll (surface_t * surfhead)
|
||||||
{
|
{
|
||||||
surface_t *surf;
|
surface_t *surf;
|
||||||
int mergefaces;
|
int mergefaces;
|
||||||
|
@ -287,13 +281,11 @@ void MergeAll (surface_t *surfhead)
|
||||||
printf ("---- MergeAll ----\n");
|
printf ("---- MergeAll ----\n");
|
||||||
|
|
||||||
mergefaces = 0;
|
mergefaces = 0;
|
||||||
for (surf = surfhead ; surf ; surf=surf->next)
|
for (surf = surfhead; surf; surf = surf->next) {
|
||||||
{
|
|
||||||
MergePlaneFaces (surf);
|
MergePlaneFaces (surf);
|
||||||
Draw_ClearWindow ();
|
Draw_ClearWindow ();
|
||||||
for (f=surf->faces ; f ; f=f->next)
|
for (f = surf->faces; f; f = f->next) {
|
||||||
{
|
Draw_DrawFace (f);
|
||||||
Draw_DrawFace (f);
|
|
||||||
mergefaces++;
|
mergefaces++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,54 +20,67 @@
|
||||||
|
|
||||||
#include "bsp5.h"
|
#include "bsp5.h"
|
||||||
|
|
||||||
void Draw_ClearBounds (void)
|
void
|
||||||
|
Draw_ClearBounds (void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw_AddToBounds (vec3_t v)
|
void
|
||||||
|
Draw_AddToBounds (vec3_t v)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw_DrawFace (face_t *f)
|
void
|
||||||
|
Draw_DrawFace (face_t * f)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw_ClearWindow (void)
|
void
|
||||||
|
Draw_ClearWindow (void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw_SetRed (void)
|
void
|
||||||
|
Draw_SetRed (void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw_SetGrey (void)
|
void
|
||||||
|
Draw_SetGrey (void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw_SetBlack (void)
|
void
|
||||||
|
Draw_SetBlack (void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawPoint (vec3_t v)
|
void
|
||||||
|
DrawPoint (vec3_t v)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawLeaf (node_t *l, int color)
|
void
|
||||||
|
DrawLeaf (node_t * l, int color)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawBrush (brush_t *b)
|
void
|
||||||
|
DrawBrush (brush_t * b)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawWinding (winding_t *w)
|
void
|
||||||
|
DrawWinding (winding_t * w)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawTri (vec3_t p1, vec3_t p2, vec3_t p3)
|
void
|
||||||
|
DrawTri (vec3_t p1, vec3_t p2, vec3_t p3)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawPortal (portal_t *portal)
|
void
|
||||||
|
DrawPortal (portal_t * portal)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,14 +32,17 @@ int outleafs;
|
||||||
PointInLeaf
|
PointInLeaf
|
||||||
===========
|
===========
|
||||||
*/
|
*/
|
||||||
node_t *PointInLeaf (node_t *node, vec3_t point)
|
node_t *
|
||||||
|
PointInLeaf (node_t * node, vec3_t point)
|
||||||
{
|
{
|
||||||
vec_t d;
|
vec_t d;
|
||||||
|
|
||||||
if (node->contents)
|
if (node->contents)
|
||||||
return node;
|
return node;
|
||||||
|
|
||||||
d = DotProduct (planes[node->planenum].normal, point) - planes[node->planenum]. dist;
|
d =
|
||||||
|
DotProduct (planes[node->planenum].normal,
|
||||||
|
point) - planes[node->planenum].dist;
|
||||||
|
|
||||||
if (d > 0)
|
if (d > 0)
|
||||||
return PointInLeaf (node->children[0], point);
|
return PointInLeaf (node->children[0], point);
|
||||||
|
@ -52,7 +55,8 @@ node_t *PointInLeaf (node_t *node, vec3_t point)
|
||||||
PlaceOccupant
|
PlaceOccupant
|
||||||
===========
|
===========
|
||||||
*/
|
*/
|
||||||
qboolean PlaceOccupant (int num, vec3_t point, node_t *headnode)
|
qboolean
|
||||||
|
PlaceOccupant (int num, vec3_t point, node_t * headnode)
|
||||||
{
|
{
|
||||||
node_t *n;
|
node_t *n;
|
||||||
|
|
||||||
|
@ -71,7 +75,8 @@ MarkLeakTrail
|
||||||
*/
|
*/
|
||||||
portal_t *prevleaknode;
|
portal_t *prevleaknode;
|
||||||
FILE *leakfile;
|
FILE *leakfile;
|
||||||
void MarkLeakTrail (portal_t *n2)
|
void
|
||||||
|
MarkLeakTrail (portal_t * n2)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
vec3_t p1, p2, dir;
|
vec3_t p1, p2, dir;
|
||||||
|
@ -88,16 +93,14 @@ void MarkLeakTrail (portal_t *n2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VectorCopy (n2->winding->points[0], p1);
|
VectorCopy (n2->winding->points[0], p1);
|
||||||
for (i=1 ; i< n2->winding->numpoints ; i++)
|
for (i = 1; i < n2->winding->numpoints; i++) {
|
||||||
{
|
for (j = 0; j < 3; j++)
|
||||||
for (j=0 ; j<3 ; j++)
|
|
||||||
p1[j] = (p1[j] + n2->winding->points[i][j]) / 2;
|
p1[j] = (p1[j] + n2->winding->points[i][j]) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorCopy (n1->winding->points[0], p2);
|
VectorCopy (n1->winding->points[0], p2);
|
||||||
for (i=1 ; i< n1->winding->numpoints ; i++)
|
for (i = 1; i < n1->winding->numpoints; i++) {
|
||||||
{
|
for (j = 0; j < 3; j++)
|
||||||
for (j=0 ; j<3 ; j++)
|
|
||||||
p2[j] = (p2[j] + n1->winding->points[i][j]) / 2;
|
p2[j] = (p2[j] + n1->winding->points[i][j]) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,11 +108,10 @@ void MarkLeakTrail (portal_t *n2)
|
||||||
len = VectorLength (dir);
|
len = VectorLength (dir);
|
||||||
VectorNormalize (dir);
|
VectorNormalize (dir);
|
||||||
|
|
||||||
while (len > 2)
|
while (len > 2) {
|
||||||
{
|
fprintf (leakfile, "%f %f %f\n", p1[0], p1[1], p1[2]);
|
||||||
fprintf (leakfile,"%f %f %f\n", p1[0], p1[1], p1[2]);
|
for (i = 0; i < 3; i++)
|
||||||
for (i=0 ; i<3 ; i++)
|
p1[i] += dir[i] * 2;
|
||||||
p1[i] += dir[i]*2;
|
|
||||||
len -= 2;
|
len -= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,7 +126,8 @@ Returns true if an occupied leaf is reached
|
||||||
*/
|
*/
|
||||||
int hit_occupied;
|
int hit_occupied;
|
||||||
int backdraw;
|
int backdraw;
|
||||||
qboolean RecursiveFillOutside (node_t *l, qboolean fill)
|
qboolean
|
||||||
|
RecursiveFillOutside (node_t * l, qboolean fill)
|
||||||
{
|
{
|
||||||
portal_t *p;
|
portal_t *p;
|
||||||
int s;
|
int s;
|
||||||
|
@ -145,14 +148,12 @@ qboolean RecursiveFillOutside (node_t *l, qboolean fill)
|
||||||
l->contents = CONTENTS_SOLID;
|
l->contents = CONTENTS_SOLID;
|
||||||
outleafs++;
|
outleafs++;
|
||||||
|
|
||||||
for (p=l->portals ; p ; )
|
for (p = l->portals; p;) {
|
||||||
{
|
|
||||||
s = (p->nodes[0] == l);
|
s = (p->nodes[0] == l);
|
||||||
|
|
||||||
if (RecursiveFillOutside (p->nodes[s], fill) )
|
if (RecursiveFillOutside (p->nodes[s], fill)) { // leaked, so stop
|
||||||
{ // leaked, so stop filling
|
// filling
|
||||||
if (backdraw-- > 0)
|
if (backdraw-- > 0) {
|
||||||
{
|
|
||||||
MarkLeakTrail (p);
|
MarkLeakTrail (p);
|
||||||
DrawLeaf (l, 2);
|
DrawLeaf (l, 2);
|
||||||
}
|
}
|
||||||
|
@ -170,12 +171,12 @@ ClearOutFaces
|
||||||
|
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void ClearOutFaces (node_t *node)
|
void
|
||||||
|
ClearOutFaces (node_t * node)
|
||||||
{
|
{
|
||||||
face_t **fp;
|
face_t **fp;
|
||||||
|
|
||||||
if (node->planenum != -1)
|
if (node->planenum != -1) {
|
||||||
{
|
|
||||||
ClearOutFaces (node->children[0]);
|
ClearOutFaces (node->children[0]);
|
||||||
ClearOutFaces (node->children[1]);
|
ClearOutFaces (node->children[1]);
|
||||||
return;
|
return;
|
||||||
|
@ -183,8 +184,7 @@ void ClearOutFaces (node_t *node)
|
||||||
if (node->contents != CONTENTS_SOLID)
|
if (node->contents != CONTENTS_SOLID)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (fp=node->markfaces ; *fp ; fp++)
|
for (fp = node->markfaces; *fp; fp++) {
|
||||||
{
|
|
||||||
// mark all the original faces that are removed
|
// mark all the original faces that are removed
|
||||||
(*fp)->numpoints = 0;
|
(*fp)->numpoints = 0;
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,8 @@ FillOutside
|
||||||
|
|
||||||
===========
|
===========
|
||||||
*/
|
*/
|
||||||
qboolean FillOutside (node_t *node)
|
qboolean
|
||||||
|
FillOutside (node_t * node)
|
||||||
{
|
{
|
||||||
int s;
|
int s;
|
||||||
vec_t *v;
|
vec_t *v;
|
||||||
|
@ -209,25 +210,23 @@ qboolean FillOutside (node_t *node)
|
||||||
|
|
||||||
qprintf ("----- FillOutside ----\n");
|
qprintf ("----- FillOutside ----\n");
|
||||||
|
|
||||||
if (nofill)
|
if (nofill) {
|
||||||
{
|
|
||||||
printf ("skipped\n");
|
printf ("skipped\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inside = false;
|
inside = false;
|
||||||
for (i=1 ; i<num_entities ; i++)
|
for (i = 1; i < num_entities; i++) {
|
||||||
{
|
if (!VectorCompare (entities[i].origin, vec3_origin)) {
|
||||||
if (!VectorCompare(entities[i].origin, vec3_origin))
|
|
||||||
{
|
|
||||||
if (PlaceOccupant (i, entities[i].origin, node))
|
if (PlaceOccupant (i, entities[i].origin, node))
|
||||||
inside = true;
|
inside = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inside)
|
if (!inside) {
|
||||||
{
|
printf
|
||||||
printf ("Hullnum %i: No entities in empty space -- no filling performed\n", hullnum);
|
("Hullnum %i: No entities in empty space -- no filling performed\n",
|
||||||
|
hullnum);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,19 +238,17 @@ qboolean FillOutside (node_t *node)
|
||||||
|
|
||||||
prevleaknode = NULL;
|
prevleaknode = NULL;
|
||||||
|
|
||||||
if (!hullnum)
|
if (!hullnum) {
|
||||||
{
|
|
||||||
leakfile = fopen (pointfilename, "w");
|
leakfile = fopen (pointfilename, "w");
|
||||||
if (!leakfile)
|
if (!leakfile)
|
||||||
Sys_Error ("Couldn't open %s\n", pointfilename);
|
Sys_Error ("Couldn't open %s\n", pointfilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RecursiveFillOutside (outside_node.portals->nodes[s], false))
|
if (RecursiveFillOutside (outside_node.portals->nodes[s], false)) {
|
||||||
{
|
|
||||||
v = entities[hit_occupied].origin;
|
v = entities[hit_occupied].origin;
|
||||||
qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
|
qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
|
||||||
qprintf ("reached occupant at: (%4.0f,%4.0f,%4.0f)\n"
|
qprintf ("reached occupant at: (%4.0f,%4.0f,%4.0f)\n", v[0], v[1],
|
||||||
, v[0], v[1], v[2]);
|
v[2]);
|
||||||
qprintf ("no filling performed\n");
|
qprintf ("no filling performed\n");
|
||||||
if (!hullnum)
|
if (!hullnum)
|
||||||
fclose (leakfile);
|
fclose (leakfile);
|
||||||
|
@ -272,5 +269,3 @@ qboolean FillOutside (node_t *node)
|
||||||
qprintf ("%4i outleafs\n", outleafs);
|
qprintf ("%4i outleafs\n", outleafs);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,9 @@
|
||||||
#include "bsp5.h"
|
#include "bsp5.h"
|
||||||
|
|
||||||
|
|
||||||
node_t outside_node; // portals outside the world face this
|
node_t outside_node; // portals outside the world face
|
||||||
|
|
||||||
|
// this
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
|
@ -35,7 +37,8 @@ node_t outside_node; // portals outside the world face this
|
||||||
AddPortalToNodes
|
AddPortalToNodes
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
void AddPortalToNodes (portal_t *p, node_t *front, node_t *back)
|
void
|
||||||
|
AddPortalToNodes (portal_t * p, node_t * front, node_t * back)
|
||||||
{
|
{
|
||||||
if (p->nodes[0] || p->nodes[1])
|
if (p->nodes[0] || p->nodes[1])
|
||||||
Sys_Error ("AddPortalToNode: allready included");
|
Sys_Error ("AddPortalToNode: allready included");
|
||||||
|
@ -55,19 +58,19 @@ void AddPortalToNodes (portal_t *p, node_t *front, node_t *back)
|
||||||
RemovePortalFromNode
|
RemovePortalFromNode
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
void RemovePortalFromNode (portal_t *portal, node_t *l)
|
void
|
||||||
|
RemovePortalFromNode (portal_t * portal, node_t * l)
|
||||||
{
|
{
|
||||||
portal_t **pp, *t;
|
portal_t **pp, *t;
|
||||||
|
|
||||||
// remove reference to the current portal
|
// remove reference to the current portal
|
||||||
pp = &l->portals;
|
pp = &l->portals;
|
||||||
while (1)
|
while (1) {
|
||||||
{
|
|
||||||
t = *pp;
|
t = *pp;
|
||||||
if (!t)
|
if (!t)
|
||||||
Sys_Error ("RemovePortalFromNode: portal not in leaf");
|
Sys_Error ("RemovePortalFromNode: portal not in leaf");
|
||||||
|
|
||||||
if ( t == portal )
|
if (t == portal)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (t->nodes[0] == l)
|
if (t->nodes[0] == l)
|
||||||
|
@ -78,13 +81,10 @@ void RemovePortalFromNode (portal_t *portal, node_t *l)
|
||||||
Sys_Error ("RemovePortalFromNode: portal not bounding leaf");
|
Sys_Error ("RemovePortalFromNode: portal not bounding leaf");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (portal->nodes[0] == l)
|
if (portal->nodes[0] == l) {
|
||||||
{
|
|
||||||
*pp = portal->next[0];
|
*pp = portal->next[0];
|
||||||
portal->nodes[0] = NULL;
|
portal->nodes[0] = NULL;
|
||||||
}
|
} else if (portal->nodes[1] == l) {
|
||||||
else if (portal->nodes[1] == l)
|
|
||||||
{
|
|
||||||
*pp = portal->next[1];
|
*pp = portal->next[1];
|
||||||
portal->nodes[1] = NULL;
|
portal->nodes[1] = NULL;
|
||||||
}
|
}
|
||||||
|
@ -92,14 +92,15 @@ void RemovePortalFromNode (portal_t *portal, node_t *l)
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
void PrintPortal (portal_t *p)
|
void
|
||||||
|
PrintPortal (portal_t * p)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
winding_t *w;
|
winding_t *w;
|
||||||
|
|
||||||
w = p->winding;
|
w = p->winding;
|
||||||
for (i=0 ; i<w->numpoints ; i++)
|
for (i = 0; i < w->numpoints; i++)
|
||||||
printf ("(%5.0f,%5.0f,%5.0f)\n",w->points[i][0]
|
printf ("(%5.0f,%5.0f,%5.0f)\n", w->points[i][0]
|
||||||
, w->points[i][1], w->points[i][2]);
|
, w->points[i][1], w->points[i][2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +111,8 @@ MakeHeadnodePortals
|
||||||
The created portals will face the global outside_node
|
The created portals will face the global outside_node
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void MakeHeadnodePortals (node_t *node)
|
void
|
||||||
|
MakeHeadnodePortals (node_t * node)
|
||||||
{
|
{
|
||||||
vec3_t bounds[2];
|
vec3_t bounds[2];
|
||||||
int i, j, n;
|
int i, j, n;
|
||||||
|
@ -121,8 +123,7 @@ void MakeHeadnodePortals (node_t *node)
|
||||||
Draw_ClearWindow ();
|
Draw_ClearWindow ();
|
||||||
|
|
||||||
// pad with some space so there will never be null volume leafs
|
// pad with some space so there will never be null volume leafs
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
{
|
|
||||||
bounds[0][i] = brushset->mins[i] - SIDESPACE;
|
bounds[0][i] = brushset->mins[i] - SIDESPACE;
|
||||||
bounds[1][i] = brushset->maxs[i] + SIDESPACE;
|
bounds[1][i] = brushset->maxs[i] + SIDESPACE;
|
||||||
}
|
}
|
||||||
|
@ -130,23 +131,19 @@ void MakeHeadnodePortals (node_t *node)
|
||||||
outside_node.contents = CONTENTS_SOLID;
|
outside_node.contents = CONTENTS_SOLID;
|
||||||
outside_node.portals = NULL;
|
outside_node.portals = NULL;
|
||||||
|
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i = 0; i < 3; i++)
|
||||||
for (j=0 ; j<2 ; j++)
|
for (j = 0; j < 2; j++) {
|
||||||
{
|
n = j * 3 + i;
|
||||||
n = j*3 + i;
|
|
||||||
|
|
||||||
p = AllocPortal ();
|
p = AllocPortal ();
|
||||||
portals[n] = p;
|
portals[n] = p;
|
||||||
|
|
||||||
pl = &bplanes[n];
|
pl = &bplanes[n];
|
||||||
memset (pl, 0, sizeof(*pl));
|
memset (pl, 0, sizeof (*pl));
|
||||||
if (j)
|
if (j) {
|
||||||
{
|
|
||||||
pl->normal[i] = -1;
|
pl->normal[i] = -1;
|
||||||
pl->dist = -bounds[j][i];
|
pl->dist = -bounds[j][i];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
pl->normal[i] = 1;
|
pl->normal[i] = 1;
|
||||||
pl->dist = bounds[j][i];
|
pl->dist = bounds[j][i];
|
||||||
}
|
}
|
||||||
|
@ -160,56 +157,55 @@ void MakeHeadnodePortals (node_t *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
// clip the basewindings by all the other planes
|
// clip the basewindings by all the other planes
|
||||||
for (i=0 ; i<6 ; i++)
|
for (i = 0; i < 6; i++) {
|
||||||
{
|
for (j = 0; j < 6; j++) {
|
||||||
for (j=0 ; j<6 ; j++)
|
|
||||||
{
|
|
||||||
if (j == i)
|
if (j == i)
|
||||||
continue;
|
continue;
|
||||||
portals[i]->winding = ClipWinding (portals[i]->winding, &bplanes[j], true);
|
portals[i]->winding =
|
||||||
|
ClipWinding (portals[i]->winding, &bplanes[j], true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
void CheckWindingInNode (winding_t *w, node_t *node)
|
void
|
||||||
|
CheckWindingInNode (winding_t * w, node_t * node)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
for (i=0 ; i<w->numpoints ; i++)
|
for (i = 0; i < w->numpoints; i++) {
|
||||||
{
|
for (j = 0; j < 3; j++)
|
||||||
for (j=0 ; j<3 ; j++)
|
|
||||||
if (w->points[i][j] < node->mins[j] - 1
|
if (w->points[i][j] < node->mins[j] - 1
|
||||||
|| w->points[i][j] > node->maxs[j] + 1)
|
|| w->points[i][j] > node->maxs[j] + 1) {
|
||||||
{
|
|
||||||
printf ("WARNING: CheckWindingInNode: outside\n");
|
printf ("WARNING: CheckWindingInNode: outside\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckWindingArea (winding_t *w)
|
void
|
||||||
|
CheckWindingArea (winding_t * w)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
float total, add;
|
float total, add;
|
||||||
vec3_t v1, v2, cross;
|
vec3_t v1, v2, cross;
|
||||||
|
|
||||||
total = 0;
|
total = 0;
|
||||||
for (i=1 ; i<w->numpoints ; i++)
|
for (i = 1; i < w->numpoints; i++) {
|
||||||
{
|
|
||||||
VectorSubtract (w->points[i], w->points[0], v1);
|
VectorSubtract (w->points[i], w->points[0], v1);
|
||||||
VectorSubtract (w->points[i+1], w->points[0], v2);
|
VectorSubtract (w->points[i + 1], w->points[0], v2);
|
||||||
CrossProduct (v1, v2, cross);
|
CrossProduct (v1, v2, cross);
|
||||||
add = VectorLength (cross);
|
add = VectorLength (cross);
|
||||||
total += add*0.5;
|
total += add * 0.5;
|
||||||
}
|
}
|
||||||
if (total < 16)
|
if (total < 16)
|
||||||
printf ("WARNING: winding area %f\n", total);
|
printf ("WARNING: winding area %f\n", total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PlaneFromWinding (winding_t *w, plane_t *plane)
|
void
|
||||||
|
PlaneFromWinding (winding_t * w, plane_t *plane)
|
||||||
{
|
{
|
||||||
vec3_t v1, v2;
|
vec3_t v1, v2;
|
||||||
|
|
||||||
|
@ -221,7 +217,8 @@ void PlaneFromWinding (winding_t *w, plane_t *plane)
|
||||||
plane->dist = DotProduct (w->points[0], plane->normal);
|
plane->dist = DotProduct (w->points[0], plane->normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckLeafPortalConsistancy (node_t *node)
|
void
|
||||||
|
CheckLeafPortalConsistancy (node_t * node)
|
||||||
{
|
{
|
||||||
int side, side2;
|
int side, side2;
|
||||||
portal_t *p, *p2;
|
portal_t *p, *p2;
|
||||||
|
@ -232,8 +229,7 @@ void CheckLeafPortalConsistancy (node_t *node)
|
||||||
|
|
||||||
side = side2 = 0; // quiet compiler warning
|
side = side2 = 0; // quiet compiler warning
|
||||||
|
|
||||||
for (p = node->portals ; p ; p = p->next[side])
|
for (p = node->portals; p; p = p->next[side]) {
|
||||||
{
|
|
||||||
if (p->nodes[0] == node)
|
if (p->nodes[0] == node)
|
||||||
side = 0;
|
side = 0;
|
||||||
else if (p->nodes[1] == node)
|
else if (p->nodes[1] == node)
|
||||||
|
@ -247,8 +243,7 @@ void CheckLeafPortalConsistancy (node_t *node)
|
||||||
plane = planes[p->planenum];
|
plane = planes[p->planenum];
|
||||||
PlaneFromWinding (p->winding, &plane2);
|
PlaneFromWinding (p->winding, &plane2);
|
||||||
|
|
||||||
for (p2 = node->portals ; p2 ; p2 = p2->next[side2])
|
for (p2 = node->portals; p2; p2 = p2->next[side2]) {
|
||||||
{
|
|
||||||
if (p2->nodes[0] == node)
|
if (p2->nodes[0] == node)
|
||||||
side2 = 0;
|
side2 = 0;
|
||||||
else if (p2->nodes[1] == node)
|
else if (p2->nodes[1] == node)
|
||||||
|
@ -256,11 +251,9 @@ void CheckLeafPortalConsistancy (node_t *node)
|
||||||
else
|
else
|
||||||
Sys_Error ("CutNodePortals_r: mislinked portal");
|
Sys_Error ("CutNodePortals_r: mislinked portal");
|
||||||
w = p2->winding;
|
w = p2->winding;
|
||||||
for (i=0 ; i<w->numpoints ; i++)
|
for (i = 0; i < w->numpoints; i++) {
|
||||||
{
|
|
||||||
dist = DotProduct (w->points[i], plane.normal) - plane.dist;
|
dist = DotProduct (w->points[i], plane.normal) - plane.dist;
|
||||||
if ( (side == 0 && dist < -1) || (side == 1 && dist > 1) )
|
if ((side == 0 && dist < -1) || (side == 1 && dist > 1)) {
|
||||||
{
|
|
||||||
printf ("WARNING: portal siding direction is wrong\n");
|
printf ("WARNING: portal siding direction is wrong\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -277,7 +270,8 @@ CutNodePortals_r
|
||||||
|
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void CutNodePortals_r (node_t *node)
|
void
|
||||||
|
CutNodePortals_r (node_t * node)
|
||||||
{
|
{
|
||||||
plane_t *plane, clipplane;
|
plane_t *plane, clipplane;
|
||||||
node_t *f, *b, *other_node;
|
node_t *f, *b, *other_node;
|
||||||
|
@ -290,8 +284,7 @@ void CutNodePortals_r (node_t *node)
|
||||||
//
|
//
|
||||||
// seperate the portals on node into it's children
|
// seperate the portals on node into it's children
|
||||||
//
|
//
|
||||||
if (node->contents)
|
if (node->contents) {
|
||||||
{
|
|
||||||
return; // at a leaf, no more dividing
|
return; // at a leaf, no more dividing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,40 +302,33 @@ void CutNodePortals_r (node_t *node)
|
||||||
|
|
||||||
w = BaseWindingForPlane (&planes[node->planenum]);
|
w = BaseWindingForPlane (&planes[node->planenum]);
|
||||||
side = 0; // shut up compiler warning
|
side = 0; // shut up compiler warning
|
||||||
for (p = node->portals ; p ; p = p->next[side])
|
for (p = node->portals; p; p = p->next[side]) {
|
||||||
{
|
|
||||||
clipplane = planes[p->planenum];
|
clipplane = planes[p->planenum];
|
||||||
if (p->nodes[0] == node)
|
if (p->nodes[0] == node)
|
||||||
side = 0;
|
side = 0;
|
||||||
else if (p->nodes[1] == node)
|
else if (p->nodes[1] == node) {
|
||||||
{
|
|
||||||
clipplane.dist = -clipplane.dist;
|
clipplane.dist = -clipplane.dist;
|
||||||
VectorSubtract (vec3_origin, clipplane.normal, clipplane.normal);
|
VectorSubtract (vec3_origin, clipplane.normal, clipplane.normal);
|
||||||
side = 1;
|
side = 1;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
Sys_Error ("CutNodePortals_r: mislinked portal");
|
Sys_Error ("CutNodePortals_r: mislinked portal");
|
||||||
|
|
||||||
w = ClipWinding (w, &clipplane, true);
|
w = ClipWinding (w, &clipplane, true);
|
||||||
if (!w)
|
if (!w) {
|
||||||
{
|
|
||||||
printf ("WARNING: CutNodePortals_r:new portal was clipped away\n");
|
printf ("WARNING: CutNodePortals_r:new portal was clipped away\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w)
|
if (w) {
|
||||||
{
|
|
||||||
// if the plane was not clipped on all sides, there was an error
|
// if the plane was not clipped on all sides, there was an error
|
||||||
new_portal->winding = w;
|
new_portal->winding = w;
|
||||||
AddPortalToNodes (new_portal, f, b);
|
AddPortalToNodes (new_portal, f, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// partition the portals
|
// partition the portals
|
||||||
//
|
//
|
||||||
for (p = node->portals ; p ; p = next_portal)
|
for (p = node->portals; p; p = next_portal) {
|
||||||
{
|
|
||||||
if (p->nodes[0] == node)
|
if (p->nodes[0] == node)
|
||||||
side = 0;
|
side = 0;
|
||||||
else if (p->nodes[1] == node)
|
else if (p->nodes[1] == node)
|
||||||
|
@ -360,23 +346,20 @@ void CutNodePortals_r (node_t *node)
|
||||||
//
|
//
|
||||||
DivideWinding (p->winding, plane, &frontwinding, &backwinding);
|
DivideWinding (p->winding, plane, &frontwinding, &backwinding);
|
||||||
|
|
||||||
if (!frontwinding)
|
if (!frontwinding) {
|
||||||
{
|
|
||||||
if (side == 0)
|
if (side == 0)
|
||||||
AddPortalToNodes (p, b, other_node);
|
AddPortalToNodes (p, b, other_node);
|
||||||
else
|
else
|
||||||
AddPortalToNodes (p, other_node, b);
|
AddPortalToNodes (p, other_node, b);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!backwinding)
|
if (!backwinding) {
|
||||||
{
|
|
||||||
if (side == 0)
|
if (side == 0)
|
||||||
AddPortalToNodes (p, f, other_node);
|
AddPortalToNodes (p, f, other_node);
|
||||||
else
|
else
|
||||||
AddPortalToNodes (p, other_node, f);
|
AddPortalToNodes (p, other_node, f);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the winding is split
|
// the winding is split
|
||||||
new_portal = AllocPortal ();
|
new_portal = AllocPortal ();
|
||||||
*new_portal = *p;
|
*new_portal = *p;
|
||||||
|
@ -384,20 +367,17 @@ void CutNodePortals_r (node_t *node)
|
||||||
FreeWinding (p->winding);
|
FreeWinding (p->winding);
|
||||||
p->winding = frontwinding;
|
p->winding = frontwinding;
|
||||||
|
|
||||||
if (side == 0)
|
if (side == 0) {
|
||||||
{
|
|
||||||
AddPortalToNodes (p, f, other_node);
|
AddPortalToNodes (p, f, other_node);
|
||||||
AddPortalToNodes (new_portal, b, other_node);
|
AddPortalToNodes (new_portal, b, other_node);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
AddPortalToNodes (p, other_node, f);
|
AddPortalToNodes (p, other_node, f);
|
||||||
AddPortalToNodes (new_portal, other_node, b);
|
AddPortalToNodes (new_portal, other_node, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawLeaf (f,1);
|
DrawLeaf (f, 1);
|
||||||
DrawLeaf (b,2);
|
DrawLeaf (b, 2);
|
||||||
|
|
||||||
CutNodePortals_r (f);
|
CutNodePortals_r (f);
|
||||||
CutNodePortals_r (b);
|
CutNodePortals_r (b);
|
||||||
|
@ -412,7 +392,8 @@ PortalizeWorld
|
||||||
Builds the exact polyhedrons for the nodes and leafs
|
Builds the exact polyhedrons for the nodes and leafs
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void PortalizeWorld (node_t *headnode)
|
void
|
||||||
|
PortalizeWorld (node_t * headnode)
|
||||||
{
|
{
|
||||||
qprintf ("----- portalize ----\n");
|
qprintf ("----- portalize ----\n");
|
||||||
|
|
||||||
|
@ -427,18 +408,17 @@ FreeAllPortals
|
||||||
|
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void FreeAllPortals (node_t *node)
|
void
|
||||||
|
FreeAllPortals (node_t * node)
|
||||||
{
|
{
|
||||||
portal_t *p, *nextp;
|
portal_t *p, *nextp;
|
||||||
|
|
||||||
if (!node->contents)
|
if (!node->contents) {
|
||||||
{
|
|
||||||
FreeAllPortals (node->children[0]);
|
FreeAllPortals (node->children[0]);
|
||||||
FreeAllPortals (node->children[1]);
|
FreeAllPortals (node->children[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (p=node->portals ; p ; p=nextp)
|
for (p = node->portals; p; p = nextp) {
|
||||||
{
|
|
||||||
if (p->nodes[0] == node)
|
if (p->nodes[0] == node)
|
||||||
nextp = p->next[0];
|
nextp = p->next[0];
|
||||||
else
|
else
|
||||||
|
@ -464,23 +444,24 @@ FILE *pf;
|
||||||
int num_visleafs; // leafs the player can be in
|
int num_visleafs; // leafs the player can be in
|
||||||
int num_visportals;
|
int num_visportals;
|
||||||
|
|
||||||
void WriteFloat (FILE *f, vec_t v)
|
void
|
||||||
|
WriteFloat (FILE * f, vec_t v)
|
||||||
{
|
{
|
||||||
if ( fabs(v - (int) (v + 0.5)) < 0.001 )
|
if (fabs (v - (int) (v + 0.5)) < 0.001)
|
||||||
fprintf (f,"%i ",(int)(v + 0.5));
|
fprintf (f, "%i ", (int) (v + 0.5));
|
||||||
else
|
else
|
||||||
fprintf (f,"%f ",v);
|
fprintf (f, "%f ", v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WritePortalFile_r (node_t *node)
|
void
|
||||||
|
WritePortalFile_r (node_t * node)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
portal_t *p;
|
portal_t *p;
|
||||||
winding_t *w;
|
winding_t *w;
|
||||||
plane_t *pl, plane2;
|
plane_t *pl, plane2;
|
||||||
|
|
||||||
if (!node->contents)
|
if (!node->contents) {
|
||||||
{
|
|
||||||
WritePortalFile_r (node->children[0]);
|
WritePortalFile_r (node->children[0]);
|
||||||
WritePortalFile_r (node->children[1]);
|
WritePortalFile_r (node->children[1]);
|
||||||
return;
|
return;
|
||||||
|
@ -489,34 +470,32 @@ void WritePortalFile_r (node_t *node)
|
||||||
if (node->contents == CONTENTS_SOLID)
|
if (node->contents == CONTENTS_SOLID)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (p = node->portals ; p ; )
|
for (p = node->portals; p;) {
|
||||||
{
|
|
||||||
w = p->winding;
|
w = p->winding;
|
||||||
if (w && p->nodes[0] == node
|
if (w && p->nodes[0] == node
|
||||||
&& p->nodes[0]->contents == p->nodes[1]->contents)
|
&& p->nodes[0]->contents == p->nodes[1]->contents) {
|
||||||
{
|
|
||||||
// write out to the file
|
// write out to the file
|
||||||
|
|
||||||
// sometimes planes get turned around when they are very near
|
// sometimes planes get turned around when they are very near
|
||||||
// the changeover point between different axis. interpret the
|
// the changeover point between different axis. interpret the
|
||||||
// plane the same way vis will, and flip the side orders if needed
|
// plane the same way vis will, and flip the side orders if
|
||||||
|
// needed
|
||||||
pl = &planes[p->planenum];
|
pl = &planes[p->planenum];
|
||||||
PlaneFromWinding (w, &plane2);
|
PlaneFromWinding (w, &plane2);
|
||||||
if ( DotProduct (pl->normal, plane2.normal) < 0.99 )
|
if (DotProduct (pl->normal, plane2.normal) < 0.99) { // backwards...
|
||||||
{ // backwards...
|
fprintf (pf, "%i %i %i ", w->numpoints, p->nodes[1]->visleafnum,
|
||||||
fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->visleafnum, p->nodes[0]->visleafnum);
|
p->nodes[0]->visleafnum);
|
||||||
}
|
} else
|
||||||
else
|
fprintf (pf, "%i %i %i ", w->numpoints, p->nodes[0]->visleafnum,
|
||||||
fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->visleafnum, p->nodes[1]->visleafnum);
|
p->nodes[1]->visleafnum);
|
||||||
for (i=0 ; i<w->numpoints ; i++)
|
for (i = 0; i < w->numpoints; i++) {
|
||||||
{
|
fprintf (pf, "(");
|
||||||
fprintf (pf,"(");
|
|
||||||
WriteFloat (pf, w->points[i][0]);
|
WriteFloat (pf, w->points[i][0]);
|
||||||
WriteFloat (pf, w->points[i][1]);
|
WriteFloat (pf, w->points[i][1]);
|
||||||
WriteFloat (pf, w->points[i][2]);
|
WriteFloat (pf, w->points[i][2]);
|
||||||
fprintf (pf,") ");
|
fprintf (pf, ") ");
|
||||||
}
|
}
|
||||||
fprintf (pf,"\n");
|
fprintf (pf, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->nodes[0] == node)
|
if (p->nodes[0] == node)
|
||||||
|
@ -532,12 +511,12 @@ void WritePortalFile_r (node_t *node)
|
||||||
NumberLeafs_r
|
NumberLeafs_r
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void NumberLeafs_r (node_t *node)
|
void
|
||||||
|
NumberLeafs_r (node_t * node)
|
||||||
{
|
{
|
||||||
portal_t *p;
|
portal_t *p;
|
||||||
|
|
||||||
if (!node->contents)
|
if (!node->contents) { // decision node
|
||||||
{ // decision node
|
|
||||||
node->visleafnum = -99;
|
node->visleafnum = -99;
|
||||||
NumberLeafs_r (node->children[0]);
|
NumberLeafs_r (node->children[0]);
|
||||||
NumberLeafs_r (node->children[1]);
|
NumberLeafs_r (node->children[1]);
|
||||||
|
@ -547,23 +526,21 @@ void NumberLeafs_r (node_t *node)
|
||||||
Draw_ClearWindow ();
|
Draw_ClearWindow ();
|
||||||
DrawLeaf (node, 1);
|
DrawLeaf (node, 1);
|
||||||
|
|
||||||
if (node->contents == CONTENTS_SOLID)
|
if (node->contents == CONTENTS_SOLID) { // solid block, viewpoint never
|
||||||
{ // solid block, viewpoint never inside
|
// inside
|
||||||
node->visleafnum = -1;
|
node->visleafnum = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
node->visleafnum = num_visleafs++;
|
node->visleafnum = num_visleafs++;
|
||||||
|
|
||||||
for (p = node->portals ; p ; )
|
for (p = node->portals; p;) {
|
||||||
{
|
|
||||||
if (p->nodes[0] == node) // only write out from first leaf
|
if (p->nodes[0] == node) // only write out from first leaf
|
||||||
{
|
{
|
||||||
if (p->nodes[0]->contents == p->nodes[1]->contents)
|
if (p->nodes[0]->contents == p->nodes[1]->contents)
|
||||||
num_visportals++;
|
num_visportals++;
|
||||||
p = p->next[0];
|
p = p->next[0];
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
p = p->next[1];
|
p = p->next[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,7 +552,8 @@ void NumberLeafs_r (node_t *node)
|
||||||
WritePortalfile
|
WritePortalfile
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void WritePortalfile (node_t *headnode)
|
void
|
||||||
|
WritePortalfile (node_t * headnode)
|
||||||
{
|
{
|
||||||
// set the visleafnum field in every leaf and count the total number of portals
|
// set the visleafnum field in every leaf and count the total number of portals
|
||||||
num_visleafs = 0;
|
num_visleafs = 0;
|
||||||
|
@ -596,5 +574,3 @@ void WritePortalfile (node_t *headnode)
|
||||||
|
|
||||||
fclose (pf);
|
fclose (pf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,8 @@ int hullnum;
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void qprintf (char *fmt, ...)
|
void
|
||||||
|
qprintf (char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ void qprintf (char *fmt, ...)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
va_start (argptr, fmt);
|
va_start (argptr, fmt);
|
||||||
vprintf (fmt,argptr);
|
vprintf (fmt, argptr);
|
||||||
va_end (argptr);
|
va_end (argptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +86,8 @@ void qprintf (char *fmt, ...)
|
||||||
BaseWindingForPlane
|
BaseWindingForPlane
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
winding_t *BaseWindingForPlane (plane_t *p)
|
winding_t *
|
||||||
|
BaseWindingForPlane (plane_t *p)
|
||||||
{
|
{
|
||||||
int i, x;
|
int i, x;
|
||||||
vec_t max, v;
|
vec_t max, v;
|
||||||
|
@ -96,21 +98,18 @@ winding_t *BaseWindingForPlane (plane_t *p)
|
||||||
|
|
||||||
max = -BOGUS_RANGE;
|
max = -BOGUS_RANGE;
|
||||||
x = -1;
|
x = -1;
|
||||||
for (i=0 ; i<3; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
{
|
v = fabs (p->normal[i]);
|
||||||
v = fabs(p->normal[i]);
|
if (v > max) {
|
||||||
if (v > max)
|
|
||||||
{
|
|
||||||
x = i;
|
x = i;
|
||||||
max = v;
|
max = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (x==-1)
|
if (x == -1)
|
||||||
Sys_Error ("BaseWindingForPlane: no axis found");
|
Sys_Error ("BaseWindingForPlane: no axis found");
|
||||||
|
|
||||||
VectorCopy (vec3_origin, vup);
|
VectorCopy (vec3_origin, vup);
|
||||||
switch (x)
|
switch (x) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
vup[2] = 1;
|
vup[2] = 1;
|
||||||
|
@ -158,12 +157,13 @@ winding_t *BaseWindingForPlane (plane_t *p)
|
||||||
CopyWinding
|
CopyWinding
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
winding_t *CopyWinding (winding_t *w)
|
winding_t *
|
||||||
|
CopyWinding (winding_t * w)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
winding_t *c;
|
winding_t *c;
|
||||||
|
|
||||||
size = (int)((winding_t *)0)->points[w->numpoints];
|
size = (int) ((winding_t *) 0)->points[w->numpoints];
|
||||||
c = malloc (size);
|
c = malloc (size);
|
||||||
memcpy (c, w, size);
|
memcpy (c, w, size);
|
||||||
return c;
|
return c;
|
||||||
|
@ -178,7 +178,8 @@ CheckWinding
|
||||||
Check for possible errors
|
Check for possible errors
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void CheckWinding (winding_t *w)
|
void
|
||||||
|
CheckWinding (winding_t * w)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +194,8 @@ If keepon is true, an exactly on-plane winding will be saved, otherwise
|
||||||
it will be clipped away.
|
it will be clipped away.
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
winding_t *ClipWinding (winding_t *in, plane_t *split, qboolean keepon)
|
winding_t *
|
||||||
|
ClipWinding (winding_t * in, plane_t *split, qboolean keepon)
|
||||||
{
|
{
|
||||||
vec_t dists[MAX_POINTS_ON_WINDING];
|
vec_t dists[MAX_POINTS_ON_WINDING];
|
||||||
int sides[MAX_POINTS_ON_WINDING];
|
int sides[MAX_POINTS_ON_WINDING];
|
||||||
|
@ -208,8 +210,7 @@ winding_t *ClipWinding (winding_t *in, plane_t *split, qboolean keepon)
|
||||||
counts[0] = counts[1] = counts[2] = 0;
|
counts[0] = counts[1] = counts[2] = 0;
|
||||||
|
|
||||||
// determine sides for each point
|
// determine sides for each point
|
||||||
for (i=0 ; i<in->numpoints ; i++)
|
for (i = 0; i < in->numpoints; i++) {
|
||||||
{
|
|
||||||
dot = DotProduct (in->points[i], split->normal);
|
dot = DotProduct (in->points[i], split->normal);
|
||||||
dot -= split->dist;
|
dot -= split->dist;
|
||||||
dists[i] = dot;
|
dists[i] = dot;
|
||||||
|
@ -217,8 +218,7 @@ winding_t *ClipWinding (winding_t *in, plane_t *split, qboolean keepon)
|
||||||
sides[i] = SIDE_FRONT;
|
sides[i] = SIDE_FRONT;
|
||||||
else if (dot < -ON_EPSILON)
|
else if (dot < -ON_EPSILON)
|
||||||
sides[i] = SIDE_BACK;
|
sides[i] = SIDE_BACK;
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
sides[i] = SIDE_ON;
|
sides[i] = SIDE_ON;
|
||||||
}
|
}
|
||||||
counts[sides[i]]++;
|
counts[sides[i]]++;
|
||||||
|
@ -229,50 +229,46 @@ winding_t *ClipWinding (winding_t *in, plane_t *split, qboolean keepon)
|
||||||
if (keepon && !counts[0] && !counts[1])
|
if (keepon && !counts[0] && !counts[1])
|
||||||
return in;
|
return in;
|
||||||
|
|
||||||
if (!counts[0])
|
if (!counts[0]) {
|
||||||
{
|
|
||||||
FreeWinding (in);
|
FreeWinding (in);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!counts[1])
|
if (!counts[1])
|
||||||
return in;
|
return in;
|
||||||
|
|
||||||
maxpts = in->numpoints+4; // can't use counts[0]+2 because
|
maxpts = in->numpoints + 4; // can't use counts[0]+2 because
|
||||||
// of fp grouping errors
|
// of fp grouping errors
|
||||||
neww = NewWinding (maxpts);
|
neww = NewWinding (maxpts);
|
||||||
|
|
||||||
for (i=0 ; i<in->numpoints ; i++)
|
for (i = 0; i < in->numpoints; i++) {
|
||||||
{
|
|
||||||
p1 = in->points[i];
|
p1 = in->points[i];
|
||||||
|
|
||||||
if (sides[i] == SIDE_ON)
|
if (sides[i] == SIDE_ON) {
|
||||||
{
|
|
||||||
VectorCopy (p1, neww->points[neww->numpoints]);
|
VectorCopy (p1, neww->points[neww->numpoints]);
|
||||||
neww->numpoints++;
|
neww->numpoints++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sides[i] == SIDE_FRONT)
|
if (sides[i] == SIDE_FRONT) {
|
||||||
{
|
|
||||||
VectorCopy (p1, neww->points[neww->numpoints]);
|
VectorCopy (p1, neww->points[neww->numpoints]);
|
||||||
neww->numpoints++;
|
neww->numpoints++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
|
if (sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// generate a split point
|
// generate a split point
|
||||||
p2 = in->points[(i+1)%in->numpoints];
|
p2 = in->points[(i + 1) % in->numpoints];
|
||||||
|
|
||||||
dot = dists[i] / (dists[i]-dists[i+1]);
|
dot = dists[i] / (dists[i] - dists[i + 1]);
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j = 0; j < 3; j++) { // avoid round off error when
|
||||||
{ // avoid round off error when possible
|
// possible
|
||||||
if (split->normal[j] == 1)
|
if (split->normal[j] == 1)
|
||||||
mid[j] = split->dist;
|
mid[j] = split->dist;
|
||||||
else if (split->normal[j] == -1)
|
else if (split->normal[j] == -1)
|
||||||
mid[j] = -split->dist;
|
mid[j] = -split->dist;
|
||||||
else
|
else
|
||||||
mid[j] = p1[j] + dot*(p2[j]-p1[j]);
|
mid[j] = p1[j] + dot * (p2[j] - p1[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorCopy (mid, neww->points[neww->numpoints]);
|
VectorCopy (mid, neww->points[neww->numpoints]);
|
||||||
|
@ -299,7 +295,9 @@ returned winding will be the input winding. If on both sides, two
|
||||||
new windings will be created.
|
new windings will be created.
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void DivideWinding (winding_t *in, plane_t *split, winding_t **front, winding_t **back)
|
void
|
||||||
|
DivideWinding (winding_t * in, plane_t *split, winding_t ** front,
|
||||||
|
winding_t ** back)
|
||||||
{
|
{
|
||||||
vec_t dists[MAX_POINTS_ON_WINDING];
|
vec_t dists[MAX_POINTS_ON_WINDING];
|
||||||
int sides[MAX_POINTS_ON_WINDING];
|
int sides[MAX_POINTS_ON_WINDING];
|
||||||
|
@ -314,8 +312,7 @@ void DivideWinding (winding_t *in, plane_t *split, winding_t **front, winding_t
|
||||||
counts[0] = counts[1] = counts[2] = 0;
|
counts[0] = counts[1] = counts[2] = 0;
|
||||||
|
|
||||||
// determine sides for each point
|
// determine sides for each point
|
||||||
for (i=0 ; i<in->numpoints ; i++)
|
for (i = 0; i < in->numpoints; i++) {
|
||||||
{
|
|
||||||
dot = DotProduct (in->points[i], split->normal);
|
dot = DotProduct (in->points[i], split->normal);
|
||||||
dot -= split->dist;
|
dot -= split->dist;
|
||||||
dists[i] = dot;
|
dists[i] = dot;
|
||||||
|
@ -323,8 +320,7 @@ void DivideWinding (winding_t *in, plane_t *split, winding_t **front, winding_t
|
||||||
sides[i] = SIDE_FRONT;
|
sides[i] = SIDE_FRONT;
|
||||||
else if (dot < -ON_EPSILON)
|
else if (dot < -ON_EPSILON)
|
||||||
sides[i] = SIDE_BACK;
|
sides[i] = SIDE_BACK;
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
sides[i] = SIDE_ON;
|
sides[i] = SIDE_ON;
|
||||||
}
|
}
|
||||||
counts[sides[i]]++;
|
counts[sides[i]]++;
|
||||||
|
@ -334,29 +330,25 @@ void DivideWinding (winding_t *in, plane_t *split, winding_t **front, winding_t
|
||||||
|
|
||||||
*front = *back = NULL;
|
*front = *back = NULL;
|
||||||
|
|
||||||
if (!counts[0])
|
if (!counts[0]) {
|
||||||
{
|
|
||||||
*back = in;
|
*back = in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!counts[1])
|
if (!counts[1]) {
|
||||||
{
|
|
||||||
*front = in;
|
*front = in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
maxpts = in->numpoints+4; // can't use counts[0]+2 because
|
maxpts = in->numpoints + 4; // can't use counts[0]+2 because
|
||||||
// of fp grouping errors
|
// of fp grouping errors
|
||||||
|
|
||||||
*front = f = NewWinding (maxpts);
|
*front = f = NewWinding (maxpts);
|
||||||
*back = b = NewWinding (maxpts);
|
*back = b = NewWinding (maxpts);
|
||||||
|
|
||||||
for (i=0 ; i<in->numpoints ; i++)
|
for (i = 0; i < in->numpoints; i++) {
|
||||||
{
|
|
||||||
p1 = in->points[i];
|
p1 = in->points[i];
|
||||||
|
|
||||||
if (sides[i] == SIDE_ON)
|
if (sides[i] == SIDE_ON) {
|
||||||
{
|
|
||||||
VectorCopy (p1, f->points[f->numpoints]);
|
VectorCopy (p1, f->points[f->numpoints]);
|
||||||
f->numpoints++;
|
f->numpoints++;
|
||||||
VectorCopy (p1, b->points[b->numpoints]);
|
VectorCopy (p1, b->points[b->numpoints]);
|
||||||
|
@ -364,32 +356,30 @@ void DivideWinding (winding_t *in, plane_t *split, winding_t **front, winding_t
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sides[i] == SIDE_FRONT)
|
if (sides[i] == SIDE_FRONT) {
|
||||||
{
|
|
||||||
VectorCopy (p1, f->points[f->numpoints]);
|
VectorCopy (p1, f->points[f->numpoints]);
|
||||||
f->numpoints++;
|
f->numpoints++;
|
||||||
}
|
}
|
||||||
if (sides[i] == SIDE_BACK)
|
if (sides[i] == SIDE_BACK) {
|
||||||
{
|
|
||||||
VectorCopy (p1, b->points[b->numpoints]);
|
VectorCopy (p1, b->points[b->numpoints]);
|
||||||
b->numpoints++;
|
b->numpoints++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
|
if (sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// generate a split point
|
// generate a split point
|
||||||
p2 = in->points[(i+1)%in->numpoints];
|
p2 = in->points[(i + 1) % in->numpoints];
|
||||||
|
|
||||||
dot = dists[i] / (dists[i]-dists[i+1]);
|
dot = dists[i] / (dists[i] - dists[i + 1]);
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j = 0; j < 3; j++) { // avoid round off error when
|
||||||
{ // avoid round off error when possible
|
// possible
|
||||||
if (split->normal[j] == 1)
|
if (split->normal[j] == 1)
|
||||||
mid[j] = split->dist;
|
mid[j] = split->dist;
|
||||||
else if (split->normal[j] == -1)
|
else if (split->normal[j] == -1)
|
||||||
mid[j] = -split->dist;
|
mid[j] = -split->dist;
|
||||||
else
|
else
|
||||||
mid[j] = p1[j] + dot*(p2[j]-p1[j]);
|
mid[j] = p1[j] + dot * (p2[j] - p1[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorCopy (mid, f->points[f->numpoints]);
|
VectorCopy (mid, f->points[f->numpoints]);
|
||||||
|
@ -410,7 +400,8 @@ int c_activesurfaces, c_peaksurfaces;
|
||||||
int c_activewindings, c_peakwindings;
|
int c_activewindings, c_peakwindings;
|
||||||
int c_activeportals, c_peakportals;
|
int c_activeportals, c_peakportals;
|
||||||
|
|
||||||
void PrintMemory (void)
|
void
|
||||||
|
PrintMemory (void)
|
||||||
{
|
{
|
||||||
printf ("faces : %6i (%6i)\n", c_activefaces, c_peakfaces);
|
printf ("faces : %6i (%6i)\n", c_activefaces, c_peakfaces);
|
||||||
printf ("surfaces: %6i (%6i)\n", c_activesurfaces, c_peaksurfaces);
|
printf ("surfaces: %6i (%6i)\n", c_activesurfaces, c_peaksurfaces);
|
||||||
|
@ -423,7 +414,8 @@ void PrintMemory (void)
|
||||||
NewWinding
|
NewWinding
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
winding_t *NewWinding (int points)
|
winding_t *
|
||||||
|
NewWinding (int points)
|
||||||
{
|
{
|
||||||
winding_t *w;
|
winding_t *w;
|
||||||
int size;
|
int size;
|
||||||
|
@ -435,7 +427,7 @@ winding_t *NewWinding (int points)
|
||||||
if (c_activewindings > c_peakwindings)
|
if (c_activewindings > c_peakwindings)
|
||||||
c_peakwindings = c_activewindings;
|
c_peakwindings = c_activewindings;
|
||||||
|
|
||||||
size = (int)((winding_t *)0)->points[points];
|
size = (int) ((winding_t *) 0)->points[points];
|
||||||
w = malloc (size);
|
w = malloc (size);
|
||||||
memset (w, 0, size);
|
memset (w, 0, size);
|
||||||
|
|
||||||
|
@ -443,7 +435,8 @@ winding_t *NewWinding (int points)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FreeWinding (winding_t *w)
|
void
|
||||||
|
FreeWinding (winding_t * w)
|
||||||
{
|
{
|
||||||
c_activewindings--;
|
c_activewindings--;
|
||||||
free (w);
|
free (w);
|
||||||
|
@ -456,7 +449,8 @@ void FreeWinding (winding_t *w)
|
||||||
AllocFace
|
AllocFace
|
||||||
===========
|
===========
|
||||||
*/
|
*/
|
||||||
face_t *AllocFace (void)
|
face_t *
|
||||||
|
AllocFace (void)
|
||||||
{
|
{
|
||||||
face_t *f;
|
face_t *f;
|
||||||
|
|
||||||
|
@ -464,15 +458,16 @@ face_t *AllocFace (void)
|
||||||
if (c_activefaces > c_peakfaces)
|
if (c_activefaces > c_peakfaces)
|
||||||
c_peakfaces = c_activefaces;
|
c_peakfaces = c_activefaces;
|
||||||
|
|
||||||
f = malloc (sizeof(face_t));
|
f = malloc (sizeof (face_t));
|
||||||
memset (f, 0, sizeof(face_t));
|
memset (f, 0, sizeof (face_t));
|
||||||
f->planenum = -1;
|
f->planenum = -1;
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FreeFace (face_t *f)
|
void
|
||||||
|
FreeFace (face_t * f)
|
||||||
{
|
{
|
||||||
c_activefaces--;
|
c_activefaces--;
|
||||||
// memset (f,0xff,sizeof(face_t));
|
// memset (f,0xff,sizeof(face_t));
|
||||||
|
@ -485,12 +480,13 @@ void FreeFace (face_t *f)
|
||||||
AllocSurface
|
AllocSurface
|
||||||
===========
|
===========
|
||||||
*/
|
*/
|
||||||
surface_t *AllocSurface (void)
|
surface_t *
|
||||||
|
AllocSurface (void)
|
||||||
{
|
{
|
||||||
surface_t *s;
|
surface_t *s;
|
||||||
|
|
||||||
s = malloc (sizeof(surface_t));
|
s = malloc (sizeof (surface_t));
|
||||||
memset (s, 0, sizeof(surface_t));
|
memset (s, 0, sizeof (surface_t));
|
||||||
|
|
||||||
c_activesurfaces++;
|
c_activesurfaces++;
|
||||||
if (c_activesurfaces > c_peaksurfaces)
|
if (c_activesurfaces > c_peaksurfaces)
|
||||||
|
@ -499,7 +495,8 @@ surface_t *AllocSurface (void)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreeSurface (surface_t *s)
|
void
|
||||||
|
FreeSurface (surface_t * s)
|
||||||
{
|
{
|
||||||
c_activesurfaces--;
|
c_activesurfaces--;
|
||||||
free (s);
|
free (s);
|
||||||
|
@ -510,7 +507,8 @@ void FreeSurface (surface_t *s)
|
||||||
AllocPortal
|
AllocPortal
|
||||||
===========
|
===========
|
||||||
*/
|
*/
|
||||||
portal_t *AllocPortal (void)
|
portal_t *
|
||||||
|
AllocPortal (void)
|
||||||
{
|
{
|
||||||
portal_t *p;
|
portal_t *p;
|
||||||
|
|
||||||
|
@ -518,13 +516,14 @@ portal_t *AllocPortal (void)
|
||||||
if (c_activeportals > c_peakportals)
|
if (c_activeportals > c_peakportals)
|
||||||
c_peakportals = c_activeportals;
|
c_peakportals = c_activeportals;
|
||||||
|
|
||||||
p = malloc (sizeof(portal_t));
|
p = malloc (sizeof (portal_t));
|
||||||
memset (p, 0, sizeof(portal_t));
|
memset (p, 0, sizeof (portal_t));
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreePortal (portal_t *p)
|
void
|
||||||
|
FreePortal (portal_t * p)
|
||||||
{
|
{
|
||||||
c_activeportals--;
|
c_activeportals--;
|
||||||
free (p);
|
free (p);
|
||||||
|
@ -536,12 +535,13 @@ void FreePortal (portal_t *p)
|
||||||
AllocNode
|
AllocNode
|
||||||
===========
|
===========
|
||||||
*/
|
*/
|
||||||
node_t *AllocNode (void)
|
node_t *
|
||||||
|
AllocNode (void)
|
||||||
{
|
{
|
||||||
node_t *n;
|
node_t *n;
|
||||||
|
|
||||||
n = malloc (sizeof(node_t));
|
n = malloc (sizeof (node_t));
|
||||||
memset (n, 0, sizeof(node_t));
|
memset (n, 0, sizeof (node_t));
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -551,12 +551,13 @@ node_t *AllocNode (void)
|
||||||
AllocBrush
|
AllocBrush
|
||||||
===========
|
===========
|
||||||
*/
|
*/
|
||||||
brush_t *AllocBrush (void)
|
brush_t *
|
||||||
|
AllocBrush (void)
|
||||||
{
|
{
|
||||||
brush_t *b;
|
brush_t *b;
|
||||||
|
|
||||||
b = malloc (sizeof(brush_t));
|
b = malloc (sizeof (brush_t));
|
||||||
memset (b, 0, sizeof(brush_t));
|
memset (b, 0, sizeof (brush_t));
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
@ -568,7 +569,8 @@ brush_t *AllocBrush (void)
|
||||||
ProcessEntity
|
ProcessEntity
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
void ProcessEntity (int entnum)
|
void
|
||||||
|
ProcessEntity (int entnum)
|
||||||
{
|
{
|
||||||
entity_t *ent;
|
entity_t *ent;
|
||||||
char mod[80];
|
char mod[80];
|
||||||
|
@ -581,8 +583,7 @@ void ProcessEntity (int entnum)
|
||||||
if (!ent->brushes)
|
if (!ent->brushes)
|
||||||
return; // non-bmodel entity
|
return; // non-bmodel entity
|
||||||
|
|
||||||
if (entnum > 0)
|
if (entnum > 0) {
|
||||||
{
|
|
||||||
worldmodel = false;
|
worldmodel = false;
|
||||||
if (entnum == 1)
|
if (entnum == 1)
|
||||||
qprintf ("--- Internal Entities ---\n");
|
qprintf ("--- Internal Entities ---\n");
|
||||||
|
@ -593,8 +594,7 @@ void ProcessEntity (int entnum)
|
||||||
if (hullnum == 0)
|
if (hullnum == 0)
|
||||||
printf ("MODEL: %s\n", mod);
|
printf ("MODEL: %s\n", mod);
|
||||||
SetKeyValue (ent, "model", mod);
|
SetKeyValue (ent, "model", mod);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
worldmodel = true;
|
worldmodel = true;
|
||||||
|
|
||||||
|
|
||||||
|
@ -604,8 +604,7 @@ void ProcessEntity (int entnum)
|
||||||
//
|
//
|
||||||
bs = Brush_LoadEntity (ent, hullnum);
|
bs = Brush_LoadEntity (ent, hullnum);
|
||||||
|
|
||||||
if (!bs->brushes)
|
if (!bs->brushes) {
|
||||||
{
|
|
||||||
PrintEntity (ent);
|
PrintEntity (ent);
|
||||||
Sys_Error ("Entity with no valid brushes");
|
Sys_Error ("Entity with no valid brushes");
|
||||||
}
|
}
|
||||||
|
@ -613,25 +612,23 @@ void ProcessEntity (int entnum)
|
||||||
brushset = bs;
|
brushset = bs;
|
||||||
surfs = CSGFaces (bs);
|
surfs = CSGFaces (bs);
|
||||||
|
|
||||||
if (hullnum != 0)
|
if (hullnum != 0) {
|
||||||
{
|
|
||||||
nodes = SolidBSP (surfs, true);
|
nodes = SolidBSP (surfs, true);
|
||||||
if (entnum == 0 && !nofill) // assume non-world bmodels are simple
|
if (entnum == 0 && !nofill) // assume non-world bmodels are
|
||||||
|
// simple
|
||||||
{
|
{
|
||||||
PortalizeWorld (nodes);
|
PortalizeWorld (nodes);
|
||||||
if (FillOutside (nodes))
|
if (FillOutside (nodes)) {
|
||||||
{
|
|
||||||
surfs = GatherNodeFaces (nodes);
|
surfs = GatherNodeFaces (nodes);
|
||||||
nodes = SolidBSP (surfs, false); // make a really good tree
|
nodes = SolidBSP (surfs, false); // make a really good
|
||||||
|
// tree
|
||||||
}
|
}
|
||||||
FreeAllPortals (nodes);
|
FreeAllPortals (nodes);
|
||||||
}
|
}
|
||||||
WriteNodePlanes (nodes);
|
WriteNodePlanes (nodes);
|
||||||
WriteClipNodes (nodes);
|
WriteClipNodes (nodes);
|
||||||
BumpModel (hullnum);
|
BumpModel (hullnum);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// SolidBSP generates a node tree
|
// SolidBSP generates a node tree
|
||||||
//
|
//
|
||||||
|
@ -644,12 +641,12 @@ void ProcessEntity (int entnum)
|
||||||
// build all the portals in the bsp tree
|
// build all the portals in the bsp tree
|
||||||
// some portals are solid polygons, and some are paths to other leafs
|
// some portals are solid polygons, and some are paths to other leafs
|
||||||
//
|
//
|
||||||
if (entnum == 0 && !nofill) // assume non-world bmodels are simple
|
if (entnum == 0 && !nofill) // assume non-world bmodels are
|
||||||
|
// simple
|
||||||
{
|
{
|
||||||
PortalizeWorld (nodes);
|
PortalizeWorld (nodes);
|
||||||
|
|
||||||
if (FillOutside (nodes))
|
if (FillOutside (nodes)) {
|
||||||
{
|
|
||||||
FreeAllPortals (nodes);
|
FreeAllPortals (nodes);
|
||||||
|
|
||||||
// get the remaining faces together into surfaces again
|
// get the remaining faces together into surfaces again
|
||||||
|
@ -685,15 +682,15 @@ UpdateEntLump
|
||||||
|
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void UpdateEntLump (void)
|
void
|
||||||
|
UpdateEntLump (void)
|
||||||
{
|
{
|
||||||
int m, entnum;
|
int m, entnum;
|
||||||
char mod[80];
|
char mod[80];
|
||||||
QFile *f;
|
QFile *f;
|
||||||
|
|
||||||
m = 1;
|
m = 1;
|
||||||
for (entnum = 1 ; entnum < num_entities ; entnum++)
|
for (entnum = 1; entnum < num_entities; entnum++) {
|
||||||
{
|
|
||||||
if (!entities[entnum].brushes)
|
if (!entities[entnum].brushes)
|
||||||
continue;
|
continue;
|
||||||
sprintf (mod, "*%i", m);
|
sprintf (mod, "*%i", m);
|
||||||
|
@ -705,7 +702,7 @@ void UpdateEntLump (void)
|
||||||
f = Qopen (bspfilename, "rb");
|
f = Qopen (bspfilename, "rb");
|
||||||
bsp = LoadBSPFile (f, Qfilesize (f));
|
bsp = LoadBSPFile (f, Qfilesize (f));
|
||||||
Qclose (f);
|
Qclose (f);
|
||||||
WriteEntitiesToString();
|
WriteEntitiesToString ();
|
||||||
f = Qopen (bspfilename, "wb");
|
f = Qopen (bspfilename, "wb");
|
||||||
WriteBSPFile (bsp, f);
|
WriteBSPFile (bsp, f);
|
||||||
Qclose (f);
|
Qclose (f);
|
||||||
|
@ -718,14 +715,15 @@ WriteClipHull
|
||||||
Write the clipping hull out to a text file so the parent process can get it
|
Write the clipping hull out to a text file so the parent process can get it
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void WriteClipHull (void)
|
void
|
||||||
|
WriteClipHull (void)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int i;
|
int i;
|
||||||
dplane_t *p;
|
dplane_t *p;
|
||||||
dclipnode_t *d;
|
dclipnode_t *d;
|
||||||
|
|
||||||
hullfilename[strlen(hullfilename)-1] = '0' + hullnum;
|
hullfilename[strlen (hullfilename) - 1] = '0' + hullnum;
|
||||||
|
|
||||||
qprintf ("---- WriteClipHull ----\n");
|
qprintf ("---- WriteClipHull ----\n");
|
||||||
qprintf ("Writing %s\n", hullfilename);
|
qprintf ("Writing %s\n", hullfilename);
|
||||||
|
@ -736,17 +734,18 @@ void WriteClipHull (void)
|
||||||
|
|
||||||
fprintf (f, "%i\n", bsp->nummodels);
|
fprintf (f, "%i\n", bsp->nummodels);
|
||||||
|
|
||||||
for (i=0 ; i<bsp->nummodels ; i++)
|
for (i = 0; i < bsp->nummodels; i++)
|
||||||
fprintf (f, "%i\n", bsp->models[i].headnode[hullnum]);
|
fprintf (f, "%i\n", bsp->models[i].headnode[hullnum]);
|
||||||
|
|
||||||
fprintf (f, "\n%i\n", bsp->numclipnodes);
|
fprintf (f, "\n%i\n", bsp->numclipnodes);
|
||||||
|
|
||||||
for (i=0 ; i<bsp->numclipnodes ; i++)
|
for (i = 0; i < bsp->numclipnodes; i++) {
|
||||||
{
|
|
||||||
d = &bsp->clipnodes[i];
|
d = &bsp->clipnodes[i];
|
||||||
p = &bsp->planes[d->planenum];
|
p = &bsp->planes[d->planenum];
|
||||||
// the node number is only written out for human readability
|
// the node number is only written out for human readability
|
||||||
fprintf (f, "%5i : %f %f %f %f : %5i %5i\n", i, p->normal[0], p->normal[1], p->normal[2], p->dist, d->children[0], d->children[1]);
|
fprintf (f, "%5i : %f %f %f %f : %5i %5i\n", i, p->normal[0],
|
||||||
|
p->normal[1], p->normal[2], p->dist, d->children[0],
|
||||||
|
d->children[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose (f);
|
fclose (f);
|
||||||
|
@ -759,7 +758,8 @@ ReadClipHull
|
||||||
Read the files written out by the child processes
|
Read the files written out by the child processes
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void ReadClipHull (int hullnum)
|
void
|
||||||
|
ReadClipHull (int hullnum)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int i, j, n;
|
int i, j, n;
|
||||||
|
@ -771,35 +771,36 @@ void ReadClipHull (int hullnum)
|
||||||
int junk;
|
int junk;
|
||||||
vec3_t norm;
|
vec3_t norm;
|
||||||
|
|
||||||
hullfilename[strlen(hullfilename)-1] = '0' + hullnum;
|
hullfilename[strlen (hullfilename) - 1] = '0' + hullnum;
|
||||||
|
|
||||||
f = fopen (hullfilename, "r");
|
f = fopen (hullfilename, "r");
|
||||||
if (!f)
|
if (!f)
|
||||||
Sys_Error ("Couldn't open %s", hullfilename);
|
Sys_Error ("Couldn't open %s", hullfilename);
|
||||||
|
|
||||||
if (fscanf (f,"%i\n", &n) != 1)
|
if (fscanf (f, "%i\n", &n) != 1)
|
||||||
Sys_Error ("Error parsing %s", hullfilename);
|
Sys_Error ("Error parsing %s", hullfilename);
|
||||||
|
|
||||||
if (n != bsp->nummodels)
|
if (n != bsp->nummodels)
|
||||||
Sys_Error ("ReadClipHull: hull had %i models, base had %i", n, bsp->nummodels);
|
Sys_Error ("ReadClipHull: hull had %i models, base had %i", n,
|
||||||
|
bsp->nummodels);
|
||||||
|
|
||||||
for (i=0 ; i<n ; i++)
|
for (i = 0; i < n; i++) {
|
||||||
{
|
|
||||||
fscanf (f, "%i\n", &j);
|
fscanf (f, "%i\n", &j);
|
||||||
bsp->models[i].headnode[hullnum] = bsp->numclipnodes + j;
|
bsp->models[i].headnode[hullnum] = bsp->numclipnodes + j;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fscanf (f,"\n%i\n", &n);
|
fscanf (f, "\n%i\n", &n);
|
||||||
firstclipnode = bsp->numclipnodes;
|
firstclipnode = bsp->numclipnodes;
|
||||||
|
|
||||||
for (i=0 ; i<n ; i++)
|
for (i = 0; i < n; i++) {
|
||||||
{
|
|
||||||
if (bsp->numclipnodes == MAX_MAP_CLIPNODES)
|
if (bsp->numclipnodes == MAX_MAP_CLIPNODES)
|
||||||
Sys_Error ("ReadClipHull: MAX_MAP_CLIPNODES");
|
Sys_Error ("ReadClipHull: MAX_MAP_CLIPNODES");
|
||||||
d = &bsp->clipnodes[bsp->numclipnodes];
|
d = &bsp->clipnodes[bsp->numclipnodes];
|
||||||
bsp->numclipnodes++;
|
bsp->numclipnodes++;
|
||||||
if (fscanf (f,"%i : %f %f %f %f : %i %i\n", &junk, &f1, &f2, &f3, &f4, &c1, &c2) != 7)
|
if (fscanf
|
||||||
|
(f, "%i : %f %f %f %f : %i %i\n", &junk, &f1, &f2, &f3, &f4, &c1,
|
||||||
|
&c2) != 7)
|
||||||
Sys_Error ("Error parsing %s", hullfilename);
|
Sys_Error ("Error parsing %s", hullfilename);
|
||||||
|
|
||||||
|
|
||||||
|
@ -808,7 +809,9 @@ void ReadClipHull (int hullnum)
|
||||||
p.normal[2] = f3;
|
p.normal[2] = f3;
|
||||||
p.dist = f4;
|
p.dist = f4;
|
||||||
|
|
||||||
norm[0] = f1; norm[1] = f2; norm[2] = f3; // vec_t precision
|
norm[0] = f1;
|
||||||
|
norm[1] = f2;
|
||||||
|
norm[2] = f3; // vec_t precision
|
||||||
p.type = PlaneTypeForNormal (norm);
|
p.type = PlaneTypeForNormal (norm);
|
||||||
|
|
||||||
d->children[0] = c1 >= 0 ? c1 + firstclipnode : c1;
|
d->children[0] = c1 >= 0 ? c1 + firstclipnode : c1;
|
||||||
|
@ -824,13 +827,13 @@ CreateSingleHull
|
||||||
|
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void CreateSingleHull (void)
|
void
|
||||||
|
CreateSingleHull (void)
|
||||||
{
|
{
|
||||||
int entnum;
|
int entnum;
|
||||||
|
|
||||||
// for each entity in the map file that has geometry
|
// for each entity in the map file that has geometry
|
||||||
for (entnum = 0 ; entnum < num_entities ; entnum++)
|
for (entnum = 0; entnum < num_entities; entnum++) {
|
||||||
{
|
|
||||||
ProcessEntity (entnum);
|
ProcessEntity (entnum);
|
||||||
if (!allverbose)
|
if (!allverbose)
|
||||||
verbose = false; // don't print rest of entities
|
verbose = false; // don't print rest of entities
|
||||||
|
@ -846,45 +849,37 @@ CreateHulls
|
||||||
|
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void CreateHulls (void)
|
void
|
||||||
|
CreateHulls (void)
|
||||||
{
|
{
|
||||||
// commanded to create a single hull only
|
// commanded to create a single hull only
|
||||||
if (hullnum)
|
if (hullnum) {
|
||||||
{
|
|
||||||
CreateSingleHull ();
|
CreateSingleHull ();
|
||||||
exit (0);
|
exit (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// commanded to use the allready existing hulls 1 and 2
|
// commanded to use the allready existing hulls 1 and 2
|
||||||
if (usehulls)
|
if (usehulls) {
|
||||||
{
|
|
||||||
CreateSingleHull ();
|
CreateSingleHull ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// commanded to ignore the hulls altogether
|
// commanded to ignore the hulls altogether
|
||||||
if (noclip)
|
if (noclip) {
|
||||||
{
|
|
||||||
CreateSingleHull ();
|
CreateSingleHull ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// create all the hulls
|
// create all the hulls
|
||||||
|
|
||||||
#ifdef __alpha
|
#ifdef __alpha
|
||||||
printf ("forking hull processes...\n");
|
printf ("forking hull processes...\n");
|
||||||
// fork a process for each clipping hull
|
// fork a process for each clipping hull
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
if (!fork ())
|
if (!fork ()) {
|
||||||
{
|
|
||||||
hullnum = 1;
|
hullnum = 1;
|
||||||
verbose = false;
|
verbose = false;
|
||||||
drawflag = false;
|
drawflag = false;
|
||||||
sprintf (argv0, "HUL%i", hullnum);
|
sprintf (argv0, "HUL%i", hullnum);
|
||||||
}
|
} else if (!fork ()) {
|
||||||
else if (!fork ())
|
|
||||||
{
|
|
||||||
hullnum = 2;
|
hullnum = 2;
|
||||||
verbose = false;
|
verbose = false;
|
||||||
drawflag = false;
|
drawflag = false;
|
||||||
|
@ -895,8 +890,10 @@ void CreateHulls (void)
|
||||||
if (hullnum)
|
if (hullnum)
|
||||||
exit (0);
|
exit (0);
|
||||||
|
|
||||||
wait (NULL); // wait for clip hull process to finish
|
wait (NULL); // wait for clip hull process to
|
||||||
wait (NULL); // wait for clip hull process to finish
|
// finish
|
||||||
|
wait (NULL); // wait for clip hull process to
|
||||||
|
// finish
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// create the hulls sequentially
|
// create the hulls sequentially
|
||||||
|
@ -926,7 +923,8 @@ ProcessFile
|
||||||
|
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void ProcessFile (char *sourcebase, char *bspfilename1)
|
void
|
||||||
|
ProcessFile (char *sourcebase, char *bspfilename1)
|
||||||
{
|
{
|
||||||
// create filenames
|
// create filenames
|
||||||
strcpy (bspfilename, bspfilename1);
|
strcpy (bspfilename, bspfilename1);
|
||||||
|
@ -945,28 +943,23 @@ void ProcessFile (char *sourcebase, char *bspfilename1)
|
||||||
COM_StripExtension (pointfilename, pointfilename);
|
COM_StripExtension (pointfilename, pointfilename);
|
||||||
strcat (pointfilename, ".pts");
|
strcat (pointfilename, ".pts");
|
||||||
|
|
||||||
if (!onlyents)
|
if (!onlyents) {
|
||||||
{
|
|
||||||
remove (bspfilename);
|
remove (bspfilename);
|
||||||
if (!usehulls)
|
if (!usehulls) {
|
||||||
{
|
hullfilename[strlen (hullfilename) - 1] = '1';
|
||||||
hullfilename[strlen(hullfilename)-1] = '1';
|
|
||||||
remove (hullfilename);
|
remove (hullfilename);
|
||||||
hullfilename[strlen(hullfilename)-1] = '2';
|
hullfilename[strlen (hullfilename) - 1] = '2';
|
||||||
remove (hullfilename);
|
remove (hullfilename);
|
||||||
}
|
}
|
||||||
remove (portfilename);
|
remove (portfilename);
|
||||||
remove (pointfilename);
|
remove (pointfilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
// load brushes and entities
|
// load brushes and entities
|
||||||
LoadMapFile (sourcebase);
|
LoadMapFile (sourcebase);
|
||||||
if (onlyents)
|
if (onlyents) {
|
||||||
{
|
|
||||||
UpdateEntLump ();
|
UpdateEntLump ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// init the tables to be shared by all models
|
// init the tables to be shared by all models
|
||||||
BeginBSPFile ();
|
BeginBSPFile ();
|
||||||
|
|
||||||
|
@ -976,7 +969,7 @@ void ProcessFile (char *sourcebase, char *bspfilename1)
|
||||||
ReadClipHull (1);
|
ReadClipHull (1);
|
||||||
ReadClipHull (2);
|
ReadClipHull (2);
|
||||||
|
|
||||||
WriteEntitiesToString();
|
WriteEntitiesToString ();
|
||||||
FinishBSPFile ();
|
FinishBSPFile ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -987,7 +980,8 @@ main
|
||||||
|
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
int main (int argc, char **argv)
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
double start, end;
|
double start, end;
|
||||||
|
@ -999,42 +993,39 @@ int main (int argc, char **argv)
|
||||||
//
|
//
|
||||||
// check command line flags
|
// check command line flags
|
||||||
//
|
//
|
||||||
for (i=1 ; i<argc ; i++)
|
for (i = 1; i < argc; i++) {
|
||||||
{
|
|
||||||
if (argv[i][0] != '-')
|
if (argv[i][0] != '-')
|
||||||
break;
|
break;
|
||||||
else if (!strcmp (argv[i],"-draw"))
|
else if (!strcmp (argv[i], "-draw"))
|
||||||
drawflag = true;
|
drawflag = true;
|
||||||
else if (!strcmp (argv[i],"-notjunc"))
|
else if (!strcmp (argv[i], "-notjunc"))
|
||||||
notjunc = true;
|
notjunc = true;
|
||||||
else if (!strcmp (argv[i],"-nofill"))
|
else if (!strcmp (argv[i], "-nofill"))
|
||||||
nofill = true;
|
nofill = true;
|
||||||
else if (!strcmp (argv[i],"-noclip"))
|
else if (!strcmp (argv[i], "-noclip"))
|
||||||
noclip = true;
|
noclip = true;
|
||||||
else if (!strcmp (argv[i],"-onlyents"))
|
else if (!strcmp (argv[i], "-onlyents"))
|
||||||
onlyents = true;
|
onlyents = true;
|
||||||
else if (!strcmp (argv[i],"-verbose"))
|
else if (!strcmp (argv[i], "-verbose"))
|
||||||
allverbose = true;
|
allverbose = true;
|
||||||
else if (!strcmp (argv[i],"-usehulls"))
|
else if (!strcmp (argv[i], "-usehulls"))
|
||||||
usehulls = true; // don't fork -- use the existing files
|
usehulls = true; // don't fork -- use the existing
|
||||||
else if (!strcmp (argv[i],"-hullnum"))
|
// files
|
||||||
{
|
else if (!strcmp (argv[i], "-hullnum")) {
|
||||||
hullnum = atoi(argv[i+1]);
|
hullnum = atoi (argv[i + 1]);
|
||||||
i++;
|
i++;
|
||||||
}
|
} else if (!strcmp (argv[i], "-subdivide")) {
|
||||||
else if (!strcmp (argv[i],"-subdivide"))
|
subdivide_size = atoi (argv[i + 1]);
|
||||||
{
|
|
||||||
subdivide_size = atoi(argv[i+1]);
|
|
||||||
i++;
|
i++;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
Sys_Error ("qbsp: Unknown option '%s'", argv[i]);
|
Sys_Error ("qbsp: Unknown option '%s'", argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != argc - 2 && i != argc - 1)
|
if (i != argc - 2 && i != argc - 1)
|
||||||
Sys_Error ("usage: qbsp [options] sourcefile [destfile]\noptions: -nojunc -nofill -threads[124] -draw -onlyents -verbose -proj <projectpath>");
|
Sys_Error
|
||||||
|
("usage: qbsp [options] sourcefile [destfile]\noptions: -nojunc -nofill -threads[124] -draw -onlyents -verbose -proj <projectpath>");
|
||||||
|
|
||||||
//XXX SetQdirFromPath (argv[i]);
|
// XXX SetQdirFromPath (argv[i]);
|
||||||
|
|
||||||
//
|
//
|
||||||
// let forked processes change name for ps status
|
// let forked processes change name for ps status
|
||||||
|
@ -1048,15 +1039,13 @@ int main (int argc, char **argv)
|
||||||
strcpy (sourcename, argv[i]);
|
strcpy (sourcename, argv[i]);
|
||||||
COM_DefaultExtension (sourcename, ".map");
|
COM_DefaultExtension (sourcename, ".map");
|
||||||
|
|
||||||
if (i != argc - 2)
|
if (i != argc - 2) {
|
||||||
{
|
|
||||||
strcpy (destname, argv[i]);
|
strcpy (destname, argv[i]);
|
||||||
COM_StripExtension (destname, destname);
|
COM_StripExtension (destname, destname);
|
||||||
strcat (destname, ".bsp");
|
strcat (destname, ".bsp");
|
||||||
printf ("outputfile: %s\n", destname);
|
printf ("outputfile: %s\n", destname);
|
||||||
}
|
} else
|
||||||
else
|
strcpy (destname, argv[i + 1]);
|
||||||
strcpy (destname, argv[i+1]);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// do it!
|
// do it!
|
||||||
|
@ -1064,7 +1053,7 @@ int main (int argc, char **argv)
|
||||||
start = Sys_DoubleTime ();
|
start = Sys_DoubleTime ();
|
||||||
ProcessFile (sourcename, destname);
|
ProcessFile (sourcename, destname);
|
||||||
end = Sys_DoubleTime ();
|
end = Sys_DoubleTime ();
|
||||||
printf ("%5.1f seconds elapsed\n", end-start);
|
printf ("%5.1f seconds elapsed\n", end - start);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,12 +51,12 @@ int firstedge;
|
||||||
|
|
||||||
vec3_t region_mins, region_maxs;
|
vec3_t region_mins, region_maxs;
|
||||||
|
|
||||||
void AddPointToRegion (vec3_t p)
|
void
|
||||||
|
AddPointToRegion (vec3_t p)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
{
|
|
||||||
if (p[i] < region_mins[i])
|
if (p[i] < region_mins[i])
|
||||||
region_mins[i] = p[i];
|
region_mins[i] = p[i];
|
||||||
if (p[i] > region_maxs[i])
|
if (p[i] > region_maxs[i])
|
||||||
|
@ -64,17 +64,19 @@ void AddPointToRegion (vec3_t p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearRegionSize (void)
|
void
|
||||||
|
ClearRegionSize (void)
|
||||||
{
|
{
|
||||||
region_mins[0] = region_mins[1] = region_mins[2] = 9999;
|
region_mins[0] = region_mins[1] = region_mins[2] = 9999;
|
||||||
region_maxs[0] = region_maxs[1] = region_maxs[2] = -9999;
|
region_maxs[0] = region_maxs[1] = region_maxs[2] = -9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddFaceToRegionSize (face_t *f)
|
void
|
||||||
|
AddFaceToRegionSize (face_t * f)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0 ; i<f->numpoints ; i++)
|
for (i = 0; i < f->numpoints; i++)
|
||||||
AddPointToRegion (f->pts[i]);
|
AddPointToRegion (f->pts[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,41 +85,35 @@ void AddFaceToRegionSize (face_t *f)
|
||||||
CanJoinFaces
|
CanJoinFaces
|
||||||
==============
|
==============
|
||||||
*/
|
*/
|
||||||
qboolean CanJoinFaces (face_t *f, face_t *f2)
|
qboolean
|
||||||
|
CanJoinFaces (face_t * f, face_t * f2)
|
||||||
{
|
{
|
||||||
vec3_t oldmins, oldmaxs;
|
vec3_t oldmins, oldmaxs;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (f2->planenum != f->planenum
|
if (f2->planenum != f->planenum
|
||||||
|| f2->planeside != f->planeside
|
|| f2->planeside != f->planeside || f2->texturenum != f->texturenum)
|
||||||
|| f2->texturenum != f->texturenum)
|
|
||||||
return false;
|
return false;
|
||||||
if (f2->outputnumber != -1)
|
if (f2->outputnumber != -1)
|
||||||
return false;
|
return false;
|
||||||
if (f2->contents[0] != f->contents[0])
|
if (f2->contents[0] != f->contents[0]) { // does this ever happen?
|
||||||
{ // does this ever happen? theyy shouldn't share.
|
// theyy shouldn't share.
|
||||||
printf ("CanJoinFaces: edge with different contents");
|
printf ("CanJoinFaces: edge with different contents");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check size constraints
|
// check size constraints
|
||||||
if ( ! (bsp->texinfo[f->texturenum].flags & TEX_SPECIAL) )
|
if (!(bsp->texinfo[f->texturenum].flags & TEX_SPECIAL)) {
|
||||||
{
|
|
||||||
VectorCopy (region_mins, oldmins);
|
VectorCopy (region_mins, oldmins);
|
||||||
VectorCopy (region_maxs, oldmaxs);
|
VectorCopy (region_maxs, oldmaxs);
|
||||||
AddFaceToRegionSize (f2);
|
AddFaceToRegionSize (f2);
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
{
|
if (region_maxs[i] - region_mins[i] > 240) {
|
||||||
if (region_maxs[i] - region_mins[i] > 240)
|
|
||||||
{
|
|
||||||
VectorCopy (oldmins, region_mins);
|
VectorCopy (oldmins, region_mins);
|
||||||
VectorCopy (oldmaxs, region_maxs);
|
VectorCopy (oldmaxs, region_maxs);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (bsp->numsurfedges - firstedge + f2->numpoints > MAX_EDGES_IN_REGION)
|
if (bsp->numsurfedges - firstedge + f2->numpoints > MAX_EDGES_IN_REGION)
|
||||||
return false; // a huge water or sky polygon
|
return false; // a huge water or sky polygon
|
||||||
}
|
}
|
||||||
|
@ -132,7 +128,8 @@ qboolean CanJoinFaces (face_t *f, face_t *f2)
|
||||||
RecursiveGrowRegion
|
RecursiveGrowRegion
|
||||||
==============
|
==============
|
||||||
*/
|
*/
|
||||||
void RecursiveGrowRegion (dface_t *r, face_t *f)
|
void
|
||||||
|
RecursiveGrowRegion (dface_t *r, face_t * f)
|
||||||
{
|
{
|
||||||
int e;
|
int e;
|
||||||
face_t *f2;
|
face_t *f2;
|
||||||
|
@ -146,29 +143,25 @@ void RecursiveGrowRegion (dface_t *r, face_t *f)
|
||||||
f->outputnumber = bsp->numfaces;
|
f->outputnumber = bsp->numfaces;
|
||||||
|
|
||||||
// add edges
|
// add edges
|
||||||
for (i=0 ; i<f->numpoints ; i++)
|
for (i = 0; i < f->numpoints; i++) {
|
||||||
{
|
|
||||||
e = f->edges[i];
|
e = f->edges[i];
|
||||||
if (!edgefaces[abs(e)][0])
|
if (!edgefaces[abs (e)][0])
|
||||||
continue; // edge has allready been removed
|
continue; // edge has allready been removed
|
||||||
if (e > 0)
|
if (e > 0)
|
||||||
f2 = edgefaces[e][1];
|
f2 = edgefaces[e][1];
|
||||||
else
|
else
|
||||||
f2 = edgefaces[-e][0];
|
f2 = edgefaces[-e][0];
|
||||||
if (f2 && f2->outputnumber == bsp->numfaces)
|
if (f2 && f2->outputnumber == bsp->numfaces) {
|
||||||
{
|
edgefaces[abs (e)][0] = NULL;
|
||||||
edgefaces[abs(e)][0] = NULL;
|
edgefaces[abs (e)][1] = NULL;
|
||||||
edgefaces[abs(e)][1] = NULL;
|
|
||||||
continue; // allready merged
|
continue; // allready merged
|
||||||
}
|
}
|
||||||
if (f2 && CanJoinFaces (f, f2))
|
if (f2 && CanJoinFaces (f, f2)) { // remove the edge and merge the
|
||||||
{ // remove the edge and merge the faces
|
// faces
|
||||||
edgefaces[abs(e)][0] = NULL;
|
edgefaces[abs (e)][0] = NULL;
|
||||||
edgefaces[abs(e)][1] = NULL;
|
edgefaces[abs (e)][1] = NULL;
|
||||||
RecursiveGrowRegion (r, f2);
|
RecursiveGrowRegion (r, f2);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// emit a surfedge
|
// emit a surfedge
|
||||||
if (bsp->numsurfedges == MAX_MAP_SURFEDGES)
|
if (bsp->numsurfedges == MAX_MAP_SURFEDGES)
|
||||||
Sys_Error ("numsurfedges == MAX_MAP_SURFEDGES");
|
Sys_Error ("numsurfedges == MAX_MAP_SURFEDGES");
|
||||||
|
@ -179,17 +172,17 @@ void RecursiveGrowRegion (dface_t *r, face_t *f)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintDface (int f)
|
void
|
||||||
|
PrintDface (int f)
|
||||||
{ // for debugging
|
{ // for debugging
|
||||||
dface_t *df;
|
dface_t *df;
|
||||||
dedge_t *e;
|
dedge_t *e;
|
||||||
int i, n;
|
int i, n;
|
||||||
|
|
||||||
df = &bsp->faces[f];
|
df = &bsp->faces[f];
|
||||||
for (i=0 ; i<df->numedges ; i++)
|
for (i = 0; i < df->numedges; i++) {
|
||||||
{
|
n = bsp->surfedges[df->firstedge + i];
|
||||||
n = bsp->surfedges[df->firstedge+i];
|
e = &bsp->edges[abs (n)];
|
||||||
e = &bsp->edges[abs(n)];
|
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
printf ("%5i = %5i : %5i\n", n, e->v[1], e->v[0]);
|
printf ("%5i = %5i : %5i\n", n, e->v[1], e->v[0]);
|
||||||
else
|
else
|
||||||
|
@ -197,21 +190,19 @@ void PrintDface (int f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FindVertexUse (int v)
|
void
|
||||||
|
FindVertexUse (int v)
|
||||||
{ // for debugging
|
{ // for debugging
|
||||||
int i, j, n;
|
int i, j, n;
|
||||||
dface_t *df;
|
dface_t *df;
|
||||||
dedge_t *e;
|
dedge_t *e;
|
||||||
|
|
||||||
for (i=firstmodelface ; i<bsp->numfaces ; i++)
|
for (i = firstmodelface; i < bsp->numfaces; i++) {
|
||||||
{
|
|
||||||
df = &bsp->faces[i];
|
df = &bsp->faces[i];
|
||||||
for (j=0 ; j<df->numedges ; j++)
|
for (j = 0; j < df->numedges; j++) {
|
||||||
{
|
n = bsp->surfedges[df->firstedge + j];
|
||||||
n = bsp->surfedges[df->firstedge+j];
|
e = &bsp->edges[abs (n)];
|
||||||
e = &bsp->edges[abs(n)];
|
if (e->v[0] == v || e->v[1] == v) {
|
||||||
if (e->v[0] == v || e->v[1] == v)
|
|
||||||
{
|
|
||||||
printf ("on face %i\n", i);
|
printf ("on face %i\n", i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -219,19 +210,17 @@ void FindVertexUse (int v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FindEdgeUse (int v)
|
void
|
||||||
|
FindEdgeUse (int v)
|
||||||
{ // for debugging
|
{ // for debugging
|
||||||
int i, j, n;
|
int i, j, n;
|
||||||
dface_t *df;
|
dface_t *df;
|
||||||
|
|
||||||
for (i=firstmodelface ; i<bsp->numfaces ; i++)
|
for (i = firstmodelface; i < bsp->numfaces; i++) {
|
||||||
{
|
|
||||||
df = &bsp->faces[i];
|
df = &bsp->faces[i];
|
||||||
for (j=0 ; j<df->numedges ; j++)
|
for (j = 0; j < df->numedges; j++) {
|
||||||
{
|
n = bsp->surfedges[df->firstedge + j];
|
||||||
n = bsp->surfedges[df->firstedge+j];
|
if (n == v || -n == v) {
|
||||||
if (n == v || -n == v)
|
|
||||||
{
|
|
||||||
printf ("on face %i\n", i);
|
printf ("on face %i\n", i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -248,7 +237,8 @@ to e2
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
int edgemapping[MAX_MAP_EDGES];
|
int edgemapping[MAX_MAP_EDGES];
|
||||||
void HealEdges (int e1, int e2)
|
void
|
||||||
|
HealEdges (int e1, int e2)
|
||||||
{
|
{
|
||||||
int i, j, n, saved;
|
int i, j, n, saved;
|
||||||
dface_t *df;
|
dface_t *df;
|
||||||
|
@ -257,14 +247,15 @@ void HealEdges (int e1, int e2)
|
||||||
dface_t *found[2];
|
dface_t *found[2];
|
||||||
int foundj[2];
|
int foundj[2];
|
||||||
|
|
||||||
return;
|
return;
|
||||||
e1 = edgemapping[e1];
|
e1 = edgemapping[e1];
|
||||||
e2 = edgemapping[e2];
|
e2 = edgemapping[e2];
|
||||||
|
|
||||||
// extend e1 to e2
|
// extend e1 to e2
|
||||||
ed = &bsp->edges[e1];
|
ed = &bsp->edges[e1];
|
||||||
ed2 = &bsp->edges[e2];
|
ed2 = &bsp->edges[e2];
|
||||||
VectorSubtract (bsp->vertexes[ed->v[1]].point, bsp->vertexes[ed->v[0]].point, v1);
|
VectorSubtract (bsp->vertexes[ed->v[1]].point,
|
||||||
|
bsp->vertexes[ed->v[0]].point, v1);
|
||||||
VectorNormalize (v1);
|
VectorNormalize (v1);
|
||||||
|
|
||||||
if (ed->v[0] == ed2->v[0])
|
if (ed->v[0] == ed2->v[0])
|
||||||
|
@ -278,7 +269,8 @@ return;
|
||||||
else
|
else
|
||||||
Sys_Error ("HealEdges: edges don't meet");
|
Sys_Error ("HealEdges: edges don't meet");
|
||||||
|
|
||||||
VectorSubtract (bsp->vertexes[ed->v[1]].point, bsp->vertexes[ed->v[0]].point, v2);
|
VectorSubtract (bsp->vertexes[ed->v[1]].point,
|
||||||
|
bsp->vertexes[ed->v[0]].point, v2);
|
||||||
VectorNormalize (v2);
|
VectorNormalize (v2);
|
||||||
|
|
||||||
if (!VectorCompare (v1, v2))
|
if (!VectorCompare (v1, v2))
|
||||||
|
@ -288,14 +280,11 @@ return;
|
||||||
saved = 0;
|
saved = 0;
|
||||||
|
|
||||||
// remove all uses of e2
|
// remove all uses of e2
|
||||||
for (i=firstmodelface ; i<bsp->numfaces ; i++)
|
for (i = firstmodelface; i < bsp->numfaces; i++) {
|
||||||
{
|
|
||||||
df = &bsp->faces[i];
|
df = &bsp->faces[i];
|
||||||
for (j=0 ; j<df->numedges ; j++)
|
for (j = 0; j < df->numedges; j++) {
|
||||||
{
|
n = bsp->surfedges[df->firstedge + j];
|
||||||
n = bsp->surfedges[df->firstedge+j];
|
if (n == e2 || n == -e2) {
|
||||||
if (n == e2 || n == -e2)
|
|
||||||
{
|
|
||||||
found[saved] = df;
|
found[saved] = df;
|
||||||
foundj[saved] = j;
|
foundj[saved] = j;
|
||||||
saved++;
|
saved++;
|
||||||
|
@ -306,16 +295,14 @@ return;
|
||||||
|
|
||||||
if (saved != 2)
|
if (saved != 2)
|
||||||
printf ("WARNING: didn't find both faces for a saved edge\n");
|
printf ("WARNING: didn't find both faces for a saved edge\n");
|
||||||
else
|
else {
|
||||||
{
|
for (i = 0; i < 2; i++) { // remove this edge
|
||||||
for (i=0 ; i<2 ; i++)
|
|
||||||
{ // remove this edge
|
|
||||||
df = found[i];
|
df = found[i];
|
||||||
j = foundj[i];
|
j = foundj[i];
|
||||||
for (j++ ; j<df->numedges ; j++)
|
for (j++; j < df->numedges; j++)
|
||||||
bsp->surfedges[df->firstedge+j-1] =
|
bsp->surfedges[df->firstedge + j - 1] =
|
||||||
bsp->surfedges[df->firstedge+j];
|
bsp->surfedges[df->firstedge + j];
|
||||||
bsp->surfedges[df->firstedge+j-1] = 0;
|
bsp->surfedges[df->firstedge + j - 1] = 0;
|
||||||
df->numedges--;
|
df->numedges--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,8 +311,7 @@ return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
int numedges;
|
int numedges;
|
||||||
int edges[2];
|
int edges[2];
|
||||||
} checkpoint_t;
|
} checkpoint_t;
|
||||||
|
@ -337,28 +323,27 @@ checkpoint_t checkpoints[MAX_MAP_VERTS];
|
||||||
RemoveColinearEdges
|
RemoveColinearEdges
|
||||||
==============
|
==============
|
||||||
*/
|
*/
|
||||||
void RemoveColinearEdges (void)
|
void
|
||||||
|
RemoveColinearEdges (void)
|
||||||
{
|
{
|
||||||
int i,j, v;
|
int i, j, v;
|
||||||
int c0, c1, c2, c3;
|
int c0, c1, c2, c3;
|
||||||
checkpoint_t *cp;
|
checkpoint_t *cp;
|
||||||
|
|
||||||
// no edges remapped yet
|
// no edges remapped yet
|
||||||
for (i=0 ; i<bsp->numedges ; i++)
|
for (i = 0; i < bsp->numedges; i++)
|
||||||
edgemapping[i] = i;
|
edgemapping[i] = i;
|
||||||
|
|
||||||
// find vertexes that only have two edges
|
// find vertexes that only have two edges
|
||||||
memset (checkpoints, 0, sizeof(checkpoints));
|
memset (checkpoints, 0, sizeof (checkpoints));
|
||||||
|
|
||||||
for (i=firstmodeledge ; i<bsp->numedges ; i++)
|
for (i = firstmodeledge; i < bsp->numedges; i++) {
|
||||||
{
|
|
||||||
if (!edgefaces[i][0])
|
if (!edgefaces[i][0])
|
||||||
continue; // removed
|
continue; // removed
|
||||||
for (j=0 ; j<2 ; j++)
|
for (j = 0; j < 2; j++) {
|
||||||
{
|
|
||||||
v = bsp->edges[i].v[j];
|
v = bsp->edges[i].v[j];
|
||||||
cp = &checkpoints[v];
|
cp = &checkpoints[v];
|
||||||
if (cp->numedges<2)
|
if (cp->numedges < 2)
|
||||||
cp->edges[cp->numedges] = i;
|
cp->edges[cp->numedges] = i;
|
||||||
cp->numedges++;
|
cp->numedges++;
|
||||||
}
|
}
|
||||||
|
@ -367,11 +352,9 @@ void RemoveColinearEdges (void)
|
||||||
// if a vertex only has two edges and they are colinear, it can be removed
|
// if a vertex only has two edges and they are colinear, it can be removed
|
||||||
c0 = c1 = c2 = c3 = 0;
|
c0 = c1 = c2 = c3 = 0;
|
||||||
|
|
||||||
for (i=0 ; i<bsp->numvertexes ; i++)
|
for (i = 0; i < bsp->numvertexes; i++) {
|
||||||
{
|
|
||||||
cp = &checkpoints[i];
|
cp = &checkpoints[i];
|
||||||
switch (cp->numedges)
|
switch (cp->numedges) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
c0++;
|
c0++;
|
||||||
break;
|
break;
|
||||||
|
@ -400,20 +383,21 @@ void RemoveColinearEdges (void)
|
||||||
CountRealNumbers
|
CountRealNumbers
|
||||||
==============
|
==============
|
||||||
*/
|
*/
|
||||||
void CountRealNumbers (void)
|
void
|
||||||
|
CountRealNumbers (void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
qprintf ("%5i regions\n", bsp->numfaces-firstmodelface);
|
qprintf ("%5i regions\n", bsp->numfaces - firstmodelface);
|
||||||
|
|
||||||
c = 0;
|
c = 0;
|
||||||
for (i=firstmodelface ; i<bsp->numfaces ; i++)
|
for (i = firstmodelface; i < bsp->numfaces; i++)
|
||||||
c += bsp->faces[i].numedges;
|
c += bsp->faces[i].numedges;
|
||||||
qprintf ("%5i real marksurfaces\n", c);
|
qprintf ("%5i real marksurfaces\n", c);
|
||||||
|
|
||||||
c = 0;
|
c = 0;
|
||||||
for (i=firstmodeledge ; i<bsp->numedges ; i++)
|
for (i = firstmodeledge; i < bsp->numedges; i++)
|
||||||
if (edgefaces[i][0])
|
if (edgefaces[i][0])
|
||||||
c++; // not removed
|
c++; // not removed
|
||||||
|
|
||||||
|
@ -427,7 +411,8 @@ void CountRealNumbers (void)
|
||||||
GrowNodeRegion_r
|
GrowNodeRegion_r
|
||||||
==============
|
==============
|
||||||
*/
|
*/
|
||||||
void GrowNodeRegion_r (node_t *node)
|
void
|
||||||
|
GrowNodeRegion_r (node_t * node)
|
||||||
{
|
{
|
||||||
dface_t *r;
|
dface_t *r;
|
||||||
face_t *f;
|
face_t *f;
|
||||||
|
@ -438,8 +423,7 @@ void GrowNodeRegion_r (node_t *node)
|
||||||
|
|
||||||
node->firstface = bsp->numfaces;
|
node->firstface = bsp->numfaces;
|
||||||
|
|
||||||
for (f=node->faces ; f ; f=f->next)
|
for (f = node->faces; f; f = f->next) {
|
||||||
{
|
|
||||||
// if (f->outputnumber != -1)
|
// if (f->outputnumber != -1)
|
||||||
// continue; // allready grown into an earlier region
|
// continue; // allready grown into an earlier region
|
||||||
|
|
||||||
|
@ -453,7 +437,7 @@ void GrowNodeRegion_r (node_t *node)
|
||||||
r->planenum = node->outputplanenum;
|
r->planenum = node->outputplanenum;
|
||||||
r->side = f->planeside;
|
r->side = f->planeside;
|
||||||
r->texinfo = f->texturenum;
|
r->texinfo = f->texturenum;
|
||||||
for (i=0 ; i<MAXLIGHTMAPS ; i++)
|
for (i = 0; i < MAXLIGHTMAPS; i++)
|
||||||
r->styles[i] = 255;
|
r->styles[i] = 255;
|
||||||
r->lightofs = -1;
|
r->lightofs = -1;
|
||||||
|
|
||||||
|
@ -465,8 +449,7 @@ void GrowNodeRegion_r (node_t *node)
|
||||||
RecursiveGrowRegion (r, f);
|
RecursiveGrowRegion (r, f);
|
||||||
#endif
|
#endif
|
||||||
r->firstedge = firstedge = bsp->numsurfedges;
|
r->firstedge = firstedge = bsp->numsurfedges;
|
||||||
for (i=0 ; i<f->numpoints ; i++)
|
for (i = 0; i < f->numpoints; i++) {
|
||||||
{
|
|
||||||
if (bsp->numsurfedges == MAX_MAP_SURFEDGES)
|
if (bsp->numsurfedges == MAX_MAP_SURFEDGES)
|
||||||
Sys_Error ("numsurfedges == MAX_MAP_SURFEDGES");
|
Sys_Error ("numsurfedges == MAX_MAP_SURFEDGES");
|
||||||
bsp->surfedges[bsp->numsurfedges] = f->edges[i];
|
bsp->surfedges[bsp->numsurfedges] = f->edges[i];
|
||||||
|
@ -490,7 +473,8 @@ void GrowNodeRegion_r (node_t *node)
|
||||||
GrowNodeRegions
|
GrowNodeRegions
|
||||||
==============
|
==============
|
||||||
*/
|
*/
|
||||||
void GrowNodeRegions (node_t *headnode)
|
void
|
||||||
|
GrowNodeRegions (node_t * headnode)
|
||||||
{
|
{
|
||||||
qprintf ("---- GrowRegions ----\n");
|
qprintf ("---- GrowRegions ----\n");
|
||||||
|
|
||||||
|
@ -521,16 +505,3 @@ for all faces
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,8 @@ FaceSide
|
||||||
For BSP hueristic
|
For BSP hueristic
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
int FaceSide (face_t *in, plane_t *split)
|
int
|
||||||
|
FaceSide (face_t * in, plane_t *split)
|
||||||
{
|
{
|
||||||
int frontcount, backcount;
|
int frontcount, backcount;
|
||||||
vec_t dot;
|
vec_t dot;
|
||||||
|
@ -57,35 +58,27 @@ int FaceSide (face_t *in, plane_t *split)
|
||||||
|
|
||||||
// axial planes are fast
|
// axial planes are fast
|
||||||
if (split->type < 3)
|
if (split->type < 3)
|
||||||
for (i=0, p = in->pts[0]+split->type ; i<in->numpoints ; i++, p+=3)
|
for (i = 0, p = in->pts[0] + split->type; i < in->numpoints;
|
||||||
{
|
i++, p += 3) {
|
||||||
if (*p > split->dist + ON_EPSILON)
|
if (*p > split->dist + ON_EPSILON) {
|
||||||
{
|
|
||||||
if (backcount)
|
if (backcount)
|
||||||
return SIDE_ON;
|
return SIDE_ON;
|
||||||
frontcount = 1;
|
frontcount = 1;
|
||||||
}
|
} else if (*p < split->dist - ON_EPSILON) {
|
||||||
else if (*p < split->dist - ON_EPSILON)
|
|
||||||
{
|
|
||||||
if (frontcount)
|
if (frontcount)
|
||||||
return SIDE_ON;
|
return SIDE_ON;
|
||||||
backcount = 1;
|
backcount = 1;
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
// sloping planes take longer
|
// sloping planes take longer
|
||||||
for (i=0, p = in->pts[0] ; i<in->numpoints ; i++, p+=3)
|
for (i = 0, p = in->pts[0]; i < in->numpoints; i++, p += 3) {
|
||||||
{
|
|
||||||
dot = DotProduct (p, split->normal);
|
dot = DotProduct (p, split->normal);
|
||||||
dot -= split->dist;
|
dot -= split->dist;
|
||||||
if (dot > ON_EPSILON)
|
if (dot > ON_EPSILON) {
|
||||||
{
|
|
||||||
if (backcount)
|
if (backcount)
|
||||||
return SIDE_ON;
|
return SIDE_ON;
|
||||||
frontcount = 1;
|
frontcount = 1;
|
||||||
}
|
} else if (dot < -ON_EPSILON) {
|
||||||
else if (dot < -ON_EPSILON)
|
|
||||||
{
|
|
||||||
if (frontcount)
|
if (frontcount)
|
||||||
return SIDE_ON;
|
return SIDE_ON;
|
||||||
backcount = 1;
|
backcount = 1;
|
||||||
|
@ -107,9 +100,10 @@ ChooseMidPlaneFromList
|
||||||
The clipping hull BSP doesn't worry about avoiding splits
|
The clipping hull BSP doesn't worry about avoiding splits
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
surface_t *ChooseMidPlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs)
|
surface_t *
|
||||||
|
ChooseMidPlaneFromList (surface_t * surfaces, vec3_t mins, vec3_t maxs)
|
||||||
{
|
{
|
||||||
int j,l;
|
int j, l;
|
||||||
surface_t *p, *bestsurface;
|
surface_t *p, *bestsurface;
|
||||||
vec_t bestvalue, value, dist;
|
vec_t bestvalue, value, dist;
|
||||||
plane_t *plane;
|
plane_t *plane;
|
||||||
|
@ -117,11 +111,10 @@ surface_t *ChooseMidPlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs
|
||||||
//
|
//
|
||||||
// pick the plane that splits the least
|
// pick the plane that splits the least
|
||||||
//
|
//
|
||||||
bestvalue = 6*8192*8192;
|
bestvalue = 6 * 8192 * 8192;
|
||||||
bestsurface = NULL;
|
bestsurface = NULL;
|
||||||
|
|
||||||
for (p=surfaces ; p ; p=p->next)
|
for (p = surfaces; p; p = p->next) {
|
||||||
{
|
|
||||||
if (p->onnode)
|
if (p->onnode)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -138,15 +131,12 @@ surface_t *ChooseMidPlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs
|
||||||
value = 0;
|
value = 0;
|
||||||
|
|
||||||
dist = plane->dist * plane->normal[l];
|
dist = plane->dist * plane->normal[l];
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j = 0; j < 3; j++) {
|
||||||
{
|
if (j == l) {
|
||||||
if (j == l)
|
value += (maxs[l] - dist) * (maxs[l] - dist);
|
||||||
{
|
value += (dist - mins[l]) * (dist - mins[l]);
|
||||||
value += (maxs[l]-dist)*(maxs[l]-dist);
|
} else
|
||||||
value += (dist-mins[l])*(dist-mins[l]);
|
value += 2 * (maxs[j] - mins[j]) * (maxs[j] - mins[j]);
|
||||||
}
|
|
||||||
else
|
|
||||||
value += 2*(maxs[j]-mins[j])*(maxs[j]-mins[j]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value > bestvalue)
|
if (value > bestvalue)
|
||||||
|
@ -159,9 +149,8 @@ surface_t *ChooseMidPlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs
|
||||||
bestsurface = p;
|
bestsurface = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bestsurface)
|
if (!bestsurface) {
|
||||||
{
|
for (p = surfaces; p; p = p->next)
|
||||||
for (p=surfaces ; p ; p=p->next)
|
|
||||||
if (!p->onnode)
|
if (!p->onnode)
|
||||||
return p; // first valid surface
|
return p; // first valid surface
|
||||||
Sys_Error ("ChooseMidPlaneFromList: no valid planes");
|
Sys_Error ("ChooseMidPlaneFromList: no valid planes");
|
||||||
|
@ -179,9 +168,11 @@ ChoosePlaneFromList
|
||||||
The real BSP hueristic
|
The real BSP hueristic
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
surface_t *ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs, qboolean usefloors)
|
surface_t *
|
||||||
|
ChoosePlaneFromList (surface_t * surfaces, vec3_t mins, vec3_t maxs,
|
||||||
|
qboolean usefloors)
|
||||||
{
|
{
|
||||||
int j,k,l;
|
int j, k, l;
|
||||||
surface_t *p, *p2, *bestsurface;
|
surface_t *p, *p2, *bestsurface;
|
||||||
vec_t bestvalue, bestdistribution, value, dist;
|
vec_t bestvalue, bestdistribution, value, dist;
|
||||||
plane_t *plane;
|
plane_t *plane;
|
||||||
|
@ -194,8 +185,7 @@ surface_t *ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs, q
|
||||||
bestsurface = NULL;
|
bestsurface = NULL;
|
||||||
bestdistribution = 9e30;
|
bestdistribution = 9e30;
|
||||||
|
|
||||||
for (p=surfaces ; p ; p=p->next)
|
for (p = surfaces; p; p = p->next) {
|
||||||
{
|
|
||||||
if (p->onnode)
|
if (p->onnode)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -205,17 +195,14 @@ surface_t *ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs, q
|
||||||
if (!usefloors && plane->normal[2] == 1)
|
if (!usefloors && plane->normal[2] == 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (p2=surfaces ; p2 ; p2=p2->next)
|
for (p2 = surfaces; p2; p2 = p2->next) {
|
||||||
{
|
|
||||||
if (p2 == p)
|
if (p2 == p)
|
||||||
continue;
|
continue;
|
||||||
if (p2->onnode)
|
if (p2->onnode)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (f=p2->faces ; f ; f=f->next)
|
for (f = p2->faces; f; f = f->next) {
|
||||||
{
|
if (FaceSide (f, plane) == SIDE_ON) {
|
||||||
if (FaceSide (f, plane) == SIDE_ON)
|
|
||||||
{
|
|
||||||
k++;
|
k++;
|
||||||
if (k >= bestvalue)
|
if (k >= bestvalue)
|
||||||
break;
|
break;
|
||||||
|
@ -229,30 +216,27 @@ surface_t *ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs, q
|
||||||
if (k > bestvalue)
|
if (k > bestvalue)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// if equal numbers, axial planes win, then decide on spatial subdivision
|
// if equal numbers, axial planes win, then decide on spatial
|
||||||
|
// subdivision
|
||||||
|
|
||||||
if (k < bestvalue || (k == bestvalue && plane->type < PLANE_ANYX) )
|
if (k < bestvalue || (k == bestvalue && plane->type < PLANE_ANYX)) {
|
||||||
{
|
|
||||||
// check for axis aligned surfaces
|
// check for axis aligned surfaces
|
||||||
l = plane->type;
|
l = plane->type;
|
||||||
|
|
||||||
if (l <= PLANE_Z)
|
if (l <= PLANE_Z) { // axial aligned
|
||||||
{ // axial aligned
|
//
|
||||||
//
|
//
|
||||||
// calculate the split metric along axis l
|
// calculate the split metric along axis l
|
||||||
//
|
//
|
||||||
value = 0;
|
value = 0;
|
||||||
|
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j = 0; j < 3; j++) {
|
||||||
{
|
if (j == l) {
|
||||||
if (j == l)
|
|
||||||
{
|
|
||||||
dist = plane->dist * plane->normal[l];
|
dist = plane->dist * plane->normal[l];
|
||||||
value += (maxs[l]-dist)*(maxs[l]-dist);
|
value += (maxs[l] - dist) * (maxs[l] - dist);
|
||||||
value += (dist-mins[l])*(dist-mins[l]);
|
value += (dist - mins[l]) * (dist - mins[l]);
|
||||||
}
|
} else
|
||||||
else
|
value += 2 * (maxs[j] - mins[j]) * (maxs[j] - mins[j]);
|
||||||
value += 2*(maxs[j]-mins[j])*(maxs[j]-mins[j]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value > bestdistribution && k == bestvalue)
|
if (value > bestdistribution && k == bestvalue)
|
||||||
|
@ -281,9 +265,10 @@ Selects a surface from a linked list of surfaces to split the group on
|
||||||
returns NULL if the surface list can not be divided any more (a leaf)
|
returns NULL if the surface list can not be divided any more (a leaf)
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
surface_t *SelectPartition (surface_t *surfaces)
|
surface_t *
|
||||||
|
SelectPartition (surface_t * surfaces)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i, j;
|
||||||
vec3_t mins, maxs;
|
vec3_t mins, maxs;
|
||||||
surface_t *p, *bestsurface;
|
surface_t *p, *bestsurface;
|
||||||
|
|
||||||
|
@ -292,31 +277,28 @@ surface_t *SelectPartition (surface_t *surfaces)
|
||||||
//
|
//
|
||||||
i = 0;
|
i = 0;
|
||||||
bestsurface = NULL;
|
bestsurface = NULL;
|
||||||
for (p=surfaces ; p ; p=p->next)
|
for (p = surfaces; p; p = p->next)
|
||||||
if (!p->onnode)
|
if (!p->onnode) {
|
||||||
{
|
|
||||||
i++;
|
i++;
|
||||||
bestsurface = p;
|
bestsurface = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i==0)
|
if (i == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (i==1)
|
if (i == 1)
|
||||||
return bestsurface; // this is a final split
|
return bestsurface; // this is a final split
|
||||||
|
|
||||||
//
|
//
|
||||||
// calculate a bounding box of the entire surfaceset
|
// calculate a bounding box of the entire surfaceset
|
||||||
//
|
//
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
{
|
|
||||||
mins[i] = 99999;
|
mins[i] = 99999;
|
||||||
maxs[i] = -99999;
|
maxs[i] = -99999;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (p=surfaces ; p ; p=p->next)
|
for (p = surfaces; p; p = p->next)
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j = 0; j < 3; j++) {
|
||||||
{
|
|
||||||
if (p->mins[j] < mins[j])
|
if (p->mins[j] < mins[j])
|
||||||
mins[j] = p->mins[j];
|
mins[j] = p->mins[j];
|
||||||
if (p->maxs[j] > maxs[j])
|
if (p->maxs[j] > maxs[j])
|
||||||
|
@ -344,9 +326,10 @@ CalcSurfaceInfo
|
||||||
Calculates the bounding box
|
Calculates the bounding box
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void CalcSurfaceInfo (surface_t *surf)
|
void
|
||||||
|
CalcSurfaceInfo (surface_t * surf)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i, j;
|
||||||
face_t *f;
|
face_t *f;
|
||||||
|
|
||||||
if (!surf->faces)
|
if (!surf->faces)
|
||||||
|
@ -355,19 +338,16 @@ void CalcSurfaceInfo (surface_t *surf)
|
||||||
//
|
//
|
||||||
// calculate a bounding box
|
// calculate a bounding box
|
||||||
//
|
//
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
{
|
|
||||||
surf->mins[i] = 99999;
|
surf->mins[i] = 99999;
|
||||||
surf->maxs[i] = -99999;
|
surf->maxs[i] = -99999;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (f=surf->faces ; f ; f=f->next)
|
for (f = surf->faces; f; f = f->next) {
|
||||||
{
|
if (f->contents[0] >= 0 || f->contents[1] >= 0)
|
||||||
if (f->contents[0] >= 0 || f->contents[1] >= 0)
|
Sys_Error ("Bad contents");
|
||||||
Sys_Error ("Bad contents");
|
for (i = 0; i < f->numpoints; i++)
|
||||||
for (i=0 ; i<f->numpoints ; i++)
|
for (j = 0; j < 3; j++) {
|
||||||
for (j=0 ; j<3 ; j++)
|
|
||||||
{
|
|
||||||
if (f->pts[i][j] < surf->mins[j])
|
if (f->pts[i][j] < surf->mins[j])
|
||||||
surf->mins[j] = f->pts[i][j];
|
surf->mins[j] = f->pts[i][j];
|
||||||
if (f->pts[i][j] > surf->maxs[j])
|
if (f->pts[i][j] > surf->maxs[j])
|
||||||
|
@ -383,7 +363,9 @@ Sys_Error ("Bad contents");
|
||||||
DividePlane
|
DividePlane
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void DividePlane (surface_t *in, plane_t *split, surface_t **front, surface_t **back)
|
void
|
||||||
|
DividePlane (surface_t * in, plane_t *split, surface_t ** front,
|
||||||
|
surface_t ** back)
|
||||||
{
|
{
|
||||||
face_t *facet, *next;
|
face_t *facet, *next;
|
||||||
face_t *frontlist, *backlist;
|
face_t *frontlist, *backlist;
|
||||||
|
@ -394,29 +376,24 @@ void DividePlane (surface_t *in, plane_t *split, surface_t **front, surface_t **
|
||||||
inplane = &planes[in->planenum];
|
inplane = &planes[in->planenum];
|
||||||
|
|
||||||
// parallel case is easy
|
// parallel case is easy
|
||||||
if (VectorCompare (inplane->normal, split->normal))
|
if (VectorCompare (inplane->normal, split->normal)) {
|
||||||
{
|
|
||||||
// check for exactly on node
|
// check for exactly on node
|
||||||
if (inplane->dist == split->dist)
|
if (inplane->dist == split->dist) { // divide the facets to the front
|
||||||
{ // divide the facets to the front and back sides
|
// and back sides
|
||||||
news = AllocSurface ();
|
news = AllocSurface ();
|
||||||
*news = *in;
|
*news = *in;
|
||||||
|
|
||||||
facet=in->faces;
|
facet = in->faces;
|
||||||
in->faces = NULL;
|
in->faces = NULL;
|
||||||
news->faces = NULL;
|
news->faces = NULL;
|
||||||
in->onnode = news->onnode = true;
|
in->onnode = news->onnode = true;
|
||||||
|
|
||||||
for ( ; facet ; facet=next)
|
for (; facet; facet = next) {
|
||||||
{
|
|
||||||
next = facet->next;
|
next = facet->next;
|
||||||
if (facet->planeside == 1)
|
if (facet->planeside == 1) {
|
||||||
{
|
|
||||||
facet->next = news->faces;
|
facet->next = news->faces;
|
||||||
news->faces = facet;
|
news->faces = facet;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
facet->next = in->faces;
|
facet->next = in->faces;
|
||||||
in->faces = facet;
|
in->faces = facet;
|
||||||
}
|
}
|
||||||
|
@ -433,35 +410,28 @@ void DividePlane (surface_t *in, plane_t *split, surface_t **front, surface_t **
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inplane->dist > split->dist)
|
if (inplane->dist > split->dist) {
|
||||||
{
|
|
||||||
*front = in;
|
*front = in;
|
||||||
*back = NULL;
|
*back = NULL;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
*front = NULL;
|
*front = NULL;
|
||||||
*back = in;
|
*back = in;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// do a real split. may still end up entirely on one side
|
// do a real split. may still end up entirely on one side
|
||||||
// OPTIMIZE: use bounding box for fast test
|
// OPTIMIZE: use bounding box for fast test
|
||||||
frontlist = NULL;
|
frontlist = NULL;
|
||||||
backlist = NULL;
|
backlist = NULL;
|
||||||
|
|
||||||
for (facet = in->faces ; facet ; facet = next)
|
for (facet = in->faces; facet; facet = next) {
|
||||||
{
|
|
||||||
next = facet->next;
|
next = facet->next;
|
||||||
SplitFace (facet, split, &frontfrag, &backfrag);
|
SplitFace (facet, split, &frontfrag, &backfrag);
|
||||||
if (frontfrag)
|
if (frontfrag) {
|
||||||
{
|
|
||||||
frontfrag->next = frontlist;
|
frontfrag->next = frontlist;
|
||||||
frontlist = frontfrag;
|
frontlist = frontfrag;
|
||||||
}
|
}
|
||||||
if (backfrag)
|
if (backfrag) {
|
||||||
{
|
|
||||||
backfrag->next = backlist;
|
backfrag->next = backlist;
|
||||||
backlist = backfrag;
|
backlist = backfrag;
|
||||||
}
|
}
|
||||||
|
@ -469,23 +439,20 @@ void DividePlane (surface_t *in, plane_t *split, surface_t **front, surface_t **
|
||||||
|
|
||||||
// if nothing actually got split, just move the in plane
|
// if nothing actually got split, just move the in plane
|
||||||
|
|
||||||
if (frontlist == NULL)
|
if (frontlist == NULL) {
|
||||||
{
|
|
||||||
*front = NULL;
|
*front = NULL;
|
||||||
*back = in;
|
*back = in;
|
||||||
in->faces = backlist;
|
in->faces = backlist;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (backlist == NULL)
|
if (backlist == NULL) {
|
||||||
{
|
|
||||||
*front = in;
|
*front = in;
|
||||||
*back = NULL;
|
*back = NULL;
|
||||||
in->faces = frontlist;
|
in->faces = frontlist;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// stuff got split, so allocate one new plane and reuse in
|
// stuff got split, so allocate one new plane and reuse in
|
||||||
news = AllocSurface ();
|
news = AllocSurface ();
|
||||||
*news = *in;
|
*news = *in;
|
||||||
|
@ -505,7 +472,8 @@ void DividePlane (surface_t *in, plane_t *split, surface_t **front, surface_t **
|
||||||
DivideNodeBounds
|
DivideNodeBounds
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void DivideNodeBounds (node_t *node, plane_t *split)
|
void
|
||||||
|
DivideNodeBounds (node_t * node, plane_t *split)
|
||||||
{
|
{
|
||||||
VectorCopy (node->mins, node->children[0]->mins);
|
VectorCopy (node->mins, node->children[0]->mins);
|
||||||
VectorCopy (node->mins, node->children[1]->mins);
|
VectorCopy (node->mins, node->children[1]->mins);
|
||||||
|
@ -528,7 +496,8 @@ Determines the contents of the leaf and creates the final list of
|
||||||
original faces that have some fragment inside this leaf
|
original faces that have some fragment inside this leaf
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void LinkConvexFaces (surface_t *planelist, node_t *leafnode)
|
void
|
||||||
|
LinkConvexFaces (surface_t * planelist, node_t * leafnode)
|
||||||
{
|
{
|
||||||
face_t *f, *next;
|
face_t *f, *next;
|
||||||
surface_t *surf, *pnext;
|
surface_t *surf, *pnext;
|
||||||
|
@ -539,10 +508,8 @@ void LinkConvexFaces (surface_t *planelist, node_t *leafnode)
|
||||||
leafnode->planenum = -1;
|
leafnode->planenum = -1;
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
for ( surf = planelist ; surf ; surf = surf->next)
|
for (surf = planelist; surf; surf = surf->next) {
|
||||||
{
|
for (f = surf->faces; f; f = f->next) {
|
||||||
for (f = surf->faces ; f ; f=f->next)
|
|
||||||
{
|
|
||||||
count++;
|
count++;
|
||||||
if (!leafnode->contents)
|
if (!leafnode->contents)
|
||||||
leafnode->contents = f->contents[0];
|
leafnode->contents = f->contents[0];
|
||||||
|
@ -554,8 +521,7 @@ void LinkConvexFaces (surface_t *planelist, node_t *leafnode)
|
||||||
if (!leafnode->contents)
|
if (!leafnode->contents)
|
||||||
leafnode->contents = CONTENTS_SOLID;
|
leafnode->contents = CONTENTS_SOLID;
|
||||||
|
|
||||||
switch (leafnode->contents)
|
switch (leafnode->contents) {
|
||||||
{
|
|
||||||
case CONTENTS_EMPTY:
|
case CONTENTS_EMPTY:
|
||||||
c_empty++;
|
c_empty++;
|
||||||
break;
|
break;
|
||||||
|
@ -576,13 +542,11 @@ void LinkConvexFaces (surface_t *planelist, node_t *leafnode)
|
||||||
// write the list of faces, and free the originals
|
// write the list of faces, and free the originals
|
||||||
//
|
//
|
||||||
leaffaces += count;
|
leaffaces += count;
|
||||||
leafnode->markfaces = malloc(sizeof(face_t *)*(count+1));
|
leafnode->markfaces = malloc (sizeof (face_t *) * (count + 1));
|
||||||
i = 0;
|
i = 0;
|
||||||
for ( surf = planelist ; surf ; surf = pnext)
|
for (surf = planelist; surf; surf = pnext) {
|
||||||
{
|
|
||||||
pnext = surf->next;
|
pnext = surf->next;
|
||||||
for (f = surf->faces ; f ; f=next)
|
for (f = surf->faces; f; f = next) {
|
||||||
{
|
|
||||||
next = f->next;
|
next = f->next;
|
||||||
leafnode->markfaces[i] = f->original;
|
leafnode->markfaces[i] = f->original;
|
||||||
i++;
|
i++;
|
||||||
|
@ -601,7 +565,8 @@ LinkNodeFaces
|
||||||
Returns a duplicated list of all faces on surface
|
Returns a duplicated list of all faces on surface
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
face_t *LinkNodeFaces (surface_t *surface)
|
face_t *
|
||||||
|
LinkNodeFaces (surface_t * surface)
|
||||||
{
|
{
|
||||||
face_t *f, *new, **prevptr;
|
face_t *f, *new, **prevptr;
|
||||||
face_t *list;
|
face_t *list;
|
||||||
|
@ -611,8 +576,7 @@ face_t *LinkNodeFaces (surface_t *surface)
|
||||||
|
|
||||||
// subdivide
|
// subdivide
|
||||||
prevptr = &surface->faces;
|
prevptr = &surface->faces;
|
||||||
while (1)
|
while (1) {
|
||||||
{
|
|
||||||
f = *prevptr;
|
f = *prevptr;
|
||||||
if (!f)
|
if (!f)
|
||||||
break;
|
break;
|
||||||
|
@ -622,8 +586,7 @@ face_t *LinkNodeFaces (surface_t *surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy
|
// copy
|
||||||
for (f=surface->faces ; f ; f=f->next)
|
for (f = surface->faces; f; f = f->next) {
|
||||||
{
|
|
||||||
nodefaces++;
|
nodefaces++;
|
||||||
new = AllocFace ();
|
new = AllocFace ();
|
||||||
*new = *f;
|
*new = *f;
|
||||||
|
@ -641,7 +604,8 @@ face_t *LinkNodeFaces (surface_t *surface)
|
||||||
PartitionSurfaces
|
PartitionSurfaces
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void PartitionSurfaces (surface_t *surfaces, node_t *node)
|
void
|
||||||
|
PartitionSurfaces (surface_t * surfaces, node_t * node)
|
||||||
{
|
{
|
||||||
surface_t *split, *p, *next;
|
surface_t *split, *p, *next;
|
||||||
surface_t *frontlist, *backlist;
|
surface_t *frontlist, *backlist;
|
||||||
|
@ -649,8 +613,7 @@ void PartitionSurfaces (surface_t *surfaces, node_t *node)
|
||||||
plane_t *splitplane;
|
plane_t *splitplane;
|
||||||
|
|
||||||
split = SelectPartition (surfaces);
|
split = SelectPartition (surfaces);
|
||||||
if (!split)
|
if (!split) { // this is a leaf node
|
||||||
{ // this is a leaf node
|
|
||||||
node->planenum = PLANENUM_LEAF;
|
node->planenum = PLANENUM_LEAF;
|
||||||
LinkConvexFaces (surfaces, node);
|
LinkConvexFaces (surfaces, node);
|
||||||
return;
|
return;
|
||||||
|
@ -673,27 +636,23 @@ void PartitionSurfaces (surface_t *surfaces, node_t *node)
|
||||||
frontlist = NULL;
|
frontlist = NULL;
|
||||||
backlist = NULL;
|
backlist = NULL;
|
||||||
|
|
||||||
for (p=surfaces ; p ; p=next)
|
for (p = surfaces; p; p = next) {
|
||||||
{
|
|
||||||
next = p->next;
|
next = p->next;
|
||||||
DividePlane (p, splitplane, &frontfrag, &backfrag);
|
DividePlane (p, splitplane, &frontfrag, &backfrag);
|
||||||
if (frontfrag && backfrag)
|
if (frontfrag && backfrag) {
|
||||||
{
|
|
||||||
// the plane was split, which may expose oportunities to merge
|
// the plane was split, which may expose oportunities to merge
|
||||||
// adjacent faces into a single face
|
// adjacent faces into a single face
|
||||||
// MergePlaneFaces (frontfrag);
|
// MergePlaneFaces (frontfrag);
|
||||||
// MergePlaneFaces (backfrag);
|
// MergePlaneFaces (backfrag);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frontfrag)
|
if (frontfrag) {
|
||||||
{
|
|
||||||
if (!frontfrag->faces)
|
if (!frontfrag->faces)
|
||||||
Sys_Error ("surface with no faces");
|
Sys_Error ("surface with no faces");
|
||||||
frontfrag->next = frontlist;
|
frontfrag->next = frontlist;
|
||||||
frontlist = frontfrag;
|
frontlist = frontfrag;
|
||||||
}
|
}
|
||||||
if (backfrag)
|
if (backfrag) {
|
||||||
{
|
|
||||||
if (!backfrag->faces)
|
if (!backfrag->faces)
|
||||||
Sys_Error ("surface with no faces");
|
Sys_Error ("surface with no faces");
|
||||||
backfrag->next = backlist;
|
backfrag->next = backlist;
|
||||||
|
@ -710,11 +669,12 @@ void PartitionSurfaces (surface_t *surfaces, node_t *node)
|
||||||
DrawSurface
|
DrawSurface
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void DrawSurface (surface_t *surf)
|
void
|
||||||
|
DrawSurface (surface_t * surf)
|
||||||
{
|
{
|
||||||
face_t *f;
|
face_t *f;
|
||||||
|
|
||||||
for (f=surf->faces ; f ; f=f->next)
|
for (f = surf->faces; f; f = f->next)
|
||||||
Draw_DrawFace (f);
|
Draw_DrawFace (f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,11 +683,11 @@ void DrawSurface (surface_t *surf)
|
||||||
DrawSurfaceList
|
DrawSurfaceList
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void DrawSurfaceList (surface_t *surf)
|
void
|
||||||
|
DrawSurfaceList (surface_t * surf)
|
||||||
{
|
{
|
||||||
Draw_ClearWindow ();
|
Draw_ClearWindow ();
|
||||||
while (surf)
|
while (surf) {
|
||||||
{
|
|
||||||
DrawSurface (surf);
|
DrawSurface (surf);
|
||||||
surf = surf->next;
|
surf = surf->next;
|
||||||
}
|
}
|
||||||
|
@ -738,7 +698,8 @@ void DrawSurfaceList (surface_t *surf)
|
||||||
SolidBSP
|
SolidBSP
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
node_t *SolidBSP (surface_t *surfhead, qboolean midsplit)
|
node_t *
|
||||||
|
SolidBSP (surface_t * surfhead, qboolean midsplit)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
node_t *headnode;
|
node_t *headnode;
|
||||||
|
@ -751,8 +712,7 @@ node_t *SolidBSP (surface_t *surfhead, qboolean midsplit)
|
||||||
//
|
//
|
||||||
// calculate a bounding box for the entire model
|
// calculate a bounding box for the entire model
|
||||||
//
|
//
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
{
|
|
||||||
headnode->mins[i] = brushset->mins[i] - SIDESPACE;
|
headnode->mins[i] = brushset->mins[i] - SIDESPACE;
|
||||||
headnode->maxs[i] = brushset->maxs[i] + SIDESPACE;
|
headnode->maxs[i] = brushset->maxs[i] + SIDESPACE;
|
||||||
}
|
}
|
||||||
|
@ -772,9 +732,8 @@ node_t *SolidBSP (surface_t *surfhead, qboolean midsplit)
|
||||||
qprintf ("%5i solid leafs\n", c_solid);
|
qprintf ("%5i solid leafs\n", c_solid);
|
||||||
qprintf ("%5i empty leafs\n", c_empty);
|
qprintf ("%5i empty leafs\n", c_empty);
|
||||||
qprintf ("%5i water leafs\n", c_water);
|
qprintf ("%5i water leafs\n", c_water);
|
||||||
qprintf ("%5i leaffaces\n",leaffaces);
|
qprintf ("%5i leaffaces\n", leaffaces);
|
||||||
qprintf ("%5i nodefaces\n", nodefaces);
|
qprintf ("%5i nodefaces\n", nodefaces);
|
||||||
|
|
||||||
return headnode;
|
return headnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,8 @@ If the face is >256 in either texture direction, carve a valid sized
|
||||||
piece off and insert the remainder in the next link
|
piece off and insert the remainder in the next link
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
void SubdivideFace (face_t *f, face_t **prevptr)
|
void
|
||||||
|
SubdivideFace (face_t * f, face_t ** prevptr)
|
||||||
{
|
{
|
||||||
float mins, maxs;
|
float mins, maxs;
|
||||||
vec_t v;
|
vec_t v;
|
||||||
|
@ -61,19 +62,16 @@ void SubdivideFace (face_t *f, face_t **prevptr)
|
||||||
// special (non-surface cached) faces don't need subdivision
|
// special (non-surface cached) faces don't need subdivision
|
||||||
tex = &bsp->texinfo[f->texturenum];
|
tex = &bsp->texinfo[f->texturenum];
|
||||||
|
|
||||||
if ( tex->flags & TEX_SPECIAL)
|
if (tex->flags & TEX_SPECIAL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
for (axis = 0 ; axis < 2 ; axis++)
|
for (axis = 0; axis < 2; axis++) {
|
||||||
{
|
while (1) {
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
mins = 9999;
|
mins = 9999;
|
||||||
maxs = -9999;
|
maxs = -9999;
|
||||||
|
|
||||||
for (i=0 ; i<f->numpoints ; i++)
|
for (i = 0; i < f->numpoints; i++) {
|
||||||
{
|
|
||||||
v = DotProduct (f->pts[i], tex->vecs[axis]);
|
v = DotProduct (f->pts[i], tex->vecs[axis]);
|
||||||
if (v < mins)
|
if (v < mins)
|
||||||
mins = v;
|
mins = v;
|
||||||
|
@ -90,7 +88,7 @@ void SubdivideFace (face_t *f, face_t **prevptr)
|
||||||
VectorCopy (tex->vecs[axis], plane.normal);
|
VectorCopy (tex->vecs[axis], plane.normal);
|
||||||
v = VectorLength (plane.normal);
|
v = VectorLength (plane.normal);
|
||||||
VectorNormalize (plane.normal);
|
VectorNormalize (plane.normal);
|
||||||
plane.dist = (mins + subdivide_size - 16)/v;
|
plane.dist = (mins + subdivide_size - 16) / v;
|
||||||
next = f->next;
|
next = f->next;
|
||||||
SplitFace (f, &plane, &front, &back);
|
SplitFace (f, &plane, &front, &back);
|
||||||
if (!front || !back)
|
if (!front || !back)
|
||||||
|
@ -109,20 +107,19 @@ void SubdivideFace (face_t *f, face_t **prevptr)
|
||||||
SubdivideFaces
|
SubdivideFaces
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void SubdivideFaces (surface_t *surfhead)
|
void
|
||||||
|
SubdivideFaces (surface_t * surfhead)
|
||||||
{
|
{
|
||||||
surface_t *surf;
|
surface_t *surf;
|
||||||
face_t *f , **prevptr;
|
face_t *f, **prevptr;
|
||||||
|
|
||||||
qprintf ("--- SubdivideFaces ---\n");
|
qprintf ("--- SubdivideFaces ---\n");
|
||||||
|
|
||||||
subdivides = 0;
|
subdivides = 0;
|
||||||
|
|
||||||
for (surf = surfhead ; surf ; surf=surf->next)
|
for (surf = surfhead; surf; surf = surf->next) {
|
||||||
{
|
|
||||||
prevptr = &surf->faces;
|
prevptr = &surf->faces;
|
||||||
while (1)
|
while (1) {
|
||||||
{
|
|
||||||
f = *prevptr;
|
f = *prevptr;
|
||||||
if (!f)
|
if (!f)
|
||||||
break;
|
break;
|
||||||
|
@ -147,24 +144,20 @@ have inside faces.
|
||||||
=============================================================================
|
=============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void GatherNodeFaces_r (node_t *node)
|
void
|
||||||
|
GatherNodeFaces_r (node_t * node)
|
||||||
{
|
{
|
||||||
face_t *f, *next;
|
face_t *f, *next;
|
||||||
|
|
||||||
if (node->planenum != PLANENUM_LEAF)
|
if (node->planenum != PLANENUM_LEAF) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// decision node
|
// decision node
|
||||||
//
|
//
|
||||||
for (f=node->faces ; f ; f=next)
|
for (f = node->faces; f; f = next) {
|
||||||
{
|
|
||||||
next = f->next;
|
next = f->next;
|
||||||
if (!f->numpoints)
|
if (!f->numpoints) { // face was removed outside
|
||||||
{ // face was removed outside
|
|
||||||
FreeFace (f);
|
FreeFace (f);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
f->next = validfaces[f->planenum];
|
f->next = validfaces[f->planenum];
|
||||||
validfaces[f->planenum] = f;
|
validfaces[f->planenum] = f;
|
||||||
}
|
}
|
||||||
|
@ -174,9 +167,7 @@ void GatherNodeFaces_r (node_t *node)
|
||||||
GatherNodeFaces_r (node->children[1]);
|
GatherNodeFaces_r (node->children[1]);
|
||||||
|
|
||||||
free (node);
|
free (node);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// leaf node
|
// leaf node
|
||||||
//
|
//
|
||||||
|
@ -190,17 +181,17 @@ GatherNodeFaces
|
||||||
|
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
surface_t *GatherNodeFaces (node_t *headnode)
|
surface_t *
|
||||||
|
GatherNodeFaces (node_t * headnode)
|
||||||
{
|
{
|
||||||
memset (validfaces, 0, sizeof(validfaces));
|
memset (validfaces, 0, sizeof (validfaces));
|
||||||
GatherNodeFaces_r (headnode);
|
GatherNodeFaces_r (headnode);
|
||||||
return BuildSurfaces ();
|
return BuildSurfaces ();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
typedef struct hashvert_s
|
typedef struct hashvert_s {
|
||||||
{
|
|
||||||
struct hashvert_s *next;
|
struct hashvert_s *next;
|
||||||
vec3_t point;
|
vec3_t point;
|
||||||
int num;
|
int num;
|
||||||
|
@ -228,7 +219,8 @@ hashvert_t *hashverts[NUM_HASH];
|
||||||
|
|
||||||
static vec3_t hash_min, hash_scale;
|
static vec3_t hash_min, hash_scale;
|
||||||
|
|
||||||
static void InitHash (void)
|
static void
|
||||||
|
InitHash (void)
|
||||||
{
|
{
|
||||||
vec3_t size;
|
vec3_t size;
|
||||||
vec_t volume;
|
vec_t volume;
|
||||||
|
@ -236,17 +228,16 @@ static void InitHash (void)
|
||||||
int newsize[2];
|
int newsize[2];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
memset (hashverts, 0, sizeof(hashverts));
|
memset (hashverts, 0, sizeof (hashverts));
|
||||||
|
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
{
|
|
||||||
hash_min[i] = -8000;
|
hash_min[i] = -8000;
|
||||||
size[i] = 16000;
|
size[i] = 16000;
|
||||||
}
|
}
|
||||||
|
|
||||||
volume = size[0]*size[1];
|
volume = size[0] * size[1];
|
||||||
|
|
||||||
scale = sqrt(volume / NUM_HASH);
|
scale = sqrt (volume / NUM_HASH);
|
||||||
|
|
||||||
newsize[0] = size[0] / scale;
|
newsize[0] = size[0] / scale;
|
||||||
newsize[1] = size[1] / scale;
|
newsize[1] = size[1] / scale;
|
||||||
|
@ -258,13 +249,14 @@ static void InitHash (void)
|
||||||
hvert_p = hvertex;
|
hvert_p = hvertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned HashVec (vec3_t vec)
|
static unsigned
|
||||||
|
HashVec (vec3_t vec)
|
||||||
{
|
{
|
||||||
unsigned h;
|
unsigned h;
|
||||||
|
|
||||||
h = hash_scale[0] * (vec[0] - hash_min[0]) * hash_scale[2]
|
h = hash_scale[0] * (vec[0] - hash_min[0]) * hash_scale[2]
|
||||||
+ hash_scale[1] * (vec[1] - hash_min[1]);
|
+ hash_scale[1] * (vec[1] - hash_min[1]);
|
||||||
if ( h >= NUM_HASH)
|
if (h >= NUM_HASH)
|
||||||
return NUM_HASH - 1;
|
return NUM_HASH - 1;
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
@ -275,16 +267,16 @@ static unsigned HashVec (vec3_t vec)
|
||||||
GetVertex
|
GetVertex
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
int GetVertex (vec3_t in, int planenum)
|
int
|
||||||
|
GetVertex (vec3_t in, int planenum)
|
||||||
{
|
{
|
||||||
int h;
|
int h;
|
||||||
int i;
|
int i;
|
||||||
hashvert_t *hv;
|
hashvert_t *hv;
|
||||||
vec3_t vert;
|
vec3_t vert;
|
||||||
|
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
{
|
if (fabs (in[i] - (int) (in[i] + 0.5)) < 0.001)
|
||||||
if ( fabs(in[i] - (int) (in[i] + 0.5)) < 0.001)
|
|
||||||
vert[i] = (int) (in[i] + 0.5);
|
vert[i] = (int) (in[i] + 0.5);
|
||||||
else
|
else
|
||||||
vert[i] = in[i];
|
vert[i] = in[i];
|
||||||
|
@ -292,16 +284,14 @@ int GetVertex (vec3_t in, int planenum)
|
||||||
|
|
||||||
h = HashVec (vert);
|
h = HashVec (vert);
|
||||||
|
|
||||||
for (hv=hashverts[h] ; hv ; hv=hv->next)
|
for (hv = hashverts[h]; hv; hv = hv->next) {
|
||||||
{
|
if (fabs (hv->point[0] - vert[0]) < POINT_EPSILON
|
||||||
if ( fabs(hv->point[0]-vert[0])<POINT_EPSILON
|
&& fabs (hv->point[1] - vert[1]) < POINT_EPSILON
|
||||||
&& fabs(hv->point[1]-vert[1])<POINT_EPSILON
|
&& fabs (hv->point[2] - vert[2]) < POINT_EPSILON) {
|
||||||
&& fabs(hv->point[2]-vert[2])<POINT_EPSILON )
|
|
||||||
{
|
|
||||||
hv->numedges++;
|
hv->numedges++;
|
||||||
if (hv->numplanes == 3)
|
if (hv->numplanes == 3)
|
||||||
return hv->num; // allready known to be a corner
|
return hv->num; // allready known to be a corner
|
||||||
for (i=0 ; i<hv->numplanes ; i++)
|
for (i = 0; i < hv->numplanes; i++)
|
||||||
if (hv->planenums[i] == planenum)
|
if (hv->planenums[i] == planenum)
|
||||||
return hv->num; // allready know this plane
|
return hv->num; // allready know this plane
|
||||||
if (hv->numplanes == 2)
|
if (hv->numplanes == 2)
|
||||||
|
@ -321,7 +311,7 @@ int GetVertex (vec3_t in, int planenum)
|
||||||
hashverts[h] = hv;
|
hashverts[h] = hv;
|
||||||
VectorCopy (vert, hv->point);
|
VectorCopy (vert, hv->point);
|
||||||
hv->num = bsp->numvertexes;
|
hv->num = bsp->numvertexes;
|
||||||
if (hv->num==MAX_MAP_VERTS)
|
if (hv->num == MAX_MAP_VERTS)
|
||||||
Sys_Error ("GetVertex: MAX_MAP_VERTS");
|
Sys_Error ("GetVertex: MAX_MAP_VERTS");
|
||||||
hvert_p++;
|
hvert_p++;
|
||||||
|
|
||||||
|
@ -349,7 +339,8 @@ Don't allow four way edges
|
||||||
*/
|
*/
|
||||||
int c_tryedges;
|
int c_tryedges;
|
||||||
|
|
||||||
int GetEdge (vec3_t p1, vec3_t p2, face_t *f)
|
int
|
||||||
|
GetEdge (vec3_t p1, vec3_t p2, face_t * f)
|
||||||
{
|
{
|
||||||
int v1, v2;
|
int v1, v2;
|
||||||
dedge_t *edge;
|
dedge_t *edge;
|
||||||
|
@ -361,13 +352,11 @@ int GetEdge (vec3_t p1, vec3_t p2, face_t *f)
|
||||||
c_tryedges++;
|
c_tryedges++;
|
||||||
v1 = GetVertex (p1, f->planenum);
|
v1 = GetVertex (p1, f->planenum);
|
||||||
v2 = GetVertex (p2, f->planenum);
|
v2 = GetVertex (p2, f->planenum);
|
||||||
for (i=firstmodeledge ; i < bsp->numedges ; i++)
|
for (i = firstmodeledge; i < bsp->numedges; i++) {
|
||||||
{
|
|
||||||
edge = &bsp->edges[i];
|
edge = &bsp->edges[i];
|
||||||
if (v1 == edge->v[1] && v2 == edge->v[0]
|
if (v1 == edge->v[1] && v2 == edge->v[0]
|
||||||
&& !edgefaces[i][1]
|
&& !edgefaces[i][1]
|
||||||
&& edgefaces[i][0]->contents[0] == f->contents[0])
|
&& edgefaces[i][0]->contents[0] == f->contents[0]) {
|
||||||
{
|
|
||||||
edgefaces[i][1] = f;
|
edgefaces[i][1] = f;
|
||||||
return -i;
|
return -i;
|
||||||
}
|
}
|
||||||
|
@ -391,7 +380,8 @@ int GetEdge (vec3_t p1, vec3_t p2, face_t *f)
|
||||||
FindFaceEdges
|
FindFaceEdges
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void FindFaceEdges (face_t *face)
|
void
|
||||||
|
FindFaceEdges (face_t * face)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -399,9 +389,9 @@ void FindFaceEdges (face_t *face)
|
||||||
if (face->numpoints > MAXEDGES)
|
if (face->numpoints > MAXEDGES)
|
||||||
Sys_Error ("WriteFace: %i points", face->numpoints);
|
Sys_Error ("WriteFace: %i points", face->numpoints);
|
||||||
|
|
||||||
for (i=0; i<face->numpoints ; i++)
|
for (i = 0; i < face->numpoints; i++)
|
||||||
face->edges[i] = GetEdge
|
face->edges[i] = GetEdge
|
||||||
(face->pts[i], face->pts[(i+1)%face->numpoints], face);
|
(face->pts[i], face->pts[(i + 1) % face->numpoints], face);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -410,14 +400,14 @@ CheckVertexes
|
||||||
// debugging
|
// debugging
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
void CheckVertexes (void)
|
void
|
||||||
|
CheckVertexes (void)
|
||||||
{
|
{
|
||||||
int cb, c0, c1, c2, c3;
|
int cb, c0, c1, c2, c3;
|
||||||
hashvert_t *hv;
|
hashvert_t *hv;
|
||||||
|
|
||||||
cb = c0 = c1 = c2 = c3 = 0;
|
cb = c0 = c1 = c2 = c3 = 0;
|
||||||
for (hv=hvertex ; hv!=hvert_p ; hv++)
|
for (hv = hvertex; hv != hvert_p; hv++) {
|
||||||
{
|
|
||||||
if (hv->numedges < 0 || hv->numedges & 1)
|
if (hv->numedges < 0 || hv->numedges & 1)
|
||||||
cb++;
|
cb++;
|
||||||
else if (!hv->numedges)
|
else if (!hv->numedges)
|
||||||
|
@ -443,7 +433,8 @@ CheckEdges
|
||||||
// debugging
|
// debugging
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
void CheckEdges (void)
|
void
|
||||||
|
CheckEdges (void)
|
||||||
{
|
{
|
||||||
dedge_t *edge;
|
dedge_t *edge;
|
||||||
int i;
|
int i;
|
||||||
|
@ -456,17 +447,16 @@ void CheckEdges (void)
|
||||||
|
|
||||||
// CheckVertexes ();
|
// CheckVertexes ();
|
||||||
|
|
||||||
for (i=1 ; i < bsp->numedges ; i++)
|
for (i = 1; i < bsp->numedges; i++) {
|
||||||
{
|
|
||||||
edge = &bsp->edges[i];
|
edge = &bsp->edges[i];
|
||||||
if (!edgefaces[i][1])
|
if (!edgefaces[i][1]) {
|
||||||
{
|
|
||||||
d1 = &bsp->vertexes[edge->v[0]];
|
d1 = &bsp->vertexes[edge->v[0]];
|
||||||
d2 = &bsp->vertexes[edge->v[1]];
|
d2 = &bsp->vertexes[edge->v[1]];
|
||||||
qprintf ("unshared edge at: (%8.2f, %8.2f, %8.2f) (%8.2f, %8.2f, %8.2f)\n",d1->point[0], d1->point[1], d1->point[2], d2->point[0], d2->point[1], d2->point[2]);
|
qprintf
|
||||||
}
|
("unshared edge at: (%8.2f, %8.2f, %8.2f) (%8.2f, %8.2f, %8.2f)\n",
|
||||||
else
|
d1->point[0], d1->point[1], d1->point[2], d2->point[0],
|
||||||
{
|
d2->point[1], d2->point[2]);
|
||||||
|
} else {
|
||||||
f1 = edgefaces[i][0];
|
f1 = edgefaces[i][0];
|
||||||
f2 = edgefaces[i][1];
|
f2 = edgefaces[i][1];
|
||||||
if (f1->planeside != f2->planeside)
|
if (f1->planeside != f2->planeside)
|
||||||
|
@ -475,13 +465,11 @@ void CheckEdges (void)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// on the same plane, might be discardable
|
// on the same plane, might be discardable
|
||||||
if (f1->texturenum == f2->texturenum)
|
if (f1->texturenum == f2->texturenum) {
|
||||||
{
|
hvertex[edge->v[0]].numedges -= 2;
|
||||||
hvertex[edge->v[0]].numedges-=2;
|
hvertex[edge->v[1]].numedges -= 2;
|
||||||
hvertex[edge->v[1]].numedges-=2;
|
|
||||||
c_nonconvex++;
|
c_nonconvex++;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
c_multitexture++;
|
c_multitexture++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -499,14 +487,15 @@ void CheckEdges (void)
|
||||||
MakeFaceEdges_r
|
MakeFaceEdges_r
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void MakeFaceEdges_r (node_t *node)
|
void
|
||||||
|
MakeFaceEdges_r (node_t * node)
|
||||||
{
|
{
|
||||||
face_t *f;
|
face_t *f;
|
||||||
|
|
||||||
if (node->planenum == PLANENUM_LEAF)
|
if (node->planenum == PLANENUM_LEAF)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (f=node->faces ; f ; f=f->next)
|
for (f = node->faces; f; f = f->next)
|
||||||
FindFaceEdges (f);
|
FindFaceEdges (f);
|
||||||
|
|
||||||
MakeFaceEdges_r (node->children[0]);
|
MakeFaceEdges_r (node->children[0]);
|
||||||
|
@ -518,7 +507,8 @@ void MakeFaceEdges_r (node_t *node)
|
||||||
MakeFaceEdges
|
MakeFaceEdges
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void MakeFaceEdges (node_t *headnode)
|
void
|
||||||
|
MakeFaceEdges (node_t * headnode)
|
||||||
{
|
{
|
||||||
qprintf ("----- MakeFaceEdges -----\n");
|
qprintf ("----- MakeFaceEdges -----\n");
|
||||||
|
|
||||||
|
@ -535,4 +525,3 @@ void MakeFaceEdges (node_t *headnode)
|
||||||
firstmodeledge = bsp->numedges;
|
firstmodeledge = bsp->numedges;
|
||||||
firstmodelface = bsp->numfaces;
|
firstmodelface = bsp->numfaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,14 +28,12 @@
|
||||||
#include "bsp5.h"
|
#include "bsp5.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct wvert_s
|
typedef struct wvert_s {
|
||||||
{
|
|
||||||
vec_t t;
|
vec_t t;
|
||||||
struct wvert_s *prev, *next;
|
struct wvert_s *prev, *next;
|
||||||
} wvert_t;
|
} wvert_t;
|
||||||
|
|
||||||
typedef struct wedge_s
|
typedef struct wedge_s {
|
||||||
{
|
|
||||||
struct wedge_s *next;
|
struct wedge_s *next;
|
||||||
vec3_t dir;
|
vec3_t dir;
|
||||||
vec3_t origin;
|
vec3_t origin;
|
||||||
|
@ -54,12 +52,14 @@ wvert_t wverts[MAXWVERTS];
|
||||||
wedge_t wedges[MAXWEDGES];
|
wedge_t wedges[MAXWEDGES];
|
||||||
|
|
||||||
|
|
||||||
void PrintFace (face_t *f)
|
void
|
||||||
|
PrintFace (face_t * f)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0 ; i<f->numpoints ; i++)
|
for (i = 0; i < f->numpoints; i++)
|
||||||
printf ("(%5.2f, %5.2f, %5.2f)\n", f->pts[i][0], f->pts[i][1], f->pts[i][2]);
|
printf ("(%5.2f, %5.2f, %5.2f)\n", f->pts[i][0], f->pts[i][1],
|
||||||
|
f->pts[i][2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
@ -70,7 +70,8 @@ wedge_t *wedge_hash[NUM_HASH];
|
||||||
|
|
||||||
static vec3_t hash_min, hash_scale;
|
static vec3_t hash_min, hash_scale;
|
||||||
|
|
||||||
static void InitHash (vec3_t mins, vec3_t maxs)
|
static void
|
||||||
|
InitHash (vec3_t mins, vec3_t maxs)
|
||||||
{
|
{
|
||||||
vec3_t size;
|
vec3_t size;
|
||||||
vec_t volume;
|
vec_t volume;
|
||||||
|
@ -79,11 +80,11 @@ static void InitHash (vec3_t mins, vec3_t maxs)
|
||||||
|
|
||||||
VectorCopy (mins, hash_min);
|
VectorCopy (mins, hash_min);
|
||||||
VectorSubtract (maxs, mins, size);
|
VectorSubtract (maxs, mins, size);
|
||||||
memset (wedge_hash, 0, sizeof(wedge_hash));
|
memset (wedge_hash, 0, sizeof (wedge_hash));
|
||||||
|
|
||||||
volume = size[0]*size[1];
|
volume = size[0] * size[1];
|
||||||
|
|
||||||
scale = sqrt(volume / NUM_HASH);
|
scale = sqrt (volume / NUM_HASH);
|
||||||
|
|
||||||
newsize[0] = size[0] / scale;
|
newsize[0] = size[0] / scale;
|
||||||
newsize[1] = size[1] / scale;
|
newsize[1] = size[1] / scale;
|
||||||
|
@ -93,55 +94,52 @@ static void InitHash (vec3_t mins, vec3_t maxs)
|
||||||
hash_scale[2] = newsize[1];
|
hash_scale[2] = newsize[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned HashVec (vec3_t vec)
|
static unsigned
|
||||||
|
HashVec (vec3_t vec)
|
||||||
{
|
{
|
||||||
unsigned h;
|
unsigned h;
|
||||||
|
|
||||||
h = hash_scale[0] * (vec[0] - hash_min[0]) * hash_scale[2]
|
h = hash_scale[0] * (vec[0] - hash_min[0]) * hash_scale[2]
|
||||||
+ hash_scale[1] * (vec[1] - hash_min[1]);
|
+ hash_scale[1] * (vec[1] - hash_min[1]);
|
||||||
if ( h >= NUM_HASH)
|
if (h >= NUM_HASH)
|
||||||
return NUM_HASH - 1;
|
return NUM_HASH - 1;
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
void CanonicalVector (vec3_t vec)
|
void
|
||||||
|
CanonicalVector (vec3_t vec)
|
||||||
{
|
{
|
||||||
VectorNormalize (vec);
|
VectorNormalize (vec);
|
||||||
if (vec[0] > EQUAL_EPSILON)
|
if (vec[0] > EQUAL_EPSILON)
|
||||||
return;
|
return;
|
||||||
else if (vec[0] < -EQUAL_EPSILON)
|
else if (vec[0] < -EQUAL_EPSILON) {
|
||||||
{
|
|
||||||
VectorSubtract (vec3_origin, vec, vec);
|
VectorSubtract (vec3_origin, vec, vec);
|
||||||
return;
|
return;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
vec[0] = 0;
|
vec[0] = 0;
|
||||||
|
|
||||||
if (vec[1] > EQUAL_EPSILON)
|
if (vec[1] > EQUAL_EPSILON)
|
||||||
return;
|
return;
|
||||||
else if (vec[1] < -EQUAL_EPSILON)
|
else if (vec[1] < -EQUAL_EPSILON) {
|
||||||
{
|
|
||||||
VectorSubtract (vec3_origin, vec, vec);
|
VectorSubtract (vec3_origin, vec, vec);
|
||||||
return;
|
return;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
vec[1] = 0;
|
vec[1] = 0;
|
||||||
|
|
||||||
if (vec[2] > EQUAL_EPSILON)
|
if (vec[2] > EQUAL_EPSILON)
|
||||||
return;
|
return;
|
||||||
else if (vec[2] < -EQUAL_EPSILON)
|
else if (vec[2] < -EQUAL_EPSILON) {
|
||||||
{
|
|
||||||
VectorSubtract (vec3_origin, vec, vec);
|
VectorSubtract (vec3_origin, vec, vec);
|
||||||
return;
|
return;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
vec[2] = 0;
|
vec[2] = 0;
|
||||||
Sys_Error ("CanonicalVector: degenerate");
|
Sys_Error ("CanonicalVector: degenerate");
|
||||||
}
|
}
|
||||||
|
|
||||||
wedge_t *FindEdge (vec3_t p1, vec3_t p2, vec_t *t1, vec_t *t2)
|
wedge_t *
|
||||||
|
FindEdge (vec3_t p1, vec3_t p2, vec_t *t1, vec_t *t2)
|
||||||
{
|
{
|
||||||
vec3_t origin;
|
vec3_t origin;
|
||||||
vec3_t dir;
|
vec3_t dir;
|
||||||
|
@ -157,8 +155,7 @@ wedge_t *FindEdge (vec3_t p1, vec3_t p2, vec_t *t1, vec_t *t2)
|
||||||
|
|
||||||
VectorMA (p1, -*t1, dir, origin);
|
VectorMA (p1, -*t1, dir, origin);
|
||||||
|
|
||||||
if (*t1 > *t2)
|
if (*t1 > *t2) {
|
||||||
{
|
|
||||||
temp = *t1;
|
temp = *t1;
|
||||||
*t1 = *t2;
|
*t1 = *t2;
|
||||||
*t2 = temp;
|
*t2 = temp;
|
||||||
|
@ -166,8 +163,7 @@ wedge_t *FindEdge (vec3_t p1, vec3_t p2, vec_t *t1, vec_t *t2)
|
||||||
|
|
||||||
h = HashVec (origin);
|
h = HashVec (origin);
|
||||||
|
|
||||||
for (w = wedge_hash[h] ; w ; w=w->next)
|
for (w = wedge_hash[h]; w; w = w->next) {
|
||||||
{
|
|
||||||
temp = w->origin[0] - origin[0];
|
temp = w->origin[0] - origin[0];
|
||||||
if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
|
if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
|
||||||
continue;
|
continue;
|
||||||
|
@ -215,14 +211,14 @@ AddVert
|
||||||
*/
|
*/
|
||||||
#define T_EPSILON 0.01
|
#define T_EPSILON 0.01
|
||||||
|
|
||||||
void AddVert (wedge_t *w, vec_t t)
|
void
|
||||||
|
AddVert (wedge_t * w, vec_t t)
|
||||||
{
|
{
|
||||||
wvert_t *v, *newv;
|
wvert_t *v, *newv;
|
||||||
|
|
||||||
v = w->head.next;
|
v = w->head.next;
|
||||||
do
|
do {
|
||||||
{
|
if (fabs (v->t - t) < T_EPSILON)
|
||||||
if (fabs(v->t - t) < T_EPSILON)
|
|
||||||
return;
|
return;
|
||||||
if (v->t > t)
|
if (v->t > t)
|
||||||
break;
|
break;
|
||||||
|
@ -250,12 +246,13 @@ AddEdge
|
||||||
|
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
void AddEdge (vec3_t p1, vec3_t p2)
|
void
|
||||||
|
AddEdge (vec3_t p1, vec3_t p2)
|
||||||
{
|
{
|
||||||
wedge_t *w;
|
wedge_t *w;
|
||||||
vec_t t1, t2;
|
vec_t t1, t2;
|
||||||
|
|
||||||
w = FindEdge(p1, p2, &t1, &t2);
|
w = FindEdge (p1, p2, &t1, &t2);
|
||||||
AddVert (w, t1);
|
AddVert (w, t1);
|
||||||
AddVert (w, t2);
|
AddVert (w, t2);
|
||||||
}
|
}
|
||||||
|
@ -266,13 +263,13 @@ AddFaceEdges
|
||||||
|
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
void AddFaceEdges (face_t *f)
|
void
|
||||||
|
AddFaceEdges (face_t * f)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
for (i=0 ; i < f->numpoints ; i++)
|
for (i = 0; i < f->numpoints; i++) {
|
||||||
{
|
j = (i + 1) % f->numpoints;
|
||||||
j = (i+1)%f->numpoints;
|
|
||||||
AddEdge (f->pts[i], f->pts[j]);
|
AddEdge (f->pts[i], f->pts[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,13 +279,14 @@ void AddFaceEdges (face_t *f)
|
||||||
|
|
||||||
// a specially allocated face that can hold hundreds of edges if needed
|
// a specially allocated face that can hold hundreds of edges if needed
|
||||||
byte superfacebuf[8192];
|
byte superfacebuf[8192];
|
||||||
face_t *superface = (face_t *)superfacebuf;
|
face_t *superface = (face_t *) superfacebuf;
|
||||||
|
|
||||||
void FixFaceEdges (face_t *f);
|
void FixFaceEdges (face_t * f);
|
||||||
|
|
||||||
face_t *newlist;
|
face_t *newlist;
|
||||||
|
|
||||||
void SplitFaceForTjunc (face_t *f, face_t *original)
|
void
|
||||||
|
SplitFaceForTjunc (face_t * f, face_t * original)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
face_t *new, *chain;
|
face_t *new, *chain;
|
||||||
|
@ -297,10 +295,9 @@ void SplitFaceForTjunc (face_t *f, face_t *original)
|
||||||
int firstcorner, lastcorner;
|
int firstcorner, lastcorner;
|
||||||
|
|
||||||
chain = NULL;
|
chain = NULL;
|
||||||
do
|
do {
|
||||||
{
|
if (f->numpoints <= MAXPOINTS) { // the face is now small enough
|
||||||
if (f->numpoints <= MAXPOINTS)
|
// without more cutting
|
||||||
{ // the face is now small enough without more cutting
|
|
||||||
// so copy it back to the original
|
// so copy it back to the original
|
||||||
*original = *f;
|
*original = *f;
|
||||||
original->original = chain;
|
original->original = chain;
|
||||||
|
@ -311,17 +308,15 @@ void SplitFaceForTjunc (face_t *f, face_t *original)
|
||||||
|
|
||||||
tjuncfaces++;
|
tjuncfaces++;
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
// find the last corner
|
// find the last corner
|
||||||
VectorSubtract (f->pts[f->numpoints-1], f->pts[0], dir);
|
VectorSubtract (f->pts[f->numpoints - 1], f->pts[0], dir);
|
||||||
VectorNormalize (dir);
|
VectorNormalize (dir);
|
||||||
for (lastcorner=f->numpoints-1 ; lastcorner > 0 ; lastcorner--)
|
for (lastcorner = f->numpoints - 1; lastcorner > 0; lastcorner--) {
|
||||||
{
|
VectorSubtract (f->pts[lastcorner - 1], f->pts[lastcorner], test);
|
||||||
VectorSubtract (f->pts[lastcorner-1], f->pts[lastcorner], test);
|
|
||||||
VectorNormalize (test);
|
VectorNormalize (test);
|
||||||
v = DotProduct (test, dir);
|
v = DotProduct (test, dir);
|
||||||
if (v < 0.9999 || v > 1.00001)
|
if (v < 0.9999 || v > 1.00001) {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,30 +324,25 @@ restart:
|
||||||
// find the first corner
|
// find the first corner
|
||||||
VectorSubtract (f->pts[1], f->pts[0], dir);
|
VectorSubtract (f->pts[1], f->pts[0], dir);
|
||||||
VectorNormalize (dir);
|
VectorNormalize (dir);
|
||||||
for (firstcorner=1 ; firstcorner < f->numpoints-1 ; firstcorner++)
|
for (firstcorner = 1; firstcorner < f->numpoints - 1; firstcorner++) {
|
||||||
{
|
VectorSubtract (f->pts[firstcorner + 1], f->pts[firstcorner], test);
|
||||||
VectorSubtract (f->pts[firstcorner+1], f->pts[firstcorner], test);
|
|
||||||
VectorNormalize (test);
|
VectorNormalize (test);
|
||||||
v = DotProduct (test, dir);
|
v = DotProduct (test, dir);
|
||||||
if (v < 0.9999 || v > 1.00001)
|
if (v < 0.9999 || v > 1.00001) {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstcorner+2 >= MAXPOINTS)
|
if (firstcorner + 2 >= MAXPOINTS) {
|
||||||
{
|
|
||||||
// rotate the point winding
|
// rotate the point winding
|
||||||
VectorCopy (f->pts[0], test);
|
VectorCopy (f->pts[0], test);
|
||||||
for (i=1 ; i<f->numpoints ; i++)
|
for (i = 1; i < f->numpoints; i++) {
|
||||||
{
|
VectorCopy (f->pts[i], f->pts[i - 1]);
|
||||||
VectorCopy (f->pts[i], f->pts[i-1]);
|
|
||||||
}
|
}
|
||||||
VectorCopy (test, f->pts[f->numpoints-1]);
|
VectorCopy (test, f->pts[f->numpoints - 1]);
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// cut off as big a piece as possible, less than MAXPOINTS, and not
|
// cut off as big a piece as possible, less than MAXPOINTS, and not
|
||||||
// past lastcorner
|
// past lastcorner
|
||||||
|
|
||||||
|
@ -365,24 +355,22 @@ restart:
|
||||||
new->next = newlist;
|
new->next = newlist;
|
||||||
newlist = new;
|
newlist = new;
|
||||||
if (f->numpoints - firstcorner <= MAXPOINTS)
|
if (f->numpoints - firstcorner <= MAXPOINTS)
|
||||||
new->numpoints = firstcorner+2;
|
new->numpoints = firstcorner + 2;
|
||||||
else if (lastcorner+2 < MAXPOINTS &&
|
else if (lastcorner + 2 < MAXPOINTS &&
|
||||||
f->numpoints - lastcorner <= MAXPOINTS)
|
f->numpoints - lastcorner <= MAXPOINTS)
|
||||||
new->numpoints = lastcorner+2;
|
new->numpoints = lastcorner + 2;
|
||||||
else
|
else
|
||||||
new->numpoints = MAXPOINTS;
|
new->numpoints = MAXPOINTS;
|
||||||
|
|
||||||
for (i=0 ; i<new->numpoints ; i++)
|
for (i = 0; i < new->numpoints; i++) {
|
||||||
{
|
|
||||||
VectorCopy (f->pts[i], new->pts[i]);
|
VectorCopy (f->pts[i], new->pts[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (i=new->numpoints-1 ; i<f->numpoints ; i++)
|
for (i = new->numpoints - 1; i < f->numpoints; i++) {
|
||||||
{
|
VectorCopy (f->pts[i], f->pts[i - (new->numpoints - 2)]);
|
||||||
VectorCopy (f->pts[i], f->pts[i-(new->numpoints-2)]);
|
|
||||||
}
|
}
|
||||||
f->numpoints -= (new->numpoints-2);
|
f->numpoints -= (new->numpoints - 2);
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -394,7 +382,8 @@ FixFaceEdges
|
||||||
|
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
void FixFaceEdges (face_t *f)
|
void
|
||||||
|
FixFaceEdges (face_t * f)
|
||||||
{
|
{
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
wedge_t *w;
|
wedge_t *w;
|
||||||
|
@ -403,24 +392,20 @@ void FixFaceEdges (face_t *f)
|
||||||
|
|
||||||
*superface = *f;
|
*superface = *f;
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
for (i=0 ; i < superface->numpoints ; i++)
|
for (i = 0; i < superface->numpoints; i++) {
|
||||||
{
|
j = (i + 1) % superface->numpoints;
|
||||||
j = (i+1)%superface->numpoints;
|
|
||||||
|
|
||||||
w = FindEdge (superface->pts[i], superface->pts[j], &t1, &t2);
|
w = FindEdge (superface->pts[i], superface->pts[j], &t1, &t2);
|
||||||
|
|
||||||
for (v=w->head.next ; v->t < t1 + T_EPSILON ; v = v->next)
|
for (v = w->head.next; v->t < t1 + T_EPSILON; v = v->next) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v->t < t2-T_EPSILON)
|
if (v->t < t2 - T_EPSILON) {
|
||||||
{
|
|
||||||
tjuncs++;
|
tjuncs++;
|
||||||
// insert a new vertex here
|
// insert a new vertex here
|
||||||
for (k = superface->numpoints ; k> j ; k--)
|
for (k = superface->numpoints; k > j; k--) {
|
||||||
{
|
VectorCopy (superface->pts[k - 1], superface->pts[k]);
|
||||||
VectorCopy (superface->pts[k-1], superface->pts[k]);
|
|
||||||
}
|
}
|
||||||
VectorMA (w->origin, v->t, w->dir, superface->pts[j]);
|
VectorMA (w->origin, v->t, w->dir, superface->pts[j]);
|
||||||
superface->numpoints++;
|
superface->numpoints++;
|
||||||
|
@ -429,14 +414,12 @@ restart:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (superface->numpoints <= MAXPOINTS)
|
if (superface->numpoints <= MAXPOINTS) {
|
||||||
{
|
|
||||||
*f = *superface;
|
*f = *superface;
|
||||||
f->next = newlist;
|
f->next = newlist;
|
||||||
newlist = f;
|
newlist = f;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the face needs to be split into multiple faces because of too many edges
|
// the face needs to be split into multiple faces because of too many edges
|
||||||
|
|
||||||
SplitFaceForTjunc (superface, f);
|
SplitFaceForTjunc (superface, f);
|
||||||
|
@ -446,21 +429,23 @@ restart:
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
void tjunc_find_r (node_t *node)
|
void
|
||||||
|
tjunc_find_r (node_t * node)
|
||||||
{
|
{
|
||||||
face_t *f;
|
face_t *f;
|
||||||
|
|
||||||
if (node->planenum == PLANENUM_LEAF)
|
if (node->planenum == PLANENUM_LEAF)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (f=node->faces ; f ; f=f->next)
|
for (f = node->faces; f; f = f->next)
|
||||||
AddFaceEdges (f);
|
AddFaceEdges (f);
|
||||||
|
|
||||||
tjunc_find_r (node->children[0]);
|
tjunc_find_r (node->children[0]);
|
||||||
tjunc_find_r (node->children[1]);
|
tjunc_find_r (node->children[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tjunc_fix_r (node_t *node)
|
void
|
||||||
|
tjunc_fix_r (node_t * node)
|
||||||
{
|
{
|
||||||
face_t *f, *next;
|
face_t *f, *next;
|
||||||
|
|
||||||
|
@ -469,8 +454,7 @@ void tjunc_fix_r (node_t *node)
|
||||||
|
|
||||||
newlist = NULL;
|
newlist = NULL;
|
||||||
|
|
||||||
for (f=node->faces ; f ; f=next)
|
for (f = node->faces; f; f = next) {
|
||||||
{
|
|
||||||
next = f->next;
|
next = f->next;
|
||||||
FixFaceEdges (f);
|
FixFaceEdges (f);
|
||||||
}
|
}
|
||||||
|
@ -487,7 +471,8 @@ tjunc
|
||||||
|
|
||||||
===========
|
===========
|
||||||
*/
|
*/
|
||||||
void tjunc (node_t *headnode)
|
void
|
||||||
|
tjunc (node_t * headnode)
|
||||||
{
|
{
|
||||||
vec3_t maxs, mins;
|
vec3_t maxs, mins;
|
||||||
int i;
|
int i;
|
||||||
|
@ -502,12 +487,11 @@ void tjunc (node_t *headnode)
|
||||||
//
|
//
|
||||||
|
|
||||||
// origin points won't allways be inside the map, so extend the hash area
|
// origin points won't allways be inside the map, so extend the hash area
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
{
|
if (fabs (brushset->maxs[i]) > fabs (brushset->mins[i]))
|
||||||
if ( fabs(brushset->maxs[i]) > fabs(brushset->mins[i]) )
|
maxs[i] = fabs (brushset->maxs[i]);
|
||||||
maxs[i] = fabs(brushset->maxs[i]);
|
|
||||||
else
|
else
|
||||||
maxs[i] = fabs(brushset->mins[i]);
|
maxs[i] = fabs (brushset->mins[i]);
|
||||||
}
|
}
|
||||||
VectorSubtract (vec3_origin, maxs, mins);
|
VectorSubtract (vec3_origin, maxs, mins);
|
||||||
|
|
||||||
|
|
|
@ -47,13 +47,13 @@ FindFinalPlane
|
||||||
Used to find plane index numbers for clip nodes read from child processes
|
Used to find plane index numbers for clip nodes read from child processes
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
int FindFinalPlane (dplane_t *p)
|
int
|
||||||
|
FindFinalPlane (dplane_t *p)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
dplane_t *dplane;
|
dplane_t *dplane;
|
||||||
|
|
||||||
for (i=0, dplane = bsp->planes ; i<bsp->numplanes ; i++, dplane++)
|
for (i = 0, dplane = bsp->planes; i < bsp->numplanes; i++, dplane++) {
|
||||||
{
|
|
||||||
if (p->type != dplane->type)
|
if (p->type != dplane->type)
|
||||||
continue;
|
continue;
|
||||||
if (p->dist != dplane->dist)
|
if (p->dist != dplane->dist)
|
||||||
|
@ -83,15 +83,15 @@ int FindFinalPlane (dplane_t *p)
|
||||||
|
|
||||||
int planemapping[MAX_MAP_PLANES];
|
int planemapping[MAX_MAP_PLANES];
|
||||||
|
|
||||||
void WriteNodePlanes_r (node_t *node)
|
void
|
||||||
|
WriteNodePlanes_r (node_t * node)
|
||||||
{
|
{
|
||||||
plane_t *plane;
|
plane_t *plane;
|
||||||
dplane_t *dplane;
|
dplane_t *dplane;
|
||||||
|
|
||||||
if (node->planenum == -1)
|
if (node->planenum == -1)
|
||||||
return;
|
return;
|
||||||
if (planemapping[node->planenum] == -1)
|
if (planemapping[node->planenum] == -1) { // a new plane
|
||||||
{ // a new plane
|
|
||||||
planemapping[node->planenum] = bsp->numplanes;
|
planemapping[node->planenum] = bsp->numplanes;
|
||||||
|
|
||||||
if (bsp->numplanes == MAX_MAP_PLANES)
|
if (bsp->numplanes == MAX_MAP_PLANES)
|
||||||
|
@ -119,9 +119,10 @@ WriteNodePlanes
|
||||||
|
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void WriteNodePlanes (node_t *nodes)
|
void
|
||||||
|
WriteNodePlanes (node_t * nodes)
|
||||||
{
|
{
|
||||||
memset (planemapping,-1, sizeof(planemapping));
|
memset (planemapping, -1, sizeof (planemapping));
|
||||||
WriteNodePlanes_r (nodes);
|
WriteNodePlanes_r (nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,27 +134,26 @@ WriteClipNodes_r
|
||||||
|
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
int WriteClipNodes_r (node_t *node)
|
int
|
||||||
|
WriteClipNodes_r (node_t * node)
|
||||||
{
|
{
|
||||||
int i, c;
|
int i, c;
|
||||||
dclipnode_t *cn;
|
dclipnode_t *cn;
|
||||||
int num;
|
int num;
|
||||||
|
|
||||||
// FIXME: free more stuff?
|
// FIXME: free more stuff?
|
||||||
if (node->planenum == -1)
|
if (node->planenum == -1) {
|
||||||
{
|
|
||||||
num = node->contents;
|
num = node->contents;
|
||||||
free (node);
|
free (node);
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit a clipnode
|
// emit a clipnode
|
||||||
c = bsp->numclipnodes;
|
c = bsp->numclipnodes;
|
||||||
cn = &bsp->clipnodes[bsp->numclipnodes];
|
cn = &bsp->clipnodes[bsp->numclipnodes];
|
||||||
bsp->numclipnodes++;
|
bsp->numclipnodes++;
|
||||||
cn->planenum = node->outputplanenum;
|
cn->planenum = node->outputplanenum;
|
||||||
for (i=0 ; i<2 ; i++)
|
for (i = 0; i < 2; i++)
|
||||||
cn->children[i] = WriteClipNodes_r(node->children[i]);
|
cn->children[i] = WriteClipNodes_r (node->children[i]);
|
||||||
|
|
||||||
free (node);
|
free (node);
|
||||||
return c;
|
return c;
|
||||||
|
@ -167,7 +167,8 @@ Called after the clipping hull is completed. Generates a disk format
|
||||||
representation and frees the original memory.
|
representation and frees the original memory.
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void WriteClipNodes (node_t *nodes)
|
void
|
||||||
|
WriteClipNodes (node_t * nodes)
|
||||||
{
|
{
|
||||||
headclipnode = bsp->numclipnodes;
|
headclipnode = bsp->numclipnodes;
|
||||||
WriteClipNodes_r (nodes);
|
WriteClipNodes_r (nodes);
|
||||||
|
@ -180,7 +181,8 @@ void WriteClipNodes (node_t *nodes)
|
||||||
WriteLeaf
|
WriteLeaf
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void WriteLeaf (node_t *node)
|
void
|
||||||
|
WriteLeaf (node_t * node)
|
||||||
{
|
{
|
||||||
face_t **fp, *f;
|
face_t **fp, *f;
|
||||||
dleaf_t *leaf_p;
|
dleaf_t *leaf_p;
|
||||||
|
@ -204,17 +206,15 @@ void WriteLeaf (node_t *node)
|
||||||
//
|
//
|
||||||
leaf_p->firstmarksurface = bsp->nummarksurfaces;
|
leaf_p->firstmarksurface = bsp->nummarksurfaces;
|
||||||
|
|
||||||
for (fp=node->markfaces ; *fp ; fp++)
|
for (fp = node->markfaces; *fp; fp++) {
|
||||||
{
|
|
||||||
// emit a marksurface
|
// emit a marksurface
|
||||||
if (bsp->nummarksurfaces == MAX_MAP_MARKSURFACES)
|
if (bsp->nummarksurfaces == MAX_MAP_MARKSURFACES)
|
||||||
Sys_Error ("nummarksurfaces == MAX_MAP_MARKSURFACES");
|
Sys_Error ("nummarksurfaces == MAX_MAP_MARKSURFACES");
|
||||||
f = *fp;
|
f = *fp;
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
bsp->marksurfaces[bsp->nummarksurfaces] = f->outputnumber;
|
bsp->marksurfaces[bsp->nummarksurfaces] = f->outputnumber;
|
||||||
bsp->nummarksurfaces++;
|
bsp->nummarksurfaces++;
|
||||||
f=f->original; // grab tjunction split faces
|
f = f->original; // grab tjunction split faces
|
||||||
} while (f);
|
} while (f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +227,8 @@ void WriteLeaf (node_t *node)
|
||||||
WriteDrawNodes_r
|
WriteDrawNodes_r
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void WriteDrawNodes_r (node_t *node)
|
void
|
||||||
|
WriteDrawNodes_r (node_t * node)
|
||||||
{
|
{
|
||||||
dnode_t *n;
|
dnode_t *n;
|
||||||
int i;
|
int i;
|
||||||
|
@ -249,20 +250,15 @@ void WriteDrawNodes_r (node_t *node)
|
||||||
// recursively output the other nodes
|
// recursively output the other nodes
|
||||||
//
|
//
|
||||||
|
|
||||||
for (i=0 ; i<2 ; i++)
|
for (i = 0; i < 2; i++) {
|
||||||
{
|
if (node->children[i]->planenum == -1) {
|
||||||
if (node->children[i]->planenum == -1)
|
|
||||||
{
|
|
||||||
if (node->children[i]->contents == CONTENTS_SOLID)
|
if (node->children[i]->contents == CONTENTS_SOLID)
|
||||||
n->children[i] = -1;
|
n->children[i] = -1;
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
n->children[i] = -(bsp->numleafs + 1);
|
n->children[i] = -(bsp->numleafs + 1);
|
||||||
WriteLeaf (node->children[i]);
|
WriteLeaf (node->children[i]);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
n->children[i] = bsp->numnodes;
|
n->children[i] = bsp->numnodes;
|
||||||
WriteDrawNodes_r (node->children[i]);
|
WriteDrawNodes_r (node->children[i]);
|
||||||
}
|
}
|
||||||
|
@ -274,7 +270,8 @@ void WriteDrawNodes_r (node_t *node)
|
||||||
WriteDrawNodes
|
WriteDrawNodes
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void WriteDrawNodes (node_t *headnode)
|
void
|
||||||
|
WriteDrawNodes (node_t * headnode)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int start;
|
int start;
|
||||||
|
@ -304,9 +301,9 @@ void WriteDrawNodes (node_t *headnode)
|
||||||
WriteDrawNodes_r (headnode);
|
WriteDrawNodes_r (headnode);
|
||||||
bm->visleafs = bsp->numleafs - start;
|
bm->visleafs = bsp->numleafs - start;
|
||||||
|
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
{
|
bm->mins[i] = headnode->mins[i] + SIDESPACE + 1; // remove the
|
||||||
bm->mins[i] = headnode->mins[i] + SIDESPACE + 1; // remove the padding
|
// padding
|
||||||
bm->maxs[i] = headnode->maxs[i] - SIDESPACE - 1;
|
bm->maxs[i] = headnode->maxs[i] - SIDESPACE - 1;
|
||||||
}
|
}
|
||||||
// FIXME: are all the children decendant of padded nodes?
|
// FIXME: are all the children decendant of padded nodes?
|
||||||
|
@ -320,7 +317,8 @@ BumpModel
|
||||||
Used by the clipping hull processes that only need to store headclipnode
|
Used by the clipping hull processes that only need to store headclipnode
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void BumpModel (int hullnum)
|
void
|
||||||
|
BumpModel (int hullnum)
|
||||||
{
|
{
|
||||||
dmodel_t *bm;
|
dmodel_t *bm;
|
||||||
|
|
||||||
|
@ -335,16 +333,14 @@ void BumpModel (int hullnum)
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
char identification[4]; // should be WAD2
|
char identification[4]; // should be WAD2
|
||||||
int numlumps;
|
int numlumps;
|
||||||
int infotableofs;
|
int infotableofs;
|
||||||
} wadinfo_t;
|
} wadinfo_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
int filepos;
|
int filepos;
|
||||||
int disksize;
|
int disksize;
|
||||||
int size; // uncompressed
|
int size; // uncompressed
|
||||||
|
@ -358,19 +354,19 @@ QFile *texfile;
|
||||||
wadinfo_t wadinfo;
|
wadinfo_t wadinfo;
|
||||||
lumpinfo_t *lumpinfo;
|
lumpinfo_t *lumpinfo;
|
||||||
|
|
||||||
void CleanupName (char *in, char *out)
|
void
|
||||||
|
CleanupName (char *in, char *out)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0 ; i< 16 ; i++ )
|
for (i = 0; i < 16; i++) {
|
||||||
{
|
|
||||||
if (!in[i])
|
if (!in[i])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
out[i] = toupper(in[i]);
|
out[i] = toupper (in[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( ; i< 16 ; i++ )
|
for (; i < 16; i++)
|
||||||
out[i] = 0;
|
out[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,25 +376,25 @@ void CleanupName (char *in, char *out)
|
||||||
TEX_InitFromWad
|
TEX_InitFromWad
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void TEX_InitFromWad (char *path)
|
void
|
||||||
|
TEX_InitFromWad (char *path)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
texfile = Qopen (path, "rb");
|
texfile = Qopen (path, "rb");
|
||||||
Qread (texfile, &wadinfo, sizeof(wadinfo));
|
Qread (texfile, &wadinfo, sizeof (wadinfo));
|
||||||
if (strncmp (wadinfo.identification, "WAD2", 4))
|
if (strncmp (wadinfo.identification, "WAD2", 4))
|
||||||
Sys_Error ("TEX_InitFromWad: %s isn't a wadfile",path);
|
Sys_Error ("TEX_InitFromWad: %s isn't a wadfile", path);
|
||||||
wadinfo.numlumps = LittleLong(wadinfo.numlumps);
|
wadinfo.numlumps = LittleLong (wadinfo.numlumps);
|
||||||
wadinfo.infotableofs = LittleLong(wadinfo.infotableofs);
|
wadinfo.infotableofs = LittleLong (wadinfo.infotableofs);
|
||||||
Qseek (texfile, wadinfo.infotableofs, SEEK_SET);
|
Qseek (texfile, wadinfo.infotableofs, SEEK_SET);
|
||||||
lumpinfo = malloc(wadinfo.numlumps*sizeof(lumpinfo_t));
|
lumpinfo = malloc (wadinfo.numlumps * sizeof (lumpinfo_t));
|
||||||
Qread (texfile, lumpinfo, wadinfo.numlumps*sizeof(lumpinfo_t));
|
Qread (texfile, lumpinfo, wadinfo.numlumps * sizeof (lumpinfo_t));
|
||||||
|
|
||||||
for (i=0 ; i<wadinfo.numlumps ; i++)
|
for (i = 0; i < wadinfo.numlumps; i++) {
|
||||||
{
|
|
||||||
CleanupName (lumpinfo[i].name, lumpinfo[i].name);
|
CleanupName (lumpinfo[i].name, lumpinfo[i].name);
|
||||||
lumpinfo[i].filepos = LittleLong(lumpinfo[i].filepos);
|
lumpinfo[i].filepos = LittleLong (lumpinfo[i].filepos);
|
||||||
lumpinfo[i].disksize = LittleLong(lumpinfo[i].disksize);
|
lumpinfo[i].disksize = LittleLong (lumpinfo[i].disksize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,17 +403,16 @@ void TEX_InitFromWad (char *path)
|
||||||
LoadLump
|
LoadLump
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
int LoadLump (char *name, byte *dest)
|
int
|
||||||
|
LoadLump (char *name, byte * dest)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char cname[16];
|
char cname[16];
|
||||||
|
|
||||||
CleanupName (name, cname);
|
CleanupName (name, cname);
|
||||||
|
|
||||||
for (i=0 ; i<wadinfo.numlumps ; i++)
|
for (i = 0; i < wadinfo.numlumps; i++) {
|
||||||
{
|
if (!strcmp (cname, lumpinfo[i].name)) {
|
||||||
if (!strcmp(cname, lumpinfo[i].name))
|
|
||||||
{
|
|
||||||
Qseek (texfile, lumpinfo[i].filepos, SEEK_SET);
|
Qseek (texfile, lumpinfo[i].filepos, SEEK_SET);
|
||||||
Qread (texfile, dest, lumpinfo[i].disksize);
|
Qread (texfile, dest, lumpinfo[i].disksize);
|
||||||
return lumpinfo[i].disksize;
|
return lumpinfo[i].disksize;
|
||||||
|
@ -434,7 +429,8 @@ int LoadLump (char *name, byte *dest)
|
||||||
AddAnimatingTextures
|
AddAnimatingTextures
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void AddAnimatingTextures (void)
|
void
|
||||||
|
AddAnimatingTextures (void)
|
||||||
{
|
{
|
||||||
int base;
|
int base;
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
|
@ -442,24 +438,21 @@ void AddAnimatingTextures (void)
|
||||||
|
|
||||||
base = nummiptex;
|
base = nummiptex;
|
||||||
|
|
||||||
for (i=0 ; i<base ; i++)
|
for (i = 0; i < base; i++) {
|
||||||
{
|
|
||||||
if (miptex[i][0] != '+')
|
if (miptex[i][0] != '+')
|
||||||
continue;
|
continue;
|
||||||
strcpy (name, miptex[i]);
|
strcpy (name, miptex[i]);
|
||||||
|
|
||||||
for (j=0 ; j<20 ; j++)
|
for (j = 0; j < 20; j++) {
|
||||||
{
|
|
||||||
if (j < 10)
|
if (j < 10)
|
||||||
name[1] = '0'+j;
|
name[1] = '0' + j;
|
||||||
else
|
else
|
||||||
name[1] = 'A'+j-10; // alternate animation
|
name[1] = 'A' + j - 10; // alternate animation
|
||||||
|
|
||||||
|
|
||||||
// see if this name exists in the wadfile
|
// see if this name exists in the wadfile
|
||||||
for (k=0 ; k<wadinfo.numlumps ; k++)
|
for (k = 0; k < wadinfo.numlumps; k++)
|
||||||
if (!strcmp(name, lumpinfo[k].name))
|
if (!strcmp (name, lumpinfo[k].name)) {
|
||||||
{
|
|
||||||
FindMiptex (name); // add to the miptex list
|
FindMiptex (name); // add to the miptex list
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -474,7 +467,8 @@ void AddAnimatingTextures (void)
|
||||||
WriteMiptex
|
WriteMiptex
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void WriteMiptex (void)
|
void
|
||||||
|
WriteMiptex (void)
|
||||||
{
|
{
|
||||||
int i, len;
|
int i, len;
|
||||||
byte *data;
|
byte *data;
|
||||||
|
@ -483,29 +477,26 @@ void WriteMiptex (void)
|
||||||
char fullpath[1024];
|
char fullpath[1024];
|
||||||
|
|
||||||
path = ValueForKey (&entities[0], "_wad");
|
path = ValueForKey (&entities[0], "_wad");
|
||||||
if (!path || !path[0])
|
if (!path || !path[0]) {
|
||||||
{
|
|
||||||
path = ValueForKey (&entities[0], "wad");
|
path = ValueForKey (&entities[0], "wad");
|
||||||
if (!path || !path[0])
|
if (!path || !path[0]) {
|
||||||
{
|
|
||||||
printf ("WARNING: no wadfile specified\n");
|
printf ("WARNING: no wadfile specified\n");
|
||||||
bsp->texdatasize = 0;
|
bsp->texdatasize = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf (fullpath, "%s/%s", /*FIXME gamedir*/".", path);
|
sprintf (fullpath, "%s/%s", /* FIXME gamedir */ ".", path);
|
||||||
|
|
||||||
TEX_InitFromWad (fullpath);
|
TEX_InitFromWad (fullpath);
|
||||||
|
|
||||||
AddAnimatingTextures ();
|
AddAnimatingTextures ();
|
||||||
|
|
||||||
l = (dmiptexlump_t *)bsp->texdata;
|
l = (dmiptexlump_t *) bsp->texdata;
|
||||||
data = (byte *)&l->dataofs[nummiptex];
|
data = (byte *) & l->dataofs[nummiptex];
|
||||||
l->nummiptex = nummiptex;
|
l->nummiptex = nummiptex;
|
||||||
for (i=0 ; i<nummiptex ; i++)
|
for (i = 0; i < nummiptex; i++) {
|
||||||
{
|
l->dataofs[i] = data - (byte *) l;
|
||||||
l->dataofs[i] = data - (byte *)l;
|
|
||||||
len = LoadLump (miptex[i], data);
|
len = LoadLump (miptex[i], data);
|
||||||
if (data + len - bsp->texdata >= MAX_MAP_MIPTEX)
|
if (data + len - bsp->texdata >= MAX_MAP_MIPTEX)
|
||||||
Sys_Error ("Textures exceeded MAX_MAP_MIPTEX");
|
Sys_Error ("Textures exceeded MAX_MAP_MIPTEX");
|
||||||
|
@ -525,7 +516,8 @@ void WriteMiptex (void)
|
||||||
BeginBSPFile
|
BeginBSPFile
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void BeginBSPFile (void)
|
void
|
||||||
|
BeginBSPFile (void)
|
||||||
{
|
{
|
||||||
// edge 0 is not used, because 0 can't be negated
|
// edge 0 is not used, because 0 can't be negated
|
||||||
bsp->numedges = 1;
|
bsp->numedges = 1;
|
||||||
|
@ -543,17 +535,18 @@ void BeginBSPFile (void)
|
||||||
FinishBSPFile
|
FinishBSPFile
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void FinishBSPFile (void)
|
void
|
||||||
|
FinishBSPFile (void)
|
||||||
{
|
{
|
||||||
QFile *f;
|
QFile *f;
|
||||||
|
|
||||||
printf ("--- FinishBSPFile ---\n");
|
printf ("--- FinishBSPFile ---\n");
|
||||||
printf ("WriteBSPFile: %s\n", bspfilename);
|
printf ("WriteBSPFile: %s\n", bspfilename);
|
||||||
|
|
||||||
WriteMiptex ();
|
WriteMiptex ();
|
||||||
|
|
||||||
//XXX PrintBSPFileSizes ();
|
// XXX PrintBSPFileSizes ();
|
||||||
f = Qopen (bspfilename, "wb");
|
f = Qopen (bspfilename, "wb");
|
||||||
WriteBSPFile (bsp, f);
|
WriteBSPFile (bsp, f);
|
||||||
Qclose (f);
|
Qclose (f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue