Home | History | Annotate | Download | only in rs
      1 /*
      2  * This implementation of the noise functions was ported from the Java
      3  * implementation by Jerry Huxtable (http://www.jhlabs.com) under
      4  * Apache License 2.0 (see http://jhlabs.com/ip/filters/download.html)
      5  *
      6  * Original header:
      7  *
      8  * Copyright 2006 Jerry Huxtable
      9  *
     10  * Licensed under the Apache License, Version 2.0 (the "License");
     11  * you may not use this file except in compliance with the License.
     12  * You may obtain a copy of the License at
     13  *
     14  * http://www.apache.org/licenses/LICENSE-2.0
     15  *
     16  * Unless required by applicable law or agreed to in writing, software
     17  * distributed under the License is distributed on an "AS IS" BASIS,
     18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     19  * See the License for the specific language governing permissions and
     20  * limitations under the License.
     21  */
     22 
     23 #include "rsNoise.h"
     24 
     25 #include <math.h>
     26 #include <stdlib.h>
     27 #include <time.h>
     28 
     29 namespace android {
     30 namespace renderscript {
     31 
     32 #define B 0x100
     33 #define BM 0xff
     34 #define N 0x1000
     35 
     36 static int p[B + B + 2];
     37 static float g3[B + B + 2][3];
     38 static float g2[B + B + 2][2];
     39 static float g1[B + B + 2];
     40 static bool noise_start = true;
     41 
     42 #define lerpf(start, stop, amount) start + (stop - start) * amount
     43 
     44 static inline float noise_sCurve(float t)
     45 {
     46     return t * t * (3.0f - 2.0f * t);
     47 }
     48 
     49 inline void SC_normalizef2(float v[])
     50 {
     51     float s = (float)sqrtf(v[0] * v[0] + v[1] * v[1]);
     52     v[0] = v[0] / s;
     53     v[1] = v[1] / s;
     54 }
     55 
     56 inline void SC_normalizef3(float v[])
     57 {
     58     float s = (float)sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
     59     v[0] = v[0] / s;
     60     v[1] = v[1] / s;
     61     v[2] = v[2] / s;
     62 }
     63 
     64 static void noise_init()
     65 {
     66     int i, j, k;
     67 
     68     for (i = 0; i < B; i++) {
     69         p[i] = i;
     70 
     71         g1[i] = (float)((rand() % (B + B)) - B) / B;
     72 
     73         for (j = 0; j < 2; j++)
     74             g2[i][j] = (float)((rand() % (B + B)) - B) / B;
     75         SC_normalizef2(g2[i]);
     76 
     77         for (j = 0; j < 3; j++)
     78             g3[i][j] = (float)((rand() % (B + B)) - B) / B;
     79         SC_normalizef3(g3[i]);
     80     }
     81 
     82     for (i = B-1; i >= 0; i--) {
     83         k = p[i];
     84         p[i] = p[j = rand() % B];
     85         p[j] = k;
     86     }
     87 
     88     for (i = 0; i < B + 2; i++) {
     89         p[B + i] = p[i];
     90         g1[B + i] = g1[i];
     91         for (j = 0; j < 2; j++)
     92             g2[B + i][j] = g2[i][j];
     93         for (j = 0; j < 3; j++)
     94             g3[B + i][j] = g3[i][j];
     95     }
     96 }
     97 
     98 float SC_noisef(float x)
     99 {
    100     srand(time(NULL));
    101     int bx0, bx1;
    102     float rx0, rx1, sx, t, u, v;
    103 
    104     if (noise_start) {
    105         noise_start = false;
    106         noise_init();
    107     }
    108 
    109     t = x + N;
    110     bx0 = ((int)t) & BM;
    111     bx1 = (bx0+1) & BM;
    112     rx0 = t - (int)t;
    113     rx1 = rx0 - 1.0f;
    114 
    115     sx = noise_sCurve(rx0);
    116 
    117     u = rx0 * g1[p[bx0]];
    118     v = rx1 * g1[p[bx1]];
    119     return 2.3f * lerpf(u, v, sx);
    120 }
    121 
    122 float SC_noisef2(float x, float y)
    123 {
    124     srand(time(NULL));
    125     int bx0, bx1, by0, by1, b00, b10, b01, b11;
    126     float rx0, rx1, ry0, ry1, sx, sy, a, b, t, u, v;
    127     float *q;
    128     int i, j;
    129 
    130     if (noise_start) {
    131         noise_start = false;
    132         noise_init();
    133     }
    134 
    135     t = x + N;
    136     bx0 = ((int)t) & BM;
    137     bx1 = (bx0+1) & BM;
    138     rx0 = t - (int)t;
    139     rx1 = rx0 - 1.0f;
    140 
    141     t = y + N;
    142     by0 = ((int)t) & BM;
    143     by1 = (by0+1) & BM;
    144     ry0 = t - (int)t;
    145     ry1 = ry0 - 1.0f;
    146 
    147     i = p[bx0];
    148     j = p[bx1];
    149 
    150     b00 = p[i + by0];
    151     b10 = p[j + by0];
    152     b01 = p[i + by1];
    153     b11 = p[j + by1];
    154 
    155     sx = noise_sCurve(rx0);
    156     sy = noise_sCurve(ry0);
    157 
    158     q = g2[b00]; u = rx0 * q[0] + ry0 * q[1];
    159     q = g2[b10]; v = rx1 * q[0] + ry0 * q[1];
    160     a = lerpf(u, v, sx);
    161 
    162     q = g2[b01]; u = rx0 * q[0] + ry1 * q[1];
    163     q = g2[b11]; v = rx1 * q[0] + ry1 * q[1];
    164     b = lerpf(u, v, sx);
    165 
    166     return 1.5f*lerpf(a, b, sy);
    167 }
    168 
    169 float SC_noisef3(float x, float y, float z)
    170 {
    171     srand(time(NULL));
    172     int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
    173     float rx0, rx1, ry0, ry1, rz0, rz1, sy, sz, a, b, c, d, t, u, v;
    174     float *q;
    175     int i, j;
    176 
    177     if (noise_start) {
    178         noise_start = false;
    179         noise_init();
    180     }
    181 
    182     t = x + N;
    183     bx0 = ((int)t) & BM;
    184     bx1 = (bx0+1) & BM;
    185     rx0 = t - (int)t;
    186     rx1 = rx0 - 1.0f;
    187 
    188     t = y + N;
    189     by0 = ((int)t) & BM;
    190     by1 = (by0+1) & BM;
    191     ry0 = t - (int)t;
    192     ry1 = ry0 - 1.0f;
    193 
    194     t = z + N;
    195     bz0 = ((int)t) & BM;
    196     bz1 = (bz0+1) & BM;
    197     rz0 = t - (int)t;
    198     rz1 = rz0 - 1.0f;
    199 
    200     i = p[bx0];
    201     j = p[bx1];
    202 
    203     b00 = p[i + by0];
    204     b10 = p[j + by0];
    205     b01 = p[i + by1];
    206     b11 = p[j + by1];
    207 
    208     t  = noise_sCurve(rx0);
    209     sy = noise_sCurve(ry0);
    210     sz = noise_sCurve(rz0);
    211 
    212     q = g3[b00 + bz0]; u = rx0 * q[0] + ry0 * q[1] + rz0 * q[2];
    213     q = g3[b10 + bz0]; v = rx1 * q[0] + ry0 * q[1] + rz0 * q[2];
    214     a = lerpf(u, v, t);
    215 
    216     q = g3[b01 + bz0]; u = rx0 * q[0] + ry1 * q[1] + rz0 * q[2];
    217     q = g3[b11 + bz0]; v = rx1 * q[0] + ry1 * q[1] + rz0 * q[2];
    218     b = lerpf(u, v, t);
    219 
    220     c = lerpf(a, b, sy);
    221 
    222     q = g3[b00 + bz1]; u = rx0 * q[0] + ry0 * q[1] + rz1 * q[2];
    223     q = g3[b10 + bz1]; v = rx1 * q[0] + ry0 * q[1] + rz1 * q[2];
    224     a = lerpf(u, v, t);
    225 
    226     q = g3[b01 + bz1]; u = rx0 * q[0] + ry1 * q[1] + rz1 * q[2];
    227     q = g3[b11 + bz1]; v = rx1 * q[0] + ry1 * q[1] + rz1 * q[2];
    228     b = lerpf(u, v, t);
    229 
    230     d = lerpf(a, b, sy);
    231 
    232     return 1.5f*lerpf(c, d, sz);
    233 }
    234 
    235 float SC_turbulencef2(float x, float y, float octaves)
    236 {
    237     srand(time(NULL));
    238     float t = 0.0f;
    239 
    240     for (float f = 1.0f; f <= octaves; f *= 2)
    241         t += fabs(SC_noisef2(f * x, f * y)) / f;
    242     return t;
    243 }
    244 
    245 float SC_turbulencef3(float x, float y, float z, float octaves)
    246 {
    247     srand(time(NULL));
    248     float t = 0.0f;
    249 
    250     for (float f = 1.0f; f <= octaves; f *= 2)
    251         t += fabs(SC_noisef3(f * x, f * y, f * z)) / f;
    252     return t;
    253 }
    254 
    255 }
    256 }