private NavigationMeshDebugVisual CreateDebugVisual(NavigationMesh navigationMesh, NavigationMesh previousNavigationMesh) { NavigationMeshDebugVisual ret = new NavigationMeshDebugVisual(); ret.DebugEntity = new Entity($"Debug entity for navigation mesh"); // Create a visual for every layer with a separate color using (var layers = navigationMesh.Layers.GetEnumerator()) { while (layers.MoveNext()) { Model model = new Model(); var currentLayer = layers.Current.Value; var currentId = layers.Current.Key; NavigationMeshDisplayGroup displayGroup; if (!groupDisplaySettings.TryGetValue(currentId, out displayGroup)) { continue; // No display settings for this group } model.Add(displayGroup.Material); model.Add(displayGroup.HighlightMaterial); foreach (var p in currentLayer.Tiles) { bool updated = true; NavigationMeshTile tile = p.Value; // Extract vertex data List <Vector3> tileVertexList = new List <Vector3>(); List <int> tileIndexList = new List <int>(); if (!tile.GetTileVertices(tileVertexList, tileIndexList)) { continue; } // Check if updated NavigationMeshLayer sourceLayer; if (previousNavigationMesh != null && previousNavigationMesh.Layers.TryGetValue(currentId, out sourceLayer)) { NavigationMeshTile oldTile = sourceLayer.FindTile(p.Key); if (oldTile != null && oldTile.Data.SequenceEqual(tile.Data)) { updated = false; } } // Stack layers vertically Vector3 offset = new Vector3(0.0f, LayerHeightMultiplier * displayGroup.Index, 0.0f); // Calculate mesh bounding box from navigation mesh points BoundingBox bb = BoundingBox.Empty; List <VertexPositionNormalTexture> meshVertices = new List <VertexPositionNormalTexture>(); for (int i = 0; i < tileVertexList.Count; i++) { Vector3 position = tileVertexList[i] + offset; BoundingBox.Merge(ref bb, ref position, out bb); VertexPositionNormalTexture vert = new VertexPositionNormalTexture(); vert.Position = position; vert.Normal = Vector3.UnitY; vert.TextureCoordinate = new Vector2(0.5f, 0.5f); meshVertices.Add(vert); } MeshDraw draw; using (var meshData = new GeometricMeshData <VertexPositionNormalTexture>(meshVertices.ToArray(), tileIndexList.ToArray(), true)) { GeometricPrimitive primitive = new GeometricPrimitive(game.GraphicsDevice, meshData); ret.GeneratedDynamicPrimitives.Add(primitive); draw = primitive.ToMeshDraw(); } Mesh mesh = new Mesh { Draw = draw, MaterialIndex = updated ? 1 : 0, BoundingBox = bb }; model.Add(mesh); } // Create an entity per layer var layerEntity = new Entity($"Navigation group {currentId}"); // Add a new model component var modelComponent = new ModelComponent(model); layerEntity.Add(modelComponent); modelComponent.Enabled = displayGroup.IsVisible; ret.ModelComponents.Add(currentId, modelComponent); ret.DebugEntity.AddChild(layerEntity); } } return(ret); }