📄 map_sin.c
字号:
/*
===========================================================================
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
===========================================================================
*/
//-----------------------------------------------------------------------------
//
// $Logfile:: /MissionPack/code/bspc/map_sin.c $
#include "qbsp.h"
#include "l_bsp_sin.h"
#include "aas_map.h" //AAS_CreateMapBrushes
//====================================================================
/*
===========
Sin_BrushContents
===========
*/
int Sin_BrushContents(mapbrush_t *b)
{
int contents;
side_t *s;
int i;
#ifdef SIN
float trans = 0;
#else
int trans;
#endif
s = &b->original_sides[0];
contents = s->contents;
#ifdef SIN
trans = sin_texinfo[s->texinfo].translucence;
#else
trans = texinfo[s->texinfo].flags;
#endif
for (i=1 ; i<b->numsides ; i++, s++)
{
s = &b->original_sides[i];
#ifdef SIN
trans += sin_texinfo[s->texinfo].translucence;
#else
trans |= texinfo[s->texinfo].flags;
#endif
if (s->contents != contents)
{
#ifdef SIN
if (
( s->contents & CONTENTS_DETAIL && !(contents & CONTENTS_DETAIL) ) ||
( !(s->contents & CONTENTS_DETAIL) && contents & CONTENTS_DETAIL )
)
{
s->contents |= CONTENTS_DETAIL;
contents |= CONTENTS_DETAIL;
continue;
}
#endif
printf ("Entity %i, Brush %i: mixed face contents\n"
, b->entitynum, b->brushnum);
break;
}
}
#ifdef SIN
if (contents & CONTENTS_FENCE)
{
// contents |= CONTENTS_TRANSLUCENT;
contents |= CONTENTS_DETAIL;
contents |= CONTENTS_DUMMYFENCE;
contents &= ~CONTENTS_SOLID;
contents &= ~CONTENTS_FENCE;
contents |= CONTENTS_WINDOW;
}
#endif
// if any side is translucent, mark the contents
// and change solid to window
#ifdef SIN
if ( trans > 0 )
#else
if ( trans & (SURF_TRANS33|SURF_TRANS66) )
#endif
{
contents |= CONTENTS_Q2TRANSLUCENT;
if (contents & CONTENTS_SOLID)
{
contents &= ~CONTENTS_SOLID;
contents |= CONTENTS_WINDOW;
}
}
return contents;
} //*/
//============================================================================
/*
=================
ParseBrush
=================
* /
void ParseBrush (entity_t *mapent)
{
mapbrush_t *b;
int i,j, k;
int mt;
side_t *side, *s2;
int planenum;
brush_texture_t td;
#ifdef SIN
textureref_t newref;
#endif
int planepts[3][3];
if (nummapbrushes == MAX_MAP_BRUSHES)
Error ("nummapbrushes == MAX_MAP_BRUSHES");
b = &mapbrushes[nummapbrushes];
b->original_sides = &brushsides[nummapbrushsides];
b->entitynum = num_entities-1;
b->brushnum = nummapbrushes - mapent->firstbrush;
do
{
if (!GetToken (true))
break;
if (!strcmp (token, "}") )
break;
if (nummapbrushsides == MAX_MAP_BRUSHSIDES)
Error ("MAX_MAP_BRUSHSIDES");
side = &brushsides[nummapbrushsides];
// read the three point plane definition
for (i=0 ; i<3 ; i++)
{
if (i != 0)
GetToken (true);
if (strcmp (token, "(") )
Error ("parsing brush");
for (j=0 ; j<3 ; j++)
{
GetToken (false);
planepts[i][j] = atoi(token);
}
GetToken (false);
if (strcmp (token, ")") )
Error ("parsing brush");
}
//
// read the texturedef
//
GetToken (false);
strcpy (td.name, token);
GetToken (false);
td.shift[0] = atoi(token);
GetToken (false);
td.shift[1] = atoi(token);
GetToken (false);
#ifdef SIN
td.rotate = atof(token);
#else
td.rotate = atoi(token);
#endif
GetToken (false);
td.scale[0] = atof(token);
GetToken (false);
td.scale[1] = atof(token);
// find default flags and values
mt = FindMiptex (td.name);
#ifdef SIN
// clear out the masks on newref
memset(&newref,0,sizeof(newref));
// copy over the name
strcpy( newref.name, td.name );
ParseSurfaceInfo( &newref );
MergeRefs( &bsp_textureref[mt], &newref, &td.tref );
side->contents = td.tref.contents;
side->surf = td.tref.flags;
#else
td.flags = textureref[mt].flags;
td.value = textureref[mt].value;
side->contents = textureref[mt].contents;
side->surf = td.flags = textureref[mt].flags;
if (TokenAvailable())
{
GetToken (false);
side->contents = atoi(token);
GetToken (false);
side->surf = td.flags = atoi(token);
GetToken (false);
td.value = atoi(token);
}
#endif
// translucent objects are automatically classified as detail
#ifdef SIN
if ( td.tref.translucence > 0 )
#else
if (side->surf & (SURF_TRANS33|SURF_TRANS66) )
#endif
side->contents |= CONTENTS_DETAIL;
if (side->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
side->contents |= CONTENTS_DETAIL;
if (fulldetail)
side->contents &= ~CONTENTS_DETAIL;
if (!(side->contents & ((LAST_VISIBLE_CONTENTS-1)
| CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_MIST) ) )
side->contents |= CONTENTS_SOLID;
// hints and skips are never detail, and have no content
if (side->surf & (SURF_HINT|SURF_SKIP) )
{
side->contents = 0;
#ifndef SIN // I think this is a bug of some kind
side->surf &= ~CONTENTS_DETAIL;
#endif
}
//
// find the plane number
//
planenum = PlaneFromPoints (planepts[0], planepts[1], planepts[2]);
if (planenum == -1)
{
printf ("Entity %i, Brush %i: plane with no normal\n"
, b->entitynum, b->brushnum);
continue;
}
//
// see if the plane has been used already
//
for (k=0 ; k<b->numsides ; k++)
{
s2 = b->original_sides + k;
if (s2->planenum == planenum)
{
printf ("Entity %i, Brush %i: duplicate plane\n"
, b->entitynum, b->brushnum);
break;
}
if ( s2->planenum == (planenum^1) )
{
printf ("Entity %i, Brush %i: mirrored plane\n"
, b->entitynum, b->brushnum);
break;
}
}
if (k != b->numsides)
continue; // duplicated
//
// keep this side
//
side = b->original_sides + b->numsides;
side->planenum = planenum;
#ifdef SIN
side->texinfo = TexinfoForBrushTexture (&mapplanes[planenum],
&td, vec3_origin, &newref);
//
// save off lightinfo
//
side->lightinfo = LightinfoForBrushTexture ( &td );
#else
side->texinfo = TexinfoForBrushTexture (&mapplanes[planenum],
&td, vec3_origin);
#endif
// save the td off in case there is an origin brush and we
// have to recalculate the texinfo
side_brushtextures[nummapbrushsides] = td;
#ifdef SIN
// save off the merged tref for animating textures
side_newrefs[nummapbrushsides] = newref;
#endif
nummapbrushsides++;
b->numsides++;
} while (1);
// get the content for the entire brush
b->contents = Sin_BrushContents (b);
// allow detail brushes to be removed
if (nodetail && (b->contents & CONTENTS_DETAIL) )
{
b->numsides = 0;
return;
}
// allow water brushes to be removed
if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) )
{
b->numsides = 0;
return;
}
// create windings for sides and bounds for brush
MakeBrushWindings (b);
// brushes that will not be visible at all will never be
// used as bsp splitters
if (b->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
{
c_clipbrushes++;
for (i=0 ; i<b->numsides ; i++)
b->original_sides[i].texinfo = TEXINFO_NODE;
}
//
// 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 (b->contents & CONTENTS_ORIGIN)
{
char string[32];
vec3_t origin;
if (num_entities == 1)
{
Error ("Entity %i, Brush %i: origin brushes not allowed in world"
, b->entitynum, b->brushnum);
return;
}
VectorAdd (b->mins, b->maxs, origin);
VectorScale (origin, 0.5, origin);
sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
SetKeyValue (&entities[b->entitynum], "origin", string);
VectorCopy (origin, entities[b->entitynum].origin);
// don't keep this brush
b->numsides = 0;
return;
}
AddBrushBevels (b);
nummapbrushes++;
mapent->numbrushes++;
} //*/
/*
================
MoveBrushesToWorld
Takes all of the brushes from the current entity and
adds them to the world's brush list.
Used by func_group and func_areaportal
================
* /
void MoveBrushesToWorld (entity_t *mapent)
{
int newbrushes;
int worldbrushes;
mapbrush_t *temp;
int i;
// this is pretty gross, because the brushes are expected to be
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -