#include "qbsp.h"
#include "l_bsp_q1.h"
#include "aas_map.h"
Include dependency graph for map_q1.c:

Go to the source code of this file.
|
||||||||||||
|
Definition at line 1001 of file map_q1.c. References AAS_CreateMapBrushes(), AddBrushBevels(), mapbrush_s::brushnum, brushsides, bspbrush_t, CheckBSPBrush(), mapbrush_s::contents, side_s::contents, mapbrush_s::entitynum, Error(), entity_t::firstbrush, side_s::flags, i, mapbrush_s::leafnum, MakeBrushWindings(), mapbrush_t, mapbrushes, mapent, entity_t::numbrushes, nummapbrushes, nummapbrushsides, bspbrush_s::numsides, mapbrush_s::numsides, mapbrush_s::original_sides, side_s::planenum, q1_numclipbrushes, bspbrush_s::side, side_t, bspbrush_s::sides, side_s::surf, side_s::texinfo, and side_s::winding. Referenced by Q1_CreateMapBrushes(). 01002 {
01003 mapbrush_t *mapbrush;
01004 side_t *side;
01005 int i, besttexinfo;
01006
01007 CheckBSPBrush(bspbrush);
01008
01009 if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
01010 Error ("nummapbrushes == MAX_MAPFILE_BRUSHES");
01011
01012 mapbrush = &mapbrushes[nummapbrushes];
01013 mapbrush->original_sides = &brushsides[nummapbrushsides];
01014 mapbrush->entitynum = mapent - entities;
01015 mapbrush->brushnum = nummapbrushes - mapent->firstbrush;
01016 mapbrush->leafnum = -1;
01017 mapbrush->numsides = 0;
01018
01019 besttexinfo = TEXINFO_NODE;
01020 for (i = 0; i < bspbrush->numsides; i++)
01021 {
01022 if (!bspbrush->sides[i].winding) continue;
01023 //
01024 if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
01025 Error ("MAX_MAPFILE_BRUSHSIDES");
01026 side = &brushsides[nummapbrushsides];
01027 //the contents of the bsp brush is stored in the side variable
01028 side->contents = bspbrush->side;
01029 side->surf = 0;
01030 side->planenum = bspbrush->sides[i].planenum;
01031 side->texinfo = bspbrush->sides[i].texinfo;
01032 if (side->texinfo != TEXINFO_NODE)
01033 {
01034 //this brush side is textured
01035 side->flags |= SFL_TEXTURED;
01036 besttexinfo = side->texinfo;
01037 } //end if
01038 //
01039 nummapbrushsides++;
01040 mapbrush->numsides++;
01041 } //end for
01042 //
01043 if (besttexinfo == TEXINFO_NODE)
01044 {
01045 mapbrush->numsides = 0;
01046 q1_numclipbrushes++;
01047 return;
01048 } //end if
01049 //set the texinfo for all the brush sides without texture
01050 for (i = 0; i < mapbrush->numsides; i++)
01051 {
01052 if (mapbrush->original_sides[i].texinfo == TEXINFO_NODE)
01053 {
01054 mapbrush->original_sides[i].texinfo = besttexinfo;
01055 } //end if
01056 } //end for
01057 //contents of the brush
01058 mapbrush->contents = bspbrush->side;
01059 //
01060 if (create_aas)
01061 {
01062 //create the AAS brushes from this brush, add brush bevels
01063 AAS_CreateMapBrushes(mapbrush, mapent, true);
01064 return;
01065 } //end if
01066 //create windings for sides and bounds for brush
01067 MakeBrushWindings(mapbrush);
01068 //add brush bevels
01069 AddBrushBevels(mapbrush);
01070 //a new brush has been created
01071 nummapbrushes++;
01072 mapent->numbrushes++;
01073 } //end of the function Q1_BSPBrushToMapBrush
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 316 of file map_q1.c. References bspbrush_t, q1_dleaf_t::contents, Error(), FindFloatPlane(), FreeBrush(), Log_Print(), bspbrush_s::next, q1_dnode_t::planenum, Q1_CONTENTS_EMPTY, Q1_CONTENTS_LAVA, Q1_CONTENTS_SKY, Q1_CONTENTS_SLIME, Q1_CONTENTS_SOLID, Q1_CONTENTS_WATER, q1_dleafs, q1_dnodes, q1_dplanes, q1_numbrushes, Q1_SplitBrush(), qprintf(), and bspbrush_s::side. Referenced by Q1_CreateBrushesFromBSP(). 00317 {
00318 int planenum;
00319 bspbrush_t *front, *back;
00320 q1_dleaf_t *leaf;
00321
00322 //if it is a leaf
00323 if (nodenum < 0)
00324 {
00325 leaf = &q1_dleafs[(-nodenum) - 1];
00326 if (leaf->contents != Q1_CONTENTS_EMPTY)
00327 {
00328 #ifdef Q1_PRINT
00329 qprintf("\r%5i", ++q1_numbrushes);
00330 #endif //Q1_PRINT
00331 } //end if
00332 switch(leaf->contents)
00333 {
00334 case Q1_CONTENTS_EMPTY:
00335 {
00336 FreeBrush(brush);
00337 return NULL;
00338 } //end case
00339 case Q1_CONTENTS_SOLID:
00340 #ifdef HLCONTENTS
00341 case Q1_CONTENTS_CLIP:
00342 #endif HLCONTENTS
00343 case Q1_CONTENTS_SKY:
00344 #ifdef HLCONTENTS
00345 case Q1_CONTENTS_TRANSLUCENT:
00346 #endif HLCONTENTS
00347 {
00348 brush->side = CONTENTS_SOLID;
00349 return brush;
00350 } //end case
00351 case Q1_CONTENTS_WATER:
00352 {
00353 brush->side = CONTENTS_WATER;
00354 return brush;
00355 } //end case
00356 case Q1_CONTENTS_SLIME:
00357 {
00358 brush->side = CONTENTS_SLIME;
00359 return brush;
00360 } //end case
00361 case Q1_CONTENTS_LAVA:
00362 {
00363 brush->side = CONTENTS_LAVA;
00364 return brush;
00365 } //end case
00366 #ifdef HLCONTENTS
00367 //these contents should not be found in the BSP
00368 case Q1_CONTENTS_ORIGIN:
00369 case Q1_CONTENTS_CURRENT_0:
00370 case Q1_CONTENTS_CURRENT_90:
00371 case Q1_CONTENTS_CURRENT_180:
00372 case Q1_CONTENTS_CURRENT_270:
00373 case Q1_CONTENTS_CURRENT_UP:
00374 case Q1_CONTENTS_CURRENT_DOWN:
00375 {
00376 Error("Q1_CreateBrushes_r: found contents %d in Half-Life BSP", leaf->contents);
00377 return NULL;
00378 } //end case
00379 #endif HLCONTENTS
00380 default:
00381 {
00382 Error("Q1_CreateBrushes_r: unknown contents %d in Half-Life BSP", leaf->contents);
00383 return NULL;
00384 } //end default
00385 } //end switch
00386 return NULL;
00387 } //end if
00388 //if the rest of the tree is solid
00389 /*if (Q1_SolidTree_r(nodenum))
00390 {
00391 brush->side = CONTENTS_SOLID;
00392 return brush;
00393 } //end if*/
00394 //
00395 planenum = q1_dnodes[nodenum].planenum;
00396 planenum = FindFloatPlane(q1_dplanes[planenum].normal, q1_dplanes[planenum].dist);
00397 //split the brush with the node plane
00398 Q1_SplitBrush(brush, planenum, nodenum, &front, &back);
00399 //free the original brush
00400 FreeBrush(brush);
00401 //every node must split the brush in two
00402 if (!front || !back)
00403 {
00404 Log_Print("Q1_CreateBrushes_r: WARNING node not splitting brush\n");
00405 //return NULL;
00406 } //end if
00407 //create brushes recursively
00408 if (front) front = Q1_CreateBrushes_r(front, q1_dnodes[nodenum].children[0]);
00409 if (back) back = Q1_CreateBrushes_r(back, q1_dnodes[nodenum].children[1]);
00410 //link the brushes if possible and return them
00411 if (front)
00412 {
00413 for (brush = front; brush->next; brush = brush->next);
00414 brush->next = back;
00415 return front;
00416 } //end if
00417 else
00418 {
00419 return back;
00420 } //end else
00421 } //end of the function Q1_CreateBrushes_r
|
Here is the call graph for this function:

|
|
Definition at line 428 of file map_q1.c. References AddPointToBounds(), BrushFromBounds(), bspbrush_t, q1_dmodel_t::headnode, i, Log_Print(), map_maxs, map_mins, bspbrush_s::maxs, q1_dnode_t::maxs, bspbrush_s::mins, q1_dnode_t::mins, Q1_CreateBrushes_r(), q1_dmodels, q1_dnodes, q1_numbrushes, qprintf(), vec3_t, and VectorCopy. Referenced by Q1_CreateMapBrushes(). 00429 {
00430 bspbrush_t *brushlist;
00431 bspbrush_t *brush;
00432 q1_dnode_t *headnode;
00433 vec3_t mins, maxs;
00434 int i;
00435
00436 //
00437 headnode = &q1_dnodes[q1_dmodels[modelnum].headnode[0]];
00438 //get the mins and maxs of the world
00439 VectorCopy(headnode->mins, mins);
00440 VectorCopy(headnode->maxs, maxs);
00441 //enlarge these mins and maxs
00442 for (i = 0; i < 3; i++)
00443 {
00444 mins[i] -= 8;
00445 maxs[i] += 8;
00446 } //end for
00447 //NOTE: have to add the BSP tree mins and maxs to the MAP mins and maxs
00448 AddPointToBounds(mins, map_mins, map_maxs);
00449 AddPointToBounds(maxs, map_mins, map_maxs);
00450 //
00451 if (!modelnum)
00452 {
00453 Log_Print("brush size: %5.0f,%5.0f,%5.0f to %5.0f,%5.0f,%5.0f\n",
00454 map_mins[0], map_mins[1], map_mins[2],
00455 map_maxs[0], map_maxs[1], map_maxs[2]);
00456 } //end if
00457 //create one huge brush containing the whole world
00458 brush = BrushFromBounds(mins, maxs);
00459 VectorCopy(mins, brush->mins);
00460 VectorCopy(maxs, brush->maxs);
00461 //
00462 #ifdef Q1_PRINT
00463 qprintf("creating Quake brushes\n");
00464 qprintf("%5d brushes", q1_numbrushes = 0);
00465 #endif //Q1_PRINT
00466 //create the brushes
00467 brushlist = Q1_CreateBrushes_r(brush, q1_dmodels[modelnum].headnode[0]);
00468 //
00469 #ifdef Q1_PRINT
00470 qprintf("\n");
00471 #endif //Q1_PRINT
00472 //now we've got a list with brushes!
00473 return brushlist;
00474 } //end of the function Q1_CreateBrushesFromBSP
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1080 of file map_q1.c. References bspbrush_t, FreeBrush(), i, mapent, bspbrush_s::next, Q1_BSPBrushToMapBrush(), Q1_CreateBrushesFromBSP(), Q1_FixContentsTextures(), Q1_MergeBrushes(), Q1_TextureBrushes(), and qprintf(). Referenced by Q1_LoadMapFromBSP(). 01081 {
01082 bspbrush_t *brushlist, *brush, *nextbrush;
01083 int i;
01084
01085 //create brushes from the model BSP tree
01086 brushlist = Q1_CreateBrushesFromBSP(modelnum);
01087 //texture the brushes and split them when necesary
01088 brushlist = Q1_TextureBrushes(brushlist, modelnum);
01089 //fix the contents textures of all brushes
01090 Q1_FixContentsTextures(brushlist);
01091 //
01092 if (!nobrushmerge)
01093 {
01094 brushlist = Q1_MergeBrushes(brushlist, modelnum);
01095 //brushlist = Q1_MergeBrushes(brushlist, modelnum);
01096 } //end if
01097 //
01098 if (!modelnum) qprintf("converting brushes to map brushes\n");
01099 if (!modelnum) qprintf("%5d brushes", i = 0);
01100 for (brush = brushlist; brush; brush = nextbrush)
01101 {
01102 nextbrush = brush->next;
01103 Q1_BSPBrushToMapBrush(brush, mapent);
01104 brush->next = NULL;
01105 FreeBrush(brush);
01106 if (!modelnum) qprintf("\r%5d", ++i);
01107 } //end for
01108 if (!modelnum) qprintf("\n");
01109 } //end of the function Q1_CreateMapBrushes
|
Here is the call graph for this function:

|
|
Definition at line 508 of file map_q1.c. References CrossProduct(), q1_dface_t::firstedge, i, q1_dface_t::numedges, q1_dvertex_t::point, q1_dedges, q1_dvertexes, q1_dedge_t::v, v, vec3_t, vec_t, VectorLength(), and VectorSubtract. 00509 {
00510 int i;
00511 float total;
00512 vec_t *v;
00513 vec3_t d1, d2, cross;
00514 q1_dedge_t *edge;
00515
00516 edge = &q1_dedges[face->firstedge];
00517 v = q1_dvertexes[edge->v[0]].point;
00518
00519 total = 0;
00520 for (i = 1; i < face->numedges - 1; i++)
00521 {
00522 edge = &q1_dedges[face->firstedge + i];
00523 VectorSubtract(q1_dvertexes[edge->v[0]].point, v, d1);
00524 VectorSubtract(q1_dvertexes[edge->v[1]].point, v, d2);
00525 CrossProduct(d1, d2, cross);
00526 total += 0.5 * VectorLength(cross);
00527 } //end for
00528 return total;
00529 } //end of the function AAS_FaceArea
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 634 of file map_q1.c. References abs(), ChopWindingInPlace(), CopyWinding(), CrossProduct(), q1_dplane_t::dist, DotProduct, q1_dface_t::firstedge, FreeWinding(), i, memcpy(), q1_dplane_t::normal, q1_dface_t::numedges, q1_dface_t::planenum, q1_dvertex_t::point, q1_dedges, q1_dplanes, q1_dsurfedges, q1_dvertexes, q1_dface_t::side, q1_dedge_t::v, v1, v2, vec3_t, vec_t, VectorNegate, VectorNormalize(), VectorSubtract, w, and WindingArea(). Referenced by Q1_TextureBrushes(). 00635 {
00636 int i, edgenum, side;
00637 float dist, area;
00638 q1_dplane_t plane;
00639 vec_t *v1, *v2;
00640 vec3_t normal, edgevec;
00641 winding_t *w;
00642
00643 //
00644 w = CopyWinding(winding);
00645 memcpy(&plane, &q1_dplanes[face->planenum], sizeof(q1_dplane_t));
00646 //check on which side of the plane the face is
00647 if (face->side)
00648 {
00649 VectorNegate(plane.normal, plane.normal);
00650 plane.dist = -plane.dist;
00651 } //end if
00652 for (i = 0; i < face->numedges && w; i++)
00653 {
00654 //get the first and second vertex of the edge
00655 edgenum = q1_dsurfedges[face->firstedge + i];
00656 side = edgenum > 0;
00657 //if the face plane is flipped
00658 v1 = q1_dvertexes[q1_dedges[abs(edgenum)].v[side]].point;
00659 v2 = q1_dvertexes[q1_dedges[abs(edgenum)].v[!side]].point;
00660 //create a plane through the edge vector, orthogonal to the face plane
00661 //and with the normal vector pointing out of the face
00662 VectorSubtract(v1, v2, edgevec);
00663 CrossProduct(edgevec, plane.normal, normal);
00664 VectorNormalize(normal);
00665 dist = DotProduct(normal, v1);
00666 //
00667 ChopWindingInPlace(&w, normal, dist, 0.9); //CLIP_EPSILON
00668 } //end for
00669 if (w)
00670 {
00671 area = WindingArea(w);
00672 FreeWinding(w);
00673 return area;
00674 } //end if
00675 return 0;
00676 } //end of the function Q1_FaceOnWinding
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 536 of file map_q1.c. References abs(), CrossProduct(), DotProduct, q1_dface_t::firstedge, q1_dvertex_t::point, q1_dedges, q1_dsurfedges, q1_dvertexes, q1_dedge_t::v, v1, v2, vec3_t, vec_t, VectorNormalize(), and VectorSubtract. 00537 {
00538 vec_t *v1, *v2, *v3;
00539 vec3_t vec1, vec2;
00540 int side, edgenum;
00541
00542 edgenum = q1_dsurfedges[face->firstedge];
00543 side = edgenum < 0;
00544 v1 = q1_dvertexes[q1_dedges[abs(edgenum)].v[side]].point;
00545 v2 = q1_dvertexes[q1_dedges[abs(edgenum)].v[!side]].point;
00546 edgenum = q1_dsurfedges[face->firstedge+1];
00547 side = edgenum < 0;
00548 v3 = q1_dvertexes[q1_dedges[abs(edgenum)].v[!side]].point;
00549 //
00550 VectorSubtract(v2, v1, vec1);
00551 VectorSubtract(v3, v1, vec2);
00552
00553 CrossProduct(vec1, vec2, normal);
00554 VectorNormalize(normal);
00555 *dist = DotProduct(v1, normal);
00556 } //end of the function Q1_FacePlane
|
Here is the call graph for this function:

|
|
Definition at line 939 of file map_q1.c. References bspbrush_t, CONTENTS_SLIME, CONTENTS_WATER, i, Log_Print(), map_texinfo, bspbrush_s::next, bspbrush_s::numsides, Q1_TextureContents(), bspbrush_s::side, bspbrush_s::sides, side_s::texinfo, and texture. Referenced by Q1_CreateMapBrushes(). 00940 {
00941 int i, texinfonum;
00942 bspbrush_t *brush;
00943
00944 for (brush = brushlist; brush; brush = brush->next)
00945 {
00946 //only fix the textures of water, slime and lava brushes
00947 if (brush->side != CONTENTS_WATER &&
00948 brush->side != CONTENTS_SLIME &&
00949 brush->side != CONTENTS_LAVA) continue;
00950 //
00951 for (i = 0; i < brush->numsides; i++)
00952 {
00953 texinfonum = brush->sides[i].texinfo;
00954 if (Q1_TextureContents(map_texinfo[texinfonum].texture) == brush->side) break;
00955 } //end for
00956 //if no specific contents texture was found
00957 if (i >= brush->numsides)
00958 {
00959 texinfonum = -1;
00960 for (i = 0; i < map_numtexinfo; i++)
00961 {
00962 if (Q1_TextureContents(map_texinfo[i].texture) == brush->side)
00963 {
00964 texinfonum = i;
00965 break;
00966 } //end if
00967 } //end for
00968 } //end if
00969 //
00970 if (texinfonum >= 0)
00971 {
00972 //give all the brush sides this contents texture
00973 for (i = 0; i < brush->numsides; i++)
00974 {
00975 brush->sides[i].texinfo = texinfonum;
00976 } //end for
00977 } //end if
00978 else Log_Print("brush contents %d with wrong textures\n", brush->side);
00979 //
00980 } //end for
00981 /*
00982 for (brush = brushlist; brush; brush = brush->next)
00983 {
00984 //give all the brush sides this contents texture
00985 for (i = 0; i < brush->numsides; i++)
00986 {
00987 if (Q1_TextureContents(map_texinfo[texinfonum].texture) != brush->side)
00988 {
00989 Error("brush contents %d with wrong contents textures %s\n", brush->side,
00990 Q1_TextureContents(map_texinfo[texinfonum].texture));
00991 } //end if
00992 } //end for
00993 } //end for*/
00994 } //end of the function Q1_FixContentsTextures
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1125 of file map_q1.c. References atoi, ClearBounds(), entities, entity_t::firstbrush, i, length(), loadedmaptype, Log_Print(), map_maxs, map_mins, entity_t::numbrushes, nummapbrushes, offset, Q1_CreateMapBrushes(), Q1_LoadBSPFile(), q1_numclipbrushes, Q1_ParseEntities(), qprintf(), strcmp(), and ValueForKey(). Referenced by LoadMapFromBSP(). 01126 {
01127 int i, modelnum;
01128 char *model, *classname;
01129
01130 Log_Print("-- Q1_LoadMapFromBSP --\n");
01131 //the loaded map type
01132 loadedmaptype = MAPTYPE_QUAKE1;
01133 //
01134 qprintf("loading map from %s at %d\n", filename, offset);
01135 //load the Half-Life BSP file
01136 Q1_LoadBSPFile(filename, offset, length);
01137 //
01138 q1_numclipbrushes = 0;
01139 //CreatePath(path);
01140 //Q1_CreateQ2WALFiles(path);
01141 //parse the entities from the BSP
01142 Q1_ParseEntities();
01143 //clear the map mins and maxs
01144 ClearBounds(map_mins, map_maxs);
01145 //
01146 qprintf("creating Quake1 brushes\n");
01147 if (lessbrushes) qprintf("creating minimum number of brushes\n");
01148 else qprintf("placing textures correctly\n");
01149 //
01150 for (i = 0; i < num_entities; i++)
01151 {
01152 entities[i].firstbrush = nummapbrushes;
01153 entities[i].numbrushes = 0;
01154 //
01155 classname = ValueForKey(&entities[i], "classname");
01156 if (classname && !strcmp(classname, "worldspawn"))
01157 {
01158 modelnum = 0;
01159 } //end if
01160 else
01161 {
01162 //
01163 model = ValueForKey(&entities[i], "model");
01164 if (!model || *model != '*') continue;
01165 model++;
01166 modelnum = atoi(model);
01167 } //end else
01168 //create map brushes for the entity
01169 Q1_CreateMapBrushes(&entities[i], modelnum);
01170 } //end for
01171 //
01172 qprintf("%5d map brushes\n", nummapbrushes);
01173 qprintf("%5d clip brushes\n", q1_numclipbrushes);
01174 } //end of the function Q1_LoadMapFromBSP
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 563 of file map_q1.c. References bspbrush_t, FreeBrush(), bspbrush_s::next, qprintf(), bspbrush_s::side, and TryMergeBrushes(). Referenced by Q1_CreateMapBrushes(). 00564 {
00565 int nummerges, merged;
00566 bspbrush_t *b1, *b2, *tail, *newbrush, *newbrushlist;
00567 bspbrush_t *lastb2;
00568
00569 if (!brushlist) return NULL;
00570
00571 if (!modelnum) qprintf("%5d brushes merged", nummerges = 0);
00572 do
00573 {
00574 for (tail = brushlist; tail; tail = tail->next)
00575 {
00576 if (!tail->next) break;
00577 } //end for
00578 merged = 0;
00579 newbrushlist = NULL;
00580 for (b1 = brushlist; b1; b1 = brushlist)
00581 {
00582 lastb2 = b1;
00583 for (b2 = b1->next; b2; b2 = b2->next)
00584 {
00585 //can't merge brushes with different contents
00586 if (b1->side != b2->side) newbrush = NULL;
00587 else newbrush = TryMergeBrushes(b1, b2);
00588 //if a merged brush is created
00589 if (newbrush)
00590 {
00591 //copy the brush contents
00592 newbrush->side = b1->side;
00593 //add the new brush to the end of the list
00594 tail->next = newbrush;
00595 //remove the second brush from the list
00596 lastb2->next = b2->next;
00597 //remove the first brush from the list
00598 brushlist = brushlist->next;
00599 //free the merged brushes
00600 FreeBrush(b1);
00601 FreeBrush(b2);
00602 //get a new tail brush
00603 for (tail = brushlist; tail; tail = tail->next)
00604 {
00605 if (!tail->next) break;
00606 } //end for
00607 merged++;
00608 if (!modelnum) qprintf("\r%5d", nummerges++);
00609 break;
00610 } //end if
00611 lastb2 = b2;
00612 } //end for
00613 //if b1 can't be merged with any of the other brushes
00614 if (!b2)
00615 {
00616 brushlist = brushlist->next;
00617 //keep b1
00618 b1->next = newbrushlist;
00619 newbrushlist = b1;
00620 } //end else
00621 } //end for
00622 brushlist = newbrushlist;
00623 } while(merged);
00624 if (!modelnum) qprintf("\n");
00625 return newbrushlist;
00626 } //end of the function Q1_MergeBrushes
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 481 of file map_q1.c. References q1_dnode_t::children, q1_dplane_t::dist, DotProduct, q1_dplane_t::normal, q1_dnode_t::planenum, point, q1_dleafs, q1_dnodes, q1_dplanes, and vec_t. 00482 {
00483 int nodenum;
00484 vec_t dist;
00485 q1_dnode_t *node;
00486 q1_dplane_t *plane;
00487
00488 nodenum = startnode;
00489 while (nodenum >= 0)
00490 {
00491 node = &q1_dnodes[nodenum];
00492 plane = &q1_dplanes[node->planenum];
00493 dist = DotProduct(point, plane->normal) - plane->dist;
00494 if (dist > 0)
00495 nodenum = node->children[0];
00496 else
00497 nodenum = node->children[1];
00498 } //end while
00499
00500 return &q1_dleafs[-nodenum - 1];
00501 } //end of the function Q1_PointInLeaf
|
|
|
Definition at line 1116 of file map_q1.c. 01117 {
01118 } //end of the function Q1_ResetMapLoading
|
|
|
Definition at line 265 of file map_q1.c. References q1_dleaf_t::contents, Q1_CONTENTS_EMPTY, Q1_CONTENTS_LAVA, Q1_CONTENTS_SKY, Q1_CONTENTS_SLIME, Q1_CONTENTS_SOLID, Q1_CONTENTS_WATER, q1_dleafs, and q1_dnodes. 00266 {
00267 if (nodenum < 0)
00268 {
00269 switch(q1_dleafs[(-nodenum) - 1].contents)
00270 {
00271 case Q1_CONTENTS_EMPTY:
00272 {
00273 return false;
00274 } //end case
00275 case Q1_CONTENTS_SOLID:
00276 #ifdef HLCONTENTS
00277 case Q1_CONTENTS_CLIP:
00278 #endif HLCONTENTS
00279 case Q1_CONTENTS_SKY:
00280 #ifdef HLCONTENTS
00281 case Q1_CONTENTS_TRANSLUCENT:
00282 #endif HLCONTENTS
00283 {
00284 return true;
00285 } //end case
00286 case Q1_CONTENTS_WATER:
00287 case Q1_CONTENTS_SLIME:
00288 case Q1_CONTENTS_LAVA:
00289 #ifdef HLCONTENTS
00290 //these contents should not be found in the BSP
00291 case Q1_CONTENTS_ORIGIN:
00292 case Q1_CONTENTS_CURRENT_0:
00293 case Q1_CONTENTS_CURRENT_90:
00294 case Q1_CONTENTS_CURRENT_180:
00295 case Q1_CONTENTS_CURRENT_270:
00296 case Q1_CONTENTS_CURRENT_UP:
00297 case Q1_CONTENTS_CURRENT_DOWN:
00298 #endif HLCONTENTS
00299 default:
00300 {
00301 return false;
00302 } //end default
00303 } //end switch
00304 return false;
00305 } //end if
00306 if (!Q1_SolidTree_r(q1_dnodes[nodenum].children[0])) return false;
00307 if (!Q1_SolidTree_r(q1_dnodes[nodenum].children[1])) return false;
00308 return true;
00309 } //end of the function Q1_SolidTree_r
|
|
||||||||||||||||||||||||
|
Definition at line 63 of file map_q1.c. References AllocBrush(), b, BaseWindingForPlane(), BoundBrush(), BrushMostlyOnSide(), BrushVolume(), bspbrush_t, ChopWindingInPlace(), ClipWindingEpsilon(), CopyBrush(), CopyWinding(), d, plane_t::dist, DotProduct, side_s::flags, FreeBrush(), FreeWinding(), i, j, Log_Print(), mapplanes, bspbrush_s::maxs, bspbrush_s::mins, plane_t::normal, winding_t::numpoints, bspbrush_s::numsides, bspbrush_s::original, winding_t::p, side_s::planenum, s, side_t, bspbrush_s::sides, side_s::surf, side_s::texinfo, v1, vec_t, w, side_s::winding, WindingIsHuge(), and WindingIsTiny(). Referenced by Q1_CreateBrushes_r(). 00065 {
00066 bspbrush_t *b[2];
00067 int i, j;
00068 winding_t *w, *cw[2], *midwinding;
00069 plane_t *plane, *plane2;
00070 side_t *s, *cs;
00071 float d, d_front, d_back;
00072
00073 *front = *back = NULL;
00074 plane = &mapplanes[planenum];
00075
00076 // check all points
00077 d_front = d_back = 0;
00078 for (i=0 ; i<brush->numsides ; i++)
00079 {
00080 w = brush->sides[i].winding;
00081 if (!w)
00082 continue;
00083 for (j=0 ; j<w->numpoints ; j++)
00084 {
00085 d = DotProduct (w->p[j], plane->normal) - plane->dist;
00086 if (d > 0 && d > d_front)
00087 d_front = d;
00088 if (d < 0 && d < d_back)
00089 d_back = d;
00090 } //end for
00091 } //end for
00092
00093 if (d_front < 0.1) // PLANESIDE_EPSILON)
00094 { // only on back
00095 *back = CopyBrush (brush);
00096 Log_Print("Q1_SplitBrush: only on back\n");
00097 return;
00098 } //end if
00099 if (d_back > -0.1) // PLANESIDE_EPSILON)
00100 { // only on front
00101 *front = CopyBrush (brush);
00102 Log_Print("Q1_SplitBrush: only on front\n");
00103 return;
00104 } //end if
00105
00106 // create a new winding from the split plane
00107
00108 w = BaseWindingForPlane (plane->normal, plane->dist);
00109 for (i = 0; i < brush->numsides && w; i++)
00110 {
00111 plane2 = &mapplanes[brush->sides[i].planenum ^ 1];
00112 ChopWindingInPlace(&w, plane2->normal, plane2->dist, 0); // PLANESIDE_EPSILON);
00113 } //end for
00114
00115 if (!w || WindingIsTiny(w))
00116 { // the brush isn't really split
00117 int side;
00118
00119 Log_Print("Q1_SplitBrush: no split winding\n");
00120 side = BrushMostlyOnSide (brush, plane);
00121 if (side == PSIDE_FRONT)
00122 *front = CopyBrush (brush);
00123 if (side == PSIDE_BACK)
00124 *back = CopyBrush (brush);
00125 return;
00126 }
00127
00128 if (WindingIsHuge(w))
00129 {
00130 Log_Print("Q1_SplitBrush: WARNING huge split winding\n");
00131 } //end of
00132
00133 midwinding = w;
00134
00135 // split it for real
00136
00137 for (i = 0; i < 2; i++)
00138 {
00139 b[i] = AllocBrush (brush->numsides+1);
00140 b[i]->original = brush->original;
00141 } //end for
00142
00143 // split all the current windings
00144
00145 for (i=0 ; i<brush->numsides ; i++)
00146 {
00147 s = &brush->sides[i];
00148 w = s->winding;
00149 if (!w)
00150 continue;
00151 ClipWindingEpsilon (w, plane->normal, plane->dist,
00152 0 /*PLANESIDE_EPSILON*/, &cw[0], &cw[1]);
00153 for (j=0 ; j<2 ; j++)
00154 {
00155 if (!cw[j])
00156 continue;
00157 #if 0
00158 if (WindingIsTiny (cw[j]))
00159 {
00160 FreeWinding (cw[j]);
00161 continue;
00162 }
00163 #endif
00164 cs = &b[j]->sides[b[j]->numsides];
00165 b[j]->numsides++;
00166 *cs = *s;
00167 // cs->planenum = s->planenum;
00168 // cs->texinfo = s->texinfo;
00169 // cs->visible = s->visible;
00170 // cs->original = s->original;
00171 cs->winding = cw[j];
00172 cs->flags &= ~SFL_TESTED;
00173 } //end for
00174 } //end for
00175
00176
00177 // see if we have valid polygons on both sides
00178
00179 for (i=0 ; i<2 ; i++)
00180 {
00181 BoundBrush (b[i]);
00182 for (j=0 ; j<3 ; j++)
00183 {
00184 if (b[i]->mins[j] < -4096 || b[i]->maxs[j] > 4096)
00185 {
00186 Log_Print("Q1_SplitBrush: bogus brush after clip\n");
00187 break;
00188 } //end if
00189 } //end for
00190
00191 if (b[i]->numsides < 3 || j < 3)
00192 {
00193 FreeBrush (b[i]);
00194 b[i] = NULL;
00195 Log_Print("Q1_SplitBrush: numsides < 3\n");
00196 } //end if
00197 } //end for
00198
00199 if ( !(b[0] && b[1]) )
00200 {
00201 if (!b[0] && !b[1])
00202 Log_Print("Q1_SplitBrush: split removed brush\n");
00203 else
00204 Log_Print("Q1_SplitBrush: split not on both sides\n");
00205 if (b[0])
00206 {
00207 FreeBrush (b[0]);
00208 *front = CopyBrush (brush);
00209 } //end if
00210 if (b[1])
00211 {
00212 FreeBrush (b[1]);
00213 *back = CopyBrush (brush);
00214 } //end if
00215 return;
00216 } //end if
00217
00218 // add the midwinding to both sides
00219 for (i = 0; i < 2; i++)
00220 {
00221 cs = &b[i]->sides[b[i]->numsides];
00222 b[i]->numsides++;
00223
00224 cs->planenum = planenum^i^1;
00225 cs->texinfo = 0;
00226 //store the node number in the surf to find the texinfo later on
00227 cs->surf = nodenum;
00228 //
00229 cs->flags &= ~SFL_VISIBLE;
00230 cs->flags &= ~SFL_TESTED;
00231 cs->flags &= ~SFL_TEXTURED;
00232 if (i==0)
00233 cs->winding = CopyWinding (midwinding);
00234 else
00235 cs->winding = midwinding;
00236 } //end for
00237
00238
00239 {
00240 vec_t v1;
00241 int i;
00242
00243 for (i=0 ; i<2 ; i++)
00244 {
00245 v1 = BrushVolume (b[i]);
00246 if (v1 < 1)
00247 {
00248 FreeBrush (b[i]);
00249 b[i] = NULL;
00250 Log_Print("Q1_SplitBrush: tiny volume after clip\n");
00251 } //end if
00252 } //end for
00253 } //*/
00254
00255 *front = b[0];
00256 *back = b[1];
00257 } //end of the function Q1_SplitBrush
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 685 of file map_q1.c. References abs(), bspbrush_t, CrossProduct(), q1_dplane_t::dist, DotProduct, FindFloatPlane(), q1_dface_t::firstedge, FreeBrush(), FreeBrushList(), i, Log_Print(), memcpy(), bspbrush_s::next, q1_dplane_t::normal, q1_dface_t::numedges, q1_dface_t::planenum, q1_dvertex_t::point, q1_dedges, q1_dplanes, q1_dsurfedges, q1_dvertexes, bspbrush_s::side, q1_dface_t::side, SplitBrush(), q1_dedge_t::v, v1, v2, vec3_t, vec_t, VectorNegate, VectorNormalize(), and VectorSubtract. Referenced by Q1_TextureBrushes(). 00686 {
00687 |