dynlight optimize attempt
This commit is contained in:
parent
1dafe942c8
commit
807043b995
12 changed files with 67 additions and 147 deletions
|
|
@ -405,36 +405,14 @@ public:
|
|||
// exact = false returns the closest match, to be used for, ex., insertions, exact = true returns Size() when no match, like Find does
|
||||
unsigned int SortedFind(const T& item, bool exact = true) const
|
||||
{
|
||||
if(Count == 0) return 0;
|
||||
if(Count == 1) return (item < Array[0]) ? 0 : 1;
|
||||
|
||||
unsigned int lo = 0;
|
||||
unsigned int hi = Count - 1;
|
||||
|
||||
while(lo <= hi)
|
||||
{
|
||||
int mid = lo + ((hi - lo) / 2);
|
||||
|
||||
if(Array[mid] < item)
|
||||
{
|
||||
lo = mid + 1;
|
||||
}
|
||||
else if(item < Array[mid])
|
||||
{
|
||||
hi = mid - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
unsigned int index = (std::lower_bound(begin(), end(), item) - begin());
|
||||
if(exact)
|
||||
{
|
||||
return Count;
|
||||
return (index < Count && Array[index] == item) ? index : Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (lo == Count || (item < Array[lo])) ? lo : lo + 1;
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -444,37 +422,14 @@ public:
|
|||
template<typename Func>
|
||||
unsigned int SortedFind(const T& item, Func &<, bool exact = true) const
|
||||
{
|
||||
if(Count == 0) return 0;
|
||||
if(Count == 1) return lt(item, Array[0]) ? 0 : 1;
|
||||
|
||||
unsigned int lo = 0;
|
||||
unsigned int hi = Count - 1;
|
||||
|
||||
while(lo <= hi)
|
||||
{
|
||||
int mid = lo + ((hi - lo) / 2);
|
||||
|
||||
if(std::invoke(lt, Array[mid], item))
|
||||
{
|
||||
lo = mid + 1;
|
||||
}
|
||||
else if(std::invoke(lt, item, Array[mid]))
|
||||
{
|
||||
if(mid == 0) break; // prevent negative overflow due to unsigned numbers
|
||||
hi = mid - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
unsigned int index = (std::lower_bound(begin(), end(), item, lt) - begin());
|
||||
if(exact)
|
||||
{
|
||||
return Count;
|
||||
return (index < Count && !std::invoke(lt, Array[index], item) && !std::invoke(lt, item, Array[index])) ? index : Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (lo == Count || std::invoke(lt, item, Array[lo])) ? lo : lo + 1;
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@
|
|||
|
||||
struct FGlobalDLightLists
|
||||
{
|
||||
TMap<FSection*, TMap<FDynamicLight*, std::unique_ptr<FLightNode>>> flat_dlist;
|
||||
TMap<side_t*, TMap<FDynamicLight*, std::unique_ptr<FLightNode>>> wall_dlist;
|
||||
TArray<TMap<FDynamicLight*, std::unique_ptr<FLightNode>>> flat_dlist;
|
||||
TArray<TMap<FDynamicLight*, std::unique_ptr<FLightNode>>> wall_dlist;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
|
|
|||
|
|
@ -426,69 +426,50 @@ void FDynamicLight::UpdateLocation()
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
int FSection::Index() const
|
||||
{
|
||||
return int(this - §or->Level->sections.allSections[0]);
|
||||
}
|
||||
|
||||
void FDynamicLight::AddLightNode(FSection *section, side_t *sidedef)
|
||||
{
|
||||
auto updateFlatTList = [&](FSection *sec)
|
||||
{
|
||||
touchlists.flat_tlist.TryEmplace(sec, sec);
|
||||
};
|
||||
auto updateWallTList = [&](side_t *sidedef)
|
||||
{
|
||||
touchlists.wall_tlist.TryEmplace(sidedef, sidedef);
|
||||
};
|
||||
|
||||
if (section)
|
||||
{
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(section);
|
||||
if (flatLightList)
|
||||
if(Level->lightlists.flat_dlist.SSize() <= section->Index())
|
||||
{
|
||||
if (!flatLightList->CheckKey(this))
|
||||
{
|
||||
FLightNode * node = new FLightNode;
|
||||
node->lightsource = this;
|
||||
node->targ = section;
|
||||
|
||||
flatLightList->TryEmplace(this, node);
|
||||
updateFlatTList(section);
|
||||
}
|
||||
Level->lightlists.flat_dlist.Resize(section->Index() + 1);
|
||||
}
|
||||
else
|
||||
|
||||
auto &flatLightList = Level->lightlists.flat_dlist[section->Index()];
|
||||
|
||||
if (!flatLightList.CheckKey(this))
|
||||
{
|
||||
FLightNode * node = new FLightNode;
|
||||
node->lightsource = this;
|
||||
node->targ = section;
|
||||
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>> u;
|
||||
u.TryEmplace(this, node);
|
||||
Level->lightlists.flat_dlist.TryEmplace(section, std::move(u));
|
||||
updateFlatTList(section);
|
||||
flatLightList.TryEmplace(this, node);
|
||||
touchlists.flat_tlist.SortedAddUnique(section);
|
||||
}
|
||||
}
|
||||
else if (sidedef)
|
||||
{
|
||||
auto wallLightList = Level->lightlists.wall_dlist.CheckKey(sidedef);
|
||||
if (wallLightList)
|
||||
if(Level->lightlists.wall_dlist.SSize() <= sidedef->Index())
|
||||
{
|
||||
if (!wallLightList->CheckKey(this))
|
||||
{
|
||||
FLightNode * node = new FLightNode;
|
||||
node->lightsource = this;
|
||||
node->targ = sidedef;
|
||||
|
||||
wallLightList->TryEmplace(this, node);
|
||||
updateWallTList(sidedef);
|
||||
}
|
||||
Level->lightlists.wall_dlist.Resize(sidedef->Index() + 1);
|
||||
}
|
||||
else
|
||||
|
||||
auto &wallLightList = Level->lightlists.wall_dlist[sidedef->Index()];
|
||||
|
||||
if (!wallLightList.CheckKey(this))
|
||||
{
|
||||
FLightNode * node = new FLightNode;
|
||||
node->lightsource = this;
|
||||
node->targ = sidedef;
|
||||
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>> u;
|
||||
u.TryEmplace(this, node);
|
||||
Level->lightlists.wall_dlist.TryEmplace(sidedef, std::move(u));
|
||||
updateWallTList(sidedef);
|
||||
wallLightList.TryEmplace(this, node);
|
||||
touchlists.wall_tlist.SortedAddUnique(sidedef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -686,32 +667,24 @@ void FDynamicLight::LinkLight()
|
|||
void FDynamicLight::UnlinkLight ()
|
||||
{
|
||||
|
||||
TMap<side_t *, side_t *>::Iterator wit(touchlists.wall_tlist);
|
||||
TMap<side_t *, side_t *>::Pair *wpair;
|
||||
while (wit.NextPair(wpair))
|
||||
for(int i = 0; i < touchlists.wall_tlist.SSize(); i++)
|
||||
{
|
||||
auto sidedef = wpair->Value;
|
||||
auto sidedef = touchlists.wall_tlist[i];
|
||||
if (!sidedef) continue;
|
||||
|
||||
auto wallLightList = Level->lightlists.wall_dlist.CheckKey(sidedef);
|
||||
if (wallLightList)
|
||||
{
|
||||
wallLightList->Remove(this);
|
||||
}
|
||||
assert(Level->lightlists.wall_dlist.SSize() < sidedef->Index());
|
||||
|
||||
Level->lightlists.wall_dlist[sidedef->Index()].Remove(this);
|
||||
}
|
||||
|
||||
TMap<FSection *, FSection *>::Iterator fit(touchlists.flat_tlist);
|
||||
TMap<FSection *, FSection *>::Pair *fpair;
|
||||
while (fit.NextPair(fpair))
|
||||
for(int i = 0; i < touchlists.flat_tlist.SSize(); i++)
|
||||
{
|
||||
auto sec = fpair->Value;
|
||||
auto sec = touchlists.flat_tlist[i];
|
||||
if (!sec) continue;
|
||||
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(sec);
|
||||
if (flatLightList)
|
||||
{
|
||||
flatLightList->Remove(this);
|
||||
}
|
||||
|
||||
assert(Level->lightlists.flat_dlist.SSize() < sec->Index());
|
||||
|
||||
Level->lightlists.flat_dlist[sec->Index()].Remove(this);
|
||||
}
|
||||
|
||||
touchlists.flat_tlist.Clear();
|
||||
|
|
|
|||
|
|
@ -199,8 +199,8 @@ struct FLightNode
|
|||
|
||||
struct FDynamicLightTouchLists
|
||||
{
|
||||
TMap<FSection*, FSection*> flat_tlist;
|
||||
TMap<side_t*, side_t*> wall_tlist;
|
||||
TArray<FSection*> flat_tlist;
|
||||
TArray<side_t*> wall_tlist;
|
||||
};
|
||||
|
||||
struct FDynamicLight
|
||||
|
|
|
|||
|
|
@ -120,6 +120,8 @@ struct FSection
|
|||
short mapsection;
|
||||
char hacked; // 1: is part of a render hack
|
||||
char flags;
|
||||
|
||||
int Index() const;
|
||||
};
|
||||
|
||||
class FSectionContainer
|
||||
|
|
|
|||
|
|
@ -159,11 +159,9 @@ void HWFlat::SetupLights(HWDrawInfo *di, FDynLightData &lightdata, int portalgro
|
|||
return; // no lights on additively blended surfaces.
|
||||
}
|
||||
|
||||
auto flatLightList = di->Level->lightlists.flat_dlist.CheckKey(section);
|
||||
|
||||
if (flatLightList)
|
||||
if (di->Level->lightlists.flat_dlist.SSize() > section->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(di->Level->lightlists.flat_dlist[section->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -117,11 +117,9 @@ int HWDrawInfo::SetupLightsForOtherPlane(subsector_t * sub, FDynLightData &light
|
|||
|
||||
lightdata.Clear();
|
||||
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(sub->section);
|
||||
|
||||
if (flatLightList)
|
||||
if (Level->lightlists.flat_dlist.SSize() > sub->section->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(Level->lightlists.flat_dlist[sub->section->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -124,11 +124,9 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, float x, float y, float z, FSec
|
|||
}
|
||||
|
||||
// Go through both light lists
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(sec);
|
||||
|
||||
if (flatLightList)
|
||||
if (Level->lightlists.flat_dlist.SSize() > sec->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(Level->lightlists.flat_dlist[sec->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
|
|
@ -255,10 +253,10 @@ void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata)
|
|||
{
|
||||
auto section = subsector->section;
|
||||
if (section->validcount == dl_validcount) return; // already done from a previous subsector.
|
||||
auto flatLightList = self->Level->lightlists.flat_dlist.CheckKey(subsector->section);
|
||||
if (flatLightList)
|
||||
|
||||
if (self->Level->lightlists.flat_dlist.SSize() > subsector->section->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(self->Level->lightlists.flat_dlist[subsector->section->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{ // check all lights touching a subsector
|
||||
|
|
|
|||
|
|
@ -427,11 +427,9 @@ void HWWall::SetupLights(HWDrawInfo*di, FDynLightData &lightdata)
|
|||
if ((seg->sidedef->Flags & WALLF_POLYOBJ) && sub)
|
||||
{
|
||||
// Polobject segs cannot be checked per sidedef so use the subsector instead.
|
||||
auto flatLightList = di->Level->lightlists.flat_dlist.CheckKey(sub->section);
|
||||
|
||||
if (flatLightList)
|
||||
if (di->Level->lightlists.flat_dlist.SSize() > sub->section->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(di->Level->lightlists.flat_dlist[sub->section->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
|
|
@ -492,11 +490,9 @@ void HWWall::SetupLights(HWDrawInfo*di, FDynLightData &lightdata)
|
|||
}
|
||||
else
|
||||
{
|
||||
auto wallLightList = di->Level->lightlists.wall_dlist.CheckKey(seg->sidedef);
|
||||
|
||||
if (wallLightList)
|
||||
if (di->Level->lightlists.wall_dlist.SSize() > seg->sidedef->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*wallLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(di->Level->lightlists.wall_dlist[seg->sidedef->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -224,10 +224,10 @@ namespace swrenderer
|
|||
else if (curline && curline->sidedef)
|
||||
{
|
||||
auto Level = curline->Subsector->sector->Level;
|
||||
auto wallLightList = Level->lightlists.wall_dlist.CheckKey(curline->sidedef);
|
||||
if (wallLightList)
|
||||
|
||||
if (Level->lightlists.wall_dlist.SSize() > curline->sidedef->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*wallLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(Level->lightlists.wall_dlist[curline->sidedef->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -76,10 +76,10 @@ namespace swrenderer
|
|||
return; // [SP] no dynlights if invul or lightamp
|
||||
|
||||
auto Level = sec->sector->Level;
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(sec);
|
||||
if (flatLightList)
|
||||
|
||||
if (Level->lightlists.flat_dlist.SSize() > sec->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(Level->lightlists.flat_dlist[sec->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -209,10 +209,10 @@ namespace swrenderer
|
|||
float lit_green = 0;
|
||||
float lit_blue = 0;
|
||||
auto Level = vis->sector->Level;
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(vis->section);
|
||||
if (flatLightList)
|
||||
|
||||
if (Level->lightlists.flat_dlist.SSize() > vis->section->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(Level->lightlists.flat_dlist[vis->section->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue