public MyGridNavigationMesh(MyCubeGrid grid, MyNavmeshCoordinator coordinator, int triPrealloc = 32, Func <long> timestampFunction = null)
            : base(coordinator != null ? coordinator.Links : null, triPrealloc, timestampFunction)
        {
            m_connectionHelper      = new Dictionary <EdgeIndex, int>();
            m_smallTriangleRegistry = new Dictionary <Vector3I, List <int> >();
            m_cubeSet = new MyVector3ISet();

            m_coordinator = coordinator;

            m_static = false;
            if (grid != null)
            {
                m_higherLevel       = new MyHighLevelGroup(this, coordinator.HighLevelLinks, timestampFunction);
                m_higherLevelHelper = new MyGridHighLevelHelper(this, m_smallTriangleRegistry, new Vector3I(8, 8, 8));

                m_grid               = grid;
                grid.OnBlockAdded   += grid_OnBlockAdded;
                grid.OnBlockRemoved += grid_OnBlockRemoved;

                float   divisor = 1.0f / grid.CubeBlocks.Count;
                Vector3 center  = Vector3.Zero;

                foreach (var block in grid.CubeBlocks)
                {
                    OnBlockAddedInternal(block);
                    center += block.Position * grid.GridSize * divisor;
                }
            }
        }
Exemple #2
0
 public MyGridNavigationMesh(MyCubeGrid grid, MyNavmeshCoordinator coordinator, int triPrealloc = 0x20, Func <long> timestampFunction = null) : this(coordinator?.Links, triPrealloc, timestampFunction)
 {
     this.m_connectionHelper      = new Dictionary <EdgeIndex, int>();
     this.m_smallTriangleRegistry = new Dictionary <Vector3I, List <int> >();
     this.m_cubeSet     = new MyVector3ISet();
     this.m_coordinator = coordinator;
     this.m_static      = false;
     if (grid != null)
     {
         this.m_higherLevel       = new MyHighLevelGroup(this, coordinator.HighLevelLinks, timestampFunction);
         this.m_higherLevelHelper = new MyGridHighLevelHelper(this, this.m_smallTriangleRegistry, new Vector3I(8, 8, 8));
         this.m_grid          = grid;
         grid.OnBlockAdded   += new Action <MySlimBlock>(this.grid_OnBlockAdded);
         grid.OnBlockRemoved += new Action <MySlimBlock>(this.grid_OnBlockRemoved);
         float   num  = 1f / ((float)grid.CubeBlocks.Count);
         Vector3 zero = Vector3.Zero;
         foreach (MySlimBlock block in grid.CubeBlocks)
         {
             this.OnBlockAddedInternal(block);
             zero += (block.Position * grid.GridSize) * num;
         }
     }
 }
        public void ProcessChangedCellComponents()
        {
            ProfilerShort.Begin("ProcessChangedCellComponents");

            m_currentHelper = this;

            Vector3I min, max, pos;
            List<int> triangles = null;
            foreach (var cell in m_changedCells)
            {
                min = CellToLowestCube(cell);
                max = min + m_cellSize - Vector3I.One;

                // Save a hashset of all the triangles in the current cell
                pos = min;
                for (var it = new Vector3I_RangeIterator(ref min, ref max); it.IsValid(); it.GetNext(out pos))
                {
                    if (!m_triangleRegistry.TryGetValue(pos, out triangles)) continue;

                    foreach (var triIndex in triangles)
                    {
                        m_tmpCellTriangles.Add(triIndex);
                    }
                }

                if (m_tmpCellTriangles.Count == 0) continue;

                MyCellCoord cellCoord = new MyCellCoord(0, cell);
                ulong packedCell = cellCoord.PackId64();
                m_components.OpenCell(packedCell);

                long timeBegin = m_mesh.GetCurrentTimestamp() + 1;
                long timeEnd = timeBegin;
                m_currentComponentRel = 0;

                m_tmpComponentTriangles.Clear();
                foreach (var triIndex in m_tmpCellTriangles)
                {
                    // Skip already visited triangles
                    var triangle = m_mesh.GetTriangle(triIndex);
                    if (m_currentComponentRel != 0 && m_mesh.VisitedBetween(triangle, timeBegin, timeEnd)) continue;

                    m_components.OpenComponent();

                    // Make sure we have place in m_currentCellConnections
                    if (m_currentComponentRel >= m_currentCellConnections.Count)
                    {
                        m_currentCellConnections.Add(new List<int>());
                    }

                    // Find connected component from an unvisited triangle and mark its connections
                    m_components.AddComponentTriangle(triangle, triangle.Center);
                    triangle.ComponentIndex = m_currentComponentRel;
                    m_tmpComponentTriangles.Add(triangle);
                    m_mesh.PrepareTraversal(triangle, null, m_processTrianglePredicate);
                    m_mesh.PerformTraversal();
                    m_tmpComponentTriangles.Add(null);

                    m_components.CloseComponent();

                    timeEnd = m_mesh.GetCurrentTimestamp();
                    if (m_currentComponentRel == 0)
                    {
                        timeBegin = timeEnd;
                    }
                    m_currentComponentRel++;
                }

                m_tmpCellTriangles.Clear();

                MyNavmeshComponents.ClosedCellInfo cellInfo = new MyNavmeshComponents.ClosedCellInfo();
                m_components.CloseAndCacheCell(ref cellInfo);

                // Renumber triangles from the old indices to the newly assigned index from m_components
                int componentIndex = cellInfo.StartingIndex;
                foreach (var triangle in m_tmpComponentTriangles)
                {
                    if (triangle == null)
                    {
                        componentIndex++;
                        continue;
                    }
                    triangle.ComponentIndex = componentIndex;
                }
                m_tmpComponentTriangles.Clear();

                // Remove old component primitives
                if (!cellInfo.NewCell && cellInfo.ComponentNum != cellInfo.OldComponentNum)
                {
                    for (int i = 0; i < cellInfo.OldComponentNum; ++i)
                    {
                        m_mesh.HighLevelGroup.RemovePrimitive(cellInfo.OldStartingIndex + i);
                    }
                }

                // Add new component primitives
                if (cellInfo.NewCell || cellInfo.ComponentNum != cellInfo.OldComponentNum)
                {
                    for (int i = 0; i < cellInfo.ComponentNum; ++i)
                    {
                        m_mesh.HighLevelGroup.AddPrimitive(cellInfo.StartingIndex + i, m_components.GetComponentCenter(i));
                    }
                }

                // Update existing component primitives
                if (!cellInfo.NewCell && cellInfo.ComponentNum == cellInfo.OldComponentNum)
                {
                    for (int i = 0; i < cellInfo.ComponentNum; ++i)
                    {
                        var primitive = m_mesh.HighLevelGroup.GetPrimitive(cellInfo.StartingIndex + i);
                        primitive.UpdatePosition(m_components.GetComponentCenter(i));
                    }
                }

                // Connect new components with the others in the neighboring cells
                for (int i = 0; i < cellInfo.ComponentNum; ++i)
                {
                    int compIndex = cellInfo.StartingIndex + i;

                    var primitive = m_mesh.HighLevelGroup.GetPrimitive(compIndex);
                    primitive.GetNeighbours(m_tmpNeighbors);

                    // Connect to disconnected components
                    foreach (var connection in m_currentCellConnections[i])
                    {
                        if (!m_tmpNeighbors.Remove(connection))
                        {
                            m_mesh.HighLevelGroup.ConnectPrimitives(compIndex, connection);
                        }
                    }

                    // Disconnect neighbors that should be no longer connected
                    foreach (var neighbor in m_tmpNeighbors)
                    {
                        // Only disconnect from the other cell if it is expanded and there was no connection found
                        var neighborPrimitive = m_mesh.HighLevelGroup.TryGetPrimitive(neighbor);
                        if (neighborPrimitive != null && neighborPrimitive.IsExpanded)
                        {
                            m_mesh.HighLevelGroup.DisconnectPrimitives(compIndex, neighbor);
                        }
                    }

                    m_tmpNeighbors.Clear();
                    m_currentCellConnections[i].Clear();
                }

                // Set all the components as expanded
                for (int i = 0; i < cellInfo.ComponentNum; ++i)
                {
                    componentIndex = cellInfo.StartingIndex + i;
                    var component = m_mesh.HighLevelGroup.GetPrimitive(componentIndex);
                    if (component != null)
                    {
                        component.IsExpanded = true;
                    }
                }
            }

            m_changedCells.Clear();

            m_currentHelper = null;

            ProfilerShort.End();
        }
Exemple #4
0
        public void ProcessChangedCellComponents()
        {
            ProfilerShort.Begin("ProcessChangedCellComponents");

            m_currentHelper = this;

            Vector3I   min, max, pos;
            List <int> triangles = null;

            foreach (var cell in m_changedCells)
            {
                min = CellToLowestCube(cell);
                max = min + m_cellSize - Vector3I.One;

                // Save a hashset of all the triangles in the current cell
                pos = min;
                for (var it = new Vector3I_RangeIterator(ref min, ref max); it.IsValid(); it.GetNext(out pos))
                {
                    if (!m_triangleRegistry.TryGetValue(pos, out triangles))
                    {
                        continue;
                    }

                    foreach (var triIndex in triangles)
                    {
                        m_tmpCellTriangles.Add(triIndex);
                    }
                }

                if (m_tmpCellTriangles.Count == 0)
                {
                    continue;
                }

                MyCellCoord cellCoord  = new MyCellCoord(0, cell);
                ulong       packedCell = cellCoord.PackId64();
                m_components.OpenCell(packedCell);

                long timeBegin = m_mesh.GetCurrentTimestamp() + 1;
                long timeEnd   = timeBegin;
                m_currentComponentRel = 0;

                m_tmpComponentTriangles.Clear();
                foreach (var triIndex in m_tmpCellTriangles)
                {
                    // Skip already visited triangles
                    var triangle = m_mesh.GetTriangle(triIndex);
                    if (m_currentComponentRel != 0 && m_mesh.VisitedBetween(triangle, timeBegin, timeEnd))
                    {
                        continue;
                    }

                    m_components.OpenComponent();

                    // Make sure we have place in m_currentCellConnections
                    if (m_currentComponentRel >= m_currentCellConnections.Count)
                    {
                        m_currentCellConnections.Add(new List <int>());
                    }

                    // Find connected component from an unvisited triangle and mark its connections
                    m_components.AddComponentTriangle(triangle, triangle.Center);
                    triangle.ComponentIndex = m_currentComponentRel;
                    m_tmpComponentTriangles.Add(triangle);
                    m_mesh.PrepareTraversal(triangle, null, m_processTrianglePredicate);
                    m_mesh.PerformTraversal();
                    m_tmpComponentTriangles.Add(null);

                    m_components.CloseComponent();

                    timeEnd = m_mesh.GetCurrentTimestamp();
                    if (m_currentComponentRel == 0)
                    {
                        timeBegin = timeEnd;
                    }
                    m_currentComponentRel++;
                }

                m_tmpCellTriangles.Clear();

                MyNavmeshComponents.ClosedCellInfo cellInfo = new MyNavmeshComponents.ClosedCellInfo();
                m_components.CloseAndCacheCell(ref cellInfo);

                // Renumber triangles from the old indices to the newly assigned index from m_components
                int componentIndex = cellInfo.StartingIndex;
                foreach (var triangle in m_tmpComponentTriangles)
                {
                    if (triangle == null)
                    {
                        componentIndex++;
                        continue;
                    }
                    triangle.ComponentIndex = componentIndex;
                }
                m_tmpComponentTriangles.Clear();

                // Remove old component primitives
                if (!cellInfo.NewCell && cellInfo.ComponentNum != cellInfo.OldComponentNum)
                {
                    for (int i = 0; i < cellInfo.OldComponentNum; ++i)
                    {
                        m_mesh.HighLevelGroup.RemovePrimitive(cellInfo.OldStartingIndex + i);
                    }
                }

                // Add new component primitives
                if (cellInfo.NewCell || cellInfo.ComponentNum != cellInfo.OldComponentNum)
                {
                    for (int i = 0; i < cellInfo.ComponentNum; ++i)
                    {
                        m_mesh.HighLevelGroup.AddPrimitive(cellInfo.StartingIndex + i, m_components.GetComponentCenter(i));
                    }
                }

                // Update existing component primitives
                if (!cellInfo.NewCell && cellInfo.ComponentNum == cellInfo.OldComponentNum)
                {
                    for (int i = 0; i < cellInfo.ComponentNum; ++i)
                    {
                        var primitive = m_mesh.HighLevelGroup.GetPrimitive(cellInfo.StartingIndex + i);
                        primitive.UpdatePosition(m_components.GetComponentCenter(i));
                    }
                }

                // Connect new components with the others in the neighboring cells
                for (int i = 0; i < cellInfo.ComponentNum; ++i)
                {
                    int compIndex = cellInfo.StartingIndex + i;

                    var primitive = m_mesh.HighLevelGroup.GetPrimitive(compIndex);
                    primitive.GetNeighbours(m_tmpNeighbors);

                    // Connect to disconnected components
                    foreach (var connection in m_currentCellConnections[i])
                    {
                        if (!m_tmpNeighbors.Remove(connection))
                        {
                            m_mesh.HighLevelGroup.ConnectPrimitives(compIndex, connection);
                        }
                    }

                    // Disconnect neighbors that should be no longer connected
                    foreach (var neighbor in m_tmpNeighbors)
                    {
                        // Only disconnect from the other cell if it is expanded and there was no connection found
                        var neighborPrimitive = m_mesh.HighLevelGroup.TryGetPrimitive(neighbor);
                        if (neighborPrimitive != null && neighborPrimitive.IsExpanded)
                        {
                            m_mesh.HighLevelGroup.DisconnectPrimitives(compIndex, neighbor);
                        }
                    }

                    m_tmpNeighbors.Clear();
                    m_currentCellConnections[i].Clear();
                }

                // Set all the components as expanded
                for (int i = 0; i < cellInfo.ComponentNum; ++i)
                {
                    componentIndex = cellInfo.StartingIndex + i;
                    var component = m_mesh.HighLevelGroup.GetPrimitive(componentIndex);
                    if (component != null)
                    {
                        component.IsExpanded = true;
                    }
                }
            }

            m_changedCells.Clear();

            m_currentHelper = null;

            ProfilerShort.End();
        }
        public void ProcessChangedCellComponents()
        {
            ProfilerShort.Begin("ProcessChangedCellComponents");

            m_currentHelper = this;

            Vector3I   min, max, pos;
            List <int> triangles = null;

            foreach (var cell in m_changedCells)
            {
                MyCellCoord cellCoord  = new MyCellCoord(0, cell);
                ulong       packedCell = cellCoord.PackId64();

                m_components.OpenCell(packedCell);

                min = CellToLowestCube(cell);
                max = min + m_cellSize - Vector3I.One;

                // Save a hashset of all the triangles in the current cell
                pos = min;
                for (var it = new Vector3I.RangeIterator(ref min, ref max); it.IsValid(); it.GetNext(out pos))
                {
                    if (!m_triangleRegistry.TryGetValue(pos, out triangles))
                    {
                        continue;
                    }

                    foreach (var triIndex in triangles)
                    {
                        m_tmpCellTriangles.Add(triIndex);
                    }
                }

                long timeBegin = m_mesh.GetCurrentTimestamp() + 1;
                long timeEnd   = timeBegin;
                m_currentComponentRel = 0;

                foreach (var triIndex in m_tmpCellTriangles)
                {
                    // Skip already visited triangles
                    var triangle = m_mesh.GetTriangle(triIndex);
                    if (m_currentComponentRel != 0 && m_mesh.VisitedBetween(triangle, timeBegin, timeEnd))
                    {
                        continue;
                    }

                    m_components.OpenComponent();

                    // Make sure we have place in m_currentCellConnections
                    if (m_currentComponentRel >= m_currentCellConnections.Count)
                    {
                        m_currentCellConnections.Add(new List <int>());
                    }

                    // Find connected component from an unvisited triangle and mark its connections
                    m_components.AddComponentTriangle(triangle, triangle.Center);
                    triangle.ComponentIndex = m_components.OpenComponentIndex;
                    m_mesh.PrepareTraversal(triangle, null, m_processTrianglePredicate);

                    var primitiveEnum = m_mesh.GetEnumerator();
                    while (primitiveEnum.MoveNext())
                    {
                        ;
                    }
                    primitiveEnum.Dispose();

                    m_components.CloseComponent();

                    timeEnd = m_mesh.GetCurrentTimestamp();
                    if (m_currentComponentRel == 0)
                    {
                        timeBegin = timeEnd;
                    }
                    m_currentComponentRel++;
                }

                m_tmpCellTriangles.Clear();

                MyNavmeshComponents.ClosedCellInfo cellInfo = new MyNavmeshComponents.ClosedCellInfo();
                m_components.CloseAndCacheCell(ref cellInfo);

                // Add new component primitives
                if (cellInfo.NewCell)
                {
                    for (int i = 0; i < cellInfo.ComponentNum; ++i)
                    {
                        m_mesh.HighLevelGroup.AddPrimitive(cellInfo.StartingIndex + i, m_components.GetComponentCenter(i));
                    }
                }

                // Connect new components with the others in the neighboring cells
                for (int i = 0; i < cellInfo.ComponentNum; ++i)
                {
                    foreach (var otherComponent in m_currentCellConnections[i])
                    {
                        m_mesh.HighLevelGroup.ConnectPrimitives(cellInfo.StartingIndex + i, otherComponent);
                    }
                    m_currentCellConnections[i].Clear();
                }

                // Set all the components as expanded
                for (int i = 0; i < cellInfo.ComponentNum; ++i)
                {
                    int componentIndex = cellInfo.StartingIndex + i;
                    var component      = m_mesh.HighLevelGroup.GetPrimitive(componentIndex);
                    if (component != null)
                    {
                        component.IsExpanded = true;
                    }
                }
            }

            m_changedCells.Clear();

            m_currentHelper = null;

            ProfilerShort.End();
        }
        public void ProcessChangedCellComponents()
        {
            ProfilerShort.Begin("ProcessChangedCellComponents");

            m_currentHelper = this;

            Vector3I min, max, pos;
            List<int> triangles = null;
            foreach (var cell in m_changedCells)
            {
                MyCellCoord cellCoord = new MyCellCoord(0, cell);
                ulong packedCell = cellCoord.PackId64();

                m_components.OpenCell(packedCell);

                min = CellToLowestCube(cell);
                max = min + m_cellSize - Vector3I.One;

                // Save a hashset of all the triangles in the current cell
                pos = min;
                for (var it = new Vector3I.RangeIterator(ref min, ref max); it.IsValid(); it.GetNext(out pos))
                {
                    if (!m_triangleRegistry.TryGetValue(pos, out triangles)) continue;

                    foreach (var triIndex in triangles)
                    {
                        m_tmpCellTriangles.Add(triIndex);
                    }
                }

                long timeBegin = m_mesh.GetCurrentTimestamp() + 1;
                long timeEnd = timeBegin;
                m_currentComponentRel = 0;

                foreach (var triIndex in m_tmpCellTriangles)
                {
                    // Skip already visited triangles
                    var triangle = m_mesh.GetTriangle(triIndex);
                    if (m_currentComponentRel != 0 && m_mesh.VisitedBetween(triangle, timeBegin, timeEnd)) continue;

                    m_components.OpenComponent();

                    // Make sure we have place in m_currentCellConnections
                    if (m_currentComponentRel >= m_currentCellConnections.Count)
                    {
                        m_currentCellConnections.Add(new List<int>());
                    }

                    // Find connected component from an unvisited triangle and mark its connections
                    m_components.AddComponentTriangle(triangle, triangle.Center);
                    triangle.ComponentIndex = m_components.OpenComponentIndex;
                    m_mesh.PrepareTraversal(triangle, null, m_processTrianglePredicate);

                    var primitiveEnum = m_mesh.GetEnumerator();
                    while (primitiveEnum.MoveNext());
                    primitiveEnum.Dispose();

                    m_components.CloseComponent();

                    timeEnd = m_mesh.GetCurrentTimestamp();
                    if (m_currentComponentRel == 0)
                    {
                        timeBegin = timeEnd;
                    }
                    m_currentComponentRel++;
                }

                m_tmpCellTriangles.Clear();

                MyNavmeshComponents.ClosedCellInfo cellInfo = new MyNavmeshComponents.ClosedCellInfo();
                m_components.CloseAndCacheCell(ref cellInfo);

                // Add new component primitives 
                if (cellInfo.NewCell)
                {
                    for (int i = 0; i < cellInfo.ComponentNum; ++i)
                    {
                        m_mesh.HighLevelGroup.AddPrimitive(cellInfo.StartingIndex + i, m_components.GetComponentCenter(i));
                    }
                }

                // Connect new components with the others in the neighboring cells
                for (int i = 0; i < cellInfo.ComponentNum; ++i)
                {
                    foreach (var otherComponent in m_currentCellConnections[i])
                    {
                        m_mesh.HighLevelGroup.ConnectPrimitives(cellInfo.StartingIndex + i, otherComponent);
                    }
                    m_currentCellConnections[i].Clear();
                }

                // Set all the components as expanded
                for (int i = 0; i < cellInfo.ComponentNum; ++i)
                {
                    int componentIndex = cellInfo.StartingIndex + i;
                    var component = m_mesh.HighLevelGroup.GetPrimitive(componentIndex);
                    if (component != null)
                    {
                        component.IsExpanded = true;
                    }
                }
            }

            m_changedCells.Clear();

            m_currentHelper = null;

            ProfilerShort.End();
        }
Exemple #7
0
        public void ProcessChangedCellComponents()
        {
            m_currentHelper = this;
            List <int> list = null;

            foreach (Vector3I vectori4 in this.m_changedCells)
            {
                Vector3I start = this.CellToLowestCube(vectori4);
                Vector3I end   = ((Vector3I)(start + this.m_cellSize)) - Vector3I.One;
                Vector3I key   = start;
                Vector3I_RangeIterator iterator = new Vector3I_RangeIterator(ref start, ref end);
                while (true)
                {
                    if (!iterator.IsValid())
                    {
                        if (m_tmpCellTriangles.Count != 0)
                        {
                            ulong cellCoord = new MyCellCoord(0, vectori4).PackId64();
                            this.m_components.OpenCell(cellCoord);
                            long num2             = this.m_mesh.GetCurrentTimestamp() + 1L;
                            long currentTimestamp = num2;
                            this.m_currentComponentRel = 0;
                            this.m_tmpComponentTriangles.Clear();
                            foreach (int num6 in m_tmpCellTriangles)
                            {
                                MyNavigationTriangle vertex = this.m_mesh.GetTriangle(num6);
                                if ((this.m_currentComponentRel == 0) || !this.m_mesh.VisitedBetween(vertex, num2, currentTimestamp))
                                {
                                    this.m_components.OpenComponent();
                                    if (this.m_currentComponentRel >= this.m_currentCellConnections.Count)
                                    {
                                        this.m_currentCellConnections.Add(new List <int>());
                                    }
                                    this.m_components.AddComponentTriangle(vertex, vertex.Center);
                                    vertex.ComponentIndex = this.m_currentComponentRel;
                                    this.m_tmpComponentTriangles.Add(vertex);
                                    this.m_mesh.PrepareTraversal(vertex, null, this.m_processTrianglePredicate, null);
                                    this.m_mesh.PerformTraversal();
                                    this.m_tmpComponentTriangles.Add(null);
                                    this.m_components.CloseComponent();
                                    currentTimestamp = this.m_mesh.GetCurrentTimestamp();
                                    if (this.m_currentComponentRel == 0)
                                    {
                                        num2 = currentTimestamp;
                                    }
                                    this.m_currentComponentRel++;
                                }
                            }
                            m_tmpCellTriangles.Clear();
                            MyNavmeshComponents.ClosedCellInfo output = new MyNavmeshComponents.ClosedCellInfo();
                            this.m_components.CloseAndCacheCell(ref output);
                            int startingIndex = output.StartingIndex;
                            foreach (MyNavigationTriangle triangle2 in this.m_tmpComponentTriangles)
                            {
                                if (triangle2 == null)
                                {
                                    startingIndex++;
                                    continue;
                                }
                                triangle2.ComponentIndex = startingIndex;
                            }
                            this.m_tmpComponentTriangles.Clear();
                            if (!output.NewCell && (output.ComponentNum != output.OldComponentNum))
                            {
                                for (int i = 0; i < output.OldComponentNum; i++)
                                {
                                    this.m_mesh.HighLevelGroup.RemovePrimitive(output.OldStartingIndex + i);
                                }
                            }
                            if (output.NewCell || (output.ComponentNum != output.OldComponentNum))
                            {
                                for (int i = 0; i < output.ComponentNum; i++)
                                {
                                    this.m_mesh.HighLevelGroup.AddPrimitive(output.StartingIndex + i, this.m_components.GetComponentCenter(i));
                                }
                            }
                            if (!output.NewCell && (output.ComponentNum == output.OldComponentNum))
                            {
                                for (int i = 0; i < output.ComponentNum; i++)
                                {
                                    this.m_mesh.HighLevelGroup.GetPrimitive(output.StartingIndex + i).UpdatePosition(this.m_components.GetComponentCenter(i));
                                }
                            }
                            int num10 = 0;
                            while (true)
                            {
                                if (num10 >= output.ComponentNum)
                                {
                                    for (int i = 0; i < output.ComponentNum; i++)
                                    {
                                        startingIndex = output.StartingIndex + i;
                                        MyHighLevelPrimitive primitive = this.m_mesh.HighLevelGroup.GetPrimitive(startingIndex);
                                        if (primitive != null)
                                        {
                                            primitive.IsExpanded = true;
                                        }
                                    }
                                    break;
                                }
                                int index = output.StartingIndex + num10;
                                this.m_mesh.HighLevelGroup.GetPrimitive(index).GetNeighbours(this.m_tmpNeighbors);
                                foreach (int num12 in this.m_currentCellConnections[num10])
                                {
                                    if (!this.m_tmpNeighbors.Remove(num12))
                                    {
                                        this.m_mesh.HighLevelGroup.ConnectPrimitives(index, num12);
                                    }
                                }
                                foreach (int num13 in this.m_tmpNeighbors)
                                {
                                    MyHighLevelPrimitive primitive = this.m_mesh.HighLevelGroup.TryGetPrimitive(num13);
                                    if ((primitive != null) && primitive.IsExpanded)
                                    {
                                        this.m_mesh.HighLevelGroup.DisconnectPrimitives(index, num13);
                                    }
                                }
                                this.m_tmpNeighbors.Clear();
                                this.m_currentCellConnections[num10].Clear();
                                num10++;
                            }
                        }
                        break;
                    }
                    if (this.m_triangleRegistry.TryGetValue(key, out list))
                    {
                        foreach (int num5 in list)
                        {
                            m_tmpCellTriangles.Add(num5);
                        }
                    }
                    iterator.GetNext(out key);
                }
            }
            this.m_changedCells.Clear();
            m_currentHelper = null;
        }
        public MyGridNavigationMesh(MyCubeGrid grid, MyNavmeshCoordinator coordinator, int triPrealloc = 32, Func<long> timestampFunction = null)
            : base(coordinator != null ? coordinator.Links : null, triPrealloc, timestampFunction)
        {
            m_connectionHelper = new Dictionary<EdgeIndex, int>();
            m_smallTriangleRegistry = new Dictionary<Vector3I, List<int>>();
            m_cubeSet = new MyVector3ISet();

            m_coordinator = coordinator;

            m_static = false;
            if (grid != null)
            {
                m_higherLevel = new MyHighLevelGroup(this, coordinator.HighLevelLinks, timestampFunction);
                m_higherLevelHelper = new MyGridHighLevelHelper(this, m_smallTriangleRegistry, new Vector3I(8, 8, 8));

                m_grid = grid;
                grid.OnBlockAdded += grid_OnBlockAdded;
                grid.OnBlockRemoved += grid_OnBlockRemoved;

                float divisor = 1.0f / grid.CubeBlocks.Count;
                Vector3 center = Vector3.Zero;

                foreach (var block in grid.CubeBlocks)
                {
                    OnBlockAddedInternal(block);
                    center += block.Position * grid.GridSize * divisor;
                }
            }
        }