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];
}
}
}
}
}