public MyDynamicAABBTreeBroadphase() { m_DAABBTree = new MyDynamicAABBTree(new Vector3(MyPhysicsConfig.AABBExtension)); m_InteractionList = new List<MyRBElementInteraction>(256); m_overlapElementList = new List<MyElement>(256); }
public PlanetBiome(MyPlanetMaterialGroup group) { Value = group.Value; Name = group.Name; Rules = new List <PlanetMaterialRule>(group.MaterialRules.Length); for (int i = 0; i < group.MaterialRules.Length; i++) { Rules.Add(new PlanetMaterialRule(group.MaterialRules[i])); } MateriaTree = new MyDynamicAABBTree(Vector3.Zero); foreach (var rule in Rules) { BoundingBox bb = new BoundingBox(new Vector3(rule.Height.Min, rule.Latitude.Min, rule.Longitude.Min), new Vector3(rule.Height.Max, rule.Latitude.Max, rule.Longitude.Max)); MateriaTree.AddProxy(ref bb, rule, 0); if (rule.Latitude.Mirror) { float min = -bb.Max.Y; bb.Max.Y = -bb.Min.Y; bb.Min.Y = min; MateriaTree.AddProxy(ref bb, rule, 0); } } }
public void InitWriteCache(int prealloc = 128) { //Debug.Assert(m_cachedChunks == null, "Error: Cache already initialized"); disabled due to shared storages if (m_cachedChunks != null) { return; } if (OperationsComponent != null) { CachedWrites = true; } else { return; } m_cachedChunks = new MyConcurrentDictionary <Vector3I, VoxelChunk>(prealloc, Vector3I.Comparer); m_pendingChunksToWrite = new MyConcurrentQueue <Vector3I>(prealloc / 10); m_chunksbyAge = new MyQueue <Vector3I>(prealloc); m_cacheMap = new MyDynamicAABBTree(Vector3.Zero); m_cacheLock = new FastResourceLock(); OperationsComponent.Add(this); }
public ProceduralConstruction(ILogging logBase, ProceduralConstructionSeed seed) { Logger = logBase.Root().CreateProxy(GetType().Name); m_roomTree = new MyDynamicAABBTree(Vector3.Zero); m_rooms = new Dictionary <int, ProceduralRoom>(); m_mountPoints = new Dictionary <Vector3I, ProceduralMountPoint>(); m_roomsSafeOrder = new List <ProceduralRoom>(); Seed = seed; BlockSetInfo = new BlockSetInfo(); }
public MyCullableRenderObject(MyEntity entity) : base(entity, null) { CulledObjects = new MyDynamicAABBTree(MyRender.PrunningExtension); EntitiesContained = 0; for (int i = 0; i < Enum.GetValues(typeof(MyOcclusionQueryID)).Length; i++) { m_queries[i] = new MyOcclusionQueryIssue(this); m_queries[i].RenderType = MyOcclusionQueryRenderType.HWDepth; } m_queries[(int)MyOcclusionQueryID.MAIN_RENDER].RenderType = MyOcclusionQueryRenderType.CustomDepth; }
public MyCullableRenderObject(MyEntity entity) : base (entity, null) { CulledObjects = new MyDynamicAABBTree(MyRender.PrunningExtension); EntitiesContained = 0; for (int i = 0; i < Enum.GetValues(typeof(MyOcclusionQueryID)).Length; i++) { m_queries[i] = new MyOcclusionQueryIssue(this); m_queries[i].RenderType = MyOcclusionQueryRenderType.HWDepth; } m_queries[(int)MyOcclusionQueryID.MAIN_RENDER].RenderType = MyOcclusionQueryRenderType.CustomDepth; }
internal static int UpdateBvh(MyDynamicAABBTree bvh, LightId lid, bool enabled, int proxy, ref BoundingBox aabb) { if (enabled && proxy == -1) { return(bvh.AddProxy(ref aabb, lid, 0)); } else if (enabled && proxy != -1) { bvh.MoveProxy(proxy, ref aabb, Vector3.Zero); return(proxy); } else { bvh.RemoveProxy(proxy); } return(-1); }
public PlanetBiome(MyPlanetMaterialGroup group, float minimumSurfaceLayerDepth) { this.Value = group.Value; this.Name = group.Name; this.Rules = new List <MyPlanetMaterialProvider.PlanetMaterialRule>(group.MaterialRules.Length); for (int i = 0; i < group.MaterialRules.Length; i++) { this.Rules.Add(new MyPlanetMaterialProvider.PlanetMaterialRule(group.MaterialRules[i], i, minimumSurfaceLayerDepth)); } this.MateriaTree = new MyDynamicAABBTree(Vector3.Zero, 1f); foreach (MyPlanetMaterialProvider.PlanetMaterialRule rule in this.Rules) { BoundingBox aabb = new BoundingBox(new Vector3(rule.Height.Min, rule.Latitude.Min, rule.Longitude.Min), new Vector3(rule.Height.Max, rule.Latitude.Max, rule.Longitude.Max)); this.MateriaTree.AddProxy(ref aabb, rule, 0, true); if (rule.Latitude.Mirror) { float num2 = -aabb.Max.Y; aabb.Max.Y = -aabb.Min.Y; aabb.Min.Y = num2; this.MateriaTree.AddProxy(ref aabb, rule, 0, true); } } }
static void Init() { m_waypoints = new MyDynamicAABBTree(MyConstants.GAME_PRUNING_STRUCTURE_AABB_EXTENSION); m_others = new MyDynamicAABBTree(MyConstants.GAME_PRUNING_STRUCTURE_AABB_EXTENSION); }
internal static int UpdateBvh(MyDynamicAABBTree bvh, LightId lid, bool enabled, int proxy, ref BoundingBox aabb) { if(enabled && proxy == -1) { return bvh.AddProxy(ref aabb, lid, 0); } else if(enabled && proxy != -1) { bvh.MoveProxy(proxy, ref aabb, Vector3.Zero); return proxy; } else { bvh.RemoveProxy(proxy); } return -1; }
public PlanetBiome(MyPlanetMaterialGroup group) { Value = group.Value; Name = group.Name; Rules = new List<PlanetMaterialRule>(group.MaterialRules.Length); for (int i = 0; i < group.MaterialRules.Length; i++) { Rules.Add(new PlanetMaterialRule(group.MaterialRules[i])); } MateriaTree = new MyDynamicAABBTree(Vector3.Zero); foreach (var rule in Rules) { BoundingBox bb = new BoundingBox(new Vector3(rule.Height.Min, rule.Latitude.Min, rule.Longitude.Min), new Vector3(rule.Height.Max, rule.Latitude.Max, rule.Longitude.Max)); MateriaTree.AddProxy(ref bb, rule, 0); if (rule.Latitude.Mirror) { float min = -bb.Max.Y; bb.Max.Y = -bb.Min.Y; bb.Min.Y = min; MateriaTree.AddProxy(ref bb, rule, 0); } } }
private void AddSectorEntities(MySectorObjectCounts asteroidCounts, MyMwcVector3Int sectorPosition, Random random, float entityMinimalSize, int maxEntityCount, List<MySolarSystemMapEntity> entities, bool onlyStaticAsteroids) { // Space around asteroid should be at least 1.2x - 2x it's size float asteroidSpacingCoeficient = 0.7f; // Asteroid count mean is 40% float asteroidCountMean = 0.4f; Dictionary<int, int> entityCounts = new Dictionary<int, int>(); foreach (MySolarSystemEntityEnum t in Enum.GetValues(typeof(MySolarSystemEntityEnum))) { entityCounts.Add((int)t, 0); } MyDynamicAABBTree prunningStructure = new MyDynamicAABBTree(Vector3.Zero); foreach (BoundingSphere boundingSphere in m_safeAreas) { BoundingBox bb = BoundingBox.CreateFromSphere(boundingSphere); prunningStructure.AddProxy(ref bb, new Render.MyRenderObject(null, null), 0); } // Generate asteroids, check collisions (order asteroids by size) //var asteroids = GetAsteroids(asteroidCounts, entityMinimalSize); var asteroids = GetAsteroids(asteroidCounts, entityMinimalSize); foreach (var info in asteroids) { if (info.EntityType != MySolarSystemEntityEnum.StaticAsteroid && onlyStaticAsteroids) continue; float radius = info.SizeInMeters / 2; float count = info.ObjectCount; float positionOffset = 1.3f; count = (float)Math.Round(count * random.Float(1 - asteroidCountMean, 1 + asteroidCountMean)); if (info.EntityType == MySolarSystemEntityEnum.VoxelAsteroid) { positionOffset = 0.6f; //generate voxels more in center } while (entityCounts[(int)info.EntityType] < count && entityCounts[(int)info.EntityType] < maxEntityCount) { Vector3? pos = FindEntityPosition(prunningStructure, random, radius, positionOffset, asteroidSpacingCoeficient); if (pos.HasValue) { MySolarSystemMapEntity entity = new MySolarSystemMapEntity(sectorPosition, pos.Value, info.SizeInMeters, info.EntityType.ToString(), info.EntityType); entities.Add(entity); if (!MySectorGenerator.IsOutsideSector(pos.Value, radius)) { entityCounts[(int)info.EntityType]++; } BoundingBox bb = new BoundingBox(pos.Value - new Vector3(radius), pos.Value + new Vector3(radius)); prunningStructure.AddProxy(ref bb, new Render.MyRenderObject(null, null), 0); } else entityCounts[(int)info.EntityType]++; } } }
/// <summary> /// Create and connect waypoints to enable navigation outside prefab containers. /// Needs to be called from the main thread (because it uses MyEntities.GetSafeIterationHelperForAll). /// </summary> public static void CreateWaypointsAroundLargeStaticObjects() { if (m_GPSWaypointsInited) return; MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("CreateWaypointsAroundLargeStaticObjects"); // memory benchmark //GC.Collect(2); //MyMwcLog.WriteLine("#CreateWaypointsAroundLargeStaticObjects# before: working set " + MyValueFormatter.GetFormatedLong(Environment.WorkingSet) + ", gc " + MyValueFormatter.GetFormatedLong(GC.GetTotalMemory(false))); // counters for debugging int largeObjects = 0; int totalWaypointsOutside = 0; int bigSubdivisions = 0; int freeEnvelopes = 0; int edgesWithoutRaycasts = 0; int edgesWithRaycastsAdded = 0; int edgesWithRaycastsNotAdded = 0; int closed = 0; var envelopes = new List<MyWayPoint[, ,]>(); var envelopeEntity = new List<MyEntity>(); var envelopeBvh = new MyDynamicAABBTree(MyConstants.GAME_PRUNING_STRUCTURE_AABB_EXTENSION); var nonFree = new HashSet<MyWayPoint>(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("create envelopes"); var interestingBoxInflation = new Vector3(MyWaypointConstants.MAXIMUM_BOX_DISTANCE_TO_INTERESTING_STUFF_TO_GENERATE_WAYPOINTS); var interestingBoxes = new List<BoundingBox>(); // find interesting stuff (only prefab containers for now) foreach (var entity in MyEntities.GetEntities()) { if (!(entity is MyPrefabContainer)) continue; entity.UpdateAABBHr(); BoundingBox box = entity.WorldAABBHr; if (box.Max - box.Min == Vector3.Zero) { box = entity.WorldAABB; if (box.Max - box.Min == Vector3.Zero) continue; // no bounding box } BoundingBox extrudedBox = new BoundingBox(box.Min - interestingBoxInflation, box.Max + interestingBoxInflation); interestingBoxes.Add(extrudedBox); } int ss = 0; int madelynsBox = -1; // create envelopes foreach (var entity in MyEntities.GetSafeIterationHelperForAll()) { if (!(entity is MyVoxelMap || entity is MyPrefabContainer || entity is MyStaticAsteroid)) continue; entity.UpdateAABBHr(); BoundingBox box = entity.WorldAABBHr; if (box.Max - box.Min == Vector3.Zero) box = entity.WorldAABB; if (entity is MyStaticAsteroid && (box.Max - box.Min).LengthSquared() < MyWaypointConstants.MINIMUM_ASTEROID_DIAGONAL_LENGTH_TO_GENERATE_WAYPOINTS * MyWaypointConstants.MINIMUM_ASTEROID_DIAGONAL_LENGTH_TO_GENERATE_WAYPOINTS) { continue; // small static asteroids: ignore } if (entity is MyStaticAsteroid) { ss++; bool inInteresting = false; foreach (var iBox in interestingBoxes) { if (iBox.Contains(box) != ContainmentType.Disjoint) { inInteresting = true; break; } } if (!inInteresting) continue; // static asteroids far from interesting stuff: ignore } // enlarge by 1% and 15 meters on each side BoundingBox extrudedBox = new BoundingBox(box.Min - (box.Max - box.Min) * 0.01f - new Vector3(15, 15, 15), box.Max + (box.Max - box.Min) * 0.01f + new Vector3(15, 15, 15)); //diagonals.Add((float)Math.Sqrt((box.Max - box.Min).LengthSquared())); var waypointsOutside = new HashSet<MyWayPoint>(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("find crossing"); // add all edges that cross the non-extruded box from inside to outside (remember out-vertices) foreach (var waypoint in MyGamePruningStructure.GetAllEntitiesInBox(ref extrudedBox, MyGamePruningStructure.QueryFlags.Waypoints)) { var v = waypoint as MyWayPoint; if (!v.Save) continue; nonFree.Add(v); using (MyWayPoint.NeighborsLock.AcquireSharedUsing()) { foreach (var n in v.Neighbors) if (n.Save && extrudedBox.Contains(n.Position) != ContainmentType.Contains) { if (waypointsOutside.Add(n)) totalWaypointsOutside++; nonFree.Add(n); } } } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); // create envelope int s = 1; if (waypointsOutside.Count > 0 || entity as MyStaticAsteroid == null) // voxel maps and prefabs are automatically subdivided more { s = 2; bigSubdivisions++; } MyWayPoint[, ,] envelope = new MyWayPoint[s + 1, s + 1, s + 1]; for (int i = 0; i <= s; i++) for (int j = 0; j <= s; j++) for (int k = 0; k <= s; k++) { if (s == 2 && i == 1 && j == 1 && k == 1) continue; envelope[i, j, k] = CreateWaypoint(new Vector3( extrudedBox.Min.X + i * (extrudedBox.Max.X - extrudedBox.Min.X) / s, extrudedBox.Min.Y + j * (extrudedBox.Max.Y - extrudedBox.Min.Y) / s, extrudedBox.Min.Z + k * (extrudedBox.Max.Z - extrudedBox.Min.Z) / s ), null); envelope[i, j, k].Save = false; // don't save generated waypoints nonFree.Add(envelope[i, j, k]); // connect with neighbors // use ConnectIfNoAABBBlockers only for non-static asteroids // don't connect to the non-existing middle vertex if (entity is MyStaticAsteroid) { if (i != 0) if (!(s == 2 && i - 1 == 1 && j == 1 && k == 1)) { MyWayPoint.Connect(envelope[i, j, k], envelope[i - 1, j, k]); edgesWithoutRaycasts++; } if (j != 0) if (!(s == 2 && j - 1 == 1 && i == 1 && k == 1)) { MyWayPoint.Connect(envelope[i, j, k], envelope[i, j - 1, k]); edgesWithoutRaycasts++; } if (k != 0) if (!(s == 2 && k - 1 == 1 && j == 1 && i == 1)) { MyWayPoint.Connect(envelope[i, j, k], envelope[i, j, k - 1]); edgesWithoutRaycasts++; } } else { if (i != 0) if (!(s == 2 && i - 1 == 1 && j == 1 && k == 1)) { if (MyWayPoint.ConnectIfNoAABBBlockers(envelope[i, j, k], envelope[i - 1, j, k])) edgesWithRaycastsAdded++; else edgesWithRaycastsNotAdded++; } if (j != 0) if (!(s == 2 && j - 1 == 1 && i == 1 && k == 1)) { if (MyWayPoint.ConnectIfNoAABBBlockers(envelope[i, j, k], envelope[i, j - 1, k])) edgesWithRaycastsAdded++; else edgesWithRaycastsNotAdded++; } if (k != 0) if (!(s == 2 && k - 1 == 1 && j == 1 && i == 1)) { if (MyWayPoint.ConnectIfNoAABBBlockers(envelope[i, j, k], envelope[i, j, k - 1])) edgesWithRaycastsAdded++; else edgesWithRaycastsNotAdded++; } } // if it's a part of a face that faces an out-vertex, connect it foreach (var v in waypointsOutside) if ((i == 0 && v.Position.X <= envelope[i, j, k].Position.X) || (i == s && v.Position.X >= envelope[i, j, k].Position.X) || (j == 0 && v.Position.Y <= envelope[i, j, k].Position.Y) || (j == s && v.Position.Y >= envelope[i, j, k].Position.Y) || (k == 0 && v.Position.Z <= envelope[i, j, k].Position.Z) || (k == s && v.Position.Z >= envelope[i, j, k].Position.Z) ) { if (MyWayPoint.ConnectIfNoAABBBlockers(v, envelope[i, j, k])) edgesWithRaycastsAdded++; else edgesWithRaycastsNotAdded++; } } envelopes.Add(envelope); envelopeEntity.Add(entity); envelopeBvh.AddProxy(ref extrudedBox, envelopes.Count - 1, 0); largeObjects++; if (entity.Name == "Madelyn") { madelynsBox = envelopes.Count - 1; } } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); var componentsDone = new HashSet<int>(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("connect free wps"); // free waypoint: check whether it's connected to an envelope foreach (var v in GetVertexListForModification()) if (!nonFree.Contains(v)) { int id = GetConnectedComponentId(v); if (componentsDone.Contains(id)) continue; componentsDone.Add(id); var connectedWaypoints = GetWaypointsWithConnectedComponentId(id); // is this component already connected to an envelope? var box = new BoundingBox(v.Position, v.Position); foreach (var w in connectedWaypoints) if (w.Save) { var pos = w.Position; box = box.Include(ref pos); if (nonFree.Contains(w)) goto alreadyConnected; } BoundingBox extrudedBox = new BoundingBox(box.Min - (box.Max - box.Min) * 0.01f - new Vector3(5, 5, 5), box.Max + (box.Max - box.Min) * 0.01f + new Vector3(5, 5, 5)); // no - create a new one int s = 1; MyWayPoint[, ,] envelope = new MyWayPoint[s + 1, s + 1, s + 1]; for (int i = 0; i <= s; i++) for (int j = 0; j <= s; j++) for (int k = 0; k <= s; k++) { envelope[i, j, k] = CreateWaypoint(new Vector3( extrudedBox.Min.X + i * (extrudedBox.Max.X - extrudedBox.Min.X) / s, extrudedBox.Min.Y + j * (extrudedBox.Max.Y - extrudedBox.Min.Y) / s, extrudedBox.Min.Z + k * (extrudedBox.Max.Z - extrudedBox.Min.Z) / s ), null); envelope[i, j, k].Save = false; // don't save generated waypoints nonFree.Add(envelope[i, j, k]); // connect with neighbors // should use ConnectIfVisible, but it's slow and we can resolve it while computing the GPS if (i != 0) { if (MyWayPoint.ConnectIfNoAABBBlockers(envelope[i, j, k], envelope[i - 1, j, k])) edgesWithRaycastsAdded++; else edgesWithRaycastsNotAdded++; } if (j != 0) { if (MyWayPoint.ConnectIfNoAABBBlockers(envelope[i, j, k], envelope[i, j - 1, k])) edgesWithRaycastsAdded++; else edgesWithRaycastsNotAdded++; } if (k != 0) { if (MyWayPoint.ConnectIfNoAABBBlockers(envelope[i, j, k], envelope[i, j, k - 1])) edgesWithRaycastsAdded++; else edgesWithRaycastsNotAdded++; } } // connect all waypoints to the closest corner of the new envelope foreach (var w in connectedWaypoints) { var pos = w.Position; if (MyWayPoint.ConnectIfNoAABBBlockers(w, envelope[pos.X < extrudedBox.GetCenter().X ? 0 : 1, pos.Y < extrudedBox.GetCenter().Y ? 0 : 1, pos.Z < extrudedBox.GetCenter().Z ? 0 : 1])) edgesWithRaycastsAdded++; else edgesWithRaycastsNotAdded++; } envelopes.Add(envelope); envelopeEntity.Add(null); envelopeBvh.AddProxy(ref extrudedBox, envelopes.Count - 1, 0); freeEnvelopes++; alreadyConnected: { } } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("connect envelopes"); // connect envelopes together for (int eIndex = 0; eIndex < envelopes.Count; eIndex++) { var e = envelopes[eIndex]; int es = e.GetLength(0) - 1; var eCenter = 0.5f * (e[0, 0, 0].Position + e[es, es, es].Position); // get K closest indices var closestEnvelopeIndices = new List<int>(); for (int i = 200; i <= 6400; i *= 2) // try 200, 400, 800, 1600, 3200, 6400 m { var halfExtent = new Vector3(i); var bbox = new BoundingBox(eCenter - halfExtent, eCenter + halfExtent); envelopeBvh.OverlapAllBoundingBox(ref bbox, closestEnvelopeIndices); if (closestEnvelopeIndices.Count >= 16) break; } // connect them together int k = 0; foreach (var qIndex in closestEnvelopeIndices) { if (++k == 16) break; // take only 16 envelopes if (qIndex == eIndex) continue; var q = envelopes[qIndex]; int qs = q.GetLength(0) - 1; var qCenter = 0.5f * (q[0, 0, 0].Position + q[qs, qs, qs].Position); // connect the closest opposite vertices int qx, qy, qz, ex, ey, ez; if (qCenter.X < eCenter.X) { qx = qs; ex = 0; } else { qx = 0; ex = es; } if (qCenter.Y < eCenter.Y) { qy = qs; ey = 0; } else { qy = 0; ey = es; } if (qCenter.Z < eCenter.Z) { qz = qs; ez = 0; } else { qz = 0; ez = es; } if (es > 1 || qs > 1) { if (MyWayPoint.ConnectIfNoAABBBlockers(e[ex, ey, ez], q[qx, qy, qz], envelopeEntity[eIndex], envelopeEntity[qIndex])) edgesWithRaycastsAdded++; else edgesWithRaycastsNotAdded++; } else { // don't make a raycast if one of the envelopes isn't important MyWayPoint.Connect(e[ex, ey, ez], q[qx, qy, qz]); edgesWithoutRaycasts++; } // connect Madelyn's waypoint to envelopes if (eIndex == madelynsBox) { MyEntity madelyn = envelopeEntity[madelynsBox]; foreach (var child in madelyn.Children) { var w = child as MyWayPoint; if (w == null) continue; MyWayPoint.ConnectIfNoAABBBlockers(w, q[qx, qy, qz]); // make a raycast } } } // connect Madelyn's waypoint to envelopes if (eIndex == madelynsBox) { MyEntity madelyn = envelopeEntity[madelynsBox]; madelyn.UpdateAABBHr(); BoundingBox extrudedAABB = madelyn.WorldAABBHr; extrudedAABB.Min -= new Vector3(500); extrudedAABB.Max += new Vector3(500); List<MyWayPoint> nearMadelynWaypoints = new List<MyWayPoint>(); foreach (var waypoint in MyGamePruningStructure.GetAllEntitiesInBox(ref extrudedAABB, MyGamePruningStructure.QueryFlags.Waypoints)) { MyWayPoint v = waypoint as MyWayPoint; if (v != null) { if (!v.Save) continue; nearMadelynWaypoints.Add(v); } } foreach (var child in madelyn.Children) { var w = child as MyWayPoint; if (w == null) continue; foreach (MyWayPoint v in nearMadelynWaypoints) { MyWayPoint.ConnectIfVisible(w, v); // make a raycast } } } } // delete generated waypoints without edges foreach (var v in GetVertexListForModification()) { if (!v.Save && v.Neighbors.Count == 0) { v.MarkForClose(); closed++; } } m_GPSWaypointsInited = true; InvalidateStoredPathCache(); // memory benchmark //GC.Collect(2); //MyMwcLog.WriteLine("#CreateWaypointsAroundLargeStaticObjects# after: working set " + MyValueFormatter.GetFormatedLong(Environment.WorkingSet) + ", gc " + MyValueFormatter.GetFormatedLong(GC.GetTotalMemory(false))); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); }
public void DoWork() { // Search for target to attack ClosestEnemy = null; ClosestVisual = null; float distanceSqr = m_seeDistance * m_seeDistance; float closestEnemyDistanceSqr = float.PositiveInfinity; float closestVisualDistanceSqr = float.PositiveInfinity; using (var rbFounded = PoolList <MyRBElement> .Get()) { try { MyEntities.EntityCloseLock.AcquireShared(); MyDynamicAABBTree prunningStructure = MyPhysics.physicsSystem.GetRigidBodyModule().GetPruningStructure(); BoundingBox rbInputElementGetWorldSpaceAABB = new BoundingBox( m_botWorldMatrix.Translation - new Vector3(m_seeDistance), m_botWorldMatrix.Translation + new Vector3(m_seeDistance)); prunningStructure.OverlapAllBoundingBox(ref rbInputElementGetWorldSpaceAABB, rbFounded, (uint)MyElementFlag.EF_RB_ELEMENT); //now try find spot foreach (MyRBElement rb in rbFounded) { if (m_bot == null) { return; } var rigidBody = rb.GetRigidBody(); if (rigidBody == null) { continue; } MyEntity entity = ((MyPhysicsBody)rigidBody.m_UserData).Entity; if (entity == m_bot || entity == null || entity.AIPriority == -1) { continue; } entity = entity.GetBaseEntity(); // Large weapons // Ignore spoiled holograms if (m_bot.IsSpoiledHologram(entity)) { continue; } // Don't attack disabled weapons MyPrefabLargeWeapon largeWeapon = entity as MyPrefabLargeWeapon; MySmallShip smallShip = entity as MySmallShip; MyPrefabLargeShip largeShip = entity as MyPrefabLargeShip; if (largeWeapon != null && !largeWeapon.IsWorking()) { continue; } // Test smallships and largeweapons if (smallShip != null || largeWeapon != null || largeShip != null) { // Is enemy? if (MyFactions.GetFactionsRelation(m_bot, entity) == MyFactionRelationEnum.Enemy && CanSeeTarget(m_bot, entity)) { var entityDistanceSqr = Vector3.DistanceSquared(entity.GetPosition(), m_position); if (entityDistanceSqr < distanceSqr && (ClosestEnemy == null || entity.AIPriority >= ClosestEnemy.AIPriority) && (entityDistanceSqr < closestEnemyDistanceSqr || entity.AIPriority > ClosestEnemy.AIPriority)) { MyLine line = new MyLine(m_position, entity.GetPosition(), true); var result = MyEntities.GetIntersectionWithLine(ref line, m_bot, entity, true, ignoreChilds: true); if (!result.HasValue) { // Visual Detection - ignore visualy detected targets if they are further than any normaly detected target if (IsVisualyDetected(smallShip)) { if (entityDistanceSqr < closestVisualDistanceSqr) { ClosestVisual = entity; closestVisualDistanceSqr = entityDistanceSqr; } } else { closestEnemyDistanceSqr = entityDistanceSqr; ClosestEnemy = entity; } } } } } } } finally { MyEntities.EntityCloseLock.ReleaseShared(); } } }
/// <summary> /// /// </summary> /// <param name="existingEntities"></param> /// <param name="rnd"></param> /// <param name="radius"></param> /// <param name="positionMultiplier">How far from offset shoud be position generated</param> /// <param name="spacing"></param> /// <param name="offset"></param> /// <returns></returns> private Vector3? FindEntityPosition(MyDynamicAABBTree existingEntities, Random rnd, float radius, float positionMultiplier = 0.8f, float spacing = 1.0f, Vector3 offset = new Vector3()) { bool collide = true; Vector3 pos = new Vector3(); int testCount = 0; //collide = false; Vector3 halfSize = MyMwcSectorConstants.SECTOR_SIZE / 2.0f * new Vector3(positionMultiplier); halfSize -= new Vector3(radius); while (collide && testCount < MaxCollisionsTestsForEntity) { pos = offset + rnd.Vector(halfSize); testCount++; collide = false; // try detect collisions with safe areas // collide = IsEntityCollideWithSafeAreas(pos, radius); //if (collide) // continue; /* foreach (var e in existingEntities) { if ((e.PositionInSector - pos).Length() < (e.Radius + radius) * spacing) { collide = true; break; } } */ BoundingBox bb = new BoundingBox(pos - new Vector3(radius) * spacing, pos + new Vector3(radius) * spacing); existingEntities.OverlapAllBoundingBox(ref bb, m_elements); if (m_elements.Count > 0) { collide = true; continue; } } return !collide ? (Vector3?)pos : null; }
public MySolarSystemMapSectorData GenerateSectorObjectBuilders(MyMwcVector3Int sector, MySolarSystemMapData solarData, List<MyMwcObjectBuilder_Base> addToList, bool onlyStaticAsteroids) { MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("GenerateSectorEntities"); var sectorData = GenerateSectorEntities(solarData, sector, 0, int.MaxValue, onlyStaticAsteroids); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); MyDynamicAABBTree prunningStructure = new MyDynamicAABBTree(Vector3.Zero); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Misc"); MyWeightDictionary<MyMwcVoxelMaterialsEnum> primaryMaterials; MyWeightDictionary<MyMwcVoxelMaterialsEnum> secondaryMaterials; MyMwcObjectBuilder_Sector sectorBuilder = addToList.FirstOrDefault(s => s.GetObjectBuilderType() == MyMwcObjectBuilderTypeEnum.Sector) as MyMwcObjectBuilder_Sector; if (sectorBuilder == null) { sectorBuilder = GetSectorBuilder(sectorData); addToList.Add(sectorBuilder); } //if (sectorBuilder != null) //{ // Vector3 kms = MySolarSystemUtils.SectorsToKm(sectorData.SectorPosition); // sectorBuilder.SunDistance = kms.Length(); //} MySector.Area = sectorData.Area; MinerWars.AppCode.Game.SolarSystem.MySolarSystemArea.AreaEnum? areaType = null; MyMwcVoxelMaterialsEnum? secondaryAsteroidMaterial = null; if (sectorData.Area.HasValue && sectorBuilder != null) { var area = MySolarSystemConstants.Areas[sectorData.Area.Value]; areaType = area.AreaType; secondaryAsteroidMaterial = area.SecondaryStaticAsteroidMaterial; primaryMaterials = new MyWeightDictionary<MyMwcVoxelMaterialsEnum>(area.SectorData.PrimaryAsteroidMaterials); secondaryMaterials = new MyWeightDictionary<MyMwcVoxelMaterialsEnum>(area.SectorData.SecondaryAsteroidMaterials); } else { primaryMaterials = new MyWeightDictionary<MyMwcVoxelMaterialsEnum>(MySolarSystemConstants.DefaultAsteroidMaterials); secondaryMaterials = new MyWeightDictionary<MyMwcVoxelMaterialsEnum>(MySolarSystemConstants.DefaultSecondaryMaterials); } Random rnd = new Random(m_seed); MyStaticAsteroidTypeSetEnum staticAsteroidsTypeset = MyStaticAsteroidTypeSetEnum.A | MyStaticAsteroidTypeSetEnum.B; var realSizes = sectorData.Entities.GroupBy(s => s.Radius).Select(s => new { Key = s.Key, Count = s.Count() }).ToArray(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("GenerateSectorObjectBuildersFromSolarEntities"); GenerateSectorObjectBuildersFromSolarEntities(sectorData.Entities, addToList, rnd, primaryMaterials, secondaryMaterials, staticAsteroidsTypeset, secondaryAsteroidMaterial, areaType); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); if (!onlyStaticAsteroids) { MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("GenerateStations"); GenerateStations(sector, solarData, sectorData, addToList, rnd, prunningStructure); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("GenerateBots"); GenerateBots(sectorData, addToList, rnd, prunningStructure); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); } return sectorData; }
private void GenerateStations(MyMwcVector3Int sector, MySolarSystemMapData solarData, MySolarSystemMapSectorData sectorData, List<MyMwcObjectBuilder_Base> addToList, Random rnd, MyDynamicAABBTree prunningStructure) { Dictionary<MyMwcVector3Int, MyMwcObjectBuilder_SectorObjectGroups> groupCache = new Dictionary<MyMwcVector3Int, MyMwcObjectBuilder_SectorObjectGroups>(); //List<MyImportantSolarObject> var objects = solarData.ImportantObjects.Where(o => o.NavigationMark.Sector.Equals(sector)); foreach(var obj in objects) { var size = MyPrefabContainerConstants.MAX_DISTANCE_FROM_CONTAINER_CENTER / 1000; Vector3? pos = FindEntityPosition(prunningStructure, rnd, size); if (pos.HasValue) { var templateSector = MyTemplateGroups.GetGroupSector(obj.TemplateGroup); MyMwcObjectBuilder_SectorObjectGroups groups; if (!groupCache.TryGetValue(templateSector, out groups)) { groups = LoadObjectGroups(templateSector); if (groups == null) { return; } groupCache.Add(templateSector, groups); } sectorData.Entities.Add(new MySolarSystemMapEntity(sector, pos.Value, size, "", MySolarSystemEntityEnum.OutpostIcon)); var group = rnd.Item(groups.Groups); IEnumerable<MyMwcObjectBuilder_PrefabBase> prefabs = group.GetPrefabBuilders(groups.Entities); IEnumerable<MyMwcObjectBuilder_Base> rootObjects = group.GetRootBuilders(groups.Entities); var objects3d = rootObjects.OfType<MyMwcObjectBuilder_Object3dBase>(); var faction = MyFactions.GetFactionBySector(sector); var objectPos = pos.Value; if (objects3d.Any()) { var firstPos = objects3d.First().PositionAndOrientation.Position; var offset = objectPos - firstPos; foreach (var o in objects3d) { // Clone var clone = o.Clone() as MyMwcObjectBuilder_Object3dBase; clone.PositionAndOrientation.Position += offset; clone.ClearEntityId(); if (clone is MyMwcObjectBuilder_PrefabContainer) { ((MyMwcObjectBuilder_PrefabContainer)clone).Faction = faction; } if (clone is MyMwcObjectBuilder_SpawnPoint) { ((MyMwcObjectBuilder_SpawnPoint)clone).Faction = faction; } addToList.Add(clone); } } else if(prefabs.Any()) { MyMwcObjectBuilder_PrefabContainer container = new MyMwcObjectBuilder_PrefabContainer(null, MyMwcObjectBuilder_PrefabContainer_TypesEnum.INSTANCE, prefabs.ToList(), 0, faction, null); var clone = container.Clone() as MyMwcObjectBuilder_PrefabContainer; // To clone children easily clone.ClearEntityId(); // Clear childs ids clone.PositionAndOrientation = new MyMwcPositionAndOrientation(objectPos, Vector3.Forward, Vector3.Up); addToList.Add(clone); } } //end of station generation if (pos.HasValue && rnd.Float(0, 1) < 0.5f) { //Create mysterious cube at 1% of stations var sizeMyst = size * 1.5f; Vector3? posMyst = FindEntityPosition(prunningStructure, rnd, sizeMyst, 1.0f, 1.0f, pos.Value); if (posMyst.HasValue) { CreateMysteriousCubes(posMyst.Value, addToList, rnd); } //Create some more int count = rnd.Next(5); for (int i = 0; i < count; i++) { var size2 = MyMwcSectorConstants.SECTOR_SIZE / 2; Vector3? pos2 = FindEntityPosition(prunningStructure, rnd, size2); if (pos2.HasValue) { CreateMysteriousCubes(pos2.Value, addToList, rnd); } } } } }
private void GenerateBots(MySolarSystemMapSectorData sectorData, List<MyMwcObjectBuilder_Base> addToList, Random rnd, MyDynamicAABBTree prunningStructure) { int spawnPt = (int)(rnd.Float(0, 50) /** sectorData.AreaInfluenceMultiplier*/ ); float radius = 100; for (int i = 0; i < spawnPt; i++) { Vector3? pos = FindEntityPosition(prunningStructure, rnd, radius, 0.8f, 0.8f); if (pos.HasValue) { //MyMwcObjectBuilder_FactionEnum faction = MyMwcObjectBuilder_FactionEnum.None; var faction = MyFactions.GetFactionBySector(sectorData.SectorPosition); //var builder = new MyMwcObjectBuilder_; MyMwcObjectBuilder_SpawnPoint spobj = MyMwcObjectBuilder_Base.CreateNewObject(MyMwcObjectBuilderTypeEnum.SpawnPoint, null) as MyMwcObjectBuilder_SpawnPoint; spobj.BoundingRadius = radius; spobj.RespawnTimer = 1; spobj.SpawnCount = 5; spobj.PositionAndOrientation.Position = pos.Value; spobj.PositionAndOrientation.Forward = Vector3.Forward; spobj.PositionAndOrientation.Up = Vector3.Up; spobj.Faction = faction; List<MyMwcObjectBuilder_SmallShip_Weapon> weapons = new List<MyMwcObjectBuilder_SmallShip_Weapon>(); List<MyMwcObjectBuilder_SmallShip_Ammo> ammo = new List<MyMwcObjectBuilder_SmallShip_Ammo>(); List<MyMwcObjectBuilder_AssignmentOfAmmo> assignments = new List<MyMwcObjectBuilder_AssignmentOfAmmo>(); weapons.Add(new MyMwcObjectBuilder_SmallShip_Weapon(MyMwcObjectBuilder_SmallShip_Weapon_TypesEnum.Autocanon)); weapons.Add(new MyMwcObjectBuilder_SmallShip_Weapon(MyMwcObjectBuilder_SmallShip_Weapon_TypesEnum.Autocanon)); weapons.Add(new MyMwcObjectBuilder_SmallShip_Weapon(MyMwcObjectBuilder_SmallShip_Weapon_TypesEnum.Cannon)); weapons.Add(new MyMwcObjectBuilder_SmallShip_Weapon(MyMwcObjectBuilder_SmallShip_Weapon_TypesEnum.Cannon)); weapons.Add(new MyMwcObjectBuilder_SmallShip_Weapon(MyMwcObjectBuilder_SmallShip_Weapon_TypesEnum.Shotgun)); weapons.Add(new MyMwcObjectBuilder_SmallShip_Weapon(MyMwcObjectBuilder_SmallShip_Weapon_TypesEnum.Drilling_Device_Crusher)); weapons.Add(new MyMwcObjectBuilder_SmallShip_Weapon(MyMwcObjectBuilder_SmallShip_Weapon_TypesEnum.Universal_Launcher_Front)); assignments.Add(new MyMwcObjectBuilder_AssignmentOfAmmo(MyMwcObjectBuilder_FireKeyEnum.Primary, MyMwcObjectBuilder_AmmoGroupEnum.Bullet, MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Autocannon_Basic)); assignments.Add(new MyMwcObjectBuilder_AssignmentOfAmmo(MyMwcObjectBuilder_FireKeyEnum.Secondary, MyMwcObjectBuilder_AmmoGroupEnum.Cannon, MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_Basic)); List<MyMwcObjectBuilder_InventoryItem> inventoryItems = new List<MyMwcObjectBuilder_InventoryItem>(); inventoryItems.Add(new MyMwcObjectBuilder_InventoryItem(new MyMwcObjectBuilder_SmallShip_Ammo(MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Autocannon_Basic), 1000f)); inventoryItems.Add(new MyMwcObjectBuilder_InventoryItem(new MyMwcObjectBuilder_SmallShip_Ammo(MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_Basic), 25)); //spobj.m_shipTemplates.Add( int numships = rnd.Next(1, 10); for (int x = 0; x < numships; x++) { spobj.ShipTemplates.Add( //new MyMwcObjectBuilder_SmallShip_Bot( // MyMwcObjectBuilder_SmallShip_TypesEnum.LIBERATOR, // weapons, // new MyMwcObjectBuilder_SmallShip_Engine(MyMwcObjectBuilder_SmallShip_Engine_TypesEnum.Chemical_1), // ammo, // assignments, // null, // faction // ) as MyMwcObjectBuilder_SmallShip_Bot new MyMwcObjectBuilder_SmallShip_Bot( MyMwcObjectBuilder_SmallShip_TypesEnum.LIBERATOR, new MyMwcObjectBuilder_Inventory(inventoryItems, 32), weapons, new MyMwcObjectBuilder_SmallShip_Engine(MyMwcObjectBuilder_SmallShip_Engine_TypesEnum.Chemical_1), assignments, null, null, null, MyGameplayConstants.HEALTH_RATIO_MAX, 100f, float.MaxValue, float.MaxValue, true, false, faction, MyAITemplateEnum.DEFAULT, 0, 1000, 1000, MyPatrolMode.CYCLE, null, BotBehaviorType.IDLE, MyLightsConstants.MAX_SPOTLIGHT_SHADOW_RANGE, 0, false, true) as MyMwcObjectBuilder_SmallShip_Bot ); } addToList.Add(spobj); /* MySolarSystemMapEntity entity = new MySolarSystemMapEntity(sectorData.SectorPosition, pos, size, "Asteroid", MySolarSystemEntityEnum.Asteroid); sectorData.Entities.Add(entity); */ } } }
public void InitWriteCache(int prealloc = 128) { //Debug.Assert(m_cachedChunks == null, "Error: Cache already initialized"); disabled due to shared storages if (m_cachedChunks != null) return; if (OperationsComponent != null) CachedWrites = true; else return; m_cachedChunks = new MyConcurrentDictionary<Vector3I, VoxelChunk>(prealloc, Vector3I.Comparer); m_pendingChunksToWrite = new MyConcurrentQueue<Vector3I>(prealloc / 10); m_chunksbyAge = new MyQueue<Vector3I>(prealloc); m_cacheMap = new MyDynamicAABBTree(Vector3.Zero); m_cacheLock = new FastResourceLock(); OperationsComponent.Add(this); }
/// <summary> /// Create and connect waypoints to enable navigation outside prefab containers. /// Needs to be called from the main thread (because it uses MyEntities.GetSafeIterationHelperForAll). /// </summary> public static void RecreateWaypointsAroundMadelyn() { MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("RecreateWaypointsAroundMadelyn"); // counters for debugging int largeObjects = 0; int totalWaypointsOutside = 0; int bigSubdivisions = 0; int closed = 0; var envelopes = new List<MyWayPoint[, ,]>(); var envelopeEntity = new List<MyEntity>(); var envelopeBvh = new MyDynamicAABBTree(MyConstants.GAME_PRUNING_STRUCTURE_AABB_EXTENSION); var nonFree = new HashSet<MyWayPoint>(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("create envelope"); int madelynsBox = -1; // create envelopes { var entity = MyEntities.GetEntityByName("Madelyn"); entity.UpdateAABBHr(); BoundingBox box = entity.WorldAABBHr; if (box.Max - box.Min == Vector3.Zero) box = entity.WorldAABB; // enlarge by 1% and 15 meters on each side BoundingBox extrudedBox = new BoundingBox(box.Min - (box.Max - box.Min) * 0.01f - new Vector3(15, 15, 15), box.Max + (box.Max - box.Min) * 0.01f + new Vector3(15, 15, 15)); var waypointsOutside = new HashSet<MyWayPoint>(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("find crossing"); // add all edges that cross the non-extruded box from inside to outside (remember out-vertices) foreach (var waypoint in MyGamePruningStructure.GetAllEntitiesInBox(ref extrudedBox, MyGamePruningStructure.QueryFlags.Waypoints)) { var v = waypoint as MyWayPoint; if (!v.Save) continue; nonFree.Add(v); using (MyWayPoint.NeighborsLock.AcquireSharedUsing()) { foreach (var n in v.Neighbors) if (n.Save && extrudedBox.Contains(n.Position) != ContainmentType.Contains) { if (waypointsOutside.Add(n)) totalWaypointsOutside++; nonFree.Add(n); } } } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); // create envelope int s = 1; if (waypointsOutside.Count > 0 || entity as MyStaticAsteroid == null) // voxel maps and prefabs are automatically subdivided more { s = 2; bigSubdivisions++; } MyWayPoint[, ,] envelope = new MyWayPoint[s + 1, s + 1, s + 1]; for (int i = 0; i <= s; i++) for (int j = 0; j <= s; j++) for (int k = 0; k <= s; k++) { if (s == 2 && i == 1 && j == 1 && k == 1) continue; envelope[i, j, k] = CreateWaypoint(new Vector3( extrudedBox.Min.X + i * (extrudedBox.Max.X - extrudedBox.Min.X) / s, extrudedBox.Min.Y + j * (extrudedBox.Max.Y - extrudedBox.Min.Y) / s, extrudedBox.Min.Z + k * (extrudedBox.Max.Z - extrudedBox.Min.Z) / s ), null); envelope[i, j, k].Save = false; // don't save generated waypoints nonFree.Add(envelope[i, j, k]); // assume Madelyn's envelope has no blockers if (i != 0) if (!(s == 2 && i - 1 == 1 && j == 1 && k == 1)) MyWayPoint.Connect(envelope[i, j, k], envelope[i - 1, j, k]); if (j != 0) if (!(s == 2 && j - 1 == 1 && i == 1 && k == 1)) MyWayPoint.Connect(envelope[i, j, k], envelope[i, j - 1, k]); if (k != 0) if (!(s == 2 && k - 1 == 1 && j == 1 && i == 1)) MyWayPoint.Connect(envelope[i, j, k], envelope[i, j, k - 1]); // if it's a part of a face that faces an out-vertex, connect it foreach (var v in waypointsOutside) if ((i == 0 && v.Position.X <= envelope[i, j, k].Position.X) || (i == s && v.Position.X >= envelope[i, j, k].Position.X) || (j == 0 && v.Position.Y <= envelope[i, j, k].Position.Y) || (j == s && v.Position.Y >= envelope[i, j, k].Position.Y) || (k == 0 && v.Position.Z <= envelope[i, j, k].Position.Z) || (k == s && v.Position.Z >= envelope[i, j, k].Position.Z) ) { MyWayPoint.Connect(v, envelope[i, j, k]); } } envelopes.Add(envelope); envelopeEntity.Add(entity); envelopeBvh.AddProxy(ref extrudedBox, envelopes.Count - 1, 0); largeObjects++; madelynsBox = envelopes.Count - 1; } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("disconnect from old waypoints"); var madelynWaypoints = new HashSet<MyWayPoint>(); { var entity = MyEntities.GetEntityByName("Madelyn"); foreach (var child in entity.Children) { var w = child as MyWayPoint; if (w == null) continue; madelynWaypoints.Add(w); } foreach (var v in madelynWaypoints) { var outsiders = new List<MyWayPoint>(); foreach (var n in v.Neighbors) if (!madelynWaypoints.Contains(n)) outsiders.Add(n); foreach (var n in outsiders) MyWayPoint.Disconnect(v, n); } } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("connect to new surrounding waypoints"); for (int eIndex = 0; eIndex < envelopes.Count; eIndex++) { var e = envelopes[eIndex]; int es = e.GetLength(0) - 1; var eCenter = 0.5f * (e[0, 0, 0].Position + e[es, es, es].Position); // connect Madelyn's inner waypoints to waypoints around her if (eIndex == madelynsBox) { MyEntity madelyn = envelopeEntity[madelynsBox]; madelyn.UpdateAABBHr(); BoundingBox extrudedAABB = madelyn.WorldAABBHr; extrudedAABB.Min -= new Vector3(500); extrudedAABB.Max += new Vector3(500); List<MyWayPoint> nearMadelynWaypoints = new List<MyWayPoint>(); foreach (var waypoint in MyGamePruningStructure.GetAllEntitiesInBox(ref extrudedAABB, MyGamePruningStructure.QueryFlags.Waypoints)) { MyWayPoint v = waypoint as MyWayPoint; if (v != null) { if (!v.Save) continue; if (madelyn.Children.Contains(v)) continue; nearMadelynWaypoints.Add(v); } } int connected = 0, raycasts = 0; foreach (MyWayPoint v in nearMadelynWaypoints) { foreach (var child in madelyn.Children) { var w = child as MyWayPoint; if (w == null) continue; if (v.Neighbors.Contains(w)) continue; raycasts++; if (MyWayPoint.ConnectIfVisible(w, v)) // make a raycast { connected++; break; } } } } } // delete generated waypoints without edges foreach (var v in GetVertexListForModification()) { if (!v.Save && v.Neighbors.Count == 0) { v.MarkForClose(); closed++; } } InvalidateStoredPathCache(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); }