2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 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.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 =========================================================
30 ONLY SAVE OUT PLANES THAT ARE ACTUALLY USED AS NODES
32 =========================================================
35 int planeused[MAX_MAP_PLANES];
41 There is no oportunity to discard planes, because all of the original
42 brushes will be saved in the map.
45 void EmitPlanes (void)
50 int planetranslate[MAX_MAP_PLANES];
53 for (i=0 ; i<nummapplanes ; i++, mp++)
55 dp = &dplanes[numplanes];
56 planetranslate[i] = numplanes;
57 VectorCopy ( mp->normal, dp->normal);
65 //========================================================
67 void EmitMarkFace (dleaf_t *leaf_p, face_t *f)
77 EmitMarkFace (leaf_p, f->split[0]);
78 EmitMarkFace (leaf_p, f->split[1]);
82 facenum = f->outputnumber;
84 return; // degenerate face
86 if (facenum < 0 || facenum >= numfaces)
87 Error ("Bad leafface");
88 for (i=leaf_p->firstleafface ; i<numleaffaces ; i++)
89 if (dleaffaces[i] == facenum)
90 break; // merged out face
91 if (i == numleaffaces)
93 if (numleaffaces >= MAX_MAP_LEAFFACES)
94 Error ("MAX_MAP_LEAFFACES");
96 dleaffaces[numleaffaces] = facenum;
108 void EmitLeaf (node_t *node)
119 if (numleafs >= MAX_MAP_LEAFS)
120 Error ("MAX_MAP_LEAFS");
122 leaf_p = &dleafs[numleafs];
125 leaf_p->contents = node->contents;
126 leaf_p->cluster = node->cluster;
127 leaf_p->area = node->area;
130 // write bounding box info
132 VectorCopy ((short) node->mins, leaf_p->mins);
133 VectorCopy ((short) node->maxs, leaf_p->maxs);
136 // write the leafbrushes
138 leaf_p->firstleafbrush = numleafbrushes;
139 for (b=node->brushlist ; b ; b=b->next)
141 if (numleafbrushes >= MAX_MAP_LEAFBRUSHES)
142 Error ("MAX_MAP_LEAFBRUSHES");
144 brushnum = b->original - mapbrushes;
145 for (i=leaf_p->firstleafbrush ; i<numleafbrushes ; i++)
146 if (dleafbrushes[i] == brushnum)
148 if (i == numleafbrushes)
150 dleafbrushes[numleafbrushes] = brushnum;
154 leaf_p->numleafbrushes = numleafbrushes - leaf_p->firstleafbrush;
157 // write the leaffaces
159 if (leaf_p->contents & CONTENTS_SOLID)
160 return; // no leaffaces in solids
162 leaf_p->firstleafface = numleaffaces;
164 for (p = node->portals ; p ; p = p->next[s])
166 s = (p->nodes[1] == node);
169 continue; // not a visible portal
171 EmitMarkFace (leaf_p, f);
174 leaf_p->numleaffaces = numleaffaces - leaf_p->firstleafface;
183 void EmitFace (face_t *f)
189 f->outputnumber = -1;
191 if (f->numpoints < 3)
193 return; // degenerated
195 if (f->merged || f->split[0] || f->split[1])
197 return; // not a final face
200 // save output number so leaffaces can use
201 f->outputnumber = numfaces;
203 if (numfaces >= MAX_MAP_FACES)
204 Error ("numfaces == MAX_MAP_FACES");
205 df = &dfaces[numfaces];
208 // planenum is used by qlight, but not quake
209 df->planenum = f->planenum & (~1);
210 df->side = f->planenum & 1;
212 df->firstedge = numsurfedges;
213 df->numedges = f->numpoints;
214 df->texinfo = f->texinfo;
215 for (i=0 ; i<f->numpoints ; i++)
217 // e = GetEdge (f->pts[i], f->pts[(i+1)%f->numpoints], f);
218 e = GetEdge2 (f->vertexnums[i], f->vertexnums[(i+1)%f->numpoints], f);
219 if (numsurfedges >= MAX_MAP_SURFEDGES)
220 Error ("numsurfedges == MAX_MAP_SURFEDGES");
221 dsurfedges[numsurfedges] = e;
231 int EmitDrawNode_r (node_t *node)
237 if (node->planenum == PLANENUM_LEAF)
244 if (numnodes == MAX_MAP_NODES)
245 Error ("MAX_MAP_NODES");
246 n = &dnodes[numnodes];
249 VectorCopy ((short) node->mins, n->mins);
250 VectorCopy ((short) node->maxs, n->maxs);
252 planeused[node->planenum]++;
253 planeused[node->planenum^1]++;
255 if (node->planenum & 1)
256 Error ("WriteDrawNodes_r: odd planenum");
257 n->planenum = node->planenum;
258 n->firstface = numfaces;
265 for (f=node->faces ; f ; f=f->next)
268 n->numfaces = numfaces - n->firstface;
272 // recursively output the other nodes
274 for (i=0 ; i<2 ; i++)
276 if (node->children[i]->planenum == PLANENUM_LEAF)
278 n->children[i] = -(numleafs + 1);
279 EmitLeaf (node->children[i]);
283 n->children[i] = numnodes;
284 EmitDrawNode_r (node->children[i]);
291 //=========================================================
299 void WriteBSP (node_t *headnode)
306 Sys_FPrintf( SYS_VRB, "--- WriteBSP ---\n");
309 dmodels[nummodels].headnode = EmitDrawNode_r (headnode);
310 EmitAreaPortals (headnode);
312 Sys_FPrintf( SYS_VRB, "%5i nodes with faces\n", c_facenodes);
313 Sys_FPrintf( SYS_VRB, "%5i nodes without faces\n", c_nofaces);
314 Sys_FPrintf( SYS_VRB, "%5i faces\n", numfaces-oldfaces);
317 //===========================================================
324 void SetModelNumbers (void)
331 for (i=1 ; i<num_entities ; i++)
333 if (entities[i].numbrushes)
335 sprintf (value, "*%i", models);
337 SetKeyValue (&entities[i], "model", value);
348 #define MAX_SWITCHED_LIGHTS 32
349 void SetLightStyles (void)
356 char lighttargets[MAX_SWITCHED_LIGHTS][64];
359 // any light that is controlled (has a targetname)
360 // must have a unique style number generated for it
363 for (i=1 ; i<num_entities ; i++)
367 t = ValueForKey (e, "classname");
368 if (Q_strncasecmp (t, "light", 5))
370 t = ValueForKey (e, "targetname");
374 // find this targetname
375 for (j=0 ; j<stylenum ; j++)
376 if (!strcmp (lighttargets[j], t))
380 if (stylenum == MAX_SWITCHED_LIGHTS)
381 Error ("stylenum == MAX_SWITCHED_LIGHTS");
382 strcpy (lighttargets[j], t);
385 sprintf (value, "%i", 32 + j);
386 SetKeyValue (e, "style", value);
391 //===========================================================
398 void EmitBrushes (void)
400 int i, j, bnum, s, x;
409 numbrushes = nummapbrushes;
411 for (bnum=0 ; bnum<nummapbrushes ; bnum++)
413 b = &mapbrushes[bnum];
414 db = &dbrushes[bnum];
416 db->contents = b->contents;
417 db->firstside = numbrushsides;
418 db->numsides = b->numsides;
419 for (j=0 ; j<b->numsides ; j++)
421 if (numbrushsides == MAX_MAP_BRUSHSIDES)
422 Error ("MAX_MAP_BRUSHSIDES");
423 cp = &dbrushsides[numbrushsides];
425 cp->planenum = b->original_sides[j].planenum;
426 cp->texinfo = b->original_sides[j].texinfo;
429 // add any axis planes not contained in the brush to bevel off corners
430 for (x=0 ; x<3 ; x++)
431 for (s=-1 ; s<=1 ; s+=2)
434 VectorCopy (vec3_origin, normal);
435 normal[x] = (float) s;
440 planenum = FindFloatPlane (normal, dist);
441 for (i=0 ; i<b->numsides ; i++)
442 if (b->original_sides[i].planenum == planenum)
444 if (i == b->numsides)
446 if (numbrushsides >= MAX_MAP_BRUSHSIDES)
447 Error ("MAX_MAP_BRUSHSIDES");
449 dbrushsides[numbrushsides].planenum = planenum;
450 dbrushsides[numbrushsides].texinfo =
451 dbrushsides[numbrushsides-1].texinfo;
461 //===========================================================
468 void BeginBSPFile (void)
470 // these values may actually be initialized
471 // if the file existed when loaded, so clear them explicitly
481 // edge 0 is not used, because 0 can't be negated
484 // leave vertex 0 as an error
487 // leave leaf 0 as an error
489 dleafs[0].contents = CONTENTS_SOLID;
498 void EndBSPFile (void)
513 sprintf (path, "%s/pics/pop.lmp", gamedir);
514 len = LoadFile (path, &buf);
515 memcpy (dpop, buf, sizeof(dpop));
520 sprintf (path, "%s.bsp", source);
521 Sys_Printf ("Writing %s\n", path);
532 extern int firstmodeledge;
533 extern int firstmodelface;
534 void BeginModel (void)
543 if (nummodels == MAX_MAP_MODELS)
544 Error ("MAX_MAP_MODELS");
545 mod = &dmodels[nummodels];
547 mod->firstface = numfaces;
549 firstmodleaf = numleafs;
550 firstmodeledge = numedges;
551 firstmodelface = numfaces;
556 e = &entities[entity_num];
558 start = e->firstbrush;
559 end = start + e->numbrushes;
560 ClearBounds (mins, maxs);
562 for (j=start ; j<end ; j++)
566 continue; // not a real brush (origin brush)
567 AddPointToBounds (b->mins, mins, maxs);
568 AddPointToBounds (b->maxs, mins, maxs);
571 VectorCopy (mins, mod->mins);
572 VectorCopy (maxs, mod->maxs);
585 mod = &dmodels[nummodels];
587 mod->numfaces = numfaces - mod->firstface;