int HWLinePortal::ClipSeg(seg_t *seg, const DVector3 &viewpos) { line_t *linedef = seg->linedef; if (!linedef) { return PClip_Inside; // should be handled properly. } return P_ClipLineToPortal(linedef, line(), viewpos) ? PClip_InFront : PClip_Inside; }
int GLLinePortal::ClipSeg(seg_t *seg) { line_t *linedef = seg->linedef; if (!linedef) { return PClip_Inside; // should be handled properly. } return P_ClipLineToPortal(linedef, line(), ViewPos) ? PClip_InFront : PClip_Inside; }
void FarClipLine::Render(seg_t *line, subsector_t *subsector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane, Fake3DOpaque opaque3dfloor) { mSubsector = subsector; mFrontSector = mSubsector->sector; mLineSegment = line; mFloorPlane = linefloorplane; mCeilingPlane = lineceilingplane; m3DFloor = opaque3dfloor; DVector2 pt1 = line->v1->fPos() - Thread->Viewport->viewpoint.Pos; DVector2 pt2 = line->v2->fPos() - Thread->Viewport->viewpoint.Pos; // Reject lines not facing viewer if (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0) return; if (WallC.Init(Thread, pt1, pt2, 32.0 / (1 << 12))) return; RenderPortal *renderportal = Thread->Portal.get(); if (WallC.sx1 >= renderportal->WindowRight || WallC.sx2 <= renderportal->WindowLeft) return; if (line->linedef == nullptr) return; // reject lines that aren't seen from the portal (if any) // [ZZ] 10.01.2016: lines inside a skybox shouldn't be clipped, although this imposes some limitations on portals in skyboxes. if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && P_ClipLineToPortal(line->linedef, renderportal->CurrentPortal->dst, Thread->Viewport->viewpoint.Pos)) return; mFrontCeilingZ1 = mFrontSector->ceilingplane.ZatPoint(line->v1); mFrontFloorZ1 = mFrontSector->floorplane.ZatPoint(line->v1); mFrontCeilingZ2 = mFrontSector->ceilingplane.ZatPoint(line->v2); mFrontFloorZ2 = mFrontSector->floorplane.ZatPoint(line->v2); mPrepped = false; Thread->ClipSegments->Clip(WallC.sx1, WallC.sx2, true, this); }
void R_AddLine (seg_t *line) { static sector_t tempsec; // killough 3/8/98: ceiling/water hack bool solid; fixed_t tx1, tx2, ty1, ty2; curline = line; // [RH] Color if not texturing line dc_color = (((int)(line - segs) * 8) + 4) & 255; tx1 = line->v1->x - viewx; tx2 = line->v2->x - viewx; ty1 = line->v1->y - viewy; ty2 = line->v2->y - viewy; // Reject lines not facing viewer if (DMulScale32 (ty1, tx1-tx2, tx1, ty2-ty1) >= 0) return; if (WallC.Init(tx1, ty1, tx2, ty2, 32)) return; if (WallC.sx1 >= WindowRight || WallC.sx2 <= WindowLeft) return; if (line->linedef == NULL) { if (R_CheckClipWallSegment (WallC.sx1, WallC.sx2)) { InSubsector->flags |= SSECF_DRAWN; } return; } // reject lines that aren't seen from the portal (if any) // [ZZ] 10.01.2016: lines inside a skybox shouldn't be clipped, although this imposes some limitations on portals in skyboxes. if (!CurrentPortalInSkybox && CurrentPortal && P_ClipLineToPortal(line->linedef, CurrentPortal->dst, viewx, viewy)) return; vertex_t *v1, *v2; v1 = line->linedef->v1; v2 = line->linedef->v2; if ((v1 == line->v1 && v2 == line->v2) || (v2 == line->v1 && v1 == line->v2)) { // The seg is the entire wall. WallT.InitFromWallCoords(&WallC); } else { // The seg is only part of the wall. if (line->linedef->sidedef[0] != line->sidedef) { swapvalues (v1, v2); } WallT.InitFromLine(v1->x - viewx, v1->y - viewy, v2->x - viewx, v2->y - viewy); } if (!(fake3D & FAKE3D_FAKEBACK)) { backsector = line->backsector; } rw_frontcz1 = frontsector->ceilingplane.ZatPoint (line->v1->x, line->v1->y); rw_frontfz1 = frontsector->floorplane.ZatPoint (line->v1->x, line->v1->y); rw_frontcz2 = frontsector->ceilingplane.ZatPoint (line->v2->x, line->v2->y); rw_frontfz2 = frontsector->floorplane.ZatPoint (line->v2->x, line->v2->y); rw_mustmarkfloor = rw_mustmarkceiling = false; rw_havehigh = rw_havelow = false; // Single sided line? if (backsector == NULL || (line->linedef->isVisualPortal() && line->sidedef == line->linedef->sidedef[0])) { solid = true; } else { // kg3D - its fake, no transfer_heights if (!(fake3D & FAKE3D_FAKEBACK)) { // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water backsector = R_FakeFlat (backsector, &tempsec, NULL, NULL, true); } doorclosed = 0; // killough 4/16/98 rw_backcz1 = backsector->ceilingplane.ZatPoint (line->v1->x, line->v1->y); rw_backfz1 = backsector->floorplane.ZatPoint (line->v1->x, line->v1->y); rw_backcz2 = backsector->ceilingplane.ZatPoint (line->v2->x, line->v2->y); rw_backfz2 = backsector->floorplane.ZatPoint (line->v2->x, line->v2->y); // Cannot make these walls solid, because it can result in // sprite clipping problems for sprites near the wall if (rw_frontcz1 > rw_backcz1 || rw_frontcz2 > rw_backcz2) { rw_havehigh = true; WallMost (wallupper, backsector->ceilingplane, &WallC); } if (rw_frontfz1 < rw_backfz1 || rw_frontfz2 < rw_backfz2) { rw_havelow = true; WallMost (walllower, backsector->floorplane, &WallC); } // Closed door. if ((rw_backcz1 <= rw_frontfz1 && rw_backcz2 <= rw_frontfz2) || (rw_backfz1 >= rw_frontcz1 && rw_backfz2 >= rw_frontcz2)) { solid = true; } else if ( // properly render skies (consider door "open" if both ceilings are sky): (backsector->GetTexture(sector_t::ceiling) != skyflatnum || frontsector->GetTexture(sector_t::ceiling) != skyflatnum) // if door is closed because back is shut: && rw_backcz1 <= rw_backfz1 && rw_backcz2 <= rw_backfz2 // preserve a kind of transparent door/lift special effect: && ((rw_backcz1 >= rw_frontcz1 && rw_backcz2 >= rw_frontcz2) || line->sidedef->GetTexture(side_t::top).isValid()) && ((rw_backfz1 <= rw_frontfz1 && rw_backfz2 <= rw_frontfz2) || line->sidedef->GetTexture(side_t::bottom).isValid())) { // killough 1/18/98 -- This function is used to fix the automap bug which // showed lines behind closed doors simply because the door had a dropoff. // // It assumes that Doom has already ruled out a door being closed because // of front-back closure (e.g. front floor is taller than back ceiling). // This fixes the automap floor height bug -- killough 1/18/98: // killough 4/7/98: optimize: save result in doorclosed for use in r_segs.c doorclosed = true; solid = true; } else if (frontsector->ceilingplane != backsector->ceilingplane || frontsector->floorplane != backsector->floorplane) { // Window. solid = false; } else if (backsector->lightlevel != frontsector->lightlevel || backsector->GetTexture(sector_t::floor) != frontsector->GetTexture(sector_t::floor) || backsector->GetTexture(sector_t::ceiling) != frontsector->GetTexture(sector_t::ceiling) || curline->sidedef->GetTexture(side_t::mid).isValid() // killough 3/7/98: Take flats offsets into account: || backsector->GetXOffset(sector_t::floor) != frontsector->GetXOffset(sector_t::floor) || backsector->GetYOffset(sector_t::floor) != frontsector->GetYOffset(sector_t::floor) || backsector->GetXOffset(sector_t::ceiling) != frontsector->GetXOffset(sector_t::ceiling) || backsector->GetYOffset(sector_t::ceiling) != frontsector->GetYOffset(sector_t::ceiling) || backsector->GetPlaneLight(sector_t::floor) != frontsector->GetPlaneLight(sector_t::floor) || backsector->GetPlaneLight(sector_t::ceiling) != frontsector->GetPlaneLight(sector_t::ceiling) || backsector->GetFlags(sector_t::floor) != frontsector->GetFlags(sector_t::floor) || backsector->GetFlags(sector_t::ceiling) != frontsector->GetFlags(sector_t::ceiling) // [RH] Also consider colormaps || backsector->ColorMap != frontsector->ColorMap // [RH] and scaling || backsector->GetXScale(sector_t::floor) != frontsector->GetXScale(sector_t::floor) || backsector->GetYScale(sector_t::floor) != frontsector->GetYScale(sector_t::floor) || backsector->GetXScale(sector_t::ceiling) != frontsector->GetXScale(sector_t::ceiling) || backsector->GetYScale(sector_t::ceiling) != frontsector->GetYScale(sector_t::ceiling) // [RH] and rotation || backsector->GetAngle(sector_t::floor) != frontsector->GetAngle(sector_t::floor) || backsector->GetAngle(sector_t::ceiling) != frontsector->GetAngle(sector_t::ceiling) // kg3D - and fake lights || (frontsector->e && frontsector->e->XFloor.lightlist.Size()) || (backsector->e && backsector->e->XFloor.lightlist.Size()) ) { solid = false; } else { // Reject empty lines used for triggers and special events. // Identical floor and ceiling on both sides, identical light levels // on both sides, and no middle texture. // When using GL nodes, do a clipping test for these lines so we can // mark their subsectors as visible for automap texturing. if (hasglnodes && !(InSubsector->flags & SSECF_DRAWN)) { if (R_CheckClipWallSegment(WallC.sx1, WallC.sx2)) { InSubsector->flags |= SSECF_DRAWN; } } return; } } rw_prepped = false; if (line->linedef->special == Line_Horizon) { // Be aware: Line_Horizon does not work properly with sloped planes clearbufshort (walltop+WallC.sx1, WallC.sx2 - WallC.sx1, centery); clearbufshort (wallbottom+WallC.sx1, WallC.sx2 - WallC.sx1, centery); } else { rw_ceilstat = WallMost (walltop, frontsector->ceilingplane, &WallC); rw_floorstat = WallMost (wallbottom, frontsector->floorplane, &WallC); // [RH] treat off-screen walls as solid #if 0 // Maybe later... if (!solid) { if (rw_ceilstat == 12 && line->sidedef->GetTexture(side_t::top) != 0) { rw_mustmarkceiling = true; solid = true; } if (rw_floorstat == 3 && line->sidedef->GetTexture(side_t::bottom) != 0) { rw_mustmarkfloor = true; solid = true; } } #endif } if (R_ClipWallSegment (WallC.sx1, WallC.sx2, solid)) { InSubsector->flags |= SSECF_DRAWN; } }