Fix cache while trace isn't moved to GPU

isn't the fastest or most memory efficient fix, but should hopefully only be temporary
This commit is contained in:
Ricardo Luís Vaz Silva 2024-12-30 17:24:05 -03:00 committed by Nash Muhandes
commit 9d9938cccc
5 changed files with 50 additions and 64 deletions

View file

@ -382,36 +382,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;
}
}
@ -421,37 +399,14 @@ public:
template<typename Func>
unsigned int SortedFind(const T& item, Func &&lt, 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;
}
}

View file

@ -134,6 +134,7 @@ static FDynamicLight *GetLight(FLevelLocals *Level)
ret->mShadowmapIndex = 1024;
ret->Level = Level;
ret->Pos.X = -10000000; // not a valid coordinate.
return ret;
}
@ -437,6 +438,27 @@ void FDynamicLight::Tick()
updated = true;
}
if(TraceActors())
{
if(updated)
{
ActorList.Clear();
}
else if(ActorList.Size() > 0)
{
unsigned i = ActorList.Size() - 1;
while(i > 0)
{
if(ActorList[i]->ObjectFlags & OF_EuthanizeMe)
{
ActorList.Delete(i);
ActorResult.Delete(i);
}
i--;
}
}
}
wasactive = m_active;
oldred = GetRed();
oldblue = GetBlue();

View file

@ -306,6 +306,9 @@ public:
float lightStrength;
TArray<AActor*> ActorList;
TArray<bool> ActorResult;
// Locations in the level mesh light list. Ends with index = 0 or all entries used
enum { max_levelmesh_entries = 4 };
struct

View file

@ -1646,7 +1646,7 @@ public:
struct
{
DVector3 Pos = DVector3(-12345678.0, -12345678.0, -12345678.0);
uint64_t Bits = 0;
bool SunResult = false;
} StaticLightsTraceCache;
void InvalidateLightTraceCache()

View file

@ -55,7 +55,7 @@ public:
if (Actor && (Actor->Pos() != Actor->StaticLightsTraceCache.Pos || (Actor->Sector && (Actor->Sector->Flags & SECF_LM_DYNAMIC) && lm_dynamic)))
{
Actor->StaticLightsTraceCache.Pos = Actor->Pos();
Actor->StaticLightsTraceCache.Bits = 0;
Actor->StaticLightsTraceCache.SunResult = false;
ActorMoved = true;
}
}
@ -66,17 +66,26 @@ public:
if (!light->TraceActors() || !level.levelMesh || !Actor)
return true;
if (!ignoreCache && !ActorMoved && CurrentBit < 64)
unsigned index = light->ActorList.SortedFind(Actor, false);
if (!ignoreCache && !ActorMoved && index < light->ActorList.Size() && light->ActorList[index] == Actor)
{
bool traceResult = (Actor->StaticLightsTraceCache.Bits >> CurrentBit) & 1;
CurrentBit++;
bool traceResult = light->ActorResult[index];
return traceResult;
}
else
{
bool traceResult = !level.levelMesh->Trace(FVector3((float)light->Pos.X, (float)light->Pos.Y, (float)light->Pos.Z), FVector3(-L.X, -L.Y, -L.Z), dist);
Actor->StaticLightsTraceCache.Bits |= ((uint64_t)traceResult) << CurrentBit;
CurrentBit++;
if(index == light->ActorList.Size() || light->ActorList[index] != Actor)
{
light->ActorList.Insert(index, Actor);
light->ActorResult.Insert(index, traceResult);
}
else
{
light->ActorResult[index] = traceResult;
}
return traceResult;
}
}
@ -86,24 +95,21 @@ public:
if (!level.lightmaps || !Actor)
return false;
if (!ActorMoved && CurrentBit < 64)
if (!ActorMoved)
{
bool traceResult = (Actor->StaticLightsTraceCache.Bits >> CurrentBit) & 1;
CurrentBit++;
bool traceResult = Actor->StaticLightsTraceCache.SunResult;
return traceResult;
}
else
{
bool traceResult = level.levelMesh->TraceSky(FVector3(x, y, z), level.SunDirection, 65536.0f);
Actor->StaticLightsTraceCache.Bits |= ((uint64_t)traceResult) << CurrentBit;
CurrentBit++;
Actor->StaticLightsTraceCache.SunResult = traceResult;
return traceResult;
}
}
AActor* Actor;
bool ActorMoved = false;
int CurrentBit = 0;
};
//==========================================================================