using Gley.UrbanSystem.Internal; using UnityEngine; using UnityEngine.Jobs; namespace Gley.TrafficSystem.Internal { /// /// Computes relative positions between cars /// internal class VehiclePositioningSystem :IDestroyable { private TransformAccessArray allVehicles; private WaypointManager waypointManager; private TrafficWaypointsDataHandler _trafficWaypointsDataHandler; /// /// Setup method /// /// /// /// internal VehiclePositioningSystem (int nrOfCars, WaypointManager waypointManager, TrafficWaypointsDataHandler trafficWaypointsDataHandler) { Assign(); allVehicles = new TransformAccessArray(nrOfCars); this.waypointManager = waypointManager; _trafficWaypointsDataHandler = trafficWaypointsDataHandler; } public void Assign() { DestroyableManager.Instance.Register(this); } /// /// Checks which vehicle is in front /// /// index of the first vehicle to test /// index of the second vehicle to test /// returns true if index1 is in front of index2 internal int IsInFront(int index1, int index2) { if (waypointManager.IsSameTarget(index1, index2)) { //check closest distance if (Vector3.SqrMagnitude(allVehicles[index1].position - _trafficWaypointsDataHandler.GetPosition(waypointManager.GetTargetWaypointIndex(index1))) < Vector3.SqrMagnitude(allVehicles[index2].position - _trafficWaypointsDataHandler.GetPosition(waypointManager.GetTargetWaypointIndex(index2)))) { return 1; } else { return 2; } } else { int result = waypointManager.IsInFront(index1, index2); if (result == 0) { result = CheckAngles(index1, index2); } return result; } } /// /// Check if 2 vehicles are oriented in the same direction /// /// /// /// true if have the same orientation internal bool IsSameOrientation(Vector3 heading1, Vector3 heading2) { float dotResult = Vector3.Dot(heading1.normalized, heading2.normalized); if (dotResult > 0) { return true; } return false; } /// /// Check if 2 vehicles are going in the same direction /// /// /// /// true if vehicles go in the same direction internal bool IsSameHeading(Vector3 myHeading, Vector3 othervelocity) { float dotResult = Vector3.Dot(myHeading.normalized, othervelocity.normalized); if (dotResult > 0) { return true; } return false; } /// /// Update car list /// /// internal void AddCar(Transform vehicle) { allVehicles.Add(vehicle); } /// /// Get up vector of the car /// /// /// internal Vector3 GetUpVector(int index) { return allVehicles[index].up; } /// /// Get forward vector of the vehicle /// /// /// internal Vector3 GetForwardVector(int index) { return allVehicles[index].forward; } /// /// Get right vector of the vehicle /// /// /// internal Vector3 GetRightVector(int index) { return allVehicles[index].right; } /// /// Get vehicle position in world space /// /// /// internal Vector3 GetPosition(int index) { return allVehicles[index].position; } /// /// Check if the velocity and orientation is the same /// /// /// /// internal bool IsGoingForward(Vector3 velicity, Vector3 heading) { if (Vector3.Dot(velicity, heading) > -0.1f) { return true; } return false; } /// /// Used to check which vehicle is in front /// /// /// /// private int CheckAngles(int index1, int index2) { //compute angles between forward vectors and relative bot position float angle1 = Vector3.Angle(GetForwardVector(index1), GetPosition(index2) - GetPosition(index1)); float angle2 = Vector3.Angle(GetForwardVector(index2), GetPosition(index1) - GetPosition(index2)); //the small angle is in front if (angle1 > angle2) { return 1; } else { return 2; } } public void OnDestroy() { allVehicles.Dispose(); } } }