Lots of csg4 documentation

This commit is contained in:
Bill Currie 2010-08-29 18:31:04 +09:00
parent 17e5813a51
commit 6c89883c8f
2 changed files with 93 additions and 46 deletions

View file

@ -30,12 +30,53 @@ struct visfacet_s;
struct brushset_s;
struct surface_s;
// build surfaces is also used by GatherNodeFaces
extern struct visfacet_s *validfaces[MAX_MAP_PLANES];
/** Build the surface lists for the brushset.
Each plane still with faces after clipping will have one surface, and
each surface will list the faces on that plane.
\return Chain of all the external surfaces with one or more
visible faces.
*/
struct surface_s *BuildSurfaces (void);
/** Create a duplicate face.
Duplicates the non point information of a face.
\param in The face to duplicate.
\return The new face.
*/
struct visfacet_s *NewFaceFromFace (struct visfacet_s *in);
/** Convert a brush-set to a list of clipped faces.
The brushes of the brush set will be clipped against each other.
\param bs The brush-set to convert.
\return list of surfaces containing all of the faces
*/
struct surface_s *CSGFaces (struct brushset_s *bs);
/** Split a face by a plane.
\param in The face to split.
\param split The plane by which to split the face.
\param front Set to the new face repesenting the part of the input
face that is in front of the plane, or NULL if there is
no front portion.
\param back Set to the new face repesenting the part of the input
face that is behind the plane, or NULL if there is
no back portion.
\note A face entirely on the plane is considered to be behind the plane.
\note The face represented by \a in becomes invalid. If either \a front
or \a back is NULL, then no split has occurred and the other will be set
to \a in.
*/
void SplitFace (struct visfacet_s *in, struct plane_s *split,
struct visfacet_s **front, struct visfacet_s **back);

View file

@ -52,14 +52,7 @@ int brushfaces;
int csgfaces;
int csgmergefaces;
/*
NewFaceFromFace
Duplicates the non point information of a face, used by SplitFace and
MergeFace.
*/
face_t *
face_t *
NewFaceFromFace (face_t *in)
{
face_t *newf;
@ -124,15 +117,15 @@ SplitFace (face_t *in, plane_t *split, face_t **front, face_t **back)
FreeFace (in);
}
/*
ClipInside
/** Clips all of the faces in the ::inside list.
Clips all of the faces in the inside list, possibly moving them to the
outside list or spliting it into a piece in each list.
Faces will be moved to the ::outside list or split into a piece in each
list. Faces exactly on the plane will stay inside unless overdrawn by
a later brush
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
\param splitplane Index of the plane by which faces will be clipped.
\param frontside The side of the plane that holds the outside list.
\param precedence XXX
*/
static void
ClipInside (int splitplane, int frontside, qboolean precedence)
@ -145,18 +138,22 @@ ClipInside (int splitplane, int frontside, qboolean precedence)
insidelist = NULL;
for (f = inside; f; f = next) {
next = f->next;
next = f->next; // f->next will get mashed by SplitFace
if (f->planenum == splitplane) { // exactly on, handle special
if (frontside != f->planeside || precedence) { // always clip off
// opposite faceing
if (f->planenum == splitplane) {
// exactly on, handle special
// always clip off opposite facing
if (frontside != f->planeside || precedence) {
frags[frontside] = NULL;
frags[!frontside] = f;
} else { // leave it on the outside
} else {
// leave it on the outside
frags[frontside] = f;
frags[!frontside] = NULL;
}
} else { // proper split
} else {
// proper split
SplitFace (f, split, &frags[0], &frags[1]);
}
@ -173,10 +170,10 @@ ClipInside (int splitplane, int frontside, qboolean precedence)
inside = insidelist;
}
/*
SaveOutside
/** Saves all of the faces in the ::outside list to the bsp plane list
(::validfaces).
Saves all of the faces in the outside list to the bsp plane list
\param mirror If true, add extra faces that face the opposite direction.
*/
static void
SaveOutside (qboolean mirror)
@ -207,10 +204,13 @@ SaveOutside (qboolean mirror)
}
}
/*
FreeInside
/** Free the faces that are inside the clipping brush.
Free all the faces that got clipped out
If the clipping brush is non-solid, then the faces will be moved to
::outside rather than being freed, thus allowing the faces to continue
to exist.
\param contents The contents of the clipping brush.
*/
static void
FreeInside (int contents)
@ -229,13 +229,7 @@ FreeInside (int contents)
}
}
/*
BuildSurfaces
Returns a chain of all the external surfaces with one or more visible
faces.
*/
surface_t *
surface_t *
BuildSurfaces (void)
{
face_t *count;
@ -269,6 +263,14 @@ BuildSurfaces (void)
return surfhead;
}
/** Create faces using the faces of the provided brush.
The ::outside list will be set to the list of created faces. The faces
will be such that their front is empty and their back is the contents of
the brush.
\param b The brush from which to create the faces.
*/
static void
CopyFacesToOutside (brush_t *b)
{
@ -291,12 +293,7 @@ CopyFacesToOutside (brush_t *b)
}
}
/*
CSGFaces
Returns a list of surfaces containing all of the faces
*/
surface_t *
surface_t *
CSGFaces (brushset_t *bs)
{
brush_t *b1, *b2;
@ -324,15 +321,17 @@ CSGFaces (brushset_t *bs)
continue;
}
// earlier brushes do NOT overwrite
overwrite = false;
for (b2 = bs->brushes; b2; b2 = b2->next) {
// see if b2 needs to clip a chunk out of b1
if (b2->faces->texturenum < 0)
continue;
// see if b2 needs to clip a chunk out of b1
if (b1 == b2) {
overwrite = true; // later brushes now overwrite
// later brushes DO overwrite
overwrite = true;
continue;
}
// check bounding box first
@ -350,12 +349,19 @@ CSGFaces (brushset_t *bs)
for (f = b2->faces; f; f = f->next)
ClipInside (f->planenum, f->planeside, overwrite);
// these faces are continued in another brush, so get rid of them
// these faces are contained in another brush, so get rid of them
if (b1->contents == CONTENTS_SOLID
&& b2->contents <= CONTENTS_WATER)
&& b2->contents <= CONTENTS_WATER) {
// Faces from a solid brush are allowed to exist inside a
// non-solid brush. This forms an intrusion into the clipping
// brush.
FreeInside (b2->contents);
else
} else {
// Unconditionally treat the clipping brush as solid to force
// contents merging, or to make an empty clipping brush clip
// away parts of other brushes.
FreeInside (CONTENTS_SOLID);
}
}
// all of the faces left in outside are real surface faces