From 8c1eb201eb97d142b083c5987aeac3dfc94df4d5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 18 Apr 2016 12:54:55 +0200 Subject: [PATCH 1/4] - optimized P_PointInSubsector. It costs more to convert the floating point coordinate for each node check than to convert it once up front and only use fixed point math afterward. --- src/p_glnodes.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index becd1f3be..bc96f14bd 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -1344,9 +1344,11 @@ subsector_t *P_PointInSubsector (double x, double y) node = gamenodes + numgamenodes - 1; + fixed_t xx = FLOAT2FIXED(x); + fixed_t yy = FLOAT2FIXED(y); do { - side = R_PointOnSide (x, y, node); + side = R_PointOnSide (xx, yy, node); node = (node_t *)node->children[side]; } while (!((size_t)node & 1)); From c30d5d42a299209454b5dca7ba5f2b36286e6950 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 18 Apr 2016 12:56:16 +0200 Subject: [PATCH 2/4] - fixed: UpdateSectorRenderList may not be called when spawning mapthings. At this time the portals have not been initialized yet and doing this here would trash the cached previous coordinate. --- src/p_maputl.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index f3dda49a9..8ee251316 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -396,14 +396,19 @@ bool AActor::FixMapthingPos() void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) { - if (spawningmapthing && (flags4 & MF4_FIXMAPTHINGPOS) && sector == NULL) + bool spawning = spawningmapthing; + + if (spawning) { - if (FixMapthingPos()) spawningmapthing = false; + if ((flags4 & MF4_FIXMAPTHINGPOS) && sector == NULL) + { + if (FixMapthingPos()) spawning = false; + } } if (sector == NULL) { - if (!spawningmapthing || numgamenodes == 0) + if (!spawning || numgamenodes == 0) { sector = P_PointInSector(Pos()); } @@ -499,7 +504,8 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) } } } - UpdateRenderSectorList(); + // Portal links cannot be done unless the level is fully initialized. + if (!spawningmapthing) UpdateRenderSectorList(); } void AActor::SetOrigin(double x, double y, double z, bool moving) From 42e88ef1206bcaacd43f4435f9bc21c5f5cf3d41 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 18 Apr 2016 12:58:40 +0200 Subject: [PATCH 3/4] - removed sector_t::FloorDisplacement and CeilingDisplacement. Using the values these return directly is just as much code. --- src/p_sectors.cpp | 8 ++++---- src/r_defs.h | 11 ----------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 357b60872..50925f57a 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -897,7 +897,7 @@ double sector_t::HighestCeilingAt(const DVector2 &p, sector_t **resultsec) // Continue until we find a blocking portal or a portal below where we actually are. while (!check->PortalBlocksMovement(ceiling) && planeheight < check->SkyBoxes[ceiling]->specialf1) { - pos += check->CeilingDisplacement(); + pos += check->SkyBoxes[ceiling]->Scale; planeheight = check->SkyBoxes[ceiling]->specialf1; check = P_PointInSector(pos); } @@ -920,7 +920,7 @@ double sector_t::LowestFloorAt(const DVector2 &p, sector_t **resultsec) // Continue until we find a blocking portal or a portal above where we actually are. while (!check->PortalBlocksMovement(floor) && planeheight > check->SkyBoxes[floor]->specialf1) { - pos += check->FloorDisplacement(); + pos += check->SkyBoxes[floor]->Scale; planeheight = check->SkyBoxes[floor]->specialf1; check = P_PointInSector(pos); } @@ -964,7 +964,7 @@ double sector_t::NextHighestCeilingAt(double x, double y, double bottomz, double } else { - DVector2 pos = sec->CeilingDisplacement(); + DVector2 pos = sec->SkyBoxes[ceiling]->Scale; x += pos.X; y += pos.Y; planeheight = sec->SkyBoxes[ceiling]->specialf1; @@ -1009,7 +1009,7 @@ double sector_t::NextLowestFloorAt(double x, double y, double z, int flags, doub } else { - DVector2 pos = sec->FloorDisplacement(); + DVector2 pos = sec->SkyBoxes[floor]->Scale; x += pos.X; y += pos.Y; planeheight = sec->SkyBoxes[floor]->specialf1; diff --git a/src/r_defs.h b/src/r_defs.h index 79af0929f..9be31e184 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -957,17 +957,6 @@ public: return (SkyBoxes[plane] != NULL && SkyBoxes[plane]->special1 == SKYBOX_LINKEDPORTAL); } - // These may only be called if the portal has been validated - DVector2 FloorDisplacement() - { - return Displacements.getOffset(PortalGroup, SkyBoxes[sector_t::floor]->Sector->PortalGroup); - } - - DVector2 CeilingDisplacement() - { - return Displacements.getOffset(PortalGroup, SkyBoxes[sector_t::ceiling]->Sector->PortalGroup); - } - int GetTerrain(int pos) const; void TransferSpecial(sector_t *model); From 961a4c852476e7513028612568276b2c760c409f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 18 Apr 2016 13:38:56 +0200 Subject: [PATCH 4/4] - optimized sector portal checks. All the PortalBlocks* functions were turned into real function calls which for such a frequent check should be avoided. So now any linked portal sets a flag in the attached sectors so that it isn't necessary to check the skybox pointer each time which makes the functions subject to inlining again. --- src/portal.cpp | 7 +++++-- src/r_defs.h | 10 ++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/portal.cpp b/src/portal.cpp index 1be08fc85..12c40e47d 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -932,7 +932,7 @@ void P_CreateLinkedPortals() { // The engine cannot deal with portals on a sloped plane. sectors[i].SkyBoxes[j] = NULL; - Printf("Portal on %s of sector %d is sloped and will be disabled\n", j == 0 ? "floor" : "ceiling", i); + Printf("Portal on %s of sector %d is sloped and will be disabled\n", j == 0 ? "floor" : "ceiling", i); } } } @@ -1057,7 +1057,7 @@ void P_CreateLinkedPortals() // This is a fatal condition. We have to remove one of the two portals. Choose the one that doesn't match the current plane Printf("Error in sector %d: Ceiling portal at z=%f is below floor portal at z=%f\n", i, cz, fz); double cp = -sectors[i].ceilingplane.fD(); - double fp = -sectors[i].ceilingplane.fD(); + double fp = sectors[i].floorplane.fD(); if (cp < fp || fz == fp) { sectors[i].SkyBoxes[sector_t::ceiling] = NULL; @@ -1068,6 +1068,9 @@ void P_CreateLinkedPortals() } } } + // mark all sector planes that check out ok for everything. + if (sectors[i].PortalIsLinked(sector_t::floor)) sectors[i].planes[sector_t::floor].Flags |= PLANEF_LINKED; + if (sectors[i].PortalIsLinked(sector_t::ceiling)) sectors[i].planes[sector_t::ceiling].Flags |= PLANEF_LINKED; } if (linkedPortals.Size() > 0) { diff --git a/src/r_defs.h b/src/r_defs.h index 9be31e184..bfb521a27 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -484,6 +484,7 @@ enum PLANEF_BLOCKSOUND = 32, PLANEF_DISABLED = 64, PLANEF_OBSTRUCTED = 128, // if the portal plane is beyond the sector's floor or ceiling. + PLANEF_LINKED = 256 // plane is flagged as a linked portal }; // Internal sector flags @@ -936,20 +937,17 @@ public: bool PortalBlocksSight(int plane) { - if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; - return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); + return PLANEF_LINKED != (planes[plane].Flags & (PLANEF_NORENDER | PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED | PLANEF_LINKED)); } bool PortalBlocksMovement(int plane) { - if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; - return !!(planes[plane].Flags & (PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); + return PLANEF_LINKED != (planes[plane].Flags & (PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED | PLANEF_LINKED)); } bool PortalBlocksSound(int plane) { - if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; - return !!(planes[plane].Flags & (PLANEF_BLOCKSOUND | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); + return PLANEF_LINKED != (planes[plane].Flags & (PLANEF_BLOCKSOUND | PLANEF_DISABLED | PLANEF_OBSTRUCTED | PLANEF_LINKED)); } bool PortalIsLinked(int plane)