Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. #include "rsnoise.h"
  2.  
  3. #include "rsgame.h"
  4.  
  5. #ifdef RS_USE_C_LIBS
  6.     #include <string.h>
  7.     #include <math.h>
  8. #else
  9.     #include "rs/rsplatform.h"
  10. #endif
  11.  
  12. rs_perlin_conf_t rs_perlin_conf;
  13.  
  14. void rs_perlin_configure(float freq, int octaves, float persistence, float seed, int tex_size) {
  15.     rs_perlin_conf.freq = freq;
  16.     rs_perlin_conf.octaves = octaves;
  17.     rs_perlin_conf.persistence = persistence;
  18.     rs_perlin_conf.seed = seed;
  19.     rs_perlin_conf.tex_size = tex_size;
  20.     rs_perlin_conf.period = (int) (0.1 + roundf(freq) ); // *tex_size
  21. };
  22.  
  23. float rs_noise(int x, int y) {
  24.     // from here, http://www.cplusplus.com/forum/general/85758/
  25.     // koef. changed
  26.     int n = x + y * 57 * 5; // no *2
  27.     n = (n << 13) ^ n;
  28.     int t = (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff;
  29.     return 1.0 - ((float)t) * 0.931322574615478515625e-9;/// 1073741824.0);
  30. }
  31.  
  32. float rs_noise_for_perlin(int x, int y) {
  33.  
  34.     x %= rs_perlin_conf.period;
  35.     y %= rs_perlin_conf.period;
  36.  
  37.     // from here, http://www.cplusplus.com/forum/general/85758/
  38.     // koef. changed
  39.     int n = x + y * 57 * 5; // no *2
  40.     n = (n << 13) ^ n;
  41.     int t = (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff;
  42.     return 1.0 - ((float)t) * 0.931322574615478515625e-9;/// 1073741824.0);
  43. }
  44.  
  45. //float rs_noise_periodical(int x, int y, int period) {
  46. //
  47. //    x %= period;
  48. //    y %= period;
  49. //
  50. //    // from here, http://www.cplusplus.com/forum/general/85758/
  51. //    // koef. changed
  52. //    int n = x + y * 57 * 5; // no *2
  53. //    n = (n << 13) ^ n;
  54. //    int t = (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff;
  55. //    return 1.0 - ((float)t) * 0.931322574615478515625e-9;/// 1073741824.0);
  56. //}
  57.  
  58. float rs_interpolate(float x, float y, float a) {
  59.     float negA = 1.0 - a;
  60.   float negASqr = negA * negA;
  61.     float fac1 = 3.0 * (negASqr) - 2.0 * (negASqr * negA);
  62.   float aSqr = a * a;
  63.     float fac2 = 3.0 * aSqr - 2.0 * (aSqr * a);
  64.  
  65.     return x * fac1 + y * fac2; //add the weighted factors
  66. }
  67.  
  68. float rs_perlin_noise(float x, float y) {
  69.  
  70. //    while (x > rs_perlin_conf.tile_period) {
  71. //        x -= rs_perlin_conf.tile_period;
  72. //    };
  73. //    
  74. //    while (y > rs_perlin_conf.tile_period) {
  75. //        y -= rs_perlin_conf.tile_period;
  76. //    };
  77.  
  78.     int Xint = (int)x;
  79.     int Yint = (int)y;
  80.     float Xfrac = x - Xint;
  81.     float Yfrac = y - Yint;
  82.  
  83.  
  84.   //noise values
  85.   float n01= rs_noise_for_perlin(Xint-1, Yint-1);
  86.   float n02= rs_noise_for_perlin(Xint+1, Yint-1);
  87.   float n03= rs_noise_for_perlin(Xint-1, Yint+1);
  88.   float n04= rs_noise_for_perlin(Xint+1, Yint+1);
  89.   float n05= rs_noise_for_perlin(Xint-1, Yint);
  90.   float n06= rs_noise_for_perlin(Xint+1, Yint);
  91.   float n07= rs_noise_for_perlin(Xint, Yint-1);
  92.   float n08= rs_noise_for_perlin(Xint, Yint+1);
  93.   float n09= rs_noise_for_perlin(Xint, Yint);
  94.  
  95.   float n12= rs_noise_for_perlin(Xint+2, Yint-1);
  96.   float n14= rs_noise_for_perlin(Xint+2, Yint+1);
  97.   float n16= rs_noise_for_perlin(Xint+2, Yint);
  98.  
  99.   float n23= rs_noise_for_perlin(Xint-1, Yint+2);
  100.   float n24= rs_noise_for_perlin(Xint+1, Yint+2);
  101.   float n28= rs_noise_for_perlin(Xint, Yint+2);
  102.  
  103.   float n34= rs_noise_for_perlin(Xint+2, Yint+2);
  104.  
  105.     //find the noise values of the four corners
  106.     float x0y0 = 0.0625*(n01+n02+n03+n04) + 0.125*(n05+n06+n07+n08) + 0.25*(n09);
  107.     float x1y0 = 0.0625*(n07+n12+n08+n14) + 0.125*(n09+n16+n02+n04) + 0.25*(n06);
  108.     float x0y1 = 0.0625*(n05+n06+n23+n24) + 0.125*(n03+n04+n09+n28) + 0.25*(n08);
  109.     float x1y1 = 0.0625*(n09+n16+n28+n34) + 0.125*(n08+n14+n06+n24) + 0.25*(n04);
  110.  
  111.     //interpolate between those values according to the x and y fractions
  112.     float v1 = rs_interpolate(x0y0, x1y0, Xfrac); //interpolate in x direction (y)
  113.     float v2 = rs_interpolate(x0y1, x1y1, Xfrac); //interpolate in x direction (y+1)
  114.     float fin = rs_interpolate(v1, v2, Yfrac);  //interpolate in y direction
  115.  
  116.     return fin;
  117. }
  118.  
  119. float rs_perlin(float i, float j) {
  120.  
  121.     float t = 0.0f;
  122.     float _amplitude = 1.0;
  123.  
  124.    
  125.     int k;
  126.    
  127.     float amplitude_divider = 0.0;
  128.     for (k = 0; k < rs_perlin_conf.octaves; k++) {
  129.         amplitude_divider += _amplitude;
  130.         _amplitude *= rs_perlin_conf.persistence;
  131.     };
  132.    
  133.     _amplitude = 1.0;
  134.    
  135.     float freq = rs_perlin_conf.freq;
  136.  
  137.     for(k = 0; k < rs_perlin_conf.octaves; k++)
  138.     {
  139.         t += rs_perlin_noise(j * freq / rs_perlin_conf.tex_size + rs_perlin_conf.seed, i * freq / rs_perlin_conf.tex_size + rs_perlin_conf.seed) * _amplitude;
  140.         _amplitude *= rs_perlin_conf.persistence;
  141.         freq *= 2;
  142.     }
  143.  
  144.     return t / amplitude_divider;
  145. };
  146.  
  147. float rs_quad_noise(float i, float j) {
  148.  
  149.     float t = 0.0f;
  150.     float _amplitude = 1.0;
  151.  
  152.    
  153.     int k;
  154.    
  155.     float amplitude_divider = 0.0;
  156.     for (k = 0; k < rs_perlin_conf.octaves; k++) {
  157.         amplitude_divider += _amplitude;
  158.         _amplitude *= rs_perlin_conf.persistence;
  159.     };
  160.    
  161.     _amplitude = 1.0;
  162.    
  163.     float freq = rs_perlin_conf.freq;
  164.  
  165.     for(k = 0; k < rs_perlin_conf.octaves; k++)
  166.     {
  167.         t += rs_noise(j * freq / rs_perlin_conf.tex_size + rs_perlin_conf.seed, i * freq / rs_perlin_conf.tex_size + rs_perlin_conf.seed) * _amplitude;
  168.         _amplitude *= rs_perlin_conf.persistence;
  169.         freq *= 2;
  170.     }
  171.  
  172.     return t / amplitude_divider;
  173. };
  174.  
  175.  
  176.