- moved portal data into FLevelLocals.

This commit is contained in:
Christoph Oelckers 2018-04-01 20:17:39 +02:00
parent 65e7b6dfaa
commit 8be788a9b3
19 changed files with 138 additions and 148 deletions

View File

@ -2,31 +2,32 @@
#include "actor.h"
#include "r_defs.h"
// These depend on both actor.h and r_defs.h so they cannot be in either file without creating a cross dependency.
#include "g_levellocals.h"
// These depend on both actor.h and r_defs.h so they cannot be in either file without creating a circular dependency.
inline DVector3 AActor::PosRelative(int portalgroup) const
{
return Pos() + Displacements.getOffset(Sector->PortalGroup, portalgroup);
return Pos() + level.Displacements.getOffset(Sector->PortalGroup, portalgroup);
}
inline DVector3 AActor::PosRelative(const AActor *other) const
{
return Pos() + Displacements.getOffset(Sector->PortalGroup, other->Sector->PortalGroup);
return Pos() + level.Displacements.getOffset(Sector->PortalGroup, other->Sector->PortalGroup);
}
inline DVector3 AActor::PosRelative(sector_t *sec) const
{
return Pos() + Displacements.getOffset(Sector->PortalGroup, sec->PortalGroup);
return Pos() + level.Displacements.getOffset(Sector->PortalGroup, sec->PortalGroup);
}
inline DVector3 AActor::PosRelative(line_t *line) const
{
return Pos() + Displacements.getOffset(Sector->PortalGroup, line->frontsector->PortalGroup);
return Pos() + level.Displacements.getOffset(Sector->PortalGroup, line->frontsector->PortalGroup);
}
inline DVector3 PosRelative(const DVector3 &pos, line_t *line, sector_t *refsec = NULL)
{
return pos + Displacements.getOffset(refsec->PortalGroup, line->frontsector->PortalGroup);
return pos + level.Displacements.getOffset(refsec->PortalGroup, line->frontsector->PortalGroup);
}

View File

@ -2540,7 +2540,7 @@ void AM_drawWalls (bool allmap)
static mline_t l;
int lock, color;
int numportalgroups = am_portaloverlay ? Displacements.size : 0;
int numportalgroups = am_portaloverlay ? level.Displacements.size : 0;
for (int p = numportalgroups - 1; p >= -1; p--)
{
@ -2564,7 +2564,7 @@ void AM_drawWalls (bool allmap)
bool portalmode = numportalgroups > 0 && pg != MapPortalGroup;
if (pg == p)
{
offset = Displacements.getOffset(pg, MapPortalGroup);
offset = level.Displacements.getOffset(pg, MapPortalGroup);
}
else if (p == -1 && (pg == MapPortalGroup || !am_portaloverlay))
{

View File

@ -2017,7 +2017,7 @@ inline T VecDiff(const T& v1, const T& v2)
if (nullptr != sec1 && nullptr != sec2)
{
result += Displacements.getOffset(sec2->PortalGroup, sec1->PortalGroup);
result += level.Displacements.getOffset(sec2->PortalGroup, sec1->PortalGroup);
}
}

View File

@ -84,6 +84,12 @@ struct FLevelLocals
TArray<uint8_t> rejectmatrix;
TArray<FSectorPortal> sectorPortals;
TArray<FLinePortal> linePortals;
FDisplacementTable Displacements;
FPortalBlockmap PortalBlockmap;
TArray<FLinePortal*> linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups.
TArray<zone_t> Zones;
FBlockmap blockmap;
@ -268,27 +274,27 @@ inline bool sector_t::PortalIsLinked(int plane)
inline FLinePortal *line_t::getPortal() const
{
return portalindex >= linePortals.Size() ? (FLinePortal*)NULL : &linePortals[portalindex];
return portalindex >= level.linePortals.Size() ? (FLinePortal*)NULL : &level.linePortals[portalindex];
}
// 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);
return portalindex >= level.linePortals.Size() ? false : !!(level.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);
return portalindex >= level.linePortals.Size() ? false : !!(level.linePortals[portalindex].mFlags & PORTF_VISIBLE);
}
inline line_t *line_t::getPortalDestination() const
{
return portalindex >= linePortals.Size() ? (line_t*)NULL : linePortals[portalindex].mDestination;
return portalindex >= level.linePortals.Size() ? (line_t*)NULL : level.linePortals[portalindex].mDestination;
}
inline int line_t::getPortalAlignment() const
{
return portalindex >= linePortals.Size() ? 0 : linePortals[portalindex].mAlign;
return portalindex >= level.linePortals.Size() ? 0 : level.linePortals[portalindex].mAlign;
}

View File

@ -409,24 +409,24 @@ void gl_InitPortals()
linePortalToGL.Clear();
TArray<int> tempindex;
tempindex.Reserve(linePortals.Size());
memset(&tempindex[0], -1, linePortals.Size() * sizeof(int));
tempindex.Reserve(level.linePortals.Size());
memset(&tempindex[0], -1, level.linePortals.Size() * sizeof(int));
for (unsigned i = 0; i < linePortals.Size(); i++)
for (unsigned i = 0; i < level.linePortals.Size(); i++)
{
auto port = linePortals[i];
auto port = level.linePortals[i];
bool gotsome;
if (tempindex[i] == -1)
{
tempindex[i] = glLinePortals.Size();
line_t *pSrcLine = linePortals[i].mOrigin;
line_t *pLine = linePortals[i].mDestination;
line_t *pSrcLine = level.linePortals[i].mOrigin;
line_t *pLine = level.linePortals[i].mDestination;
FGLLinePortal &glport = glLinePortals[glLinePortals.Reserve(1)];
glport.lines.Push(&linePortals[i]);
glport.lines.Push(&level.linePortals[i]);
// We cannot do this grouping for non-linked glSectorPortals because they can be changed at run time.
if (linePortals[i].mType == PORTT_LINKED && pLine != nullptr)
if (level.linePortals[i].mType == PORTT_LINKED && pLine != nullptr)
{
glport.v1 = pLine->v1;
glport.v2 = pLine->v2;
@ -434,12 +434,12 @@ void gl_InitPortals()
{
// now collect all other colinear lines connected to this one. We run this loop as long as it still finds a match
gotsome = false;
for (unsigned j = 0; j < linePortals.Size(); j++)
for (unsigned j = 0; j < level.linePortals.Size(); j++)
{
if (tempindex[j] == -1)
{
line_t *pSrcLine2 = linePortals[j].mOrigin;
line_t *pLine2 = linePortals[j].mDestination;
line_t *pSrcLine2 = level.linePortals[j].mOrigin;
line_t *pLine2 = level.linePortals[j].mDestination;
// angular precision is intentionally reduced to 32 bit BAM to account for precision problems (otherwise many not perfectly horizontal or vertical glSectorPortals aren't found here.)
unsigned srcang = pSrcLine->Delta().Angle().BAMs();
unsigned dstang = pLine->Delta().Angle().BAMs();
@ -456,7 +456,7 @@ void gl_InitPortals()
tempindex[j] = tempindex[i];
if (pLine->v1 == pLine2->v2) glport.v1 = pLine2->v1;
else glport.v2 = pLine2->v2;
glport.lines.Push(&linePortals[j]);
glport.lines.Push(&level.linePortals[j]);
}
}
}
@ -465,13 +465,13 @@ void gl_InitPortals()
}
}
}
linePortalToGL.Resize(linePortals.Size());
for (unsigned i = 0; i < linePortals.Size(); i++)
linePortalToGL.Resize(level.linePortals.Size());
for (unsigned i = 0; i < level.linePortals.Size(); i++)
{
linePortalToGL[i] = &glLinePortals[tempindex[i]];
/*
Printf("portal at line %d translates to GL portal %d, range = %f,%f to %f,%f\n",
int(linePortals[i].mOrigin - lines), tempindex[i], linePortalToGL[i]->v1->fixX() / 65536., linePortalToGL[i]->v1->fixY() / 65536., linePortalToGL[i]->v2->fixX() / 65536., linePortalToGL[i]->v2->fixY() / 65536.);
int(level.linePortals[i].mOrigin - lines), tempindex[i], linePortalToGL[i]->v1->fixX() / 65536., linePortalToGL[i]->v1->fixY() / 65536., linePortalToGL[i]->v2->fixX() / 65536., linePortalToGL[i]->v2->fixY() / 65536.);
*/
}
}

View File

@ -726,13 +726,13 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
// [RH] Interpolate the sprite's position to make it look smooth
DVector3 thingpos = thing->InterpolatedPosition(r_viewpoint.TicFrac);
if (thruportal == 1) thingpos += Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup);
if (thruportal == 1) thingpos += level.Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup);
// Some added checks if the camera actor is not supposed to be seen. It can happen that some portal setup has this actor in view in which case it may not be skipped here
if (thing == camera && !r_viewpoint.showviewer)
{
DVector3 thingorigin = thing->Pos();
if (thruportal == 1) thingorigin += Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup);
if (thruportal == 1) thingorigin += level.Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup);
if (fabs(thingorigin.X - r_viewpoint.ActorPos.X) < 2 && fabs(thingorigin.Y - r_viewpoint.ActorPos.Y) < 2) return;
}
// Thing is invisible if close to the camera.

View File

@ -81,13 +81,13 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
// This is a performance critical section of code where we cannot afford to let the compiler decide whether to inline the function or not.
// This will do the calculations explicitly rather than calling one of AActor's utility functions.
if (Displacements.size > 0)
if (level.Displacements.size > 0)
{
int fromgroup = light->Sector->PortalGroup;
int togroup = subsec->sector->PortalGroup;
if (fromgroup == togroup || fromgroup == 0 || togroup == 0) goto direct;
DVector2 offset = Displacements.getOffset(fromgroup, togroup);
DVector2 offset = level.Displacements.getOffset(fromgroup, togroup);
L = FVector3(x - light->X() - offset.X, y - light->Y() - offset.Y, z - light->Z());
}
else

View File

@ -177,7 +177,7 @@ void GLWall::PutPortal(int ptype)
if (!portal)
{
line_t *otherside = lineportal->lines[0]->mDestination;
if (otherside != NULL && otherside->portalindex < linePortals.Size())
if (otherside != NULL && otherside->portalindex < level.linePortals.Size())
{
mDrawer->RenderActorsInPortal(linePortalToGL[otherside->portalindex]);
}

View File

@ -912,7 +912,7 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item)
bool FMultiBlockLinesIterator::startIteratorForGroup(int group)
{
offset = Displacements.getOffset(basegroup, group);
offset = level.Displacements.getOffset(basegroup, group);
offset.X += checkpoint.X;
offset.Y += checkpoint.Y;
cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset);
@ -1219,7 +1219,7 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite
if (thing != NULL)
{
item->thing = thing;
item->Position = checkpoint + Displacements.getOffset(basegroup, thing->Sector->PortalGroup);
item->Position = checkpoint + level.Displacements.getOffset(basegroup, thing->Sector->PortalGroup);
item->portalflags = portalflags;
return true;
}
@ -1258,7 +1258,7 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite
void FMultiBlockThingsIterator::startIteratorForGroup(int group)
{
DVector2 offset = Displacements.getOffset(basegroup, group);
DVector2 offset = level.Displacements.getOffset(basegroup, group);
offset.X += checkpoint.X;
offset.Y += checkpoint.Y;
bbox.setBox(offset.X, offset.Y, checkpoint.Z);

View File

@ -993,7 +993,7 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
arc("sidedefs", level.sides, level.loadsides);
arc("sectors", level.sectors, level.loadsectors);
arc("zones", level.Zones);
arc("lineportals", linePortals);
arc("lineportals", level.linePortals);
arc("sectorportals", level.sectorPortals);
if (arc.isReading()) P_CollectLinkedPortals();

View File

@ -389,16 +389,16 @@ void AActor::UpdateRenderSectorList()
{
// Only check if the map contains line portals
ClearRenderLineList();
if (PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY())
if (level.PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY())
{
int bx = level.blockmap.GetBlockX(X());
int by = level.blockmap.GetBlockY(Y());
FBoundingBox bb(X(), Y(), MIN(radius*1.5, 128.)); // Don't go further than 128 map units, even for large actors
// Are there any portals near the actor's position?
if (level.blockmap.isValidBlock(bx, by) && PortalBlockmap(bx, by).neighborContainsLines)
if (level.blockmap.isValidBlock(bx, by) && level.PortalBlockmap(bx, by).neighborContainsLines)
{
// Go through the entire list. In most cases this is faster than setting up a blockmap iterator
for (auto &p : linePortals)
for (auto &p : level.linePortals)
{
if (p.mType == PORTT_VISUAL) continue;
if (bb.inRange(p.mOrigin) && bb.BoxOnLineSide(p.mOrigin))

View File

@ -486,10 +486,10 @@ int SightCheck::P_SightBlockLinesIterator (int x, int y)
// if any of the previous blocks may contain a portal we may abort the collection of lines here, but we may not abort the sight check.
// (We still try to delay activating this for as long as possible.)
portalfound = portalfound || PortalBlockmap(x, y).containsLinkedPortals;
portalfound = portalfound || level.PortalBlockmap(x, y).containsLinkedPortals;
polyLink = PolyBlockMap[offset];
portalfound |= (polyLink && PortalBlockmap.hasLinkedPolyPortals);
portalfound |= (polyLink && level.PortalBlockmap.hasLinkedPolyPortals);
while (polyLink)
{
if (polyLink->polyobj)

View File

@ -917,15 +917,15 @@ int P_Thing_Warp(AActor *caller, AActor *reference, double xofs, double yofs, do
if (flags & WARPF_WARPINTERPOLATION)
{
// This just translates the movement but doesn't change the vector
DVector3 displacedold = old + Displacements.getOffset(oldpgroup, caller->Sector->PortalGroup);
DVector3 displacedold = old + level.Displacements.getOffset(oldpgroup, caller->Sector->PortalGroup);
caller->Prev += caller->Pos() - displacedold;
caller->PrevPortalGroup = caller->Sector->PortalGroup;
}
else if (flags & WARPF_COPYINTERPOLATION)
{
// Map both positions of the reference actor to the current portal group
DVector3 displacedold = old + Displacements.getOffset(reference->PrevPortalGroup, caller->Sector->PortalGroup);
DVector3 displacedref = old + Displacements.getOffset(reference->Sector->PortalGroup, caller->Sector->PortalGroup);
DVector3 displacedold = old + level.Displacements.getOffset(reference->PrevPortalGroup, caller->Sector->PortalGroup);
DVector3 displacedref = old + level.Displacements.getOffset(reference->Sector->PortalGroup, caller->Sector->PortalGroup);
caller->Prev = caller->Pos() + displacedold - displacedref;
caller->PrevPortalGroup = caller->Sector->PortalGroup;
}

View File

@ -2326,7 +2326,7 @@ void P_PredictionLerpReset()
bool P_LerpCalculate(AActor *pmo, PredictPos from, PredictPos to, PredictPos &result, float scale)
{
//DVector2 pfrom = Displacements.getOffset(from.portalgroup, to.portalgroup);
//DVector2 pfrom = level.Displacements.getOffset(from.portalgroup, to.portalgroup);
DVector3 vecFrom = from.pos;
DVector3 vecTo = to.pos;
DVector3 vecResult;

View File

@ -906,7 +906,7 @@ void FPolyObj::UpdateLinks()
{
processed[destgroup] = true;
DVector2 delta = port->mDisplacement - old;
Displacements.MoveGroup(destgroup, delta);
level.Displacements.MoveGroup(destgroup, delta);
}
}
}

View File

@ -57,13 +57,6 @@
// simulation recurions maximum
CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO)
FDisplacementTable Displacements;
FPortalBlockmap PortalBlockmap;
TArray<FLinePortal> linePortals;
TArray<FLinePortal*> linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups.
DEFINE_FIELD(FSectorPortal, mType);
DEFINE_FIELD(FSectorPortal, mFlags);
DEFINE_FIELD(FSectorPortal, mPartner);
@ -117,14 +110,14 @@ static void BuildBlockmap()
auto bmapwidth = level.blockmap.bmapwidth;
auto bmapheight = level.blockmap.bmapheight;
PortalBlockmap.Clear();
PortalBlockmap.Create(bmapwidth, bmapheight);
level.PortalBlockmap.Clear();
level.PortalBlockmap.Create(bmapwidth, bmapheight);
for (int y = 0; y < bmapheight; y++)
{
for (int x = 0; x < bmapwidth; x++)
{
int *list = level.blockmap.GetLines(x, y);
FPortalBlock &block = PortalBlockmap(x, y);
FPortalBlock &block = level.PortalBlockmap(x, y);
while (*list != -1)
{
@ -132,14 +125,14 @@ static void BuildBlockmap()
FLinePortal *port = ld->getPortal();
if (port && port->mType != PORTT_VISUAL)
{
PortalBlockmap.containsLines = true;
level.PortalBlockmap.containsLines = true;
block.portallines.Push(ld);
block.neighborContainsLines = true;
if (ld->getPortal()->mType == PORTT_LINKED) block.containsLinkedPortals = true;
if (x > 0) PortalBlockmap(x - 1, y).neighborContainsLines = true;
if (y > 0) PortalBlockmap(x, y - 1).neighborContainsLines = true;
if (x < PortalBlockmap.dx - 1) PortalBlockmap(x + 1, y).neighborContainsLines = true;
if (y < PortalBlockmap.dy - 1) PortalBlockmap(x, y + 1).neighborContainsLines = true;
if (x > 0) level.PortalBlockmap(x - 1, y).neighborContainsLines = true;
if (y > 0) level.PortalBlockmap(x, y - 1).neighborContainsLines = true;
if (x < level.PortalBlockmap.dx - 1) level.PortalBlockmap(x + 1, y).neighborContainsLines = true;
if (y < level.PortalBlockmap.dy - 1) level.PortalBlockmap(x, y + 1).neighborContainsLines = true;
}
else
{
@ -150,7 +143,7 @@ static void BuildBlockmap()
yes |= ld->backsector->PortalIsLinked(sector_t::ceiling) || ld->backsector->PortalIsLinked(sector_t::floor);
}
block.containsLinkedPortals |= yes;
PortalBlockmap.hasLinkedSectorPortals |= yes;
level.PortalBlockmap.hasLinkedSectorPortals |= yes;
}
}
@ -168,9 +161,9 @@ static void BuildBlockmap()
void FLinePortalTraverse::AddLineIntercepts(int bx, int by)
{
if (by < 0 || by >= PortalBlockmap.dy || bx < 0 || bx >= PortalBlockmap.dx) return;
if (by < 0 || by >= level.PortalBlockmap.dy || bx < 0 || bx >= level.PortalBlockmap.dx) return;
FPortalBlock &block = PortalBlockmap(bx, by);
FPortalBlock &block = level.PortalBlockmap(bx, by);
for (unsigned i = 0; i<block.portallines.Size(); i++)
{
@ -284,8 +277,8 @@ void P_SpawnLinePortal(line_t* line)
{
dst = FindDestination(line, line->args[0]);
line->portalindex = linePortals.Reserve(1);
FLinePortal *port = &linePortals.Last();
line->portalindex = level.linePortals.Reserve(1);
FLinePortal *port = &level.linePortals.Last();
memset(port, 0, sizeof(FLinePortal));
port->mOrigin = line;
@ -321,8 +314,8 @@ void P_SpawnLinePortal(line_t* line)
{
if (tagManager.GetFirstLineID(&ln) == mytag && ln.args[0] == 1 && ln.special == Line_SetPortal)
{
line->portalindex = linePortals.Reserve(1);
FLinePortal *port = &linePortals.Last();
line->portalindex = level.linePortals.Reserve(1);
FLinePortal *port = &level.linePortals.Last();
memset(port, 0, sizeof(FLinePortal));
port->mOrigin = line;
@ -332,8 +325,8 @@ void P_SpawnLinePortal(line_t* line)
port->mDefFlags = PORTF_TYPEINTERACTIVE;
// we need to create the backlink here, too.
ln.portalindex = linePortals.Reserve(1);
port = &linePortals.Last();
ln.portalindex = level.linePortals.Reserve(1);
port = &level.linePortals.Last();
memset(port, 0, sizeof(FLinePortal));
port->mOrigin = &ln;
@ -388,7 +381,7 @@ void P_UpdatePortal(FLinePortal *port)
port->mFlags = port->mDefFlags;
if (port->mType == PORTT_LINKED)
{
if (linePortals[port->mDestination->portalindex].mType != PORTT_LINKED)
if (level.linePortals[port->mDestination->portalindex].mType != PORTT_LINKED)
{
port->mType = PORTT_INTERACTIVE; // linked portals must be two-way.
}
@ -412,13 +405,13 @@ void P_UpdatePortal(FLinePortal *port)
void P_CollectLinkedPortals()
{
linkedPortals.Clear();
for (unsigned i = 0; i < linePortals.Size(); i++)
level.linkedPortals.Clear();
for (unsigned i = 0; i < level.linePortals.Size(); i++)
{
FLinePortal * port = &linePortals[i];
FLinePortal * port = &level.linePortals[i];
if (port->mType == PORTT_LINKED)
{
linkedPortals.Push(port);
level.linkedPortals.Push(port);
}
}
}
@ -431,9 +424,9 @@ void P_CollectLinkedPortals()
void P_FinalizePortals()
{
for (unsigned i = 0; i < linePortals.Size(); i++)
for (unsigned i = 0; i < level.linePortals.Size(); i++)
{
FLinePortal * port = &linePortals[i];
FLinePortal * port = &level.linePortals[i];
P_UpdatePortal(port);
}
P_CollectLinkedPortals();
@ -449,8 +442,8 @@ void P_FinalizePortals()
static bool ChangePortalLine(line_t *line, int destid)
{
if (line->portalindex >= linePortals.Size()) return false;
FLinePortal *port = &linePortals[line->portalindex];
if (line->portalindex >= level.linePortals.Size()) return false;
FLinePortal *port = &level.linePortals[line->portalindex];
if (port->mType == PORTT_LINKED) return false; // linked portals cannot be changed.
if (destid == 0) port->mDestination = nullptr;
port->mDestination = FindDestination(line, destid);
@ -460,7 +453,7 @@ static bool ChangePortalLine(line_t *line, int destid)
}
else if (port->mType == PORTT_INTERACTIVE)
{
FLinePortal *portd = port->mDestination->portalindex < linePortals.Size()? &linePortals[port->mDestination->portalindex] : nullptr;
FLinePortal *portd = port->mDestination->portalindex < level.linePortals.Size()? &level.linePortals[port->mDestination->portalindex] : nullptr;
if (portd != nullptr && portd->mType == PORTT_INTERACTIVE && portd->mDestination == line)
{
// this is a 2-way interactive portal
@ -510,9 +503,9 @@ bool P_ChangePortal(line_t *ln, int thisid, int destid)
void P_ClearPortals()
{
Displacements.Create(1);
linePortals.Clear();
linkedPortals.Clear();
level.Displacements.Create(1);
level.linePortals.Clear();
level.linkedPortals.Clear();
level.sectorPortals.Resize(2);
// The first entry must always be the default skybox. This is what every sector gets by default.
memset(&level.sectorPortals[0], 0, sizeof(level.sectorPortals[0]));
@ -751,7 +744,7 @@ unsigned P_GetStackPortal(AActor *point, int plane)
DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy)
{
DVector2 dest(x + dx, y + dy);
if (PortalBlockmap.containsLines)
if (level.PortalBlockmap.containsLines)
{
double actx = x, acty = y;
// Try some easily discoverable early-out first. If we know that the trace cannot possibly find a portal, this saves us from calling the traverser completely for vast parts of the map.
@ -759,7 +752,7 @@ DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy)
{
int blockx = level.blockmap.GetBlockX(actx);
int blocky = level.blockmap.GetBlockY(acty);
if (blockx < 0 || blocky < 0 || blockx >= PortalBlockmap.dx || blocky >= PortalBlockmap.dy || !PortalBlockmap(blockx, blocky).neighborContainsLines) return dest;
if (blockx < 0 || blocky < 0 || blockx >= level.PortalBlockmap.dx || blocky >= level.PortalBlockmap.dy || !level.PortalBlockmap(blockx, blocky).neighborContainsLines) return dest;
}
bool repeat;
@ -867,14 +860,14 @@ static void AddDisplacementForPortal(FSectorPortal *portal)
portal->mType = PORTS_PORTAL;
return;
}
if (thisgroup <= 0 || thisgroup >= Displacements.size || othergroup <= 0 || othergroup >= Displacements.size)
if (thisgroup <= 0 || thisgroup >= level.Displacements.size || othergroup <= 0 || othergroup >= level.Displacements.size)
{
Printf("Portal between sectors %d and %d has invalid group and will be disabled\n", portal->mOrigin->sectornum, portal->mDestination->sectornum);
portal->mType = PORTS_PORTAL;
return;
}
FDisplacement & disp = Displacements(thisgroup, othergroup);
FDisplacement & disp = level.Displacements(thisgroup, othergroup);
if (!disp.isSet)
{
disp.pos = portal->mDisplacement;
@ -899,17 +892,17 @@ static void AddDisplacementForPortal(FLinePortal *portal)
if (thisgroup == othergroup)
{
Printf("Portal between lines %d and %d has both sides in same group\n", portal->mOrigin->Index(), portal->mDestination->Index());
portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
portal->mType = level.linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
return;
}
if (thisgroup <= 0 || thisgroup >= Displacements.size || othergroup <= 0 || othergroup >= Displacements.size)
if (thisgroup <= 0 || thisgroup >= level.Displacements.size || othergroup <= 0 || othergroup >= level.Displacements.size)
{
Printf("Portal between lines %d and %d has invalid group\n", portal->mOrigin->Index(), portal->mDestination->Index());
portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
portal->mType = level.linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
return;
}
FDisplacement & disp = Displacements(thisgroup, othergroup);
FDisplacement & disp = level.Displacements(thisgroup, othergroup);
if (!disp.isSet)
{
disp.pos = portal->mDisplacement;
@ -920,7 +913,7 @@ static void AddDisplacementForPortal(FLinePortal *portal)
if (disp.pos != portal->mDisplacement)
{
Printf("Portal between lines %d and %d has displacement mismatch\n", portal->mOrigin->Index(), portal->mDestination->Index());
portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
portal->mType = level.linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
return;
}
}
@ -943,19 +936,19 @@ static bool ConnectGroups()
do
{
changed = false;
for (int x = 1; x < Displacements.size; x++)
for (int x = 1; x < level.Displacements.size; x++)
{
for (int y = 1; y < Displacements.size; y++)
for (int y = 1; y < level.Displacements.size; y++)
{
FDisplacement &dispxy = Displacements(x, y);
FDisplacement &dispxy = level.Displacements(x, y);
if (dispxy.isSet)
{
for (int z = 1; z < Displacements.size; z++)
for (int z = 1; z < level.Displacements.size; z++)
{
FDisplacement &dispyz = Displacements(y, z);
FDisplacement &dispyz = level.Displacements(y, z);
if (dispyz.isSet)
{
FDisplacement &dispxz = Displacements(x, z);
FDisplacement &dispxz = level.Displacements(x, z);
if (dispxz.isSet)
{
if (dispxy.pos.X + dispyz.pos.X != dispxz.pos.X || dispxy.pos.Y + dispyz.pos.Y != dispxz.pos.Y)
@ -1034,25 +1027,25 @@ void P_CreateLinkedPortals()
if (CollectSectors(id, orgs[i]->mDestination)) id++;
}
}
for (unsigned i = 0; i < linePortals.Size(); i++)
for (unsigned i = 0; i < level.linePortals.Size(); i++)
{
if (linePortals[i].mType == PORTT_LINKED)
if (level.linePortals[i].mType == PORTT_LINKED)
{
if (linePortals[i].mDestination == nullptr)
if (level.linePortals[i].mDestination == nullptr)
{
Printf("Linked portal on line %d is unconnected and will be disabled\n", linePortals[i].mOrigin->Index());
linePortals[i].mOrigin->portalindex = UINT_MAX;
linePortals[i].mType = PORTT_VISUAL;
Printf("Linked portal on line %d is unconnected and will be disabled\n", level.linePortals[i].mOrigin->Index());
level.linePortals[i].mOrigin->portalindex = UINT_MAX;
level.linePortals[i].mType = PORTT_VISUAL;
}
else
{
if (CollectSectors(id, linePortals[i].mOrigin->frontsector)) id++;
if (CollectSectors(id, linePortals[i].mDestination->frontsector)) id++;
if (CollectSectors(id, level.linePortals[i].mOrigin->frontsector)) id++;
if (CollectSectors(id, level.linePortals[i].mDestination->frontsector)) id++;
}
}
}
Displacements.Create(id);
level.Displacements.Create(id);
// Check for leftover sectors that connect to a portal
for (auto &sec : level.sectors)
{
@ -1069,20 +1062,20 @@ void P_CreateLinkedPortals()
{
AddDisplacementForPortal(orgs[i]);
}
for (unsigned i = 0; i < linePortals.Size(); i++)
for (unsigned i = 0; i < level.linePortals.Size(); i++)
{
if (linePortals[i].mType == PORTT_LINKED)
if (level.linePortals[i].mType == PORTT_LINKED)
{
AddDisplacementForPortal(&linePortals[i]);
AddDisplacementForPortal(&level.linePortals[i]);
}
}
for (int x = 1; x < Displacements.size; x++)
for (int x = 1; x < level.Displacements.size; x++)
{
for (int y = x + 1; y < Displacements.size; y++)
for (int y = x + 1; y < level.Displacements.size; y++)
{
FDisplacement &dispxy = Displacements(x, y);
FDisplacement &dispyx = Displacements(y, x);
FDisplacement &dispxy = level.Displacements(x, y);
FDisplacement &dispyx = level.Displacements(y, x);
if (dispxy.isSet && dispyx.isSet &&
(dispxy.pos.X != -dispyx.pos.X || dispxy.pos.Y != -dispyx.pos.Y))
{
@ -1121,7 +1114,7 @@ void P_CreateLinkedPortals()
}
// reject would just get in the way when checking sight through portals.
if (Displacements.size > 1)
if (level.Displacements.size > 1)
{
level.rejectmatrix.Reset();
}
@ -1162,7 +1155,7 @@ void P_CreateLinkedPortals()
if (sec.PortalIsLinked(sector_t::floor)) sec.planes[sector_t::floor].Flags |= PLANEF_LINKED;
if (sec.PortalIsLinked(sector_t::ceiling)) sec.planes[sector_t::ceiling].Flags |= PLANEF_LINKED;
}
if (linkedPortals.Size() > 0)
if (level.linkedPortals.Size() > 0)
{
// We need to relink all actors that may touch a linked line portal
TThinkerIterator<AActor> it;
@ -1203,14 +1196,14 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
bool retval = false;
out.inited = true;
processMask.setSize(Displacements.size);
if (Displacements.size == 1)
processMask.setSize(level.Displacements.size);
if (level.Displacements.size == 1)
{
processMask.setBit(startgroup);
return false;
}
if (linkedPortals.Size() != 0)
if (level.linkedPortals.Size() != 0)
{
processMask.clear();
foundPortals.Clear();
@ -1219,17 +1212,17 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
processMask.setBit(thisgroup);
//out.Add(thisgroup);
for (unsigned i = 0; i < linkedPortals.Size(); i++)
for (unsigned i = 0; i < level.linkedPortals.Size(); i++)
{
line_t *ld = linkedPortals[i]->mOrigin;
line_t *ld = level.linkedPortals[i]->mOrigin;
int othergroup = ld->frontsector->PortalGroup;
FDisplacement &disp = Displacements(thisgroup, othergroup);
FDisplacement &disp = level.Displacements(thisgroup, othergroup);
if (!disp.isSet) continue; // no connection.
FBoundingBox box(position.X + disp.pos.X, position.Y + disp.pos.Y, checkradius);
if (!box.inRange(ld) || box.BoxOnLineSide(linkedPortals[i]->mOrigin) != -1) continue; // not touched
foundPortals.Push(linkedPortals[i]);
if (!box.inRange(ld) || box.BoxOnLineSide(level.linkedPortals[i]->mOrigin) != -1) continue; // not touched
foundPortals.Push(level.linkedPortals[i]);
}
bool foundone = true;
while (foundone)
@ -1256,7 +1249,7 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
while (!wsec->PortalBlocksMovement(sector_t::ceiling) && upperz > wsec->GetPortalPlaneZ(sector_t::ceiling))
{
int othergroup = wsec->GetOppositePortalGroup(sector_t::ceiling);
DVector2 pos = Displacements.getOffset(startgroup, othergroup) + position;
DVector2 pos = level.Displacements.getOffset(startgroup, othergroup) + position;
if (processMask.getBit(othergroup)) break;
processMask.setBit(othergroup);
out.Add(othergroup | FPortalGroupArray::UPPER);
@ -1267,21 +1260,21 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
while (!wsec->PortalBlocksMovement(sector_t::floor) && position.Z < wsec->GetPortalPlaneZ(sector_t::floor))
{
int othergroup = wsec->GetOppositePortalGroup(sector_t::floor);
DVector2 pos = Displacements.getOffset(startgroup, othergroup) + position;
DVector2 pos = level.Displacements.getOffset(startgroup, othergroup) + position;
if (processMask.getBit(othergroup)) break;
processMask.setBit(othergroup);
out.Add(othergroup | FPortalGroupArray::LOWER);
wsec = P_PointInSector(pos); // get lower sector at the exact spot we want to check and repeat
retval = true;
}
if (out.method == FPortalGroupArray::PGA_Full3d && PortalBlockmap.hasLinkedSectorPortals)
if (out.method == FPortalGroupArray::PGA_Full3d && level.PortalBlockmap.hasLinkedSectorPortals)
{
groupsToCheck.Clear();
groupsToCheck.Push(startgroup);
int thisgroup = startgroup;
for (unsigned i = 0; i < groupsToCheck.Size();i++)
{
DVector2 disp = Displacements.getOffset(startgroup, thisgroup & ~FPortalGroupArray::FLAT);
DVector2 disp = level.Displacements.getOffset(startgroup, thisgroup & ~FPortalGroupArray::FLAT);
FBoundingBox box(position.X + disp.X, position.Y + disp.Y, checkradius);
FBlockLinesIterator it(box);
line_t *ld;
@ -1344,11 +1337,11 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
CCMD(dumplinktable)
{
for (int x = 1; x < Displacements.size; x++)
for (int x = 1; x < level.Displacements.size; x++)
{
for (int y = 1; y < Displacements.size; y++)
for (int y = 1; y < level.Displacements.size; y++)
{
FDisplacement &disp = Displacements(x, y);
FDisplacement &disp = level.Displacements(x, y);
Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, int(disp.pos.X), int(disp.pos.Y));
}
Printf("\n");

View File

@ -75,8 +75,6 @@ struct FDisplacementTable
}
};
extern FDisplacementTable Displacements;
//============================================================================
//
@ -129,8 +127,6 @@ struct FPortalBlockmap
}
};
extern FPortalBlockmap PortalBlockmap;
//============================================================================
//
@ -193,8 +189,6 @@ struct FLinePortal
portnode_t *lineportal_thinglist;
};
extern TArray<FLinePortal> linePortals;
//============================================================================
//
// All information about a sector plane portal
@ -249,10 +243,6 @@ bool P_ChangePortal(line_t *ln, int thisid, int destid);
void P_CreateLinkedPortals();
bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double upperz, double checkradius, FPortalGroupArray &out);
void P_CollectLinkedPortals();
inline int P_NumPortalGroups()
{
return Displacements.size;
}
unsigned P_GetSkyboxPortal(AActor *actor);
unsigned P_GetPortal(int type, int plane, sector_t *orgsec, sector_t *destsec, const DVector2 &displacement);
unsigned P_GetStackPortal(AActor *point, int plane);

View File

@ -506,7 +506,7 @@ void R_InterpolateView (FRenderViewpoint &viewpoint, player_t *player, double Fr
}
else
{
DVector2 disp = Displacements.getOffset(oldgroup, newgroup);
DVector2 disp = level.Displacements.getOffset(oldgroup, newgroup);
viewpoint.Pos = iview->Old.Pos + (iview->New.Pos - iview->Old.Pos - disp) * Frac;
viewpoint.Path[0] = viewpoint.Path[1] = iview->New.Pos;
}

View File

@ -732,7 +732,7 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
if(type == SOURCE_Unattached)
{
sector_t *sec = P_PointInSector(pt[0], pt[2]);
DVector2 disp = Displacements.getOffset(pgroup, sec->PortalGroup);
DVector2 disp = level.Displacements.getOffset(pgroup, sec->PortalGroup);
pos->X = pt[0] - (float)disp.X;
pos->Y = !(chanflags & CHAN_LISTENERZ) ? pt[1] : (float)listenpos.Z;
pos->Z = pt[2] - (float)disp.Y;
@ -749,7 +749,7 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
//assert(actor != NULL);
if (actor != NULL)
{
DVector2 disp = Displacements.getOffset(pgroup, actor->Sector->PortalGroup);
DVector2 disp = level.Displacements.getOffset(pgroup, actor->Sector->PortalGroup);
DVector3 posi = actor->Pos() - disp;
*pos = { (float)posi.X, (float)posi.Z, (float)posi.Y };
}
@ -759,7 +759,7 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
assert(sector != NULL);
if (sector != NULL)
{
DVector2 disp = Displacements.getOffset(pgroup, sector->PortalGroup);
DVector2 disp = level.Displacements.getOffset(pgroup, sector->PortalGroup);
if (chanflags & CHAN_AREA)
{
// listener must be reversely offset to calculate the proper sound origin.
@ -781,7 +781,7 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
assert(poly != NULL);
if (poly != NULL)
{
DVector2 disp = Displacements.getOffset(pgroup, poly->CenterSubsector->sector->PortalGroup);
DVector2 disp = level.Displacements.getOffset(pgroup, poly->CenterSubsector->sector->PortalGroup);
CalcPolyobjSoundOrg(listenpos + disp, poly, *pos);
pos->X += (float)disp.X;
pos->Z += (float)disp.Y;