int FPortal::PointOnShapeLineSide(fixed_t x, fixed_t y, int shapeindex) { int shapeindex2 = (shapeindex+1)%Shape.Size(); return DMulScale32(y - Shape[shapeindex]->y, Shape[shapeindex2]->x - Shape[shapeindex]->x, Shape[shapeindex]->x - x, Shape[shapeindex2]->y - Shape[shapeindex]->y); }
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; WallTX1 = DMulScale20 (tx1, viewsin, -ty1, viewcos); WallTX2 = DMulScale20 (tx2, viewsin, -ty2, viewcos); WallTY1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin); WallTY2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin); if (MirrorFlags & RF_XFLIP) { int t = 256-WallTX1; WallTX1 = 256-WallTX2; WallTX2 = t; swap (WallTY1, WallTY2); } if (WallTX1 >= -WallTY1) { if (WallTX1 > WallTY1) return; // left edge is off the right side if (WallTY1 == 0) return; WallSX1 = (centerxfrac + Scale (WallTX1, centerxfrac, WallTY1)) >> FRACBITS; if (WallTX1 >= 0) WallSX1 = MIN (viewwidth, WallSX1+1); // fix for signed divide WallSZ1 = WallTY1; } else { if (WallTX2 < -WallTY2) return; // wall is off the left side
void ADynamicLight::CollectWithinRadius(subsector_t *subSec, float radius) { if (!subSec) return; subSec->validcount = ::validcount; touching_subsectors = AddLightNode(&subSec->lighthead, subSec, this, touching_subsectors); if (subSec->sector->validcount != ::validcount) { touching_sector = AddLightNode(&subSec->render_sector->lighthead, subSec->sector, this, touching_sector); subSec->sector->validcount = ::validcount; } for (unsigned int i = 0; i < subSec->numlines; i++) { seg_t * seg = subSec->firstline + i; if (seg->sidedef && seg->linedef && seg->linedef->validcount!=::validcount) { // light is in front of the seg if (DMulScale32 (y-seg->v1->y, seg->v2->x-seg->v1->x, seg->v1->x-x, seg->v2->y-seg->v1->y) <=0) { seg->linedef->validcount=validcount; touching_sides = AddLightNode(&seg->sidedef->lighthead, seg->sidedef, this, touching_sides); } } seg_t *partner = seg->PartnerSeg; if (partner) { subsector_t *sub = partner->Subsector; if (sub != NULL && sub->validcount!=::validcount) { // check distance from x/y to seg and if within radius add opposing subsector (lather/rinse/repeat) if (DistToSeg(seg) <= radius) { CollectWithinRadius(sub, radius); } } } } }
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; } }
int PolyCull::PointOnSide(const DVector2 &pos, const node_t *node) { return DMulScale32(FLOAT2FIXED(pos.Y) - node->y, node->dx, node->x - FLOAT2FIXED(pos.X), node->dy) > 0; }