PageRenderTime 44ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/noise.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 352 lines | 204 code | 63 blank | 85 comment | 16 complexity | 60f53c5014245e9260ab51b15b23b0f1 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file noise.h
  3. * @brief Perlin noise routines for procedural textures, etc
  4. *
  5. * $LicenseInfo:firstyear=2000&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef LL_NOISE_H
  27. #define LL_NOISE_H
  28. #include "llmath.h"
  29. F32 turbulence2(F32 *v, F32 freq);
  30. F32 turbulence3(float *v, float freq);
  31. F32 clouds3(float *v, float freq);
  32. F32 noise2(float *vec);
  33. F32 noise3(float *vec);
  34. inline F32 bias(F32 a, F32 b)
  35. {
  36. return (F32)pow(a, (F32)(log(b) / log(0.5f)));
  37. }
  38. inline F32 gain(F32 a, F32 b)
  39. {
  40. F32 p = (F32) (log(1.f - b) / log(0.5f));
  41. if (a < .001f)
  42. return 0.f;
  43. else if (a > .999f)
  44. return 1.f;
  45. if (a < 0.5f)
  46. return (F32)(pow(2 * a, p) / 2.f);
  47. else
  48. return (F32)(1.f - pow(2 * (1.f - a), p) / 2.f);
  49. }
  50. inline F32 turbulence2(F32 *v, F32 freq)
  51. {
  52. F32 t, vec[2];
  53. for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) {
  54. vec[0] = freq * v[0];
  55. vec[1] = freq * v[1];
  56. t += noise2(vec)/freq;
  57. }
  58. return t;
  59. }
  60. inline F32 turbulence3(F32 *v, F32 freq)
  61. {
  62. F32 t, vec[3];
  63. for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) {
  64. vec[0] = freq * v[0];
  65. vec[1] = freq * v[1];
  66. vec[2] = freq * v[2];
  67. t += noise3(vec)/freq;
  68. // t += fabs(noise3(vec)) / freq; // Like snow - bubbly at low frequencies
  69. // t += sqrt(fabs(noise3(vec))) / freq; // Better at low freq
  70. // t += (noise3(vec)*noise3(vec)) / freq;
  71. }
  72. return t;
  73. }
  74. inline F32 clouds3(F32 *v, F32 freq)
  75. {
  76. F32 t, vec[3];
  77. for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) {
  78. vec[0] = freq * v[0];
  79. vec[1] = freq * v[1];
  80. vec[2] = freq * v[2];
  81. //t += noise3(vec)/freq;
  82. // t += fabs(noise3(vec)) / freq; // Like snow - bubbly at low frequencies
  83. // t += sqrt(fabs(noise3(vec))) / freq; // Better at low freq
  84. t += (noise3(vec)*noise3(vec)) / freq;
  85. }
  86. return t;
  87. }
  88. /* noise functions over 1, 2, and 3 dimensions */
  89. #define B 0x100
  90. #define BM 0xff
  91. #define N 0x1000
  92. #define NF32 (4096.f)
  93. #define NP 12 /* 2^N */
  94. #define NM 0xfff
  95. extern S32 p[B + B + 2];
  96. extern F32 g3[B + B + 2][3];
  97. extern F32 g2[B + B + 2][2];
  98. extern F32 g1[B + B + 2];
  99. extern S32 gNoiseStart;
  100. static void init(void);
  101. #define s_curve(t) ( t * t * (3.f - 2.f * t) )
  102. #define lerp_m(t, a, b) ( a + t * (b - a) )
  103. #define setup_noise(i,b0,b1,r0,r1)\
  104. t = vec[i] + N;\
  105. b0 = (lltrunc(t)) & BM;\
  106. b1 = (b0+1) & BM;\
  107. r0 = t - lltrunc(t);\
  108. r1 = r0 - 1.f;
  109. inline void fast_setup(F32 vec, U8 &b0, U8 &b1, F32 &r0, F32 &r1)
  110. {
  111. S32 t_S32;
  112. r1 = vec + NF32;
  113. t_S32 = lltrunc(r1);
  114. b0 = (U8)t_S32;
  115. b1 = b0 + 1;
  116. r0 = r1 - t_S32;
  117. r1 = r0 - 1.f;
  118. }
  119. inline F32 noise1(const F32 arg)
  120. {
  121. int bx0, bx1;
  122. F32 rx0, rx1, sx, t, u, v, vec[1];
  123. vec[0] = arg;
  124. if (gNoiseStart) {
  125. gNoiseStart = 0;
  126. init();
  127. }
  128. setup_noise(0, bx0,bx1, rx0,rx1);
  129. sx = s_curve(rx0);
  130. u = rx0 * g1[ p[ bx0 ] ];
  131. v = rx1 * g1[ p[ bx1 ] ];
  132. return lerp_m(sx, u, v);
  133. }
  134. inline F32 fast_at2(F32 rx, F32 ry, F32 *q)
  135. {
  136. return rx * (*q) + ry * (*(q + 1));
  137. }
  138. inline F32 fast_at3(F32 rx, F32 ry, F32 rz, F32 *q)
  139. {
  140. return rx * (*q) + ry * (*(q + 1)) + rz * (*(q + 2));
  141. }
  142. inline F32 noise3(F32 *vec)
  143. {
  144. U8 bx0, bx1, by0, by1, bz0, bz1;
  145. S32 b00, b10, b01, b11;
  146. F32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
  147. S32 i, j;
  148. if (gNoiseStart) {
  149. gNoiseStart = 0;
  150. init();
  151. }
  152. fast_setup(*vec, bx0,bx1, rx0,rx1);
  153. fast_setup(*(vec + 1), by0,by1, ry0,ry1);
  154. fast_setup(*(vec + 2), bz0,bz1, rz0,rz1);
  155. i = p[ bx0 ];
  156. j = p[ bx1 ];
  157. b00 = p[ i + by0 ];
  158. b10 = p[ j + by0 ];
  159. b01 = p[ i + by1 ];
  160. b11 = p[ j + by1 ];
  161. t = s_curve(rx0);
  162. sy = s_curve(ry0);
  163. sz = s_curve(rz0);
  164. q = g3[ b00 + bz0 ];
  165. u = fast_at3(rx0,ry0,rz0,q);
  166. q = g3[ b10 + bz0 ];
  167. v = fast_at3(rx1,ry0,rz0,q);
  168. a = lerp_m(t, u, v);
  169. q = g3[ b01 + bz0 ];
  170. u = fast_at3(rx0,ry1,rz0,q);
  171. q = g3[ b11 + bz0 ];
  172. v = fast_at3(rx1,ry1,rz0,q);
  173. b = lerp_m(t, u, v);
  174. c = lerp_m(sy, a, b);
  175. q = g3[ b00 + bz1 ];
  176. u = fast_at3(rx0,ry0,rz1,q);
  177. q = g3[ b10 + bz1 ];
  178. v = fast_at3(rx1,ry0,rz1,q);
  179. a = lerp_m(t, u, v);
  180. q = g3[ b01 + bz1 ];
  181. u = fast_at3(rx0,ry1,rz1,q);
  182. q = g3[ b11 + bz1 ];
  183. v = fast_at3(rx1,ry1,rz1,q);
  184. b = lerp_m(t, u, v);
  185. d = lerp_m(sy, a, b);
  186. return lerp_m(sz, c, d);
  187. }
  188. /*
  189. F32 noise3(F32 *vec)
  190. {
  191. int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
  192. F32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
  193. S32 i, j;
  194. if (gNoiseStart) {
  195. gNoiseStart = 0;
  196. init();
  197. }
  198. setup_noise(0, bx0,bx1, rx0,rx1);
  199. setup_noise(1, by0,by1, ry0,ry1);
  200. setup_noise(2, bz0,bz1, rz0,rz1);
  201. i = p[ bx0 ];
  202. j = p[ bx1 ];
  203. b00 = p[ i + by0 ];
  204. b10 = p[ j + by0 ];
  205. b01 = p[ i + by1 ];
  206. b11 = p[ j + by1 ];
  207. t = s_curve(rx0);
  208. sy = s_curve(ry0);
  209. sz = s_curve(rz0);
  210. #define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
  211. q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
  212. q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
  213. a = lerp_m(t, u, v);
  214. q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
  215. q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
  216. b = lerp_m(t, u, v);
  217. c = lerp_m(sy, a, b);
  218. q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
  219. q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
  220. a = lerp_m(t, u, v);
  221. q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
  222. q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
  223. b = lerp_m(t, u, v);
  224. d = lerp_m(sy, a, b);
  225. return lerp_m(sz, c, d);
  226. }
  227. */
  228. static void normalize2(F32 v[2])
  229. {
  230. F32 s;
  231. s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1]);
  232. v[0] = v[0] * s;
  233. v[1] = v[1] * s;
  234. }
  235. static void normalize3(F32 v[3])
  236. {
  237. F32 s;
  238. s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
  239. v[0] = v[0] * s;
  240. v[1] = v[1] * s;
  241. v[2] = v[2] * s;
  242. }
  243. static void init(void)
  244. {
  245. int i, j, k;
  246. for (i = 0 ; i < B ; i++) {
  247. p[i] = i;
  248. g1[i] = (F32)((rand() % (B + B)) - B) / B;
  249. for (j = 0 ; j < 2 ; j++)
  250. g2[i][j] = (F32)((rand() % (B + B)) - B) / B;
  251. normalize2(g2[i]);
  252. for (j = 0 ; j < 3 ; j++)
  253. g3[i][j] = (F32)((rand() % (B + B)) - B) / B;
  254. normalize3(g3[i]);
  255. }
  256. while (--i) {
  257. k = p[i];
  258. p[i] = p[j = rand() % B];
  259. p[j] = k;
  260. }
  261. for (i = 0 ; i < B + 2 ; i++) {
  262. p[B + i] = p[i];
  263. g1[B + i] = g1[i];
  264. for (j = 0 ; j < 2 ; j++)
  265. g2[B + i][j] = g2[i][j];
  266. for (j = 0 ; j < 3 ; j++)
  267. g3[B + i][j] = g3[i][j];
  268. }
  269. }
  270. #undef B
  271. #undef BM
  272. #undef N
  273. #undef NF32
  274. #undef NP
  275. #undef NM
  276. #endif // LL_NOISE_