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