]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/extra/qe4/csg.c
Merge branch 'NateEag-master-patch-12920' into 'master'
[xonotic/netradiant.git] / tools / quake2 / extra / qe4 / csg.c
1 /*
2 ===========================================================================
3 Copyright (C) 1997-2006 Id Software, Inc.
4
5 This file is part of Quake 2 Tools source code.
6
7 Quake 2 Tools source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
12 Quake 2 Tools source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Quake 2 Tools source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 ===========================================================================
21 */
22
23 #include "qe3.h"
24
25 /*
26 ==============
27 CSG_SplitBrushByFace
28
29 The incoming brush is NOT freed.
30 The incoming face is NOT left referenced.
31 ==============
32 */
33 void CSG_SplitBrushByFace (brush_t *in, face_t *f, brush_t **front, brush_t **back)
34 {
35         brush_t *b;
36         face_t  *nf;
37         vec3_t  temp;
38
39         b = Brush_Clone (in);
40         nf = Face_Clone (f);
41
42         nf->texdef = b->brush_faces->texdef;
43         nf->next = b->brush_faces;
44         b->brush_faces = nf;
45
46         Brush_Build( b );
47         Brush_RemoveEmptyFaces ( b );
48         if ( !b->brush_faces )
49         {       // completely clipped away
50                 Brush_Free (b);
51                 *back = NULL;
52         }
53         else
54         {
55                 Entity_LinkBrush (in->owner, b);
56                 *back = b;
57         }
58
59         b = Brush_Clone (in);
60         nf = Face_Clone (f);
61         // swap the plane winding
62         VectorCopy (nf->planepts[0], temp);
63         VectorCopy (nf->planepts[1], nf->planepts[0]);
64         VectorCopy (temp, nf->planepts[1]);
65
66         nf->texdef = b->brush_faces->texdef;
67         nf->next = b->brush_faces;
68         b->brush_faces = nf;
69
70         Brush_Build( b );
71         Brush_RemoveEmptyFaces ( b );
72         if ( !b->brush_faces )
73         {       // completely clipped away
74                 Brush_Free (b);
75                 *front = NULL;
76         }
77         else
78         {
79                 Entity_LinkBrush (in->owner, b);
80                 *front = b;
81         }
82 }
83
84 /*
85 =============
86 CSG_MakeHollow
87 =============
88 */
89 void CSG_MakeHollow (void)
90 {
91         brush_t         *b, *front, *back, *next;
92         face_t          *f;
93         face_t          split;
94         vec3_t          move;
95         int                     i;
96
97         for (b = selected_brushes.next ; b != &selected_brushes ; b=next)
98         {
99                 next = b->next;
100                 for (f = b->brush_faces ; f ; f=f->next)
101                 {
102                         split = *f;
103                         VectorScale (f->plane.normal, g_qeglobals.d_gridsize, move);
104                         for (i=0 ; i<3 ; i++)
105                                 VectorSubtract (split.planepts[i], move, split.planepts[i]);
106
107                         CSG_SplitBrushByFace (b, &split, &front, &back);
108                         if (back)
109                                 Brush_Free (back);
110                         if (front)
111                                 Brush_AddToList (front, &selected_brushes);
112                 }
113                 Brush_Free (b);
114         }
115         Sys_UpdateWindows (W_ALL);
116 }
117
118
119 /*
120 =============
121 CSG_Subtract
122 =============
123 */
124 void CSG_Subtract (void)
125 {
126         brush_t         *b, *s, *frag, *front, *back, *next, *snext;
127         face_t          *f;
128         int                     i;
129
130         Sys_Printf ("Subtracting...\n");
131
132         for (b = selected_brushes.next ; b != &selected_brushes ; b=next)
133         {
134                 next = b->next;
135
136                 if (b->owner->eclass->fixedsize)
137                         continue;       // can't use texture from a fixed entity, so don't subtract
138
139                 for (s=active_brushes.next ; s != &active_brushes ; s=snext)
140                 {
141                         snext = s->next;
142                         if (s->owner->eclass->fixedsize)
143                                 continue;
144
145                         for (i=0 ; i<3 ; i++)
146                                 if (b->mins[i] >= s->maxs[i] - ON_EPSILON
147                                 || b->maxs[i] <= s->mins[i] + ON_EPSILON)
148                                         break;
149                         if (i != 3)
150                                 continue;       // definately don't touch
151
152                         frag = s;
153                         for (f = b->brush_faces ; f && frag ; f=f->next)
154                         {
155                                 CSG_SplitBrushByFace (frag, f, &front, &back);
156                                 Brush_Free (frag);
157                                 frag = back;
158                                 if (front)
159                                         Brush_AddToList (front, &active_brushes);
160                         }
161                         if (frag)
162                                 Brush_Free (frag);
163                 }
164         }
165
166         Sys_Printf ("done.\n");
167         Sys_UpdateWindows (W_ALL);
168 }