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();
}
}
}