Grid.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  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 OpenSim 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. using System;
  28. namespace libTerrain
  29. {
  30. partial class Channel
  31. {
  32. public Channel Normalise()
  33. {
  34. SetDiff();
  35. double max = FindMax();
  36. double min = FindMin();
  37. int x, y;
  38. if (max != min)
  39. {
  40. for (x = 0; x < w; x++)
  41. {
  42. for (y = 0; y < h; y++)
  43. {
  44. map[x, y] = (map[x, y] - min)*(1.0/(max - min));
  45. }
  46. }
  47. }
  48. else
  49. {
  50. Fill(0.5);
  51. }
  52. return this;
  53. }
  54. public Channel Normalise(double minv, double maxv)
  55. {
  56. SetDiff();
  57. if (minv == maxv)
  58. {
  59. Fill(minv);
  60. return this;
  61. }
  62. double max = FindMax();
  63. double min = FindMin();
  64. int x, y;
  65. for (x = 0; x < w; x++)
  66. {
  67. for (y = 0; y < h; y++)
  68. {
  69. if (min != max)
  70. {
  71. double val = (map[x, y] - min)*(1.0/(max - min));
  72. val *= maxv - minv;
  73. val += minv;
  74. map[x, y] = val;
  75. }
  76. else
  77. {
  78. map[x, y] = 0.5;
  79. }
  80. }
  81. }
  82. return this;
  83. }
  84. public Channel Elevate(double meters)
  85. {
  86. SetDiff();
  87. int x, y;
  88. for (x = 0; x < w; x++)
  89. {
  90. for (y = 0; y < h; y++)
  91. {
  92. map[x, y] += meters;
  93. }
  94. }
  95. return this;
  96. }
  97. public Channel Clip()
  98. {
  99. int x, y;
  100. for (x = 0; x < w; x++)
  101. {
  102. for (y = 0; y < h; y++)
  103. {
  104. SetClip(x, y, map[x, y]);
  105. }
  106. }
  107. return this;
  108. }
  109. public Channel Clip(double min, double max)
  110. {
  111. int x, y;
  112. for (x = 0; x < w; x++)
  113. {
  114. for (y = 0; y < h; y++)
  115. {
  116. double val = map[x, y];
  117. if (val > max) val = max;
  118. if (val < min) val = min;
  119. Set(x, y, val);
  120. }
  121. }
  122. return this;
  123. }
  124. public Channel Crop(int x1, int y1, int x2, int y2)
  125. {
  126. int width = x1 - x2 + 1;
  127. int height = y1 - y2 + 1;
  128. Channel chan = new Channel(width, height);
  129. int x, y;
  130. int nx, ny;
  131. nx = 0;
  132. for (x = x1; x < x2; x++)
  133. {
  134. ny = 0;
  135. for (y = y1; y < y2; y++)
  136. {
  137. chan.map[nx, ny] = map[x, y];
  138. ny++;
  139. }
  140. nx++;
  141. }
  142. return this;
  143. }
  144. public Channel AddClip(Channel other)
  145. {
  146. SetDiff();
  147. int x, y;
  148. for (x = 0; x < w; x++)
  149. {
  150. for (y = 0; y < h; y++)
  151. {
  152. map[x, y] = other.map[x, y];
  153. if (map[x, y] > 1)
  154. map[x, y] = 1;
  155. if (map[x, y] < 0)
  156. map[x, y] = 0;
  157. }
  158. }
  159. return this;
  160. }
  161. public void Smooth(double amount)
  162. {
  163. SetDiff();
  164. double area = amount;
  165. double step = amount/4.0;
  166. double[,] manipulate = new double[w,h];
  167. int x, y;
  168. double n, l;
  169. for (x = 0; x < w; x++)
  170. {
  171. for (y = 0; y < h; y++)
  172. {
  173. double average = 0.0;
  174. int avgsteps = 0;
  175. for (n = 0.0 - area; n < area; n += step)
  176. {
  177. for (l = 0.0 - area; l < area; l += step)
  178. {
  179. avgsteps++;
  180. average += GetBilinearInterpolate(x + n, y + l);
  181. }
  182. }
  183. manipulate[x, y] = average/avgsteps;
  184. }
  185. }
  186. map = manipulate;
  187. }
  188. public void Pertubation(double amount)
  189. {
  190. SetDiff();
  191. // Simple pertubation filter
  192. double[,] manipulated = new double[w,h];
  193. Random generator = new Random(seed); // Seeds FTW!
  194. //double amount = 8.0;
  195. int x, y;
  196. for (x = 0; x < w; x++)
  197. {
  198. for (y = 0; y < h; y++)
  199. {
  200. double offset_x = (double) x + (generator.NextDouble()*amount) - (amount/2.0);
  201. double offset_y = (double) y + (generator.NextDouble()*amount) - (amount/2.0);
  202. double p = GetBilinearInterpolate(offset_x, offset_y);
  203. manipulated[x, y] = p;
  204. }
  205. }
  206. map = manipulated;
  207. }
  208. public void PertubationMask(Channel mask)
  209. {
  210. // Simple pertubation filter
  211. double[,] manipulated = new double[w,h];
  212. Random generator = new Random(seed); // Seeds FTW!
  213. //double amount = 8.0;
  214. double amount;
  215. int x, y;
  216. for (x = 0; x < w; x++)
  217. {
  218. for (y = 0; y < h; y++)
  219. {
  220. amount = mask.map[x, y];
  221. double offset_x = (double) x + (generator.NextDouble()*amount) - (amount/2.0);
  222. double offset_y = (double) y + (generator.NextDouble()*amount) - (amount/2.0);
  223. if (offset_x > w)
  224. offset_x = w - 1;
  225. if (offset_y > h)
  226. offset_y = h - 1;
  227. if (offset_y < 0)
  228. offset_y = 0;
  229. if (offset_x < 0)
  230. offset_x = 0;
  231. double p = GetBilinearInterpolate(offset_x, offset_y);
  232. manipulated[x, y] = p;
  233. SetDiff(x, y);
  234. }
  235. }
  236. map = manipulated;
  237. }
  238. public void Distort(Channel mask, double str)
  239. {
  240. // Simple pertubation filter
  241. double[,] manipulated = new double[w,h];
  242. double amount;
  243. int x, y;
  244. for (x = 0; x < w; x++)
  245. {
  246. for (y = 0; y < h; y++)
  247. {
  248. amount = mask.map[x, y];
  249. double offset_x = (double) x + (amount*str) - (0.5*str);
  250. double offset_y = (double) y + (amount*str) - (0.5*str);
  251. if (offset_x > w)
  252. offset_x = w - 1;
  253. if (offset_y > h)
  254. offset_y = h - 1;
  255. if (offset_y < 0)
  256. offset_y = 0;
  257. if (offset_x < 0)
  258. offset_x = 0;
  259. double p = GetBilinearInterpolate(offset_x, offset_y);
  260. manipulated[x, y] = p;
  261. SetDiff(x, y);
  262. }
  263. }
  264. map = manipulated;
  265. }
  266. public void Distort(Channel mask, Channel mask2, double str)
  267. {
  268. // Simple pertubation filter
  269. double[,] manipulated = new double[w,h];
  270. double amountX;
  271. double amountY;
  272. int x, y;
  273. for (x = 0; x < w; x++)
  274. {
  275. for (y = 0; y < h; y++)
  276. {
  277. amountX = mask.map[x, y];
  278. amountY = mask2.map[x, y];
  279. double offset_x = (double) x + (amountX*str) - (0.5*str);
  280. double offset_y = (double) y + (amountY*str) - (0.5*str);
  281. if (offset_x > w)
  282. offset_x = w - 1;
  283. if (offset_y > h)
  284. offset_y = h - 1;
  285. if (offset_y < 0)
  286. offset_y = 0;
  287. if (offset_x < 0)
  288. offset_x = 0;
  289. double p = GetBilinearInterpolate(offset_x, offset_y);
  290. manipulated[x, y] = p;
  291. SetDiff(x, y);
  292. }
  293. }
  294. map = manipulated;
  295. }
  296. public Channel Blend(Channel other, double amount)
  297. {
  298. int x, y;
  299. for (x = 0; x < w; x++)
  300. {
  301. for (y = 0; y < h; y++)
  302. {
  303. Set(x, y, Tools.LinearInterpolate(map[x, y], other.map[x, y], amount));
  304. }
  305. }
  306. return this;
  307. }
  308. public Channel Blend(Channel other, Channel amount)
  309. {
  310. int x, y;
  311. for (x = 0; x < w; x++)
  312. {
  313. for (y = 0; y < h; y++)
  314. {
  315. Set(x, y, Tools.LinearInterpolate(map[x, y], other.map[x, y], amount.map[x, y]));
  316. }
  317. }
  318. return this;
  319. }
  320. }
  321. }