aboutsummaryrefslogtreecommitdiffstats
path: root/q3map/map.c
diff options
context:
space:
mode:
authortma <tma@edf5b092-35ff-0310-97b2-ce42778d08ea>2005-09-28 18:55:31 +0000
committertma <tma@edf5b092-35ff-0310-97b2-ce42778d08ea>2005-09-28 18:55:31 +0000
commitec912002d3f75729c627cf467903c4607a529495 (patch)
treeb944aa3ec6a159d4607b3bb25cb09640bca02ddb /q3map/map.c
parentea1ca0473a510a02fff82788a2a6c8d95a6bf2d3 (diff)
downloadioquake3-aero-ec912002d3f75729c627cf467903c4607a529495.tar.gz
ioquake3-aero-ec912002d3f75729c627cf467903c4607a529495.zip
* Removed q3map and associated common and libs directories
git-svn-id: svn://svn.icculus.org/quake3/trunk@123 edf5b092-35ff-0310-97b2-ce42778d08ea
Diffstat (limited to 'q3map/map.c')
-rw-r--r--q3map/map.c1251
1 files changed, 0 insertions, 1251 deletions
diff --git a/q3map/map.c b/q3map/map.c
deleted file mode 100644
index 3de6ede..0000000
--- a/q3map/map.c
+++ /dev/null
@@ -1,1251 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code 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.
-
-Quake III Arena source code 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 Foobar; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-// map.c
-
-#include "qbsp.h"
-
-
-int entitySourceBrushes; // to track editor brush numbers
-
-int numMapPatches;
-
-// undefine to make plane finding use linear sort
-#define USE_HASHING
-#define PLANE_HASHES 1024
-plane_t *planehash[PLANE_HASHES];
-
-plane_t mapplanes[MAX_MAP_PLANES];
-int nummapplanes;
-
-// as brushes and patches are read in, the shaders are stored out in order
-// here, so -onlytextures can just copy them out over the existing shaders
-// in the drawSurfaces
-char mapIndexedShaders[MAX_MAP_BRUSHSIDES][MAX_QPATH];
-int numMapIndexedShaders;
-
-vec3_t map_mins, map_maxs;
-
-entity_t *mapent;
-
-
-
-int c_boxbevels;
-int c_edgebevels;
-
-int c_areaportals;
-int c_detail;
-int c_structural;
-
-// brushes are parsed into a temporary array of sides,
-// which will have the bevels added and duplicates
-// removed before the final brush is allocated
-bspbrush_t *buildBrush;
-
-
-void TestExpandBrushes (void);
-void SetTerrainTextures( void );
-void ParseTerrain( void );
-
-
-/*
-=============================================================================
-
-PLANE FINDING
-
-=============================================================================
-*/
-
-
-/*
-================
-PlaneEqual
-================
-*/
-#define NORMAL_EPSILON 0.00001
-#define DIST_EPSILON 0.01
-qboolean PlaneEqual (plane_t *p, vec3_t normal, vec_t dist)
-{
-#if 1
- if (
- fabs(p->normal[0] - normal[0]) < NORMAL_EPSILON
- && fabs(p->normal[1] - normal[1]) < NORMAL_EPSILON
- && fabs(p->normal[2] - normal[2]) < NORMAL_EPSILON
- && fabs(p->dist - dist) < DIST_EPSILON )
- return qtrue;
-#else
- if (p->normal[0] == normal[0]
- && p->normal[1] == normal[1]
- && p->normal[2] == normal[2]
- && p->dist == dist)
- return qtrue;
-#endif
- return qfalse;
-}
-
-/*
-================
-AddPlaneToHash
-================
-*/
-void AddPlaneToHash (plane_t *p)
-{
- int hash;
-
- hash = (int)fabs(p->dist) / 8;
- hash &= (PLANE_HASHES-1);
-
- p->hash_chain = planehash[hash];
- planehash[hash] = p;
-}
-
-/*
-================
-CreateNewFloatPlane
-================
-*/
-int CreateNewFloatPlane (vec3_t normal, vec_t dist)
-{
- plane_t *p, temp;
-
- if (VectorLength(normal) < 0.5)
- {
- _printf( "FloatPlane: bad normal\n");
- return -1;
- }
-
- // create a new plane
- if (nummapplanes+2 > MAX_MAP_PLANES)
- Error ("MAX_MAP_PLANES");
-
- p = &mapplanes[nummapplanes];
- VectorCopy (normal, p->normal);
- p->dist = dist;
- p->type = (p+1)->type = PlaneTypeForNormal (p->normal);
-
- VectorSubtract (vec3_origin, normal, (p+1)->normal);
- (p+1)->dist = -dist;
-
- nummapplanes += 2;
-
- // allways put axial planes facing positive first
- if (p->type < 3)
- {
- if (p->normal[0] < 0 || p->normal[1] < 0 || p->normal[2] < 0)
- {
- // flip order
- temp = *p;
- *p = *(p+1);
- *(p+1) = temp;
-
- AddPlaneToHash (p);
- AddPlaneToHash (p+1);
- return nummapplanes - 1;
- }
- }
-
- AddPlaneToHash (p);
- AddPlaneToHash (p+1);
- return nummapplanes - 2;
-}
-
-/*
-==============
-SnapVector
-==============
-*/
-void SnapVector (vec3_t normal)
-{
- int i;
-
- for (i=0 ; i<3 ; i++)
- {
- if ( fabs(normal[i] - 1) < NORMAL_EPSILON )
- {
- VectorClear (normal);
- normal[i] = 1;
- break;
- }
- if ( fabs(normal[i] - -1) < NORMAL_EPSILON )
- {
- VectorClear (normal);
- normal[i] = -1;
- break;
- }
- }
-}
-
-/*
-==============
-SnapPlane
-==============
-*/
-void SnapPlane (vec3_t normal, vec_t *dist)
-{
- SnapVector (normal);
-
- if (fabs(*dist-Q_rint(*dist)) < DIST_EPSILON)
- *dist = Q_rint(*dist);
-}
-
-/*
-=============
-FindFloatPlane
-
-=============
-*/
-#ifndef USE_HASHING
-int FindFloatPlane (vec3_t normal, vec_t dist)
-{
- int i;
- plane_t *p;
-
- SnapPlane (normal, &dist);
- for (i=0, p=mapplanes ; i<nummapplanes ; i++, p++)
- {
- if (PlaneEqual (p, normal, dist))
- return i;
- }
-
- return CreateNewFloatPlane (normal, dist);
-}
-#else
-int FindFloatPlane (vec3_t normal, vec_t dist)
-{
- int i;
- plane_t *p;
- int hash, h;
-
- SnapPlane (normal, &dist);
- hash = (int)fabs(dist) / 8;
- hash &= (PLANE_HASHES-1);
-
- // search the border bins as well
- for (i=-1 ; i<=1 ; i++)
- {
- h = (hash+i)&(PLANE_HASHES-1);
- for (p = planehash[h] ; p ; p=p->hash_chain)
- {
- if (PlaneEqual (p, normal, dist))
- return p-mapplanes;
- }
- }
-
- return CreateNewFloatPlane (normal, dist);
-}
-#endif
-
-/*
-================
-MapPlaneFromPoints
-================
-*/
-int MapPlaneFromPoints (vec3_t p0, vec3_t p1, vec3_t p2) {
- vec3_t t1, t2, normal;
- vec_t dist;
-
- VectorSubtract (p0, p1, t1);
- VectorSubtract (p2, p1, t2);
- CrossProduct (t1, t2, normal);
- VectorNormalize (normal, normal);
-
- dist = DotProduct (p0, normal);
-
- return FindFloatPlane (normal, dist);
-}
-
-
-//====================================================================
-
-/*
-===========
-SetBrushContents
-
-The contents on all sides of a brush should be the same
-Sets contentsShader, contents, opaque, and detail
-===========
-*/
-void SetBrushContents( bspbrush_t *b ) {
- int contents, c2;
- side_t *s;
- int i;
- qboolean mixed;
- int allFlags;
-
- s = &b->sides[0];
- contents = s->contents;
- b->contentShader = s->shaderInfo;
- mixed = qfalse;
-
- allFlags = 0;
-
- for ( i=1 ; i<b->numsides ; i++, s++ ) {
- s = &b->sides[i];
-
- if ( !s->shaderInfo ) {
- continue;
- }
-
- c2 = s->contents;
- if (c2 != contents) {
- mixed = qtrue;
- }
-
- allFlags |= s->surfaceFlags;
- }
-
- if ( mixed ) {
- qprintf ("Entity %i, Brush %i: mixed face contents\n"
- , b->entitynum, b->brushnum);
- }
-
- if ( ( contents & CONTENTS_DETAIL ) && ( contents & CONTENTS_STRUCTURAL ) ) {
- _printf ("Entity %i, Brush %i: mixed CONTENTS_DETAIL and CONTENTS_STRUCTURAL\n"
- , num_entities-1, entitySourceBrushes );
- contents &= ~CONTENTS_DETAIL;
- }
-
- // the fulldetail flag will cause detail brushes to be
- // treated like normal brushes
- if ( fulldetail ) {
- contents &= ~CONTENTS_DETAIL;
- }
-
- // all translucent brushes that aren't specirically made structural will
- // be detail
- if ( ( contents & CONTENTS_TRANSLUCENT ) && !( contents & CONTENTS_STRUCTURAL ) ) {
- contents |= CONTENTS_DETAIL;
- }
-
- if ( contents & CONTENTS_DETAIL ) {
- c_detail++;
- b->detail = qtrue;
- } else {
- c_structural++;
- b->detail = qfalse;
- }
-
- if ( contents & CONTENTS_TRANSLUCENT ) {
- b->opaque = qfalse;
- } else {
- b->opaque = qtrue;
- }
-
- if ( contents & CONTENTS_AREAPORTAL ) {
- c_areaportals++;
- }
-
- b->contents = contents;
-}
-
-
-//============================================================================
-
-/*
-=================
-AddBrushBevels
-
-Adds any additional planes necessary to allow the brush being
-built to be expanded against axial bounding boxes
-=================
-*/
-void AddBrushBevels( void ) {
- int axis, dir;
- int i, order;
- side_t sidetemp;
- side_t *s;
- vec3_t normal;
- float dist;
-
- //
- // add the axial planes
- //
- order = 0;
- for (axis=0 ; axis <3 ; axis++)
- {
- for (dir=-1 ; dir <= 1 ; dir+=2, order++)
- {
- // see if the plane is allready present
- for ( i=0, s=buildBrush->sides ; i < buildBrush->numsides ; i++,s++ ) {
- if (mapplanes[s->planenum].normal[axis] == dir)
- break;
- }
-
- if (i == buildBrush->numsides )
- { // add a new side
- if ( buildBrush->numsides == MAX_BUILD_SIDES ) {
- Error( "MAX_BUILD_SIDES" );
- }
- memset( s, 0, sizeof( *s ) );
- buildBrush->numsides++;
- VectorClear (normal);
- normal[axis] = dir;
- if (dir == 1)
- dist = buildBrush->maxs[axis];
- else
- dist = -buildBrush->mins[axis];
- s->planenum = FindFloatPlane (normal, dist);
- s->contents = buildBrush->sides[0].contents;
- s->bevel = qtrue;
- c_boxbevels++;
- }
-
- // if the plane is not in it canonical order, swap it
- if (i != order)
- {
- sidetemp = buildBrush->sides[order];
- buildBrush->sides[order] = buildBrush->sides[i];
- buildBrush->sides[i] = sidetemp;
- }
- }
- }
-
- //
- // add the edge bevels
- //
- if ( buildBrush->numsides == 6 ) {
- return; // pure axial
- } else {
- int j, k, l;
- float d;
- winding_t *w, *w2;
- side_t *s2;
- vec3_t vec, vec2;
-
- // test the non-axial plane edges
- // this code tends to cause some problems...
- for (i=6 ; i<buildBrush->numsides ; i++)
- {
- s = buildBrush->sides + i;
- w = s->winding;
- if (!w)
- continue;
- for (j=0 ; j<w->numpoints ; j++)
- {
- k = (j+1)%w->numpoints;
- VectorSubtract (w->p[j], w->p[k], vec);
- if (VectorNormalize (vec, vec) < 0.5)
- continue;
- SnapVector (vec);
- for (k=0 ; k<3 ; k++)
- if ( vec[k] == -1 || vec[k] == 1)
- break; // axial
- if (k != 3)
- continue; // only test non-axial edges
-
- // try the six possible slanted axials from this edge
- for (axis=0 ; axis <3 ; axis++)
- {
- for (dir=-1 ; dir <= 1 ; dir+=2)
- {
- // construct a plane
- VectorClear (vec2);
- vec2[axis] = dir;
- CrossProduct (vec, vec2, normal);
- if (VectorNormalize (normal, normal) < 0.5)
- continue;
- dist = DotProduct (w->p[j], normal);
-
- // if all the points on all the sides are
- // behind this plane, it is a proper edge bevel
- for (k=0 ; k < buildBrush->numsides ; k++)
- {
- // if this plane has allready been used, skip it
- if (PlaneEqual (&mapplanes[buildBrush->sides[k].planenum]
- , normal, dist) )
- break;
-
- w2 = buildBrush->sides[k].winding;
- if (!w2)
- continue;
- for (l=0 ; l<w2->numpoints ; l++)
- {
- d = DotProduct (w2->p[l], normal) - dist;
- if (d > 0.1)
- break; // point in front
- }
- if (l != w2->numpoints)
- break;
- }
-
- if (k != buildBrush->numsides)
- continue; // wasn't part of the outer hull
- // add this plane
- if ( buildBrush->numsides == MAX_BUILD_SIDES ) {
- Error( "MAX_BUILD_SIDES" );
- }
-
- s2 = &buildBrush->sides[buildBrush->numsides];
- buildBrush->numsides++;
- memset( s2, 0, sizeof( *s2 ) );
-
- s2->planenum = FindFloatPlane (normal, dist);
- s2->contents = buildBrush->sides[0].contents;
- s2->bevel = qtrue;
- c_edgebevels++;
- }
- }
- }
- }
- }
-}
-
-/*
-===============
-AddBackSides
-
-fog volumes need to have inside faces created
-===============
-*/
-void AddBackSides( void ) {
-/*
- bspbrush_t *b;
- int i, originalSides;
- side_t *s;
- side_t *newSide;
-
- b = buildBrush;
- originalSides = b->numsides;
- for ( i = 0 ; i < originalSides ; i++ ) {
- s = &b->sides[i];
- if ( !s->shaderInfo ) {
- continue;
- }
- if ( !(s->shaderInfo->contents & CONTENTS_FOG) ) {
- continue;
- }
-
- // duplicate the up-facing side
- if ( mapplanes[ s->planenum ].normal[2] == 1 ) {
- newSide = &b->sides[ b->numsides ];
- b->numsides++;
-
- *newSide = *s;
- newSide->backSide = qtrue;
- newSide->planenum = s->planenum ^ 1; // opposite side
- }
- }
-*/
-}
-
-/*
-===============
-FinishBrush
-
-Produces a final brush based on the buildBrush->sides array
-and links it to the current entity
-===============
-*/
-bspbrush_t *FinishBrush( void ) {
- bspbrush_t *b;
-
- // liquids may need to have extra sides created for back sides
- AddBackSides();
-
- // create windings for sides and bounds for brush
- if ( !CreateBrushWindings( buildBrush ) ) {
- // don't keep this brush
- return NULL;
- }
-
- // brushes that will not be visible at all are forced to be detail
- if ( buildBrush->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
- {
- buildBrush->detail = qtrue;
- c_detail++;
- }
-
- //
- // origin brushes are removed, but they set
- // the rotation origin for the rest of the brushes
- // in the entity. After the entire entity is parsed,
- // the planenums and texinfos will be adjusted for
- // the origin brush
- //
- if ( buildBrush->contents & CONTENTS_ORIGIN )
- {
- char string[32];
- vec3_t origin;
-
- if (num_entities == 1) {
- _printf ("Entity %i, Brush %i: origin brushes not allowed in world\n"
- , num_entities - 1, entitySourceBrushes);
- return NULL;
- }
-
- VectorAdd (buildBrush->mins, buildBrush->maxs, origin);
- VectorScale (origin, 0.5, origin);
-
- sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
- SetKeyValue (&entities[num_entities - 1], "origin", string);
-
- VectorCopy (origin, entities[num_entities - 1].origin);
-
- // don't keep this brush
- return NULL;
- }
-
- if ( buildBrush->contents & CONTENTS_AREAPORTAL ) {
- if (num_entities != 1) {
- _printf ("Entity %i, Brush %i: areaportals only allowed in world\n"
- , num_entities - 1, entitySourceBrushes);
- return NULL;
- }
- }
-
- AddBrushBevels ();
-
- // keep it
- b = CopyBrush( buildBrush );
-
- b->entitynum = num_entities-1;
- b->brushnum = entitySourceBrushes;
-
- b->original = b;
-
- b->next = mapent->brushes;
- mapent->brushes = b;
-
- return b;
-}
-
-//======================================================================
-
-
-/*
-==================
-textureAxisFromPlane
-==================
-*/
-vec3_t baseaxis[18] =
-{
-{0,0,1}, {1,0,0}, {0,-1,0}, // floor
-{0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling
-{1,0,0}, {0,1,0}, {0,0,-1}, // west wall
-{-1,0,0}, {0,1,0}, {0,0,-1}, // east wall
-{0,1,0}, {1,0,0}, {0,0,-1}, // south wall
-{0,-1,0}, {1,0,0}, {0,0,-1} // north wall
-};
-
-void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv)
-{
- int bestaxis;
- vec_t dot,best;
- int i;
-
- best = 0;
- bestaxis = 0;
-
- for (i=0 ; i<6 ; i++)
- {
- dot = DotProduct (pln->normal, baseaxis[i*3]);
- if (dot > best)
- {
- best = dot;
- bestaxis = i;
- }
- }
-
- VectorCopy (baseaxis[bestaxis*3+1], xv);
- VectorCopy (baseaxis[bestaxis*3+2], yv);
-}
-
-
-
-/*
-=================
-QuakeTextureVecs
-
-Creates world-to-texture mapping vecs for crappy quake plane arrangements
-=================
-*/
-void QuakeTextureVecs( plane_t *plane, vec_t shift[2], vec_t rotate, vec_t scale[2],
- vec_t mappingVecs[2][4] ) {
-
- vec3_t vecs[2];
- int sv, tv;
- vec_t ang, sinv, cosv;
- vec_t ns, nt;
- int i, j;
-
- TextureAxisFromPlane(plane, vecs[0], vecs[1]);
-
- if (!scale[0])
- scale[0] = 1;
- if (!scale[1])
- scale[1] = 1;
-
- // rotate axis
- if (rotate == 0)
- { sinv = 0 ; cosv = 1; }
- else if (rotate == 90)
- { sinv = 1 ; cosv = 0; }
- else if (rotate == 180)
- { sinv = 0 ; cosv = -1; }
- else if (rotate == 270)
- { sinv = -1 ; cosv = 0; }
- else
- {
- ang = rotate / 180 * Q_PI;
- sinv = sin(ang);
- cosv = cos(ang);
- }
-
- if (vecs[0][0])
- sv = 0;
- else if (vecs[0][1])
- sv = 1;
- else
- sv = 2;
-
- if (vecs[1][0])
- tv = 0;
- else if (vecs[1][1])
- tv = 1;
- else
- tv = 2;
-
- for (i=0 ; i<2 ; i++) {
- ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
- nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
- vecs[i][sv] = ns;
- vecs[i][tv] = nt;
- }
-
- for (i=0 ; i<2 ; i++)
- for (j=0 ; j<3 ; j++)
- mappingVecs[i][j] = vecs[i][j] / scale[i];
-
- mappingVecs[0][3] = shift[0];
- mappingVecs[1][3] = shift[1];
-}
-
-//======================================================================
-
-/*
-=================
-ParseRawBrush
-
-Just parses the sides into buildBrush->sides[], nothing else.
-no validation, back plane removal, etc.
-
-Timo - 08/26/99
-added brush epairs parsing ( ignoring actually )
-Timo - 08/04/99
-added exclusive brush primitive parsing
-Timo - 08/08/99
-support for old brush format back in
-NOTE : it would be "cleaner" to have seperate functions to parse between old and new brushes
-=================
-*/
-void ParseRawBrush( ) {
- side_t *side;
- vec3_t planepts[3];
- int planenum;
- shaderInfo_t *si;
- // old brushes
- vec_t shift[2];
- vec_t rotate;
- vec_t scale[2];
- char name[MAX_QPATH];
- char shader[MAX_QPATH];
- int flags;
-
- buildBrush->numsides = 0;
- buildBrush->detail = qfalse;
-
- if (g_bBrushPrimit==BPRIMIT_NEWBRUSHES)
- MatchToken( "{" );
-
- do
- {
- if (!GetToken (qtrue))
- break;
- if (!strcmp (token, "}") )
- break;
- //Timo : brush primitive : here we may have to jump over brush epairs ( only used in editor )
- if (g_bBrushPrimit==BPRIMIT_NEWBRUSHES)
- {
- do
- {
- if (strcmp (token, "(") )
- GetToken( qfalse );
- else
- break;
- GetToken( qtrue );
- } while (1);
- }
- UnGetToken();
-
- if ( buildBrush->numsides == MAX_BUILD_SIDES ) {
- Error( "MAX_BUILD_SIDES" );
- }
-
- side = &buildBrush->sides[ buildBrush->numsides ];
- memset( side, 0, sizeof( *side ) );
- buildBrush->numsides++;
-
- // read the three point plane definition
- Parse1DMatrix( 3, planepts[0] );
- Parse1DMatrix( 3, planepts[1] );
- Parse1DMatrix( 3, planepts[2] );
-
- if (g_bBrushPrimit==BPRIMIT_NEWBRUSHES)
- // read the texture matrix
- Parse2DMatrix( 2, 3, (float *)side->texMat );
-
- // read the texturedef
- GetToken (qfalse);
- strcpy (name, token);
-
- // save the shader name for retexturing
- if ( numMapIndexedShaders == MAX_MAP_BRUSHSIDES ) {
- Error( "MAX_MAP_BRUSHSIDES" );
- }
- strcpy( mapIndexedShaders[numMapIndexedShaders], name );
- numMapIndexedShaders++;
-
- if (g_bBrushPrimit==BPRIMIT_OLDBRUSHES)
- {
- GetToken (qfalse);
- shift[0] = atoi(token);
- GetToken (qfalse);
- shift[1] = atoi(token);
- GetToken (qfalse);
- rotate = atoi(token);
- GetToken (qfalse);
- scale[0] = atof(token);
- GetToken (qfalse);
- scale[1] = atof(token);
- }
-
- // find default flags and values
- sprintf( shader, "textures/%s", name );
- si = ShaderInfoForShader( shader );
- side->shaderInfo = si;
- side->surfaceFlags = si->surfaceFlags;
- side->value = si->value;
- side->contents = si->contents;
-
- // allow override of default flags and values
- // in Q3, the only thing you can override is DETAIL
- if (TokenAvailable())
- {
- GetToken (qfalse);
-// side->contents = atoi(token);
- flags = atoi(token);
- if ( flags & CONTENTS_DETAIL ) {
- side->contents |= CONTENTS_DETAIL;
- }
-
- GetToken (qfalse);
-// td.flags = atoi(token);
-
- GetToken (qfalse);
-// td.value = atoi(token);
- }
-
-
- // find the plane number
- planenum = MapPlaneFromPoints (planepts[0], planepts[1], planepts[2]);
- side->planenum = planenum;
-
- if (g_bBrushPrimit==BPRIMIT_OLDBRUSHES)
- // get the texture mapping for this texturedef / plane combination
- QuakeTextureVecs( &mapplanes[planenum], shift, rotate, scale, side->vecs );
-
- } while (1);
-
- if (g_bBrushPrimit==BPRIMIT_NEWBRUSHES)
- {
- UnGetToken();
- MatchToken( "}" );
- MatchToken( "}" );
- }
-}
-
-/*
-=================
-RemoveDuplicateBrushPlanes
-
-Returns false if the brush has a mirrored set of planes,
-meaning it encloses no volume.
-Also removes planes without any normal
-=================
-*/
-qboolean RemoveDuplicateBrushPlanes( bspbrush_t * b ) {
- int i, j, k;
- side_t *sides;
-
- sides = b->sides;
-
- for ( i = 1 ; i < b->numsides ; i++ ) {
-
- // check for a degenerate plane
- if ( sides[i].planenum == -1) {
- _printf ("Entity %i, Brush %i: degenerate plane\n"
- , b->entitynum, b->brushnum);
- // remove it
- for ( k = i + 1 ; k < b->numsides ; k++ ) {
- sides[k-1] = sides[k];
- }
- b->numsides--;
- i--;
- continue;
- }
-
- // check for duplication and mirroring
- for ( j = 0 ; j < i ; j++ ) {
- if ( sides[i].planenum == sides[j].planenum ) {
- _printf ("Entity %i, Brush %i: duplicate plane\n"
- , b->entitynum, b->brushnum);
- // remove the second duplicate
- for ( k = i + 1 ; k < b->numsides ; k++ ) {
- sides[k-1] = sides[k];
- }
- b->numsides--;
- i--;
- break;
- }
-
- if ( sides[i].planenum == (sides[j].planenum ^ 1) ) {
- // mirror plane, brush is invalid
- _printf ("Entity %i, Brush %i: mirrored plane\n"
- , b->entitynum, b->brushnum);
- return qfalse;
- }
- }
- }
- return qtrue;
-}
-
-
-/*
-=================
-ParseBrush
-
- qboolean parameter to true -> parse new brush primitive format ( else use old format )
-=================
-*/
-void ParseBrush (void) {
- bspbrush_t *b;
-
- ParseRawBrush();
-
- buildBrush->portalareas[0] = -1;
- buildBrush->portalareas[1] = -1;
- buildBrush->entitynum = num_entities-1;
- buildBrush->brushnum = entitySourceBrushes;
-
- // if there are mirrored planes, the entire brush is invalid
- if ( !RemoveDuplicateBrushPlanes( buildBrush ) ) {
- return;
- }
-
- // get the content for the entire brush
- SetBrushContents( buildBrush );
-
- // allow detail brushes to be removed
- if (nodetail && (buildBrush->contents & CONTENTS_DETAIL) ) {
- FreeBrush( buildBrush );
- return;
- }
-
- // allow water brushes to be removed
- if (nowater && (buildBrush->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) ) {
- FreeBrush( buildBrush );
- return;
- }
-
- b = FinishBrush( );
- if ( !b ) {
- return;
- }
-}
-
-
-/*
-================
-MoveBrushesToWorld
-
-Takes all of the brushes from the current entity and
-adds them to the world's brush list.
-
-Used by func_group
-================
-*/
-void MoveBrushesToWorld (entity_t *mapent) {
- bspbrush_t *b, *next;
- parseMesh_t *pm;
-
- // move brushes
- for ( b = mapent->brushes ; b ; b = next ) {
- next = b->next;
-
- b->next = entities[0].brushes;
- entities[0].brushes = b;
- }
- mapent->brushes = NULL;
-
- // move patches
- if ( mapent->patches ) {
-
- for ( pm = mapent->patches ; pm->next ; pm = pm->next ) {
- }
-
- pm->next = entities[0].patches;
- entities[0].patches = mapent->patches;
-
- mapent->patches = NULL;
- }
-}
-
-
-/*
-================
-AdjustBrushesForOrigin
-================
-*/
-void AdjustBrushesForOrigin( entity_t *ent ) {
- bspbrush_t *b;
- int i;
- side_t *s;
- vec_t newdist;
- parseMesh_t *p;
-
- for ( b = ent->brushes ; b ; b = b->next ) {
- for (i=0 ; i<b->numsides ; i++) {
- s = &b->sides[i];
- newdist = mapplanes[s->planenum].dist -
- DotProduct (mapplanes[s->planenum].normal, ent->origin);
- s->planenum = FindFloatPlane (mapplanes[s->planenum].normal, newdist);
- }
- CreateBrushWindings(b);
- }
-
- for ( p = ent->patches ; p ; p = p->next ) {
- for ( i = 0 ; i < p->mesh.width*p->mesh.height ; i++ ) {
- VectorSubtract( p->mesh.verts[i].xyz, ent->origin, p->mesh.verts[i].xyz );
- }
- }
-
-}
-
-/*
-================
-ParseMapEntity
-================
-*/
-qboolean ParseMapEntity (void) {
- epair_t *e;
-
- if (!GetToken (qtrue))
- return qfalse;
-
- if (strcmp (token, "{") )
- {
- Error ("ParseEntity: { not found, found %s on line %d - last entity was at: <%4.2f, %4.2f, %4.2f>...", token, scriptline, entities[num_entities].origin[0], entities[num_entities].origin[1], entities[num_entities].origin[2]);
- }
-
- if (num_entities == MAX_MAP_ENTITIES)
- Error ("num_entities == MAX_MAP_ENTITIES");
-
- entitySourceBrushes = 0;
-
- mapent = &entities[num_entities];
- num_entities++;
- memset (mapent, 0, sizeof(*mapent));
-
- do
- {
- if (!GetToken (qtrue))
- Error ("ParseEntity: EOF without closing brace");
- if (!strcmp (token, "}") )
- break;
-
- if (!strcmp (token, "{") ) {
- // parse a brush or patch
- if (!GetToken (qtrue))
- break;
- if ( !strcmp( token, "patchDef2" ) ) {
- numMapPatches++;
- ParsePatch();
- } else if ( !strcmp( token, "terrainDef" ) ) {
- ParseTerrain();
- } else if ( !strcmp( token, "brushDef" ) ) {
- if (g_bBrushPrimit==BPRIMIT_OLDBRUSHES)
- Error("old brush format not allowed in new brush format map");
- g_bBrushPrimit=BPRIMIT_NEWBRUSHES;
- // parse brush primitive
- ParseBrush();
- }
- else
- {
- if (g_bBrushPrimit==BPRIMIT_NEWBRUSHES)
- Error("new brush format not allowed in old brush format map");
- g_bBrushPrimit=BPRIMIT_OLDBRUSHES;
- // parse old brush format
- UnGetToken();
- ParseBrush();
- }
- entitySourceBrushes++;
- }
- else
- {
- // parse a key / value pair
- e = ParseEpair ();
- e->next = mapent->epairs;
- mapent->epairs = e;
- }
- } while (1);
-
- GetVectorForKey (mapent, "origin", mapent->origin);
-
- //
- // if there was an origin brush, offset all of the planes and texinfo
- // for all the brushes in the entity
- if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2]) {
- AdjustBrushesForOrigin( mapent );
- }
-
- // group_info entities are just for editor grouping
- // ignored
- // FIXME: leak!
- if (!strcmp("group_info", ValueForKey (mapent, "classname")))
- {
- num_entities--;
- return qtrue;
- }
-
- // group entities are just for editor convenience
- // toss all brushes into the world entity
- if (!strcmp ("func_group", ValueForKey (mapent, "classname")))
- {
- if ( !strcmp ("1", ValueForKey (mapent, "terrain"))) {
- SetTerrainTextures();
- }
- MoveBrushesToWorld (mapent);
- num_entities--;
- return qtrue;
- }
-
- return qtrue;
-}
-
-//===================================================================
-
-
-/*
-================
-LoadMapFile
-================
-*/
-void LoadMapFile (char *filename) {
- bspbrush_t *b;
-
- qprintf ("--- LoadMapFile ---\n");
- _printf ("Loading map file %s\n", filename);
-
- LoadScriptFile (filename);
-
- num_entities = 0;
- numMapDrawSurfs = 0;
- c_detail = 0;
-
- g_bBrushPrimit = BPRIMIT_UNDEFINED;
-
- // allocate a very large temporary brush for building
- // the brushes as they are loaded
- buildBrush = AllocBrush( MAX_BUILD_SIDES );
-
- while (ParseMapEntity ())
- {
- }
-
- ClearBounds (map_mins, map_maxs);
- for ( b = entities[0].brushes ; b ; b=b->next ) {
- AddPointToBounds( b->mins, map_mins, map_maxs );
- AddPointToBounds( b->maxs, map_mins, map_maxs );
- }
-
- qprintf ("%5i total world brushes\n", CountBrushList( entities[0].brushes ) );
- qprintf ("%5i detail brushes\n", c_detail );
- qprintf ("%5i patches\n", numMapPatches);
- qprintf ("%5i boxbevels\n", c_boxbevels);
- qprintf ("%5i edgebevels\n", c_edgebevels);
- qprintf ("%5i entities\n", num_entities);
- qprintf ("%5i planes\n", nummapplanes);
- qprintf ("%5i areaportals\n", c_areaportals);
- qprintf ("size: %5.0f,%5.0f,%5.0f to %5.0f,%5.0f,%5.0f\n", map_mins[0],map_mins[1],map_mins[2],
- map_maxs[0],map_maxs[1],map_maxs[2]);
-
- if ( fakemap ) {
- WriteBspBrushMap ("fakemap.map", entities[0].brushes );
- }
-
- if ( testExpand ) {
- TestExpandBrushes ();
- }
-}
-
-
-//====================================================================
-
-
-/*
-================
-TestExpandBrushes
-
-Expands all the brush planes and saves a new map out to
-allow visual inspection of the clipping bevels
-================
-*/
-void TestExpandBrushes( void ) {
- side_t *s;
- int i, j;
- bspbrush_t *brush, *list, *copy;
- vec_t dist;
- plane_t *plane;
-
- list = NULL;
-
- for ( brush = entities[0].brushes ; brush ; brush = brush->next ) {
- copy = CopyBrush( brush );
- copy->next = list;
- list = copy;
-
- // expand all the planes
- for ( i=0 ; i<brush->numsides ; i++ ) {
- s = brush->sides + i;
- plane = &mapplanes[s->planenum];
- dist = plane->dist;
- for (j=0 ; j<3 ; j++) {
- dist += fabs( 16 * plane->normal[j] );
- }
- s->planenum = FindFloatPlane( plane->normal, dist );
- }
-
- }
-
- WriteBspBrushMap ( "expanded.map", entities[0].brushes );
-
- Error ("can't proceed after expanding brushes");
-}