mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- link actors to touching line portals, for use by the renderer.
This commit is contained in:
parent
afa3009f93
commit
382a6e8b9f
5 changed files with 134 additions and 3 deletions
|
@ -965,6 +965,7 @@ public:
|
||||||
void CheckSectorTransition(sector_t *oldsec);
|
void CheckSectorTransition(sector_t *oldsec);
|
||||||
void UpdateRenderSectorList();
|
void UpdateRenderSectorList();
|
||||||
void ClearRenderSectorList();
|
void ClearRenderSectorList();
|
||||||
|
void ClearRenderLineList();
|
||||||
|
|
||||||
// info for drawing
|
// info for drawing
|
||||||
// NOTE: The first member variable *must* be snext.
|
// NOTE: The first member variable *must* be snext.
|
||||||
|
@ -1101,7 +1102,8 @@ public:
|
||||||
|
|
||||||
// a linked list of sectors where this object appears
|
// a linked list of sectors where this object appears
|
||||||
struct msecnode_t *touching_sectorlist; // phares 3/14/98
|
struct msecnode_t *touching_sectorlist; // phares 3/14/98
|
||||||
struct msecnode_t *render_sectorlist; // same for cross-portal rendering
|
struct msecnode_t *render_sectorlist; // same for cross-sectorportal rendering
|
||||||
|
struct portnode_t *render_portallist; // and for cross-lineportal
|
||||||
|
|
||||||
|
|
||||||
TObjPtr<AInventory> Inventory; // [RH] This actor's inventory
|
TObjPtr<AInventory> Inventory; // [RH] This actor's inventory
|
||||||
|
|
115
src/p_map.cpp
115
src/p_map.cpp
|
@ -44,6 +44,7 @@
|
||||||
#include "p_trace.h"
|
#include "p_trace.h"
|
||||||
#include "p_checkposition.h"
|
#include "p_checkposition.h"
|
||||||
#include "r_utility.h"
|
#include "r_utility.h"
|
||||||
|
#include "p_blockmap.h"
|
||||||
|
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
#include "decallib.h"
|
#include "decallib.h"
|
||||||
|
@ -6238,6 +6239,91 @@ void P_CreateSecNodeList(AActor *thing)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
// P_DelPortalnode
|
||||||
|
//
|
||||||
|
// Same for line portal nodes
|
||||||
|
//
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
portnode_t *P_DelPortalnode(portnode_t *node)
|
||||||
|
{
|
||||||
|
portnode_t* tp; // prev node on thing thread
|
||||||
|
portnode_t* tn; // next node on thing thread
|
||||||
|
portnode_t* sp; // prev node on sector thread
|
||||||
|
portnode_t* sn; // next node on sector thread
|
||||||
|
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
// Unlink from the Thing thread. The Thing thread begins at
|
||||||
|
// sector_list and not from AActor->touching_sectorlist.
|
||||||
|
|
||||||
|
tp = node->m_tprev;
|
||||||
|
tn = node->m_tnext;
|
||||||
|
if (tp)
|
||||||
|
tp->m_tnext = tn;
|
||||||
|
if (tn)
|
||||||
|
tn->m_tprev = tp;
|
||||||
|
|
||||||
|
// Unlink from the sector thread. This thread begins at
|
||||||
|
// sector_t->touching_thinglist.
|
||||||
|
|
||||||
|
sp = node->m_sprev;
|
||||||
|
sn = node->m_snext;
|
||||||
|
if (sp)
|
||||||
|
sp->m_snext = sn;
|
||||||
|
else
|
||||||
|
node->m_portal->render_thinglist = sn;
|
||||||
|
if (sn)
|
||||||
|
sn->m_sprev = sp;
|
||||||
|
|
||||||
|
// Return this node to the freelist (use the same one as for msecnodes, since both types are the same size.)
|
||||||
|
P_PutSecnode(reinterpret_cast<msecnode_t *>(node));
|
||||||
|
return tn;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
// P_AddPortalnode
|
||||||
|
//
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
portnode_t *P_AddPortalnode(FLinePortal *s, AActor *thing, portnode_t *nextnode)
|
||||||
|
{
|
||||||
|
portnode_t *node;
|
||||||
|
|
||||||
|
if (s == 0)
|
||||||
|
{
|
||||||
|
I_FatalError("AddSecnode of 0 for %s\n", thing->GetClass()->TypeName.GetChars());
|
||||||
|
}
|
||||||
|
|
||||||
|
node = reinterpret_cast<portnode_t*>(P_GetSecnode());
|
||||||
|
|
||||||
|
// killough 4/4/98, 4/7/98: mark new nodes unvisited.
|
||||||
|
node->visited = 0;
|
||||||
|
|
||||||
|
node->m_portal = s; // portal
|
||||||
|
node->m_thing = thing; // mobj
|
||||||
|
node->m_tprev = NULL; // prev node on Thing thread
|
||||||
|
node->m_tnext = nextnode; // next node on Thing thread
|
||||||
|
if (nextnode)
|
||||||
|
nextnode->m_tprev = node; // set back link on Thing
|
||||||
|
|
||||||
|
// Add new node at head of portal thread starting at s->touching_thinglist
|
||||||
|
|
||||||
|
node->m_sprev = NULL; // prev node on portal thread
|
||||||
|
node->m_snext = s->render_thinglist; // next node on portal thread
|
||||||
|
if (s->render_thinglist)
|
||||||
|
node->m_snext->m_sprev = node;
|
||||||
|
s->render_thinglist = node;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Handle the lists used to render actors from other portal areas
|
// Handle the lists used to render actors from other portal areas
|
||||||
|
@ -6249,6 +6335,27 @@ void AActor::UpdateRenderSectorList()
|
||||||
static const double SPRITE_SPACE = 64.;
|
static const double SPRITE_SPACE = 64.;
|
||||||
if (Pos() != OldRenderPos && !(flags & MF_NOSECTOR))
|
if (Pos() != OldRenderPos && !(flags & MF_NOSECTOR))
|
||||||
{
|
{
|
||||||
|
// Only check if the map contains line portals
|
||||||
|
ClearRenderLineList();
|
||||||
|
if (PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY())
|
||||||
|
{
|
||||||
|
int bx = GetBlockX(X());
|
||||||
|
int by = GetBlockX(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 (bx >= 0 && by >= 0 && bx < bmapwidth && by < bmapheight && 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)
|
||||||
|
{
|
||||||
|
if (p.mType == PORTT_VISUAL) continue;
|
||||||
|
if (bb.inRange(p.mOrigin) && bb.BoxOnLineSide(p.mOrigin))
|
||||||
|
{
|
||||||
|
render_portallist = P_AddPortalnode(&p, this, render_portallist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
sector_t *sec = Sector;
|
sector_t *sec = Sector;
|
||||||
double lasth = -FLT_MAX;
|
double lasth = -FLT_MAX;
|
||||||
ClearRenderSectorList();
|
ClearRenderSectorList();
|
||||||
|
@ -6284,6 +6391,14 @@ void AActor::ClearRenderSectorList()
|
||||||
render_sectorlist = NULL;
|
render_sectorlist = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AActor::ClearRenderLineList()
|
||||||
|
{
|
||||||
|
portnode_t *node = render_portallist;
|
||||||
|
while (node)
|
||||||
|
node = P_DelPortalnode(node);
|
||||||
|
render_portallist = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
|
|
@ -119,8 +119,8 @@ static void BuildBlockmap()
|
||||||
while (*list != -1)
|
while (*list != -1)
|
||||||
{
|
{
|
||||||
line_t *ld = &lines[*list++];
|
line_t *ld = &lines[*list++];
|
||||||
|
FLinePortal *port = ld->getPortal();
|
||||||
if (ld->isLinePortal())
|
if (port && port->mType != PORTT_VISUAL)
|
||||||
{
|
{
|
||||||
PortalBlockmap.containsLines = true;
|
PortalBlockmap.containsLines = true;
|
||||||
block.portallines.Push(ld);
|
block.portallines.Push(ld);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
struct FPortalGroupArray;
|
struct FPortalGroupArray;
|
||||||
class ASkyViewpoint;
|
class ASkyViewpoint;
|
||||||
|
struct portnode_t;
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// This table holds the offsets for the different parts of a map
|
// This table holds the offsets for the different parts of a map
|
||||||
|
@ -189,6 +190,7 @@ struct FLinePortal
|
||||||
DAngle mAngleDiff;
|
DAngle mAngleDiff;
|
||||||
double mSinRot;
|
double mSinRot;
|
||||||
double mCosRot;
|
double mCosRot;
|
||||||
|
portnode_t *render_thinglist;
|
||||||
void *mRenderData;
|
void *mRenderData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
12
src/r_defs.h
12
src/r_defs.h
|
@ -1387,6 +1387,18 @@ struct msecnode_t
|
||||||
bool visited; // killough 4/4/98, 4/7/98: used in search algorithms
|
bool visited; // killough 4/4/98, 4/7/98: used in search algorithms
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// use the same memory layout as msecnode_t so both can be used from the same freelist.
|
||||||
|
struct portnode_t
|
||||||
|
{
|
||||||
|
FLinePortal *m_portal; // a portal containing this object
|
||||||
|
AActor *m_thing; // this object
|
||||||
|
struct portnode_t *m_tprev; // prev msecnode_t for this thing
|
||||||
|
struct portnode_t *m_tnext; // next msecnode_t for this thing
|
||||||
|
struct portnode_t *m_sprev; // prev msecnode_t for this portal
|
||||||
|
struct portnode_t *m_snext; // next msecnode_t for this portal
|
||||||
|
bool visited;
|
||||||
|
};
|
||||||
|
|
||||||
struct FPolyNode;
|
struct FPolyNode;
|
||||||
struct FMiniBSP;
|
struct FMiniBSP;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue