using System.Collections; using System.Collections.Generic; using Unity.Entities; using UnityEngine; using System.Linq; using Unity.Mathematics; /* https://www.habrador.com/tutorials/interpolation/2-bezier-curve/ http://www.graphicfilth.com/2014/10/3d-bezier-curves-in-unity/ */ public class AirCorridorAuthoring : MonoBehaviour, IConvertGameObjectToEntity { [Header("CityBuilder WebApi")] public string Address = "localhost"; public int Port = 44378; public bool IsHttps = true; [Header("City")] public int CityId = 15; public double LatitudeOrigin; public double LongitudeOrigin; private EntityManager manager; ElementCity[] elements; CityBoundary boundary; public float DefaultHeight = 50; void Awake() { CityBuilderConnector.Initialize(Address, Port, IsHttps); elements = CityBuilderConnector.Instance.GetElements(CityId).Where(x => x.Element.Name == "DroneRoute").ToArray(); Debug.Log($"Drone routes: {elements.Count()}"); boundary = FindObjectOfType(); manager = World.DefaultGameObjectInjectionWorld.EntityManager; } public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) { GeoCoord geoOrigin; geoOrigin = new GeoCoord(LatitudeOrigin, LongitudeOrigin); for (int i = 0; i < elements.Length; i++) { var routeEntity = dstManager.CreateEntity(); #if UNITY_EDITOR dstManager.SetName(routeEntity, $"DroneRoute_{i}"); #endif //convert geo coords to XY Unity Coords var pathString = elements[i].Parameters.Where(x => x.Name == "Path").First().Value; var points = Deserialize2D(pathString); points = (points.Prepend( new float3(points[0].x, 0, points[0].z))).ToArray(); var beziers1 = elements[i].Parameters.Where(x => x.Name == "PathBezier1"); float3[] control1s = null; float3[] control2s = null; if (beziers1.Any()) { control1s = Deserialize3D(beziers1.First().Value); } var beziers2 = elements[i].Parameters.Where(x => x.Name == "PathBezier2"); if (beziers2.Any()) { control2s = Deserialize3D(beziers2.First().Value); } var buffer = dstManager.AddBuffer(routeEntity); buffer.ResizeUninitialized(points.Length); for (int x = 0; x < points.Length; x++) { buffer.ElementAt(x).Points = points[x]; buffer.ElementAt(x).Control1 = control1s[x]; buffer.ElementAt(x).Control2 = control2s[x]; } for (int u = 0; u < 1000; u++) { var droneEntity = dstManager.CreateEntity(); #if UNITY_EDITOR dstManager.SetName(droneEntity, $"Drone_{i}"); #endif dstManager.AddComponentData(droneEntity, new DroneComponent() { deltaPos = 0, position = points[0] }); } } } private float3[] Deserialize2D(string pathString) { var pathtuples = pathString.Split(':'); List pos3ds = new List(); foreach (var p in pathtuples) { var coord = p.Split(';'); // Lat, long, Height(optional) var geopos = boundary.GetMapCoord(float.Parse(coord[0]), float.Parse(coord[1])); if (coord.Length == 2) { pos3ds.Add(new Vector3(geopos.x, DefaultHeight, geopos.y)); } else { pos3ds.Add(new Vector3(geopos.x, float.Parse(coord[2]), geopos.y)); } } return pos3ds.ToArray(); } private float3[] Deserialize3D(string pathString) { var pathtuples = pathString.Split(':'); List pos3ds = new List(); foreach (var p in pathtuples) { var coord = p.Split(';'); // Lat, long var geopos = boundary.GetMapCoord(float.Parse(coord[0]), float.Parse(coord[1])); pos3ds.Add(new Vector3(geopos.x, float.Parse(coord[2]), geopos.y)); } return pos3ds.ToArray(); } }