bool AddSeg(seg_t *seg) { FGLSectionLine &line = SectionLines[SectionLines.Reserve(1)]; bool firstline = loop->numlines == 0; if (ISDONE(seg-segs, processed_segs)) { // should never happen! DPrintf("Tried to add seg %d to Sections twice. Cannot create Sections.\n", seg-segs); return false; } SETDONE(seg-segs, processed_segs); section_for_segs[seg-segs] = Sections.Size()-1; line.start = seg->v1; line.end = seg->v2; line.sidedef = seg->sidedef; line.linedef = seg->linedef; line.refseg = seg; line.polysub = NULL; line.otherside = -1; if (loop->numlines == 0) { v1_l1 = seg->v1; v2_l1 = seg->v2; } loop->numlines++; return true; }
//============================================================================= // // all segs and subsectors must be grouped into Sections // //============================================================================= bool CheckSections() { bool res = true; for (int i = 0; i < numsegs; i++) { if (segs[i].sidedef != NULL && !ISDONE(i, processed_segs) && !IntraSectorSeg(&segs[i])) { Printf("Seg %d (Linedef %d) not processed during section creation\n", i, segs[i].linedef-lines); res = false; } } for (int i = 0; i < numsubsectors; i++) { if (!ISDONE(i, processed_subsectors)) { Printf("Subsector %d (Sector %d) not processed during section creation\n", i, subsectors[i].sector-sectors); res = false; } } return res; }
//============================================================================= // // // //============================================================================= bool CreateSections() { int pick = 0; MarkInternalSubsectors(); while (pick < numsubsectors) { if (ISDONE(pick, processed_subsectors)) { pick++; continue; } subsector_t *subsector = &subsectors[pick]; seg_t *workseg = NULL; vertex_t *startpt = NULL; NewSection(subsector->render_sector); while (1) { if (!ISDONE(subsector-subsectors, processed_subsectors)) { SETDONE(subsector-subsectors, processed_subsectors); section->subsectors.Push(subsector); SectionForSubsector[subsector - subsectors] = int(section - &Sections[0]); } bool result = AddSubSector(subsector, startpt, &workseg); if (!result) { return false; // couldn't create Sections } else if (workseg != NULL) { // crossing into another subsector seg_t *partner = workseg->PartnerSeg; if (workseg->v2 != partner->v1) { DPrintf("Inconsistent subsector references in seg %d. Cannot create Sections.\n", workseg-segs); return false; } subsector = partner->Subsector; startpt = workseg->v1; } else { // loop complete. Check adjoining subsectors for other loops to // be added to this section if (!FindNextSeg(&workseg)) { return false; } else if (workseg == NULL) { // No more subsectors found. This section is complete! FinalizeSection(); break; } else { subsector = workseg->Subsector; // If this is a regular seg, start there, otherwise start // at the subsector's first seg startpt = workseg->sidedef == NULL? NULL : workseg->v1; NewLoop(); } } } } if (!CheckSections()) return false; SetReferences(); Sections.ShrinkToFit(); SectionLoops.ShrinkToFit(); SectionLines.ShrinkToFit(); tesselateSections(); return true; }
//========================================================================== // // returns the seg whose partner seg determines where this // section continues // //========================================================================== bool AddSubSector(subsector_t *subsec, vertex_t *startpt, seg_t **pNextSeg) { unsigned i = 0; if (startpt != NULL) { // find the seg in this subsector that starts at the given vertex for(i = 0; i < subsec->numlines; i++) { if (subsec->firstline[i].v1 == startpt) break; } if (i == subsec->numlines) { DPrintf("Vertex not found in subsector %d. Cannot create Sections.\n", subsec-subsectors); return false; // Nodes are bad } } else { // Find the first unprocessed non-miniseg for(i = 0; i < subsec->numlines; i++) { seg_t *seg = subsec->firstline + i; if (seg->sidedef == NULL) continue; if (IntraSectorSeg(seg)) continue; if (ISDONE(seg-segs, processed_segs)) continue; break; } if (i == subsec->numlines) { DPrintf("Unable to find a start seg. Cannot create Sections.\n"); return false; // Nodes are bad } startpt = subsec->firstline[i].v1; } seg_t *thisseg = subsec->firstline + i; if (IntraSectorSeg(thisseg)) { SETDONE(thisseg-segs, processed_segs); // continue with the loop in the adjoining subsector *pNextSeg = thisseg; return true; } while(1) { if (loop->numlines > 0 && thisseg->v1 == v1_l1 && thisseg->v2 == v2_l1) { // This loop is complete *pNextSeg = NULL; return true; } if (!AddSeg(thisseg)) return NULL; i = (i+1) % subsec->numlines; seg_t *nextseg = subsec->firstline + i; if (thisseg->v2 != nextseg->v1) { DPrintf("Segs in subsector %d are not continuous. Cannot create Sections.\n", subsec-subsectors); return false; // Nodes are bad } if (IntraSectorSeg(nextseg)) { SETDONE(nextseg-segs, processed_segs); // continue with the loop in the adjoining subsector *pNextSeg = nextseg; return true; } thisseg = nextseg; } }