face_t *MergeFaceToList (face_t *face, face_t *list) { face_t *newf, *f; for (f=list ; f ; f=f->next) { //CheckColinear (f); if (mergedebug) { Draw_ClearWindow (); Draw_DrawFace (face); Draw_DrawFace (f); Draw_SetBlack (); } newf = TryMerge (face, f); if (!newf) continue; FreeFace (face); f->numpoints = -1; // merged out return MergeFaceToList (newf, list); } // didn't merge, so add at start face->next = list; return face; }
/* ============ BoundWorld ============ */ void BoundWorld (void) { int i; brushhull_t *h; ClearBounds (world_mins, world_maxs); for (i=0 ; i<nummapbrushes ; i++) { h = &mapbrushes[i].hulls[0]; if (!h->faces) continue; AddPointToBounds (h->mins, world_mins, world_maxs); AddPointToBounds (h->maxs, world_mins, world_maxs); } qprintf ("World bounds: (%i %i %i) to (%i %i %i)\n", (int)world_mins[0],(int)world_mins[1],(int)world_mins[2], (int)world_maxs[0],(int)world_maxs[1],(int)world_maxs[2]); VectorCopy (world_mins, draw_mins); VectorCopy (world_maxs, draw_maxs); Draw_ClearWindow (); }
/* ================ MakeHeadnodePortals The created portals will face the global outside_node ================ */ void MakeHeadnodePortals (node_t *node) { vec3_t bounds[2]; int i, j, n; portal_t *p, *portals[6]; plane_t bplanes[6], *pl; int side; Draw_ClearWindow (); // pad with some space so there will never be null volume leafs for (i=0 ; i<3 ; i++) { bounds[0][i] = brushset->mins[i] - SIDESPACE; bounds[1][i] = brushset->maxs[i] + SIDESPACE; } outside_node.contents = CONTENTS_SOLID; outside_node.portals = NULL; for (i=0 ; i<3 ; i++) for (j=0 ; j<2 ; j++) { n = j*3 + i; p = AllocPortal (); portals[n] = p; pl = &bplanes[n]; memset (pl, 0, sizeof(*pl)); if (j) { pl->normal[i] = -1; pl->dist = -bounds[j][i]; } else { pl->normal[i] = 1; pl->dist = bounds[j][i]; } p->planenum = FindPlane (pl, &side); p->winding = BaseWindingForPlane (pl); if (side) AddPortalToNodes (p, &outside_node, node); else AddPortalToNodes (p, node, &outside_node); } // clip the basewindings by all the other planes for (i=0 ; i<6 ; i++) { for (j=0 ; j<6 ; j++) { if (j == i) continue; portals[i]->winding = ClipWinding (portals[i]->winding, &bplanes[j], true); } } }
/* ================ DrawEdges ================ */ static void DrawEdges( optIsland_t* island ) { // optEdge_t *edge; if( !dmapGlobals.drawflag ) { return; } #if 0 Draw_ClearWindow(); qglBegin( GL_LINES ); for( edge = island->edges ; edge ; edge = edge->islandLink ) { if( edge->v1 == NULL ) { continue; } qglColor3f( 1, 0, 0 ); qglVertex3fv( edge->v1->pv.ToFloatPtr() ); qglColor3f( 0, 0, 0 ); qglVertex3fv( edge->v2->pv.ToFloatPtr() ); } qglEnd(); qglFlush(); // GLimp_SwapBuffers(); #endif }
/* ================ DrawAllEdges ================ */ static void DrawAllEdges() { // int i; if( !dmapGlobals.drawflag ) { return; } #if 0 Draw_ClearWindow(); qglBegin( GL_LINES ); for( i = 0 ; i < numOptEdges ; i++ ) { if( optEdges[i].v1 == NULL ) { continue; } qglColor3f( 1, 0, 0 ); qglVertex3fv( optEdges[i].v1->pv.ToFloatPtr() ); qglColor3f( 0, 0, 0 ); qglVertex3fv( optEdges[i].v2->pv.ToFloatPtr() ); } qglEnd(); qglFlush(); // GLimp_SwapBuffers(); #endif }
/* ================== DrawSurfaces ================== */ void DrawSurfaces (surface_t *surf) { face_t *f; Draw_ClearWindow (); for ( ; surf ; surf=surf->next) { for (f = surf->faces ; f ; f=f->next) { Draw_DrawFace (f); } } }
/* ================= DrawOriginalEdges ================= */ static void DrawOriginalEdges( int numOriginalEdges, originalEdges_t *originalEdges ) { int i; if ( !dmapGlobals.drawflag ) { return; } Draw_ClearWindow(); qglBegin( GL_LINES ); for ( i = 0 ; i < numOriginalEdges ; i++ ) { qglColor3f( 1, 0, 0 ); qglVertex3fv( originalEdges[i].v1->pv.ToFloatPtr() ); qglColor3f( 0, 0, 0 ); qglVertex3fv( originalEdges[i].v2->pv.ToFloatPtr() ); } qglEnd(); qglFlush(); }
/* ================== SolidBSP Takes a chain of surfaces plus a split type, and returns a bsp tree with faces off the nodes. The original surface chain will be completely freed. ================== */ node_t *SolidBSP (surfchain_t *surfhead) { int i; node_t *headnode; qprintf ("----- SolidBSP -----\n"); headnode = AllocNode (); headnode->surfaces = surfhead->surfaces; Draw_ClearWindow (); c_splitnodes = 0; c_nodefaces = 0; c_leaffaces = 0; if (!surfhead->surfaces) { // nothing at all to build headnode->planenum = -1; headnode->contents = CONTENTS_EMPTY; return headnode; } // // generate six portals that enclose the entire world // MakeHeadnodePortals (headnode, surfhead->mins, surfhead->maxs); // // recursively partition everything // BuildBspTree_r (headnode); qprintf ("%5i split nodes\n", c_splitnodes); qprintf ("%5i node faces\n", c_nodefaces); qprintf ("%5i leaf faces\n", c_leaffaces); return headnode; }
/* ============ MergeAll ============ */ void MergeAll (surface_t *surfhead) { surface_t *surf; int mergefaces; face_t *f; printf ("---- MergeAll ----\n"); mergefaces = 0; for (surf = surfhead ; surf ; surf=surf->next) { MergePlaneFaces (surf); Draw_ClearWindow (); for (f=surf->faces ; f ; f=f->next) { Draw_DrawFace (f); mergefaces++; } } printf ("%i mergefaces\n", mergefaces); }
/* ================ NumberLeafs_r ================ */ void NumberLeafs_r (node_t *node) { portal_t *p; if (!node->contents) { // decision node node->visleafnum = -99; NumberLeafs_r (node->children[0]); NumberLeafs_r (node->children[1]); return; } Draw_ClearWindow (); DrawLeaf (node, 1); if (node->contents == CONTENTS_SOLID) { // solid block, viewpoint never inside node->visleafnum = -1; return; } node->visleafnum = num_visleafs++; for (p = node->portals ; p ; ) { if (p->nodes[0] == node) // only write out from first leaf { if ( (watervis && p->nodes[0]->contents != CONTENTS_SOLID && p->nodes[1]->contents != CONTENTS_SOLID) || (p->nodes[0]->contents == p->nodes[1]->contents) ) num_visportals++; p = p->next[0]; } else p = p->next[1]; } }
/* ================== CSGFaces Returns a list of surfaces containing aall of the faces ================== */ surface_t *CSGFaces (brushset_t *bs) { brush_t *b1, *b2; int i; qboolean overwrite; face_t *f; surface_t *surfhead; qprintf ("---- CSGFaces ----\n"); memset (validfaces, 0, sizeof(validfaces)); csgfaces = brushfaces = csgmergefaces = 0; Draw_ClearWindow (); // // do the solid faces // for (b1 = bs->brushes ; b1 ; b1 = b1->next) { // set outside to a copy of the brush's faces CopyFacesToOutside (b1); overwrite = false; for (b2 = bs->brushes ; b2 ; b2 = b2->next) { // see if b2 needs to clip a chunk out of b1 if (b1 == b2) { overwrite = true; // later brushes now overwrite continue; } // check bounding box first for (i = 0 ; i < 3 ; i++) if (b1->mins[i] > b2->maxs[i] || b1->maxs[i] < b2->mins[i]) break; if (i < 3) continue; // divide faces by the planes of the new brush inside = outside; outside = NULL; for (f = b2->faces ; f ; f = f->next) ClipInside (f->planenum, f->planeside, overwrite); // these faces are continued in another brush, so get rid of them if (b1->contents == CONTENTS_SOLID && b2->contents <= CONTENTS_WATER) FreeInside (b2->contents); else FreeInside (CONTENTS_SOLID); } // all of the faces left in outside are real surface faces if (b1->contents != CONTENTS_SOLID) SaveOutside (true); // mirror faces for inside view else SaveOutside (false); } #if 0 if (!csgfaces) Error ("No faces"); #endif surfhead = BuildSurfaces (); qprintf ("%5i brushfaces\n", brushfaces); qprintf ("%5i csgfaces\n", csgfaces); qprintf ("%5i mergedfaces\n", csgmergefaces); return surfhead; }