aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim.Framework/HeightMapGenHills.cs
diff options
context:
space:
mode:
authorgareth2007-03-22 10:11:15 +0000
committergareth2007-03-22 10:11:15 +0000
commit7daa3955bc3a1918e40962851f9e8d38597a245e (patch)
treebee3e1372a7eed0c1b220a8a49f7bee7d29a6b91 /OpenSim.Framework/HeightMapGenHills.cs
parentLoad XML for neighbourinfo from grid (diff)
downloadopensim-SC_OLD-7daa3955bc3a1918e40962851f9e8d38597a245e.zip
opensim-SC_OLD-7daa3955bc3a1918e40962851f9e8d38597a245e.tar.gz
opensim-SC_OLD-7daa3955bc3a1918e40962851f9e8d38597a245e.tar.bz2
opensim-SC_OLD-7daa3955bc3a1918e40962851f9e8d38597a245e.tar.xz
brought zircon branch into trunk
Diffstat (limited to 'OpenSim.Framework/HeightMapGenHills.cs')
-rw-r--r--OpenSim.Framework/HeightMapGenHills.cs149
1 files changed, 149 insertions, 0 deletions
diff --git a/OpenSim.Framework/HeightMapGenHills.cs b/OpenSim.Framework/HeightMapGenHills.cs
new file mode 100644
index 0000000..6a729da
--- /dev/null
+++ b/OpenSim.Framework/HeightMapGenHills.cs
@@ -0,0 +1,149 @@
1/*
2* Copyright (c) OpenSim project, http://sim.opensecondlife.org/
3*
4* Redistribution and use in source and binary forms, with or without
5* modification, are permitted provided that the following conditions are met:
6* * Redistributions of source code must retain the above copyright
7* notice, this list of conditions and the following disclaimer.
8* * Redistributions in binary form must reproduce the above copyright
9* notice, this list of conditions and the following disclaimer in the
10* documentation and/or other materials provided with the distribution.
11* * Neither the name of the <organization> nor the
12* names of its contributors may be used to endorse or promote products
13* derived from this software without specific prior written permission.
14*
15* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
16* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
19* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*
26*/
27
28using System;
29
30namespace OpenSim.Framework.Terrain
31{
32 public class HeightmapGenHills
33 {
34 private Random Rand = new Random();
35 private int NumHills;
36 private float HillMin;
37 private float HillMax;
38 private bool Island;
39 private float[] heightmap;
40
41 public float[] GenerateHeightmap(int numHills, float hillMin, float hillMax, bool island)
42 {
43 NumHills = numHills;
44 HillMin = hillMin;
45 HillMax = hillMax;
46 Island = island;
47
48 heightmap = new float[256 * 256];
49
50 for (int i = 0; i < numHills; i++)
51 {
52 AddHill();
53 }
54
55 Normalize();
56
57 return heightmap;
58 }
59
60 private void AddHill()
61 {
62 float x, y;
63 float radius = RandomRange(HillMin, HillMax);
64
65 if (Island)
66 {
67 // Which direction from the center of the map the hill is placed
68 float theta = RandomRange(0, 6.28f);
69
70 // How far from the center of the map to place the hill. The radius
71 // is subtracted from the range to prevent any part of the hill from
72 // reaching the edge of the map
73 float distance = RandomRange(radius / 2.0f, 128.0f - radius);
74
75 x = 128.0f + (float)Math.Cos(theta) * distance;
76 y = 128.0f + (float)Math.Sin(theta) * distance;
77 }
78 else
79 {
80 x = RandomRange(-radius, 256.0f + radius);
81 y = RandomRange(-radius, 256.0f + radius);
82 }
83
84 float radiusSq = radius * radius;
85 float distSq;
86 float height;
87
88 int xMin = (int)(x - radius) - 1;
89 int xMax = (int)(x + radius) + 1;
90 if (xMin < 0) xMin = 0;
91 if (xMax > 255) xMax = 255;
92
93 int yMin = (int)(y - radius) - 1;
94 int yMax = (int)(y + radius) + 1;
95 if (yMin < 0) yMin = 0;
96 if (yMax > 255) yMax = 255;
97
98 // Loop through each affected cell and determine the height at that point
99 for (int v = yMin; v <= yMax; ++v)
100 {
101 float fv = (float)v;
102
103 for (int h = xMin; h <= xMax; ++h)
104 {
105 float fh = (float)h;
106
107 // Determine how far from the center of this hill this point is
108 distSq = (x - fh) * (x - fh) + (y - fv) * (y - fv);
109 height = radiusSq - distSq;
110
111 // Don't add negative hill values
112 if (height > 0.0f) heightmap[h + v * 256] += height;
113 }
114 }
115 }
116
117 private void Normalize()
118 {
119 float min = heightmap[0];
120 float max = heightmap[0];
121
122 for (int x = 0; x < 256; x++)
123 {
124 for (int y = 0; y < 256; y++)
125 {
126 if (heightmap[x + y * 256] < min) min = heightmap[x + y * 256];
127 if (heightmap[x + y * 256] > max) max = heightmap[x + y * 256];
128 }
129 }
130
131 // Avoid a rare divide by zero
132 if (min != max)
133 {
134 for (int x = 0; x < 256; x++)
135 {
136 for (int y = 0; y < 256; y++)
137 {
138 heightmap[x + y * 256] = ((heightmap[x + y * 256] - min) / (max - min)) * (HillMax - HillMin);
139 }
140 }
141 }
142 }
143
144 private float RandomRange(float min, float max)
145 {
146 return (float)Rand.NextDouble() * (max - min) + min;
147 }
148 }
149}