/// <summary> /// Add the spheres that prevent autopilot from getting stuck between objects. /// </summary> /// <remarks> /// For every cluster, adds a sphere that includes the centre of every sphere in the cluster. /// </remarks> public void AddMiddleSpheres() { for (int indexO = Clusters.Count - 1; indexO >= 0; indexO--) { List <RepulseSphere> cluster = Clusters[indexO]; if (cluster.Count < 2) { continue; } Vector3D[] points = new Vector3D[cluster.Count]; for (int indexI = cluster.Count - 1; indexI >= 0; indexI--) { points[indexI] = cluster[indexI].Centre; } BoundingSphereD sphere = BoundingSphereD.CreateFromPoints(points); RepulseSphere repulse = new RepulseSphere() { Centre = sphere.Center, FixedRadius = sphere.Radius }; #if DEBUG List <IMyEntity> entities; ResourcePool.Get(out entities); foreach (RepulseSphere rs in cluster) { entities.AddArray(rs.Entities); } repulse.Entities = entities.ToArray(); entities.Clear(); ResourcePool.Return(entities); #endif cluster.Add(repulse); } }
public void Add(ref RepulseSphere sphere) { List <RepulseSphere> joinedCluster = null; List <RepulseSphere> emptyCluster = null; for (int indexO = Clusters.Count - 1; indexO >= 0; indexO--) { List <RepulseSphere> cluster = Clusters[indexO]; if (cluster.Count == 0) { emptyCluster = cluster; continue; } for (int indexI = cluster.Count - 1; indexI >= 0; indexI--) { RepulseSphere checkSphere = cluster[indexI]; double distSq; Vector3D.DistanceSquared(ref sphere.Centre, ref checkSphere.Centre, out distSq); double radii = sphere.FixedRadius + checkSphere.FixedRadius; radii *= radii; if (distSq <= radii) { if (joinedCluster != null) { joinedCluster.AddList(cluster); cluster.Clear(); } else { joinedCluster = cluster; cluster.Add(sphere); } break; } } } if (joinedCluster == null) { if (emptyCluster != null) { emptyCluster.Add(sphere); } else { ResourcePool.Get(out joinedCluster); joinedCluster.Add(sphere); Clusters.Add(joinedCluster); } } }