RSS

(root)/iphone/common : 61 : Jigs/source/SimplexNoise.m

« back to all changes in this revision

Viewing changes to Jigs/source/SimplexNoise.m

Dömötör Gulyás
2010-01-18 09:03:51
Revision ID: dognotdog@gmail.com-20100118080351-ib2knxvk4w8ssw3h
made common a nested tree

Show diffs side-by-side

added added

removed removed

1
 
//
2
 
//  SimplexNoise.m
3
 
//  JigsawGenerator
4
 
//
5
 
//  Created by DoG on 19.02.07.
6
 
//  Copyright 2007 Doemoetoer Gulyas. All rights reserved.
7
 
//
8
 
 
9
 
#import "SimplexNoise.h"
10
 
#import "MersenneTwister.h"
11
 
#import "geometry.h"
12
 
 
13
 
static  const   float grad3[12][3] = {
14
 
        {1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0},
15
 
        {1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1},
16
 
        {0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}
17
 
};
18
 
 
19
 
static  float dot3(const float g[], const float x, const float y, const float z)
20
 
{ return g[0]*x + g[1]*y + g[2]*z; };
21
 
 
22
 
 
23
 
@implementation SimplexNoise
24
 
 
25
 
- (id) init
26
 
{
27
 
        self = [super init];
28
 
        if(!self)
29
 
                return nil;
30
 
        
31
 
        [self setSeed: 4537];
32
 
        
33
 
        return self;
34
 
};
35
 
- (void) dealloc
36
 
{
37
 
        free(perm - 256);
38
 
        [super dealloc];
39
 
}
40
 
 
41
 
- (void) setSeed: (uint32_t) seed
42
 
{
43
 
        MersenneTwister* rgen = [[[MersenneTwister alloc] initWithSeed: seed] autorelease];
44
 
        if (perm)
45
 
                free(perm-256);
46
 
                
47
 
        perm = calloc(3*256, sizeof(uint32_t));
48
 
        perm = perm + 256;
49
 
        // generate array from 0..255
50
 
        for (uint32_t i = 0; i < 256; ++i)
51
 
        {
52
 
                perm[i] = i;
53
 
        }
54
 
        // randomly swap indices
55
 
        for (uint32_t i = 0; i < 256; ++i)
56
 
        {
57
 
                uint32_t r1 = [rgen randomNumber] & 0xFF;
58
 
                
59
 
                uint32_t tmp = perm[i];
60
 
                
61
 
                perm[i] = perm[r1];
62
 
                perm[r1] = tmp;
63
 
        }
64
 
        for (uint32_t i = 0; i < 256; ++i)
65
 
        {
66
 
                perm[i + 256] = perm[i];
67
 
                perm[i - 256] = perm[i];
68
 
        }
69
 
 
70
 
};
71
 
 
72
 
 
73
 
static float sumFA(float *v, uint32_t n)
74
 
{
75
 
        float res = 0.0f;
76
 
        for (unsigned int i = 0; i < n; ++i)
77
 
                res += v[i];
78
 
        return res;
79
 
};
80
 
 
81
 
 
82
 
static v3 atv(uint32_t* array)
83
 
{
84
 
        v3 res;
85
 
        for (size_t i = 0; i < 3; ++i)
86
 
                res.a[i] = array[i];
87
 
        return res;
88
 
};
89
 
 
90
 
- (float) noise3dWithVector: (v3) v
91
 
{
92
 
        //float n[4] = {0.0f,0.0f,0.0f,0.0f};
93
 
                
94
 
        const float F3 = 1.0f/3.0f;
95
 
        const float G3 = 1.0f/6.0f;
96
 
        
97
 
        float s = vsum(v)*F3;
98
 
        v3 ijk = vfloor(vadd(v,vcreate(s,s,s)));
99
 
        float t = vsum(ijk)*G3;
100
 
        
101
 
        v3 X0 = vsub(ijk, vcreate(t,t,t));
102
 
        v3 x[4];
103
 
        x[0] = vsub(v, X0);
104
 
 
105
 
        BOOL Xy = x[0].a[0] >= x[0].a[1];
106
 
        BOOL Yz = x[0].a[1] >= x[0].a[2];
107
 
        BOOL Zx = x[0].a[2] >= x[0].a[0];
108
 
        
109
 
        int xOrder = !Xy + Zx;
110
 
        int yOrder = Xy + !Yz;
111
 
        int zOrder = !Zx + Yz;
112
 
        
113
 
        if ((xOrder == 1) && (yOrder == 1) && (zOrder == 1))
114
 
        {
115
 
                xOrder = 0;
116
 
                yOrder = 1;
117
 
                zOrder = 2;
118
 
        }
119
 
 
120
 
        int i1 = (xOrder < 1), j1 = (yOrder < 1), k1 = (zOrder < 1); // Offsets for second corner of simplex in (i,j,k) coords
121
 
        int i2 = (xOrder < 2), j2 = (yOrder < 2), k2 = (zOrder < 2); // Offsets for third corner of simplex in (i,j,k) coords
122
 
 
123
 
        v3 ijk1 = {{i1,j1,k1}};
124
 
        v3 ijk2 = {{i2,j2,k2}};
125
 
        v3 G3v = {{G3,G3,G3}};
126
 
        x[1] = vadd(vsub(x[0], ijk1), G3v);
127
 
        x[2] = vadd(vsub(x[0], ijk2), vmul(G3v, 2.0f));
128
 
        x[3] = vadd(vsub(x[0], vcreate(1.0f, 1.0f, 1.0f)), vmul(G3v, 3.0f));
129
 
 
130
 
 
131
 
 
132
 
        int32_t ii = (int32_t)ijk.a[0] % 256;
133
 
        int32_t jj = (int32_t)ijk.a[1] % 256;
134
 
        int32_t kk = (int32_t)ijk.a[2] % 256;
135
 
        
136
 
        uint32_t gi[4] = {      perm[ii + perm[jj + perm[kk]]] % 12,
137
 
                                                perm[ii + i1 + perm[jj + j1 + perm[kk + k1]]] % 12,
138
 
                                                perm[ii + i2 + perm[jj + j2 + perm[kk + k2]]] % 12,
139
 
                                                perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] % 12};
140
 
        
141
 
        float n[4] = {0.0f,0.0f,0.0f,0.0f};
142
 
        
143
 
        /*
144
 
        if ((v.v.x == 0.0f) && (v.v.y == 0.0f) && (v.v.z == 0.0f))
145
 
        {
146
 
                NSLog(@"zing");
147
 
        }
148
 
        */
149
 
        for (size_t i = 0; i < 4; ++i)
150
 
        {
151
 
                float ti = 0.6f - vdot(x[i],x[i]);
152
 
                if (ti > 0.0f)
153
 
                {
154
 
                        ti *= ti;
155
 
                        n[i] = ti*ti*dot3(grad3[gi[i]], x[i].a[0], x[i].a[1], x[i].a[2]);
156
 
                }
157
 
        }
158
 
        float result = 32.0f*(sumFA(n,4));
159
 
        //NSLog(@"%f", result);
160
 
        return result; // range: -1..1
161
 
};
162
 
 
163
 
- (float) noise3dWithX: (float) _x Y: (float) _y Z: (float) _z
164
 
{
165
 
        //float n[4] = {0.0f,0.0f,0.0f,0.0f};
166
 
        
167
 
        v3 v = {{_x,_y,_z}};
168
 
        return [self noise3dWithVector: v];
169
 
        
170
 
}
171
 
 
172
 
static const int primes[100] = {1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523};
173
 
 
174
 
- (float) noise3dPrimeWithX: (float) x Y: (float) y Z: (float) z withOctaves: (size_t) count
175
 
{
176
 
        v3 v = {{x,y,z}};
177
 
 
178
 
        float noise = 0.0f;
179
 
        float factors = 0.0f;
180
 
        
181
 
        if (count > 100)
182
 
                count = 100;
183
 
        
184
 
        for (size_t i = 0; i < count; ++i)
185
 
        {
186
 
                float scale = primes[i];
187
 
                float factor = 1.0f/scale;
188
 
                factors += factor;
189
 
                v3 offset = {{i,i,i}};
190
 
                noise += [self noise3dWithVector: vadd(vmul(v,scale),offset)]*factor;
191
 
        }
192
 
        return noise/factors;
193
 
};
194
 
 
195
 
- (float) noise3dOctavesWithX: (float) x Y: (float) y Z: (float) z withOctaves: (size_t) count
196
 
{
197
 
 
198
 
        v3 v = {{x,y,z}};
199
 
 
200
 
        float noise = 0.0f;
201
 
        float factors = 0.0f;
202
 
        
203
 
        if (count > 100)
204
 
                count = 100;
205
 
        
206
 
        float scale = 1.0f;
207
 
        
208
 
        for (size_t i = 0; i < count; ++i)
209
 
        {
210
 
                float factor = 1.0f/(scale);
211
 
                factors += factor;
212
 
                v3 offset = {{i,i,i}};
213
 
                noise += [self noise3dWithVector: vadd(vmul(v,scale),offset)]*factor;
214
 
                scale *= 2.0f;
215
 
        }
216
 
        return noise/factors;
217
 
};
218
 
 
219
 
- (float) noise3dOctavesSqrWithX: (float) x Y: (float) y Z: (float) z withOctaves: (size_t) count
220
 
{
221
 
 
222
 
        v3 v = {{x,y,z}};
223
 
 
224
 
        float noise = 0.0f;
225
 
        float factors = 0.0f;
226
 
        
227
 
        if (count > 100)
228
 
                count = 100;
229
 
        
230
 
        float scale = 1.0f;
231
 
        
232
 
        for (size_t i = 0; i < count; ++i)
233
 
        {
234
 
                float factor = 1.0f/(scale*scale);
235
 
                factors += factor;
236
 
                v3 offset = {{i,i,i}};
237
 
                noise += [self noise3dWithVector: vadd(vmul(v,scale),offset)]*factor;
238
 
                scale *= 2.0f;
239
 
        }
240
 
        return noise/factors;
241
 
};
242
 
 
243
 
- (float) noise3dWhiteWithX: (float) x Y: (float) y Z: (float) z withOctaves: (size_t) count
244
 
{
245
 
 
246
 
        v3 v = {{x,y,z}};
247
 
 
248
 
        float noise = 0.0f;
249
 
        float factors = 0.0f;
250
 
        
251
 
        if (count > 100)
252
 
                count = 100;
253
 
        
254
 
        
255
 
        for (size_t i = 0; i < count; ++i)
256
 
        {
257
 
                float scale = 1.0f+i;
258
 
                float factor = 1.0f;
259
 
                factors += factor;
260
 
                v3 offset = {{i,i,i}};
261
 
                noise += [self noise3dWithVector: vadd(vmul(v,scale),offset)]*factor;
262
 
        }
263
 
        return noise/factors;
264
 
};
265
 
 
266
 
- (float) noise3dPinkWithX: (float) x Y: (float) y Z: (float) z withOctaves: (size_t) count
267
 
{
268
 
 
269
 
        v3 v = {{x,y,z}};
270
 
 
271
 
        float noise = 0.0f;
272
 
        float factors = 0.0f;
273
 
        
274
 
        if (count > 100)
275
 
                count = 100;
276
 
        
277
 
        
278
 
        for (size_t i = 0; i < count; ++i)
279
 
        {
280
 
                float scale = 1.0f+i;
281
 
                float factor = 1.0f/scale;
282
 
                factors += factor;
283
 
                v3 offset = {{i,i,i}};
284
 
                noise += [self noise3dWithVector: vadd(vmul(v,scale),offset)]*factor;
285
 
        }
286
 
        return noise/factors;
287
 
};
288
 
 
289
 
- (float) noise3dBrownWithX: (float) x Y: (float) y Z: (float) z withOctaves: (size_t) count
290
 
{
291
 
 
292
 
        v3 v = {{x,y,z}};
293
 
 
294
 
        float noise = 0.0f;
295
 
        float factors = 0.0f;
296
 
        
297
 
        if (count > 100)
298
 
                count = 100;
299
 
        
300
 
        
301
 
        for (size_t i = 0; i < count; ++i)
302
 
        {
303
 
                float scale = 1.0f+i;
304
 
                float factor = 1.0f/(scale*scale);
305
 
                factors += factor;
306
 
                v3 offset = {{i,i,i}};
307
 
                noise += [self noise3dWithVector: vadd(vmul(v,scale),offset)]*factor;
308
 
        }
309
 
        return noise/factors;
310
 
};
311
 
 
312
 
- (float) noise3dWithX: (float) x Y: (float) y Z: (float) z withOctaves: (size_t) count ofType: (int) type
313
 
{
314
 
        switch(type)
315
 
        {
316
 
                case 6:
317
 
                return [self noise3dBrownWithX: x Y: y Z: z withOctaves: count];
318
 
                case 5:
319
 
                return [self noise3dPinkWithX: x Y: y Z: z withOctaves: count];
320
 
                case 4:
321
 
                return [self noise3dWhiteWithX: x Y: y Z: z withOctaves: count];
322
 
                case 3:
323
 
                return [self noise3dOctavesSqrWithX: x Y: y Z: z withOctaves: count];
324
 
                case 2:
325
 
                return [self noise3dOctavesWithX: x Y: y Z: z withOctaves: count];
326
 
                case 1:
327
 
                return [self noise3dPrimeWithX: x Y: y Z: z withOctaves: count];
328
 
                case 0:
329
 
                default:
330
 
                return [self noise3dWithX: x Y: y Z: z];
331
 
        }
332
 
};
333
 
 
334
 
@end

Loggerhead 1.17 is a web-based interface for Bazaar branches