Exemplo n.º 1
0
        public MyDynamicAABBTreeBroadphase()
        {
            m_DAABBTree = new MyDynamicAABBTree(new Vector3(MyPhysicsConfig.AABBExtension));

            m_InteractionList = new List<MyRBElementInteraction>(256);
            m_overlapElementList = new List<MyElement>(256);
        }
Exemplo n.º 2
0
            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;
        }
Exemplo n.º 7
0
        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);
        }
Exemplo n.º 8
0
 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);
         }
     }
 }
Exemplo n.º 9
0
 static void Init()
 {
     m_waypoints = new MyDynamicAABBTree(MyConstants.GAME_PRUNING_STRUCTURE_AABB_EXTENSION);
     m_others    = new MyDynamicAABBTree(MyConstants.GAME_PRUNING_STRUCTURE_AABB_EXTENSION);
 }
Exemplo n.º 10
0
        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);
                    }
                }
            }
Exemplo n.º 12
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]++;
                }
            }
        }
Exemplo n.º 13
0
        /// <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();
        }
Exemplo n.º 14
0
        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();
                }
            }
        }
Exemplo n.º 15
0
        /// <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;
        }
Exemplo n.º 16
0
        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;
        }
Exemplo n.º 17
0
        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);
                        }
                    }
                }
            }
        }
Exemplo n.º 18
0
        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);
                    */
                }
            }
        }
Exemplo n.º 19
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);
        }
Exemplo n.º 20
0
        /// <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();
        }