Skip to content

Commit

Permalink
1.9.7: first performance improvements regarding vehicle state update
Browse files Browse the repository at this point in the history
  • Loading branch information
VictorPhilipp committed Jun 10, 2017
1 parent 0d4d64e commit ce52829
Show file tree
Hide file tree
Showing 29 changed files with 1,284 additions and 1,549 deletions.
2 changes: 1 addition & 1 deletion TLM/TLM/Custom/AI/CustomAmbulanceAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vecto
#endif

ExtVehicleType vehicleType = (vehicleData.m_flags & Vehicle.Flags.Emergency2) != 0 ? ExtVehicleType.Emergency : ExtVehicleType.Service;
VehicleStateManager.Instance._GetVehicleState(vehicleID).VehicleType = vehicleType;
VehicleStateManager.Instance.VehicleStates[VehicleStateManager.Instance.GetFrontVehicleId(vehicleID, ref vehicleData)].vehicleType = vehicleType;

VehicleInfo info = this.m_info;
bool allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0;
Expand Down
118 changes: 55 additions & 63 deletions TLM/TLM/Custom/AI/CustomCarAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,26 +68,6 @@ public void CustomSimulationStep(ushort vehicleId, ref Vehicle vehicleData, Vect
}
}

/// NON-STOCK CODE START ///
if (Options.prioritySignsEnabled || Options.timedLightsEnabled) {
// update vehicle position for timed traffic lights and priority signs
try {
VehicleStateManager.Instance.UpdateVehiclePos(vehicleId, ref vehicleData);
} catch (Exception e) {
Log.Error("CarAI CustomSimulationStep Error: " + e.ToString());
}
}

if (!Options.isStockLaneChangerUsed()) {
// Advanced AI traffic measurement
try {
VehicleStateManager.Instance.LogTraffic(vehicleId, ref vehicleData, true);
} catch (Exception e) {
Log.Error("CarAI CustomSimulationStep Error: " + e.ToString());
}
}
/// NON-STOCK CODE END ///

Vector3 lastFramePosition = vehicleData.GetLastFramePosition();
int lodPhysics;
if (Vector3.SqrMagnitude(physicsLodRefPos - lastFramePosition) >= 1210000f) {
Expand Down Expand Up @@ -123,26 +103,24 @@ public void CustomSimulationStep(ushort vehicleId, ref Vehicle vehicleData, Vect
}
}

public override bool TrySpawn(ushort vehicleID, ref Vehicle vehicleData) {
public override bool TrySpawn(ushort vehicleId, ref Vehicle vehicleData) {
if ((vehicleData.m_flags & Vehicle.Flags.Spawned) != (Vehicle.Flags)0) {
// NON-STOCK CODE START
if (Options.prioritySignsEnabled || Options.timedLightsEnabled) {
VehicleStateManager.Instance.OnVehicleSpawned(vehicleID, ref vehicleData);
}
// NON-STOCK CODE END

return true;
}
if (CustomCarAI.CheckOverlap(vehicleData.m_segment, 0, 1000f)) {
vehicleData.m_flags |= Vehicle.Flags.WaitingSpace;
return false;
}
vehicleData.Spawn(vehicleID);
vehicleData.Spawn(vehicleId);
vehicleData.m_flags &= ~Vehicle.Flags.WaitingSpace;

// NON-STOCK CODE START
if (Options.prioritySignsEnabled || Options.timedLightsEnabled) {
VehicleStateManager.Instance.OnVehicleSpawned(vehicleID, ref vehicleData);
#if DEBUG
if (GlobalConfig.Instance.DebugSwitches[9])
Log._Debug($"CustomCarAI.TrySpawn({vehicleId}): calling OnSpawnVehicle in TrySpawn");
#endif
VehicleStateManager.Instance.OnSpawnVehicle(vehicleId, ref vehicleData);
}
// NON-STOCK CODE END

Expand All @@ -152,36 +130,7 @@ public override bool TrySpawn(ushort vehicleID, ref Vehicle vehicleData) {
public void CustomCalculateSegmentPosition(ushort vehicleId, ref Vehicle vehicleData, PathUnit.Position nextPosition,
PathUnit.Position position, uint laneID, byte offset, PathUnit.Position prevPos, uint prevLaneID,
byte prevOffset, int index, out Vector3 pos, out Vector3 dir, out float maxSpeed) {
// NON-STOCK CODE START
if ((Options.prioritySignsEnabled || Options.timedLightsEnabled) && Options.simAccuracy <= 1) {
// update vehicle position for timed traffic lights and priority signs
try {
VehicleStateManager.Instance.UpdateVehiclePos(vehicleId, ref vehicleData, ref prevPos, ref position);
} catch (Exception e) {
Log.Error("CarAI CustomCalculateSegmentPosition Error: " + e.ToString());
}
}
// NON-STOCK CODE END

var netManager = Singleton<NetManager>.instance;
netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CalculatePositionAndDirection(offset * 0.003921569f, out pos, out dir);

float braking = this.m_info.m_braking;
if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) != (Vehicle.Flags)0) {
braking *= 2f;
}

Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData();
Vector3 lastFrameVehiclePos = lastFrameData.m_position;

var camPos = Camera.main.transform.position;

// I think this is supposed to be the lane position?
// [VN, 12/23/2015] It's the 3D car position on the Bezier curve of the lane.
// This crazy 0.003921569f equals to 1f/255 and prevOffset is the byte value (0..255) of the car position.
var vehiclePosOnBezier = netManager.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].CalculatePosition(prevOffset * 0.003921569f);
//ushort currentSegmentId = netManager.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].m_segment;

ushort targetNodeId;
ushort nextTargetNodeId;
if (offset < position.m_offset) {
Expand All @@ -193,16 +142,59 @@ public void CustomCalculateSegmentPosition(ushort vehicleId, ref Vehicle vehicle
}
var prevTargetNodeId = prevOffset == 0 ? netManager.m_segments.m_buffer[prevPos.m_segment].m_startNode : netManager.m_segments.m_buffer[prevPos.m_segment].m_endNode;

Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData();
Vector3 lastFrameVehiclePos = lastFrameData.m_position;
float sqrVelocity = lastFrameData.m_velocity.sqrMagnitude;

netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CalculatePositionAndDirection(offset * 0.003921569f, out pos, out dir);

float braking = this.m_info.m_braking;
if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) != (Vehicle.Flags)0) {
braking *= 2f;
}

// car position on the Bezier curve of the lane
var vehiclePosOnBezier = netManager.m_lanes.m_buffer[prevLaneID].CalculatePosition(prevOffset * 0.003921569f);
//ushort currentSegmentId = netManager.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].m_segment;

// this seems to be like the required braking force in order to stop the vehicle within its half length.
var crazyValue = 0.5f * sqrVelocity / braking + m_info.m_generatedInfo.m_size.z * 0.5f;
bool withinBrakingDistance = Vector3.Distance(lastFrameVehiclePos, vehiclePosOnBezier) >= crazyValue - 1f;

// NON-STOCK CODE START
ushort frontVehicleId = VehicleStateManager.Instance.GetFrontVehicleId(vehicleId, ref vehicleData);
#if DEBUG
if (GlobalConfig.Instance.DebugSwitches[9])
Log._Debug($"CustomCarAI.CustomCalculateSegmentPosition({vehicleId}): processing front vehicle {frontVehicleId} @ PREV seg. {prevPos.m_segment}, lane {prevPos.m_lane}, off {prevPos.m_offset} -> CURRENT seg. {position.m_segment}, lane {position.m_lane}, off {position.m_offset} -> NEXT seg. {nextPosition.m_segment}, lane {nextPosition.m_lane}, off {nextPosition.m_offset} || prevOffset: {prevOffset}, offset: {offset} || prevTargetNodeId: {prevTargetNodeId}, targetNodeId: {targetNodeId}, nextTargetNodeId: {nextTargetNodeId} || pathPositionIndex: {vehicleData.m_pathPositionIndex}");
#endif
if (vehicleId == frontVehicleId) {
if (Options.prioritySignsEnabled || Options.timedLightsEnabled) {
// update vehicle position for timed traffic lights and priority signs
int pathPosIndex = vehicleData.m_pathPositionIndex >> 1;
PathUnit.Position curPathPos = Singleton<PathManager>.instance.m_pathUnits.m_buffer[vehicleData.m_path].GetPosition(pathPosIndex);
PathUnit.Position nextPathPos;
Singleton<PathManager>.instance.m_pathUnits.m_buffer[vehicleData.m_path].GetNextPosition(pathPosIndex, out nextPathPos);
VehicleStateManager.Instance.VehicleStates[frontVehicleId].UpdatePosition(ref vehicleData, sqrVelocity, ref curPathPos, ref nextPathPos);
}
} else {
#if DEBUG
if (GlobalConfig.Instance.DebugSwitches[9])
Log._Debug($"CustomCarAI.CustomCalculateSegmentPosition({vehicleId}): processing non-front vehicle! frontVehicleId={frontVehicleId}");
#endif
}
// NON-STOCK CODE END

bool isRecklessDriver = VehicleStateManager.Instance.IsRecklessDriver(vehicleId, ref vehicleData); // NON-STOCK CODE
if (targetNodeId == prevTargetNodeId) {
if (Vector3.Distance(lastFrameVehiclePos, vehiclePosOnBezier) >= crazyValue - 1f) {
if (!VehicleBehaviorManager.Instance.MayChangeSegment(vehicleId, ref vehicleData, ref lastFrameData, isRecklessDriver, ref prevPos, ref netManager.m_segments.m_buffer[prevPos.m_segment], prevTargetNodeId, prevLaneID, ref position, targetNodeId, ref netManager.m_nodes.m_buffer[targetNodeId], laneID, ref nextPosition, nextTargetNodeId, out maxSpeed)) // NON-STOCK CODE
return;
if (targetNodeId == prevTargetNodeId && withinBrakingDistance) {
// NON-STOCK CODE START
if (vehicleId == frontVehicleId && !Options.isStockLaneChangerUsed()) {
// Advanced AI traffic measurement
VehicleStateManager.Instance.LogTraffic(frontVehicleId, ref vehicleData, position.m_segment, position.m_lane, true);
}
// NON-STOCK CODE END

if (!VehicleBehaviorManager.Instance.MayChangeSegment(frontVehicleId, ref VehicleStateManager.Instance.VehicleStates[frontVehicleId], ref vehicleData, ref lastFrameData, isRecklessDriver, ref prevPos, ref netManager.m_segments.m_buffer[prevPos.m_segment], prevTargetNodeId, prevLaneID, ref position, targetNodeId, ref netManager.m_nodes.m_buffer[targetNodeId], laneID, ref nextPosition, nextTargetNodeId, out maxSpeed)) // NON-STOCK CODE
return;
}

var info2 = netManager.m_segments.m_buffer[position.m_segment].Info;
Expand Down Expand Up @@ -253,7 +245,7 @@ public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vecto
uint path;

// NON-STOCK CODE START
ExtVehicleType vehicleType = VehicleStateManager.Instance._GetVehicleState(vehicleID).VehicleType;
ExtVehicleType vehicleType = VehicleStateManager.Instance.VehicleStates[VehicleStateManager.Instance.GetFrontVehicleId(vehicleID, ref vehicleData)].vehicleType;
if (vehicleType == ExtVehicleType.None) {
#if DEBUG
Log.Warning($"CustomCarAI.CustomStartPathFind: Vehicle {vehicleID} does not have a valid vehicle type!");
Expand Down
2 changes: 1 addition & 1 deletion TLM/TLM/Custom/AI/CustomFireTruckAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vecto
#endif

ExtVehicleType vehicleType = (vehicleData.m_flags & Vehicle.Flags.Emergency2) != 0 ? ExtVehicleType.Emergency : ExtVehicleType.Service;
VehicleStateManager.Instance._GetVehicleState(vehicleID).VehicleType = vehicleType;
VehicleStateManager.Instance.VehicleStates[VehicleStateManager.Instance.GetFrontVehicleId(vehicleID, ref vehicleData)].vehicleType = vehicleType;

VehicleInfo info = this.m_info;
bool allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0;
Expand Down
23 changes: 14 additions & 9 deletions TLM/TLM/Custom/AI/CustomHumanAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ protected static bool EnterParkedCar(ushort instanceID, ref CitizenInstance inst
#endif
return false;
}

// change instances
InstanceID parkedVehInstance = InstanceID.Empty;
parkedVehInstance.ParkedVehicle = parkedVehicleId;
Expand Down Expand Up @@ -870,29 +870,34 @@ internal static string EnrichLocalizedStatus(string ret, ExtCitizenInstance extI
}

public bool CustomCheckTrafficLights(ushort node, ushort segment) {
var nodeSimulation = Options.timedLightsEnabled ? TrafficLightSimulationManager.Instance.GetNodeSimulation(node) : null;
var netManager = Singleton<NetManager>.instance;

var instance = Singleton<NetManager>.instance;
var currentFrameIndex = Singleton<SimulationManager>.instance.m_currentFrameIndex;

var num = (uint)((node << 8) / 32768);
var stepWaitTime = currentFrameIndex - num & 255u;

// NON-STOCK CODE START //
var nodeSimulation = Options.timedLightsEnabled ? TrafficLightSimulationManager.Instance.GetNodeSimulation(node) : null;
RoadBaseAI.TrafficLightState pedestrianLightState;
bool startNode = instance.m_segments.m_buffer[segment].m_startNode == node;
CustomSegmentLights lights = CustomSegmentLightsManager.Instance.GetSegmentLights(segment, startNode, false);
bool startNode = netManager.m_segments.m_buffer[segment].m_startNode == node;

CustomSegmentLights lights = null;
if (nodeSimulation != null && nodeSimulation.IsSimulationActive()) {
lights = CustomSegmentLightsManager.Instance.GetSegmentLights(segment, startNode, false);
}

if (lights == null || nodeSimulation == null || !nodeSimulation.IsSimulationActive()) {
if (lights == null) {
// NON-STOCK CODE END //
RoadBaseAI.TrafficLightState vehicleLightState;
bool vehicles;
bool pedestrians;

RoadBaseAI.GetTrafficLightState(node, ref instance.m_segments.m_buffer[segment], currentFrameIndex - num, out vehicleLightState, out pedestrianLightState, out vehicles, out pedestrians);
RoadBaseAI.GetTrafficLightState(node, ref netManager.m_segments.m_buffer[segment], currentFrameIndex - num, out vehicleLightState, out pedestrianLightState, out vehicles, out pedestrians);
if ((pedestrianLightState == RoadBaseAI.TrafficLightState.GreenToRed || pedestrianLightState == RoadBaseAI.TrafficLightState.Red) && !pedestrians && stepWaitTime >= 196u) {
RoadBaseAI.SetTrafficLightState(node, ref instance.m_segments.m_buffer[segment], currentFrameIndex - num, vehicleLightState, pedestrianLightState, vehicles, true);
RoadBaseAI.SetTrafficLightState(node, ref netManager.m_segments.m_buffer[segment], currentFrameIndex - num, vehicleLightState, pedestrianLightState, vehicles, true);
return true;
}
// NON-STOCK CODE START //
} else {
if (lights.InvalidPedestrianLight) {
pedestrianLightState = RoadBaseAI.TrafficLightState.Green;
Expand Down
12 changes: 5 additions & 7 deletions TLM/TLM/Custom/AI/CustomPassengerCarAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ public string CustomGetLocalizedStatus(ushort vehicleID, ref Vehicle data, out I

string ret = Locale.Get("VEHICLE_STATUS_GOINGTO");
if (Options.prohibitPocketCars) {
VehicleState state = VehicleStateManager.Instance._GetVehicleState(vehicleID);
ExtCitizenInstance driverExtInstance = state.GetDriverExtInstance();
ret = AdvancedParkingManager.Instance.EnrichLocalizedStatus(ret, driverExtInstance);
ExtCitizenInstance driverExtInstance = ExtCitizenInstanceManager.Instance.GetExtInstance(driverInstanceId);
if (driverExtInstance != null) {
ret = AdvancedParkingManager.Instance.EnrichLocalizedStatus(ret, driverExtInstance);
}
}

return ret;
Expand Down Expand Up @@ -114,8 +115,7 @@ public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vecto
bool skipQueue = false;
ExtPathType extPathType = ExtPathType.None;
if (Options.prohibitPocketCars) {
VehicleState state = VehicleStateManager.Instance._GetVehicleState(vehicleData.GetFirstVehicle(vehicleID));
ExtCitizenInstance driverExtInstance = state.GetDriverExtInstance();
ExtCitizenInstance driverExtInstance = ExtCitizenInstanceManager.Instance.GetExtInstance(driverInstanceId);
if (driverExtInstance != null) {
#if DEBUG
if (GlobalConfig.Instance.DebugSwitches[2])
Expand Down Expand Up @@ -368,14 +368,12 @@ public bool CustomParkVehicle(ushort vehicleID, ref Vehicle vehicleData, PathUni
}

// NON-STOCK CODE START
VehicleState state = null;
ExtCitizenInstance driverExtInstance = null;
bool prohibitPocketCars = false;
// NON-STOCK CODE END

if (driverCitizenId != 0u) {
if (Options.prohibitPocketCars) {
state = VehicleStateManager.Instance._GetVehicleState(vehicleData.GetFirstVehicle(vehicleID));
if (driverCitizenInstanceId != 0) {
driverExtInstance = ExtCitizenInstanceManager.Instance.GetExtInstance(driverCitizenInstanceId);
prohibitPocketCars = true;
Expand Down
2 changes: 1 addition & 1 deletion TLM/TLM/Custom/AI/CustomPoliceCarAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vecto
#endif

ExtVehicleType vehicleType = (vehicleData.m_flags & Vehicle.Flags.Emergency2) != 0 ? ExtVehicleType.Emergency : ExtVehicleType.Service;
VehicleStateManager.Instance._GetVehicleState(vehicleID).VehicleType = vehicleType;
VehicleStateManager.Instance.VehicleStates[VehicleStateManager.Instance.GetFrontVehicleId(vehicleID, ref vehicleData)].vehicleType = vehicleType;

VehicleInfo info = this.m_info;
bool allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0;
Expand Down
22 changes: 9 additions & 13 deletions TLM/TLM/Custom/AI/CustomRoadAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ public void CustomNodeSimulationStep(ushort nodeId, ref NetNode data) {
}

public void CustomSegmentSimulationStep(ushort segmentID, ref NetSegment data) {
try {
uint curLaneId = data.m_lanes;
//try {
/*uint curLaneId = data.m_lanes;
int numLanes = data.Info.m_lanes.Length;
uint laneIndex = 0;
uint laneIndex = 0;*/

/*while (laneIndex < numLanes && curLaneId != 0u) {
Flags.applyLaneArrowFlags(curLaneId);
Expand All @@ -50,9 +50,9 @@ public void CustomSegmentSimulationStep(ushort segmentID, ref NetSegment data) {
}*/

SegmentEndManager.Instance.SegmentSimulationStep(segmentID);
} catch (Exception e) {
/*} catch (Exception e) {
Log.Error($"Error occured while housekeeping segment {segmentID}: " + e.ToString());
}
}*/

if (!Options.isStockLaneChangerUsed()) {
if (segmentID < lastSimulatedSegmentId) {
Expand All @@ -71,19 +71,15 @@ public void CustomSegmentSimulationStep(ushort segmentID, ref NetSegment data) {
}

if (doTrafficMeasurement) {
try {
//try {
TrafficMeasurementManager.Instance.SimulationStep(segmentID, ref data);
} catch (Exception e) {
/*} catch (Exception e) {
Log.Error("Error occured while calculating lane traffic density: " + e.ToString());
}
}*/
}
}

try {
OriginalSimulationStep(segmentID, ref data);
} catch (Exception ex) {
Log.Error($"Error in CustomRoadAI.SimulationStep for segment {segmentID}: " + ex.ToString());
}
OriginalSimulationStep(segmentID, ref data);
}

public static void GetTrafficLightState(ushort vehicleId, ref Vehicle vehicleData, ushort nodeId, ushort fromSegmentId, byte fromLaneIndex, ushort toSegmentId, ref NetSegment segmentData, uint frame, out RoadBaseAI.TrafficLightState vehicleLightState, out RoadBaseAI.TrafficLightState pedestrianLightState) {
Expand Down
2 changes: 1 addition & 1 deletion TLM/TLM/Custom/AI/CustomShipAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vecto
#endif

/// NON-STOCK CODE START ///
ExtVehicleType vehicleType = VehicleStateManager.Instance._GetVehicleState(vehicleID).VehicleType;
ExtVehicleType vehicleType = VehicleStateManager.Instance.VehicleStates[VehicleStateManager.Instance.GetFrontVehicleId(vehicleID, ref vehicleData)].vehicleType;
if (vehicleType == ExtVehicleType.None) {
#if DEBUG
Log.Warning($"CustomShipAI.CustomStartPathFind: Vehicle {vehicleID} does not have a valid vehicle type!");
Expand Down
Loading

0 comments on commit ce52829

Please sign in to comment.