- did some profiling which revealed that P_PointInSector was called needlessly often. Did some optimization to the MultiBlock iterators to avoid this problem.

This commit is contained in:
Christoph Oelckers 2016-03-10 14:22:18 +01:00
parent 3063312f7f
commit 3d367d585d
7 changed files with 27 additions and 21 deletions

View file

@ -576,6 +576,6 @@ DThinker *FThinkerIterator::Next ()
ADD_STAT (think) ADD_STAT (think)
{ {
FString out; 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; return out;
} }

View file

@ -2607,7 +2607,7 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates)
FPortalGroupArray check(FPortalGroupArray::PGA_Full3d); 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; FMultiBlockThingsIterator::CheckResult cres;
while (it.Next(&cres)) while (it.Next(&cres))
{ {

View file

@ -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. // P_LineOpening requires the thing's z to be the destination z in order to work.
fixed_t savedz = thing->Z(); fixed_t savedz = thing->Z();
thing->SetZ(z); thing->SetZ(z);
sector_t *sector = P_PointInSector(x, y);
FPortalGroupArray grouplist; 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; FMultiBlockLinesIterator::CheckResult cres;
while (mit.Next(&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; 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; FMultiBlockThingsIterator::CheckResult cres2;
while (mit2.Next(&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); FBoundingBox box(x, y, thing->radius);
FPortalGroupArray pcheck; 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; FMultiBlockThingsIterator::CheckResult tcres;
while ((it2.Next(&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(); spechit.Clear();
portalhit.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; FMultiBlockLinesIterator::CheckResult lcres;
fixed_t thingdropoffz = tm.floorz; fixed_t thingdropoffz = tm.floorz;
@ -5258,7 +5259,7 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo
double bombdamagefloat = (double)bombdamage; double bombdamagefloat = (double)bombdamage;
FPortalGroupArray grouplist(FPortalGroupArray::PGA_Full3d); 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; FMultiBlockThingsIterator::CheckResult cres;
if (flags & RADF_SOURCEISSPOT) if (flags & RADF_SOURCEISSPOT)

View file

@ -741,16 +741,19 @@ FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, AAc
if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->Top(), checkradius, checklist); if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->Top(), checkradius, checklist);
checkpoint.z = checkradius == -1? origin->radius : checkradius; checkpoint.z = checkradius == -1? origin->radius : checkradius;
basegroup = origin->Sector->PortalGroup; basegroup = origin->Sector->PortalGroup;
startsector = origin->Sector;
Reset(); 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) : checklist(check)
{ {
checkpoint.x = checkx; checkpoint.x = checkx;
checkpoint.y = checky; checkpoint.y = checky;
checkpoint.z = checkz; 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); if (!check.inited) P_CollectConnectedGroups(basegroup, checkpoint, checkz + checkh, checkradius, checklist);
checkpoint.z = checkradius; checkpoint.z = checkradius;
Reset(); Reset();
@ -766,10 +769,9 @@ bool FMultiBlockLinesIterator::GoUp(fixed_t x, fixed_t y)
{ {
if (continueup) if (continueup)
{ {
sector_t *sector = P_PointInSector(x, y); if (!cursector->PortalBlocksMovement(sector_t::ceiling))
if (!sector->PortalBlocksMovement(sector_t::ceiling))
{ {
startIteratorForGroup(sector->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup); startIteratorForGroup(cursector->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup);
portalflags = FFCF_NOFLOOR; portalflags = FFCF_NOFLOOR;
return true; return true;
} }
@ -788,10 +790,9 @@ bool FMultiBlockLinesIterator::GoDown(fixed_t x, fixed_t y)
{ {
if (continuedown) if (continuedown)
{ {
sector_t *sector = P_PointInSector(x, y); if (!cursector->PortalBlocksMovement(sector_t::floor))
if (!sector->PortalBlocksMovement(sector_t::floor))
{ {
startIteratorForGroup(sector->SkyBoxes[sector_t::floor]->Sector->PortalGroup); startIteratorForGroup(cursector->SkyBoxes[sector_t::floor]->Sector->PortalGroup);
portalflags = FFCF_NOCEILING; portalflags = FFCF_NOCEILING;
return true; return true;
} }
@ -871,6 +872,7 @@ void FMultiBlockLinesIterator::startIteratorForGroup(int group)
offset = Displacements.getOffset(basegroup, group); offset = Displacements.getOffset(basegroup, group);
offset.x += checkpoint.x; offset.x += checkpoint.x;
offset.y += checkpoint.y; offset.y += checkpoint.y;
cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset.x, offset.y);
bbox.setBox(offset.x, offset.y, checkpoint.z); bbox.setBox(offset.x, offset.y, checkpoint.z);
blockIterator.init(bbox); blockIterator.init(bbox);
} }
@ -1076,13 +1078,14 @@ FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, A
Reset(); 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) : checklist(check)
{ {
checkpoint.x = checkx; checkpoint.x = checkx;
checkpoint.y = checky; checkpoint.y = checky;
checkpoint.z = checkz; 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); if (!check.inited) P_CollectConnectedGroups(basegroup, checkpoint, checkz + checkh, checkradius, checklist);
checkpoint.z = checkradius; checkpoint.z = checkradius;
Reset(); Reset();

View file

@ -218,6 +218,8 @@ class FMultiBlockLinesIterator
FPortalGroupArray &checklist; FPortalGroupArray &checklist;
fixedvec3 checkpoint; fixedvec3 checkpoint;
fixedvec2 offset; fixedvec2 offset;
sector_t *startsector;
sector_t *cursector;
short basegroup; short basegroup;
short portalflags; short portalflags;
short index; short index;
@ -240,7 +242,7 @@ public:
}; };
FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius = -1); 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); bool Next(CheckResult *item);
void Reset(); 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. // 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, 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); bool Next(CheckResult *item);
void Reset(); void Reset();
const FBoundingBox &Box() const const FBoundingBox &Box() const

View file

@ -2250,7 +2250,7 @@ void DPusher::Tick ()
// point pusher. Crosses sectors, so use blockmap. // point pusher. Crosses sectors, so use blockmap.
FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); // no sector portals because this thing is utterly z-unaware. 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; FMultiBlockThingsIterator::CheckResult cres;

View file

@ -5583,7 +5583,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
{ {
FPortalGroupArray check(FPortalGroupArray::PGA_Full3d); FPortalGroupArray check(FPortalGroupArray::PGA_Full3d);
fixed_t mid = self->Z() + self->height / 2; 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; FMultiBlockThingsIterator::CheckResult cres;
while ((it.Next(&cres))) while ((it.Next(&cres)))