/// <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 }); }
protected override void LoadContent() { // Load shader, set up settings var black = Game.Content.Load <Texture2D>("Textures/black"); basicShader = Game.Content.Load <Effect>("Shaders/BasicColorMapped"); basicShader.CurrentTechnique = basicShader.Techniques["DefaultTechnique"]; basicShader.Parameters["ColorMapTexture"].SetValue(black); basicShader.Parameters["ColorInfluence"].SetValue(1.0f); basicShader.Parameters["FogColor"].SetValue(SkyColor.ToVector4()); basicShader.Parameters["FogEndDistance"].SetValue(FogDistance); // Load models, decoration and biome data var modelLoader = new AtlasModelLoader(2048, 2048, basicShader, Game.Content); var decorationData = orbis.Content.Load <XMLModel.DecorationCollection>("Config/Decorations"); var decorationManager = new DecorationManager(decorationData, modelLoader, GraphicsDevice); // Load decorations foreach (var data in decorationData.Decorations) { decorations.Add(data.Name, new DecorationPool(decorationManager.GetDecorationMesh(data.Name), GraphicsDevice, 1)); } var biomeData = orbis.Content.Load <XMLModel.BiomeCollection>("Config/Biomes"); biomeMappedData = new Dictionary <string, BiomeMappedData>(); // Load biomes foreach (var biome in biomeData.Biomes) { biomeMappedData.Add(biome.Name, new BiomeMappedData { HexMesh = modelLoader.LoadModel(biome.HexModel.Name, biome.HexModel.Texture, biome.HexModel.ColorTexture).Mesh, DefaultDecoration = biome.DefaultDecoration, DefaultDensity = biome.DecorationDensity, }); } // Load tile highlight mesh var model = modelLoader.LoadModel("flag", "flag"); tileHighlightMesh = new RenderableMesh(GraphicsDevice, model.Mesh); modelLoader.FinializeLoading(GraphicsDevice); // Set up shader textures basicShader.Parameters["MainTexture"].SetValue(modelLoader.Material.Texture); basicShader.Parameters["ColorMapTexture"].SetValue(modelLoader.Material.ColorMap); if (atlasDebugEnabled) { // Atlas texture debugging Mesh mesh = null; using (var stream = TitleContainer.OpenStream("Content/Meshes/quad_up.obj")) { mesh = ObjParser.FromStream(stream); } atlasDebugInstance = new RenderInstance { mesh = new RenderableMesh(GraphicsDevice, mesh), matrix = Matrix.CreateScale(10) * Matrix.CreateTranslation(0, 0, 30), }; basicShader.Parameters["ColorMapTexture"].SetValue(black); } base.LoadContent(); }