📄 map_q3.c
字号:
// , 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;
// }
//ME: the bsp brushes already have bevels, so we won't try to
// add them again (especially since Johny Boy's bevel adding might
// be crappy)
// AddBrushBevels(b);
nummapbrushes++;
mapent->numbrushes++;
} //end of the function Q3_BSPBrushToMapBrush
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Q3_ParseBSPBrushes(entity_t *mapent)
{
int i;
for (i = 0; i < q3_dmodels[mapent->modelnum].numBrushes; i++)
{
Q3_BSPBrushToMapBrush(&q3_dbrushes[q3_dmodels[mapent->modelnum].firstBrush + i], mapent);
} //end for
} //end of the function Q3_ParseBSPBrushes
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean Q3_ParseBSPEntity(int entnum)
{
entity_t *mapent;
char *model;
int startbrush, startsides;
startbrush = nummapbrushes;
startsides = nummapbrushsides;
mapent = &entities[entnum];//num_entities];
mapent->firstbrush = nummapbrushes;
mapent->numbrushes = 0;
mapent->modelnum = -1; //-1 = no BSP model
model = ValueForKey(mapent, "model");
if (model && strlen(model))
{
if (*model == '*')
{
//get the model number of this entity (skip the leading *)
mapent->modelnum = atoi(&model[1]);
} //end if
} //end if
GetVectorForKey(mapent, "origin", mapent->origin);
//if this is the world entity it has model number zero
//the world entity has no model key
if (!strcmp("worldspawn", ValueForKey(mapent, "classname")))
{
mapent->modelnum = 0;
} //end if
//if the map entity has a BSP model (a modelnum of -1 is used for
//entities that aren't using a BSP model)
if (mapent->modelnum >= 0)
{
//parse the bsp brushes
Q3_ParseBSPBrushes(mapent);
} //end if
//
//the origin of the entity is already taken into account
//
//func_group entities can't be in the bsp file
//
//check out the func_areaportal entities
if (!strcmp ("func_areaportal", ValueForKey (mapent, "classname")))
{
c_areaportals++;
mapent->areaportalnum = c_areaportals;
return true;
} //end if
return true;
} //end of the function Q3_ParseBSPEntity
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#define MAX_PATCH_VERTS 1024
void AAS_CreateCurveBrushes(void)
{
int i, j, n, planenum, numcurvebrushes = 0;
q3_dsurface_t *surface;
q3_drawVert_t *dv_p;
vec3_t points[MAX_PATCH_VERTS];
int width, height, c;
patchCollide_t *pc;
facet_t *facet;
mapbrush_t *brush;
side_t *side;
entity_t *mapent;
winding_t *winding;
qprintf("nummapbrushsides = %d\n", nummapbrushsides);
mapent = &entities[0];
for (i = 0; i < q3_numDrawSurfaces; i++)
{
surface = &q3_drawSurfaces[i];
if ( ! surface->patchWidth ) continue;
// if the curve is not solid
if (!(q3_dshaders[surface->shaderNum].contentFlags & (CONTENTS_SOLID|CONTENTS_PLAYERCLIP)))
{
//Log_Print("skipped non-solid curve\n");
continue;
} //end if
// if this curve should not be used for AAS
if ( q3_dshaders[surface->shaderNum].contentFlags & CONTENTS_NOBOTCLIP ) {
continue;
}
//
width = surface->patchWidth;
height = surface->patchHeight;
c = width * height;
if (c > MAX_PATCH_VERTS)
{
Error("ParseMesh: MAX_PATCH_VERTS");
} //end if
dv_p = q3_drawVerts + surface->firstVert;
for ( j = 0 ; j < c ; j++, dv_p++ )
{
points[j][0] = dv_p->xyz[0];
points[j][1] = dv_p->xyz[1];
points[j][2] = dv_p->xyz[2];
} //end for
// create the internal facet structure
pc = CM_GeneratePatchCollide(width, height, points);
//
for (j = 0; j < pc->numFacets; j++)
{
facet = &pc->facets[j];
//
brush = &mapbrushes[nummapbrushes];
brush->original_sides = &brushsides[nummapbrushsides];
brush->entitynum = 0;
brush->brushnum = nummapbrushes - mapent->firstbrush;
//
brush->numsides = facet->numBorders + 2;
nummapbrushsides += brush->numsides;
brush->contents = CONTENTS_SOLID;
//
//qprintf("\r%6d curve brushes", nummapbrushsides);//++numcurvebrushes);
qprintf("\r%6d curve brushes", ++numcurvebrushes);
//
planenum = FindFloatPlane(pc->planes[facet->surfacePlane].plane, pc->planes[facet->surfacePlane].plane[3]);
//
side = &brush->original_sides[0];
side->planenum = planenum;
side->contents = CONTENTS_SOLID;
side->flags |= SFL_TEXTURED|SFL_VISIBLE|SFL_CURVE;
side->surf = 0;
//
side = &brush->original_sides[1];
if (create_aas)
{
//the plane is expanded later so it's not a problem that
//these first two opposite sides are coplanar
side->planenum = planenum ^ 1;
} //end if
else
{
side->planenum = FindFloatPlane(mapplanes[planenum^1].normal, mapplanes[planenum^1].dist + 1);
side->flags |= SFL_TEXTURED|SFL_VISIBLE;
} //end else
side->contents = CONTENTS_SOLID;
side->flags |= SFL_CURVE;
side->surf = 0;
//
winding = BaseWindingForPlane(mapplanes[side->planenum].normal, mapplanes[side->planenum].dist);
for (n = 0; n < facet->numBorders; n++)
{
//never use the surface plane as a border
if (facet->borderPlanes[n] == facet->surfacePlane) continue;
//
side = &brush->original_sides[2 + n];
side->planenum = FindFloatPlane(pc->planes[facet->borderPlanes[n]].plane, pc->planes[facet->borderPlanes[n]].plane[3]);
if (facet->borderInward[n]) side->planenum ^= 1;
side->contents = CONTENTS_SOLID;
side->flags |= SFL_TEXTURED|SFL_CURVE;
side->surf = 0;
//chop the winding in place
if (winding) ChopWindingInPlace(&winding, mapplanes[side->planenum^1].normal, mapplanes[side->planenum^1].dist, 0.1); //CLIP_EPSILON);
} //end for
//VectorCopy(pc->bounds[0], brush->mins);
//VectorCopy(pc->bounds[1], brush->maxs);
if (!winding)
{
Log_Print("WARNING: AAS_CreateCurveBrushes: no winding\n");
brush->numsides = 0;
continue;
} //end if
brush->original_sides[0].winding = winding;
WindingBounds(winding, brush->mins, brush->maxs);
for (n = 0; n < 3; n++)
{
//IDBUG: all the indexes into the mins and maxs were zero (not using i)
if (brush->mins[n] < -MAX_MAP_BOUNDS || brush->maxs[n] > MAX_MAP_BOUNDS)
{
Log_Print("entity %i, brush %i: bounds out of range\n", brush->entitynum, brush->brushnum);
Log_Print("brush->mins[%d] = %f, brush->maxs[%d] = %f\n", n, brush->mins[n], n, brush->maxs[n]);
brush->numsides = 0; //remove the brush
break;
} //end if
if (brush->mins[n] > MAX_MAP_BOUNDS || brush->maxs[n] < -MAX_MAP_BOUNDS)
{
Log_Print("entity %i, brush %i: no visible sides on brush\n", brush->entitynum, brush->brushnum);
Log_Print("brush->mins[%d] = %f, brush->maxs[%d] = %f\n", n, brush->mins[n], n, brush->maxs[n]);
brush->numsides = 0; //remove the brush
break;
} //end if
} //end for
if (create_aas)
{
//NOTE: brush bevels now already added
//AddBrushBevels(brush);
AAS_CreateMapBrushes(brush, mapent, false);
} //end if
else
{
// create windings for sides and bounds for brush
MakeBrushWindings(brush);
AddBrushBevels(brush);
nummapbrushes++;
mapent->numbrushes++;
} //end else
} //end for
} //end for
//qprintf("\r%6d curve brushes", nummapbrushsides);//++numcurvebrushes);
qprintf("\r%6d curve brushes\n", numcurvebrushes);
} //end of the function AAS_CreateCurveBrushes
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ExpandMapBrush(mapbrush_t *brush, vec3_t mins, vec3_t maxs);
void Q3_LoadMapFromBSP(struct quakefile_s *qf)
{
int i;
vec3_t mins = {-1,-1,-1}, maxs = {1, 1, 1};
Log_Print("-- Q3_LoadMapFromBSP --\n");
//loaded map type
loadedmaptype = MAPTYPE_QUAKE3;
Log_Print("Loading map from %s...\n", qf->filename);
//load the bsp file
Q3_LoadBSPFile(qf);
//create an index from bsp planes to map planes
//DPlanes2MapPlanes();
//clear brush model numbers
for (i = 0; i < MAX_MAPFILE_BRUSHES; i++)
brushmodelnumbers[i] = -1;
nummapbrushsides = 0;
num_entities = 0;
Q3_ParseEntities();
//
for (i = 0; i < num_entities; i++)
{
Q3_ParseBSPEntity(i);
} //end for
AAS_CreateCurveBrushes();
//get the map mins and maxs from the world model
ClearBounds(map_mins, map_maxs);
for (i = 0; i < entities[0].numbrushes; i++)
{
if (mapbrushes[i].numsides <= 0)
continue;
AddPointToBounds (mapbrushes[i].mins, map_mins, map_maxs);
AddPointToBounds (mapbrushes[i].maxs, map_mins, map_maxs);
} //end for
/*/
for (i = 0; i < nummapbrushes; i++)
{
//if (!mapbrushes[i].original_sides) continue;
//AddBrushBevels(&mapbrushes[i]);
//AAS_ExpandMapBrush(&mapbrushes[i], mins, maxs);
} //end for*/
/*
for (i = 0; i < nummapbrushsides; i++)
{
Log_Write("side %d flags = %d", i, brushsides[i].flags);
} //end for
for (i = 0; i < nummapbrushes; i++)
{
Log_Write("brush contents: ");
PrintContents(mapbrushes[i].contents);
Log_Print("\n");
} //end for*/
} //end of the function Q3_LoadMapFromBSP
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Q3_ResetMapLoading(void)
{
//reset for map loading from bsp
memset(nodestack, 0, NODESTACKSIZE * sizeof(int));
nodestackptr = NULL;
nodestacksize = 0;
memset(brushmodelnumbers, 0, MAX_MAPFILE_BRUSHES * sizeof(int));
} //end of the function Q3_ResetMapLoading
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -