OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
Perlin.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using OpenMetaverse;
30 
31 namespace OpenSim.Region.CoreModules.World.Warp3DMap
32 {
33  public static class Perlin
34  {
35  // We use a hardcoded seed to keep the noise generation consistent between runs
36  private const int SEED = 42;
37 
38  private const int SAMPLE_SIZE = 1024;
39  private const int B = SAMPLE_SIZE;
40  private const int BM = SAMPLE_SIZE - 1;
41  private const int N = 0x1000;
42 
43  private static readonly int[] p = new int[SAMPLE_SIZE + SAMPLE_SIZE + 2];
44  private static readonly float[,] g3 = new float[SAMPLE_SIZE + SAMPLE_SIZE + 2, 3];
45  private static readonly float[,] g2 = new float[SAMPLE_SIZE + SAMPLE_SIZE + 2, 2];
46  private static readonly float[] g1 = new float[SAMPLE_SIZE + SAMPLE_SIZE + 2];
47 
48  static Perlin()
49  {
50  Random rng = new Random(SEED);
51  int i, j, k;
52 
53  for (i = 0; i < B; i++)
54  {
55  p[i] = i;
56  g1[i] = (float)((rng.Next() % (B + B)) - B) / B;
57 
58  for (j = 0; j < 2; j++)
59  g2[i, j] = (float)((rng.Next() % (B + B)) - B) / B;
60  normalize2(g2, i);
61 
62  for (j = 0; j < 3; j++)
63  g3[i, j] = (float)((rng.Next() % (B + B)) - B) / B;
64  normalize3(g3, i);
65  }
66 
67  while (--i > 0)
68  {
69  k = p[i];
70  p[i] = p[j = rng.Next() % B];
71  p[j] = k;
72  }
73 
74  for (i = 0; i < B + 2; i++)
75  {
76  p[B + i] = p[i];
77  g1[B + i] = g1[i];
78  for (j = 0; j < 2; j++)
79  g2[B + i, j] = g2[i, j];
80  for (j = 0; j < 3; j++)
81  g3[B + i, j] = g3[i, j];
82  }
83  }
84 
85  public static float noise1(float arg)
86  {
87  int bx0, bx1;
88  float rx0, rx1, sx, t, u, v;
89 
90  t = arg + N;
91  bx0 = ((int)t) & BM;
92  bx1 = (bx0 + 1) & BM;
93  rx0 = t - (int)t;
94  rx1 = rx0 - 1f;
95 
96  sx = s_curve(rx0);
97 
98  u = rx0 * g1[p[bx0]];
99  v = rx1 * g1[p[bx1]];
100 
101  return Utils.Lerp(u, v, sx);
102  }
103 
104  public static float noise2(float x, float y)
105  {
106  int bx0, bx1, by0, by1, b00, b10, b01, b11;
107  float rx0, rx1, ry0, ry1, sx, sy, a, b, t, u, v;
108  int i, j;
109 
110  t = x + N;
111  bx0 = ((int)t) & BM;
112  bx1 = (bx0 + 1) & BM;
113  rx0 = t - (int)t;
114  rx1 = rx0 - 1f;
115 
116  t = y + N;
117  by0 = ((int)t) & BM;
118  by1 = (by0 + 1) & BM;
119  ry0 = t - (int)t;
120  ry1 = ry0 - 1f;
121 
122  i = p[bx0];
123  j = p[bx1];
124 
125  b00 = p[i + by0];
126  b10 = p[j + by0];
127  b01 = p[i + by1];
128  b11 = p[j + by1];
129 
130  sx = s_curve(rx0);
131  sy = s_curve(ry0);
132 
133  u = rx0 * g2[b00, 0] + ry0 * g2[b00, 1];
134  v = rx1 * g2[b10, 0] + ry0 * g2[b10, 1];
135  a = Utils.Lerp(u, v, sx);
136 
137  u = rx0 * g2[b01, 0] + ry1 * g2[b01, 1];
138  v = rx1 * g2[b11, 0] + ry1 * g2[b11, 1];
139  b = Utils.Lerp(u, v, sx);
140 
141  return Utils.Lerp(a, b, sy);
142  }
143 
144  public static float noise3(float x, float y, float z)
145  {
146  int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
147  float rx0, rx1, ry0, ry1, rz0, rz1, sy, sz, a, b, c, d, t, u, v;
148  int i, j;
149 
150  t = x + N;
151  bx0 = ((int)t) & BM;
152  bx1 = (bx0 + 1) & BM;
153  rx0 = t - (int)t;
154  rx1 = rx0 - 1f;
155 
156  t = y + N;
157  by0 = ((int)t) & BM;
158  by1 = (by0 + 1) & BM;
159  ry0 = t - (int)t;
160  ry1 = ry0 - 1f;
161 
162  t = z + N;
163  bz0 = ((int)t) & BM;
164  bz1 = (bz0 + 1) & BM;
165  rz0 = t - (int)t;
166  rz1 = rz0 - 1f;
167 
168  i = p[bx0];
169  j = p[bx1];
170 
171  b00 = p[i + by0];
172  b10 = p[j + by0];
173  b01 = p[i + by1];
174  b11 = p[j + by1];
175 
176  t = s_curve(rx0);
177  sy = s_curve(ry0);
178  sz = s_curve(rz0);
179 
180  u = rx0 * g3[b00 + bz0, 0] + ry0 * g3[b00 + bz0, 1] + rz0 * g3[b00 + bz0, 2];
181  v = rx1 * g3[b10 + bz0, 0] + ry0 * g3[b10 + bz0, 1] + rz0 * g3[b10 + bz0, 2];
182  a = Utils.Lerp(u, v, t);
183 
184  u = rx0 * g3[b01 + bz0, 0] + ry1 * g3[b01 + bz0, 1] + rz0 * g3[b01 + bz0, 2];
185  v = rx1 * g3[b11 + bz0, 0] + ry1 * g3[b11 + bz0, 1] + rz0 * g3[b11 + bz0, 2];
186  b = Utils.Lerp(u, v, t);
187 
188  c = Utils.Lerp(a, b, sy);
189 
190  u = rx0 * g3[b00 + bz1, 0] + ry0 * g3[b00 + bz1, 1] + rz1 * g3[b00 + bz1, 2];
191  v = rx1 * g3[b10 + bz1, 0] + ry0 * g3[b10 + bz1, 1] + rz1 * g3[b10 + bz1, 2];
192  a = Utils.Lerp(u, v, t);
193 
194  u = rx0 * g3[b01 + bz1, 0] + ry1 * g3[b01 + bz1, 1] + rz1 * g3[b01 + bz1, 2];
195  v = rx1 * g3[b11 + bz1, 0] + ry1 * g3[b11 + bz1, 1] + rz1 * g3[b11 + bz1, 2];
196  b = Utils.Lerp(u, v, t);
197 
198  d = Utils.Lerp(a, b, sy);
199  return Utils.Lerp(c, d, sz);
200  }
201 
202  public static float turbulence1(float x, float freq)
203  {
204  float t;
205  float v;
206 
207  for (t = 0f; freq >= 1f; freq *= 0.5f)
208  {
209  v = freq * x;
210  t += noise1(v) / freq;
211  }
212  return t;
213  }
214 
215  public static float turbulence2(float x, float y, float freq)
216  {
217  float t;
218  Vector2 vec;
219 
220  for (t = 0f; freq >= 1f; freq *= 0.5f)
221  {
222  vec.X = freq * x;
223  vec.Y = freq * y;
224  t += noise2(vec.X, vec.Y) / freq;
225  }
226  return t;
227  }
228 
229  public static float turbulence3(float x, float y, float z, float freq)
230  {
231  float t;
232  Vector3 vec;
233 
234  for (t = 0f; freq >= 1f; freq *= 0.5f)
235  {
236  vec.X = freq * x;
237  vec.Y = freq * y;
238  vec.Z = freq * z;
239  t += noise3(vec.X, vec.Y, vec.Z) / freq;
240  }
241  return t;
242  }
243 
244  private static void normalize2(float[,] v, int i)
245  {
246  float s;
247 
248  s = (float)Math.Sqrt(v[i, 0] * v[i, 0] + v[i, 1] * v[i, 1]);
249  s = 1.0f / s;
250  v[i, 0] = v[i, 0] * s;
251  v[i, 1] = v[i, 1] * s;
252  }
253 
254  private static void normalize3(float[,] v, int i)
255  {
256  float s;
257 
258  s = (float)Math.Sqrt(v[i, 0] * v[i, 0] + v[i, 1] * v[i, 1] + v[i, 2] * v[i, 2]);
259  s = 1.0f / s;
260 
261  v[i, 0] = v[i, 0] * s;
262  v[i, 1] = v[i, 1] * s;
263  v[i, 2] = v[i, 2] * s;
264  }
265 
266  private static float s_curve(float t)
267  {
268  return t * t * (3f - 2f * t);
269  }
270  }
271 }
Interactive OpenSim region server
Definition: OpenSim.cs:55