From 53e8d91c06b3fc5cf61ba767930fa733a6efb232 Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Fri, 14 Mar 2008 13:37:39 +0000 Subject: * Fixed 'flatten area' brush, so it now has a 'force' instead of instantly flattening the selected area. * Noise, and Noise-Area brushes now use Perlin noise, more closely simulating the method LL uses officially. * TerrainModule has been cleaned up slightly. * TerrainUtil class has several new functions related to seeded noise generation. * Extracted ITerrainEffect, ITerrainFloodEffect, ITerrainLoader, ITerrainPaintableEffect, TerrainChannel to seperate files. --- .../Modules/Terrain/FloodBrushes/FlattenArea.cs | 4 +- .../Modules/Terrain/FloodBrushes/NoiseArea.cs | 67 +-------- .../Environment/Modules/Terrain/ITerrainEffect.cs | 36 +++++ .../Modules/Terrain/ITerrainFloodEffect.cs | 37 +++++ .../Environment/Modules/Terrain/ITerrainLoader.cs | 37 +++++ .../Modules/Terrain/ITerrainPaintableEffect.cs | 36 +++++ .../Modules/Terrain/PaintBrushes/NoiseSphere.cs | 9 +- .../Environment/Modules/Terrain/TerrainChannel.cs | 119 ++++++++++++++++ .../Environment/Modules/Terrain/TerrainModule.cs | 149 ++------------------- .../Environment/Modules/Terrain/TerrainUtil.cs | 55 ++++++++ 10 files changed, 336 insertions(+), 213 deletions(-) create mode 100644 OpenSim/Region/Environment/Modules/Terrain/ITerrainEffect.cs create mode 100644 OpenSim/Region/Environment/Modules/Terrain/ITerrainFloodEffect.cs create mode 100644 OpenSim/Region/Environment/Modules/Terrain/ITerrainLoader.cs create mode 100644 OpenSim/Region/Environment/Modules/Terrain/ITerrainPaintableEffect.cs create mode 100644 OpenSim/Region/Environment/Modules/Terrain/TerrainChannel.cs (limited to 'OpenSim/Region/Environment/Modules/Terrain') diff --git a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/FlattenArea.cs b/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/FlattenArea.cs index 4551f53..007d37e 100644 --- a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/FlattenArea.cs +++ b/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/FlattenArea.cs @@ -58,12 +58,14 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes avg = sum / steps; + double str = 0.1 * strength; // == 0.2 in the default client + for (x = 0; x < map.Width; x++) { for (y = 0; y < map.Height; y++) { if (fillArea[x, y] == true) - map[x, y] = avg; + map[x, y] = (map[x, y] * (1.0 - str)) + (avg * str); } } } diff --git a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/NoiseArea.cs b/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/NoiseArea.cs index 6063b2f..95ad57d 100644 --- a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/NoiseArea.cs +++ b/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/NoiseArea.cs @@ -31,65 +31,6 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes { public class NoiseArea : ITerrainFloodEffect { - private double Noise(int x, int y) - { - // TODO: Seed - int n = x + y * 57; - n = (n<<13) ^ n; - return (1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0); - } - - private double SmoothedNoise1(int x, int y) - { - double corners = (Noise(x - 1, y - 1) + Noise(x + 1, y - 1) + Noise(x - 1, y + 1) + Noise(x + 1, y + 1)) / 16; - double sides = (Noise(x - 1, y) + Noise(x + 1, y) + Noise(x, y - 1) + Noise(x, y + 1)) / 8; - double center = Noise(x, y) / 4; - return corners + sides + center; - } - - private double Interpolate(double x, double y, double z) - { - return (x * (1.0 - z)) + (y * z); - } - - private double InterpolatedNoise(double x, double y) - { - int integer_X = (int)(x); - double fractional_X = x - integer_X; - - int integer_Y = (int)y; - double fractional_Y = y - integer_Y; - - double v1 = SmoothedNoise1(integer_X, integer_Y); - double v2 = SmoothedNoise1(integer_X + 1, integer_Y); - double v3 = SmoothedNoise1(integer_X, integer_Y + 1); - double v4 = SmoothedNoise1(integer_X + 1, integer_Y + 1); - - double i1 = Interpolate(v1, v2, fractional_X); - double i2 = Interpolate(v3, v4, fractional_X); - - return Interpolate(i1, i2, fractional_Y); - } - - private double PerlinNoise2D(double x, double y) - { - int octaves = 1; - double persistence = 0.0005; - - double frequency = 0.0; - double amplitude = 0.0; - double total = 0.0; - - for (int i = 0; i < octaves; i++) - { - frequency = System.Math.Pow(2, i); - amplitude = System.Math.Pow(persistence, i); - - total += InterpolatedNoise(x * frequency, y * frequency) * amplitude; - } - return total; - } - #region ITerrainFloodEffect Members public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) @@ -101,11 +42,9 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes { if (fillArea[x, y] == true) { - lock (OpenSim.Framework.Util.RandomClass) - { - double noise = PerlinNoise2D(x, y);//OpenSim.Framework.Util.RandomClass.NextDouble(); - map[x, y] += (noise /*- 0.5*/) * strength; - } + double noise = TerrainUtil.PerlinNoise2D((double)x / (double)Framework.Constants.RegionSize, (double)y / (double)Framework.Constants.RegionSize, 8, 1.0); + + map[x, y] += noise * strength; } } } diff --git a/OpenSim/Region/Environment/Modules/Terrain/ITerrainEffect.cs b/OpenSim/Region/Environment/Modules/Terrain/ITerrainEffect.cs new file mode 100644 index 0000000..e7fcf68 --- /dev/null +++ b/OpenSim/Region/Environment/Modules/Terrain/ITerrainEffect.cs @@ -0,0 +1,36 @@ +/* +* Copyright (c) Contributors, http://opensimulator.org/ +* See CONTRIBUTORS.TXT for a full list of copyright holders. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the OpenSim Project nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ +using OpenSim.Region.Environment.Interfaces; + +namespace OpenSim.Region.Environment.Modules.Terrain +{ + public interface ITerrainEffect + { + void RunEffect(ITerrainChannel map, double strength); + } +} diff --git a/OpenSim/Region/Environment/Modules/Terrain/ITerrainFloodEffect.cs b/OpenSim/Region/Environment/Modules/Terrain/ITerrainFloodEffect.cs new file mode 100644 index 0000000..aabd19b --- /dev/null +++ b/OpenSim/Region/Environment/Modules/Terrain/ITerrainFloodEffect.cs @@ -0,0 +1,37 @@ +/* +* Copyright (c) Contributors, http://opensimulator.org/ +* See CONTRIBUTORS.TXT for a full list of copyright holders. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the OpenSim Project nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ +using OpenSim.Region.Environment.Interfaces; +using System; + +namespace OpenSim.Region.Environment.Modules.Terrain +{ + public interface ITerrainFloodEffect + { + void FloodEffect(ITerrainChannel map, Boolean[,] fillArea, double strength); + } +} diff --git a/OpenSim/Region/Environment/Modules/Terrain/ITerrainLoader.cs b/OpenSim/Region/Environment/Modules/Terrain/ITerrainLoader.cs new file mode 100644 index 0000000..b67c8f2 --- /dev/null +++ b/OpenSim/Region/Environment/Modules/Terrain/ITerrainLoader.cs @@ -0,0 +1,37 @@ +/* +* Copyright (c) Contributors, http://opensimulator.org/ +* See CONTRIBUTORS.TXT for a full list of copyright holders. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the OpenSim Project nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ +using OpenSim.Region.Environment.Interfaces; + +namespace OpenSim.Region.Environment.Modules.Terrain +{ + public interface ITerrainLoader + { + ITerrainChannel LoadFile(string filename); + void SaveFile(string filename, ITerrainChannel map); + } +} diff --git a/OpenSim/Region/Environment/Modules/Terrain/ITerrainPaintableEffect.cs b/OpenSim/Region/Environment/Modules/Terrain/ITerrainPaintableEffect.cs new file mode 100644 index 0000000..cf1ea4e --- /dev/null +++ b/OpenSim/Region/Environment/Modules/Terrain/ITerrainPaintableEffect.cs @@ -0,0 +1,36 @@ +/* +* Copyright (c) Contributors, http://opensimulator.org/ +* See CONTRIBUTORS.TXT for a full list of copyright holders. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the OpenSim Project nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ +using OpenSim.Region.Environment.Interfaces; + +namespace OpenSim.Region.Environment.Modules.Terrain +{ + public interface ITerrainPaintableEffect + { + void PaintEffect(ITerrainChannel map, double x, double y, double strength, double duration); + } +} diff --git a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/NoiseSphere.cs b/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/NoiseSphere.cs index 4a03a17..9754a99 100644 --- a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/NoiseSphere.cs +++ b/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/NoiseSphere.cs @@ -57,15 +57,10 @@ namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes z *= z; z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); - double noise; - - lock (Util.RandomClass) - { - noise = Util.RandomClass.NextDouble(); - } + double noise = TerrainUtil.PerlinNoise2D((double)x / (double)Framework.Constants.RegionSize, (double)y / (double)Framework.Constants.RegionSize, 8, 1.0); if (z > 0.0) - map[x, y] += (noise - 0.5) * z * duration; + map[x, y] += noise * z * duration; } } } diff --git a/OpenSim/Region/Environment/Modules/Terrain/TerrainChannel.cs b/OpenSim/Region/Environment/Modules/Terrain/TerrainChannel.cs new file mode 100644 index 0000000..59937d1 --- /dev/null +++ b/OpenSim/Region/Environment/Modules/Terrain/TerrainChannel.cs @@ -0,0 +1,119 @@ + +using OpenSim.Framework; +using OpenSim.Region.Environment.Interfaces; + +namespace OpenSim.Region.Environment.Modules.Terrain +{ + + /// + /// A new version of the old Channel class, simplified + /// + public class TerrainChannel : ITerrainChannel + { + private double[,] map; + private bool[,] taint; + + public int Width + { + get { return map.GetLength(0); } + } + + public int Height + { + get { return map.GetLength(1); } + } + + public TerrainChannel Copy() + { + TerrainChannel copy = new TerrainChannel(false); + copy.map = (double[,])this.map.Clone(); + + return copy; + } + + public float[] GetFloatsSerialised() + { + float[] heights = new float[Width * Height]; + int i; + + for (i = 0; i < Width * Height; i++) + { + heights[i] = (float)map[i % Width, i / Width]; + } + + return heights; + } + + public double[,] GetDoubles() + { + return map; + } + + public double this[int x, int y] + { + get + { + return map[x, y]; + } + set + { + if (map[x, y] != value) + { + taint[x / 16, y / 16] = true; + map[x, y] = value; + } + } + } + + public bool Tainted(int x, int y) + { + if (taint[x / 16, y / 16] != false) + { + taint[x / 16, y / 16] = false; + return true; + } + else + { + return false; + } + } + + public TerrainChannel() + { + map = new double[Constants.RegionSize, Constants.RegionSize]; + taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16]; + + int x, y; + for (x = 0; x < Constants.RegionSize; x++) + { + for (y = 0; y < Constants.RegionSize; y++) + { + map[x, y] = 60.0 - // 60 = Sphere Radius + ((x - (Constants.RegionSize / 2)) * (x - (Constants.RegionSize / 2)) + + (y - (Constants.RegionSize / 2)) * (y - (Constants.RegionSize / 2))); + } + } + } + + public TerrainChannel(double[,] import) + { + map = import; + taint = new bool[import.GetLength(0), import.GetLength(1)]; + } + + public TerrainChannel(bool createMap) + { + if (createMap) + { + map = new double[Constants.RegionSize, Constants.RegionSize]; + taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16]; + } + } + + public TerrainChannel(int w, int h) + { + map = new double[w, h]; + taint = new bool[w / 16, h / 16]; + } + } +} diff --git a/OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs b/OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs index 83c6658..5931552 100644 --- a/OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs +++ b/OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs @@ -36,151 +36,18 @@ using OpenSim.Region.Environment.Scenes; namespace OpenSim.Region.Environment.Modules.Terrain { - public interface ITerrainPaintableEffect - { - void PaintEffect(ITerrainChannel map, double x, double y, double strength, double duration); - } - - public interface ITerrainFloodEffect - { - void FloodEffect(ITerrainChannel map, Boolean[,] fillArea, double strength); - } - - public interface ITerrainEffect - { - void RunEffect(ITerrainChannel map, double strength); - } - - public interface ITerrainLoader - { - ITerrainChannel LoadFile(string filename); - void SaveFile(string filename, ITerrainChannel map); - } - - /// - /// A new version of the old Channel class, simplified - /// - public class TerrainChannel : ITerrainChannel + public class TerrainModule : IRegionModule { - private double[,] map; - private bool[,] taint; - - public int Width - { - get { return map.GetLength(0); } - } - - public int Height - { - get { return map.GetLength(1); } - } - - public TerrainChannel Copy() - { - TerrainChannel copy = new TerrainChannel(false); - copy.map = (double[,])this.map.Clone(); - - return copy; - } - - public float[] GetFloatsSerialised() - { - float[] heights = new float[Width * Height]; - int i; - - for (i = 0; i < Width * Height; i++) - { - heights[i] = (float)map[i % Width, i / Width]; - } - - return heights; - } - - public double[,] GetDoubles() - { - return map; - } - - public double this[int x, int y] - { - get - { - return map[x, y]; - } - set - { - if (map[x, y] != value) - { - taint[x / 16, y / 16] = true; - map[x, y] = value; - } - } - } - - public bool Tainted(int x, int y) + public enum StandardTerrainEffects : byte { - if (taint[x / 16, y / 16] != false) - { - taint[x / 16, y / 16] = false; - return true; - } - else - { - return false; - } + Flatten = 0, + Raise = 1, + Lower = 2, + Smooth = 3, + Noise = 4, + Revert = 5 } - public TerrainChannel() - { - map = new double[Constants.RegionSize, Constants.RegionSize]; - taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16]; - - int x, y; - for (x = 0; x < Constants.RegionSize; x++) - { - for (y = 0; y < Constants.RegionSize; y++) - { - map[x, y] = 60.0 - // 60 = Sphere Radius - ((x - (Constants.RegionSize / 2)) * (x - (Constants.RegionSize / 2)) + - (y - (Constants.RegionSize / 2)) * (y - (Constants.RegionSize / 2))); - } - } - } - - public TerrainChannel(double[,] import) - { - map = import; - taint = new bool[import.GetLength(0), import.GetLength(1)]; - } - - public TerrainChannel(bool createMap) - { - if (createMap) - { - map = new double[Constants.RegionSize, Constants.RegionSize]; - taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16]; - } - } - - public TerrainChannel(int w, int h) - { - map = new double[w, h]; - taint = new bool[w / 16, h / 16]; - } - } - - public enum StandardTerrainEffects : byte - { - Flatten = 0, - Raise = 1, - Lower = 2, - Smooth = 3, - Noise = 4, - Revert = 5 - } - - public class TerrainModule : IRegionModule - { private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private Dictionary m_painteffects = diff --git a/OpenSim/Region/Environment/Modules/Terrain/TerrainUtil.cs b/OpenSim/Region/Environment/Modules/Terrain/TerrainUtil.cs index 23ab321..55265d9 100644 --- a/OpenSim/Region/Environment/Modules/Terrain/TerrainUtil.cs +++ b/OpenSim/Region/Environment/Modules/Terrain/TerrainUtil.cs @@ -47,5 +47,60 @@ namespace OpenSim.Region.Environment.Modules.Terrain double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz); return hi; } + + private static double Noise(double x, double y) + { + int n = (int)x + (int)(y * 749); + n = (n << 13) ^ n; + return (1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0); + } + + private static double SmoothedNoise1(double x, double y) + { + double corners = (Noise(x - 1, y - 1) + Noise(x + 1, y - 1) + Noise(x - 1, y + 1) + Noise(x + 1, y + 1)) / 16; + double sides = (Noise(x - 1, y) + Noise(x + 1, y) + Noise(x, y - 1) + Noise(x, y + 1)) / 8; + double center = Noise(x, y) / 4; + return corners + sides + center; + } + + private static double Interpolate(double x, double y, double z) + { + return (x * (1.0 - z)) + (y * z); + } + + private static double InterpolatedNoise(double x, double y) + { + int integer_X = (int)(x); + double fractional_X = x - integer_X; + + int integer_Y = (int)y; + double fractional_Y = y - integer_Y; + + double v1 = SmoothedNoise1(integer_X, integer_Y); + double v2 = SmoothedNoise1(integer_X + 1, integer_Y); + double v3 = SmoothedNoise1(integer_X, integer_Y + 1); + double v4 = SmoothedNoise1(integer_X + 1, integer_Y + 1); + + double i1 = Interpolate(v1, v2, fractional_X); + double i2 = Interpolate(v3, v4, fractional_X); + + return Interpolate(i1, i2, fractional_Y); + } + + public static double PerlinNoise2D(double x, double y, int octaves, double persistence) + { + double frequency = 0.0; + double amplitude = 0.0; + double total = 0.0; + + for (int i = 0; i < octaves; i++) + { + frequency = System.Math.Pow(2, i); + amplitude = System.Math.Pow(persistence, i); + + total += InterpolatedNoise(x * frequency, y * frequency) * amplitude; + } + return total; + } } } -- cgit v1.1