using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Content; using LibNoise; using LibNoise.Modifiers; namespace PlanetTest { /// /// Using LibNoise: /// http://libnoisedotnet.codeplex.com/SourceControl/changeset/view/13259#230817 /// Copyright (c) 2008 Jason Bell /// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), /// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, /// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: /// class PlanetTerrainMap { //using a jagged array instead of multidimensional supposedly increases performance public double[][] Heights { get; set; } public int Size { get; set; } public Color[] colors; public Texture2D colorScaleTexture; public Color[] colorScale; public Texture2D Image; public PlanetTerrainMap(int size) { Size = size; Heights = new double[Size][]; for (int i = 0; i < Size; i++) Heights[i] = new double[Size]; } public PlanetTerrainMap(int size, int seed, GraphicsDevice graphics, ContentManager Content) : this(size) { //load the color texture colorScaleTexture = Content.Load("EarthLookupTable"); //load the colors from the scale colorScale = new Color[colorScaleTexture.Width * colorScaleTexture.Height]; colorScaleTexture.GetData(colorScale); colors = new Color[size * size]; //generate the planet map GenerateFastPlanet(seed, 10, 0.2, 2.0, 1.0); //create the planet map image Image = new Texture2D(graphics, size, size); Image.SetData(colors); } private void GenerateFastPlanet(int seed, int octaves, double frequency, double lacunarity, double persistence) { IModule module; FastNoise fastPlanetContinents = new FastNoise(seed); fastPlanetContinents.Frequency = 1.5; FastBillow fastPlanetLowlands = new FastBillow(); fastPlanetLowlands.Frequency = 4; LibNoise.Modifiers.ScaleBiasOutput fastPlanetLowlandsScaled = new ScaleBiasOutput(fastPlanetLowlands); fastPlanetLowlandsScaled.Scale = 0.2; fastPlanetLowlandsScaled.Bias = 0.5; FastRidgedMultifractal fastPlanetMountainsBase = new FastRidgedMultifractal(seed); fastPlanetMountainsBase.Frequency = 4; ScaleBiasOutput fastPlanetMountainsScaled = new ScaleBiasOutput(fastPlanetMountainsBase); fastPlanetMountainsScaled.Scale = 0.4; fastPlanetMountainsScaled.Bias = 0.85; FastTurbulence fastPlanetMountains = new FastTurbulence(fastPlanetMountainsScaled); fastPlanetMountains.Power = 0.1; fastPlanetMountains.Frequency = 50; FastNoise fastPlanetLandFilter = new FastNoise(seed + 1); fastPlanetLandFilter.Frequency = 6; Select fastPlanetLand = new Select(fastPlanetLandFilter, fastPlanetLowlandsScaled, fastPlanetMountains); fastPlanetLand.SetBounds(0, 1000); fastPlanetLand.EdgeFalloff = 0.5; FastBillow fastPlanetOceanBase = new FastBillow(seed); fastPlanetOceanBase.Frequency = 15; ScaleOutput fastPlanetOcean = new ScaleOutput(fastPlanetOceanBase, 0.1); Select fastPlanetFinal = new Select(fastPlanetContinents, fastPlanetOcean, fastPlanetLand); fastPlanetFinal.SetBounds(0, 1000); fastPlanetFinal.EdgeFalloff = 0.5; module = fastPlanetFinal; LibNoise.Models.Sphere sphere = new LibNoise.Models.Sphere(module); double value; for (int x = 0; x < Size; x++) { for (int y = 0; y < Size; y++) { //convert to sphere coordinates int offsetX = -(x - 512); int offsetY = -(y - 512); double longitude = offsetY / 5.6888888888; if (longitude > 90.0) longitude = 90.0; if (longitude < -90.0) longitude = -90.0; double latitude = offsetX / 2.844444444; if (latitude > 180.0) latitude = 180.0; if (latitude < -190.0) latitude = -180.0; value = sphere.GetValue(longitude, latitude); //save this as the height data Heights[x][y] = value; if (value < 0) value = 0; if (value > 1.0) value = 1.0; int index = (int)(value * colorScale.Length); if (index >= colorScale.Length) index = colorScale.Length - 1; colors[x * y] = colorScale[index]; } } } } }