public MyGridHighLevelHelper(MyGridNavigationMesh mesh, Dictionary <Vector3I, List <int> > triangleRegistry, Vector3I cellSize) { m_mesh = mesh; m_cellSize = cellSize; m_packedCoord = 0; m_currentCellConnections = new List <List <int> >(); m_changedCells = new MyVector3ISet(); m_changedCubes = new MyVector3ISet(); m_triangleRegistry = triangleRegistry; m_components = new MyNavmeshComponents(); }
public MyGridHighLevelHelper(MyGridNavigationMesh mesh, Dictionary<Vector3I, List<int>> triangleRegistry, Vector3I cellSize) { m_mesh = mesh; m_cellSize = cellSize; m_packedCoord = 0; m_currentCellConnections = new List<List<int>>(); m_changedCells = new MyVector3ISet(); m_changedCubes = new MyVector3ISet(); m_triangleRegistry = triangleRegistry; m_components = new MyNavmeshComponents(); }
public void Update() { if (this.m_highLevelNavigationDirty) { foreach (KeyValuePair <MyCubeGrid, MyGridNavigationMesh> pair in this.m_navigationMeshes) { MyGridNavigationMesh mesh = pair.Value; if (mesh.HighLevelDirty) { mesh.UpdateHighLevel(); } } this.m_highLevelNavigationDirty = false; } }
private void FixCubeFace(ref Vector3I pos, ref Vector3I dir) { if (this.m_cubeSet.Contains(ref pos)) { MySlimBlock cubeBlock = this.m_grid.GetCubeBlock(pos); MyCompoundCubeBlock fatBlock = cubeBlock.FatBlock as MyCompoundCubeBlock; if (fatBlock != null) { ListReader <MySlimBlock> blocks = fatBlock.GetBlocks(); MySlimBlock block3 = null; foreach (MySlimBlock block4 in blocks) { if (block4.BlockDefinition.NavigationDefinition != null) { block3 = block4; break; } } if (block3 != null) { cubeBlock = block3; } } if (cubeBlock.BlockDefinition.NavigationDefinition != null) { MatrixI xi2; Vector3I vectori; Vector3I vectori2; List <int> list; MatrixI matrix = new MatrixI(cubeBlock.Position, cubeBlock.Orientation.Forward, cubeBlock.Orientation.Up); MatrixI.Invert(ref matrix, out xi2); Vector3I.Transform(ref pos, ref xi2, out vectori); Vector3I.TransformNormal(ref dir, ref xi2, out vectori2); MyGridNavigationMesh mesh = cubeBlock.BlockDefinition.NavigationDefinition.Mesh; if ((mesh != null) && mesh.m_smallTriangleRegistry.TryGetValue(vectori, out list)) { foreach (int num in list) { MyNavigationTriangle triangle = mesh.GetTriangle(num); if (this.IsFaceTriangle(triangle, vectori, vectori2)) { this.CopyTriangle(triangle, vectori, ref matrix); } } } } } }
public List <Vector4D> FindPathGlobal(MyCubeGrid startGrid, MyCubeGrid endGrid, ref Vector3D start, ref Vector3D end) { Debug.Assert(startGrid == endGrid, "Pathfinding between different grids not implemented yet!"); if (startGrid != endGrid) { return(null); } Vector3D tformedStart = Vector3D.Transform(start, startGrid.PositionComp.WorldMatrixInvScaled); Vector3D tformedEnd = Vector3D.Transform(end, endGrid.PositionComp.WorldMatrixInvScaled); MyGridNavigationMesh mesh = null; if (m_navigationMeshes.TryGetValue(startGrid, out mesh)) { return(mesh.FindPath(tformedStart, tformedEnd)); } return(null); }
public void RemoveGridNavmeshLinks(MyCubeGrid grid) { MyGridNavigationMesh navmesh = this.m_gridPathfinding.GetNavmesh(grid); if (navmesh != null) { m_tmpNavPrims.Clear(); MyVector3ISet.Enumerator cubes = navmesh.GetCubes(); while (cubes.MoveNext()) { int num; MyGridPathfinding.CubeId key = new MyGridPathfinding.CubeId { Grid = grid, Coords = cubes.Current }; if (this.m_gridLinkCounter.TryGetValue(key, out num)) { m_tmpNavTris.Clear(); navmesh.GetCubeTriangles(cubes.Current, m_tmpNavTris); foreach (MyNavigationTriangle triangle in m_tmpNavTris) { this.m_links.RemoveAllLinks(triangle); MyHighLevelPrimitive highLevelPrimitive = triangle.GetHighLevelPrimitive(); if (!m_tmpNavPrims.Contains(highLevelPrimitive)) { m_tmpNavPrims.Add(highLevelPrimitive); } } m_tmpNavTris.Clear(); this.m_gridLinkCounter.Remove(key); } } cubes.Dispose(); foreach (MyNavigationPrimitive primitive2 in m_tmpNavPrims) { this.m_highLevelLinks.RemoveAllLinks(primitive2); } m_tmpNavPrims.Clear(); } }
public void Update() { if (m_highLevelNavigationDirty) { ProfilerShort.Begin("MyGridPathfinding.Update"); foreach (var entry in m_navigationMeshes) { MyGridNavigationMesh navMesh = entry.Value; if (!navMesh.HighLevelDirty) { continue; } navMesh.UpdateHighLevel(); } m_highLevelNavigationDirty = false; ProfilerShort.End(); } }
public MyBlockNavigationDefinition() { m_mesh = null; NoEntry = false; }
public Component(MyGridNavigationMesh parent, int componentIndex) { m_parent = parent; m_componentIndex = componentIndex; }
private void MergeFromAnotherMesh(MyGridNavigationMesh otherMesh, ref MatrixI transform) { ProfilerShort.Begin("MergeFromAnotherMesh"); m_mergeHelper.Clear(); // Save the cubes from the other mesh that are touching cubes of this mesh into a helper set. // Also put the touched cubes from this mesh into the set. foreach (var position in otherMesh.m_smallTriangleRegistry.Keys) { bool add = false; foreach (var direction in Base6Directions.IntDirections) { // CH: TODO: We query the grid so far, but in the future, we should make sure that the access is thread-safe Vector3I pos = Vector3I.Transform(position + direction, transform); if (m_cubeSet.Contains(ref pos)) // Test the transformed position... { m_mergeHelper.Add(position + direction); // ... but add the original one add = true; } } if (add) { m_mergeHelper.Add(position); } } foreach (var entry in otherMesh.m_smallTriangleRegistry) { Vector3I originalCube = entry.Key; Vector3I tformedCube; Vector3I.Transform(ref originalCube, ref transform, out tformedCube); // If the cube is one of the touching cubes, we have to intersect the touching triangles if (m_mergeHelper.Contains(originalCube)) { // Take the touching pairs one by one and calculate triangulation of the disjoint union of the opposing faces // Remove the opposing faces from the old block // Add the triangulation to the mesh // Add the rest of the navmesh from this block to the mesh m_tmpTriangleList.Clear(); // CH: TODO. Just remove the triangles now foreach (var direction in Base6Directions.EnumDirections) { Vector3I directionVec = Base6Directions.GetIntVector((int)direction); Base6Directions.Direction tformedDirection = transform.GetDirection(direction); Vector3I tformedFlippedVec = Base6Directions.GetIntVector((int)Base6Directions.GetFlippedDirection(tformedDirection)); // Remove face triangles from this mesh if (m_mergeHelper.Contains(originalCube + directionVec)) { List <int> triList = null; if (m_smallTriangleRegistry.TryGetValue(tformedCube - tformedFlippedVec, out triList)) { foreach (var index in triList) { var triangle = GetTriangle(index); // CH: TODO: This will probably be expensive. Could we precalculate it? if (IsFaceTriangle(triangle, tformedCube - tformedFlippedVec, tformedFlippedVec)) { m_tmpTriangleList.Add(new KeyValuePair <MyNavigationTriangle, Vector3I>(triangle, tformedCube - tformedFlippedVec)); } } } } } foreach (var triangle in m_tmpTriangleList) { RemoveTriangle(triangle.Key, triangle.Value); } m_tmpTriangleList.Clear(); int debugCounter = 0; // CH: TODO: optimize this (actually whole this method) foreach (var triangleIndex in entry.Value) { var triangle = otherMesh.GetTriangle(triangleIndex); Vector3I pos = entry.Key; bool addTriangle = true; foreach (var direction in Base6Directions.EnumDirections) { Vector3I dirvec = Base6Directions.GetIntVector((int)direction); if (m_mergeHelper.Contains(pos + dirvec) && IsFaceTriangle(triangle, pos, dirvec)) { addTriangle = false; break; } } if (addTriangle) { if (debugCounter == 5) { } CopyTriangle(triangle, pos, ref transform); debugCounter++; } } } // Otherwise, we just transform the triangles from the other mesh and add them to this mesh else { foreach (var triangleIndex in entry.Value) { var triangle = otherMesh.GetTriangle(triangleIndex); CopyTriangle(triangle, entry.Key, ref transform); //if (triangleIndex > 1) break; } } } m_mergeHelper.Clear(); ProfilerShort.End(); }
public MyBlockNavigationDefinition() { m_mesh = null; NoEntry = false; }
protected override void Init(MyObjectBuilder_DefinitionBase ob) { base.Init(ob); var objectBuilder = ob as MyObjectBuilder_BlockNavigationDefinition; Debug.Assert(ob != null); if (ob == null) return; if (objectBuilder.NoEntry || objectBuilder.Triangles == null) { NoEntry = true; } else { NoEntry = false; var newMesh = new MyGridNavigationMesh(null, null, objectBuilder.Triangles.Length); Vector3I maxPos = objectBuilder.Size - Vector3I.One - objectBuilder.Center; Vector3I minPos = - (Vector3I)(objectBuilder.Center); foreach (var triOb in objectBuilder.Triangles) { Vector3 pa = (Vector3)triOb.Points[0]; Vector3 pb = (Vector3)triOb.Points[1]; Vector3 pc = (Vector3)triOb.Points[2]; var tri = newMesh.AddTriangle(ref pa, ref pb, ref pc); var center = (pa + pb + pc) / 3.0f; // We want to move the triangle vertices more towards the triangle center to ensure correct calculation of containing cube Vector3 cvA = (center - pa) * 0.0001f; Vector3 cvB = (center - pb) * 0.0001f; Vector3 cvC = (center - pc) * 0.0001f; Vector3I gridPosA = Vector3I.Round(pa + cvA); Vector3I gridPosB = Vector3I.Round(pb + cvB); Vector3I gridPosC = Vector3I.Round(pc + cvC); Vector3I.Clamp(ref gridPosA, ref minPos, ref maxPos, out gridPosA); Vector3I.Clamp(ref gridPosB, ref minPos, ref maxPos, out gridPosB); Vector3I.Clamp(ref gridPosC, ref minPos, ref maxPos, out gridPosC); Vector3I min, max; Vector3I.Min(ref gridPosA, ref gridPosB, out min); Vector3I.Min(ref min, ref gridPosC, out min); Vector3I.Max(ref gridPosA, ref gridPosB, out max); Vector3I.Max(ref max, ref gridPosC, out max); Vector3I pos = min; for (var it = new Vector3I.RangeIterator(ref min, ref max); it.IsValid(); it.GetNext(out pos)) { newMesh.RegisterTriangle(tri, ref pos); } } m_mesh = newMesh; } }
protected override unsafe void Init(MyObjectBuilder_DefinitionBase ob) { base.Init(ob); MyObjectBuilder_BlockNavigationDefinition definition = ob as MyObjectBuilder_BlockNavigationDefinition; if (ob != null) { if (definition.NoEntry || (definition.Triangles == null)) { this.NoEntry = true; } else { this.NoEntry = false; MyGridNavigationMesh mesh = new MyGridNavigationMesh(null, null, definition.Triangles.Length, null); Vector3I max = (Vector3I)((definition.Size - Vector3I.One) - definition.Center); Vector3I min = (Vector3I) - definition.Center; MyObjectBuilder_BlockNavigationDefinition.Triangle[] triangles = definition.Triangles; int index = 0; while (index < triangles.Length) { Vector3I vectori6; Vector3I vectori7; MyObjectBuilder_BlockNavigationDefinition.Triangle triangle1 = triangles[index]; Vector3 a = (Vector3)triangle1.Points[0]; Vector3 b = (Vector3)triangle1.Points[1]; Vector3 c = (Vector3)triangle1.Points[2]; MyNavigationTriangle tri = mesh.AddTriangle(ref a, ref b, ref c); Vector3 vector4 = ((((a + b) + c) / 3f) - a) * 0.0001f; Vector3 vector5 = ((((a + b) + c) / 3f) - b) * 0.0001f; Vector3 vector6 = ((((a + b) + c) / 3f) - c) * 0.0001f; Vector3I result = Vector3I.Round(a + vector4); Vector3I vectori4 = Vector3I.Round(b + vector5); Vector3I vectori5 = Vector3I.Round(c + vector6); Vector3I *vectoriPtr1 = (Vector3I *)ref result; Vector3I.Clamp(ref (Vector3I) ref vectoriPtr1, ref min, ref max, out result); Vector3I *vectoriPtr2 = (Vector3I *)ref vectori4; Vector3I.Clamp(ref (Vector3I) ref vectoriPtr2, ref min, ref max, out vectori4); Vector3I *vectoriPtr3 = (Vector3I *)ref vectori5; Vector3I.Clamp(ref (Vector3I) ref vectoriPtr3, ref min, ref max, out vectori5); Vector3I.Min(ref result, ref vectori4, out vectori6); Vector3I *vectoriPtr4 = (Vector3I *)ref vectori6; Vector3I.Min(ref (Vector3I) ref vectoriPtr4, ref vectori5, out vectori6); Vector3I.Max(ref result, ref vectori4, out vectori7); Vector3I *vectoriPtr5 = (Vector3I *)ref vectori7; Vector3I.Max(ref (Vector3I) ref vectoriPtr5, ref vectori5, out vectori7); Vector3I gridPos = vectori6; Vector3I_RangeIterator iterator = new Vector3I_RangeIterator(ref vectori6, ref vectori7); while (true) { if (!iterator.IsValid()) { index++; break; } mesh.RegisterTriangle(tri, ref gridPos); iterator.GetNext(out gridPos); } } this.m_mesh = mesh; } } }
private void MergeFromAnotherMesh(MyGridNavigationMesh otherMesh, ref MatrixI transform) { int num; m_mergeHelper.Clear(); foreach (Vector3I vectori in otherMesh.m_smallTriangleRegistry.Keys) { bool flag = false; Vector3I[] intDirections = Base6Directions.IntDirections; num = 0; while (true) { if (num >= intDirections.Length) { if (flag) { m_mergeHelper.Add(vectori); } break; } Vector3I vectori2 = intDirections[num]; Vector3I position = Vector3I.Transform((Vector3I)(vectori + vectori2), (MatrixI)transform); if (this.m_cubeSet.Contains(ref position)) { m_mergeHelper.Add(vectori + vectori2); flag = true; } num++; } } using (Dictionary <Vector3I, List <int> > .Enumerator enumerator2 = otherMesh.m_smallTriangleRegistry.GetEnumerator()) { while (true) { while (true) { if (enumerator2.MoveNext()) { Vector3I vectori5; KeyValuePair <Vector3I, List <int> > current = enumerator2.Current; Vector3I key = current.Key; Vector3I.Transform(ref key, ref transform, out vectori5); if (m_mergeHelper.Contains(key)) { m_tmpTriangleList.Clear(); Base6Directions.Direction[] enumDirections = Base6Directions.EnumDirections; num = 0; while (true) { if (num < enumDirections.Length) { Base6Directions.Direction direction = enumDirections[num]; Vector3I intVector = Base6Directions.GetIntVector((int)direction); Vector3I vectori7 = Base6Directions.GetIntVector((int)Base6Directions.GetFlippedDirection(transform.GetDirection(direction))); if (m_mergeHelper.Contains(key + intVector)) { List <int> list = null; if (this.m_smallTriangleRegistry.TryGetValue(vectori5 - vectori7, out list)) { foreach (int num3 in list) { MyNavigationTriangle triangle = base.GetTriangle(num3); if (this.IsFaceTriangle(triangle, vectori5 - vectori7, vectori7)) { m_tmpTriangleList.Add(new KeyValuePair <MyNavigationTriangle, Vector3I>(triangle, vectori5 - vectori7)); } } } } num++; continue; } foreach (KeyValuePair <MyNavigationTriangle, Vector3I> pair2 in m_tmpTriangleList) { this.RemoveTriangle(pair2.Key, pair2.Value); } m_tmpTriangleList.Clear(); int num2 = 0; foreach (int num4 in current.Value) { MyNavigationTriangle triangle = otherMesh.GetTriangle(num4); Vector3I cubePosition = current.Key; bool flag2 = true; enumDirections = Base6Directions.EnumDirections; num = 0; while (true) { if (num < enumDirections.Length) { Vector3I intVector = Base6Directions.GetIntVector((int)enumDirections[num]); if (!m_mergeHelper.Contains(cubePosition + intVector) || !this.IsFaceTriangle(triangle, cubePosition, intVector)) { num++; continue; } flag2 = false; } if (flag2) { int num6 = num2; this.CopyTriangle(triangle, cubePosition, ref transform); num2++; } break; } } } } foreach (int num5 in current.Value) { MyNavigationTriangle triangle = otherMesh.GetTriangle(num5); this.CopyTriangle(triangle, current.Key, ref transform); } } else { goto TR_0000; } } } } TR_0000: m_mergeHelper.Clear(); }
public Component(MyGridNavigationMesh parent, int componentIndex) { m_parent = parent; m_componentIndex = componentIndex; }
private void MergeFromAnotherMesh(MyGridNavigationMesh otherMesh, ref MatrixI transform) { ProfilerShort.Begin("MergeFromAnotherMesh"); m_mergeHelper.Clear(); // Save the cubes from the other mesh that are touching cubes of this mesh into a helper set. // Also put the touched cubes from this mesh into the set. foreach (var position in otherMesh.m_smallTriangleRegistry.Keys) { bool add = false; foreach (var direction in Base6Directions.IntDirections) { // CH: TODO: We query the grid so far, but in the future, we should make sure that the access is thread-safe Vector3I pos = Vector3I.Transform(position + direction, transform); if (m_cubeSet.Contains(ref pos)) // Test the transformed position... { m_mergeHelper.Add(position + direction); // ... but add the original one add = true; } } if (add) m_mergeHelper.Add(position); } foreach (var entry in otherMesh.m_smallTriangleRegistry) { Vector3I originalCube = entry.Key; Vector3I tformedCube; Vector3I.Transform(ref originalCube, ref transform, out tformedCube); // If the cube is one of the touching cubes, we have to intersect the touching triangles if (m_mergeHelper.Contains(originalCube)) { // Take the touching pairs one by one and calculate triangulation of the disjoint union of the opposing faces // Remove the opposing faces from the old block // Add the triangulation to the mesh // Add the rest of the navmesh from this block to the mesh m_tmpTriangleList.Clear(); // CH: TODO. Just remove the triangles now foreach (var direction in Base6Directions.EnumDirections) { Vector3I directionVec = Base6Directions.GetIntVector((int)direction); Base6Directions.Direction tformedDirection = transform.GetDirection(direction); Vector3I tformedFlippedVec = Base6Directions.GetIntVector((int)Base6Directions.GetFlippedDirection(tformedDirection)); // Remove face triangles from this mesh if (m_mergeHelper.Contains(originalCube + directionVec)) { List<int> triList = null; if (m_smallTriangleRegistry.TryGetValue(tformedCube - tformedFlippedVec, out triList)) { foreach (var index in triList) { var triangle = GetTriangle(index); // CH: TODO: This will probably be expensive. Could we precalculate it? if (IsFaceTriangle(triangle, tformedCube - tformedFlippedVec, tformedFlippedVec)) m_tmpTriangleList.Add(new KeyValuePair<MyNavigationTriangle, Vector3I>(triangle, tformedCube - tformedFlippedVec)); } } } } foreach (var triangle in m_tmpTriangleList) { RemoveTriangle(triangle.Key, triangle.Value); } m_tmpTriangleList.Clear(); int debugCounter = 0; // CH: TODO: optimize this (actually whole this method) foreach (var triangleIndex in entry.Value) { var triangle = otherMesh.GetTriangle(triangleIndex); Vector3I pos = entry.Key; bool addTriangle = true; foreach (var direction in Base6Directions.EnumDirections) { Vector3I dirvec = Base6Directions.GetIntVector((int)direction); if (m_mergeHelper.Contains(pos + dirvec) && IsFaceTriangle(triangle, pos, dirvec)) { addTriangle = false; break; } } if (addTriangle) { if (debugCounter == 5) { } CopyTriangle(triangle, pos, ref transform); debugCounter++; } } } // Otherwise, we just transform the triangles from the other mesh and add them to this mesh else { foreach (var triangleIndex in entry.Value) { var triangle = otherMesh.GetTriangle(triangleIndex); CopyTriangle(triangle, entry.Key, ref transform); //if (triangleIndex > 1) break; } } } m_mergeHelper.Clear(); ProfilerShort.End(); }