From 3d367d585df63e810606d9cb4ffa8ebdbe0f77cf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 10 Mar 2016 14:22:18 +0100 Subject: [PATCH] - did some profiling which revealed that P_PointInSector was called needlessly often. Did some optimization to the MultiBlock iterators to avoid this problem. --- src/dthinker.cpp | 2 +- src/p_enemy.cpp | 2 +- src/p_map.cpp | 11 ++++++----- src/p_maputl.cpp | 23 +++++++++++++---------- src/p_maputl.h | 6 ++++-- src/p_spec.cpp | 2 +- src/thingdef/thingdef_codeptr.cpp | 2 +- 7 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/dthinker.cpp b/src/dthinker.cpp index 93096b5c3..230d0dd41 100644 --- a/src/dthinker.cpp +++ b/src/dthinker.cpp @@ -576,6 +576,6 @@ DThinker *FThinkerIterator::Next () ADD_STAT (think) { FString out; - out.Format ("Think time = %04.1f ms, Action = %04.1f ms", ThinkCycles.TimeMS(), ActionCycles.TimeMS()); + out.Format ("Think time = %04.2f ms, Action = %04.2f ms", ThinkCycles.TimeMS(), ActionCycles.TimeMS()); return out; } diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 9a7851277..2d8d4980c 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2607,7 +2607,7 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) FPortalGroupArray check(FPortalGroupArray::PGA_Full3d); - FMultiBlockThingsIterator it(check, viletry.x, viletry.y, self->Z() - 64* FRACUNIT, self->Top() + 64 * FRACUNIT, 32 * FRACUNIT); + FMultiBlockThingsIterator it(check, viletry.x, viletry.y, self->Z() - 64* FRACUNIT, self->Top() + 64 * FRACUNIT, 32 * FRACUNIT, false, NULL); FMultiBlockThingsIterator::CheckResult cres; while (it.Next(&cres)) { diff --git a/src/p_map.cpp b/src/p_map.cpp index 181e730b7..0b7d6fc05 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -431,9 +431,10 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra // P_LineOpening requires the thing's z to be the destination z in order to work. fixed_t savedz = thing->Z(); thing->SetZ(z); + sector_t *sector = P_PointInSector(x, y); FPortalGroupArray grouplist; - FMultiBlockLinesIterator mit(grouplist, x, y, z, thing->height, thing->radius); + FMultiBlockLinesIterator mit(grouplist, x, y, z, thing->height, thing->radius, sector); FMultiBlockLinesIterator::CheckResult cres; while (mit.Next(&cres)) @@ -444,7 +445,7 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra if (tmf.touchmidtex) tmf.dropoffz = tmf.floorz; - FMultiBlockThingsIterator mit2(grouplist, x, y, z, thing->height, thing->radius); + FMultiBlockThingsIterator mit2(grouplist, x, y, z, thing->height, thing->radius, false, sector); FMultiBlockThingsIterator::CheckResult cres2; while (mit2.Next(&cres2)) @@ -1670,7 +1671,7 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo FBoundingBox box(x, y, thing->radius); FPortalGroupArray pcheck; - FMultiBlockThingsIterator it2(pcheck, x, y, thing->Z(), thing->height, thing->radius); + FMultiBlockThingsIterator it2(pcheck, x, y, thing->Z(), thing->height, thing->radius, false, newsec); FMultiBlockThingsIterator::CheckResult tcres; while ((it2.Next(&tcres))) @@ -1740,7 +1741,7 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo spechit.Clear(); portalhit.Clear(); - FMultiBlockLinesIterator it(pcheck, x, y, thing->Z(), thing->height, thing->radius); + FMultiBlockLinesIterator it(pcheck, x, y, thing->Z(), thing->height, thing->radius, newsec); FMultiBlockLinesIterator::CheckResult lcres; fixed_t thingdropoffz = tm.floorz; @@ -5258,7 +5259,7 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo double bombdamagefloat = (double)bombdamage; FPortalGroupArray grouplist(FPortalGroupArray::PGA_Full3d); - FMultiBlockThingsIterator it(grouplist, bombspot->X(), bombspot->Y(), bombspot->Z() - bombdistfix, bombspot->height + bombdistfix*2, bombdistfix); + FMultiBlockThingsIterator it(grouplist, bombspot->X(), bombspot->Y(), bombspot->Z() - bombdistfix, bombspot->height + bombdistfix*2, bombdistfix, false, bombspot->Sector); FMultiBlockThingsIterator::CheckResult cres; if (flags & RADF_SOURCEISSPOT) diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 55ce03470..526626b22 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -741,16 +741,19 @@ FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, AAc if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->Top(), checkradius, checklist); checkpoint.z = checkradius == -1? origin->radius : checkradius; basegroup = origin->Sector->PortalGroup; + startsector = origin->Sector; Reset(); } -FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius) +FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, sector_t *newsec) : checklist(check) { checkpoint.x = checkx; checkpoint.y = checky; checkpoint.z = checkz; - basegroup = P_PointInSector(checkx, checky)->PortalGroup; + if (newsec == NULL) newsec = P_PointInSector(checkx, checky); + startsector = newsec; + basegroup = newsec->PortalGroup; if (!check.inited) P_CollectConnectedGroups(basegroup, checkpoint, checkz + checkh, checkradius, checklist); checkpoint.z = checkradius; Reset(); @@ -766,10 +769,9 @@ bool FMultiBlockLinesIterator::GoUp(fixed_t x, fixed_t y) { if (continueup) { - sector_t *sector = P_PointInSector(x, y); - if (!sector->PortalBlocksMovement(sector_t::ceiling)) + if (!cursector->PortalBlocksMovement(sector_t::ceiling)) { - startIteratorForGroup(sector->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup); + startIteratorForGroup(cursector->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup); portalflags = FFCF_NOFLOOR; return true; } @@ -788,10 +790,9 @@ bool FMultiBlockLinesIterator::GoDown(fixed_t x, fixed_t y) { if (continuedown) { - sector_t *sector = P_PointInSector(x, y); - if (!sector->PortalBlocksMovement(sector_t::floor)) + if (!cursector->PortalBlocksMovement(sector_t::floor)) { - startIteratorForGroup(sector->SkyBoxes[sector_t::floor]->Sector->PortalGroup); + startIteratorForGroup(cursector->SkyBoxes[sector_t::floor]->Sector->PortalGroup); portalflags = FFCF_NOCEILING; return true; } @@ -871,6 +872,7 @@ void FMultiBlockLinesIterator::startIteratorForGroup(int group) offset = Displacements.getOffset(basegroup, group); offset.x += checkpoint.x; offset.y += checkpoint.y; + cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset.x, offset.y); bbox.setBox(offset.x, offset.y, checkpoint.z); blockIterator.init(bbox); } @@ -1076,13 +1078,14 @@ FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, A Reset(); } -FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, bool ignorerestricted) +FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, bool ignorerestricted, sector_t *newsec) : checklist(check) { checkpoint.x = checkx; checkpoint.y = checky; checkpoint.z = checkz; - basegroup = P_PointInSector(checkx, checky)->PortalGroup; + if (newsec == NULL) newsec = P_PointInSector(checkx, checky); + basegroup = newsec->PortalGroup; if (!check.inited) P_CollectConnectedGroups(basegroup, checkpoint, checkz + checkh, checkradius, checklist); checkpoint.z = checkradius; Reset(); diff --git a/src/p_maputl.h b/src/p_maputl.h index 7f045c24f..6ef5aa6c8 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -218,6 +218,8 @@ class FMultiBlockLinesIterator FPortalGroupArray &checklist; fixedvec3 checkpoint; fixedvec2 offset; + sector_t *startsector; + sector_t *cursector; short basegroup; short portalflags; short index; @@ -240,7 +242,7 @@ public: }; FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius = -1); - FMultiBlockLinesIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius); + FMultiBlockLinesIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, sector_t *newsec); bool Next(CheckResult *item); void Reset(); // for stopping group traversal through portals. Only the calling code can decide whether this is needed so this needs to be set from the outside. @@ -325,7 +327,7 @@ public: }; FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius = -1, bool ignorerestricted = false); - FMultiBlockThingsIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, bool ignorerestricted = false); + FMultiBlockThingsIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, bool ignorerestricted, sector_t *newsec); bool Next(CheckResult *item); void Reset(); const FBoundingBox &Box() const diff --git a/src/p_spec.cpp b/src/p_spec.cpp index c60529a60..ece79c2fb 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -2250,7 +2250,7 @@ void DPusher::Tick () // point pusher. Crosses sectors, so use blockmap. FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); // no sector portals because this thing is utterly z-unaware. - FMultiBlockThingsIterator it(check, m_X, m_Y, 0, 0, m_Radius); + FMultiBlockThingsIterator it(check, m_X, m_Y, 0, 0, m_Radius, false, m_Source->Sector); FMultiBlockThingsIterator::CheckResult cres; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 072059901..a807fb7fd 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5583,7 +5583,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) { FPortalGroupArray check(FPortalGroupArray::PGA_Full3d); fixed_t mid = self->Z() + self->height / 2; - FMultiBlockThingsIterator it(check, self->X(), self->Y(), mid-distance, mid+distance, distance); + FMultiBlockThingsIterator it(check, self->X(), self->Y(), mid-distance, mid+distance, distance, false, self->Sector); FMultiBlockThingsIterator::CheckResult cres; while ((it.Next(&cres)))