mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-02-26 13:10:59 +00:00
- changed dynamic light traversal to use sections instead of the subsectors.
This is mostly complete, except for handling intra-section sidedefs.
This commit is contained in:
parent
9ddca3c3a9
commit
ba66c0c889
20 changed files with 119 additions and 125 deletions
|
@ -80,7 +80,7 @@ DEFINE_CLASS_PROPERTY(type, S, DynamicLight)
|
||||||
{
|
{
|
||||||
PROP_STRING_PARM(str, 0);
|
PROP_STRING_PARM(str, 0);
|
||||||
static const char * ltype_names[]={
|
static const char * ltype_names[]={
|
||||||
"Point","Pulse","Flicker","Sector","RandomFlicker", "ColorPulse", "ColorFlicker", "RandomColorFlicker", NULL};
|
"Point","Pulse","Flicker","Sector","RandomFlicker", "ColorPulse", "ColorFlicker", "RandomColorFlicker", nullptr};
|
||||||
|
|
||||||
static const int ltype_values[]={
|
static const int ltype_values[]={
|
||||||
PointLight, PulseLight, FlickerLight, SectorLight, RandomFlickerLight, ColorPulseLight, ColorFlickerLight, RandomColorFlickerLight };
|
PointLight, PulseLight, FlickerLight, SectorLight, RandomFlickerLight, ColorPulseLight, ColorFlickerLight, RandomColorFlickerLight };
|
||||||
|
@ -182,7 +182,7 @@ void ADynamicLight::PostBeginPlay()
|
||||||
|
|
||||||
if (!(SpawnFlags & MTF_DORMANT))
|
if (!(SpawnFlags & MTF_DORMANT))
|
||||||
{
|
{
|
||||||
Activate (NULL);
|
Activate (nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
subsector = R_PointInSubsector(Pos());
|
subsector = R_PointInSubsector(Pos());
|
||||||
|
@ -430,14 +430,14 @@ void ADynamicLight::SetOffset(const DVector3 &pos)
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// The target pointer in dynamic lights should never be substituted unless
|
// The target pointer in dynamic lights should never be substituted unless
|
||||||
// notOld is NULL (which indicates that the object was destroyed by force.)
|
// notOld is nullptr (which indicates that the object was destroyed by force.)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
size_t ADynamicLight::PointerSubstitution (DObject *old, DObject *notOld)
|
size_t ADynamicLight::PointerSubstitution (DObject *old, DObject *notOld)
|
||||||
{
|
{
|
||||||
AActor *saved_target = target;
|
AActor *saved_target = target;
|
||||||
size_t ret = Super::PointerSubstitution(old, notOld);
|
size_t ret = Super::PointerSubstitution(old, notOld);
|
||||||
if (notOld != NULL) target = saved_target;
|
if (notOld != nullptr) target = saved_target;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +494,7 @@ FLightNode * AddLightNode(FLightNode ** thread, void * linkto, ADynamicLight * l
|
||||||
//
|
//
|
||||||
// P_DelSecnode() deletes a sector node from the list of
|
// P_DelSecnode() deletes a sector node from the list of
|
||||||
// sectors this object appears in. Returns a pointer to the next node
|
// sectors this object appears in. Returns a pointer to the next node
|
||||||
// on the linked list, or NULL.
|
// on the linked list, or nullptr.
|
||||||
//
|
//
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
|
@ -516,7 +516,7 @@ static FLightNode * DeleteLightNode(FLightNode * node)
|
||||||
delete node;
|
delete node;
|
||||||
return(tn);
|
return(tn);
|
||||||
}
|
}
|
||||||
return(NULL);
|
return(nullptr);
|
||||||
} // phares 3/13/98
|
} // phares 3/13/98
|
||||||
|
|
||||||
|
|
||||||
|
@ -527,20 +527,20 @@ static FLightNode * DeleteLightNode(FLightNode * node)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
double ADynamicLight::DistToSeg(const DVector3 &pos, seg_t *seg)
|
double ADynamicLight::DistToSeg(const DVector3 &pos, FSectionLine *segment)
|
||||||
{
|
{
|
||||||
double u, px, py;
|
double u, px, py;
|
||||||
|
|
||||||
double seg_dx = seg->v2->fX() - seg->v1->fX();
|
double seg_dx = segment->end->fX() - segment->start->fX();
|
||||||
double seg_dy = seg->v2->fY() - seg->v1->fY();
|
double seg_dy = segment->end->fY() - segment->start->fY();
|
||||||
double seg_length_sq = seg_dx * seg_dx + seg_dy * seg_dy;
|
double seg_length_sq = seg_dx * seg_dx + seg_dy * seg_dy;
|
||||||
|
|
||||||
u = (((pos.X - seg->v1->fX()) * seg_dx) + (pos.Y - seg->v1->fY()) * seg_dy) / seg_length_sq;
|
u = (((pos.X - segment->start->fX()) * seg_dx) + (pos.Y - segment->start->fY()) * seg_dy) / seg_length_sq;
|
||||||
if (u < 0.) u = 0.; // clamp the test point to the line segment
|
if (u < 0.) u = 0.; // clamp the test point to the line segment
|
||||||
else if (u > 1.) u = 1.;
|
else if (u > 1.) u = 1.;
|
||||||
|
|
||||||
px = seg->v1->fX() + (u * seg_dx);
|
px = segment->start->fX() + (u * seg_dx);
|
||||||
py = seg->v1->fY() + (u * seg_dy);
|
py = segment->start->fY() + (u * seg_dy);
|
||||||
|
|
||||||
px -= pos.X;
|
px -= pos.X;
|
||||||
py -= pos.Y;
|
py -= pos.Y;
|
||||||
|
@ -557,108 +557,110 @@ double ADynamicLight::DistToSeg(const DVector3 &pos, seg_t *seg)
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
struct LightLinkEntry
|
struct LightLinkEntry
|
||||||
{
|
{
|
||||||
subsector_t *sub;
|
FSection *sect;
|
||||||
DVector3 pos;
|
DVector3 pos;
|
||||||
};
|
};
|
||||||
static TArray<LightLinkEntry> collected_ss;
|
static TArray<LightLinkEntry> collected_ss;
|
||||||
|
|
||||||
void ADynamicLight::CollectWithinRadius(const DVector3 &opos, subsector_t *subSec, float radius)
|
void ADynamicLight::CollectWithinRadius(const DVector3 &opos, FSection *section, float radius)
|
||||||
{
|
{
|
||||||
if (!subSec) return;
|
if (!section) return;
|
||||||
collected_ss.Clear();
|
collected_ss.Clear();
|
||||||
collected_ss.Push({ subSec, opos });
|
collected_ss.Push({ section, opos });
|
||||||
subSec->validcount = ::validcount;
|
section->validcount = dl_validcount;
|
||||||
|
|
||||||
bool hitonesidedback = false;
|
bool hitonesidedback = false;
|
||||||
for (unsigned i = 0; i < collected_ss.Size(); i++)
|
for (unsigned i = 0; i < collected_ss.Size(); i++)
|
||||||
{
|
{
|
||||||
subSec = collected_ss[i].sub;
|
section = collected_ss[i].sect;
|
||||||
|
|
||||||
//touching_subsectors = AddLightNode(&subSec->lighthead, subSec, this, touching_subsectors);
|
touching_sector = AddLightNode(§ion->lighthead, section, this, touching_sector);
|
||||||
if (subSec->sector->validcount != ::validcount)
|
|
||||||
{
|
|
||||||
touching_sector = AddLightNode(&subSec->render_sector->lighthead, subSec->sector, this, touching_sector);
|
|
||||||
subSec->sector->validcount = ::validcount;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int j = 0; j < subSec->numlines; ++j)
|
for (auto &segment : section->segments)
|
||||||
{
|
{
|
||||||
auto &pos = collected_ss[i].pos;
|
auto &pos = collected_ss[i].pos;
|
||||||
seg_t *seg = subSec->firstline + j;
|
|
||||||
|
|
||||||
// check distance from x/y to seg and if within radius add this seg and, if present the opposing subsector (lather/rinse/repeat)
|
// check distance from x/y to seg and if within radius add this seg and, if present the opposing subsector (lather/rinse/repeat)
|
||||||
// If out of range we do not need to bother with this seg.
|
// If out of range we do not need to bother with this seg.
|
||||||
if (DistToSeg(pos, seg) <= radius)
|
if (DistToSeg(pos, &segment) <= radius)
|
||||||
{
|
{
|
||||||
if (seg->sidedef && seg->linedef && seg->linedef->validcount != ::validcount)
|
if (segment.sidedef)
|
||||||
{
|
{
|
||||||
// light is in front of the seg
|
auto sidedef = segment.sidedef;
|
||||||
if ((pos.Y - seg->v1->fY()) * (seg->v2->fX() - seg->v1->fX()) + (seg->v1->fX() - pos.X) * (seg->v2->fY() - seg->v1->fY()) <= 0)
|
auto linedef = sidedef->linedef;
|
||||||
|
if (linedef && linedef->validcount != ::validcount)
|
||||||
{
|
{
|
||||||
seg->linedef->validcount = validcount;
|
// light is in front of the seg
|
||||||
touching_sides = AddLightNode(&seg->sidedef->lighthead, seg->sidedef, this, touching_sides);
|
if ((pos.Y - segment.start->fY()) * (segment.end->fX() - segment.start->fX()) + (segment.start->fX() - pos.X) * (segment.end->fY() - segment.start->fY()) <= 0)
|
||||||
}
|
|
||||||
else if (seg->linedef->sidedef[0] == seg->sidedef && seg->linedef->sidedef[1] == nullptr)
|
|
||||||
{
|
|
||||||
hitonesidedback = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (seg->linedef)
|
|
||||||
{
|
|
||||||
FLinePortal *port = seg->linedef->getPortal();
|
|
||||||
if (port && port->mType == PORTT_LINKED)
|
|
||||||
{
|
|
||||||
line_t *other = port->mDestination;
|
|
||||||
if (other->validcount != ::validcount)
|
|
||||||
{
|
{
|
||||||
subsector_t *othersub = R_PointInSubsector(other->v1->fPos() + other->Delta() / 2);
|
linedef->validcount = ::validcount;
|
||||||
if (othersub->validcount != ::validcount)
|
touching_sides = AddLightNode(&sidedef->lighthead, sidedef, this, touching_sides);
|
||||||
|
}
|
||||||
|
else if (linedef->sidedef[0] == sidedef && linedef->sidedef[1] == nullptr)
|
||||||
|
{
|
||||||
|
hitonesidedback = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (linedef)
|
||||||
|
{
|
||||||
|
FLinePortal *port = linedef->getPortal();
|
||||||
|
if (port && port->mType == PORTT_LINKED)
|
||||||
|
{
|
||||||
|
line_t *other = port->mDestination;
|
||||||
|
if (other->validcount != ::validcount)
|
||||||
{
|
{
|
||||||
othersub->validcount = ::validcount;
|
subsector_t *othersub = R_PointInSubsector(other->v1->fPos() + other->Delta() / 2);
|
||||||
collected_ss.Push({ othersub, PosRelative(other) });
|
FSection *othersect = othersub->section;
|
||||||
|
if (othersect->validcount != ::validcount)
|
||||||
|
{
|
||||||
|
othersect->validcount = ::validcount;
|
||||||
|
collected_ss.Push({ othersect, PosRelative(other) });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
seg_t *partner = seg->PartnerSeg;
|
auto partner = segment.partner;
|
||||||
if (partner)
|
if (partner)
|
||||||
{
|
{
|
||||||
subsector_t *sub = partner->Subsector;
|
FSection *sect = partner->section;
|
||||||
if (sub != NULL && sub->validcount != ::validcount)
|
if (sect != nullptr && sect->validcount != dl_validcount)
|
||||||
{
|
{
|
||||||
sub->validcount = ::validcount;
|
sect->validcount = dl_validcount;
|
||||||
collected_ss.Push({ sub, pos });
|
collected_ss.Push({ sect, pos });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sector_t *sec = subSec->sector;
|
sector_t *sec = section->sector;
|
||||||
if (!sec->PortalBlocksSight(sector_t::ceiling))
|
if (!sec->PortalBlocksSight(sector_t::ceiling))
|
||||||
{
|
{
|
||||||
line_t *other = subSec->firstline->linedef;
|
line_t *other = section->segments[0].sidedef->linedef;
|
||||||
if (sec->GetPortalPlaneZ(sector_t::ceiling) < Z() + radius)
|
if (sec->GetPortalPlaneZ(sector_t::ceiling) < Z() + radius)
|
||||||
{
|
{
|
||||||
DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::ceiling);
|
DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::ceiling);
|
||||||
subsector_t *othersub = R_PointInSubsector(refpos);
|
subsector_t *othersub = R_PointInSubsector(refpos);
|
||||||
if (othersub->validcount != ::validcount)
|
FSection *othersect = othersub->section;
|
||||||
|
if (othersect->validcount != dl_validcount)
|
||||||
{
|
{
|
||||||
othersub->validcount = ::validcount;
|
othersect->validcount = dl_validcount;
|
||||||
collected_ss.Push({ othersub, PosRelative(othersub->sector) });
|
collected_ss.Push({ othersect, PosRelative(othersub->sector) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!sec->PortalBlocksSight(sector_t::floor))
|
if (!sec->PortalBlocksSight(sector_t::floor))
|
||||||
{
|
{
|
||||||
line_t *other = subSec->firstline->linedef;
|
line_t *other = section->segments[0].sidedef->linedef;
|
||||||
if (sec->GetPortalPlaneZ(sector_t::floor) > Z() - radius)
|
if (sec->GetPortalPlaneZ(sector_t::floor) > Z() - radius)
|
||||||
{
|
{
|
||||||
DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::floor);
|
DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::floor);
|
||||||
subsector_t *othersub = R_PointInSubsector(refpos);
|
subsector_t *othersub = R_PointInSubsector(refpos);
|
||||||
if (othersub->validcount != ::validcount)
|
FSection *othersect = othersub->section;
|
||||||
|
if (othersect->validcount != dl_validcount)
|
||||||
{
|
{
|
||||||
othersub->validcount = ::validcount;
|
othersect->validcount = dl_validcount;
|
||||||
collected_ss.Push({ othersub, PosRelative(othersub->sector) });
|
collected_ss.Push({ othersect, PosRelative(othersub->sector) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -680,32 +682,33 @@ void ADynamicLight::LinkLight()
|
||||||
node = touching_sides;
|
node = touching_sides;
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
node->lightsource = NULL;
|
node->lightsource = nullptr;
|
||||||
node = node->nextTarget;
|
node = node->nextTarget;
|
||||||
}
|
}
|
||||||
node = touching_sector;
|
node = touching_sector;
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
node->lightsource = NULL;
|
node->lightsource = nullptr;
|
||||||
node = node->nextTarget;
|
node = node->nextTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (radius>0)
|
if (radius>0)
|
||||||
{
|
{
|
||||||
// passing in radius*radius allows us to do a distance check without any calls to sqrt
|
// passing in radius*radius allows us to do a distance check without any calls to sqrt
|
||||||
subsector_t * subSec = R_PointInSubsector(Pos());
|
FSection *sect = R_PointInSubsector(Pos())->section;
|
||||||
::validcount++;
|
|
||||||
CollectWithinRadius(Pos(), subSec, float(radius*radius));
|
dl_validcount++;
|
||||||
|
CollectWithinRadius(Pos(), sect, float(radius*radius));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now delete any nodes that won't be used. These are the ones where
|
// Now delete any nodes that won't be used. These are the ones where
|
||||||
// m_thing is still NULL.
|
// m_thing is still nullptr.
|
||||||
|
|
||||||
node = touching_sides;
|
node = touching_sides;
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
if (node->lightsource == NULL)
|
if (node->lightsource == nullptr)
|
||||||
{
|
{
|
||||||
node = DeleteLightNode(node);
|
node = DeleteLightNode(node);
|
||||||
}
|
}
|
||||||
|
@ -716,7 +719,7 @@ void ADynamicLight::LinkLight()
|
||||||
node = touching_sector;
|
node = touching_sector;
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
if (node->lightsource == NULL)
|
if (node->lightsource == nullptr)
|
||||||
{
|
{
|
||||||
node = DeleteLightNode(node);
|
node = DeleteLightNode(node);
|
||||||
}
|
}
|
||||||
|
@ -733,7 +736,7 @@ void ADynamicLight::LinkLight()
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
void ADynamicLight::UnlinkLight ()
|
void ADynamicLight::UnlinkLight ()
|
||||||
{
|
{
|
||||||
if (owned && target != NULL)
|
if (owned && target != nullptr)
|
||||||
{
|
{
|
||||||
// Delete reference in owning actor
|
// Delete reference in owning actor
|
||||||
for(int c=target->AttachedLights.Size()-1; c>=0; c--)
|
for(int c=target->AttachedLights.Size()-1; c>=0; c--)
|
||||||
|
@ -770,7 +773,7 @@ void AActor::AttachLight(unsigned int count, const FLightDefaults *lightdef)
|
||||||
if (count < AttachedLights.Size())
|
if (count < AttachedLights.Size())
|
||||||
{
|
{
|
||||||
light = barrier_cast<ADynamicLight*>(AttachedLights[count]);
|
light = barrier_cast<ADynamicLight*>(AttachedLights[count]);
|
||||||
assert(light != NULL);
|
assert(light != nullptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -797,13 +800,13 @@ void AActor::SetDynamicLights()
|
||||||
TArray<FInternalLightAssociation *> & LightAssociations = GetInfo()->LightAssociations;
|
TArray<FInternalLightAssociation *> & LightAssociations = GetInfo()->LightAssociations;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
|
||||||
if (state == NULL) return;
|
if (state == nullptr) return;
|
||||||
if (LightAssociations.Size() > 0)
|
if (LightAssociations.Size() > 0)
|
||||||
{
|
{
|
||||||
ADynamicLight *lights, *tmpLight;
|
ADynamicLight *lights, *tmpLight;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
lights = tmpLight = NULL;
|
lights = tmpLight = nullptr;
|
||||||
|
|
||||||
for (i = 0; i < LightAssociations.Size(); i++)
|
for (i = 0; i < LightAssociations.Size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -816,7 +819,7 @@ void AActor::SetDynamicLights()
|
||||||
}
|
}
|
||||||
if (count == 0 && state->Light > 0)
|
if (count == 0 && state->Light > 0)
|
||||||
{
|
{
|
||||||
for(int i= state->Light; StateLights[i] != NULL; i++)
|
for(int i= state->Light; StateLights[i] != nullptr; i++)
|
||||||
{
|
{
|
||||||
if (StateLights[i] != (FLightDefaults*)-1)
|
if (StateLights[i] != (FLightDefaults*)-1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,7 @@ struct seg_t;
|
||||||
|
|
||||||
class ADynamicLight;
|
class ADynamicLight;
|
||||||
class FSerializer;
|
class FSerializer;
|
||||||
|
struct FSectionLine;
|
||||||
|
|
||||||
enum ELightType
|
enum ELightType
|
||||||
{
|
{
|
||||||
|
@ -209,8 +210,8 @@ public:
|
||||||
FLightNode * touching_sector;
|
FLightNode * touching_sector;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double DistToSeg(const DVector3 &pos, seg_t *seg);
|
double DistToSeg(const DVector3 &pos, FSectionLine *seg);
|
||||||
void CollectWithinRadius(const DVector3 &pos, subsector_t *subSec, float radius);
|
void CollectWithinRadius(const DVector3 &pos, FSection *section, float radius);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DVector3 m_off;
|
DVector3 m_off;
|
||||||
|
|
|
@ -633,11 +633,9 @@ public:
|
||||||
{
|
{
|
||||||
output.allSections.Resize(groups.Size());
|
output.allSections.Resize(groups.Size());
|
||||||
output.allIndices.Resize(level.subsectors.Size() + level.sides.Size() + 2*level.sectors.Size());
|
output.allIndices.Resize(level.subsectors.Size() + level.sides.Size() + 2*level.sectors.Size());
|
||||||
output.sectionForSubsectorPtr = &output.allIndices[0];
|
output.sectionForSidedefPtr = &output.allIndices[0];
|
||||||
output.sectionForSidedefPtr = &output.allIndices[level.subsectors.Size()];
|
output.firstSectionForSectorPtr = &output.allIndices[level.sides.Size()];
|
||||||
output.firstSectionForSectorPtr = &output.allIndices[level.subsectors.Size() + level.sides.Size()];
|
output.numberOfSectionForSectorPtr = &output.allIndices[level.sides.Size() + level.sectors.Size()];
|
||||||
output.numberOfSectionForSectorPtr = &output.allIndices[level.subsectors.Size() + level.sides.Size() + level.sectors.Size()];
|
|
||||||
memset(output.sectionForSubsectorPtr, -1, sizeof(int) * level.subsectors.Size());
|
|
||||||
memset(output.firstSectionForSectorPtr, -1, sizeof(int) * level.sectors.Size());
|
memset(output.firstSectionForSectorPtr, -1, sizeof(int) * level.sectors.Size());
|
||||||
memset(output.numberOfSectionForSectorPtr, 0, sizeof(int) * level.sectors.Size());
|
memset(output.numberOfSectionForSectorPtr, 0, sizeof(int) * level.sectors.Size());
|
||||||
|
|
||||||
|
@ -704,6 +702,7 @@ public:
|
||||||
fseg.end = segment->end;
|
fseg.end = segment->end;
|
||||||
fseg.partner = segment->partner == nullptr ? nullptr : &output.allLines[segment->partner->tempindex];
|
fseg.partner = segment->partner == nullptr ? nullptr : &output.allLines[segment->partner->tempindex];
|
||||||
fseg.sidedef = segment->sidedef;
|
fseg.sidedef = segment->sidedef;
|
||||||
|
fseg.section = &dest;
|
||||||
dest.bounds.addVertex(fseg.start->fX(), fseg.start->fY());
|
dest.bounds.addVertex(fseg.start->fX(), fseg.start->fY());
|
||||||
dest.bounds.addVertex(fseg.end->fX(), fseg.end->fY());
|
dest.bounds.addVertex(fseg.end->fX(), fseg.end->fY());
|
||||||
}
|
}
|
||||||
|
@ -717,7 +716,7 @@ public:
|
||||||
for (auto ssi : group.subsectors)
|
for (auto ssi : group.subsectors)
|
||||||
{
|
{
|
||||||
output.allSubsectors[numsubsectors++] = &level.subsectors[ssi];
|
output.allSubsectors[numsubsectors++] = &level.subsectors[ssi];
|
||||||
output.sectionForSubsectorPtr[ssi] = curgroup;
|
level.subsectors[ssi].section = &output.allSections[curgroup];
|
||||||
}
|
}
|
||||||
curgroup++;
|
curgroup++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,7 @@ struct FSectionLine
|
||||||
vertex_t *start;
|
vertex_t *start;
|
||||||
vertex_t *end;
|
vertex_t *end;
|
||||||
FSectionLine *partner;
|
FSectionLine *partner;
|
||||||
|
FSection *section;
|
||||||
side_t *sidedef;
|
side_t *sidedef;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -101,27 +102,10 @@ public:
|
||||||
TArray<subsector_t *> allSubsectors;
|
TArray<subsector_t *> allSubsectors;
|
||||||
TArray<int> allIndices;
|
TArray<int> allIndices;
|
||||||
|
|
||||||
int *sectionForSubsectorPtr; // stored inside allIndices
|
|
||||||
int *sectionForSidedefPtr; // also stored inside allIndices;
|
int *sectionForSidedefPtr; // also stored inside allIndices;
|
||||||
int *firstSectionForSectorPtr; // ditto.
|
int *firstSectionForSectorPtr; // ditto.
|
||||||
int *numberOfSectionForSectorPtr; // ditto.
|
int *numberOfSectionForSectorPtr; // ditto.
|
||||||
|
|
||||||
FSection *SectionForSubsector(subsector_t *sub)
|
|
||||||
{
|
|
||||||
return SectionForSubsector(sub->Index());
|
|
||||||
}
|
|
||||||
FSection *SectionForSubsector(int ssindex)
|
|
||||||
{
|
|
||||||
return ssindex < 0 ? nullptr : &allSections[sectionForSubsectorPtr[ssindex]];
|
|
||||||
}
|
|
||||||
int SectionNumForSubsector(subsector_t *sub)
|
|
||||||
{
|
|
||||||
return SectionNumForSubsector(sub->Index());
|
|
||||||
}
|
|
||||||
int SectionNumForSubsector(int ssindex)
|
|
||||||
{
|
|
||||||
return ssindex < 0 ? -1 : sectionForSubsectorPtr[ssindex];
|
|
||||||
}
|
|
||||||
FSection *SectionForSidedef(side_t *side)
|
FSection *SectionForSidedef(side_t *side)
|
||||||
{
|
{
|
||||||
return SectionForSidedef(side->Index());
|
return SectionForSidedef(side->Index());
|
||||||
|
|
|
@ -155,7 +155,7 @@ void HWDrawInfo::WorkerThread()
|
||||||
{
|
{
|
||||||
GLFlat flat;
|
GLFlat flat;
|
||||||
SetupFlat.Clock();
|
SetupFlat.Clock();
|
||||||
flat.section = level.sections.SectionForSubsector(job->sub);
|
flat.section = job->sub->section;
|
||||||
front = hw_FakeFlat(job->sub->render_sector, &fakefront, in_area, false);
|
front = hw_FakeFlat(job->sub->render_sector, &fakefront, in_area, false);
|
||||||
flat.ProcessSector(this, front);
|
flat.ProcessSector(this, front);
|
||||||
SetupFlat.Unclock();
|
SetupFlat.Unclock();
|
||||||
|
@ -680,8 +680,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
|
||||||
fakesector = hw_FakeFlat(sector, &fake, in_area, false);
|
fakesector = hw_FakeFlat(sector, &fake, in_area, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto secnum = level.sections.SectionNumForSubsector(sub);
|
uint8_t &srf = section_renderflags[level.sections.SectionIndex(sub->section)];
|
||||||
uint8_t &srf = section_renderflags[secnum];
|
|
||||||
if (!(srf & SSRF_PROCESSED))
|
if (!(srf & SSRF_PROCESSED))
|
||||||
{
|
{
|
||||||
srf |= SSRF_PROCESSED;
|
srf |= SSRF_PROCESSED;
|
||||||
|
@ -693,7 +692,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GLFlat flat;
|
GLFlat flat;
|
||||||
flat.section = level.sections.SectionForSubsector(sub);
|
flat.section = sub->section;
|
||||||
SetupFlat.Clock();
|
SetupFlat.Clock();
|
||||||
flat.ProcessSector(this, fakesector);
|
flat.ProcessSector(this, fakesector);
|
||||||
SetupFlat.Unclock();
|
SetupFlat.Unclock();
|
||||||
|
|
|
@ -184,7 +184,7 @@ void GLFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state)
|
||||||
{
|
{
|
||||||
if (level.HasDynamicLights && screen->BuffersArePersistent())
|
if (level.HasDynamicLights && screen->BuffersArePersistent())
|
||||||
{
|
{
|
||||||
SetupLights(di, sector->lighthead, lightdata, sector->PortalGroup);
|
SetupLights(di, section->lighthead, lightdata, sector->PortalGroup);
|
||||||
}
|
}
|
||||||
state.SetLightIndex(dynlightindex);
|
state.SetLightIndex(dynlightindex);
|
||||||
|
|
||||||
|
@ -346,7 +346,7 @@ inline void GLFlat::PutFlat(HWDrawInfo *di, bool fog)
|
||||||
{
|
{
|
||||||
if (level.HasDynamicLights && gltexture != nullptr)
|
if (level.HasDynamicLights && gltexture != nullptr)
|
||||||
{
|
{
|
||||||
SetupLights(di, sector->lighthead, lightdata, sector->PortalGroup);
|
SetupLights(di, section->lighthead, lightdata, sector->PortalGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
di->AddFlat(this, fog);
|
di->AddFlat(this, fog);
|
||||||
|
|
|
@ -54,7 +54,8 @@ int HWDrawInfo::SetupLightsForOtherPlane(subsector_t * sub, FDynLightData &light
|
||||||
if (level.HasDynamicLights && !isFullbrightScene())
|
if (level.HasDynamicLights && !isFullbrightScene())
|
||||||
{
|
{
|
||||||
Plane p;
|
Plane p;
|
||||||
FLightNode * node = sub->sector->lighthead;
|
|
||||||
|
FLightNode * node = sub->section->lighthead;
|
||||||
|
|
||||||
lightdata.Clear();
|
lightdata.Clear();
|
||||||
while (node)
|
while (node)
|
||||||
|
|
|
@ -131,11 +131,11 @@ void HWDrawInfo::GetDynSpriteLight(AActor *thing, particle_t *particle, float *o
|
||||||
{
|
{
|
||||||
if (thing != NULL)
|
if (thing != NULL)
|
||||||
{
|
{
|
||||||
GetDynSpriteLight(thing, (float)thing->X(), (float)thing->Y(), (float)thing->Center(), thing->Sector->lighthead, thing->Sector->PortalGroup, out);
|
GetDynSpriteLight(thing, (float)thing->X(), (float)thing->Y(), (float)thing->Center(), thing->section->lighthead, thing->Sector->PortalGroup, out);
|
||||||
}
|
}
|
||||||
else if (particle != NULL)
|
else if (particle != NULL)
|
||||||
{
|
{
|
||||||
GetDynSpriteLight(NULL, (float)particle->Pos.X, (float)particle->Pos.Y, (float)particle->Pos.Z, particle->subsector->sector->lighthead, particle->subsector->sector->PortalGroup, out);
|
GetDynSpriteLight(NULL, (float)particle->Pos.X, (float)particle->Pos.Y, (float)particle->Pos.Z, particle->subsector->section->lighthead, particle->subsector->sector->PortalGroup, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,10 +157,13 @@ void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata)
|
||||||
float y = (float)self->Y();
|
float y = (float)self->Y();
|
||||||
float z = (float)self->Center();
|
float z = (float)self->Center();
|
||||||
float radiusSquared = (float)(self->renderradius * self->renderradius);
|
float radiusSquared = (float)(self->renderradius * self->renderradius);
|
||||||
|
dl_validcount++;
|
||||||
|
|
||||||
BSPWalkCircle(x, y, radiusSquared, [&](subsector_t *subsector) // Iterate through all subsectors potentially touched by actor
|
BSPWalkCircle(x, y, radiusSquared, [&](subsector_t *subsector) // Iterate through all subsectors potentially touched by actor
|
||||||
{
|
{
|
||||||
FLightNode * node = subsector->sector->lighthead;
|
auto section = subsector->section;
|
||||||
|
if (section->validcount == dl_validcount) return; // already done from a previous subsector.
|
||||||
|
FLightNode * node = section->lighthead;
|
||||||
while (node) // check all lights touching a subsector
|
while (node) // check all lights touching a subsector
|
||||||
{
|
{
|
||||||
ADynamicLight *light = node->lightsource;
|
ADynamicLight *light = node->lightsource;
|
||||||
|
|
|
@ -302,7 +302,7 @@ void GLWall::SetupLights(HWDrawInfo *di, FDynLightData &lightdata)
|
||||||
else if (sub)
|
else if (sub)
|
||||||
{
|
{
|
||||||
// Polobject segs cannot be checked per sidedef so use the subsector instead.
|
// Polobject segs cannot be checked per sidedef so use the subsector instead.
|
||||||
node = sub->sector->lighthead;
|
node = sub->section->lighthead;
|
||||||
}
|
}
|
||||||
else node = NULL;
|
else node = NULL;
|
||||||
|
|
||||||
|
|
|
@ -470,7 +470,7 @@ void AActor::LinkToWorld(FLinkContext *ctx, bool spawningmapthing, sector_t *sec
|
||||||
|
|
||||||
Sector = sector;
|
Sector = sector;
|
||||||
subsector = R_PointInSubsector(Pos()); // this is from the rendering nodes, not the gameplay nodes!
|
subsector = R_PointInSubsector(Pos()); // this is from the rendering nodes, not the gameplay nodes!
|
||||||
section = level.sections.SectionForSubsector(subsector->Index());
|
section = subsector->section;
|
||||||
|
|
||||||
if (!(flags & MF_NOSECTOR))
|
if (!(flags & MF_NOSECTOR))
|
||||||
{
|
{
|
||||||
|
|
|
@ -70,7 +70,7 @@ void PolyModelRenderer::AddLights(AActor *actor)
|
||||||
|
|
||||||
BSPWalkCircle(x, y, radiusSquared, [&](subsector_t *subsector) // Iterate through all subsectors potentially touched by actor
|
BSPWalkCircle(x, y, radiusSquared, [&](subsector_t *subsector) // Iterate through all subsectors potentially touched by actor
|
||||||
{
|
{
|
||||||
FLightNode * node = subsector->sector->lighthead;
|
FLightNode * node = subsector->section->lighthead;
|
||||||
while (node) // check all lights touching a subsector
|
while (node) // check all lights touching a subsector
|
||||||
{
|
{
|
||||||
ADynamicLight *light = node->lightsource;
|
ADynamicLight *light = node->lightsource;
|
||||||
|
|
|
@ -275,7 +275,7 @@ void RenderPolyPlane::SetDynLights(PolyRenderThread *thread, PolyDrawArgs &args,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FLightNode *light_list = sub->sector->lighthead;
|
FLightNode *light_list = sub->section->lighthead;
|
||||||
|
|
||||||
auto cameraLight = PolyCameraLight::Instance();
|
auto cameraLight = PolyCameraLight::Instance();
|
||||||
if ((cameraLight->FixedLightLevel() >= 0) || (cameraLight->FixedColormap() != nullptr))
|
if ((cameraLight->FixedLightLevel() >= 0) || (cameraLight->FixedColormap() != nullptr))
|
||||||
|
|
|
@ -381,7 +381,7 @@ void RenderPolySprite::SetDynlight(AActor *thing, PolyDrawArgs &args)
|
||||||
float lit_red = 0;
|
float lit_red = 0;
|
||||||
float lit_green = 0;
|
float lit_green = 0;
|
||||||
float lit_blue = 0;
|
float lit_blue = 0;
|
||||||
auto node = thing->Sector->lighthead;
|
auto node = thing->section->lighthead;
|
||||||
while (node != nullptr)
|
while (node != nullptr)
|
||||||
{
|
{
|
||||||
ADynamicLight *light = node->lightsource;
|
ADynamicLight *light = node->lightsource;
|
||||||
|
|
|
@ -51,6 +51,7 @@ struct FLinePortal;
|
||||||
struct seg_t;
|
struct seg_t;
|
||||||
struct sector_t;
|
struct sector_t;
|
||||||
class AActor;
|
class AActor;
|
||||||
|
struct FSection;
|
||||||
|
|
||||||
#define MAXWIDTH 12000
|
#define MAXWIDTH 12000
|
||||||
#define MAXHEIGHT 5000
|
#define MAXHEIGHT 5000
|
||||||
|
@ -1028,7 +1029,6 @@ public:
|
||||||
|
|
||||||
// killough 3/7/98: support flat heights drawn at another sector's heights
|
// killough 3/7/98: support flat heights drawn at another sector's heights
|
||||||
sector_t *heightsec; // other sector, or NULL if no other sector
|
sector_t *heightsec; // other sector, or NULL if no other sector
|
||||||
FLightNode * lighthead;
|
|
||||||
|
|
||||||
uint32_t bottommap, midmap, topmap; // killough 4/4/98: dynamic colormaps
|
uint32_t bottommap, midmap, topmap; // killough 4/4/98: dynamic colormaps
|
||||||
// [RH] these can also be blend values if
|
// [RH] these can also be blend values if
|
||||||
|
@ -1455,13 +1455,13 @@ struct subsector_t
|
||||||
FMiniBSP *BSP;
|
FMiniBSP *BSP;
|
||||||
seg_t *firstline;
|
seg_t *firstline;
|
||||||
sector_t *render_sector;
|
sector_t *render_sector;
|
||||||
|
FSection *section;
|
||||||
uint32_t numlines;
|
uint32_t numlines;
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
uint16_t sectorindex;
|
short mapsection;
|
||||||
|
|
||||||
// subsector related GL data
|
// subsector related GL data
|
||||||
int validcount;
|
int validcount;
|
||||||
short mapsection;
|
|
||||||
char hacked; // 1: is part of a render hack
|
char hacked; // 1: is part of a render hack
|
||||||
|
|
||||||
void BuildPolyBSP();
|
void BuildPolyBSP();
|
||||||
|
|
|
@ -142,6 +142,7 @@ bool setsizeneeded;
|
||||||
|
|
||||||
unsigned int R_OldBlend = ~0;
|
unsigned int R_OldBlend = ~0;
|
||||||
int validcount = 1; // increment every time a check is made
|
int validcount = 1; // increment every time a check is made
|
||||||
|
int dl_validcount = 1; // increment every time a check is made
|
||||||
FCanvasTextureInfo *FCanvasTextureInfo::List;
|
FCanvasTextureInfo *FCanvasTextureInfo::List;
|
||||||
|
|
||||||
DVector3a view;
|
DVector3a view;
|
||||||
|
|
|
@ -66,6 +66,7 @@ extern FViewWindow r_viewwindow;
|
||||||
extern int setblocks;
|
extern int setblocks;
|
||||||
extern bool r_NoInterpolate;
|
extern bool r_NoInterpolate;
|
||||||
extern int validcount;
|
extern int validcount;
|
||||||
|
extern int dl_validcount; // For use with FSection. validcount is in use by the renderer and any quick section exclusion needs another variable.
|
||||||
|
|
||||||
extern angle_t LocalViewAngle; // [RH] Added to consoleplayer's angle
|
extern angle_t LocalViewAngle; // [RH] Added to consoleplayer's angle
|
||||||
extern int LocalViewPitch; // [RH] Used directly instead of consoleplayer's pitch
|
extern int LocalViewPitch; // [RH] Used directly instead of consoleplayer's pitch
|
||||||
|
|
|
@ -558,7 +558,7 @@ namespace swrenderer
|
||||||
Fake3DOpaque::Normal,
|
Fake3DOpaque::Normal,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
ceilingplane->AddLights(Thread, frontsector->lighthead);
|
ceilingplane->AddLights(Thread, sub->section->lighthead);
|
||||||
}
|
}
|
||||||
|
|
||||||
int adjusted_floorlightlevel = floorlightlevel;
|
int adjusted_floorlightlevel = floorlightlevel;
|
||||||
|
@ -598,7 +598,7 @@ namespace swrenderer
|
||||||
Fake3DOpaque::Normal,
|
Fake3DOpaque::Normal,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
floorplane->AddLights(Thread, frontsector->lighthead);
|
floorplane->AddLights(Thread, sub->section->lighthead);
|
||||||
}
|
}
|
||||||
|
|
||||||
Add3DFloorPlanes(sub, frontsector, basecolormap, foggy, adjusted_ceilinglightlevel, adjusted_floorlightlevel);
|
Add3DFloorPlanes(sub, frontsector, basecolormap, foggy, adjusted_ceilinglightlevel, adjusted_floorlightlevel);
|
||||||
|
@ -742,7 +742,7 @@ namespace swrenderer
|
||||||
Fake3DOpaque::FakeFloor,
|
Fake3DOpaque::FakeFloor,
|
||||||
fakeAlpha);
|
fakeAlpha);
|
||||||
|
|
||||||
floorplane3d->AddLights(Thread, tempsec.lighthead);
|
floorplane3d->AddLights(Thread, sub->section->lighthead);
|
||||||
|
|
||||||
FakeDrawLoop(sub, &tempsec, floorplane3d, nullptr, foggy, basecolormap, Fake3DOpaque::FakeFloor);
|
FakeDrawLoop(sub, &tempsec, floorplane3d, nullptr, foggy, basecolormap, Fake3DOpaque::FakeFloor);
|
||||||
}
|
}
|
||||||
|
@ -810,7 +810,7 @@ namespace swrenderer
|
||||||
Fake3DOpaque::FakeCeiling,
|
Fake3DOpaque::FakeCeiling,
|
||||||
fakeAlpha);
|
fakeAlpha);
|
||||||
|
|
||||||
ceilingplane3d->AddLights(Thread, tempsec.lighthead);
|
ceilingplane3d->AddLights(Thread, sub->section->lighthead);
|
||||||
|
|
||||||
FakeDrawLoop(sub, &tempsec, nullptr, ceilingplane3d, foggy, basecolormap, Fake3DOpaque::FakeCeiling);
|
FakeDrawLoop(sub, &tempsec, nullptr, ceilingplane3d, foggy, basecolormap, Fake3DOpaque::FakeCeiling);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace swrenderer
|
||||||
|
|
||||||
BSPWalkCircle(x, y, radiusSquared, [&](subsector_t *subsector) // Iterate through all subsectors potentially touched by actor
|
BSPWalkCircle(x, y, radiusSquared, [&](subsector_t *subsector) // Iterate through all subsectors potentially touched by actor
|
||||||
{
|
{
|
||||||
FLightNode * node = subsector->sector->lighthead;
|
FLightNode * node = subsector->section->lighthead;
|
||||||
while (node) // check all lights touching a subsector
|
while (node) // check all lights touching a subsector
|
||||||
{
|
{
|
||||||
ADynamicLight *light = node->lightsource;
|
ADynamicLight *light = node->lightsource;
|
||||||
|
|
|
@ -202,6 +202,7 @@ namespace swrenderer
|
||||||
// killough 3/27/98: save sector for special clipping later
|
// killough 3/27/98: save sector for special clipping later
|
||||||
vis->heightsec = heightsec;
|
vis->heightsec = heightsec;
|
||||||
vis->sector = thing->Sector;
|
vis->sector = thing->Sector;
|
||||||
|
vis->section = thing->section;
|
||||||
|
|
||||||
vis->depth = (float)tz;
|
vis->depth = (float)tz;
|
||||||
vis->gpos = { (float)pos.X, (float)pos.Y, (float)pos.Z };
|
vis->gpos = { (float)pos.X, (float)pos.Y, (float)pos.Z };
|
||||||
|
@ -251,7 +252,7 @@ namespace swrenderer
|
||||||
float lit_red = 0;
|
float lit_red = 0;
|
||||||
float lit_green = 0;
|
float lit_green = 0;
|
||||||
float lit_blue = 0;
|
float lit_blue = 0;
|
||||||
auto node = vis->sector->lighthead;
|
auto node = vis->section->lighthead;
|
||||||
while (node != nullptr)
|
while (node != nullptr)
|
||||||
{
|
{
|
||||||
ADynamicLight *light = node->lightsource;
|
ADynamicLight *light = node->lightsource;
|
||||||
|
|
|
@ -73,6 +73,7 @@ namespace swrenderer
|
||||||
|
|
||||||
FVector3 gpos = { 0.0f, 0.0f, 0.0f }; // origin in world coordinates
|
FVector3 gpos = { 0.0f, 0.0f, 0.0f }; // origin in world coordinates
|
||||||
sector_t *sector = nullptr; // sector this sprite is in
|
sector_t *sector = nullptr; // sector this sprite is in
|
||||||
|
FSection *section;
|
||||||
|
|
||||||
ColormapLight Light;
|
ColormapLight Light;
|
||||||
float Alpha = 0.0f;
|
float Alpha = 0.0f;
|
||||||
|
|
Loading…
Reference in a new issue