Ejemplo n.º 1
0
        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);
        }