示例#1
0
        /// <summary>
        /// Sets the decoration for a specific cell
        /// </summary>
        /// <param name="cell">The cell to set for</param>
        /// <param name="cellMappedData">The cell's mapped data</param>
        /// <param name="mesh">The decoration mesh</param>
        private void SetCellDecoration(Cell cell, CellMappedData cellMappedData, string decoration)
        {
            if (cellMappedData.Decoration.Key == decoration)
            {
                return;
            }

            // Free old decoration
            if (cellMappedData.Decoration.Key != null)
            {
                this.decorations[cellMappedData.Decoration.Key].FreeIndex(cellMappedData.Decoration.Value);
            }

            // Set new decoration
            if (decoration != null && decoration.Length > 0)
            {
                var index = this.decorations[decoration].GetFreeIndex();
                cellMappedData.Decoration = new KeyValuePair <string, int>(decoration, index);
                this.decorations[decoration].SetPosition(index, new Vector3(TopographyHelper.HexToWorld(cell.Coordinates), (float)cell.Elevation));
            }
            else
            {
                cellMappedData.Decoration = new KeyValuePair <string, int>(null, 0);
            }
        }
示例#2
0
        /// <summary>
        /// Generates terrain meshes, cell and biome data from a scene. Can be put in a task.
        /// </summary>
        /// <param name="scene">The scene to generate from</param>
        /// <returns>Results</returns>
        private MeshGenerationResult GenerateMeshesFromScene(Scene scene)
        {
            // Results
            var renderableMeshes = new List <RenderableMesh>();
            var rawMeshes        = new List <Mesh>();
            var cellData         = new Dictionary <Cell, CellMappedData>();
            // Stopwatch used for performance logging
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            // Create world meshes
            var hexCombiner = new MeshCombiner();
            int range       = scene.WorldMap.Radius;

            for (int p = -range; p <= range; p++)
            {
                for (int q = -range; q <= range; q++)
                {
                    var cell = scene.WorldMap.GetCell(p, q);
                    // Due to the hexagonal shape we might be out of bounds
                    if (cell == null)
                    {
                        continue;
                    }

                    var  worldPoint = TopographyHelper.HexToWorld(new Point(p, q));
                    var  position   = new Vector3(worldPoint, (float)cell.Elevation);
                    var  color      = GetCellColor(cell);
                    Mesh mesh       = biomeMappedData[cell.Biome.Name].HexMesh;

                    // Ensure sea is actually level
                    if (cell.IsWater && cell.Elevation < scene.Settings.SeaLevel)
                    {
                        position.Z = scene.Settings.SeaLevel;
                    }

                    // Add it to the combiner, using the cell's location as a tag so we can later
                    // get the vertexes of this hex inside the larger mesh
                    int meshIndex = hexCombiner.Add(new MeshInstance
                    {
                        mesh     = mesh,
                        matrix   = Matrix.CreateTranslation(position),
                        tag      = new Point(p, q),
                        color    = color,
                        useColor = true,
                    });

                    // Register partial cell mapped data to be used later
                    var cellMappedData = new CellMappedData
                    {
                        MeshIndex = meshIndex
                    };
                    cellData[cell] = cellMappedData;
                }
            }

            // Combine meshes
            var meshList = hexCombiner.GetCombinedMeshes();

            for (int i = 0; i < meshList.Count; i++)
            {
                var renderable = new RenderableMesh(orbis.GraphicsDevice, meshList[i]);
                renderableMeshes.Add(renderable);
            }
            // Finish cell mapped data
            foreach (var cell in cellData)
            {
                var mesh = meshList[cell.Value.MeshIndex];
                cell.Value.VertexIndexes = mesh.TagIndexMap[cell.Key.Coordinates];
            }

            stopwatch.Stop();
            Debug.WriteLine("Generated " + renderableMeshes.Count + " meshes in " + stopwatch.ElapsedMilliseconds + " ms");

            return(new MeshGenerationResult {
                cellData = cellData,
                rawMeshes = rawMeshes,
                renderableMeshes = renderableMeshes
            });
        }