mirror of
https://github.com/metrostroi-repo/MetrostroiAddon.git
synced 2026-05-02 00:42:29 +00:00
Оптимизация обращений к полям в Metrostroi.ScanTrack. Константные углы вынесены в локальные переменные
This commit is contained in:
@@ -39,6 +39,9 @@ if not Metrostroi.Paths then
|
||||
end
|
||||
Metrostroi.SignalVersion = 1.2
|
||||
|
||||
local vector_origin = vector_origin
|
||||
local vector_up = vector_up
|
||||
local angle_zero = angle_zero
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Size of spatial cells into which all the 3D space is divided
|
||||
@@ -46,10 +49,11 @@ local SPATIAL_CELL_WIDTH = 1024
|
||||
local SPATIAL_CELL_HEIGHT = 256
|
||||
|
||||
-- Return spatial cell indexes for given XYZ
|
||||
local floor = math.floor
|
||||
local function spatialPosition(pos)
|
||||
return math.floor(pos.x/SPATIAL_CELL_WIDTH),
|
||||
math.floor(pos.y/SPATIAL_CELL_WIDTH),
|
||||
math.floor(pos.z/SPATIAL_CELL_HEIGHT)
|
||||
return floor(pos.x/SPATIAL_CELL_WIDTH),
|
||||
floor(pos.y/SPATIAL_CELL_WIDTH),
|
||||
floor(pos.z/SPATIAL_CELL_HEIGHT)
|
||||
end
|
||||
|
||||
local function addLookup(node)
|
||||
@@ -111,7 +115,7 @@ function Metrostroi.GetPositionOnTrack(pos,ang,opts)
|
||||
if not opts then opts = empty_table end
|
||||
|
||||
-- Angle can be specified to determine if facing forward or backward
|
||||
ang = ang or Angle(0,0,0)
|
||||
ang = ang or angle_zero
|
||||
|
||||
-- Size of box which envelopes region of space that counts as being on track
|
||||
local X_PAD = 0
|
||||
@@ -123,14 +127,13 @@ function Metrostroi.GetPositionOnTrack(pos,ang,opts)
|
||||
for nodeID,node in Metrostroi.NearestNodes(pos) do
|
||||
-- Get local coordinate system of a section
|
||||
local forward = node.dir
|
||||
local up = Vector(0,0,1)
|
||||
local right = forward:Cross(up)
|
||||
local right = forward:Cross(vector_up)
|
||||
|
||||
-- Transform position into local coordinates
|
||||
local local_pos = pos - node.pos
|
||||
local local_x = local_pos:Dot(forward)
|
||||
local local_y = local_pos:Dot(right)
|
||||
local local_z = local_pos:Dot(up)
|
||||
local local_z = local_pos:Dot(vector_up)
|
||||
local yz_delta = math.sqrt(local_y^2 + local_z^2)
|
||||
|
||||
-- Determine if facing forward or backward
|
||||
@@ -509,40 +512,42 @@ function Metrostroi.ScanTrack(itype,node,func,x,dir,checked)
|
||||
local isolateBackward = false -- Should scanning continue backward along track
|
||||
if Metrostroi.SignalEntitiesForNode[node] then
|
||||
for k,v in pairs(Metrostroi.SignalEntitiesForNode[node]) do
|
||||
if not IsValid(v) then continue end
|
||||
local v = v:GetTable()
|
||||
local trackX = v.TrackX
|
||||
local routeTbl = v.Routes[v.Route or 1]
|
||||
|
||||
local isolating = false
|
||||
if IsValid(v) then
|
||||
if light then
|
||||
isolating = ((v.TrackDir == dir and not v.Routes[v.Route or 1].Repeater) or (v.TrackDir == dir and v.Routes[v.Route or 1].Repeater and tonumber(v.RouteNumber) == 9) or (tonumber(v.RouteNumber) ~= nil and v.Routes[v.Route or 1].Repeater)) and (not v.PassOcc or v.TrackX == x)
|
||||
end
|
||||
if ars then
|
||||
isolating = v.TrackDir == dir and (not v.PassOcc or v.TrackX == x)
|
||||
end
|
||||
if switch then
|
||||
isolating = v.IsolateSwitches
|
||||
end
|
||||
--if itype == "ars" then isolating = true end
|
||||
if light then
|
||||
isolating = ((v.TrackDir == dir and not routeTbl.Repeater) or (v.TrackDir == dir and routeTbl.Repeater and v.iRouteNumber == 9) or (v.iRouteNumber ~= nil and routeTbl.Repeater)) and (not v.PassOcc or trackX == x)
|
||||
elseif ars then
|
||||
isolating = v.TrackDir == dir and (not v.PassOcc or trackX == x)
|
||||
elseif switch then
|
||||
isolating = v.IsolateSwitches
|
||||
end
|
||||
--if itype == "ars" then isolating = true end
|
||||
|
||||
if isolating then
|
||||
-- If scanning forward, and there's a joint IN FRONT of current X
|
||||
if dir and (v.TrackX > x) then
|
||||
max_x = math.min(max_x,v.TrackX)
|
||||
if dir and (trackX > x) then
|
||||
max_x = math.min(max_x,trackX)
|
||||
isolateForward = true
|
||||
end
|
||||
-- If scanning forward, and there's a joint in current X
|
||||
-- This is triggered when traffic light searches for next light from its own X (then
|
||||
-- scan direction is defined by dir)
|
||||
if dir and (v.TrackX == x) then
|
||||
min_x = math.max(min_x,v.TrackX)
|
||||
if dir and (trackX == x) then
|
||||
min_x = math.max(min_x,trackX)
|
||||
isolateBackward = true
|
||||
end
|
||||
-- if scanning backward, and there's a joint BEHIND current X
|
||||
if (not dir) and (v.TrackX < x) then
|
||||
min_x = math.max(min_x,v.TrackX)
|
||||
if (not dir) and (trackX < x) then
|
||||
min_x = math.max(min_x,trackX)
|
||||
isolateBackward = true
|
||||
end
|
||||
-- If scanning backward starting from current X, use dir for guiding scan
|
||||
if (not dir) and (v.TrackX == x) then
|
||||
max_x = math.min(max_x,v.TrackX)
|
||||
if (not dir) and (trackX == x) then
|
||||
max_x = math.min(max_x,trackX)
|
||||
isolateForward = true
|
||||
end
|
||||
end
|
||||
@@ -566,7 +571,7 @@ function Metrostroi.ScanTrack(itype,node,func,x,dir,checked)
|
||||
end
|
||||
-- First check all the branches, whose positions fall within min_x..max_x
|
||||
if node.branches and not ars then
|
||||
for k,v in pairs(node.branches) do
|
||||
for k,v in ipairs(node.branches) do
|
||||
if (v[1] >= min_x) and (v[1] <= max_x) then
|
||||
-- FIXME: somehow define direction and X!
|
||||
local results = {Metrostroi.ScanTrack(itype,v[2],func,v[1],true,checked)}
|
||||
@@ -858,6 +863,8 @@ function Metrostroi.PredictTrainPositions()
|
||||
train.OldPos = pos.x+train.PosX
|
||||
end
|
||||
end
|
||||
local vector_p25 = Vector(25,0,0)
|
||||
local vector_m25 = Vector(-25,0,0)
|
||||
function Metrostroi.UpdateTrainPositions()
|
||||
Metrostroi.TrainPositions = {}
|
||||
Metrostroi.TrainDirections = {}
|
||||
@@ -868,13 +875,14 @@ function Metrostroi.UpdateTrainPositions()
|
||||
if train.ALS_ARS and train.ALS_ARS.IgnoreThisARS or train.NoTrain then continue end
|
||||
train.PosX = 0--(train:GetVelocity():Dot(train:GetAngles():Forward()) * 0.01905)*FrameTime()
|
||||
local pos1e = IsValid(train.FrontBogey) and train.FrontBogey or train
|
||||
local positions = Metrostroi.GetPositionOnTrack(pos1e:GetPos(),train:GetAngles())
|
||||
local trainAng = train:GetAngles()
|
||||
local positions = Metrostroi.GetPositionOnTrack(pos1e:GetPos(),trainAng)
|
||||
local positions2
|
||||
if not positions or not positions[1] then
|
||||
positions = Metrostroi.GetPositionOnTrack(train:LocalToWorld(Vector(0,0,0)),train:GetAngles())
|
||||
positions2 = Metrostroi.GetPositionOnTrack(train:LocalToWorld(Vector(25,0,0)), train:GetAngles())
|
||||
positions = Metrostroi.GetPositionOnTrack(train:GetPos(),trainAng)
|
||||
positions2 = Metrostroi.GetPositionOnTrack(train:LocalToWorld(vector_p25), trainAng)
|
||||
else
|
||||
positions2 = Metrostroi.GetPositionOnTrack(pos1e:LocalToWorld(Vector(-25,0,0)), train:GetAngles())
|
||||
positions2 = Metrostroi.GetPositionOnTrack(pos1e:LocalToWorld(vector_m25), trainAng)
|
||||
end
|
||||
Metrostroi.TrainPositions[train] = {}
|
||||
Metrostroi.TrainDirections[train] = true
|
||||
@@ -1081,8 +1089,8 @@ local function loadTracks(name)
|
||||
|
||||
if prevNode then
|
||||
prevNode.next = nil
|
||||
prevNode.dir = Vector(0,0,0)
|
||||
prevNode.vec = Vector(0,0,0)
|
||||
prevNode.dir = vector_origin
|
||||
prevNode.vec = vector_origin
|
||||
prevNode.length = 0
|
||||
end
|
||||
end
|
||||
@@ -1172,6 +1180,7 @@ local function loadSigns(name,keep)
|
||||
ent.LensesStr = v.LensesStr
|
||||
ent.Lenses = string.Explode("-",v.LensesStr)
|
||||
ent.RouteNumber = v.RouteNumber
|
||||
ent.iRouteNumber = tonumber(v.RouteNumber)
|
||||
ent.IsolateSwitches = v.IsolateSwitches
|
||||
ent.Routes = v.Routes
|
||||
ent.ARSOnly = v.ARSOnly
|
||||
|
||||
Reference in New Issue
Block a user