perlin.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /* coherent noise function over 1, 2 or 3 dimensions */
  2. /* (copyright Ken Perlin) */
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <math.h>
  6. #include "perlin.h"
  7. #define B SAMPLE_SIZE
  8. #define BM (SAMPLE_SIZE-1)
  9. #define N 0x1000
  10. #define NP 12 /* 2^N */
  11. #define NM 0xfff
  12. #define s_curve(t) ( t * t * (3.0f - 2.0f * t) )
  13. #define lerp(t, a, b) ( a + t * (b - a) )
  14. #define setup(i,b0,b1,r0,r1)\
  15. t = vec[i] + N;\
  16. b0 = ((int)t) & BM;\
  17. b1 = (b0+1) & BM;\
  18. r0 = t - (int)t;\
  19. r1 = r0 - 1.0f;
  20. float Perlin::noise1(float arg)
  21. {
  22. int bx0, bx1;
  23. float rx0, rx1, sx, t, u, v, vec[1];
  24. vec[0] = arg;
  25. if (mStart)
  26. {
  27. srand(mSeed);
  28. mStart = false;
  29. init();
  30. }
  31. setup(0, bx0,bx1, rx0,rx1);
  32. sx = s_curve(rx0);
  33. u = rx0 * g1[ p[ bx0 ] ];
  34. v = rx1 * g1[ p[ bx1 ] ];
  35. return lerp(sx, u, v);
  36. }
  37. float Perlin::noise2(float vec[2])
  38. {
  39. int bx0, bx1, by0, by1, b00, b10, b01, b11;
  40. float rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
  41. int i, j;
  42. if (mStart)
  43. {
  44. srand(mSeed);
  45. mStart = false;
  46. init();
  47. }
  48. setup(0,bx0,bx1,rx0,rx1);
  49. setup(1,by0,by1,ry0,ry1);
  50. i = p[bx0];
  51. j = p[bx1];
  52. b00 = p[i + by0];
  53. b10 = p[j + by0];
  54. b01 = p[i + by1];
  55. b11 = p[j + by1];
  56. sx = s_curve(rx0);
  57. sy = s_curve(ry0);
  58. #define at2(rx,ry) ( rx * q[0] + ry * q[1] )
  59. q = g2[b00];
  60. u = at2(rx0,ry0);
  61. q = g2[b10];
  62. v = at2(rx1,ry0);
  63. a = lerp(sx, u, v);
  64. q = g2[b01];
  65. u = at2(rx0,ry1);
  66. q = g2[b11];
  67. v = at2(rx1,ry1);
  68. b = lerp(sx, u, v);
  69. return lerp(sy, a, b);
  70. }
  71. float Perlin::noise3(float vec[3])
  72. {
  73. int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
  74. float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
  75. int i, j;
  76. if (mStart)
  77. {
  78. srand(mSeed);
  79. mStart = false;
  80. init();
  81. }
  82. setup(0, bx0,bx1, rx0,rx1);
  83. setup(1, by0,by1, ry0,ry1);
  84. setup(2, bz0,bz1, rz0,rz1);
  85. i = p[ bx0 ];
  86. j = p[ bx1 ];
  87. b00 = p[ i + by0 ];
  88. b10 = p[ j + by0 ];
  89. b01 = p[ i + by1 ];
  90. b11 = p[ j + by1 ];
  91. t = s_curve(rx0);
  92. sy = s_curve(ry0);
  93. sz = s_curve(rz0);
  94. #define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
  95. q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
  96. q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
  97. a = lerp(t, u, v);
  98. q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
  99. q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
  100. b = lerp(t, u, v);
  101. c = lerp(sy, a, b);
  102. q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
  103. q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
  104. a = lerp(t, u, v);
  105. q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
  106. q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
  107. b = lerp(t, u, v);
  108. d = lerp(sy, a, b);
  109. return lerp(sz, c, d);
  110. }
  111. void Perlin::normalize2(float v[2])
  112. {
  113. float s;
  114. s = (float)sqrt(v[0] * v[0] + v[1] * v[1]);
  115. s = 1.0f/s;
  116. v[0] = v[0] * s;
  117. v[1] = v[1] * s;
  118. }
  119. void Perlin::normalize3(float v[3])
  120. {
  121. float s;
  122. s = (float)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
  123. s = 1.0f/s;
  124. v[0] = v[0] * s;
  125. v[1] = v[1] * s;
  126. v[2] = v[2] * s;
  127. }
  128. void Perlin::init(void)
  129. {
  130. int i, j, k;
  131. for (i = 0 ; i < B ; i++)
  132. {
  133. p[i] = i;
  134. g1[i] = (float)((rand() % (B + B)) - B) / B;
  135. for (j = 0 ; j < 2 ; j++)
  136. g2[i][j] = (float)((rand() % (B + B)) - B) / B;
  137. normalize2(g2[i]);
  138. for (j = 0 ; j < 3 ; j++)
  139. g3[i][j] = (float)((rand() % (B + B)) - B) / B;
  140. normalize3(g3[i]);
  141. }
  142. while (--i)
  143. {
  144. k = p[i];
  145. p[i] = p[j = rand() % B];
  146. p[j] = k;
  147. }
  148. for (i = 0 ; i < B + 2 ; i++)
  149. {
  150. p[B + i] = p[i];
  151. g1[B + i] = g1[i];
  152. for (j = 0 ; j < 2 ; j++)
  153. g2[B + i][j] = g2[i][j];
  154. for (j = 0 ; j < 3 ; j++)
  155. g3[B + i][j] = g3[i][j];
  156. }
  157. }
  158. float Perlin::perlin_noise_2D(float vec[2])
  159. {
  160. int terms = mOctaves;
  161. float freq = mFrequency;
  162. float result = 0.0f;
  163. float amp = mAmplitude;
  164. vec[0]*=mFrequency;
  165. vec[1]*=mFrequency;
  166. for( int i=0; i<terms; i++ )
  167. {
  168. result += noise2(vec)*amp;
  169. vec[0] *= 2.0f;
  170. vec[1] *= 2.0f;
  171. amp*=0.5f;
  172. }
  173. return result;
  174. }
  175. Perlin::Perlin(int octaves,float freq,float amp,int seed)
  176. {
  177. mOctaves = octaves;
  178. mFrequency = freq;
  179. mAmplitude = amp;
  180. mSeed = seed;
  181. mStart = true;
  182. }