From 66d287ea81a3435d03688a42f7e758a71f3bc3f5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 8 Dec 2016 10:16:22 +0100 Subject: [PATCH 1/4] - fixed: Stepping through a ceiling portal on a two-sided line did not work. - fixed: Stepping up an actor checked against the sector's own ceiling, even if it was a crossable portal. --- src/p_map.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 16a5933d5..f889069f1 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -860,6 +860,20 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec FLineOpening open; P_LineOpening(open, tm.thing, ld, ref, &cres.Position, cres.portalflags); + if (!tm.thing->Sector->PortalBlocksMovement(sector_t::ceiling)) + { + sector_t *oppsec = cres.line->frontsector == tm.thing->Sector ? cres.line->backsector : cres.line->frontsector; + if (oppsec->PortalBlocksMovement(sector_t::ceiling)) + { + double portz = tm.thing->Sector->GetPortalPlaneZ(sector_t::ceiling); + if (tm.thing->Z() < portz && tm.thing->Z() + tm.thing->MaxStepHeight >= portz && tm.floorz < portz) + { + // Actor is stepping through a portal. + tm.portalstep = true; + return true; + } + } + } // [RH] Steep sectors count as dropoffs, if the actor touches the boundary between a steep slope and something else if (!(tm.thing->flags & MF_DROPOFF) && @@ -2130,7 +2144,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, goto pushline; } else if (BlockingMobj->Top() - thing->Z() > thing->MaxStepHeight - || (BlockingMobj->Sector->ceilingplane.ZatPoint(pos) - (BlockingMobj->Top()) < thing->Height) + || ((BlockingMobj->Sector->ceilingplane.ZatPoint(pos) - (BlockingMobj->Top()) < thing->Height) && BlockingMobj->Sector->PortalBlocksMovement(sector_t::ceiling)) || (tm.ceilingz - (BlockingMobj->Top()) < thing->Height)) { goto pushline; From 3aac058022285f01021f011129614c38837c6260 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Thu, 8 Dec 2016 12:07:12 +0200 Subject: [PATCH 2/4] Fixed loading of Hexen and Strife Names in sprite offsets files for these IWADs contain '[' and '\' characters and such names need to be quoted --- wadsrc/static/filter/hexen/sprofs.txt | 2 +- wadsrc/static/filter/strife/sprofs.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/wadsrc/static/filter/hexen/sprofs.txt b/wadsrc/static/filter/hexen/sprofs.txt index a8d614ca0..4408e3b95 100644 --- a/wadsrc/static/filter/hexen/sprofs.txt +++ b/wadsrc/static/filter/hexen/sprofs.txt @@ -57,7 +57,7 @@ CLERW0, 37, 53, iwad CLERX0, 37, 43, iwad CLERY0, 38, 30, iwad CLERZ0, 38, 18, iwad -CLER[0, 38, 12, iwad +"CLER[0", 38, 12, iwad CPB1A0, 8, 7, iwad CPB2A0, 7, 6, iwad CPB3A0, 12, 4, iwad diff --git a/wadsrc/static/filter/strife/sprofs.txt b/wadsrc/static/filter/strife/sprofs.txt index d7118297b..c6dafb581 100644 --- a/wadsrc/static/filter/strife/sprofs.txt +++ b/wadsrc/static/filter/strife/sprofs.txt @@ -200,8 +200,8 @@ PGRDW0, 35, 28, iwad PGRDX0, 35, 28, iwad PGRDY0, 35, 28, iwad PGRDZ0, 35, 28, iwad -PGRD[0, 35, 28, iwad -PGRD\0, 35, 28, iwad +"PGRD[0", 35, 28, iwad +"PGRD\0", 35, 28, iwad PDEDE0, 22, 20, iwad PDEDF0, 23, 16, iwad PDEDG0, 23, 15, iwad From d741e0eb26744a9b3bbd62fe01011b8fd0edc812 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 8 Dec 2016 11:23:08 +0100 Subject: [PATCH 3/4] - fixed: P_CheckSight returned incorrect results when having to traverse the collected lines just for adding more portals to the list. --- src/p_sight.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/p_sight.cpp b/src/p_sight.cpp index 21aa1bbe3..df02e2ebb 100644 --- a/src/p_sight.cpp +++ b/src/p_sight.cpp @@ -716,6 +716,7 @@ bool SightCheck::P_SightPathTraverse () // step through map blocks // Count is present to prevent a round off error from skipping the break + int itres; for (count = 0 ; count < 1000 ; count++) { // end traversing when reaching the end of the blockmap @@ -724,15 +725,15 @@ bool SightCheck::P_SightPathTraverse () { break; } - int res = P_SightBlockLinesIterator(mapx, mapy); - if (res == 0) + itres = P_SightBlockLinesIterator(mapx, mapy); + if (itres == 0) { sightcounts[1]++; return false; // early out } // either reached the end or had an early-out condition with portals left to check, - if (res == -1 || (mapxstep | mapystep) == 0) + if (itres == -1 || (mapxstep | mapystep) == 0) break; switch (((xs_FloorToInt(yintercept) == mapy) << 1) | (xs_FloorToInt(xintercept) == mapx)) @@ -787,7 +788,9 @@ sightcounts[1]++; // sightcounts[2]++; - return P_SightTraverseIntercepts ( ); + bool traverseres = P_SightTraverseIntercepts ( ); + if (itres == -1) return false; // if the iterator had an early out there was no line of sight. The traverser was only called to collect more portals. + return traverseres; } /* From 3558b2234c273abf461f5b3bcd30ad2dfb749daa Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 8 Dec 2016 12:49:40 +0100 Subject: [PATCH 4/4] - fixed: The dynamic light setup for walls did not portal-translate the light's coordinate. - changed ADynamicLight::CollectWithinRadius to work iteratively to avoid the high stack overhead of 64 bit code. --- src/gl/dynlights/a_dynlight.cpp | 136 +++++++++++++++++++------------- src/gl/scene/gl_walls_draw.cpp | 7 +- 2 files changed, 85 insertions(+), 58 deletions(-) diff --git a/src/gl/dynlights/a_dynlight.cpp b/src/gl/dynlights/a_dynlight.cpp index 45e8bfb14..0ab834505 100644 --- a/src/gl/dynlights/a_dynlight.cpp +++ b/src/gl/dynlights/a_dynlight.cpp @@ -582,81 +582,107 @@ double ADynamicLight::DistToSeg(const DVector3 &pos, seg_t *seg) // to sidedefs and sector parts. // //========================================================================== +struct LightLinkEntry +{ + subsector_t *sub; + DVector3 pos; +}; +static TArray collected_ss; -void ADynamicLight::CollectWithinRadius(const DVector3 &pos, subsector_t *subSec, float radius) +void ADynamicLight::CollectWithinRadius(const DVector3 &opos, subsector_t *subSec, float radius) { if (!subSec) return; - + collected_ss.Clear(); + collected_ss.Push({ subSec, opos }); subSec->validcount = ::validcount; - touching_subsectors = AddLightNode(&subSec->lighthead, subSec, this, touching_subsectors); - if (subSec->sector->validcount != ::validcount) + for (unsigned i = 0; i < collected_ss.Size(); i++) { - touching_sector = AddLightNode(&subSec->render_sector->lighthead, subSec->sector, this, touching_sector); - subSec->sector->validcount = ::validcount; - } + subSec = collected_ss[i].sub; + auto &pos = collected_ss[i].pos; - for (unsigned int i = 0; i < subSec->numlines; i++) - { - seg_t * seg = subSec->firstline + i; - - // check distance from x/y to seg and if within radius add this seg and, if present the opposing subsector (lather/rinse/repeat) - // If out of range we do not need to bother with this seg. - if (DistToSeg(pos, seg) <= radius) + touching_subsectors = AddLightNode(&subSec->lighthead, subSec, this, touching_subsectors); + if (subSec->sector->validcount != ::validcount) { - if (seg->sidedef && seg->linedef && seg->linedef->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; + + // check distance from x/y to seg and if within radius add this seg and, if present the opposing subsector (lather/rinse/repeat) + // If out of range we do not need to bother with this seg. + if (DistToSeg(pos, seg) <= radius) { - // light is in front of the seg - if ((pos.Y - seg->v1->fY()) * (seg->v2->fX() - seg->v1->fX()) + (seg->v1->fX() - pos.X) * (seg->v2->fY() - seg->v1->fY()) <= 0) + if (seg->sidedef && seg->linedef && seg->linedef->validcount != ::validcount) { - seg->linedef->validcount = validcount; - touching_sides = AddLightNode(&seg->sidedef->lighthead, seg->sidedef, this, touching_sides); - } - } - if (seg->linedef) - { - FLinePortal *port = seg->linedef->getPortal(); - if (port && port->mType == PORTT_LINKED) - { - line_t *other = port->mDestination; - if (other->validcount != ::validcount) + // light is in front of the seg + if ((pos.Y - seg->v1->fY()) * (seg->v2->fX() - seg->v1->fX()) + (seg->v1->fX() - pos.X) * (seg->v2->fY() - seg->v1->fY()) <= 0) { - subsector_t *othersub = R_PointInSubsector(other->v1->fPos() + other->Delta() / 2); - if (othersub->validcount != ::validcount) CollectWithinRadius(PosRelative(other), othersub, radius); + seg->linedef->validcount = validcount; + touching_sides = AddLightNode(&seg->sidedef->lighthead, seg->sidedef, this, touching_sides); + } + } + if (seg->linedef) + { + FLinePortal *port = seg->linedef->getPortal(); + if (port && port->mType == PORTT_LINKED) + { + line_t *other = port->mDestination; + if (other->validcount != ::validcount) + { + subsector_t *othersub = R_PointInSubsector(other->v1->fPos() + other->Delta() / 2); + if (othersub->validcount != ::validcount) + { + othersub->validcount = ::validcount; + collected_ss.Push({ othersub, PosRelative(other) }); + } + } + } + } + + seg_t *partner = seg->PartnerSeg; + if (partner) + { + subsector_t *sub = partner->Subsector; + if (sub != NULL && sub->validcount != ::validcount) + { + sub->validcount = ::validcount; + collected_ss.Push({ sub, pos }); } } } - - seg_t *partner = seg->PartnerSeg; - if (partner) + } + sector_t *sec = subSec->sector; + if (!sec->PortalBlocksSight(sector_t::ceiling)) + { + line_t *other = subSec->firstline->linedef; + if (sec->GetPortalPlaneZ(sector_t::ceiling) < Z() + radius) { - subsector_t *sub = partner->Subsector; - if (sub != NULL && sub->validcount != ::validcount) + DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::ceiling); + subsector_t *othersub = R_PointInSubsector(refpos); + if (othersub->validcount != ::validcount) { - CollectWithinRadius(pos, sub, radius); + othersub->validcount = ::validcount; + collected_ss.Push({ othersub, PosRelative(othersub->sector) }); } } } - } - sector_t *sec = subSec->sector; - if (!sec->PortalBlocksSight(sector_t::ceiling)) - { - line_t *other = subSec->firstline->linedef; - if (sec->GetPortalPlaneZ(sector_t::ceiling) < Z() + radius) + if (!sec->PortalBlocksSight(sector_t::floor)) { - DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::ceiling); - subsector_t *othersub = R_PointInSubsector(refpos); - if (othersub->validcount != ::validcount) CollectWithinRadius(PosRelative(othersub->sector), othersub, radius); - } - } - if (!sec->PortalBlocksSight(sector_t::floor)) - { - line_t *other = subSec->firstline->linedef; - if (sec->GetPortalPlaneZ(sector_t::floor) > Z() - radius) - { - DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::floor); - subsector_t *othersub = R_PointInSubsector(refpos); - if (othersub->validcount != ::validcount) CollectWithinRadius(PosRelative(othersub->sector), othersub, radius); + line_t *other = subSec->firstline->linedef; + if (sec->GetPortalPlaneZ(sector_t::floor) > Z() - radius) + { + DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::floor); + subsector_t *othersub = R_PointInSubsector(refpos); + if (othersub->validcount != ::validcount) + { + othersub->validcount = ::validcount; + collected_ss.Push({ othersub, PosRelative(othersub->sector) }); + } + } } } } diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index d392439e7..f166a2ce1 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -102,9 +102,10 @@ void GLWall::SetupLights() Vector fn, pos; - float x = node->lightsource->X(); - float y = node->lightsource->Y(); - float z = node->lightsource->Z(); + DVector3 posrel = node->lightsource->PosRelative(seg->frontsector); + float x = posrel.X; + float y = posrel.Y; + float z = posrel.Z; float dist = fabsf(p.DistToPoint(x, z, y)); float radius = node->lightsource->GetRadius(); float scale = 1.0f / ((2.f * radius) - dist);