Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5235 alpine 1
#include "rsnoise.h"
2
 
3
#include "rsgame.h"
4
 
5
#ifdef RS_USE_C_LIBS
6
    #include 
7
    #include 
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