Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

map_q2.c File Reference

#include "qbsp.h"
#include "l_mem.h"
#include "../botlib/aasfile.h"
#include "aas_store.h"
#include "aas_cfg.h"
#include "aas_map.h"
#include "l_bsp_q2.h"

Include dependency graph for map_q2.c:

Include dependency graph

Go to the source code of this file.

Defines

#define BBOX_NORMAL_EPSILON   0.0001
#define NODESTACKSIZE   1024

Functions

void DPlanes2MapPlanes (void)
void MakeAreaPortalBrush (mapbrush_t *brush)
void MarkVisibleBrushSides (mapbrush_t *brush)
int Q2_BrushContents (mapbrush_t *b)
void Q2_BSPBrushToMapBrush (dbrush_t *bspbrush, entity_t *mapent)
void Q2_CreateMapTexinfo (void)
void Q2_InitNodeStack (void)
void Q2_LoadMapFile (char *filename)
void Q2_LoadMapFromBSP (char *filename, int offset, int length)
void Q2_MoveBrushesToWorld (entity_t *mapent)
void Q2_ParseBrush (script_t *script, entity_t *mapent)
void Q2_ParseBSPBrushes (entity_t *mapent)
qboolean Q2_ParseBSPEntity (int entnum)
qboolean Q2_ParseMapEntity (script_t *script)
int Q2_PopNodeStack (void)
void Q2_PushNodeStack (int num)
void Q2_ResetMapLoading (void)
void Q2_SetBrushModelNumbers (entity_t *mapent)
void Q2_SetLeafBrushesModelNumbers (int leafnum, int modelnum)
void TestExpandBrushes (void)

Variables

int brushmodelnumbers [MAX_MAPFILE_BRUSHES]
int dbrushleafnums [MAX_MAPFILE_BRUSHES]
int dplanes2mapplanes [MAX_MAPFILE_PLANES]
int nodestack [NODESTACKSIZE]
int * nodestackptr
int nodestacksize = 0


Define Documentation

#define BBOX_NORMAL_EPSILON   0.0001
 

Definition at line 117 of file map_q2.c.

#define NODESTACKSIZE   1024
 

Definition at line 39 of file map_q2.c.

Referenced by Q2_ResetMapLoading(), Q3_ResetMapLoading(), and Sin_ResetMapLoading().


Function Documentation

void DPlanes2MapPlanes void   ) 
 

Definition at line 148 of file map_q2.c.

References dplanes, dplanes2mapplanes, FindFloatPlane(), and i.

00149 {
00150     int i;
00151 
00152     for (i = 0; i < numplanes; i++)
00153     {
00154         dplanes2mapplanes[i] = FindFloatPlane(dplanes[i].normal, dplanes[i].dist);
00155     } //end for
00156 } //end of the function DPlanes2MapPlanes

Here is the call graph for this function:

void MakeAreaPortalBrush mapbrush_t brush  ) 
 

Definition at line 125 of file map_q2.c.

References side_s::contents, mapbrush_s::contents, mapbrush_t, mapbrush_s::numsides, mapbrush_s::original_sides, s, side_t, side_s::surf, SURF_HINT, and side_s::texinfo.

00126 {
00127     int sn;
00128     side_t *s;
00129 
00130     brush->contents = CONTENTS_AREAPORTAL;
00131 
00132     for (sn = 0; sn < brush->numsides; sn++)
00133     {
00134         s = brush->original_sides + sn;
00135         //make sure the surfaces are not hint or skip
00136         s->surf &= ~(SURF_HINT|SURF_SKIP);
00137         //
00138         s->texinfo = 0;
00139         s->contents = CONTENTS_AREAPORTAL;
00140     } //end for
00141 } //end of the function MakeAreaPortalBrush

void MarkVisibleBrushSides mapbrush_t brush  ) 
 

Definition at line 163 of file map_q2.c.

References dfaces, dplanes2mapplanes, side_s::flags, i, mapbrush_s::leafnum, mapbrush_t, n, mapbrush_s::numsides, mapbrush_s::original_sides, side_s::planenum, dface_t::planenum, and side_t.

00164 {
00165     int n, i, planenum;
00166     side_t *side;
00167     dface_t *face;
00168     //
00169     for (n = 0; n < brush->numsides; n++)
00170     {
00171         side = brush->original_sides + n;
00172         //if this side is a bevel or the leaf number of the brush is unknown
00173         if ((side->flags & SFL_BEVEL) || brush->leafnum < 0)
00174         {
00175             //this side is a valid splitter
00176             side->flags |= SFL_VISIBLE;
00177             continue;
00178         } //end if
00179         //assum this side will not be used as a splitter
00180         side->flags &= ~SFL_VISIBLE;
00181         //check if the side plane is used by a visible face
00182         for (i = 0; i < numfaces; i++)
00183         {
00184             face = &dfaces[i];
00185             planenum = dplanes2mapplanes[face->planenum];
00186             if ((planenum & ~1) == (side->planenum & ~1))
00187             {
00188                 //this side is a valid splitter
00189                 side->flags |= SFL_VISIBLE;
00190             } //end if
00191         } //end for
00192     } //end for
00193 } //end of the function MarkVisibleBrushSides

int Q2_BrushContents mapbrush_t b  ) 
 

Definition at line 77 of file map_q2.c.

References b, mapbrush_s::brushnum, side_s::contents, mapbrush_s::entitynum, texinfo_s::flags, i, Log_Print(), mapbrush_t, mapbrush_s::numsides, mapbrush_s::original_sides, s, side_t, SURF_TRANS33, side_s::texinfo, and texinfo.

Referenced by Q2_BSPBrushToMapBrush(), and Q2_ParseBrush().

00078 {
00079     int         contents;
00080     side_t      *s;
00081     int         i;
00082     int         trans;
00083 
00084     s = &b->original_sides[0];
00085     contents = s->contents;
00086     trans = texinfo[s->texinfo].flags;
00087     for (i = 1; i < b->numsides; i++, s++)
00088     {
00089         s = &b->original_sides[i];
00090         trans |= texinfo[s->texinfo].flags;
00091         if (s->contents != contents)
00092         {
00093             Log_Print("Entity %i, Brush %i: mixed face contents\n"
00094                 , b->entitynum, b->brushnum);
00095             Log_Print("texture name = %s\n", texinfo[s->texinfo].texture);
00096             break;
00097         }
00098     }
00099 
00100     // if any side is translucent, mark the contents
00101     // and change solid to window
00102     if ( trans & (SURF_TRANS33|SURF_TRANS66) )
00103     {
00104         contents |= CONTENTS_Q2TRANSLUCENT;
00105         if (contents & CONTENTS_SOLID)
00106         {
00107             contents &= ~CONTENTS_SOLID;
00108             contents |= CONTENTS_WINDOW;
00109         }
00110     }
00111 
00112     return contents;
00113 }

Here is the call graph for this function:

void Q2_BSPBrushToMapBrush dbrush_t bspbrush,
entity_t mapent
 

Definition at line 772 of file map_q2.c.

References AAS_CreateMapBrushes(), b, BrushExists(), mapbrush_s::brushnum, brushsides, brushsidetextured, c_clipbrushes, c_squattbrushes, mapbrush_s::contents, dbrush_t::contents, side_s::contents, CONTENTS_LAVA, CONTENTS_MONSTERCLIP, CONTENTS_PLAYERCLIP, CONTENTS_SLIME, dbrushleafnums, dbrushsides, dplane_t::dist, dplanes, mapbrush_s::entitynum, Error(), FindFloatPlane(), entity_t::firstbrush, dbrush_t::firstside, texinfo_s::flags, side_s::flags, i, k, LAST_VISIBLE_CONTENTS, mapbrush_s::leafnum, Log_Print(), MakeBrushWindings(), mapbrush_t, mapbrushes, mapent, MarkBrushBevels(), n, nodetail, dplane_t::normal, nowater, entity_t::numbrushes, nummapbrushes, nummapbrushsides, mapbrush_s::numsides, dbrush_t::numsides, mapbrush_s::original_sides, side_s::planenum, dbrushside_t::planenum, Q2_BrushContents(), side_t, side_s::surf, SURF_HINT, SURF_TRANS33, side_s::texinfo, texinfo, and dbrushside_t::texinfo.

Referenced by Q2_ParseBSPBrushes().

00773 {
00774     mapbrush_t *b;
00775     int i, k, n;
00776     side_t *side, *s2;
00777     int planenum;
00778     dbrushside_t *bspbrushside;
00779     dplane_t *bspplane;
00780 
00781     if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
00782         Error ("nummapbrushes >= MAX_MAPFILE_BRUSHES");
00783 
00784     b = &mapbrushes[nummapbrushes];
00785     b->original_sides = &brushsides[nummapbrushsides];
00786     b->entitynum = mapent-entities;
00787     b->brushnum = nummapbrushes - mapent->firstbrush;
00788     b->leafnum = dbrushleafnums[bspbrush - dbrushes];
00789 
00790     for (n = 0; n < bspbrush->numsides; n++)
00791     {
00792         //pointer to the bsp brush side
00793         bspbrushside = &dbrushsides[bspbrush->firstside + n];
00794 
00795         if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
00796         {
00797             Error ("MAX_MAPFILE_BRUSHSIDES");
00798         } //end if
00799         //pointer to the map brush side
00800         side = &brushsides[nummapbrushsides];
00801         //if the BSP brush side is textured
00802         if (brushsidetextured[bspbrush->firstside + n]) side->flags |= SFL_TEXTURED;
00803         else side->flags &= ~SFL_TEXTURED;
00804         //ME: can get side contents and surf directly from BSP file
00805         side->contents = bspbrush->contents;
00806         //if the texinfo is TEXINFO_NODE
00807         if (bspbrushside->texinfo < 0) side->surf = 0;
00808         else side->surf = texinfo[bspbrushside->texinfo].flags;
00809 
00810         // translucent objects are automatically classified as detail
00811         if (side->surf & (SURF_TRANS33|SURF_TRANS66) )
00812             side->contents |= CONTENTS_DETAIL;
00813         if (side->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
00814             side->contents |= CONTENTS_DETAIL;
00815         if (fulldetail)
00816             side->contents &= ~CONTENTS_DETAIL;
00817         if (!(side->contents & ((LAST_VISIBLE_CONTENTS-1) 
00818             | CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_MIST)  ) )
00819             side->contents |= CONTENTS_SOLID;
00820 
00821         // hints and skips are never detail, and have no content
00822         if (side->surf & (SURF_HINT|SURF_SKIP) )
00823         {
00824             side->contents = 0;
00825             side->surf &= ~CONTENTS_DETAIL;
00826         }
00827 
00828         //ME: get a plane for this side
00829         bspplane = &dplanes[bspbrushside->planenum];
00830         planenum = FindFloatPlane(bspplane->normal, bspplane->dist);
00831         //
00832         // see if the plane has been used already
00833         //
00834         //ME: this really shouldn't happen!!!
00835         //ME: otherwise the bsp file is corrupted??
00836         //ME: still it seems to happen, maybe Johny Boy's
00837         //ME: brush bevel adding is crappy ?
00838         for (k = 0; k < b->numsides; k++)
00839         {
00840             s2 = b->original_sides + k;
00841 //          if (DotProduct (mapplanes[s2->planenum].normal, mapplanes[planenum].normal) > 0.999
00842 //                          && fabs(mapplanes[s2->planenum].dist - mapplanes[planenum].dist) < 0.01 )
00843 
00844             if (s2->planenum == planenum)
00845             {
00846                 Log_Print("Entity %i, Brush %i: duplicate plane\n"
00847                     , b->entitynum, b->brushnum);
00848                 break;
00849             }
00850             if ( s2->planenum == (planenum^1) )
00851             {
00852                 Log_Print("Entity %i, Brush %i: mirrored plane\n"
00853                     , b->entitynum, b->brushnum);
00854                 break;
00855             }
00856         }
00857         if (k != b->numsides)
00858             continue;       // duplicated
00859 
00860         //
00861         // keep this side
00862         //
00863         //ME: reset pointer to side, why? hell I dunno (pointer is set above already)
00864         side = b->original_sides + b->numsides;
00865         //ME: store the plane number
00866         side->planenum = planenum;
00867         //ME: texinfo is already stored when bsp is loaded
00868         //NOTE: check for TEXINFO_NODE, otherwise crash in Q2_BrushContents
00869         if (bspbrushside->texinfo < 0) side->texinfo = 0;
00870         else side->texinfo = bspbrushside->texinfo;
00871 
00872         // save the td off in case there is an origin brush and we
00873         // have to recalculate the texinfo
00874         // ME: don't need to recalculate because it's already done
00875         //     (for non-world entities) in the BSP file
00876 //      side_brushtextures[nummapbrushsides] = td;
00877 
00878         nummapbrushsides++;
00879         b->numsides++;
00880     } //end for
00881 
00882     // get the content for the entire brush
00883     b->contents = bspbrush->contents;
00884     Q2_BrushContents(b);
00885 
00886     if (BrushExists(b))
00887     {
00888         c_squattbrushes++;
00889         b->numsides = 0;
00890         return;
00891     } //end if
00892 
00893     //if we're creating AAS
00894     if (create_aas)
00895     {
00896         //create the AAS brushes from this brush, don't add brush bevels
00897         AAS_CreateMapBrushes(b, mapent, false);
00898         return;
00899     } //end if
00900 
00901     // allow detail brushes to be removed 
00902     if (nodetail && (b->contents & CONTENTS_DETAIL) )
00903     {
00904         b->numsides = 0;
00905         return;
00906     } //end if
00907 
00908     // allow water brushes to be removed
00909     if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) )
00910     {
00911         b->numsides = 0;
00912         return;
00913     } //end if
00914 
00915     // create windings for sides and bounds for brush
00916     MakeBrushWindings(b);
00917 
00918     //mark brushes without winding or with a tiny window as bevels
00919     MarkBrushBevels(b);
00920 
00921     // brushes that will not be visible at all will never be
00922     // used as bsp splitters
00923     if (b->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
00924     {
00925             c_clipbrushes++;
00926         for (i = 0; i < b->numsides; i++)
00927             b->original_sides[i].texinfo = TEXINFO_NODE;
00928     } //end for
00929 
00930     //
00931     // origin brushes are removed, but they set
00932     // the rotation origin for the rest of the brushes
00933     // in the entity.  After the entire entity is parsed,
00934     // the planenums and texinfos will be adjusted for
00935     // the origin brush
00936     //
00937     //ME: not needed because the entities in the BSP file already
00938     //    have an origin set
00939 //  if (b->contents & CONTENTS_ORIGIN)
00940 //  {
00941 //      char    string[32];
00942 //      vec3_t  origin;
00943 //
00944 //      if (num_entities == 1)
00945 //      {
00946 //          Error ("Entity %i, Brush %i: origin brushes not allowed in world"
00947 //              , b->entitynum, b->brushnum);
00948 //          return;
00949 //      }
00950 //
00951 //      VectorAdd (b->mins, b->maxs, origin);
00952 //      VectorScale (origin, 0.5, origin);
00953 //
00954 //      sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
00955 //      SetKeyValue (&entities[b->entitynum], "origin", string);
00956 //
00957 //      VectorCopy (origin, entities[b->entitynum].origin);
00958 //
00959 //      // don't keep this brush
00960 //      b->numsides = 0;
00961 //
00962 //      return;
00963 //  }
00964 
00965     //ME: the bsp brushes already have bevels, so we won't try to
00966     //    add them again (especially since Johny Boy's bevel adding might
00967     //    be crappy)
00968 //  AddBrushBevels(b);
00969 
00970     nummapbrushes++;
00971     mapent->numbrushes++;
00972 } //end of the function Q2_BSPBrushToMapBrush

Here is the call graph for this function:

void Q2_CreateMapTexinfo void   ) 
 

Definition at line 58 of file map_q2.c.

References texinfo_s::flags, map_texinfo_t::flags, i, map_texinfo, memcpy(), map_texinfo_t::nexttexinfo, strcpy(), texinfo, texture, texinfo_s::value, map_texinfo_t::value, and vecs.

Referenced by Q2_LoadMapFile(), and Q2_LoadMapFromBSP().

00059 {
00060     int i;
00061 
00062     for (i = 0; i < numtexinfo; i++)
00063     {
00064         memcpy(map_texinfo[i].vecs, texinfo[i].vecs, sizeof(float) * 2 * 4);
00065         map_texinfo[i].flags = texinfo[i].flags;
00066         map_texinfo[i].value = texinfo[i].value;
00067         strcpy(map_texinfo[i].texture, texinfo[i].texture);
00068         map_texinfo[i].nexttexinfo = 0;
00069     } //end for
00070 } //end of the function Q2_CreateMapTexinfo

Here is the call graph for this function:

void Q2_InitNodeStack void   ) 
 

Definition at line 678 of file map_q2.c.

References nodestackptr, and nodestacksize.

Referenced by Q2_SetBrushModelNumbers().

00679 {
00680     nodestackptr = nodestack;
00681     nodestacksize = 0;
00682 } //end of the function Q2_InitNodeStack

void Q2_LoadMapFile char *  filename  ) 
 

Definition at line 603 of file map_q2.c.

References AddPointToBounds(), ClearBounds(), entities, FreeScript(), i, loadedmaptype, LoadScriptFile(), Log_Print(), map_maxs, map_mins, mapbrushes, mapbrush_s::mins, num_entities, entity_t::numbrushes, nummapbrushsides, PrintMapInfo(), Q2_CreateMapTexinfo(), Q2_ParseMapEntity(), ResetMapLoading(), SCFL_NOSTRINGESCAPECHARS, SCFL_NOSTRINGWHITESPACES, SCFL_PRIMITIVE, script, and SetScriptFlags().

00604 {       
00605     int i;
00606     script_t *script;
00607 
00608     Log_Print("-- Q2_LoadMapFile --\n");
00609 #ifdef ME
00610     //loaded map type
00611     loadedmaptype = MAPTYPE_QUAKE2;
00612     //reset the map loading
00613     ResetMapLoading();
00614 #endif //ME
00615 
00616     script = LoadScriptFile(filename);
00617     if (!script)
00618     {
00619         Log_Print("couldn't open %s\n", filename);
00620         return;
00621     } //end if
00622     //white spaces and escape characters inside a string are not allowed
00623     SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES |
00624                                     SCFL_NOSTRINGESCAPECHARS |
00625                                     SCFL_PRIMITIVE);
00626 
00627     nummapbrushsides = 0;
00628     num_entities = 0;
00629     
00630     while (Q2_ParseMapEntity(script))
00631     {
00632     }
00633 
00634     ClearBounds (map_mins, map_maxs);
00635     for (i=0 ; i<entities[0].numbrushes ; i++)
00636     {
00637         if (mapbrushes[i].mins[0] > 4096)
00638             continue;   // no valid points
00639         AddPointToBounds (mapbrushes[i].mins, map_mins, map_maxs);
00640         AddPointToBounds (mapbrushes[i].maxs, map_mins, map_maxs);
00641     } //end for
00642 
00643     PrintMapInfo();
00644 
00645     //free the script
00646     FreeScript(script);
00647 //  TestExpandBrushes ();
00648     //
00649     Q2_CreateMapTexinfo();
00650 } //end of the function Q2_LoadMapFile

Here is the call graph for this function:

void Q2_LoadMapFromBSP char *  filename,
int  offset,
int  length
 

Definition at line 1053 of file map_q2.c.

References AddPointToBounds(), brushmodelnumbers, ClearBounds(), entities, i, length(), loadedmaptype, Log_Print(), map_maxs, map_mins, mapbrushes, mapbrush_s::mins, num_entities, entity_t::numbrushes, nummapbrushsides, offset, PrintMapInfo(), Q2_CreateMapTexinfo(), Q2_LoadBSPFile(), Q2_ParseBSPEntity(), and Q2_ParseEntities().

Referenced by LoadMapFromBSP().

01054 {
01055     int i;
01056 
01057     Log_Print("-- Q2_LoadMapFromBSP --\n");
01058     //loaded map type
01059     loadedmaptype = MAPTYPE_QUAKE2;
01060 
01061     Log_Print("Loading map from %s...\n", filename);
01062     //load the bsp file
01063     Q2_LoadBSPFile(filename, offset, length);
01064 
01065     //create an index from bsp planes to map planes
01066     //DPlanes2MapPlanes();
01067     //clear brush model numbers
01068     for (i = 0; i < MAX_MAPFILE_BRUSHES; i++)
01069         brushmodelnumbers[i] = -1;
01070 
01071     nummapbrushsides = 0;
01072     num_entities = 0;
01073 
01074     Q2_ParseEntities();
01075     //
01076     for (i = 0; i < num_entities; i++)
01077     {
01078         Q2_ParseBSPEntity(i);
01079     } //end for
01080 
01081     //get the map mins and maxs from the world model
01082     ClearBounds(map_mins, map_maxs);
01083     for (i = 0; i < entities[0].numbrushes; i++)
01084     {
01085         if (mapbrushes[i].mins[0] > 4096)
01086             continue;   //no valid points
01087         AddPointToBounds (mapbrushes[i].mins, map_mins, map_maxs);
01088         AddPointToBounds (mapbrushes[i].maxs, map_mins, map_maxs);
01089     } //end for
01090 
01091     PrintMapInfo();
01092     //
01093     Q2_CreateMapTexinfo();
01094 } //end of the function Q2_LoadMapFromBSP

Here is the call graph for this function:

void Q2_MoveBrushesToWorld entity_t mapent  ) 
 

Definition at line 448 of file map_q2.c.

References entities, mapbrush_s::entitynum, entity_t::firstbrush, FreeMemory(), GetMemory(), i, mapbrush_t, mapbrushes, mapent, memcpy(), memmove(), entity_t::numbrushes, and nummapbrushes.

Referenced by Q2_ParseMapEntity().

00449 {
00450     int         newbrushes;
00451     int         worldbrushes;
00452     mapbrush_t  *temp;
00453     int         i;
00454 
00455     // this is pretty gross, because the brushes are expected to be
00456     // in linear order for each entity
00457 
00458     newbrushes = mapent->numbrushes;
00459     worldbrushes = entities[0].numbrushes;
00460 
00461     temp = GetMemory(newbrushes*sizeof(mapbrush_t));
00462     memcpy (temp, mapbrushes + mapent->firstbrush, newbrushes*sizeof(mapbrush_t));
00463 
00464 #if 0       // let them keep their original brush numbers
00465     for (i=0 ; i<newbrushes ; i++)
00466         temp[i].entitynum = 0;
00467 #endif
00468 
00469     // make space to move the brushes (overlapped copy)
00470     memmove (mapbrushes + worldbrushes + newbrushes,
00471         mapbrushes + worldbrushes,
00472         sizeof(mapbrush_t) * (nummapbrushes - worldbrushes - newbrushes) );
00473 
00474     // copy the new brushes down
00475     memcpy (mapbrushes + worldbrushes, temp, sizeof(mapbrush_t) * newbrushes);
00476 
00477     // fix up indexes
00478     entities[0].numbrushes += newbrushes;
00479     for (i=1 ; i<num_entities ; i++)
00480         entities[i].firstbrush += newbrushes;
00481     FreeMemory(temp);
00482 
00483     mapent->numbrushes = 0;
00484 }

Here is the call graph for this function:

void Q2_ParseBrush script_t script,
entity_t mapent
 

Definition at line 202 of file map_q2.c.

References AAS_CreateMapBrushes(), AddBrushBevels(), atof(), atol(), b, BrushExists(), mapbrush_s::brushnum, brushsides, c_clipbrushes, c_squattbrushes, mapbrush_s::contents, textureref_t::contents, side_s::contents, CONTENTS_LAVA, CONTENTS_MONSTERCLIP, CONTENTS_PLAYERCLIP, CONTENTS_SLIME, entities, mapbrush_s::entitynum, Error(), FindMiptex(), entity_t::firstbrush, side_s::flags, textureref_t::flags, brush_texture_t::flags, i, token_s::intvalue, j, k, LAST_VISIBLE_CONTENTS, mapbrush_s::leafnum, Log_Print(), MakeBrushWindings(), mapbrush_t, mapbrushes, mapent, mapplanes, mapbrush_s::maxs, mapbrush_s::mins, brush_texture_t::name, nodetail, nowater, num_entities, entity_t::numbrushes, nummapbrushes, nummapbrushsides, mapbrush_s::numsides, mapbrush_s::original_sides, PlaneFromPoints(), side_s::planenum, PS_CheckTokenType(), PS_ExpectAnyToken(), PS_ExpectTokenString(), PS_ExpectTokenType(), PS_ReadToken(), Q2_BrushContents(), brush_texture_t::rotate, brush_texture_t::scale, script, SetKeyValue(), brush_texture_t::shift, side_brushtextures, side_t, sprintf(), strcmp(), strcpy(), string(), token_s::string, side_s::surf, SURF_HINT, SURF_TRANS33, side_s::texinfo, TexinfoForBrushTexture(), textureref, token, token_t, TT_NUMBER, textureref_t::value, brush_texture_t::value, vec3_origin, vec3_t, VectorAdd, VectorCopy, and VectorScale.

Referenced by Q2_ParseMapEntity().

00203 {
00204     mapbrush_t *b;
00205     int i, j, k;
00206     int mt;
00207     side_t *side, *s2;
00208     int planenum;
00209     brush_texture_t td;
00210     int planepts[3][3];
00211     token_t token;
00212 
00213     if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
00214         Error ("nummapbrushes == MAX_MAPFILE_BRUSHES");
00215 
00216     b = &mapbrushes[nummapbrushes];
00217     b->original_sides = &brushsides[nummapbrushsides];
00218     b->entitynum = num_entities-1;
00219     b->brushnum = nummapbrushes - mapent->firstbrush;
00220     b->leafnum = -1;
00221 
00222     do
00223     {
00224         if (!PS_ReadToken(script, &token))
00225             break;
00226         if (!strcmp(token.string, "}") )
00227             break;
00228 
00229         //IDBUG: mixed use of MAX_MAPFILE_? and MAX_MAP_? this could
00230         //          lead to out of bound indexing of the arrays
00231         if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
00232             Error ("MAX_MAPFILE_BRUSHSIDES");
00233         side = &brushsides[nummapbrushsides];
00234 
00235         //read the three point plane definition
00236         for (i = 0; i < 3; i++)
00237         {
00238             if (i != 0) PS_ExpectTokenString(script, "(");
00239             for (j = 0; j < 3; j++)
00240             {
00241                 PS_ExpectAnyToken(script, &token);
00242                 planepts[i][j] = atof(token.string);
00243             } //end for
00244             PS_ExpectTokenString(script, ")");
00245         } //end for
00246 
00247         //
00248         //read the texturedef
00249         //
00250         PS_ExpectAnyToken(script, &token);
00251         strcpy(td.name, token.string);
00252 
00253         PS_ExpectAnyToken(script, &token);
00254         td.shift[0] = atol(token.string);
00255         PS_ExpectAnyToken(script, &token);
00256         td.shift[1] = atol(token.string);
00257         PS_ExpectAnyToken(script, &token);
00258         td.rotate = atol(token.string);
00259         PS_ExpectAnyToken(script, &token);
00260         td.scale[0] = atof(token.string);
00261         PS_ExpectAnyToken(script, &token);
00262         td.scale[1] = atof(token.string);
00263 
00264         //find default flags and values
00265         mt = FindMiptex (td.name);
00266         td.flags = textureref[mt].flags;
00267         td.value = textureref[mt].value;
00268         side->contents = textureref[mt].contents;
00269         side->surf = td.flags = textureref[mt].flags;
00270 
00271         //check if there's a number available
00272         if (PS_CheckTokenType(script, TT_NUMBER, 0, &token))
00273         {
00274             side->contents = token.intvalue;
00275             PS_ExpectTokenType(script, TT_NUMBER, 0, &token);
00276             side->surf = td.flags = token.intvalue;
00277             PS_ExpectTokenType(script, TT_NUMBER, 0, &token);
00278             td.value = token.intvalue;
00279         }
00280 
00281         // translucent objects are automatically classified as detail
00282         if (side->surf & (SURF_TRANS33|SURF_TRANS66) )
00283             side->contents |= CONTENTS_DETAIL;
00284         if (side->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
00285             side->contents |= CONTENTS_DETAIL;
00286         if (fulldetail)
00287             side->contents &= ~CONTENTS_DETAIL;
00288         if (!(side->contents & ((LAST_VISIBLE_CONTENTS-1) 
00289             | CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_MIST)  ) )
00290             side->contents |= CONTENTS_SOLID;
00291 
00292         // hints and skips are never detail, and have no content
00293         if (side->surf & (SURF_HINT|SURF_SKIP) )
00294         {
00295             side->contents = 0;
00296             side->surf &= ~CONTENTS_DETAIL;
00297         }
00298 
00299 #ifdef ME
00300         //for creating AAS... this side is textured
00301         side->flags |= SFL_TEXTURED;
00302 #endif //ME
00303         //
00304         // find the plane number
00305         //
00306         planenum = PlaneFromPoints (planepts[0], planepts[1], planepts[2]);
00307         if (planenum == -1)
00308         {
00309             Log_Print("Entity %i, Brush %i: plane with no normal\n"
00310                 , b->entitynum, b->brushnum);
00311             continue;
00312         }
00313 
00314         //
00315         // see if the plane has been used already
00316         //
00317         for (k=0 ; k<b->numsides ; k++)
00318         {
00319             s2 = b->original_sides + k;
00320             if (s2->planenum == planenum)
00321             {
00322                 Log_Print("Entity %i, Brush %i: duplicate plane\n"
00323                     , b->entitynum, b->brushnum);
00324                 break;
00325             }
00326             if ( s2->planenum == (planenum^1) )
00327             {
00328                 Log_Print("Entity %i, Brush %i: mirrored plane\n"
00329                     , b->entitynum, b->brushnum);
00330                 break;
00331             }
00332         }
00333         if (k != b->numsides)
00334             continue;       // duplicated
00335 
00336         //
00337         // keep this side
00338         //
00339 
00340         side = b->original_sides + b->numsides;
00341         side->planenum = planenum;
00342         side->texinfo = TexinfoForBrushTexture (&mapplanes[planenum],
00343             &td, vec3_origin);
00344 
00345         // save the td off in case there is an origin brush and we
00346         // have to recalculate the texinfo
00347         side_brushtextures[nummapbrushsides] = td;
00348 
00349         nummapbrushsides++;
00350         b->numsides++;
00351     } while (1);
00352 
00353     // get the content for the entire brush
00354     b->contents = Q2_BrushContents (b);
00355 
00356 #ifdef ME
00357     if (BrushExists(b))
00358     {
00359         c_squattbrushes++;
00360         b->numsides = 0;
00361         return;
00362     } //end if
00363 
00364     if (create_aas)
00365     {
00366         //create AAS brushes, and add brush bevels
00367         AAS_CreateMapBrushes(b, mapent, true);
00368         //NOTE: if we return here then duplicate plane errors occur for the non world entities
00369         return;
00370     } //end if
00371 #endif //ME
00372 
00373     // allow detail brushes to be removed 
00374     if (nodetail && (b->contents & CONTENTS_DETAIL) )
00375     {
00376         b->numsides = 0;
00377         return;
00378     }
00379 
00380     // allow water brushes to be removed
00381     if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) )
00382     {
00383         b->numsides = 0;
00384         return;
00385     }
00386 
00387     // create windings for sides and bounds for brush
00388     MakeBrushWindings (b);
00389 
00390     // brushes that will not be visible at all will never be
00391     // used as bsp splitters
00392     if (b->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
00393     {
00394         c_clipbrushes++;
00395         for (i=0 ; i<b->numsides ; i++)
00396             b->original_sides[i].texinfo = TEXINFO_NODE;
00397     }
00398 
00399     //
00400     // origin brushes are removed, but they set
00401     // the rotation origin for the rest of the brushes
00402     // in the entity.  After the entire entity is parsed,
00403     // the planenums and texinfos will be adjusted for
00404     // the origin brush
00405     //
00406     if (b->contents & CONTENTS_ORIGIN)
00407     {
00408         char    string[32];
00409         vec3_t  origin;
00410 
00411         if (num_entities == 1)
00412         {
00413             Error ("Entity %i, Brush %i: origin brushes not allowed in world"
00414                 , b->entitynum, b->brushnum);
00415             return;
00416         }
00417 
00418         VectorAdd (b->mins, b->maxs, origin);
00419         VectorScale (origin, 0.5, origin);
00420 
00421         sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
00422         SetKeyValue (&entities[b->entitynum], "origin", string);
00423 
00424         VectorCopy (origin, entities[b->entitynum].origin);
00425 
00426         // don't keep this brush
00427         b->numsides = 0;
00428 
00429         return;
00430     }
00431 
00432     AddBrushBevels(b);
00433 
00434     nummapbrushes++;
00435     mapent->numbrushes++;       
00436 }

Here is the call graph for this function:

void Q2_ParseBSPBrushes entity_t mapent  ) 
 

Definition at line 975 of file map_q2.c.

References brushmodelnumbers, dbrushes, i, mapent, entity_t::modelnum, Q2_BSPBrushToMapBrush(), and Q2_SetBrushModelNumbers().

Referenced by Q2_ParseBSPEntity().

00976 {
00977     int i;
00978 
00979     //give all the brushes that belong to this entity the number of the
00980     //BSP model used by this entity
00981     Q2_SetBrushModelNumbers(mapent);
00982     //now parse all the brushes with the correct mapent->modelnum
00983     for (i = 0; i < numbrushes; i++)
00984     {
00985         if (brushmodelnumbers[i] == mapent->modelnum)
00986         {
00987             Q2_BSPBrushToMapBrush(&dbrushes[i], mapent);
00988         } //end if
00989     } //end for
00990 } //end of the function Q2_ParseBSPBrushes

Here is the call graph for this function:

qboolean Q2_ParseBSPEntity int  entnum  ) 
 

Definition at line 993 of file map_q2.c.

References entity_t::areaportalnum, atoi, c_areaportals, entities, Error(), entity_t::firstbrush, GetVectorForKey(), mapent, entity_t::modelnum, entity_t::numbrushes, entity_t::origin, Q2_ParseBSPBrushes(), qboolean, strcmp(), strlen(), and ValueForKey().

Referenced by Q2_LoadMapFromBSP().

00994 {
00995     entity_t    *mapent;
00996     char *model;
00997     int startbrush, startsides;
00998 
00999     startbrush = nummapbrushes;
01000     startsides = nummapbrushsides;
01001 
01002     mapent = &entities[entnum];//num_entities];
01003     mapent->firstbrush = nummapbrushes;
01004     mapent->numbrushes = 0;
01005     mapent->modelnum = -1;  //-1 = no model
01006 
01007     model = ValueForKey(mapent, "model");
01008     if (model && strlen(model))
01009     {
01010         if (*model != '*')
01011         {
01012             Error("Q2_ParseBSPEntity: model number without leading *");
01013         } //end if
01014         //get the model number of this entity (skip the leading *)
01015         mapent->modelnum = atoi(&model[1]);
01016     } //end if
01017 
01018     GetVectorForKey(mapent, "origin", mapent->origin);
01019 
01020     //if this is the world entity it has model number zero
01021     //the world entity has no model key
01022     if (!strcmp("worldspawn", ValueForKey(mapent, "classname")))
01023     {
01024         mapent->modelnum = 0;
01025     } //end if
01026     //if the map entity has a BSP model (a modelnum of -1 is used for
01027     //entities that aren't using a BSP model)
01028     if (mapent->modelnum >= 0)
01029     {
01030         //parse the bsp brushes
01031         Q2_ParseBSPBrushes(mapent);
01032     } //end if
01033     //
01034     //the origin of the entity is already taken into account
01035     //
01036     //func_group entities can't be in the bsp file
01037     //
01038     //check out the func_areaportal entities
01039     if (!strcmp ("func_areaportal", ValueForKey (mapent, "classname")))
01040     {
01041         c_areaportals++;
01042         mapent->areaportalnum = c_areaportals;
01043         return true;
01044     } //end if
01045     return true;
01046 } //end of the function Q2_ParseBSPEntity

Here is the call graph for this function:

qboolean Q2_ParseMapEntity script_t script  ) 
 

Definition at line 491 of file map_q2.c.

References entity_t::areaportalnum, b, brushsides, c_areaportals, mapbrush_s::contents,