From 6c89883c8fefdde67956a0b7b60c5fc509693546 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 29 Aug 2010 18:31:04 +0900 Subject: [PATCH] Lots of csg4 documentation --- tools/qfbsp/include/csg4.h | 43 ++++++++++++++++- tools/qfbsp/source/csg4.c | 96 ++++++++++++++++++++------------------ 2 files changed, 93 insertions(+), 46 deletions(-) diff --git a/tools/qfbsp/include/csg4.h b/tools/qfbsp/include/csg4.h index 3b18c3667..bafb7557f 100644 --- a/tools/qfbsp/include/csg4.h +++ b/tools/qfbsp/include/csg4.h @@ -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); diff --git a/tools/qfbsp/source/csg4.c b/tools/qfbsp/source/csg4.c index 5a31ea025..45a716ab6 100644 --- a/tools/qfbsp/source/csg4.c +++ b/tools/qfbsp/source/csg4.c @@ -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