Skip to content

Commit

Permalink
Fixed performance issues on quieter-behind tracers
Browse files Browse the repository at this point in the history
  • Loading branch information
Grocel committed Feb 17, 2024
1 parent 9f84e26 commit fcb96c3
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 78 deletions.
4 changes: 2 additions & 2 deletions lua/entities/base_streamradio.lua
Original file line number Diff line number Diff line change
Expand Up @@ -692,8 +692,8 @@ function ENT:ShowDebug()
end

if CLIENT then
function ENT:DrawTranslucent()
self:DrawModel()
function ENT:DrawTranslucent(flags)
self:DrawModel(flags)

if not g_isWiremodLoaded then return end
Wire_Render(self)
Expand Down
4 changes: 2 additions & 2 deletions lua/entities/base_streamradio_gui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1097,8 +1097,8 @@ if CLIENT then
cam.End3D2D( )
end

function ENT:DrawTranslucent( )
BaseClass.DrawTranslucent( self )
function ENT:DrawTranslucent(...)
BaseClass.DrawTranslucent(self, ...)
self.isseen = true
self:DrawGUI()
end
Expand Down
123 changes: 83 additions & 40 deletions lua/entities/sent_streamradio/cl_init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -190,30 +190,47 @@ function ENT:OnModelSetup()
end

function ENT:GetWallTraceParamenters()
if not self.WallTraceParamenters then
self.WallTraceParamenters = {
mask = MASK_SHOT_PORTAL,
filter = function(ent)
if not IsValid(ent) then return false end
if not IsValid(self) then return false end

if ent == self then return false end
if ent.__IsRadio then return false end
if ent:IsPlayer() then return false end
if ent:IsVehicle() then return false end
if ent:IsNPC() then return false end

local camera = StreamRadioLib.GetCameraEnt()
if IsValid(camera) and ent == camera then return false end

return true
end
}
local wallTraceParamenters = self.WallTraceParamenters

if not wallTraceParamenters then
self.WallTraceParamenters = {}

wallTraceParamenters = self.WallTraceParamenters
wallTraceParamenters.mask = MASK_SHOT_PORTAL
wallTraceParamenters.filter = {}
end

self.WallTraceParamenters.output = self.WallTraceParamenters.output or {}
wallTraceParamenters.output = wallTraceParamenters.output or {}

local camera = StreamRadioLib.GetCameraEnt(ent)
local cameraVehicle = false

if IsValid(camera) then
cameraVehicle = camera.GetVehicle and camera:GetVehicle() or false
else
camera = false
end

local tmp = {}

tmp[self] = self
tmp[camera] = camera
tmp[cameraVehicle] = cameraVehicle

return self.WallTraceParamenters
local filter = wallTraceParamenters.filter
table.Empty(filter)

for _, filterEnt in pairs(tmp) do
if not IsValid(filterEnt) then continue end
table.insert(filter, filterEnt)
end

for _, filterEnt in pairs(StreamRadioLib.SpawnedRadios) do
table.insert(filter, filterEnt)
end

wallTraceParamenters.filter = filter
return wallTraceParamenters
end

function ENT:TraceToCamera(frompos)
Expand All @@ -228,18 +245,13 @@ function ENT:TraceToCamera(frompos)
local result = traceparams.output

-- Tracers Debug
-- debugoverlay.Line(frompos, result.HitPos or endpos, 0.1, color_white, false)
-- debugoverlay.Line(result.HitPos or endpos, endpos, 0.1, color_black, false)
-- debugoverlay.Line(frompos, result.HitPos or endpos, 0.5, color_white, false)
-- debugoverlay.Line(result.HitPos or endpos, endpos, 0.5, color_black, false)

return result
end

function ENT:TraceWalls(radius)
local coveredvol = StreamRadioLib.GetCoveredVolume()
if coveredvol >= 1 then
return 1
end

local startpos = self.SoundPos

local camtrace = self:TraceToCamera(startpos)
Expand All @@ -251,7 +263,7 @@ function ENT:TraceWalls(radius)

traceparams.start = startpos

local traces = StreamRadioLib.StarTrace(traceparams, radius, 16, 16)
local traces = StreamRadioLib.StarTrace(traceparams, radius)

local blockcount = 0
local wallcount = 0
Expand Down Expand Up @@ -285,7 +297,9 @@ function ENT:TraceWalls(radius)

local f = blockcount / wallcount

local volfactor = math.Clamp((1 - f) * 2, coveredvol, 1)
f = (1 - f) * 2

local volfactor = math.Clamp(f, 0, 1)
return volfactor
end

Expand All @@ -300,24 +314,53 @@ function ENT:GetWallVolumeFactor()
return 0
end

if StreamRadioLib.GetCoveredVolume() >= 1 then
local coveredvol = StreamRadioLib.GetCoveredVolume()

if coveredvol >= 1 then
self.wallvolcache = nil
return 1
end

local streamingRadioCount = StreamRadioLib.GetStreamingRadioCount()
if streamingRadioCount <= 0 then
self.wallvolcache = nil
return 1
end

local now = RealTime()

self.wallvolcache = self.wallvolcache or {}
if (self.wallvolcache.nexttime or 0) >= now then
return self.wallvolcache.value or 0
local cache = self.wallvolcache
local oldvalue = cache.value or 0

if cache.nexttime and cache.nexttime > now then
return math.max(oldvalue, coveredvol)
end

local startTime = SysTime()

local value = self:TraceWalls(self.Radius) or 1

local endTime = SysTime()
local runtime = endTime - startTime

local mintime = math.max(RealFrameTime() * 30, runtime * streamingRadioCount * 50, 0.1)

if oldvalue <= 0 and value <= 0 then
-- already quiet radios should retest less often
mintime = math.max(mintime * 3, 0.5)
elseif oldvalue >= 1 and value >= 1 then
-- already clear radios should retest less often
mintime = math.max(mintime * 3, 0.5)
end

local mintime = math.max(FrameTime() * 3, 0.075)
mintime = math.Rand(mintime, mintime * 2)
mintime = math.min(mintime, 3)

self.wallvolcache.value = self:TraceWalls(self.Radius)
self.wallvolcache.nexttime = now + math.Rand(mintime, mintime * 4)
cache.nexttime = now + mintime

return self.wallvolcache.value or 1
cache.value = value
return math.max(value, coveredvol)
end

function ENT:GetWallVolumeFactorSmoothed()
Expand Down Expand Up @@ -635,9 +678,9 @@ function ENT:OnMasterradioChange(masterradio, oldmasterradio)
end
end

function ENT:DrawTranslucent()
BaseClass.DrawTranslucent(self)
self:CallModelFunction("Draw")
function ENT:DrawTranslucent(...)
BaseClass.DrawTranslucent(self, ...)
self:CallModelFunction("Draw", ...)
end

function ENT:PostFakeRemove()
Expand Down
63 changes: 33 additions & 30 deletions lua/streamradio_core/lib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,6 @@ function StreamRadioLib.Trace(ent)
table.insert(filter, filterEnt)
end

g_PlayerTrace.filter = filter

local trace = util.TraceLine(g_PlayerTrace)

-- prevent the cache from overflowing
Expand All @@ -247,27 +245,17 @@ end

local g_PI = math.pi
local g_TAU = g_PI * 2
local g_starTracePoses = {}

function StreamRadioLib.StarTrace(traceparams, size, edges, layers)
traceparams = traceparams or {}

local centerpos = traceparams.start or Vector()

size = math.abs(size or 0)
edges = math.abs(edges or 0)
local function buildStarTracePoses(layers, edges)
layers = math.abs(layers or 0)
edges = math.abs(edges or 0)

traceparams.start = centerpos
traceparams.output = nil

local traceposes = {}
local traces = {}

for e = 1, edges do
local u = g_TAU / edges * e
for l = 1, layers do
local u = g_TAU / layers * l

for l = 1, layers do
local v = g_TAU / layers * l
for e = 1, edges do
local v = g_TAU / edges * e

local x = math.cos(u) * math.cos(v)
local y = math.cos(u) * math.sin(v)
Expand All @@ -276,28 +264,43 @@ function StreamRadioLib.StarTrace(traceparams, size, edges, layers)
local v = Vector(x, y, z)
v:Normalize()

if traceposes[v] then continue end
traceposes[v] = true
if g_starTracePoses[v] then continue end
g_starTracePoses[v] = true
end
end

traceposes[Vector(0, 0, 1)] = true
traceposes[Vector(0, 1, 0)] = true
traceposes[Vector(1, 0, 0)] = true
g_starTracePoses[Vector(0, 0, 1)] = true
g_starTracePoses[Vector(0, 1, 0)] = true
g_starTracePoses[Vector(1, 0, 0)] = true

traceposes[Vector(0, 0, -1)] = true
traceposes[Vector(0, -1, 0)] = true
traceposes[Vector(-1, 0, 0)] = true
g_starTracePoses[Vector(0, 0, -1)] = true
g_starTracePoses[Vector(0, -1, 0)] = true
g_starTracePoses[Vector(-1, 0, 0)] = true
end

buildStarTracePoses(10, 6)

function StreamRadioLib.StarTrace(traceparams, size)
traceparams = traceparams or {}

local centerpos = traceparams.start or Vector()

size = math.abs(size or 0)

traceparams.start = centerpos
traceparams.output = nil

local traces = {}

for v, _ in pairs(traceposes) do
for v, _ in pairs(g_starTracePoses) do
local endpos = centerpos + v * size
traceparams.endpos = endpos

local trace = util.TraceLine(traceparams)

-- Tracers Debug
-- debugoverlay.Line(centerpos, trace.HitPos or endpos, 0.1, color_white, false)
-- debugoverlay.Line(trace.HitPos or endpos, endpos, 0.1, color_black, false)
-- debugoverlay.Line(centerpos, trace.HitPos or endpos, 0.5, color_white, false)
-- debugoverlay.Line(trace.HitPos or endpos, endpos, 0.5, color_black, false)

table.insert(traces, trace)
end
Expand Down
2 changes: 0 additions & 2 deletions lua/streamradio_core/vr.lua
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,6 @@ function LIB.TraceHand()
table.insert(filter, filterEnt)
end

g_PlayerHandTrace.filter = filter

util.TraceLine(g_PlayerHandTrace)
g_PlayerHandTraceCache = g_PlayerHandTrace.output

Expand Down
4 changes: 2 additions & 2 deletions materials/3dstreamradio/_data/version.vmt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
442
1704655335
443
1708179919

0 comments on commit fcb96c3

Please sign in to comment.