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

map_q3.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 
00023 #include "qbsp.h"
00024 #include "l_mem.h"
00025 #include "../botlib/aasfile.h"  //aas_bbox_t
00026 #include "aas_store.h"          //AAS_MAX_BBOXES
00027 #include "aas_cfg.h"
00028 #include "aas_map.h"            //AAS_CreateMapBrushes
00029 #include "l_bsp_q3.h"
00030 #include "../qcommon/cm_patch.h"
00031 #include "../game/surfaceflags.h"
00032 
00033 #define NODESTACKSIZE       1024
00034 
00035 //===========================================================================
00036 //
00037 // Parameter:           -
00038 // Returns:             -
00039 // Changes Globals:     -
00040 //===========================================================================
00041 void PrintContents(int contents);
00042 
00043 int Q3_BrushContents(mapbrush_t *b)
00044 {
00045     int contents, i, mixed, hint;
00046     side_t *s;
00047 
00048     s = &b->original_sides[0];
00049     contents = s->contents;
00050     //
00051     mixed = false;
00052     hint = false;
00053     for (i = 1; i < b->numsides; i++)
00054     {
00055         s = &b->original_sides[i];
00056         if (s->contents != contents) mixed = true;
00057         if (s->surf & (SURF_HINT|SURF_SKIP)) hint = true;
00058         contents |= s->contents;
00059     } //end for
00060     //
00061     if (hint)
00062     {
00063         if (contents)
00064         {
00065             Log_Write("WARNING: hint brush with contents: ");
00066             PrintContents(contents);
00067             Log_Write("\r\n");
00068             //
00069             Log_Write("brush contents is: ");
00070             PrintContents(b->contents);
00071             Log_Write("\r\n");
00072         } //end if
00073         return 0;
00074     } //end if
00075     //Log_Write("brush %d contents ", nummapbrushes);
00076     //PrintContents(contents);
00077     //Log_Write("\r\n");
00078     //remove ladder and fog contents
00079     contents &= ~(CONTENTS_LADDER|CONTENTS_FOG);
00080     //
00081     if (mixed)
00082     {
00083         Log_Write("Entity %i, Brush %i: mixed face contents "
00084             , b->entitynum, b->brushnum);
00085         PrintContents(contents);
00086         Log_Write("\r\n");
00087         //
00088         Log_Write("brush contents is: ");
00089         PrintContents(b->contents);
00090         Log_Write("\r\n");
00091         //
00092         if (contents & CONTENTS_DONOTENTER) return CONTENTS_DONOTENTER;//Log_Print("mixed contents with donotenter\n");
00093         /*
00094         Log_Print("contents:"); PrintContents(contents);
00095         Log_Print("\ncontents:"); PrintContents(s->contents);
00096         Log_Print("\n");
00097         Log_Print("texture name = %s\n", texinfo[s->texinfo].texture);
00098         */
00099         //if liquid brush
00100         if (contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER))
00101         {
00102             return (contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER));
00103         } //end if
00104         if (contents & CONTENTS_PLAYERCLIP) return (contents & CONTENTS_PLAYERCLIP);
00105         return (contents & CONTENTS_SOLID);
00106     } //end if
00107     /*
00108     if (contents & CONTENTS_AREAPORTAL)
00109     {
00110         static int num;
00111         Log_Write("Entity %i, Brush %i: area portal %d\r\n", b->entitynum, b->brushnum, num++);
00112     } //end if*/
00113     if (contents == (contents & CONTENTS_STRUCTURAL))
00114     {
00115         //Log_Print("brush %i is only structural\n", b->brushnum);
00116         contents = 0;
00117     } //end if
00118     if (contents & CONTENTS_DONOTENTER)
00119     {
00120         Log_Print("brush %i is a donotenter brush, c = %X\n", b->brushnum, contents);
00121     } //end if
00122     return contents;
00123 } //end of the function Q3_BrushContents
00124 #define BBOX_NORMAL_EPSILON         0.0001
00125 //===========================================================================
00126 //
00127 // Parameter:           -
00128 // Returns:             -
00129 // Changes Globals:     -
00130 //===========================================================================
00131 void Q3_DPlanes2MapPlanes(void)
00132 {
00133     int i;
00134 
00135     for (i = 0; i < q3_numplanes; i++)
00136     {
00137         dplanes2mapplanes[i] = FindFloatPlane(q3_dplanes[i].normal, q3_dplanes[i].dist);
00138     } //end for
00139 } //end of the function Q3_DPlanes2MapPlanes
00140 //===========================================================================
00141 //
00142 // Parameter:           -
00143 // Returns:             -
00144 // Changes Globals:     -
00145 //===========================================================================
00146 void Q3_BSPBrushToMapBrush(q3_dbrush_t *bspbrush, entity_t *mapent)
00147 {
00148     mapbrush_t *b;
00149     int i, k, n;
00150     side_t *side, *s2;
00151     int planenum;
00152     q3_dbrushside_t *bspbrushside;
00153     q3_dplane_t *bspplane;
00154 
00155     if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
00156         Error ("nummapbrushes >= MAX_MAPFILE_BRUSHES");
00157 
00158     b = &mapbrushes[nummapbrushes];
00159     b->original_sides = &brushsides[nummapbrushsides];
00160     b->entitynum = mapent-entities;
00161     b->brushnum = nummapbrushes - mapent->firstbrush;
00162     b->leafnum = dbrushleafnums[bspbrush - q3_dbrushes];
00163 
00164     for (n = 0; n < bspbrush->numSides; n++)
00165     {
00166         //pointer to the bsp brush side
00167         bspbrushside = &q3_dbrushsides[bspbrush->firstSide + n];
00168 
00169         if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
00170         {
00171             Error ("MAX_MAPFILE_BRUSHSIDES");
00172         } //end if
00173         //pointer to the map brush side
00174         side = &brushsides[nummapbrushsides];
00175         //if the BSP brush side is textured
00176         if (q3_dbrushsidetextured[bspbrush->firstSide + n]) side->flags |= SFL_TEXTURED|SFL_VISIBLE;
00177         else side->flags &= ~SFL_TEXTURED;
00178         //NOTE: all Quake3 sides are assumed textured
00179         //side->flags |= SFL_TEXTURED|SFL_VISIBLE;
00180         //
00181         if (bspbrushside->shaderNum < 0)
00182         {
00183             side->contents = 0;
00184             side->surf = 0;
00185         } //end if
00186         else
00187         {
00188             side->contents = q3_dshaders[bspbrushside->shaderNum].contentFlags;
00189             side->surf = q3_dshaders[bspbrushside->shaderNum].surfaceFlags;
00190             if (strstr(q3_dshaders[bspbrushside->shaderNum].shader, "common/hint"))
00191             {
00192                 //Log_Print("found hint side\n");
00193                 side->surf |= SURF_HINT;
00194             } //end if
00195         } //end else
00196         //
00197         if (side->surf & SURF_NODRAW)
00198         {
00199             side->flags |= SFL_TEXTURED|SFL_VISIBLE;
00200         } //end if
00201         /*
00202         if (side->contents & (CONTENTS_TRANSLUCENT|CONTENTS_STRUCTURAL))
00203         {
00204             side->flags |= SFL_TEXTURED|SFL_VISIBLE;
00205         } //end if*/
00206 
00207         // hints and skips are never detail, and have no content
00208         if (side->surf & (SURF_HINT|SURF_SKIP) )
00209         {
00210             side->contents = 0;
00211             //Log_Print("found hint brush side\n");
00212         }
00213         /*
00214         if ((side->surf & SURF_NODRAW) && (side->surf & SURF_NOIMPACT))
00215         {
00216             side->contents = 0;
00217             side->surf &= ~CONTENTS_DETAIL;
00218             Log_Print("probably found hint brush in a BSP without hints being used\n");
00219         } //end if*/
00220 
00221         //ME: get a plane for this side
00222         bspplane = &q3_dplanes[bspbrushside->planeNum];
00223         planenum = FindFloatPlane(bspplane->normal, bspplane->dist);
00224         //
00225         // see if the plane has been used already
00226         //
00227         //ME: this really shouldn't happen!!!
00228         //ME: otherwise the bsp file is corrupted??
00229         //ME: still it seems to happen, maybe Johny Boy's
00230         //ME: brush bevel adding is crappy ?
00231         for (k = 0; k < b->numsides; k++)
00232         {
00233             s2 = b->original_sides + k;
00234 //          if (DotProduct (mapplanes[s2->planenum].normal, mapplanes[planenum].normal) > 0.999
00235 //                          && fabs(mapplanes[s2->planenum].dist - mapplanes[planenum].dist) < 0.01 )
00236 
00237             if (s2->planenum == planenum)
00238             {
00239                 Log_Print("Entity %i, Brush %i: duplicate plane\n"
00240                     , b->entitynum, b->brushnum);
00241                 break;
00242             }
00243             if ( s2->planenum == (planenum^1) )
00244             {
00245                 Log_Print("Entity %i, Brush %i: mirrored plane\n"
00246                     , b->entitynum, b->brushnum);
00247                 break;
00248             }
00249         }
00250         if (k != b->numsides)
00251             continue;       // duplicated
00252 
00253         //
00254         // keep this side
00255         //
00256         //ME: reset pointer to side, why? hell I dunno (pointer is set above already)
00257         side = b->original_sides + b->numsides;
00258         //ME: store the plane number
00259         side->planenum = planenum;
00260         //ME: texinfo is already stored when bsp is loaded
00261         //NOTE: check for TEXINFO_NODE, otherwise crash in Q3_BrushContents
00262         //if (bspbrushside->texinfo < 0) side->texinfo = 0;
00263         //else side->texinfo = bspbrushside->texinfo;
00264 
00265         // save the td off in case there is an origin brush and we
00266         // have to recalculate the texinfo
00267         // ME: don't need to recalculate because it's already done
00268         //     (for non-world entities) in the BSP file
00269 //      side_brushtextures[nummapbrushsides] = td;
00270 
00271         nummapbrushsides++;
00272         b->numsides++;
00273     } //end for
00274 
00275     // get the content for the entire brush
00276     b->contents = q3_dshaders[bspbrush->shaderNum].contentFlags;
00277     b->contents &= ~(CONTENTS_LADDER|CONTENTS_FOG|CONTENTS_STRUCTURAL);
00278 //  b->contents = Q3_BrushContents(b);
00279     //
00280 
00281     if (BrushExists(b))
00282     {
00283         c_squattbrushes++;
00284         b->numsides = 0;
00285         return;
00286     } //end if
00287 
00288     //if we're creating AAS
00289     if (create_aas)
00290     {
00291         //create the AAS brushes from this brush, don't add brush bevels
00292         AAS_CreateMapBrushes(b, mapent, false);
00293         return;
00294     } //end if
00295 
00296     // allow detail brushes to be removed 
00297     if (nodetail && (b->contents & CONTENTS_DETAIL) )
00298     {
00299         b->numsides = 0;
00300         return;
00301     } //end if
00302 
00303     // allow water brushes to be removed
00304     if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) )
00305     {
00306         b->numsides = 0;
00307         return;
00308     } //end if
00309 
00310     // create windings for sides and bounds for brush
00311     MakeBrushWindings(b);
00312 
00313     //mark brushes without winding or with a tiny window as bevels
00314     MarkBrushBevels(b);
00315 
00316     // brushes that will not be visible at all will never be
00317     // used as bsp splitters
00318     if (b->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
00319     {
00320             c_clipbrushes++;
00321         for (i = 0; i < b->numsides; i++)
00322             b->original_sides[i].texinfo = TEXINFO_NODE;
00323     } //end for
00324 
00325     //
00326     // origin brushes are removed, but they set
00327     // the rotation origin for the rest of the brushes
00328     // in the entity.  After the entire entity is parsed,
00329     // the planenums and texinfos will be adjusted for
00330     // the origin brush
00331     //
00332     //ME: not needed because the entities in the BSP file already
00333     //    have an origin set
00334 //  if (b->contents & CONTENTS_ORIGIN)
00335 //  {
00336 //      char    string[32];
00337 //      vec3_t  origin;
00338 //
00339 //      if (num_entities == 1)
00340 //      {
00341 //          Error ("Entity %i, Brush %i: origin brushes not allowed in world"
00342 //              , b->entitynum, b->brushnum);
00343 //          return;
00344 //      }
00345 //
00346 //      VectorAdd (b->mins, b->maxs, origin);
00347 //      VectorScale (origin, 0.5, origin);
00348 //
00349 //      sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
00350 //      SetKeyValue (&entities[b->entitynum], "origin", string);
00351 //
00352 //      VectorCopy (origin, entities[b->entitynum].origin);
00353 //
00354 //      // don't keep this brush
00355 //      b->numsides = 0;
00356 //
00357 //      return;
00358 //  }
00359 
00360     //ME: the bsp brushes already have bevels, so we won't try to
00361     //    add them again (especially since Johny Boy's bevel adding might
00362     //    be crappy)
00363 //  AddBrushBevels(b);
00364 
00365     nummapbrushes++;
00366     mapent->numbrushes++;
00367 } //end of the function Q3_BSPBrushToMapBrush
00368 //===========================================================================
00369 //
00370 // Parameter:           -
00371 // Returns:             -
00372 // Changes Globals:     -
00373 //===========================================================================
00374 void Q3_ParseBSPBrushes(entity_t *mapent)
00375 {
00376     int i;
00377 
00378     for (i = 0; i < q3_dmodels[mapent->modelnum].numBrushes; i++)
00379     {
00380         Q3_BSPBrushToMapBrush(&q3_dbrushes[q3_dmodels[mapent->modelnum].firstBrush + i], mapent);
00381     } //end for
00382 } //end of the function Q3_ParseBSPBrushes
00383 //===========================================================================
00384 //
00385 // Parameter:           -
00386 // Returns:             -
00387 // Changes Globals:     -
00388 //===========================================================================
00389 qboolean Q3_ParseBSPEntity(int entnum)
00390 {
00391     entity_t *mapent;
00392     char *model;
00393     int startbrush, startsides;
00394 
00395     startbrush = nummapbrushes;
00396     startsides = nummapbrushsides;
00397 
00398     mapent = &entities[entnum];//num_entities];
00399     mapent->firstbrush = nummapbrushes;
00400     mapent->numbrushes = 0;
00401     mapent->modelnum = -1;  //-1 = no BSP model
00402 
00403     model = ValueForKey(mapent, "model");
00404     if (model && strlen(model))
00405     {
00406         if (*model == '*')
00407         {
00408             //get the model number of this entity (skip the leading *)
00409             mapent->modelnum = atoi(&model[1]);
00410         } //end if
00411     } //end if
00412 
00413     GetVectorForKey(mapent, "origin", mapent->origin);
00414 
00415     //if this is the world entity it has model number zero
00416     //the world entity has no model key
00417     if (!strcmp("worldspawn", ValueForKey(mapent, "classname")))
00418     {
00419         mapent->modelnum = 0;
00420     } //end if
00421     //if the map entity has a BSP model (a modelnum of -1 is used for
00422     //entities that aren't using a BSP model)
00423     if (mapent->modelnum >= 0)
00424     {
00425         //parse the bsp brushes
00426         Q3_ParseBSPBrushes(mapent);
00427     } //end if
00428     //
00429     //the origin of the entity is already taken into account
00430     //
00431     //func_group entities can't be in the bsp file
00432     //
00433     //check out the func_areaportal entities
00434     if (!strcmp ("func_areaportal", ValueForKey (mapent, "classname")))
00435     {
00436         c_areaportals++;
00437         mapent->areaportalnum = c_areaportals;
00438         return true;
00439     } //end if
00440     return true;
00441 } //end of the function Q3_ParseBSPEntity
00442 //===========================================================================
00443 //
00444 // Parameter:           -
00445 // Returns:             -
00446 // Changes Globals:     -
00447 //===========================================================================
00448 #define MAX_PATCH_VERTS     1024
00449 
00450 void AAS_CreateCurveBrushes(void)
00451 {
00452     int i, j, n, planenum, numcurvebrushes = 0;
00453     q3_dsurface_t *surface;
00454     q3_drawVert_t *dv_p;
00455     vec3_t points[MAX_PATCH_VERTS];
00456     int width, height, c;
00457     patchCollide_t *pc;
00458     facet_t *facet;
00459     mapbrush_t *brush;
00460     side_t *side;
00461     entity_t *mapent;
00462     winding_t *winding;
00463 
00464     qprintf("nummapbrushsides = %d\n", nummapbrushsides);
00465     mapent = &entities[0];
00466     for (i = 0; i < q3_numDrawSurfaces; i++)
00467     {
00468         surface = &q3_drawSurfaces[i];
00469         if ( ! surface->patchWidth ) continue;
00470         // if the curve is not solid
00471         if (!(q3_dshaders[surface->shaderNum].contentFlags & (CONTENTS_SOLID|CONTENTS_PLAYERCLIP)))
00472         {
00473             //Log_Print("skipped non-solid curve\n");
00474             continue;
00475         } //end if
00476         // if this curve should not be used for AAS
00477         if ( q3_dshaders[surface->shaderNum].contentFlags & CONTENTS_NOBOTCLIP ) {
00478             continue;
00479         }
00480         //
00481         width = surface->patchWidth;
00482         height = surface->patchHeight;
00483         c = width * height;
00484         if (c > MAX_PATCH_VERTS)
00485         {
00486             Error("ParseMesh: MAX_PATCH_VERTS");
00487         } //end if
00488 
00489         dv_p = q3_drawVerts + surface->firstVert;
00490         for ( j = 0 ; j < c ; j++, dv_p++ )
00491         {
00492             points[j][0] = dv_p->xyz[0];
00493             points[j][1] = dv_p->xyz[1];
00494             points[j][2] = dv_p->xyz[2];
00495         } //end for
00496         // create the internal facet structure
00497         pc = CM_GeneratePatchCollide(width, height, points);
00498         //
00499         for (j = 0; j < pc->numFacets; j++)
00500         {
00501             facet = &pc->facets[j];
00502             //
00503             brush = &mapbrushes[nummapbrushes];
00504             brush->original_sides = &brushsides[nummapbrushsides];
00505             brush->entitynum = 0;
00506             brush->brushnum = nummapbrushes - mapent->firstbrush;
00507             //
00508             brush->numsides = facet->numBorders + 2;
00509             nummapbrushsides += brush->numsides;
00510             brush->contents = CONTENTS_SOLID;
00511             //
00512             //qprintf("\r%6d curve brushes", nummapbrushsides);//++numcurvebrushes);
00513             qprintf("\r%6d curve brushes", ++numcurvebrushes);
00514             //
00515             planenum = FindFloatPlane(pc->planes[facet->surfacePlane].plane, pc->planes[facet->surfacePlane].plane[3]);
00516             //
00517             side = &brush->original_sides[0];
00518             side->planenum = planenum;
00519             side->contents = CONTENTS_SOLID;
00520             side->flags |= SFL_TEXTURED|SFL_VISIBLE|SFL_CURVE;
00521             side->surf = 0;
00522             //
00523             side = &brush->original_sides[1];
00524             if (create_aas)
00525             {
00526                 //the plane is expanded later so it's not a problem that
00527                 //these first two opposite sides are coplanar
00528                 side->planenum = planenum ^ 1;
00529             } //end if
00530             else
00531             {
00532                 side->planenum = FindFloatPlane(mapplanes[planenum^1].normal, mapplanes[planenum^1].dist + 1);
00533                 side->flags |= SFL_TEXTURED|SFL_VISIBLE;
00534             } //end else
00535             side->contents = CONTENTS_SOLID;
00536             side->flags |= SFL_CURVE;
00537             side->surf = 0;
00538             //
00539             winding = BaseWindingForPlane(mapplanes[side->planenum].normal, mapplanes[side->planenum].dist);
00540             for (n = 0; n < facet->numBorders; n++)
00541             {
00542                 //never use the surface plane as a border
00543                 if (facet->borderPlanes[n] == facet->surfacePlane) continue;
00544                 //
00545                 side = &brush->original_sides[2 + n];
00546                 side->planenum = FindFloatPlane(pc->planes[facet->borderPlanes[n]].plane, pc->planes[facet->borderPlanes[n]].plane[3]);
00547                 if (facet->borderInward[n]) side->planenum ^= 1;
00548                 side->contents = CONTENTS_SOLID;
00549                 side->flags |= SFL_TEXTURED|SFL_CURVE;
00550                 side->surf = 0;
00551                 //chop the winding in place
00552                 if (winding) ChopWindingInPlace(&winding, mapplanes[side->planenum^1].normal, mapplanes[side->planenum^1].dist, 0.1); //CLIP_EPSILON);
00553             } //end for
00554             //VectorCopy(pc->bounds[0], brush->mins);
00555             //VectorCopy(pc->bounds[1], brush->maxs);
00556             if (!winding)
00557             {
00558                 Log_Print("WARNING: AAS_CreateCurveBrushes: no winding\n");
00559                 brush->numsides = 0;
00560                 continue;
00561             } //end if
00562             brush->original_sides[0].winding = winding;
00563             WindingBounds(winding, brush->mins, brush->maxs);
00564             for (n = 0; n < 3; n++)
00565             {
00566                 //IDBUG: all the indexes into the mins and maxs were zero (not using i)
00567                 if (brush->mins[n] < -MAX_MAP_BOUNDS || brush->maxs[n] > MAX_MAP_BOUNDS)
00568                 {
00569                     Log_Print("entity %i, brush %i: bounds out of range\n", brush->entitynum, brush->brushnum);
00570                     Log_Print("brush->mins[%d] = %f, brush->maxs[%d] = %f\n", n, brush->mins[n], n, brush->maxs[n]);
00571                     brush->numsides = 0; //remove the brush
00572                     break;
00573                 } //end if
00574                 if (brush->mins[n] > MAX_MAP_BOUNDS || brush->maxs[n] < -MAX_MAP_BOUNDS)
00575                 {
00576                     Log_Print("entity %i, brush %i: no visible sides on brush\n", brush->entitynum, brush->brushnum);
00577                     Log_Print("brush->mins[%d] = %f, brush->maxs[%d] = %f\n", n, brush->mins[n], n, brush->maxs[n]);
00578                     brush->numsides = 0; //remove the brush
00579                     break;
00580                 } //end if
00581             } //end for
00582             if (create_aas)
00583             {
00584                 //NOTE: brush bevels now already added
00585                 //AddBrushBevels(brush);
00586                 AAS_CreateMapBrushes(brush, mapent, false);
00587             } //end if
00588             else
00589             {
00590                 // create windings for sides and bounds for brush
00591                 MakeBrushWindings(brush);
00592                 AddBrushBevels(brush);
00593                 nummapbrushes++;
00594                 mapent->numbrushes++;
00595             } //end else
00596         } //end for
00597     } //end for
00598     //qprintf("\r%6d curve brushes", nummapbrushsides);//++numcurvebrushes);
00599     qprintf("\r%6d curve brushes\n", numcurvebrushes);
00600 } //end of the function AAS_CreateCurveBrushes
00601 //===========================================================================
00602 //
00603 // Parameter:           -
00604 // Returns:             -
00605 // Changes Globals:     -
00606 //===========================================================================
00607 void AAS_ExpandMapBrush(mapbrush_t *brush, vec3_t mins, vec3_t maxs);
00608 
00609 void Q3_LoadMapFromBSP(struct quakefile_s *qf)
00610 {
00611     int i;
00612     vec3_t mins = {-1,-1,-1}, maxs = {1, 1, 1};
00613 
00614     Log_Print("-- Q3_LoadMapFromBSP --\n");
00615     //loaded map type
00616     loadedmaptype = MAPTYPE_QUAKE3;
00617 
00618     Log_Print("Loading map from %s...\n", qf->filename);
00619     //load the bsp file
00620     Q3_LoadBSPFile(qf);
00621 
00622     //create an index from bsp planes to map planes
00623     //DPlanes2MapPlanes();
00624     //clear brush model numbers
00625     for (i = 0; i < MAX_MAPFILE_BRUSHES; i++)
00626         brushmodelnumbers[i] = -1;
00627 
00628     nummapbrushsides = 0;
00629     num_entities = 0;
00630 
00631     Q3_ParseEntities();
00632     //
00633     for (i = 0; i < num_entities; i++)
00634     {
00635         Q3_ParseBSPEntity(i);
00636     } //end for
00637 
00638     AAS_CreateCurveBrushes();
00639     //get the map mins and maxs from the world model
00640     ClearBounds(map_mins, map_maxs);
00641     for (i = 0; i < entities[0].numbrushes; i++)
00642     {
00643         if (mapbrushes[i].numsides <= 0)
00644             continue;
00645         AddPointToBounds (mapbrushes[i].mins, map_mins, map_maxs);
00646         AddPointToBounds (mapbrushes[i].maxs, map_mins, map_maxs);
00647     } //end for
00648     /*/
00649     for (i = 0; i < nummapbrushes; i++)
00650     {
00651         //if (!mapbrushes[i].original_sides) continue;
00652         //AddBrushBevels(&mapbrushes[i]);
00653         //AAS_ExpandMapBrush(&mapbrushes[i], mins, maxs);
00654     } //end for*/
00655     /*
00656     for (i = 0; i < nummapbrushsides; i++)
00657     {
00658         Log_Write("side %d flags = %d", i, brushsides[i].flags);
00659     } //end for
00660     for (i = 0; i < nummapbrushes; i++)
00661     {
00662         Log_Write("brush contents: ");
00663         PrintContents(mapbrushes[i].contents);
00664         Log_Print("\n");
00665     } //end for*/
00666 } //end of the function Q3_LoadMapFromBSP
00667 //===========================================================================
00668 //
00669 // Parameter:           -
00670 // Returns:             -
00671 // Changes Globals:     -
00672 //===========================================================================
00673 void Q3_ResetMapLoading(void)
00674 {
00675     //reset for map loading from bsp
00676     memset(nodestack, 0, NODESTACKSIZE * sizeof(int));
00677     nodestackptr = NULL;
00678     nodestacksize = 0;
00679     memset(brushmodelnumbers, 0, MAX_MAPFILE_BRUSHES * sizeof(int));
00680 } //end of the function Q3_ResetMapLoading
00681 

Generated on Thu Aug 25 12:37:18 2005 for Quake III Arena by  doxygen 1.3.9.1