1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.Xna.Framework;
  6. using Microsoft.Xna.Framework.Graphics;
  7. using Microsoft.Xna.Framework.Content;
  8. using LibNoise;
  9. using LibNoise.Modifiers;
  10.  
  11. namespace PlanetTest
  12. {
  13.     /// <summary>
  14.     /// Using LibNoise:
  15.     /// http://libnoisedotnet.codeplex.com/SourceControl/changeset/view/13259#230817
  16.     /// Copyright (c) 2008 Jason Bell
  17.     /// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
  18.     /// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
  19.     /// 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:
  20.     /// </summary>
  21.     class PlanetTerrainMap
  22.     {
  23.         //using a jagged array instead of multidimensional supposedly increases performance
  24.         public double[][] Heights { get; set; }
  25.         public int Size { get; set; }
  26.  
  27.         public Color[] colors;
  28.         public Texture2D colorScaleTexture;
  29.         public Color[] colorScale;
  30.  
  31.         public Texture2D Image;
  32.  
  33.         public PlanetTerrainMap(int size)
  34.         {
  35.             Size = size;
  36.             Heights = new double[Size][];
  37.             for (int i = 0; i < Size; i++)
  38.                 Heights[i] = new double[Size];
  39.         }
  40.  
  41.         public PlanetTerrainMap(int size, int seed, GraphicsDevice graphics, ContentManager Content)
  42.             : this(size)
  43.         {
  44.             //load the color texture
  45.             colorScaleTexture = Content.Load<Texture2D>("EarthLookupTable");
  46.             //load the colors from the scale
  47.             colorScale = new Color[colorScaleTexture.Width * colorScaleTexture.Height];
  48.             colorScaleTexture.GetData<Color>(colorScale);
  49.             colors = new Color[size * size];
  50.             //generate the planet map
  51.             GenerateFastPlanet(seed, 10, 0.2, 2.0, 1.0);
  52.             //create the planet map image
  53.             Image = new Texture2D(graphics, size, size);
  54.             Image.SetData<Color>(colors);
  55.         }
  56.  
  57.         private void GenerateFastPlanet(int seed, int octaves, double frequency, double lacunarity, double persistence)
  58.         {
  59.             IModule module;
  60.  
  61.             FastNoise fastPlanetContinents = new FastNoise(seed);
  62.             fastPlanetContinents.Frequency = 1.5;
  63.  
  64.             FastBillow fastPlanetLowlands = new FastBillow();
  65.             fastPlanetLowlands.Frequency = 4;
  66.             LibNoise.Modifiers.ScaleBiasOutput fastPlanetLowlandsScaled = new ScaleBiasOutput(fastPlanetLowlands);
  67.             fastPlanetLowlandsScaled.Scale = 0.2;
  68.             fastPlanetLowlandsScaled.Bias = 0.5;
  69.  
  70.             FastRidgedMultifractal fastPlanetMountainsBase = new FastRidgedMultifractal(seed);
  71.             fastPlanetMountainsBase.Frequency = 4;
  72.  
  73.             ScaleBiasOutput fastPlanetMountainsScaled = new ScaleBiasOutput(fastPlanetMountainsBase);
  74.             fastPlanetMountainsScaled.Scale = 0.4;
  75.             fastPlanetMountainsScaled.Bias = 0.85;
  76.  
  77.             FastTurbulence fastPlanetMountains = new FastTurbulence(fastPlanetMountainsScaled);
  78.             fastPlanetMountains.Power = 0.1;
  79.             fastPlanetMountains.Frequency = 50;
  80.  
  81.             FastNoise fastPlanetLandFilter = new FastNoise(seed + 1);
  82.             fastPlanetLandFilter.Frequency = 6;
  83.  
  84.             Select fastPlanetLand = new Select(fastPlanetLandFilter, fastPlanetLowlandsScaled, fastPlanetMountains);
  85.             fastPlanetLand.SetBounds(0, 1000);
  86.             fastPlanetLand.EdgeFalloff = 0.5;
  87.  
  88.             FastBillow fastPlanetOceanBase = new FastBillow(seed);
  89.             fastPlanetOceanBase.Frequency = 15;
  90.             ScaleOutput fastPlanetOcean = new ScaleOutput(fastPlanetOceanBase, 0.1);
  91.  
  92.             Select fastPlanetFinal = new Select(fastPlanetContinents, fastPlanetOcean, fastPlanetLand);
  93.             fastPlanetFinal.SetBounds(0, 1000);
  94.             fastPlanetFinal.EdgeFalloff = 0.5;
  95.  
  96.             module = fastPlanetFinal;
  97.  
  98.             LibNoise.Models.Sphere sphere = new LibNoise.Models.Sphere(module);
  99.  
  100.             double value;
  101.  
  102.             for (int x = 0; x < Size; x++)
  103.             {
  104.                 for (int y = 0; y < Size; y++)
  105.                 {
  106.                     //convert to sphere coordinates
  107.                     int offsetX = -(x - 512);
  108.                     int offsetY = -(y - 512);
  109.                     double longitude = offsetY / 5.6888888888;
  110.                     if (longitude > 90.0) longitude = 90.0;
  111.                     if (longitude < -90.0) longitude = -90.0;
  112.                     double latitude = offsetX / 2.844444444;
  113.                     if (latitude > 180.0) latitude = 180.0;
  114.                     if (latitude < -190.0) latitude = -180.0;
  115.                     value = sphere.GetValue(longitude, latitude);
  116.                     //save this as the height data
  117.                     Heights[x][y] = value;
  118.  
  119.                     if (value < 0) value = 0;
  120.                     if (value > 1.0) value = 1.0;
  121.                     int index = (int)(value * colorScale.Length);
  122.                     if (index >= colorScale.Length) index = colorScale.Length - 1;
  123.                     colors[x * y] = colorScale[index];
  124.                 }
  125.             }
  126.         }
  127.     }
  128. }