public void ProcessCellComponents()
        {
            ProfilerShort.Begin("ProcessCellComponents");
            m_triangleLists.Add(m_packedCoord, m_triangleList.GetCopy());

            // Find the components by traversing the graph
            MyNavmeshComponents.ClosedCellInfo cellInfo = ConstructComponents();

            // Assign correct component indices to the new components and their triangles
            // Then, remove or create the respective high-level primitives, if the components changed since last time
            // Then, update connections, if the components changed since last time
            UpdateHighLevelPrimitives(ref cellInfo);

            // Mark explored directions in the navmesh component helper
            MarkExploredDirections(ref cellInfo);

            // 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;
                }
            }

            ProfilerShort.End();
        }
        private void MarkExploredDirections(ref MyNavmeshComponents.ClosedCellInfo cellInfo)
        {
            foreach (var direction in Base6Directions.EnumDirections)
            {
                var dirFlag = Base6Directions.GetDirectionFlag(direction);
                if (cellInfo.ExploredDirections.HasFlag(dirFlag))
                {
                    continue;
                }

                Vector3I dirVec = Base6Directions.GetIntVector(direction);

                MyCellCoord otherCoord = new MyCellCoord();
                otherCoord.Lod        = MyVoxelNavigationMesh.NAVMESH_LOD;
                otherCoord.CoordInLod = m_currentCell + dirVec;
                if (otherCoord.CoordInLod.X == -1 || otherCoord.CoordInLod.Y == -1 || otherCoord.CoordInLod.Z == -1)
                {
                    continue;
                }

                ulong otherPackedCoord = otherCoord.PackId64();

                if (m_triangleLists.ContainsKey(otherPackedCoord))
                {
                    m_navmeshComponents.MarkExplored(otherPackedCoord, Base6Directions.GetFlippedDirection(direction));
                    cellInfo.ExploredDirections |= Base6Directions.GetDirectionFlag(direction);
                }
            }
            m_navmeshComponents.SetExplored(m_packedCoord, cellInfo.ExploredDirections);
        }
Esempio n. 3
0
 private unsafe void MarkExploredDirections(ref MyNavmeshComponents.ClosedCellInfo cellInfo)
 {
     foreach (Base6Directions.Direction direction in Base6Directions.EnumDirections)
     {
         Base6Directions.DirectionFlags directionFlag = Base6Directions.GetDirectionFlag(direction);
         if (!cellInfo.ExploredDirections.HasFlag(directionFlag))
         {
             Vector3I    intVector = Base6Directions.GetIntVector(direction);
             MyCellCoord coord     = new MyCellCoord {
                 Lod        = 0,
                 CoordInLod = (Vector3I)(this.m_currentCell + intVector)
             };
             if (((coord.CoordInLod.X != -1) && (coord.CoordInLod.Y != -1)) && (coord.CoordInLod.Z != -1))
             {
                 ulong key = coord.PackId64();
                 if (this.m_triangleLists.ContainsKey(key))
                 {
                     this.m_navmeshComponents.MarkExplored(key, Base6Directions.GetFlippedDirection(direction));
                     Base6Directions.DirectionFlags *flagsPtr1 = (Base6Directions.DirectionFlags *) ref cellInfo.ExploredDirections;
                     *((sbyte *)flagsPtr1) = *(((byte *)flagsPtr1)) | Base6Directions.GetDirectionFlag(direction);
                 }
             }
         }
     }
     this.m_navmeshComponents.SetExplored(this.m_packedCoord, cellInfo.ExploredDirections);
 }
Esempio n. 4
0
        private void UpdateHighLevelPrimitives(ref MyNavmeshComponents.ClosedCellInfo cellInfo)
        {
            int startingIndex = cellInfo.StartingIndex;

            foreach (MyNavigationTriangle triangle in this.m_tmpComponentTriangles)
            {
                if (triangle == null)
                {
                    startingIndex++;
                    continue;
                }
                triangle.ComponentIndex = startingIndex;
            }
            this.m_tmpComponentTriangles.Clear();
            if (!cellInfo.NewCell && (cellInfo.ComponentNum != cellInfo.OldComponentNum))
            {
                for (int j = 0; j < cellInfo.OldComponentNum; j++)
                {
                    this.m_mesh.HighLevelGroup.RemovePrimitive(cellInfo.OldStartingIndex + j);
                }
            }
            if (cellInfo.NewCell || (cellInfo.ComponentNum != cellInfo.OldComponentNum))
            {
                for (int j = 0; j < cellInfo.ComponentNum; j++)
                {
                    this.m_mesh.HighLevelGroup.AddPrimitive(cellInfo.StartingIndex + j, this.m_navmeshComponents.GetComponentCenter(j));
                }
            }
            if (!cellInfo.NewCell && (cellInfo.ComponentNum == cellInfo.OldComponentNum))
            {
                for (int j = 0; j < cellInfo.ComponentNum; j++)
                {
                    this.m_mesh.HighLevelGroup.GetPrimitive(cellInfo.StartingIndex + j).UpdatePosition(this.m_navmeshComponents.GetComponentCenter(j));
                }
            }
            for (int i = 0; i < cellInfo.ComponentNum; i++)
            {
                int index = cellInfo.StartingIndex + i;
                this.m_mesh.HighLevelGroup.GetPrimitive(index).GetNeighbours(this.m_tmpNeighbors);
                foreach (ConnectionInfo info in this.m_currentCellConnections[i])
                {
                    if (!this.m_tmpNeighbors.Remove(info.ComponentIndex))
                    {
                        this.m_mesh.HighLevelGroup.ConnectPrimitives(index, info.ComponentIndex);
                    }
                }
                foreach (int num7 in this.m_tmpNeighbors)
                {
                    MyHighLevelPrimitive primitive = this.m_mesh.HighLevelGroup.TryGetPrimitive(num7);
                    if ((primitive != null) && primitive.IsExpanded)
                    {
                        this.m_mesh.HighLevelGroup.DisconnectPrimitives(index, num7);
                    }
                }
                this.m_tmpNeighbors.Clear();
                this.m_currentCellConnections[i].Clear();
            }
        }
        private MyNavmeshComponents.ClosedCellInfo ConstructComponents()
        {
            ProfilerShort.Begin("ConstructComponents");

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

            m_currentComponentRel = 0;
            m_navmeshComponents.OpenCell(m_packedCoord);

            m_tmpComponentTriangles.Clear();
            foreach (var triIndex in m_triangleList)
            {
                // The marker is used as a fake component index in triangles to mark visited triangles.
                // Negative numbers from -2 down are used to avoid collisions with existing component numbers (0, 1, 2, ...) or the special value -1
                m_currentComponentMarker = -2 - m_currentComponentRel;

                // Skip already visited triangles
                var triangle = m_mesh.GetTriangle(triIndex);
                if (m_mesh.VisitedBetween(triangle, timeBegin, timeEnd))
                {
                    continue;
                }

                m_navmeshComponents.OpenComponent();

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

                // Find connected component from an unvisited triangle
                ProfilerShort.Begin("Graph traversal");
                m_currentHelper = this;

                m_navmeshComponents.AddComponentTriangle(triangle, triangle.Center);
                triangle.ComponentIndex = m_currentComponentMarker;
                m_tmpComponentTriangles.Add(triangle);

                m_mesh.PrepareTraversal(triangle, null, m_processTrianglePredicate);
                m_mesh.PerformTraversal();
                ProfilerShort.End();

                m_tmpComponentTriangles.Add(null); // Mark end of component in m_tmpComponentTriangles
                m_navmeshComponents.CloseComponent();

                timeEnd = m_mesh.GetCurrentTimestamp();
                m_currentComponentRel++;
            }

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

            ProfilerShort.End();
            return(cellInfo);
        }
Esempio n. 6
0
 public void ProcessCellComponents()
 {
     this.m_triangleLists.Add(this.m_packedCoord, this.m_triangleList.GetCopy());
     MyNavmeshComponents.ClosedCellInfo cellInfo = this.ConstructComponents();
     this.UpdateHighLevelPrimitives(ref cellInfo);
     this.MarkExploredDirections(ref cellInfo);
     for (int i = 0; i < cellInfo.ComponentNum; i++)
     {
         int index = cellInfo.StartingIndex + i;
         MyHighLevelPrimitive primitive = this.m_mesh.HighLevelGroup.GetPrimitive(index);
         if (primitive != null)
         {
             primitive.IsExpanded = true;
         }
     }
 }
Esempio n. 7
0
        private MyNavmeshComponents.ClosedCellInfo ConstructComponents()
        {
            long start = this.m_mesh.GetCurrentTimestamp() + 1L;
            long end   = start;

            this.m_currentComponentRel = 0;
            this.m_navmeshComponents.OpenCell(this.m_packedCoord);
            this.m_tmpComponentTriangles.Clear();
            MyIntervalList.Enumerator enumerator = this.m_triangleList.GetEnumerator();
            while (enumerator.MoveNext())
            {
                int current = enumerator.Current;
                this.m_currentComponentMarker = -2 - this.m_currentComponentRel;
                MyNavigationTriangle vertex = this.m_mesh.GetTriangle(current);
                if (!this.m_mesh.VisitedBetween(vertex, start, end))
                {
                    this.m_navmeshComponents.OpenComponent();
                    if (this.m_currentComponentRel >= this.m_currentCellConnections.Count)
                    {
                        this.m_currentCellConnections.Add(new List <ConnectionInfo>());
                    }
                    m_currentHelper = this;
                    this.m_navmeshComponents.AddComponentTriangle(vertex, vertex.Center);
                    vertex.ComponentIndex = this.m_currentComponentMarker;
                    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_navmeshComponents.CloseComponent();
                    end = this.m_mesh.GetCurrentTimestamp();
                    this.m_currentComponentRel++;
                }
            }
            MyNavmeshComponents.ClosedCellInfo output = new MyNavmeshComponents.ClosedCellInfo();
            this.m_navmeshComponents.CloseAndCacheCell(ref output);
            return(output);
        }
        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 ProcessCellComponents()
        {
            ProfilerShort.Begin("ProcessCellComponents");
            m_triangleLists.Add(m_packedCoord, m_triangleList.GetCopy());

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

            m_currentComponentRel = 0;
            m_currentComponent = m_navmeshComponents.OpenCell(m_packedCoord);

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

                m_navmeshComponents.OpenComponent();

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

                // Find connected component from an unvisited triangle
                ProfilerShort.Begin("Graph traversal");
                m_currentHelper = this;

                m_navmeshComponents.AddComponentTriangle(triangle, triangle.Center);
                triangle.ComponentIndex = m_navmeshComponents.OpenComponentIndex;
                m_mesh.PrepareTraversal(triangle, null, m_processTrianglePredicate);

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

                m_navmeshComponents.CloseComponent();

                timeEnd = m_mesh.GetCurrentTimestamp();
                m_currentComponentRel++;
            }

            MyNavmeshComponents.ClosedCellInfo cellInfo = new MyNavmeshComponents.ClosedCellInfo();
            m_navmeshComponents.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_navmeshComponents.GetComponentCenter(i));
                }
            }
            
            // Connect new components with the others in the neighboring cells
            for (int i = 0; i < cellInfo.ComponentNum; ++i)
            {
                foreach (var connectionInfo in m_currentCellConnections[i])
                {
                    if (!cellInfo.ExploredDirections.HasFlag(Base6Directions.GetDirectionFlag(connectionInfo.Direction)))
                    {
                        m_mesh.HighLevelGroup.ConnectPrimitives(cellInfo.StartingIndex + i, connectionInfo.ComponentIndex);
                    }
                }
                m_currentCellConnections[i].Clear();
            }

            // Mark explored directions in the navmesh component helper
            foreach (var direction in Base6Directions.EnumDirections)
            {
                var dirFlag = Base6Directions.GetDirectionFlag(direction);
                if (cellInfo.ExploredDirections.HasFlag(dirFlag))
                {
                    continue;
                }

                Vector3I dirVec = Base6Directions.GetIntVector(direction);

                MyCellCoord otherCoord = new MyCellCoord();
                otherCoord.Lod = MyVoxelNavigationMesh.NAVMESH_LOD;
                otherCoord.CoordInLod = m_currentCell + dirVec;
                if (otherCoord.CoordInLod.X == -1 || otherCoord.CoordInLod.Y == -1 || otherCoord.CoordInLod.Z == -1)
                {
                    continue;
                }

                ulong otherPackedCoord = otherCoord.PackId64();

                if (m_triangleLists.ContainsKey(otherPackedCoord))
                {
                    m_navmeshComponents.MarkExplored(otherPackedCoord, Base6Directions.GetFlippedDirection(direction));
                    cellInfo.ExploredDirections |= Base6Directions.GetDirectionFlag(direction);
                }
            }
            m_navmeshComponents.SetExplored(m_packedCoord, cellInfo.ExploredDirections);

            // 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;
                }
            }

            ProfilerShort.End();
        }
Esempio n. 10
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();
        }
        private void UpdateHighLevelPrimitives(ref MyNavmeshComponents.ClosedCellInfo cellInfo)
        {
            ProfilerShort.Begin("UpdateHighLevelPrimitives");

            // 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_navmeshComponents.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_navmeshComponents.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 connectionInfo in m_currentCellConnections[i])
                {
                    if (!m_tmpNeighbors.Remove(connectionInfo.ComponentIndex))
                    {
                        m_mesh.HighLevelGroup.ConnectPrimitives(compIndex, connectionInfo.ComponentIndex);
                    }
                }

                // 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();
            }

            ProfilerShort.End();
        }
Esempio n. 14
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;
        }
        private MyNavmeshComponents.ClosedCellInfo ConstructComponents()
        {
            ProfilerShort.Begin("ConstructComponents");

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

            m_currentComponentRel = 0;
            m_navmeshComponents.OpenCell(m_packedCoord);

            m_tmpComponentTriangles.Clear();
            foreach (var triIndex in m_triangleList)
            {
                // The marker is used as a fake component index in triangles to mark visited triangles.
                // Negative numbers from -2 down are used to avoid collisions with existing component numbers (0, 1, 2, ...) or the special value -1
                m_currentComponentMarker = -2 - m_currentComponentRel;

                // Skip already visited triangles
                var triangle = m_mesh.GetTriangle(triIndex);
                if (m_mesh.VisitedBetween(triangle, timeBegin, timeEnd))
                {
                    continue;
                }

                m_navmeshComponents.OpenComponent();

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

                // Find connected component from an unvisited triangle
                ProfilerShort.Begin("Graph traversal");
                m_currentHelper = this;

                m_navmeshComponents.AddComponentTriangle(triangle, triangle.Center);
                triangle.ComponentIndex = m_currentComponentMarker;
                m_tmpComponentTriangles.Add(triangle);

                m_mesh.PrepareTraversal(triangle, null, m_processTrianglePredicate);
                m_mesh.PerformTraversal();
                ProfilerShort.End();

                m_tmpComponentTriangles.Add(null); // Mark end of component in m_tmpComponentTriangles
                m_navmeshComponents.CloseComponent();

                timeEnd = m_mesh.GetCurrentTimestamp();
                m_currentComponentRel++;
            }

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

            ProfilerShort.End();
            return cellInfo;
        }
Esempio n. 16
0
        public void ProcessCellComponents()
        {
            ProfilerShort.Begin("ProcessCellComponents");
            m_triangleLists.Add(m_packedCoord, m_triangleList.GetCopy());

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

            m_currentComponentRel = 0;
            m_currentComponent    = m_navmeshComponents.OpenCell(m_packedCoord);

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

                m_navmeshComponents.OpenComponent();

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

                // Find connected component from an unvisited triangle
                ProfilerShort.Begin("Graph traversal");
                m_currentHelper = this;

                m_navmeshComponents.AddComponentTriangle(triangle, triangle.Center);
                triangle.ComponentIndex = m_navmeshComponents.OpenComponentIndex;
                m_mesh.PrepareTraversal(triangle, null, m_processTrianglePredicate);

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

                m_navmeshComponents.CloseComponent();

                timeEnd = m_mesh.GetCurrentTimestamp();
                m_currentComponentRel++;
            }

            MyNavmeshComponents.ClosedCellInfo cellInfo = new MyNavmeshComponents.ClosedCellInfo();
            m_navmeshComponents.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_navmeshComponents.GetComponentCenter(i));
                }
            }

            // Connect new components with the others in the neighboring cells
            for (int i = 0; i < cellInfo.ComponentNum; ++i)
            {
                foreach (var connectionInfo in m_currentCellConnections[i])
                {
                    if (!cellInfo.ExploredDirections.HasFlag(Base6Directions.GetDirectionFlag(connectionInfo.Direction)))
                    {
                        m_mesh.HighLevelGroup.ConnectPrimitives(cellInfo.StartingIndex + i, connectionInfo.ComponentIndex);
                    }
                }
                m_currentCellConnections[i].Clear();
            }

            // Mark explored directions in the navmesh component helper
            foreach (var direction in Base6Directions.EnumDirections)
            {
                var dirFlag = Base6Directions.GetDirectionFlag(direction);
                if (cellInfo.ExploredDirections.HasFlag(dirFlag))
                {
                    continue;
                }

                Vector3I dirVec = Base6Directions.GetIntVector(direction);

                MyCellCoord otherCoord = new MyCellCoord();
                otherCoord.Lod        = MyVoxelNavigationMesh.NAVMESH_LOD;
                otherCoord.CoordInLod = m_currentCell + dirVec;
                if (otherCoord.CoordInLod.X == -1 || otherCoord.CoordInLod.Y == -1 || otherCoord.CoordInLod.Z == -1)
                {
                    continue;
                }

                ulong otherPackedCoord = otherCoord.PackId64();

                if (m_triangleLists.ContainsKey(otherPackedCoord))
                {
                    m_navmeshComponents.MarkExplored(otherPackedCoord, Base6Directions.GetFlippedDirection(direction));
                    cellInfo.ExploredDirections |= Base6Directions.GetDirectionFlag(direction);
                }
            }
            m_navmeshComponents.SetExplored(m_packedCoord, cellInfo.ExploredDirections);

            // 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;
                }
            }

            ProfilerShort.End();
        }