X-Git-Url: https://de.git.xonotic.org/?p=voretournament%2Fvoretournament.git;a=blobdiff_plain;f=misc%2Fmediasource%2Fnetradiant-src%2Ftools%2Fquake2%2Fq2map%2Fcsg.c;fp=misc%2Fmediasource%2Fnetradiant-src%2Ftools%2Fquake2%2Fq2map%2Fcsg.c;h=0000000000000000000000000000000000000000;hp=2e058299e86575facba78e29a598512ca1842d40;hb=2376f1d3e3ea56046cca61d87cb8d648034e1a11;hpb=71c85af29fb024d5657f383c6e6f33720cd2c25e diff --git a/misc/mediasource/netradiant-src/tools/quake2/q2map/csg.c b/misc/mediasource/netradiant-src/tools/quake2/q2map/csg.c deleted file mode 100644 index 2e058299..00000000 --- a/misc/mediasource/netradiant-src/tools/quake2/q2map/csg.c +++ /dev/null @@ -1,634 +0,0 @@ -/* -Copyright (C) 1999-2006 Id Software, Inc. and contributors. -For a list of contributors, see the accompanying CONTRIBUTORS file. - -This file is part of GtkRadiant. - -GtkRadiant is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -GtkRadiant is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GtkRadiant; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "qbsp.h" - -/* - -tag all brushes with original contents -brushes may contain multiple contents -there will be no brush overlap after csg phase - - - - -each side has a count of the other sides it splits - -the best split will be the one that minimizes the total split counts -of all remaining sides - -precalc side on plane table - -evaluate split side -{ -cost = 0 -for all sides - for all sides - get - if side splits side and splitside is on same child - cost++; -} - - - */ - -void SplitBrush2 (bspbrush_t *brush, int planenum, - bspbrush_t **front, bspbrush_t **back) -{ - SplitBrush (brush, planenum, front, back); -#if 0 - if (*front && (*front)->sides[(*front)->numsides-1].texinfo == -1) - (*front)->sides[(*front)->numsides-1].texinfo = (*front)->sides[0].texinfo; // not -1 - if (*back && (*back)->sides[(*back)->numsides-1].texinfo == -1) - (*back)->sides[(*back)->numsides-1].texinfo = (*back)->sides[0].texinfo; // not -1 -#endif -} - -/* -=============== -SubtractBrush - -Returns a list of brushes that remain after B is subtracted from A. -May by empty if A is contained inside B. - -The originals are undisturbed. -=============== -*/ -bspbrush_t *SubtractBrush (bspbrush_t *a, bspbrush_t *b) -{ // a - b = out (list) - int i; - bspbrush_t *front, *back; - bspbrush_t *out, *in; - - in = a; - out = NULL; - for (i=0 ; inumsides && in ; i++) - { - SplitBrush2 (in, b->sides[i].planenum, &front, &back); - if (in != a) - FreeBrush (in); - if (front) - { // add to list - front->next = out; - out = front; - } - in = back; - } - if (in) - FreeBrush (in); - else - { // didn't really intersect - FreeBrushList (out); - return a; - } - return out; -} - -/* -=============== -IntersectBrush - -Returns a single brush made up by the intersection of the -two provided brushes, or NULL if they are disjoint. - -The originals are undisturbed. -=============== -*/ -bspbrush_t *IntersectBrush (bspbrush_t *a, bspbrush_t *b) -{ - int i; - bspbrush_t *front, *back; - bspbrush_t *in; - - in = a; - for (i=0 ; inumsides && in ; i++) - { - SplitBrush2 (in, b->sides[i].planenum, &front, &back); - if (in != a) - FreeBrush (in); - if (front) - FreeBrush (front); - in = back; - } - - if (in == a) - return NULL; - - in->next = NULL; - return in; -} - - -/* -=============== -BrushesDisjoint - -Returns true if the two brushes definately do not intersect. -There will be false negatives for some non-axial combinations. -=============== -*/ -qboolean BrushesDisjoint (bspbrush_t *a, bspbrush_t *b) -{ - int i, j; - - // check bounding boxes - for (i=0 ; i<3 ; i++) - if (a->mins[i] >= b->maxs[i] - || a->maxs[i] <= b->mins[i]) - return true; // bounding boxes don't overlap - - // check for opposing planes - for (i=0 ; inumsides ; i++) - { - for (j=0 ; jnumsides ; j++) - { - if (a->sides[i].planenum == - (b->sides[j].planenum^1) ) - return true; // opposite planes, so not touching - } - } - - return false; // might intersect -} - -/* -=============== -IntersectionContents - -Returns a content word for the intersection of two brushes. -Some combinations will generate a combination (water + clip), -but most will be the stronger of the two contents. -=============== -*/ -int IntersectionContents (int c1, int c2) -{ - int out; - - out = c1 | c2; - - if (out & CONTENTS_SOLID) - out = CONTENTS_SOLID; - - return out; -} - - -int minplanenums[3]; -int maxplanenums[3]; - -/* -=============== -ClipBrushToBox - -Any planes shared with the box edge will be set to no texinfo -=============== -*/ -bspbrush_t *ClipBrushToBox (bspbrush_t *brush, vec3_t clipmins, vec3_t clipmaxs) -{ - int i, j; - bspbrush_t *front, *back; - int p; - - for (j=0 ; j<2 ; j++) - { - if (brush->maxs[j] > clipmaxs[j]) - { - SplitBrush (brush, maxplanenums[j], &front, &back); - if (front) - FreeBrush (front); - brush = back; - if (!brush) - return NULL; - } - if (brush->mins[j] < clipmins[j]) - { - SplitBrush (brush, minplanenums[j], &front, &back); - if (back) - FreeBrush (back); - brush = front; - if (!brush) - return NULL; - } - } - - // remove any colinear faces - - for (i=0 ; inumsides ; i++) - { - p = brush->sides[i].planenum & ~1; - if (p == maxplanenums[0] || p == maxplanenums[1] - || p == minplanenums[0] || p == minplanenums[1]) - { - brush->sides[i].texinfo = TEXINFO_NODE; - brush->sides[i].visible = false; - } - } - return brush; -} - -/* -=============== -MakeBspBrushList -=============== -*/ -bspbrush_t *MakeBspBrushList (int startbrush, int endbrush, - vec3_t clipmins, vec3_t clipmaxs) -{ - mapbrush_t *mb; - bspbrush_t *brushlist, *newbrush; - int i, j; - int c_faces; - int c_brushes; - int numsides; - int vis; - vec3_t normal; - float dist; - - for (i=0 ; i<2 ; i++) - { - VectorClear (normal); - normal[i] = 1; - dist = clipmaxs[i]; - maxplanenums[i] = FindFloatPlane (normal, dist); - dist = clipmins[i]; - minplanenums[i] = FindFloatPlane (normal, dist); - } - - brushlist = NULL; - c_faces = 0; - c_brushes = 0; - - for (i=startbrush ; inumsides; - if (!numsides) - continue; - // make sure the brush has at least one face showing - vis = 0; - for (j=0 ; joriginal_sides[j].visible && mb->original_sides[j].winding) - vis++; -#if 0 - if (!vis) - continue; // no faces at all -#endif - // if the brush is outside the clip area, skip it - for (j=0 ; j<3 ; j++) - if (mb->mins[j] >= clipmaxs[j] - || mb->maxs[j] <= clipmins[j]) - break; - if (j != 3) - continue; - - // - // make a copy of the brush - // - newbrush = AllocBrush (mb->numsides); - newbrush->original = mb; - newbrush->numsides = mb->numsides; - memcpy (newbrush->sides, mb->original_sides, numsides*sizeof(side_t)); - for (j=0 ; jsides[j].winding) - newbrush->sides[j].winding = CopyWinding (newbrush->sides[j].winding); - if (newbrush->sides[j].surf & SURF_HINT) - newbrush->sides[j].visible = true; // hints are always visible - } - VectorCopy (mb->mins, newbrush->mins); - VectorCopy (mb->maxs, newbrush->maxs); - - // - // carve off anything outside the clip box - // - newbrush = ClipBrushToBox (newbrush, clipmins, clipmaxs); - if (!newbrush) - continue; - - c_faces += vis; - c_brushes++; - - newbrush->next = brushlist; - brushlist = newbrush; - } - - return brushlist; -} - -/* -=============== -AddBspBrushListToTail -=============== -*/ -bspbrush_t *AddBrushListToTail (bspbrush_t *list, bspbrush_t *tail) -{ - bspbrush_t *walk, *next; - - for (walk=list ; walk ; walk=next) - { // add to end of list - next = walk->next; - walk->next = NULL; - tail->next = walk; - tail = walk; - } - - return tail; -} - -/* -=========== -CullList - -Builds a new list that doesn't hold the given brush -=========== -*/ -bspbrush_t *CullList (bspbrush_t *list, bspbrush_t *skip1) -{ - bspbrush_t *newlist; - bspbrush_t *next; - - newlist = NULL; - - for ( ; list ; list = next) - { - next = list->next; - if (list == skip1) - { - FreeBrush (list); - continue; - } - list->next = newlist; - newlist = list; - } - return newlist; -} - - -/* -================== -WriteBrushMap -================== -*/ -void WriteBrushMap (char *name, bspbrush_t *list) -{ - FILE *f; - side_t *s; - int i; - winding_t *w; - - Sys_Printf ("writing %s\n", name); - f = fopen (name, "wb"); - if (!f) - Error ("Can't write %s\b", name); - - fprintf (f, "{\n\"classname\" \"worldspawn\"\n"); - - for ( ; list ; list=list->next ) - { - fprintf (f, "{\n"); - for (i=0,s=list->sides ; inumsides ; i++,s++) - { - w = BaseWindingForPlane (mapplanes[s->planenum].normal, mapplanes[s->planenum].dist); - - fprintf (f,"( %i %i %i ) ", (int)w->p[0][0], (int)w->p[0][1], (int)w->p[0][2]); - fprintf (f,"( %i %i %i ) ", (int)w->p[1][0], (int)w->p[1][1], (int)w->p[1][2]); - fprintf (f,"( %i %i %i ) ", (int)w->p[2][0], (int)w->p[2][1], (int)w->p[2][2]); - - fprintf (f, "%s 0 0 0 1 1\n", texinfo[s->texinfo].texture); - FreeWinding (w); - } - fprintf (f, "}\n"); - } - fprintf (f, "}\n"); - - fclose (f); - -} - -/* -================== -BrushGE - -Returns true if b1 is allowed to bite b2 -================== -*/ -qboolean BrushGE (bspbrush_t *b1, bspbrush_t *b2) -{ - // detail brushes never bite structural brushes - if ( (b1->original->contents & CONTENTS_DETAIL) - && !(b2->original->contents & CONTENTS_DETAIL) ) - return false; - if (b1->original->contents & CONTENTS_SOLID) - return true; - return false; -} - -/* -================= -ChopBrushes - -Carves any intersecting solid brushes into the minimum number -of non-intersecting brushes. -================= -*/ -bspbrush_t *ChopBrushes (bspbrush_t *head) -{ - bspbrush_t *b1, *b2, *next; - bspbrush_t *tail; - bspbrush_t *keep; - bspbrush_t *sub, *sub2; - int c1, c2; - - Sys_FPrintf( SYS_VRB, "---- ChopBrushes ----\n"); - Sys_FPrintf( SYS_VRB, "original brushes: %i\n", CountBrushList (head)); - -#if 0 - if (startbrush == 0) - WriteBrushList ("before.gl", head, false); -#endif - keep = NULL; - -newlist: - // find tail - if (!head) - return NULL; - for (tail=head ; tail->next ; tail=tail->next) - ; - - for (b1=head ; b1 ; b1=next) - { - next = b1->next; - for (b2=b1->next ; b2 ; b2 = b2->next) - { - if (BrushesDisjoint (b1, b2)) - continue; - - sub = NULL; - sub2 = NULL; - c1 = 999999; - c2 = 999999; - - if ( BrushGE (b2, b1) ) - { - sub = SubtractBrush (b1, b2); - if (sub == b1) - continue; // didn't really intersect - if (!sub) - { // b1 is swallowed by b2 - head = CullList (b1, b1); - goto newlist; - } - c1 = CountBrushList (sub); - } - - if ( BrushGE (b1, b2) ) - { - sub2 = SubtractBrush (b2, b1); - if (sub2 == b2) - continue; // didn't really intersect - if (!sub2) - { // b2 is swallowed by b1 - FreeBrushList (sub); - head = CullList (b1, b2); - goto newlist; - } - c2 = CountBrushList (sub2); - } - - if (!sub && !sub2) - continue; // neither one can bite - - // only accept if it didn't fragment - // (commening this out allows full fragmentation) - if (c1 > 1 && c2 > 1) - { - if (sub2) - FreeBrushList (sub2); - if (sub) - FreeBrushList (sub); - continue; - } - - if (c1 < c2) - { - if (sub2) - FreeBrushList (sub2); - tail = AddBrushListToTail (sub, tail); - head = CullList (b1, b1); - goto newlist; - } - else - { - if (sub) - FreeBrushList (sub); - tail = AddBrushListToTail (sub2, tail); - head = CullList (b1, b2); - goto newlist; - } - } - - if (!b2) - { // b1 is no longer intersecting anything, so keep it - b1->next = keep; - keep = b1; - } - } - - Sys_FPrintf( SYS_VRB, "output brushes: %i\n", CountBrushList (keep)); -#if 0 - { - WriteBrushList ("after.gl", keep, false); - WriteBrushMap ("after.map", keep); - } -#endif - return keep; -} - - -/* -================= -InitialBrushList -================= -*/ -bspbrush_t *InitialBrushList (bspbrush_t *list) -{ - bspbrush_t *b; - bspbrush_t *out, *newb; - int i; - - // only return brushes that have visible faces - out = NULL; - for (b=list ; b ; b=b->next) - { -#if 0 - for (i=0 ; inumsides ; i++) - if (b->sides[i].visible) - break; - if (i == b->numsides) - continue; -#endif - newb = CopyBrush (b); - newb->next = out; - out = newb; - - // clear visible, so it must be set by MarkVisibleFaces_r - // to be used in the optimized list - for (i=0 ; inumsides ; i++) - { - newb->sides[i].original = &b->sides[i]; -// newb->sides[i].visible = true; - b->sides[i].visible = false; - } - } - - return out; -} - -/* -================= -OptimizedBrushList -================= -*/ -bspbrush_t *OptimizedBrushList (bspbrush_t *list) -{ - bspbrush_t *b; - bspbrush_t *out, *newb; - int i; - - // only return brushes that have visible faces - out = NULL; - for (b=list ; b ; b=b->next) - { - for (i=0 ; inumsides ; i++) - if (b->sides[i].visible) - break; - if (i == b->numsides) - continue; - newb = CopyBrush (b); - newb->next = out; - out = newb; - } - -// WriteBrushList ("vis.gl", out, true); - - return out; -}