From 02d75723434f9b7d3debc86f9b8d9e62251ce72c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 19 Feb 2016 14:08:41 +0100 Subject: [PATCH] =?UTF-8?q?-=20some=20header=20dependency=20cleanup=20so?= =?UTF-8?q?=20that=20it=20is=20no=20longer=20needed=20to=20include=20porta?= =?UTF-8?q?l.h=20to=20get=20the=20inline=20functions.=20Portal.h=20has=20b?= =?UTF-8?q?een=20reduced=20of=20most=20dependencies=20now=20so=20that=20in?= =?UTF-8?q?cluding=20it=20is=20cheap=20and=20can=20be=20done=20in=20other?= =?UTF-8?q?=20headers.=20-=20some=20consolidation=20in=20p=5Fmap.cpp.=20PI?= =?UTF-8?q?T=5FCheckLine=20and=20PIT=5FFindFloorCeiling=20had=20quite=20a?= =?UTF-8?q?=20bit=20of=20redundancy=20which=20has=20been=20merged.=20-=20?= =?UTF-8?q?=C4=8Dontinued=20work=20on=20FMultiBlockLinesIterator.=20It's?= =?UTF-8?q?=20still=20not=20completely=20finished.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/actor.h | 10 +- src/basictypes.h | 6 ++ src/m_bbox.cpp | 2 +- src/m_bbox.h | 7 +- src/p_acs.cpp | 1 - src/p_buildmap.cpp | 1 - src/p_lnspec.cpp | 1 - src/p_local.h | 2 + src/p_map.cpp | 252 ++++++++++++++++++++++----------------------- src/p_maputl.cpp | 30 ++++-- src/p_maputl.h | 28 ++--- src/p_saveg.cpp | 1 - src/p_sectors.cpp | 5 +- src/p_setup.cpp | 1 - src/p_spec.cpp | 21 ++-- src/p_udmf.cpp | 1 - src/portal.cpp | 7 +- src/portal.h | 90 ---------------- src/r_bsp.cpp | 1 - src/r_bsp.h | 2 +- src/r_defs.h | 87 +++++++++++++--- src/r_main.cpp | 1 - src/r_plane.cpp | 1 - src/r_segs.cpp | 1 - src/r_utility.cpp | 3 +- 25 files changed, 269 insertions(+), 293 deletions(-) diff --git a/src/actor.h b/src/actor.h index 4c636638e..35afef397 100644 --- a/src/actor.h +++ b/src/actor.h @@ -40,6 +40,7 @@ #include "memarena.h" #include "g_level.h" #include "tflags.h" +#include "portal.h" struct subsector_t; class PClassAmmo; @@ -1182,9 +1183,9 @@ public: } fixedvec3 Pos() const { - fixedvec3 ret = { X(), Y(), Z() }; - return ret; + return __pos; } + fixedvec3 PosRelative(AActor *other) const; fixedvec3 PosRelative(sector_t *sec) const; fixedvec3 PosRelative(line_t *line) const; @@ -1366,11 +1367,6 @@ inline fixedvec2 Vec2Angle(fixed_t length, angle_t angle) return ret; } -inline fixedvec3 PosRelative(const fixedvec3 &pos, line_t *line, sector_t *refsec = NULL) -{ - return pos; -} - void PrintMiscActorInfo(AActor * query); AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch, ActorFlags actorMask, DWORD wallMask); diff --git a/src/basictypes.h b/src/basictypes.h index 6caf40a36..ea56e9093 100644 --- a/src/basictypes.h +++ b/src/basictypes.h @@ -126,6 +126,12 @@ inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec3 &v2) return v; } +inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec2 &v2) +{ + fixedvec3 v = { v1.x + v2.x, v1.y + v2.y, v1.z }; + return v; +} + #define FIXED_MAX (signed)(0x7fffffff) #define FIXED_MIN (signed)(0x80000000) diff --git a/src/m_bbox.cpp b/src/m_bbox.cpp index f7827ef72..a8f55e4cf 100644 --- a/src/m_bbox.cpp +++ b/src/m_bbox.cpp @@ -34,7 +34,7 @@ // //========================================================================== -FBoundingBox::FBoundingBox(fixed_t x, fixed_t y, fixed_t radius) +void FBoundingBox::setBox(fixed_t x, fixed_t y, fixed_t radius) { m_Box[BOXTOP] = (fixed_t)MIN((SQWORD)y + radius, FIXED_MAX); m_Box[BOXLEFT] = (fixed_t)MAX((SQWORD)x - radius, FIXED_MIN); diff --git a/src/m_bbox.h b/src/m_bbox.h index 174cd6ecf..c43bb3c79 100644 --- a/src/m_bbox.h +++ b/src/m_bbox.h @@ -43,7 +43,12 @@ public: m_Box[BOXBOTTOM] = bottom; } - FBoundingBox(fixed_t x, fixed_t y, fixed_t radius); + FBoundingBox(fixed_t x, fixed_t y, fixed_t radius) + { + setBox(x, y, radius); + } + + void setBox(fixed_t x, fixed_t y, fixed_t radius); void ClearBox () { diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 9d2899d7e..c6b96252d 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -76,7 +76,6 @@ #include "actorptrselect.h" #include "farchive.h" #include "decallib.h" -#include "portal.h" #include "p_terrain.h" #include "version.h" #include "p_effect.h" diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 116c9ff6d..8d7e75076 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -17,7 +17,6 @@ #include "g_level.h" #include "r_data/colormaps.h" #include "gi.h" -#include "portal.h" #include "p_spec.h" // MACROS ------------------------------------------------------------------ diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 1e45c0fe5..1af76d6d9 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -57,7 +57,6 @@ #include "d_net.h" #include "d_event.h" #include "gstrings.h" -#include "portal.h" #include "po_man.h" #include "d_player.h" #include "r_utility.h" diff --git a/src/p_local.h b/src/p_local.h index c4c5d3914..dac4dbc26 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -288,6 +288,8 @@ enum FFCF_ONLY3DFLOORS = 4, // includes 3D midtexes FFCF_3DRESTRICT = 8, // ignore 3D midtexes and floors whose floorz are above thing's z FFCF_NOPORTALS = 16, // ignore portals (considers them impassable.) + FFCF_NOFLOOR = 32, + FFCF_NOCEILING = 64, }; void P_FindFloorCeiling (AActor *actor, int flags=0); diff --git a/src/p_map.cpp b/src/p_map.cpp index 2b9faa03a..bce8c7739 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -80,6 +80,7 @@ TArray spechit; // Temporary holder for thing_sectorlist threads msecnode_t* sector_list = NULL; // phares 3/16/98 + //========================================================================== // // GetCoefficientClosestPointInLine24 @@ -91,8 +92,9 @@ msecnode_t* sector_list = NULL; // phares 3/16/98 // //========================================================================== -static fixed_t GetCoefficientClosestPointInLine24(line_t *ld, FCheckPosition &tm) +static inline fixed_t GetCoefficientClosestPointInLine24(line_t *ld, fixedvec2 pos) { +#ifndef USE_FLOAT // [EP] Use 64 bit integers in order to keep the exact result of the // multiplication, because in the case the vertexes have both the // distance coordinates equal to the map limit (32767 units, which is @@ -102,8 +104,8 @@ static fixed_t GetCoefficientClosestPointInLine24(line_t *ld, FCheckPosition &tm // fixed_t notation, which is 1.52587890625e-05 in float notation), the // product and the sum can be 1 in the worst case, which is very tiny. - SQWORD r_num = ((SQWORD(tm.x - ld->v1->x)*ld->dx) + - (SQWORD(tm.y - ld->v1->y)*ld->dy)); + SQWORD r_num = ((SQWORD(pos.x - ld->v1->x)*ld->dx) + + (SQWORD(pos.y - ld->v1->y)*ld->dy)); // The denominator is always positive. Use this to avoid useless // calculations. @@ -131,16 +133,58 @@ static fixed_t GetCoefficientClosestPointInLine24(line_t *ld, FCheckPosition &tm // Thanks to the fact that in this code path the denominator is greater // than the numerator, it's possible to avoid this bad situation by // just checking the last 24 bits of the numerator. - if ((r_num >> (63-24)) != 0) { + if ((r_num >> (63 - 24)) != 0) { // [EP] In fact, if the numerator is greater than // (1 << (63-24)), the denominator must be greater than // (1 << (63-24)), hence the denominator won't be zero after // the right shift by 24 places. - return (fixed_t)(r_num/(r_den >> 24)); + return (fixed_t)(r_num / (r_den >> 24)); } // [EP] Having the last 24 bits all zero allows left shifting // the numerator by 24 bits without overflow. - return (fixed_t)((r_num << 24)/r_den); + return (fixed_t)((r_num << 24) / r_den); +#else + double dx = ld->dx; + double dy = ld->dy; + return xs_CRoundToInt(((double)(pos.x - ld->v1->x) * dx + (double)(pos.y - ld->v1->y) * dy) / (dx*dx + dy*dy) * 16777216.f); +#endif +} + + +//========================================================================== +// +// FindRefPoint +// +// Finds the point on the line closest to the given coordinate +// +//========================================================================== + +static inline fixedvec2 FindRefPoint(line_t *ld, fixedvec2 pos) +{ + if (!((((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) | + (ld->backsector->floorplane.a | ld->backsector->floorplane.b) | + (ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) | + (ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0) + && ld->backsector->e->XFloor.ffloors.Size() == 0 && ld->frontsector->e->XFloor.ffloors.Size() == 0)) + { + fixed_t r = GetCoefficientClosestPointInLine24(ld, pos); + if (r <= 0) + { + pos.x = ld->v1->x; + pos.y = ld->v1->y; + } + else if (r >= (1 << 24)) + { + pos.x = ld->v2->x; + pos.y = ld->v2->y; + } + else + { + pos.x = ld->v1->x + MulScale24(r, ld->dx); + pos.y = ld->v1->y + MulScale24(r, ld->dy); + } + } + return pos; } //========================================================================== @@ -151,8 +195,10 @@ static fixed_t GetCoefficientClosestPointInLine24(line_t *ld, FCheckPosition &tm // //========================================================================== -static bool PIT_FindFloorCeiling(line_t *ld, const FBoundingBox &box, FCheckPosition &tmf, int flags) +static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator::CheckResult &cres, const FBoundingBox &box, FCheckPosition &tmf, int flags) { + line_t *ld = cres.line; + if (box.Right() <= ld->bbox[BOXLEFT] || box.Left() >= ld->bbox[BOXRIGHT] || box.Top() <= ld->bbox[BOXBOTTOM] @@ -169,76 +215,52 @@ static bool PIT_FindFloorCeiling(line_t *ld, const FBoundingBox &box, FCheckPosi return true; } - fixed_t sx, sy; + fixedvec2 refpoint = FindRefPoint(ld, cres.position); FLineOpening open; - // set openrange, opentop, openbottom - if ((((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) | - (ld->backsector->floorplane.a | ld->backsector->floorplane.b) | - (ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) | - (ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0) - && ld->backsector->e->XFloor.ffloors.Size() == 0 && ld->frontsector->e->XFloor.ffloors.Size() == 0) - { - P_LineOpening(open, tmf.thing, ld, sx = tmf.x, sy = tmf.y, tmf.x, tmf.y, flags); - } - else - { // Find the point on the line closest to the actor's center, and use - // that to calculate openings - double dx = ld->dx; - double dy = ld->dy; - fixed_t r = xs_CRoundToInt(((double)(tmf.x - ld->v1->x) * dx + - (double)(tmf.y - ld->v1->y) * dy) / - (dx*dx + dy*dy) * 16777216.f); - if (r <= 0) - { - P_LineOpening(open, tmf.thing, ld, sx = ld->v1->x, sy = ld->v1->y, tmf.x, tmf.y, flags); - } - else if (r >= (1 << 24)) - { - P_LineOpening(open, tmf.thing, ld, sx = ld->v2->x, sy = ld->v2->y, tmf.thing->X(), tmf.thing->Y(), flags); - } - else - { - P_LineOpening(open, tmf.thing, ld, sx = ld->v1->x + MulScale24(r, ld->dx), - sy = ld->v1->y + MulScale24(r, ld->dy), tmf.x, tmf.y, flags); - } - } + P_LineOpening(open, tmf.thing, ld, refpoint.x, refpoint.y, cres.position.x, cres.position.y, flags); // adjust floor / ceiling heights - if (open.top < tmf.ceilingz) + if (!(flags & FFCF_NOCEILING)) { - tmf.ceilingz = open.top; + if (open.top < tmf.ceilingz) + { + tmf.ceilingz = open.top; + } } - if (open.bottom > tmf.floorz) + if (!(flags & FFCF_NOFLOOR)) { - tmf.floorz = open.bottom; - if (open.bottomsec != NULL) tmf.floorsector = open.bottomsec; - tmf.touchmidtex = open.touchmidtex; - tmf.abovemidtex = open.abovemidtex; - } - else if (open.bottom == tmf.floorz) - { - tmf.touchmidtex |= open.touchmidtex; - tmf.abovemidtex |= open.abovemidtex; - } - - if (open.lowfloor < tmf.dropoffz) - tmf.dropoffz = open.lowfloor; + if (open.bottom > tmf.floorz) + { + tmf.floorz = open.bottom; + if (open.bottomsec != NULL) tmf.floorsector = open.bottomsec; + tmf.touchmidtex = open.touchmidtex; + tmf.abovemidtex = open.abovemidtex; + } + else if (open.bottom == tmf.floorz) + { + tmf.touchmidtex |= open.touchmidtex; + tmf.abovemidtex |= open.abovemidtex; + } + if (open.lowfloor < tmf.dropoffz) + tmf.dropoffz = open.lowfloor; + } return true; } //========================================================================== // -// +// calculates the actual floor and ceiling position at a given +// coordinate. Traverses through portals unless being told not to. // //========================================================================== void P_GetFloorCeilingZ(FCheckPosition &tmf, int flags) { - sector_t *sec = !(flags & FFCF_SAMESECTOR) ? P_PointInSector(tmf.x, tmf.y) : tmf.thing->Sector; + sector_t *sec = (!(flags & FFCF_SAMESECTOR) || tmf.thing->Sector == NULL)? P_PointInSector(tmf.x, tmf.y) : tmf.thing->Sector; if (flags & FFCF_NOPORTALS) { @@ -268,17 +290,20 @@ void P_GetFloorCeilingZ(FCheckPosition &tmf, int flags) if (ff_top > tmf.floorz) { - if (ff_top <= tmf.z || (!(flags & FFCF_3DRESTRICT) && (tmf.thing != NULL && ff_bottom < tmf.z && ff_top < tmf.z + tmf.thing->MaxStepHeight))) + // either with feet above the 3D floor or feet with less than 'stepheight' map units inside + if (ff_top <= tmf.z || (!(flags & FFCF_3DRESTRICT) && (ff_bottom < tmf.z && ff_top < tmf.z + tmf.thing->MaxStepHeight))) { tmf.dropoffz = tmf.floorz = ff_top; tmf.floorpic = *rover->top.texture; tmf.floorterrain = rover->model->GetTerrain(rover->top.isceiling); + tmf.floorsector = sec; } } if (ff_bottom <= tmf.ceilingz && ff_bottom > tmf.z + tmf.thing->height) { tmf.ceilingz = ff_bottom; tmf.ceilingpic = *rover->bottom.texture; + tmf.ceilingsector = sec; } } } @@ -303,6 +328,7 @@ void P_FindFloorCeiling(AActor *actor, int flags) flags |= FFCF_3DRESTRICT; } P_GetFloorCeilingZ(tmf, flags); + assert(tmf.thing->Sector != NULL); actor->floorz = tmf.floorz; actor->dropoffz = tmf.dropoffz; @@ -313,44 +339,44 @@ void P_FindFloorCeiling(AActor *actor, int flags) actor->ceilingpic = tmf.ceilingpic; actor->ceilingsector = tmf.ceilingsector; - FBoundingBox box(tmf.x, tmf.y, actor->radius); - tmf.touchmidtex = false; tmf.abovemidtex = false; validcount++; - FBlockLinesIterator it(box); - line_t *ld; + FPortalGroupArray grouplist; + FMultiBlockLinesIterator mit(grouplist, actor, tmf.x, tmf.y, actor->radius); + FMultiBlockLinesIterator::CheckResult cres; - while ((ld = it.Next())) + // if we already have a valid floor/ceiling sector within the current sector, + // we do not need to iterate through plane portals to find a floor or ceiling. + if (actor->floorsector == actor->Sector) mit.StopDown(); + if (actor->ceilingsector == actor->Sector) mit.StopUp(); + + while ((mit.Next(&cres))) { - PIT_FindFloorCeiling(ld, box, tmf, flags); + PIT_FindFloorCeiling(cres, mit.Box(), tmf, flags|cres.portalflags); } if (tmf.touchmidtex) tmf.dropoffz = tmf.floorz; - if (!(flags & FFCF_ONLYSPAWNPOS) || (tmf.abovemidtex && (tmf.floorz <= actor->Z()))) + bool usetmf = !(flags & FFCF_ONLYSPAWNPOS) || (tmf.abovemidtex && (tmf.floorz <= actor->Z())); + + // when actual floor or ceiling are beyond a portal plane we also need to use the result of the blockmap iterator, regardless of the flags being specified. + if (usetmf || tmf.floorsector->PortalGroup != actor->Sector->PortalGroup) { actor->floorz = tmf.floorz; actor->dropoffz = tmf.dropoffz; - actor->ceilingz = tmf.ceilingz; actor->floorpic = tmf.floorpic; actor->floorterrain = tmf.floorterrain; actor->floorsector = tmf.floorsector; + } + + if (usetmf || tmf.ceilingsector->PortalGroup != actor->Sector->PortalGroup) + { + actor->ceilingz = tmf.ceilingz; actor->ceilingpic = tmf.ceilingpic; actor->ceilingsector = tmf.ceilingsector; } - else - { - actor->floorsector = actor->ceilingsector = actor->Sector; - // [BB] Don't forget to update floorpic and ceilingpic. - if (actor->Sector != NULL) - { - actor->floorpic = actor->Sector->GetTexture(sector_t::floor); - actor->floorterrain = actor->Sector->GetTerrain(sector_t::floor); - actor->ceilingpic = actor->Sector->GetTexture(sector_t::ceiling); - } - } } //========================================================================== @@ -392,16 +418,17 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra bool StompAlwaysFrags = ((thing->flags2 & MF2_TELESTOMP) || (level.flags & LEVEL_MONSTERSTELEFRAG) || telefrag) && !(thing->flags7 & MF7_NOTELESTOMP); - FBoundingBox box(x, y, thing->radius); - FBlockLinesIterator it(box); - line_t *ld; - // P_LineOpening requires the thing's z to be the destination z in order to work. fixed_t savedz = thing->Z(); thing->SetZ(z); - while ((ld = it.Next())) + + FPortalGroupArray grouplist; + FMultiBlockLinesIterator mit(grouplist, thing, tmf.x, tmf.y, thing->radius); + FMultiBlockLinesIterator::CheckResult cres; + + while (mit.Next(&cres)) { - PIT_FindFloorCeiling(ld, box, tmf, 0); + PIT_FindFloorCeiling(cres, mit.Box(), tmf, 0); } thing->SetZ(savedz); @@ -714,6 +741,7 @@ int P_GetMoveFactor(const AActor *mo, int *frictionp) return movefactor; } + // // MOVEMENT ITERATOR FUNCTIONS // @@ -825,56 +853,18 @@ bool PIT_CheckLine(line_t *ld, const FBoundingBox &box, FCheckPosition &tm) } } - fixed_t sx = 0, sy = 0; + fixedvec2 rpos = { tm.x, tm.y }; + fixedvec2 ref = FindRefPoint(ld, rpos); FLineOpening open; - // set openrange, opentop, openbottom - if ((((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) | - (ld->backsector->floorplane.a | ld->backsector->floorplane.b) | - (ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) | - (ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0) - && ld->backsector->e->XFloor.ffloors.Size() == 0 && ld->frontsector->e->XFloor.ffloors.Size() == 0) + // the floorplane on both sides is identical with the current one + // so don't mess around with the z-position. + if (ld->frontsector->floorplane == ld->backsector->floorplane && + ld->frontsector->floorplane == tm.thing->Sector->floorplane && + !ld->frontsector->e->XFloor.ffloors.Size() && !ld->backsector->e->XFloor.ffloors.Size() && + !open.abovemidtex) { - P_LineOpening(open, tm.thing, ld, sx = tm.x, sy = tm.y, tm.x, tm.y); - } - else - { // Find the point on the line closest to the actor's center, and use - // that to calculate openings - fixed_t r = GetCoefficientClosestPointInLine24(ld, tm); - - /* Printf ("%d:%d: %d (%d %d %d %d) (%d %d %d %d)\n", level.time, ld-lines, r, - ld->frontsector->floorplane.a, - ld->frontsector->floorplane.b, - ld->frontsector->floorplane.c, - ld->frontsector->floorplane.ic, - ld->backsector->floorplane.a, - ld->backsector->floorplane.b, - ld->backsector->floorplane.c, - ld->backsector->floorplane.ic);*/ - if (r <= 0) - { - P_LineOpening(open, tm.thing, ld, sx = ld->v1->x, sy = ld->v1->y, tm.x, tm.y); - } - else if (r >= (1 << 24)) - { - P_LineOpening(open, tm.thing, ld, sx = ld->v2->x, sy = ld->v2->y, pos.x, pos.y); - } - else - { - P_LineOpening(open, tm.thing, ld, sx = ld->v1->x + MulScale24(r, ld->dx), - sy = ld->v1->y + MulScale24(r, ld->dy), tm.x, tm.y); - } - - // the floorplane on both sides is identical with the current one - // so don't mess around with the z-position - if (ld->frontsector->floorplane == ld->backsector->floorplane && - ld->frontsector->floorplane == tm.thing->Sector->floorplane && - !ld->frontsector->e->XFloor.ffloors.Size() && !ld->backsector->e->XFloor.ffloors.Size() && - !open.abovemidtex) - { - open.bottom = INT_MIN; - } - /* Printf (" %d %d %d\n", sx, sy, openbottom);*/ + open.bottom = INT_MIN; } if (rail && @@ -886,7 +876,7 @@ bool PIT_CheckLine(line_t *ld, const FBoundingBox &box, FCheckPosition &tm) // from either side. How long until somebody reports this as a bug and I'm // forced to say, "It's not a bug. It's a feature?" Ugh. (!(level.flags2 & LEVEL2_RAILINGHACK) || - open.bottom == tm.thing->Sector->floorplane.ZatPoint(sx, sy))) + open.bottom == tm.thing->Sector->floorplane.ZatPoint(ref.x, ref.y))) { open.bottom += 32 * FRACUNIT; } diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 80190e624..38be280d6 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -39,7 +39,6 @@ #include "p_3dmidtex.h" #include "p_blockmap.h" #include "r_utility.h" -#include "portal.h" // State. #include "r_state.h" @@ -694,7 +693,8 @@ line_t *FBlockLinesIterator::Next() // //=========================================================================== -FMultiBlockLinesIterator::FMultiBlockLinesIterator(AActor *origin, fixed_t checkx, fixed_t checky, fixed_t checkradius) +FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkx, fixed_t checky, fixed_t checkradius) + : checklist(check) { checkpoint = origin->Pos(); if (checkx != FIXED_MAX) checkpoint.x = checkx; @@ -712,7 +712,7 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item) { item->line = line; item->position = offset; - item->portalposition = portalposition; + item->portalflags = portalflags; return true; } else if (checklist[index] & FPortalGroupArray::UPPER) @@ -723,6 +723,7 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item) if (!sector->PortalBlocksMovement(sector_t::ceiling)) { startIteratorForGroup(sector->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup); + portalflags = FFCF_NOFLOOR; return Next(item); } } @@ -735,13 +736,28 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item) if (!sector->PortalBlocksMovement(sector_t::floor)) { startIteratorForGroup(sector->SkyBoxes[sector_t::floor]->Sector->PortalGroup); + portalflags = FFCF_NOCEILING; return Next(item); } } } index++; if (index >= checklist.Size()) return false; - startIteratorForGroup(checklist[index]); + startIteratorForGroup(checklist[index] & ~FPortalGroupArray::FLAT); + switch (checklist[index] & FPortalGroupArray::FLAT) + { + case FPortalGroupArray::UPPER: + portalflags = FFCF_NOFLOOR; + break; + + case FPortalGroupArray::LOWER: + portalflags = FFCF_NOCEILING; + break; + + default: + portalflags = 0; + } + return Next(item); } @@ -750,15 +766,15 @@ void FMultiBlockLinesIterator::startIteratorForGroup(int group) offset = Displacements(basegroup, group); offset.x += checkpoint.x; offset.y += checkpoint.y; - FBoundingBox box(offset.x, offset.y, checkpoint.z); - blockIterator.init(box); + bbox.setBox(offset.x, offset.y, checkpoint.z); + blockIterator.init(bbox); } void FMultiBlockLinesIterator::Reset() { continueup = continueup = true; index = -1; - portalposition = PP_ORIGIN; + portalflags = 0; startIteratorForGroup(basegroup); } diff --git a/src/p_maputl.h b/src/p_maputl.h index 0686b507b..3ebc02f31 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -3,6 +3,7 @@ #include "r_defs.h" #include "doomstat.h" +#include "m_bbox.h" extern int validcount; @@ -141,12 +142,14 @@ struct FPortalGroupArray FPortalGroupArray() { varused = 0; + inited = false; } void Clear() { data.Clear(); varused = 0; + inited = false; } void Add(DWORD num) @@ -165,9 +168,11 @@ struct FPortalGroupArray return index < MAX_STATIC ? entry[index] : data[index - MAX_STATIC]; } + bool inited; + private: WORD entry[MAX_STATIC]; - unsigned varused; + BYTE varused; TArray data; }; @@ -195,36 +200,29 @@ public: class FMultiBlockLinesIterator { + FPortalGroupArray &checklist; fixedvec3 checkpoint; fixedvec2 offset; short basegroup; - short portalposition; + short portalflags; WORD index; bool continueup; bool continuedown; FBlockLinesIterator blockIterator; - FPortalGroupArray checklist; + FBoundingBox bbox; void startIteratorForGroup(int group); public: - enum - { - PP_ORIGIN, - PP_ABOVE, - PP_BELOW, - PP_THROUGHLINE - }; - struct CheckResult { line_t *line; fixedvec2 position; - int portalposition; + int portalflags; }; - FMultiBlockLinesIterator(AActor *origin, fixed_t checkx = FIXED_MAX, fixed_t checky = FIXED_MAX, fixed_t checkradius = -1); + FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkx = FIXED_MAX, fixed_t checky = FIXED_MAX, fixed_t checkradius = -1); 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. @@ -236,6 +234,10 @@ public: { continuedown = false; } + const FBoundingBox &Box() const + { + return bbox; + } }; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index a72c9d897..2f113810d 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -55,7 +55,6 @@ #include "p_lnspec.h" #include "p_acs.h" #include "p_terrain.h" -#include "portal.h" static void CopyPlayer (player_t *dst, player_t *src, const char *name); static void ReadOnePlayer (FArchive &arc, bool skipload); diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index ac42da11f..ab1cc40d7 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -30,7 +30,6 @@ #include "po_man.h" #include "farchive.h" #include "r_utility.h" -#include "portal.h" #include "a_sharedglobal.h" #include "r_data/colormaps.h" @@ -806,7 +805,7 @@ int sector_t::GetCeilingLight () const ASkyViewpoint *sector_t::GetSkyBox(int which) { - if (SkyBoxes[which] != NULL) return SkyBoxes[which]; + if (SkyBoxes[which] != NULL) return barrier_cast(SkyBoxes[which]); if (MoreFlags & (SECF_NOFLOORSKYBOX << which)) return NULL; return level.DefaultSkybox; } @@ -874,7 +873,7 @@ int sector_t::GetTerrain(int pos) const void sector_t::CheckPortalPlane(int plane) { - ASkyViewpoint *portal = SkyBoxes[plane]; + AActor *portal = SkyBoxes[plane]; if (!portal || portal->special1 != SKYBOX_LINKEDPORTAL) return; fixed_t planeh = planes[plane].TexZ; diff --git a/src/p_setup.cpp b/src/p_setup.cpp index c5780e912..55dbdfcac 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -69,7 +69,6 @@ #include "po_man.h" #include "r_renderer.h" #include "r_data/colormaps.h" -#include "portal.h" #include "p_blockmap.h" #include "r_utility.h" #include "p_spec.h" diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 6007963c6..e18f78b29 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -67,7 +67,6 @@ #include "c_dispatch.h" #include "r_sky.h" #include "d_player.h" -#include "portal.h" #include "p_maputl.h" #include "p_blockmap.h" #ifndef NO_EDATA @@ -919,10 +918,11 @@ static void SetupFloorPortal (AStackPoint *point) { NActorIterator it (NAME_LowerStackLookOnly, point->tid); sector_t *Sector = point->Sector; - Sector->SkyBoxes[sector_t::floor] = static_cast(it.Next()); - if (Sector->SkyBoxes[sector_t::floor] != NULL && Sector->SkyBoxes[sector_t::floor]->bAlways) + ASkyViewpoint *skyv = static_cast(it.Next()); + Sector->SkyBoxes[sector_t::floor] = skyv; + if (skyv != NULL && skyv->bAlways) { - Sector->SkyBoxes[sector_t::floor]->Mate = point; + skyv->Mate = point; if (Sector->GetAlpha(sector_t::floor) == OPAQUE) Sector->SetAlpha(sector_t::floor, Scale (point->args[0], OPAQUE, 255)); } @@ -932,12 +932,13 @@ static void SetupCeilingPortal (AStackPoint *point) { NActorIterator it (NAME_UpperStackLookOnly, point->tid); sector_t *Sector = point->Sector; - Sector->SkyBoxes[sector_t::ceiling] = static_cast(it.Next()); - if (Sector->SkyBoxes[sector_t::ceiling] != NULL && Sector->SkyBoxes[sector_t::ceiling]->bAlways) + ASkyViewpoint *skyv = static_cast(it.Next()); + Sector->SkyBoxes[sector_t::ceiling] = skyv; + if (skyv != NULL && skyv->bAlways) { - Sector->SkyBoxes[sector_t::ceiling]->Mate = point; + skyv->Mate = point; if (Sector->GetAlpha(sector_t::ceiling) == OPAQUE) - Sector->SetAlpha(sector_t::ceiling, Scale (point->args[0], OPAQUE, 255)); + Sector->SetAlpha(sector_t::ceiling, Scale(point->args[0], OPAQUE, 255)); } } @@ -968,7 +969,7 @@ static void SetPortal(sector_t *sector, int plane, ASkyViewpoint *portal, fixed_ // plane: 0=floor, 1=ceiling, 2=both if (plane > 0) { - if (sector->SkyBoxes[sector_t::ceiling] == NULL || !sector->SkyBoxes[sector_t::ceiling]->bAlways) + if (sector->SkyBoxes[sector_t::ceiling] == NULL || !barrier_cast(sector->SkyBoxes[sector_t::ceiling])->bAlways) { sector->SkyBoxes[sector_t::ceiling] = portal; if (sector->GetAlpha(sector_t::ceiling) == OPAQUE) @@ -979,7 +980,7 @@ static void SetPortal(sector_t *sector, int plane, ASkyViewpoint *portal, fixed_ } if (plane == 2 || plane == 0) { - if (sector->SkyBoxes[sector_t::floor] == NULL || !sector->SkyBoxes[sector_t::floor]->bAlways) + if (sector->SkyBoxes[sector_t::floor] == NULL || !barrier_cast(sector->SkyBoxes[sector_t::floor])->bAlways) { sector->SkyBoxes[sector_t::floor] = portal; } diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 2b01be372..e86093a8c 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -47,7 +47,6 @@ #include "r_data/colormaps.h" #include "w_wad.h" #include "p_tags.h" -#include "portal.h" #include "p_terrain.h" //=========================================================================== diff --git a/src/portal.cpp b/src/portal.cpp index a247aafcc..efd46d851 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -37,7 +37,6 @@ */ -#include "portal.h" #include "p_local.h" #include "p_lnspec.h" #include "r_bsp.h" @@ -925,7 +924,7 @@ void P_CreateLinkedPortals() { for (int j = 0; j < 2; j++) { - ASkyViewpoint *box = sectors[i].SkyBoxes[j]; + AActor *box = sectors[i].SkyBoxes[j]; if (box != NULL && box->special1 == SKYBOX_LINKEDPORTAL) { secplane_t &plane = j == 0 ? sectors[i].floorplane : sectors[i].ceilingplane; @@ -961,7 +960,7 @@ void P_CreateLinkedPortals() { for (int j = 0; j < 2; j++) { - ASkyViewpoint *box = sectors[i].SkyBoxes[j]; + ASkyViewpoint *box = barrier_cast(sectors[i].SkyBoxes[j]); if (box != NULL) { if (box->special1 == SKYBOX_LINKEDPORTAL && sectors[i].PortalGroup == 0) @@ -1061,10 +1060,10 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t static TArray foundPortals; bool retval = false; + out.inited = true; if (linkedPortals.Size() == 0) { // If there are no portals, all sectors are in group 0. - out.Add(0); return false; } processMask.setSize(linkedPortals.Size()); diff --git a/src/portal.h b/src/portal.h index fcf6c545b..c974d8049 100644 --- a/src/portal.h +++ b/src/portal.h @@ -3,11 +3,7 @@ #include "basictypes.h" #include "v_video.h" -#include "r_defs.h" -#include "actor.h" -#include "p_local.h" #include "m_bbox.h" -#include "a_sharedglobal.h" struct FPortalGroupArray; //============================================================================ @@ -180,90 +176,4 @@ public: /* new code */ fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y); -//============================================================================ -// -// some wrappers around the portal data. -// -//============================================================================ - - -// returns true if the portal is crossable by actors -inline bool line_t::isLinePortal() const -{ - return portalindex >= linePortals.Size() ? false : !!(linePortals[portalindex].mFlags & PORTF_PASSABLE); -} - -// returns true if the portal needs to be handled by the renderer -inline bool line_t::isVisualPortal() const -{ - return portalindex >= linePortals.Size() ? false : !!(linePortals[portalindex].mFlags & PORTF_VISIBLE); -} - -inline line_t *line_t::getPortalDestination() const -{ - return portalindex >= linePortals.Size() ? (line_t*)NULL : linePortals[portalindex].mDestination; -} - -inline int line_t::getPortalAlignment() const -{ - return portalindex >= linePortals.Size() ? 0 : linePortals[portalindex].mAlign; -} - -inline bool sector_t::PortalBlocksView(int plane) -{ - if (SkyBoxes[plane] == NULL) return true; - if (SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return false; - return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); -} - -inline bool sector_t::PortalBlocksSight(int plane) -{ - if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; - return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); -} - -inline bool sector_t::PortalBlocksMovement(int plane) -{ - if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; - return !!(planes[plane].Flags & (PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); -} - -inline bool sector_t::PortalBlocksSound(int plane) -{ - if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; - return !!(planes[plane].Flags & (PLANEF_BLOCKSOUND | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); -} - -// These may only be called if the portal has been validated -inline FDisplacement §or_t::FloorDisplacement() -{ - return Displacements(PortalGroup, SkyBoxes[sector_t::floor]->Sector->PortalGroup); -} - -inline FDisplacement §or_t::CeilingDisplacement() -{ - return Displacements(PortalGroup, SkyBoxes[sector_t::ceiling]->Sector->PortalGroup); -} - -inline fixedvec3 AActor::PosRelative(AActor *other) const -{ - FDisplacement &disp = Displacements(Sector->PortalGroup, other->Sector->PortalGroup); - fixedvec3 ret = { X() + disp.pos.x, Y() + disp.pos.y, Z() }; - return ret; -} - -inline fixedvec3 AActor::PosRelative(sector_t *sec) const -{ - FDisplacement &disp = Displacements(Sector->PortalGroup, sec->PortalGroup); - fixedvec3 ret = { X() + disp.pos.x, Y() + disp.pos.y, Z() }; - return ret; -} - -inline fixedvec3 AActor::PosRelative(line_t *line) const -{ - FDisplacement &disp = Displacements(Sector->PortalGroup, line->frontsector->PortalGroup); - fixedvec3 ret = { X() + disp.pos.x, Y() + disp.pos.y, Z() }; - return ret; -} - #endif \ No newline at end of file diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 8fba4a8e3..a95bd97a0 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -56,7 +56,6 @@ #include "r_sky.h" #include "po_man.h" #include "r_data/colormaps.h" -#include "portal.h" seg_t* curline; side_t* sidedef; diff --git a/src/r_bsp.h b/src/r_bsp.h index 8c19a2670..30ddf3b0e 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -25,7 +25,7 @@ #include "tarray.h" #include -#include "portal.h" +#include "r_defs.h" // The 3072 below is just an arbitrary value picked to avoid // drawing lines the player is too close to that would overflow diff --git a/src/r_defs.h b/src/r_defs.h index 80764fe21..07903403e 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -739,10 +739,41 @@ struct sector_t Flags &= ~SECF_SPECIALFLAGS; } - bool PortalBlocksView(int plane); - bool PortalBlocksSight(int plane); - bool PortalBlocksMovement(int plane); - bool PortalBlocksSound(int plane); + bool PortalBlocksView(int plane) + { + if (SkyBoxes[plane] == NULL) return true; + if (SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return false; + return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); + } + + bool PortalBlocksSight(int plane) + { + if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; + return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); + } + + 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)); + } + + 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)); + } + + // These may only be called if the portal has been validated + FDisplacement &FloorDisplacement() + { + return Displacements(PortalGroup, SkyBoxes[sector_t::floor]->Sector->PortalGroup); + } + + FDisplacement &CeilingDisplacement() + { + return Displacements(PortalGroup, SkyBoxes[sector_t::ceiling]->Sector->PortalGroup); + } int GetTerrain(int pos) const; @@ -778,9 +809,6 @@ struct sector_t return NextLowestFloorAt(a->X(), a->Y(), z, resultsec, resultffloor); } - FDisplacement &FloorDisplacement(); - FDisplacement &CeilingDisplacement(); - // Member variables fixed_t CenterFloor () const { return floorplane.ZatPoint (soundorg[0], soundorg[1]); } fixed_t CenterCeiling () const { return ceilingplane.ZatPoint (soundorg[0], soundorg[1]); } @@ -864,7 +892,7 @@ struct sector_t // [RH] The sky box to render for this sector. NULL means use a // regular sky. - TObjPtr SkyBoxes[2]; + TObjPtr SkyBoxes[2]; int PortalGroup; int sectornum; // for comparing sector copies @@ -1045,11 +1073,26 @@ struct line_t unsigned portalindex; // returns true if the portal is crossable by actors - bool isLinePortal() const; + bool isLinePortal() const + { + return portalindex >= linePortals.Size() ? false : !!(linePortals[portalindex].mFlags & PORTF_PASSABLE); + } + // returns true if the portal needs to be handled by the renderer - bool isVisualPortal() const; - line_t *getPortalDestination() const; - int getPortalAlignment() const; + bool isVisualPortal() const + { + return portalindex >= linePortals.Size() ? false : !!(linePortals[portalindex].mFlags & PORTF_VISIBLE); + } + + line_t *getPortalDestination() const + { + return portalindex >= linePortals.Size() ? (line_t*)NULL : linePortals[portalindex].mDestination; + } + + int getPortalAlignment() const + { + return portalindex >= linePortals.Size() ? 0 : linePortals[portalindex].mAlign; + } }; // phares 3/14/98 @@ -1195,6 +1238,24 @@ inline sector_t *P_PointInSector(fixed_t x, fixed_t y) return P_PointInSubsector(x, y)->sector; } -#define _ZatPoint ZatPoint // so that it still compiles during the transition +inline fixedvec3 AActor::PosRelative(AActor *other) const +{ + return __pos + Displacements(Sector->PortalGroup, other->Sector->PortalGroup); +} + +inline fixedvec3 AActor::PosRelative(sector_t *sec) const +{ + return __pos + Displacements(Sector->PortalGroup, sec->PortalGroup); +} + +inline fixedvec3 AActor::PosRelative(line_t *line) const +{ + return __pos + Displacements(Sector->PortalGroup, line->frontsector->PortalGroup); +} + +inline fixedvec3 PosRelative(const fixedvec3 &pos, line_t *line, sector_t *refsec = NULL) +{ + return pos + Displacements(refsec->PortalGroup, line->frontsector->PortalGroup); +} #endif diff --git a/src/r_main.cpp b/src/r_main.cpp index 90b8d865b..02a3349a3 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -58,7 +58,6 @@ #include "v_font.h" #include "r_data/colormaps.h" #include "farchive.h" -#include "portal.h" // MACROS ------------------------------------------------------------------ diff --git a/src/r_plane.cpp b/src/r_plane.cpp index f1deceb9f..862eed3fb 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -58,7 +58,6 @@ #include "r_3dfloors.h" #include "v_palette.h" #include "r_data/colormaps.h" -#include "portal.h" #ifdef _MSC_VER #pragma warning(disable:4244) diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 96a0595d7..ae38b3978 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -52,7 +52,6 @@ #include "r_3dfloors.h" #include "v_palette.h" #include "r_data/colormaps.h" -#include "portal.h" #define WALLYREPEAT 8 diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 45760a5ce..10a39ba57 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -34,7 +34,6 @@ #include "doomstat.h" #include "m_random.h" #include "m_bbox.h" -#include "portal.h" #include "r_sky.h" #include "st_stuff.h" #include "c_cvars.h" @@ -57,7 +56,7 @@ #include "farchive.h" #include "r_utility.h" #include "d_player.h" -#include "portal.h" +#include "p_local.h" // EXTERNAL DATA DECLARATIONS ----------------------------------------------