- some header dependency cleanup so that it is no longer needed to include portal.h to get the inline functions. Portal.h has been reduced of most dependencies now so that including it is cheap and can be done in other headers.

- some consolidation in p_map.cpp. PIT_CheckLine and PIT_FindFloorCeiling had quite a bit of redundancy which has been merged.
- čontinued work on FMultiBlockLinesIterator. It's still not completely finished.
This commit is contained in:
Christoph Oelckers 2016-02-19 14:08:41 +01:00
parent 15040c955e
commit 02d7572343
25 changed files with 269 additions and 293 deletions

View file

@ -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);

View file

@ -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)

View file

@ -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>((SQWORD)y + radius, FIXED_MAX);
m_Box[BOXLEFT] = (fixed_t)MAX<SQWORD>((SQWORD)x - radius, FIXED_MIN);

View file

@ -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 ()
{

View file

@ -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"

View file

@ -17,7 +17,6 @@
#include "g_level.h"
#include "r_data/colormaps.h"
#include "gi.h"
#include "portal.h"
#include "p_spec.h"
// MACROS ------------------------------------------------------------------

View file

@ -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"

View file

@ -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);

View file

@ -80,6 +80,7 @@ TArray<line_t *> 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;
}

View file

@ -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);
}

View file

@ -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<WORD> 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;
}
};

View file

@ -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);

View file

@ -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<ASkyViewpoint*>(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;

View file

@ -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"

View file

@ -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<ASkyViewpoint*>(it.Next());
if (Sector->SkyBoxes[sector_t::floor] != NULL && Sector->SkyBoxes[sector_t::floor]->bAlways)
ASkyViewpoint *skyv = static_cast<ASkyViewpoint*>(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<ASkyViewpoint*>(it.Next());
if (Sector->SkyBoxes[sector_t::ceiling] != NULL && Sector->SkyBoxes[sector_t::ceiling]->bAlways)
ASkyViewpoint *skyv = static_cast<ASkyViewpoint*>(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<ASkyViewpoint*>(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<ASkyViewpoint*>(sector->SkyBoxes[sector_t::floor])->bAlways)
{
sector->SkyBoxes[sector_t::floor] = portal;
}

View file

@ -47,7 +47,6 @@
#include "r_data/colormaps.h"
#include "w_wad.h"
#include "p_tags.h"
#include "portal.h"
#include "p_terrain.h"
//===========================================================================

View file

@ -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<ASkyViewpoint*>(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<FLinePortal*> 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());

View file

@ -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 &sector_t::FloorDisplacement()
{
return Displacements(PortalGroup, SkyBoxes[sector_t::floor]->Sector->PortalGroup);
}
inline FDisplacement &sector_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

View file

@ -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;

View file

@ -25,7 +25,7 @@
#include "tarray.h"
#include <stddef.h>
#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

View file

@ -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<ASkyViewpoint> SkyBoxes[2];
TObjPtr<AActor> 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

View file

@ -58,7 +58,6 @@
#include "v_font.h"
#include "r_data/colormaps.h"
#include "farchive.h"
#include "portal.h"
// MACROS ------------------------------------------------------------------

View file

@ -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)

View file

@ -52,7 +52,6 @@
#include "r_3dfloors.h"
#include "v_palette.h"
#include "r_data/colormaps.h"
#include "portal.h"
#define WALLYREPEAT 8

View file

@ -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 ----------------------------------------------