source: trunk/examples/demo/opengl/fbm.c@ 203

Last change on this file since 203 was 160, checked in by dmik, 19 years ago

Imported table and iconview modules and a bunch of dependent examples from the official release 3.3.1 from Trolltech.

  • Property svn:keywords set to Id
File size: 4.6 KB
Line 
1/*****************************************************************
2
3 Implementation of the fractional Brownian motion algorithm. These
4 functions were originally the work of F. Kenton Musgrave.
5 For documentation of the different functions please refer to the
6 book:
7 "Texturing and modeling: a procedural approach"
8 by David S. Ebert et. al.
9
10******************************************************************/
11
12#if defined (_MSC_VER)
13#include <qglobal.h>
14#endif
15
16#include <time.h>
17#include <stdlib.h>
18#include "fbm.h"
19
20#if defined(Q_CC_MSVC)
21#pragma warning(disable:4244)
22#endif
23
24/* Definitions used by the noise2() functions */
25
26#define B 0x100
27#define BM 0xff
28
29#define N 0x1000
30#define NP 12 /* 2^N */
31#define NM 0xfff
32
33static int p[B + B + 2];
34static float g3[B + B + 2][3];
35static float g2[B + B + 2][2];
36static float g1[B + B + 2];
37static int start = 1;
38
39static void init(void);
40
41#define s_curve(t) ( t * t * (3. - 2. * t) )
42
43#define lerp(t, a, b) ( a + t * (b - a) )
44
45#define setup(i,b0,b1,r0,r1)\
46 t = vec[i] + N;\
47 b0 = ((int)t) & BM;\
48 b1 = (b0+1) & BM;\
49 r0 = t - (int)t;\
50 r1 = r0 - 1.;
51#define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
52
53/* Fractional Brownian Motion function */
54
55double fBm( Vector point, double H, double lacunarity, double octaves,
56 int init )
57{
58
59 double value, frequency, remainder;
60 int i;
61 static double exponent_array[10];
62 float vec[3];
63
64 /* precompute and store spectral weights */
65 if ( init ) {
66 start = 1;
67 srand( time(0) );
68 /* seize required memory for exponent_array */
69 frequency = 1.0;
70 for (i=0; i<=octaves; i++) {
71 /* compute weight for each frequency */
72 exponent_array[i] = pow( frequency, -H );
73 frequency *= lacunarity;
74 }
75 }
76
77 value = 0.0; /* initialize vars to proper values */
78 frequency = 1.0;
79 vec[0]=point.x;
80 vec[1]=point.y;
81 vec[2]=point.z;
82
83
84 /* inner loop of spectral construction */
85 for (i=0; i<octaves; i++) {
86 /* value += noise3( vec ) * exponent_array[i];*/
87 value += noise3( vec ) * exponent_array[i];
88 vec[0] *= lacunarity;
89 vec[1] *= lacunarity;
90 vec[2] *= lacunarity;
91 } /* for */
92
93 remainder = octaves - (int)octaves;
94 if ( remainder ) /* add in ``octaves'' remainder */
95 /* ``i'' and spatial freq. are preset in loop above */
96 value += remainder * noise3( vec ) * exponent_array[i];
97
98 return( value );
99
100} /* fBm() */
101
102
103static float noise3(float vec[3])
104{
105 int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
106 float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
107 register int i, j;
108
109 if (start) {
110 start = 0;
111 init();
112 }
113
114 setup(0, bx0,bx1, rx0,rx1);
115 setup(1, by0,by1, ry0,ry1);
116 setup(2, bz0,bz1, rz0,rz1);
117
118 i = p[ bx0 ];
119 j = p[ bx1 ];
120
121 b00 = p[ i + by0 ];
122 b10 = p[ j + by0 ];
123 b01 = p[ i + by1 ];
124 b11 = p[ j + by1 ];
125
126 t = s_curve(rx0);
127 sy = s_curve(ry0);
128 sz = s_curve(rz0);
129
130
131 q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
132 q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
133 a = lerp(t, u, v);
134
135 q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
136 q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
137 b = lerp(t, u, v);
138
139 c = lerp(sy, a, b);
140
141 q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
142 q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
143 a = lerp(t, u, v);
144
145 q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
146 q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
147 b = lerp(t, u, v);
148
149 d = lerp(sy, a, b);
150
151 return lerp(sz, c, d);
152}
153
154static void normalize2(float v[2])
155{
156 float s;
157
158 s = sqrt(v[0] * v[0] + v[1] * v[1]);
159 v[0] = v[0] / s;
160 v[1] = v[1] / s;
161}
162
163static void normalize3(float v[3])
164{
165 float s;
166
167 s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
168 v[0] = v[0] / s;
169 v[1] = v[1] / s;
170 v[2] = v[2] / s;
171}
172
173static void init(void)
174{
175 int i, j, k;
176
177 for (i = 0 ; i < B ; i++) {
178 p[i] = i;
179
180 g1[i] = (float)((rand() % (B + B)) - B) / B;
181
182 for (j = 0 ; j < 2 ; j++)
183 g2[i][j] = (float)((rand() % (B + B)) - B) / B;
184 normalize2(g2[i]);
185
186 for (j = 0 ; j < 3 ; j++)
187 g3[i][j] = (float)((rand() % (B + B)) - B) / B;
188 normalize3(g3[i]);
189 }
190
191 while (--i) {
192 k = p[i];
193 p[i] = p[j = rand() % B];
194 p[j] = k;
195 }
196
197 for (i = 0 ; i < B + 2 ; i++) {
198 p[B + i] = p[i];
199 g1[B + i] = g1[i];
200 for (j = 0 ; j < 2 ; j++)
201 g2[B + i][j] = g2[i][j];
202 for (j = 0 ; j < 3 ; j++)
203 g3[B + i][j] = g3[i][j];
204 }
205}
Note: See TracBrowser for help on using the repository browser.