mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-13 07:57:58 +00:00
- moved portal data into FLevelLocals.
This commit is contained in:
parent
65e7b6dfaa
commit
8be788a9b3
19 changed files with 138 additions and 148 deletions
|
@ -2,31 +2,32 @@
|
||||||
|
|
||||||
#include "actor.h"
|
#include "actor.h"
|
||||||
#include "r_defs.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
|
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
|
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
|
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
|
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)
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2540,7 +2540,7 @@ void AM_drawWalls (bool allmap)
|
||||||
static mline_t l;
|
static mline_t l;
|
||||||
int lock, color;
|
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--)
|
for (int p = numportalgroups - 1; p >= -1; p--)
|
||||||
{
|
{
|
||||||
|
@ -2564,7 +2564,7 @@ void AM_drawWalls (bool allmap)
|
||||||
bool portalmode = numportalgroups > 0 && pg != MapPortalGroup;
|
bool portalmode = numportalgroups > 0 && pg != MapPortalGroup;
|
||||||
if (pg == p)
|
if (pg == p)
|
||||||
{
|
{
|
||||||
offset = Displacements.getOffset(pg, MapPortalGroup);
|
offset = level.Displacements.getOffset(pg, MapPortalGroup);
|
||||||
}
|
}
|
||||||
else if (p == -1 && (pg == MapPortalGroup || !am_portaloverlay))
|
else if (p == -1 && (pg == MapPortalGroup || !am_portaloverlay))
|
||||||
{
|
{
|
||||||
|
|
|
@ -2017,7 +2017,7 @@ inline T VecDiff(const T& v1, const T& v2)
|
||||||
|
|
||||||
if (nullptr != sec1 && nullptr != sec2)
|
if (nullptr != sec1 && nullptr != sec2)
|
||||||
{
|
{
|
||||||
result += Displacements.getOffset(sec2->PortalGroup, sec1->PortalGroup);
|
result += level.Displacements.getOffset(sec2->PortalGroup, sec1->PortalGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,12 @@ struct FLevelLocals
|
||||||
TArray<uint8_t> rejectmatrix;
|
TArray<uint8_t> rejectmatrix;
|
||||||
|
|
||||||
TArray<FSectorPortal> sectorPortals;
|
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;
|
TArray<zone_t> Zones;
|
||||||
|
|
||||||
FBlockmap blockmap;
|
FBlockmap blockmap;
|
||||||
|
@ -268,27 +274,27 @@ inline bool sector_t::PortalIsLinked(int plane)
|
||||||
|
|
||||||
inline FLinePortal *line_t::getPortal() const
|
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
|
// returns true if the portal is crossable by actors
|
||||||
inline bool line_t::isLinePortal() const
|
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
|
// returns true if the portal needs to be handled by the renderer
|
||||||
inline bool line_t::isVisualPortal() const
|
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
|
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
|
inline int line_t::getPortalAlignment() const
|
||||||
{
|
{
|
||||||
return portalindex >= linePortals.Size() ? 0 : linePortals[portalindex].mAlign;
|
return portalindex >= level.linePortals.Size() ? 0 : level.linePortals[portalindex].mAlign;
|
||||||
}
|
}
|
||||||
|
|
|
@ -409,24 +409,24 @@ void gl_InitPortals()
|
||||||
linePortalToGL.Clear();
|
linePortalToGL.Clear();
|
||||||
TArray<int> tempindex;
|
TArray<int> tempindex;
|
||||||
|
|
||||||
tempindex.Reserve(linePortals.Size());
|
tempindex.Reserve(level.linePortals.Size());
|
||||||
memset(&tempindex[0], -1, linePortals.Size() * sizeof(int));
|
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;
|
bool gotsome;
|
||||||
|
|
||||||
if (tempindex[i] == -1)
|
if (tempindex[i] == -1)
|
||||||
{
|
{
|
||||||
tempindex[i] = glLinePortals.Size();
|
tempindex[i] = glLinePortals.Size();
|
||||||
line_t *pSrcLine = linePortals[i].mOrigin;
|
line_t *pSrcLine = level.linePortals[i].mOrigin;
|
||||||
line_t *pLine = linePortals[i].mDestination;
|
line_t *pLine = level.linePortals[i].mDestination;
|
||||||
FGLLinePortal &glport = glLinePortals[glLinePortals.Reserve(1)];
|
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.
|
// 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.v1 = pLine->v1;
|
||||||
glport.v2 = pLine->v2;
|
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
|
// now collect all other colinear lines connected to this one. We run this loop as long as it still finds a match
|
||||||
gotsome = false;
|
gotsome = false;
|
||||||
for (unsigned j = 0; j < linePortals.Size(); j++)
|
for (unsigned j = 0; j < level.linePortals.Size(); j++)
|
||||||
{
|
{
|
||||||
if (tempindex[j] == -1)
|
if (tempindex[j] == -1)
|
||||||
{
|
{
|
||||||
line_t *pSrcLine2 = linePortals[j].mOrigin;
|
line_t *pSrcLine2 = level.linePortals[j].mOrigin;
|
||||||
line_t *pLine2 = linePortals[j].mDestination;
|
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.)
|
// 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 srcang = pSrcLine->Delta().Angle().BAMs();
|
||||||
unsigned dstang = pLine->Delta().Angle().BAMs();
|
unsigned dstang = pLine->Delta().Angle().BAMs();
|
||||||
|
@ -456,7 +456,7 @@ void gl_InitPortals()
|
||||||
tempindex[j] = tempindex[i];
|
tempindex[j] = tempindex[i];
|
||||||
if (pLine->v1 == pLine2->v2) glport.v1 = pLine2->v1;
|
if (pLine->v1 == pLine2->v2) glport.v1 = pLine2->v1;
|
||||||
else glport.v2 = pLine2->v2;
|
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());
|
linePortalToGL.Resize(level.linePortals.Size());
|
||||||
for (unsigned i = 0; i < linePortals.Size(); i++)
|
for (unsigned i = 0; i < level.linePortals.Size(); i++)
|
||||||
{
|
{
|
||||||
linePortalToGL[i] = &glLinePortals[tempindex[i]];
|
linePortalToGL[i] = &glLinePortals[tempindex[i]];
|
||||||
/*
|
/*
|
||||||
Printf("portal at line %d translates to GL portal %d, range = %f,%f to %f,%f\n",
|
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.);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
// [RH] Interpolate the sprite's position to make it look smooth
|
||||||
DVector3 thingpos = thing->InterpolatedPosition(r_viewpoint.TicFrac);
|
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
|
// 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)
|
if (thing == camera && !r_viewpoint.showviewer)
|
||||||
{
|
{
|
||||||
DVector3 thingorigin = thing->Pos();
|
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;
|
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.
|
// Thing is invisible if close to the camera.
|
||||||
|
|
|
@ -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 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.
|
// 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 fromgroup = light->Sector->PortalGroup;
|
||||||
int togroup = subsec->sector->PortalGroup;
|
int togroup = subsec->sector->PortalGroup;
|
||||||
if (fromgroup == togroup || fromgroup == 0 || togroup == 0) goto direct;
|
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());
|
L = FVector3(x - light->X() - offset.X, y - light->Y() - offset.Y, z - light->Z());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -177,7 +177,7 @@ void GLWall::PutPortal(int ptype)
|
||||||
if (!portal)
|
if (!portal)
|
||||||
{
|
{
|
||||||
line_t *otherside = lineportal->lines[0]->mDestination;
|
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]);
|
mDrawer->RenderActorsInPortal(linePortalToGL[otherside->portalindex]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -912,7 +912,7 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item)
|
||||||
|
|
||||||
bool FMultiBlockLinesIterator::startIteratorForGroup(int group)
|
bool FMultiBlockLinesIterator::startIteratorForGroup(int group)
|
||||||
{
|
{
|
||||||
offset = Displacements.getOffset(basegroup, group);
|
offset = level.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);
|
cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset);
|
||||||
|
@ -1219,7 +1219,7 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite
|
||||||
if (thing != NULL)
|
if (thing != NULL)
|
||||||
{
|
{
|
||||||
item->thing = thing;
|
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;
|
item->portalflags = portalflags;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1258,7 +1258,7 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite
|
||||||
|
|
||||||
void FMultiBlockThingsIterator::startIteratorForGroup(int group)
|
void FMultiBlockThingsIterator::startIteratorForGroup(int group)
|
||||||
{
|
{
|
||||||
DVector2 offset = Displacements.getOffset(basegroup, group);
|
DVector2 offset = level.Displacements.getOffset(basegroup, group);
|
||||||
offset.X += checkpoint.X;
|
offset.X += checkpoint.X;
|
||||||
offset.Y += checkpoint.Y;
|
offset.Y += checkpoint.Y;
|
||||||
bbox.setBox(offset.X, offset.Y, checkpoint.Z);
|
bbox.setBox(offset.X, offset.Y, checkpoint.Z);
|
||||||
|
|
|
@ -993,7 +993,7 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
|
||||||
arc("sidedefs", level.sides, level.loadsides);
|
arc("sidedefs", level.sides, level.loadsides);
|
||||||
arc("sectors", level.sectors, level.loadsectors);
|
arc("sectors", level.sectors, level.loadsectors);
|
||||||
arc("zones", level.Zones);
|
arc("zones", level.Zones);
|
||||||
arc("lineportals", linePortals);
|
arc("lineportals", level.linePortals);
|
||||||
arc("sectorportals", level.sectorPortals);
|
arc("sectorportals", level.sectorPortals);
|
||||||
if (arc.isReading()) P_CollectLinkedPortals();
|
if (arc.isReading()) P_CollectLinkedPortals();
|
||||||
|
|
||||||
|
|
|
@ -389,16 +389,16 @@ void AActor::UpdateRenderSectorList()
|
||||||
{
|
{
|
||||||
// Only check if the map contains line portals
|
// Only check if the map contains line portals
|
||||||
ClearRenderLineList();
|
ClearRenderLineList();
|
||||||
if (PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY())
|
if (level.PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY())
|
||||||
{
|
{
|
||||||
int bx = level.blockmap.GetBlockX(X());
|
int bx = level.blockmap.GetBlockX(X());
|
||||||
int by = level.blockmap.GetBlockY(Y());
|
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
|
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?
|
// 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
|
// 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 (p.mType == PORTT_VISUAL) continue;
|
||||||
if (bb.inRange(p.mOrigin) && bb.BoxOnLineSide(p.mOrigin))
|
if (bb.inRange(p.mOrigin) && bb.BoxOnLineSide(p.mOrigin))
|
||||||
|
|
|
@ -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.
|
// 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.)
|
// (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];
|
polyLink = PolyBlockMap[offset];
|
||||||
portalfound |= (polyLink && PortalBlockmap.hasLinkedPolyPortals);
|
portalfound |= (polyLink && level.PortalBlockmap.hasLinkedPolyPortals);
|
||||||
while (polyLink)
|
while (polyLink)
|
||||||
{
|
{
|
||||||
if (polyLink->polyobj)
|
if (polyLink->polyobj)
|
||||||
|
|
|
@ -917,15 +917,15 @@ int P_Thing_Warp(AActor *caller, AActor *reference, double xofs, double yofs, do
|
||||||
if (flags & WARPF_WARPINTERPOLATION)
|
if (flags & WARPF_WARPINTERPOLATION)
|
||||||
{
|
{
|
||||||
// This just translates the movement but doesn't change the vector
|
// 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->Prev += caller->Pos() - displacedold;
|
||||||
caller->PrevPortalGroup = caller->Sector->PortalGroup;
|
caller->PrevPortalGroup = caller->Sector->PortalGroup;
|
||||||
}
|
}
|
||||||
else if (flags & WARPF_COPYINTERPOLATION)
|
else if (flags & WARPF_COPYINTERPOLATION)
|
||||||
{
|
{
|
||||||
// Map both positions of the reference actor to the current portal group
|
// Map both positions of the reference actor to the current portal group
|
||||||
DVector3 displacedold = old + Displacements.getOffset(reference->PrevPortalGroup, caller->Sector->PortalGroup);
|
DVector3 displacedold = old + level.Displacements.getOffset(reference->PrevPortalGroup, caller->Sector->PortalGroup);
|
||||||
DVector3 displacedref = old + Displacements.getOffset(reference->Sector->PortalGroup, caller->Sector->PortalGroup);
|
DVector3 displacedref = old + level.Displacements.getOffset(reference->Sector->PortalGroup, caller->Sector->PortalGroup);
|
||||||
caller->Prev = caller->Pos() + displacedold - displacedref;
|
caller->Prev = caller->Pos() + displacedold - displacedref;
|
||||||
caller->PrevPortalGroup = caller->Sector->PortalGroup;
|
caller->PrevPortalGroup = caller->Sector->PortalGroup;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2326,7 +2326,7 @@ void P_PredictionLerpReset()
|
||||||
|
|
||||||
bool P_LerpCalculate(AActor *pmo, PredictPos from, PredictPos to, PredictPos &result, float scale)
|
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 vecFrom = from.pos;
|
||||||
DVector3 vecTo = to.pos;
|
DVector3 vecTo = to.pos;
|
||||||
DVector3 vecResult;
|
DVector3 vecResult;
|
||||||
|
|
|
@ -906,7 +906,7 @@ void FPolyObj::UpdateLinks()
|
||||||
{
|
{
|
||||||
processed[destgroup] = true;
|
processed[destgroup] = true;
|
||||||
DVector2 delta = port->mDisplacement - old;
|
DVector2 delta = port->mDisplacement - old;
|
||||||
Displacements.MoveGroup(destgroup, delta);
|
level.Displacements.MoveGroup(destgroup, delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
163
src/portal.cpp
163
src/portal.cpp
|
@ -57,13 +57,6 @@
|
||||||
// simulation recurions maximum
|
// simulation recurions maximum
|
||||||
CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO)
|
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, mType);
|
||||||
DEFINE_FIELD(FSectorPortal, mFlags);
|
DEFINE_FIELD(FSectorPortal, mFlags);
|
||||||
DEFINE_FIELD(FSectorPortal, mPartner);
|
DEFINE_FIELD(FSectorPortal, mPartner);
|
||||||
|
@ -117,14 +110,14 @@ static void BuildBlockmap()
|
||||||
auto bmapwidth = level.blockmap.bmapwidth;
|
auto bmapwidth = level.blockmap.bmapwidth;
|
||||||
auto bmapheight = level.blockmap.bmapheight;
|
auto bmapheight = level.blockmap.bmapheight;
|
||||||
|
|
||||||
PortalBlockmap.Clear();
|
level.PortalBlockmap.Clear();
|
||||||
PortalBlockmap.Create(bmapwidth, bmapheight);
|
level.PortalBlockmap.Create(bmapwidth, bmapheight);
|
||||||
for (int y = 0; y < bmapheight; y++)
|
for (int y = 0; y < bmapheight; y++)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < bmapwidth; x++)
|
for (int x = 0; x < bmapwidth; x++)
|
||||||
{
|
{
|
||||||
int *list = level.blockmap.GetLines(x, y);
|
int *list = level.blockmap.GetLines(x, y);
|
||||||
FPortalBlock &block = PortalBlockmap(x, y);
|
FPortalBlock &block = level.PortalBlockmap(x, y);
|
||||||
|
|
||||||
while (*list != -1)
|
while (*list != -1)
|
||||||
{
|
{
|
||||||
|
@ -132,14 +125,14 @@ static void BuildBlockmap()
|
||||||
FLinePortal *port = ld->getPortal();
|
FLinePortal *port = ld->getPortal();
|
||||||
if (port && port->mType != PORTT_VISUAL)
|
if (port && port->mType != PORTT_VISUAL)
|
||||||
{
|
{
|
||||||
PortalBlockmap.containsLines = true;
|
level.PortalBlockmap.containsLines = true;
|
||||||
block.portallines.Push(ld);
|
block.portallines.Push(ld);
|
||||||
block.neighborContainsLines = true;
|
block.neighborContainsLines = true;
|
||||||
if (ld->getPortal()->mType == PORTT_LINKED) block.containsLinkedPortals = true;
|
if (ld->getPortal()->mType == PORTT_LINKED) block.containsLinkedPortals = true;
|
||||||
if (x > 0) PortalBlockmap(x - 1, y).neighborContainsLines = true;
|
if (x > 0) level.PortalBlockmap(x - 1, y).neighborContainsLines = true;
|
||||||
if (y > 0) PortalBlockmap(x, y - 1).neighborContainsLines = true;
|
if (y > 0) level.PortalBlockmap(x, y - 1).neighborContainsLines = true;
|
||||||
if (x < PortalBlockmap.dx - 1) PortalBlockmap(x + 1, y).neighborContainsLines = true;
|
if (x < level.PortalBlockmap.dx - 1) level.PortalBlockmap(x + 1, y).neighborContainsLines = true;
|
||||||
if (y < PortalBlockmap.dy - 1) PortalBlockmap(x, y + 1).neighborContainsLines = true;
|
if (y < level.PortalBlockmap.dy - 1) level.PortalBlockmap(x, y + 1).neighborContainsLines = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -150,7 +143,7 @@ static void BuildBlockmap()
|
||||||
yes |= ld->backsector->PortalIsLinked(sector_t::ceiling) || ld->backsector->PortalIsLinked(sector_t::floor);
|
yes |= ld->backsector->PortalIsLinked(sector_t::ceiling) || ld->backsector->PortalIsLinked(sector_t::floor);
|
||||||
}
|
}
|
||||||
block.containsLinkedPortals |= yes;
|
block.containsLinkedPortals |= yes;
|
||||||
PortalBlockmap.hasLinkedSectorPortals |= yes;
|
level.PortalBlockmap.hasLinkedSectorPortals |= yes;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,9 +161,9 @@ static void BuildBlockmap()
|
||||||
|
|
||||||
void FLinePortalTraverse::AddLineIntercepts(int bx, int by)
|
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++)
|
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]);
|
dst = FindDestination(line, line->args[0]);
|
||||||
|
|
||||||
line->portalindex = linePortals.Reserve(1);
|
line->portalindex = level.linePortals.Reserve(1);
|
||||||
FLinePortal *port = &linePortals.Last();
|
FLinePortal *port = &level.linePortals.Last();
|
||||||
|
|
||||||
memset(port, 0, sizeof(FLinePortal));
|
memset(port, 0, sizeof(FLinePortal));
|
||||||
port->mOrigin = line;
|
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)
|
if (tagManager.GetFirstLineID(&ln) == mytag && ln.args[0] == 1 && ln.special == Line_SetPortal)
|
||||||
{
|
{
|
||||||
line->portalindex = linePortals.Reserve(1);
|
line->portalindex = level.linePortals.Reserve(1);
|
||||||
FLinePortal *port = &linePortals.Last();
|
FLinePortal *port = &level.linePortals.Last();
|
||||||
|
|
||||||
memset(port, 0, sizeof(FLinePortal));
|
memset(port, 0, sizeof(FLinePortal));
|
||||||
port->mOrigin = line;
|
port->mOrigin = line;
|
||||||
|
@ -332,8 +325,8 @@ void P_SpawnLinePortal(line_t* line)
|
||||||
port->mDefFlags = PORTF_TYPEINTERACTIVE;
|
port->mDefFlags = PORTF_TYPEINTERACTIVE;
|
||||||
|
|
||||||
// we need to create the backlink here, too.
|
// we need to create the backlink here, too.
|
||||||
ln.portalindex = linePortals.Reserve(1);
|
ln.portalindex = level.linePortals.Reserve(1);
|
||||||
port = &linePortals.Last();
|
port = &level.linePortals.Last();
|
||||||
|
|
||||||
memset(port, 0, sizeof(FLinePortal));
|
memset(port, 0, sizeof(FLinePortal));
|
||||||
port->mOrigin = &ln;
|
port->mOrigin = &ln;
|
||||||
|
@ -388,7 +381,7 @@ void P_UpdatePortal(FLinePortal *port)
|
||||||
port->mFlags = port->mDefFlags;
|
port->mFlags = port->mDefFlags;
|
||||||
if (port->mType == PORTT_LINKED)
|
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.
|
port->mType = PORTT_INTERACTIVE; // linked portals must be two-way.
|
||||||
}
|
}
|
||||||
|
@ -412,13 +405,13 @@ void P_UpdatePortal(FLinePortal *port)
|
||||||
|
|
||||||
void P_CollectLinkedPortals()
|
void P_CollectLinkedPortals()
|
||||||
{
|
{
|
||||||
linkedPortals.Clear();
|
level.linkedPortals.Clear();
|
||||||
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];
|
||||||
if (port->mType == PORTT_LINKED)
|
if (port->mType == PORTT_LINKED)
|
||||||
{
|
{
|
||||||
linkedPortals.Push(port);
|
level.linkedPortals.Push(port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -431,9 +424,9 @@ void P_CollectLinkedPortals()
|
||||||
|
|
||||||
void P_FinalizePortals()
|
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_UpdatePortal(port);
|
||||||
}
|
}
|
||||||
P_CollectLinkedPortals();
|
P_CollectLinkedPortals();
|
||||||
|
@ -449,8 +442,8 @@ void P_FinalizePortals()
|
||||||
|
|
||||||
static bool ChangePortalLine(line_t *line, int destid)
|
static bool ChangePortalLine(line_t *line, int destid)
|
||||||
{
|
{
|
||||||
if (line->portalindex >= linePortals.Size()) return false;
|
if (line->portalindex >= level.linePortals.Size()) return false;
|
||||||
FLinePortal *port = &linePortals[line->portalindex];
|
FLinePortal *port = &level.linePortals[line->portalindex];
|
||||||
if (port->mType == PORTT_LINKED) return false; // linked portals cannot be changed.
|
if (port->mType == PORTT_LINKED) return false; // linked portals cannot be changed.
|
||||||
if (destid == 0) port->mDestination = nullptr;
|
if (destid == 0) port->mDestination = nullptr;
|
||||||
port->mDestination = FindDestination(line, destid);
|
port->mDestination = FindDestination(line, destid);
|
||||||
|
@ -460,7 +453,7 @@ static bool ChangePortalLine(line_t *line, int destid)
|
||||||
}
|
}
|
||||||
else if (port->mType == PORTT_INTERACTIVE)
|
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)
|
if (portd != nullptr && portd->mType == PORTT_INTERACTIVE && portd->mDestination == line)
|
||||||
{
|
{
|
||||||
// this is a 2-way interactive portal
|
// this is a 2-way interactive portal
|
||||||
|
@ -510,9 +503,9 @@ bool P_ChangePortal(line_t *ln, int thisid, int destid)
|
||||||
|
|
||||||
void P_ClearPortals()
|
void P_ClearPortals()
|
||||||
{
|
{
|
||||||
Displacements.Create(1);
|
level.Displacements.Create(1);
|
||||||
linePortals.Clear();
|
level.linePortals.Clear();
|
||||||
linkedPortals.Clear();
|
level.linkedPortals.Clear();
|
||||||
level.sectorPortals.Resize(2);
|
level.sectorPortals.Resize(2);
|
||||||
// The first entry must always be the default skybox. This is what every sector gets by default.
|
// 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]));
|
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 P_GetOffsetPosition(double x, double y, double dx, double dy)
|
||||||
{
|
{
|
||||||
DVector2 dest(x + dx, y + dy);
|
DVector2 dest(x + dx, y + dy);
|
||||||
if (PortalBlockmap.containsLines)
|
if (level.PortalBlockmap.containsLines)
|
||||||
{
|
{
|
||||||
double actx = x, acty = y;
|
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.
|
// 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 blockx = level.blockmap.GetBlockX(actx);
|
||||||
int blocky = level.blockmap.GetBlockY(acty);
|
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;
|
bool repeat;
|
||||||
|
@ -867,14 +860,14 @@ static void AddDisplacementForPortal(FSectorPortal *portal)
|
||||||
portal->mType = PORTS_PORTAL;
|
portal->mType = PORTS_PORTAL;
|
||||||
return;
|
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);
|
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;
|
portal->mType = PORTS_PORTAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FDisplacement & disp = Displacements(thisgroup, othergroup);
|
FDisplacement & disp = level.Displacements(thisgroup, othergroup);
|
||||||
if (!disp.isSet)
|
if (!disp.isSet)
|
||||||
{
|
{
|
||||||
disp.pos = portal->mDisplacement;
|
disp.pos = portal->mDisplacement;
|
||||||
|
@ -899,17 +892,17 @@ static void AddDisplacementForPortal(FLinePortal *portal)
|
||||||
if (thisgroup == othergroup)
|
if (thisgroup == othergroup)
|
||||||
{
|
{
|
||||||
Printf("Portal between lines %d and %d has both sides in same group\n", portal->mOrigin->Index(), portal->mDestination->Index());
|
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;
|
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());
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FDisplacement & disp = Displacements(thisgroup, othergroup);
|
FDisplacement & disp = level.Displacements(thisgroup, othergroup);
|
||||||
if (!disp.isSet)
|
if (!disp.isSet)
|
||||||
{
|
{
|
||||||
disp.pos = portal->mDisplacement;
|
disp.pos = portal->mDisplacement;
|
||||||
|
@ -920,7 +913,7 @@ static void AddDisplacementForPortal(FLinePortal *portal)
|
||||||
if (disp.pos != portal->mDisplacement)
|
if (disp.pos != portal->mDisplacement)
|
||||||
{
|
{
|
||||||
Printf("Portal between lines %d and %d has displacement mismatch\n", portal->mOrigin->Index(), portal->mDestination->Index());
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -943,19 +936,19 @@ static bool ConnectGroups()
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
changed = false;
|
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)
|
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)
|
if (dispyz.isSet)
|
||||||
{
|
{
|
||||||
FDisplacement &dispxz = Displacements(x, z);
|
FDisplacement &dispxz = level.Displacements(x, z);
|
||||||
if (dispxz.isSet)
|
if (dispxz.isSet)
|
||||||
{
|
{
|
||||||
if (dispxy.pos.X + dispyz.pos.X != dispxz.pos.X || dispxy.pos.Y + dispyz.pos.Y != dispxz.pos.Y)
|
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++;
|
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());
|
Printf("Linked portal on line %d is unconnected and will be disabled\n", level.linePortals[i].mOrigin->Index());
|
||||||
linePortals[i].mOrigin->portalindex = UINT_MAX;
|
level.linePortals[i].mOrigin->portalindex = UINT_MAX;
|
||||||
linePortals[i].mType = PORTT_VISUAL;
|
level.linePortals[i].mType = PORTT_VISUAL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (CollectSectors(id, linePortals[i].mOrigin->frontsector)) id++;
|
if (CollectSectors(id, level.linePortals[i].mOrigin->frontsector)) id++;
|
||||||
if (CollectSectors(id, linePortals[i].mDestination->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
|
// Check for leftover sectors that connect to a portal
|
||||||
for (auto &sec : level.sectors)
|
for (auto &sec : level.sectors)
|
||||||
{
|
{
|
||||||
|
@ -1069,20 +1062,20 @@ void P_CreateLinkedPortals()
|
||||||
{
|
{
|
||||||
AddDisplacementForPortal(orgs[i]);
|
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 &dispxy = level.Displacements(x, y);
|
||||||
FDisplacement &dispyx = Displacements(y, x);
|
FDisplacement &dispyx = level.Displacements(y, x);
|
||||||
if (dispxy.isSet && dispyx.isSet &&
|
if (dispxy.isSet && dispyx.isSet &&
|
||||||
(dispxy.pos.X != -dispyx.pos.X || dispxy.pos.Y != -dispyx.pos.Y))
|
(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.
|
// reject would just get in the way when checking sight through portals.
|
||||||
if (Displacements.size > 1)
|
if (level.Displacements.size > 1)
|
||||||
{
|
{
|
||||||
level.rejectmatrix.Reset();
|
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::floor)) sec.planes[sector_t::floor].Flags |= PLANEF_LINKED;
|
||||||
if (sec.PortalIsLinked(sector_t::ceiling)) sec.planes[sector_t::ceiling].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
|
// We need to relink all actors that may touch a linked line portal
|
||||||
TThinkerIterator<AActor> it;
|
TThinkerIterator<AActor> it;
|
||||||
|
@ -1203,14 +1196,14 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
out.inited = true;
|
out.inited = true;
|
||||||
|
|
||||||
processMask.setSize(Displacements.size);
|
processMask.setSize(level.Displacements.size);
|
||||||
if (Displacements.size == 1)
|
if (level.Displacements.size == 1)
|
||||||
{
|
{
|
||||||
processMask.setBit(startgroup);
|
processMask.setBit(startgroup);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (linkedPortals.Size() != 0)
|
if (level.linkedPortals.Size() != 0)
|
||||||
{
|
{
|
||||||
processMask.clear();
|
processMask.clear();
|
||||||
foundPortals.Clear();
|
foundPortals.Clear();
|
||||||
|
@ -1219,17 +1212,17 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
|
||||||
processMask.setBit(thisgroup);
|
processMask.setBit(thisgroup);
|
||||||
//out.Add(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;
|
int othergroup = ld->frontsector->PortalGroup;
|
||||||
FDisplacement &disp = Displacements(thisgroup, othergroup);
|
FDisplacement &disp = level.Displacements(thisgroup, othergroup);
|
||||||
if (!disp.isSet) continue; // no connection.
|
if (!disp.isSet) continue; // no connection.
|
||||||
|
|
||||||
FBoundingBox box(position.X + disp.pos.X, position.Y + disp.pos.Y, checkradius);
|
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
|
if (!box.inRange(ld) || box.BoxOnLineSide(level.linkedPortals[i]->mOrigin) != -1) continue; // not touched
|
||||||
foundPortals.Push(linkedPortals[i]);
|
foundPortals.Push(level.linkedPortals[i]);
|
||||||
}
|
}
|
||||||
bool foundone = true;
|
bool foundone = true;
|
||||||
while (foundone)
|
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))
|
while (!wsec->PortalBlocksMovement(sector_t::ceiling) && upperz > wsec->GetPortalPlaneZ(sector_t::ceiling))
|
||||||
{
|
{
|
||||||
int othergroup = wsec->GetOppositePortalGroup(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;
|
if (processMask.getBit(othergroup)) break;
|
||||||
processMask.setBit(othergroup);
|
processMask.setBit(othergroup);
|
||||||
out.Add(othergroup | FPortalGroupArray::UPPER);
|
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))
|
while (!wsec->PortalBlocksMovement(sector_t::floor) && position.Z < wsec->GetPortalPlaneZ(sector_t::floor))
|
||||||
{
|
{
|
||||||
int othergroup = wsec->GetOppositePortalGroup(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;
|
if (processMask.getBit(othergroup)) break;
|
||||||
processMask.setBit(othergroup);
|
processMask.setBit(othergroup);
|
||||||
out.Add(othergroup | FPortalGroupArray::LOWER);
|
out.Add(othergroup | FPortalGroupArray::LOWER);
|
||||||
wsec = P_PointInSector(pos); // get lower sector at the exact spot we want to check and repeat
|
wsec = P_PointInSector(pos); // get lower sector at the exact spot we want to check and repeat
|
||||||
retval = true;
|
retval = true;
|
||||||
}
|
}
|
||||||
if (out.method == FPortalGroupArray::PGA_Full3d && PortalBlockmap.hasLinkedSectorPortals)
|
if (out.method == FPortalGroupArray::PGA_Full3d && level.PortalBlockmap.hasLinkedSectorPortals)
|
||||||
{
|
{
|
||||||
groupsToCheck.Clear();
|
groupsToCheck.Clear();
|
||||||
groupsToCheck.Push(startgroup);
|
groupsToCheck.Push(startgroup);
|
||||||
int thisgroup = startgroup;
|
int thisgroup = startgroup;
|
||||||
for (unsigned i = 0; i < groupsToCheck.Size();i++)
|
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);
|
FBoundingBox box(position.X + disp.X, position.Y + disp.Y, checkradius);
|
||||||
FBlockLinesIterator it(box);
|
FBlockLinesIterator it(box);
|
||||||
line_t *ld;
|
line_t *ld;
|
||||||
|
@ -1344,11 +1337,11 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
|
||||||
|
|
||||||
CCMD(dumplinktable)
|
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("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, int(disp.pos.X), int(disp.pos.Y));
|
||||||
}
|
}
|
||||||
Printf("\n");
|
Printf("\n");
|
||||||
|
|
10
src/portal.h
10
src/portal.h
|
@ -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;
|
portnode_t *lineportal_thinglist;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern TArray<FLinePortal> linePortals;
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// All information about a sector plane portal
|
// All information about a sector plane portal
|
||||||
|
@ -249,10 +243,6 @@ bool P_ChangePortal(line_t *ln, int thisid, int destid);
|
||||||
void P_CreateLinkedPortals();
|
void P_CreateLinkedPortals();
|
||||||
bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double upperz, double checkradius, FPortalGroupArray &out);
|
bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double upperz, double checkradius, FPortalGroupArray &out);
|
||||||
void P_CollectLinkedPortals();
|
void P_CollectLinkedPortals();
|
||||||
inline int P_NumPortalGroups()
|
|
||||||
{
|
|
||||||
return Displacements.size;
|
|
||||||
}
|
|
||||||
unsigned P_GetSkyboxPortal(AActor *actor);
|
unsigned P_GetSkyboxPortal(AActor *actor);
|
||||||
unsigned P_GetPortal(int type, int plane, sector_t *orgsec, sector_t *destsec, const DVector2 &displacement);
|
unsigned P_GetPortal(int type, int plane, sector_t *orgsec, sector_t *destsec, const DVector2 &displacement);
|
||||||
unsigned P_GetStackPortal(AActor *point, int plane);
|
unsigned P_GetStackPortal(AActor *point, int plane);
|
||||||
|
|
|
@ -506,7 +506,7 @@ void R_InterpolateView (FRenderViewpoint &viewpoint, player_t *player, double Fr
|
||||||
}
|
}
|
||||||
else
|
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.Pos = iview->Old.Pos + (iview->New.Pos - iview->Old.Pos - disp) * Frac;
|
||||||
viewpoint.Path[0] = viewpoint.Path[1] = iview->New.Pos;
|
viewpoint.Path[0] = viewpoint.Path[1] = iview->New.Pos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -732,7 +732,7 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
|
||||||
if(type == SOURCE_Unattached)
|
if(type == SOURCE_Unattached)
|
||||||
{
|
{
|
||||||
sector_t *sec = P_PointInSector(pt[0], pt[2]);
|
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->X = pt[0] - (float)disp.X;
|
||||||
pos->Y = !(chanflags & CHAN_LISTENERZ) ? pt[1] : (float)listenpos.Z;
|
pos->Y = !(chanflags & CHAN_LISTENERZ) ? pt[1] : (float)listenpos.Z;
|
||||||
pos->Z = pt[2] - (float)disp.Y;
|
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);
|
//assert(actor != NULL);
|
||||||
if (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;
|
DVector3 posi = actor->Pos() - disp;
|
||||||
*pos = { (float)posi.X, (float)posi.Z, (float)posi.Y };
|
*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);
|
assert(sector != NULL);
|
||||||
if (sector != NULL)
|
if (sector != NULL)
|
||||||
{
|
{
|
||||||
DVector2 disp = Displacements.getOffset(pgroup, sector->PortalGroup);
|
DVector2 disp = level.Displacements.getOffset(pgroup, sector->PortalGroup);
|
||||||
if (chanflags & CHAN_AREA)
|
if (chanflags & CHAN_AREA)
|
||||||
{
|
{
|
||||||
// listener must be reversely offset to calculate the proper sound origin.
|
// 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);
|
assert(poly != NULL);
|
||||||
if (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);
|
CalcPolyobjSoundOrg(listenpos + disp, poly, *pos);
|
||||||
pos->X += (float)disp.X;
|
pos->X += (float)disp.X;
|
||||||
pos->Z += (float)disp.Y;
|
pos->Z += (float)disp.Y;
|
||||||
|
|
Loading…
Reference in a new issue