void PolyCull::CullScene(const TriMatrix &worldToClip, const PolyClipPlane &portalClipPlane) { PvsSectors.clear(); PortalClipPlane = portalClipPlane; // Cull front to back FirstSkyHeight = true; MaxCeilingHeight = 0.0; MinFloorHeight = 0.0; if (level.nodes.Size() == 0) CullSubsector(&level.subsectors[0]); else CullNode(level.HeadNode()); }
void PolyCull::CullScene(const PolyClipPlane &portalClipPlane) { ClearSolidSegments(); MarkViewFrustum(); if (level.LevelName != lastLevelName) // Is this the best way to detect a level change? { lastLevelName = level.LevelName; SubsectorDepths.clear(); SubsectorDepths.resize(level.subsectors.Size(), 0xffffffff); SectorSeen.clear(); SectorSeen.resize(level.sectors.Size()); } else { for (const auto &sub : PvsSectors) SubsectorDepths[sub->Index()] = 0xffffffff; SubsectorDepths.resize(level.subsectors.Size(), 0xffffffff); for (const auto §or : SeenSectors) SectorSeen[sector->Index()] = false; SectorSeen.resize(level.sectors.Size()); } PvsSectors.clear(); SeenSectors.clear(); NextPvsLineStart = 0; PvsLineStart.clear(); PvsLineVisible.resize(level.segs.Size()); PortalClipPlane = portalClipPlane; // Cull front to back FirstSkyHeight = true; MaxCeilingHeight = 0.0; MinFloorHeight = 0.0; if (level.nodes.Size() == 0) CullSubsector(&level.subsectors[0]); else CullNode(level.HeadNode()); }
void PolyCull::CullNode(void *node) { while (!((size_t)node & 1)) // Keep going until found a subsector { node_t *bsp = (node_t *)node; // Decide which side the view point is on. int side = PointOnSide(ViewPos, bsp); // Recursively divide front space (toward the viewer). CullNode(bsp->children[side]); // Possibly divide back space (away from the viewer). side ^= 1; if (!CheckBBox(bsp->bbox[side])) return; node = bsp->children[side]; } // Mark that we need to render this subsector_t *sub = (subsector_t *)((BYTE *)node - 1); MaxCeilingHeight = MAX(MaxCeilingHeight, sub->sector->ceilingplane.Zat0()); MinFloorHeight = MIN(MinFloorHeight, sub->sector->floorplane.Zat0()); PvsSectors.push_back(sub); // Update culling info for further bsp clipping for (uint32_t i = 0; i < sub->numlines; i++) { seg_t *line = &sub->firstline[i]; if ((line->sidedef == nullptr || !(line->sidedef->Flags & WALLF_POLYOBJ)) && line->backsector == nullptr) { int sx1, sx2; if (GetSegmentRangeForLine(line->v1->fX(), line->v1->fY(), line->v2->fX(), line->v2->fY(), sx1, sx2)) { MarkSegmentCulled(sx1, sx2); } } } }
void PolyCull::CullScene(const TriMatrix &worldToClip) { ClearSolidSegments(); PvsSectors.clear(); frustumPlanes = FrustumPlanes(worldToClip); // Cull front to back if (numnodes == 0) { PvsSectors.push_back(subsectors); MaxCeilingHeight = subsectors->sector->ceilingplane.Zat0(); MinFloorHeight = subsectors->sector->floorplane.Zat0(); } else { MaxCeilingHeight = 0.0; MinFloorHeight = 0.0; CullNode(nodes + numnodes - 1); // The head node is the last node output. } ClearSolidSegments(); }
void PolyCull::CullNode(void *node) { while (!((size_t)node & 1)) // Keep going until found a subsector { node_t *bsp = (node_t *)node; // Decide which side the view point is on. int side = PointOnSide(PolyRenderer::Instance()->Viewpoint.Pos, bsp); // Recursively divide front space (toward the viewer). CullNode(bsp->children[side]); // Possibly divide back space (away from the viewer). side ^= 1; if (!CheckBBox(bsp->bbox[side])) return; node = bsp->children[side]; } subsector_t *sub = (subsector_t *)((uint8_t *)node - 1); CullSubsector(sub); }