/***************************************************************************
 * Copyright 1998-2017 by authors (see AUTHORS.txt)                        *
 *                                                                         *
 *   This file is part of LuxRender.                                       *
 *                                                                         *
 * Licensed under the Apache License, Version 2.0 (the "License");         *
 * you may not use this file except in compliance with the License.        *
 * You may obtain a copy of the License at                                 *
 *                                                                         *
 *     http://www.apache.org/licenses/LICENSE-2.0                          *
 *                                                                         *
 * Unless required by applicable law or agreed to in writing, software     *
 * distributed under the License is distributed on an "AS IS" BASIS,       *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.*
 * See the License for the specific language governing permissions and     *
 * limitations under the License.                                          *
 ***************************************************************************/

#include "slg/core/sdl.h"
#include "slg/textures/blender_noiselib.h"

namespace slg {

namespace blender {

typedef unsigned long long r_uint64;

#define RNG_MULTIPLIER	0x5DEECE66Dll
#define RNG_MASK		0x0000FFFFFFFFFFFFll
#define RNG_ADDEND		0xB

struct RNG {
    r_uint64 X;
};

static RNG theBLI_rng = {0};

int rng_getInt(RNG *rng) {
    rng->X = (RNG_MULTIPLIER * rng->X + RNG_ADDEND) & RNG_MASK;
    return (int) (rng->X >> 17);
}

int BLI_rand(void) {
    return rng_getInt(&theBLI_rng);
}

/* needed for voronoi */
#define HASHPNT(x,y,z) hashpntf+3*hash[ (hash[ (hash[(z) & 255]+(y)) & 255]+(x)) & 255]

static float hashpntf[768] = {0.536902f, 0.020915f, 0.501445f, 0.216316f, 0.517036f, 0.822466f, 0.965315f,
0.377313f, 0.678764f, 0.744545f, 0.097731f, 0.396357f, 0.247202f, 0.520897f,
0.613396f, 0.542124f, 0.146813f, 0.255489f, 0.810868f, 0.638641f, 0.980742f,
0.292316f, 0.357948f, 0.114382f, 0.861377f, 0.629634f, 0.722530f, 0.714103f,
0.048549f, 0.075668f, 0.564920f, 0.162026f, 0.054466f, 0.411738f, 0.156897f,
0.887657f, 0.599368f, 0.074249f, 0.170277f, 0.225799f, 0.393154f, 0.301348f,
0.057434f, 0.293849f, 0.442745f, 0.150002f, 0.398732f, 0.184582f, 0.915200f,
0.630984f, 0.974040f, 0.117228f, 0.795520f, 0.763238f, 0.158982f, 0.616211f,
0.250825f, 0.906539f, 0.316874f, 0.676205f, 0.234720f, 0.667673f, 0.792225f,
0.273671f, 0.119363f, 0.199131f, 0.856716f, 0.828554f, 0.900718f, 0.705960f,
0.635923f, 0.989433f, 0.027261f, 0.283507f, 0.113426f, 0.388115f, 0.900176f,
0.637741f, 0.438802f, 0.715490f, 0.043692f, 0.202640f, 0.378325f, 0.450325f,
0.471832f, 0.147803f, 0.906899f, 0.524178f, 0.784981f, 0.051483f, 0.893369f,
0.596895f, 0.275635f, 0.391483f, 0.844673f, 0.103061f, 0.257322f, 0.708390f,
0.504091f, 0.199517f, 0.660339f, 0.376071f, 0.038880f, 0.531293f, 0.216116f,
0.138672f, 0.907737f, 0.807994f, 0.659582f, 0.915264f, 0.449075f, 0.627128f,
0.480173f, 0.380942f, 0.018843f, 0.211808f, 0.569701f, 0.082294f, 0.689488f, 
0.573060f, 0.593859f, 0.216080f, 0.373159f, 0.108117f, 0.595539f, 0.021768f, 
0.380297f, 0.948125f, 0.377833f, 0.319699f, 0.315249f, 0.972805f, 0.792270f, 
0.445396f, 0.845323f, 0.372186f, 0.096147f, 0.689405f, 0.423958f, 0.055675f, 
0.117940f, 0.328456f, 0.605808f, 0.631768f, 0.372170f, 0.213723f, 0.032700f, 
0.447257f, 0.440661f, 0.728488f, 0.299853f, 0.148599f, 0.649212f, 0.498381f,
0.049921f, 0.496112f, 0.607142f, 0.562595f, 0.990246f, 0.739659f, 0.108633f, 
0.978156f, 0.209814f, 0.258436f, 0.876021f, 0.309260f, 0.600673f, 0.713597f, 
0.576967f, 0.641402f, 0.853930f, 0.029173f, 0.418111f, 0.581593f, 0.008394f, 
0.589904f, 0.661574f, 0.979326f, 0.275724f, 0.111109f, 0.440472f, 0.120839f, 
0.521602f, 0.648308f, 0.284575f, 0.204501f, 0.153286f, 0.822444f, 0.300786f, 
0.303906f, 0.364717f, 0.209038f, 0.916831f, 0.900245f, 0.600685f, 0.890002f, 
0.581660f, 0.431154f, 0.705569f, 0.551250f, 0.417075f, 0.403749f, 0.696652f, 
0.292652f, 0.911372f, 0.690922f, 0.323718f, 0.036773f, 0.258976f, 0.274265f, 
0.225076f, 0.628965f, 0.351644f, 0.065158f, 0.080340f, 0.467271f, 0.130643f,
0.385914f, 0.919315f, 0.253821f, 0.966163f, 0.017439f, 0.392610f, 0.478792f, 
0.978185f, 0.072691f, 0.982009f, 0.097987f, 0.731533f, 0.401233f, 0.107570f, 
0.349587f, 0.479122f, 0.700598f, 0.481751f, 0.788429f, 0.706864f, 0.120086f, 
0.562691f, 0.981797f, 0.001223f, 0.192120f, 0.451543f, 0.173092f, 0.108960f,
0.549594f, 0.587892f, 0.657534f, 0.396365f, 0.125153f, 0.666420f, 0.385823f, 
0.890916f, 0.436729f, 0.128114f, 0.369598f, 0.759096f, 0.044677f, 0.904752f, 
0.088052f, 0.621148f, 0.005047f, 0.452331f, 0.162032f, 0.494238f, 0.523349f, 
0.741829f, 0.698450f, 0.452316f, 0.563487f, 0.819776f, 0.492160f, 0.004210f, 
0.647158f, 0.551475f, 0.362995f, 0.177937f, 0.814722f, 0.727729f, 0.867126f, 
0.997157f, 0.108149f, 0.085726f, 0.796024f, 0.665075f, 0.362462f, 0.323124f,
0.043718f, 0.042357f, 0.315030f, 0.328954f, 0.870845f, 0.683186f, 0.467922f, 
0.514894f, 0.809971f, 0.631979f, 0.176571f, 0.366320f, 0.850621f, 0.505555f, 
0.749551f, 0.750830f, 0.401714f, 0.481216f, 0.438393f, 0.508832f, 0.867971f, 
0.654581f, 0.058204f, 0.566454f, 0.084124f, 0.548539f, 0.902690f, 0.779571f, 
0.562058f, 0.048082f, 0.863109f, 0.079290f, 0.713559f, 0.783496f, 0.265266f, 
0.672089f, 0.786939f, 0.143048f, 0.086196f, 0.876129f, 0.408708f, 0.229312f, 
0.629995f, 0.206665f, 0.207308f, 0.710079f, 0.341704f, 0.264921f, 0.028748f, 
0.629222f, 0.470173f, 0.726228f, 0.125243f, 0.328249f, 0.794187f, 0.741340f, 
0.489895f, 0.189396f, 0.724654f, 0.092841f, 0.039809f, 0.860126f, 0.247701f, 
0.655331f, 0.964121f, 0.672536f, 0.044522f, 0.690567f, 0.837238f, 0.631520f, 
0.953734f, 0.352484f, 0.289026f, 0.034152f, 0.852575f, 0.098454f, 0.795529f, 
0.452181f, 0.826159f, 0.186993f, 0.820725f, 0.440328f, 0.922137f, 0.704592f,
0.915437f, 0.738183f, 0.733461f, 0.193798f, 0.929213f, 0.161390f, 0.318547f,
0.888751f, 0.430968f, 0.740837f, 0.193544f, 0.872253f, 0.563074f, 0.274598f, 
0.347805f, 0.666176f, 0.449831f, 0.800991f, 0.588727f, 0.052296f, 0.714761f, 
0.420620f, 0.570325f, 0.057550f, 0.210888f, 0.407312f, 0.662848f, 0.924382f, 
0.895958f, 0.775198f, 0.688605f, 0.025721f, 0.301913f, 0.791408f, 0.500602f, 
0.831984f, 0.828509f, 0.642093f, 0.494174f, 0.525880f, 0.446365f, 0.440063f, 
0.763114f, 0.630358f, 0.223943f, 0.333806f, 0.906033f, 0.498306f, 0.241278f,
0.427640f, 0.772683f, 0.198082f, 0.225379f, 0.503894f, 0.436599f, 0.016503f, 
0.803725f, 0.189878f, 0.291095f, 0.499114f, 0.151573f, 0.079031f, 0.904618f, 
0.708535f, 0.273900f, 0.067419f, 0.317124f, 0.936499f, 0.716511f, 0.543845f, 
0.939909f, 0.826574f, 0.715090f, 0.154864f, 0.750150f, 0.845808f, 0.648108f, 
0.556564f, 0.644757f, 0.140873f, 0.799167f, 0.632989f, 0.444245f, 0.471978f, 
0.435910f, 0.359793f, 0.216241f, 0.007633f, 0.337236f, 0.857863f, 0.380247f, 
0.092517f, 0.799973f, 0.919000f, 0.296798f, 0.096989f, 0.854831f, 0.165369f, 
0.568475f, 0.216855f, 0.020457f, 0.835511f, 0.538039f, 0.999742f, 0.620226f, 
0.244053f, 0.060399f, 0.323007f, 0.294874f, 0.988899f, 0.384919f, 0.735655f, 
0.773428f, 0.549776f, 0.292882f, 0.660611f, 0.593507f, 0.621118f, 0.175269f, 
0.682119f, 0.794493f, 0.868197f, 0.632150f, 0.807823f, 0.509656f, 0.482035f, 
0.001780f, 0.259126f, 0.358002f, 0.280263f, 0.192985f, 0.290367f, 0.208111f, 
0.917633f, 0.114422f, 0.925491f, 0.981110f, 0.255570f, 0.974862f, 0.016629f,
0.552599f, 0.575741f, 0.612978f, 0.615965f, 0.803615f, 0.772334f, 0.089745f, 
0.838812f, 0.634542f, 0.113709f, 0.755832f, 0.577589f, 0.667489f, 0.529834f,
0.325660f, 0.817597f, 0.316557f, 0.335093f, 0.737363f, 0.260951f, 0.737073f, 
0.049540f, 0.735541f, 0.988891f, 0.299116f, 0.147695f, 0.417271f, 0.940811f, 
0.524160f, 0.857968f, 0.176403f, 0.244835f, 0.485759f, 0.033353f, 0.280319f, 
0.750688f, 0.755809f, 0.924208f, 0.095956f, 0.962504f, 0.275584f, 0.173715f,
0.942716f, 0.706721f, 0.078464f, 0.576716f, 0.804667f, 0.559249f, 0.900611f, 
0.646904f, 0.432111f, 0.927885f, 0.383277f, 0.269973f, 0.114244f, 0.574867f, 
0.150703f, 0.241855f, 0.272871f, 0.199950f, 0.079719f, 0.868566f, 0.962833f, 
0.789122f, 0.320025f, 0.905554f, 0.234876f, 0.991356f, 0.061913f, 0.732911f, 
0.785960f, 0.874074f, 0.069035f, 0.658632f, 0.309901f, 0.023676f, 0.791603f, 
0.764661f, 0.661278f, 0.319583f, 0.829650f, 0.117091f, 0.903124f, 0.982098f, 
0.161631f, 0.193576f, 0.670428f, 0.857390f, 0.003760f, 0.572578f, 0.222162f, 
0.114551f, 0.420118f, 0.530404f, 0.470682f, 0.525527f, 0.764281f, 0.040596f, 
0.443275f, 0.501124f, 0.816161f, 0.417467f, 0.332172f, 0.447565f, 0.614591f, 
0.559246f, 0.805295f, 0.226342f, 0.155065f, 0.714630f, 0.160925f, 0.760001f, 
0.453456f, 0.093869f, 0.406092f, 0.264801f, 0.720370f, 0.743388f, 0.373269f, 
0.403098f, 0.911923f, 0.897249f, 0.147038f, 0.753037f, 0.516093f, 0.739257f, 
0.175018f, 0.045768f, 0.735857f, 0.801330f, 0.927708f, 0.240977f, 0.591870f,
0.921831f, 0.540733f, 0.149100f, 0.423152f, 0.806876f, 0.397081f, 0.061100f, 
0.811630f, 0.044899f, 0.460915f, 0.961202f, 0.822098f, 0.971524f, 0.867608f, 
0.773604f, 0.226616f, 0.686286f, 0.926972f, 0.411613f, 0.267873f, 0.081937f, 
0.226124f, 0.295664f, 0.374594f, 0.533240f, 0.237876f, 0.669629f, 0.599083f, 
0.513081f, 0.878719f, 0.201577f, 0.721296f, 0.495038f, 0.079760f, 0.965959f,
0.233090f, 0.052496f, 0.714748f, 0.887844f, 0.308724f, 0.972885f, 0.723337f,
0.453089f, 0.914474f, 0.704063f, 0.823198f, 0.834769f, 0.906561f, 0.919600f,
0.100601f, 0.307564f, 0.901977f, 0.468879f, 0.265376f, 0.885188f, 0.683875f,
0.868623f, 0.081032f, 0.466835f, 0.199087f, 0.663437f, 0.812241f, 0.311337f,
0.821361f, 0.356628f, 0.898054f, 0.160781f, 0.222539f, 0.714889f, 0.490287f,
0.984915f, 0.951755f, 0.964097f, 0.641795f, 0.815472f, 0.852732f, 0.862074f,
0.051108f, 0.440139f, 0.323207f, 0.517171f, 0.562984f, 0.115295f, 0.743103f,
0.977914f, 0.337596f, 0.440694f, 0.535879f, 0.959427f, 0.351427f, 0.704361f,
0.010826f, 0.131162f, 0.577080f, 0.349572f, 0.774892f, 0.425796f, 0.072697f,
0.500001f, 0.267322f, 0.909654f, 0.206176f, 0.223987f, 0.937698f, 0.323423f,
0.117501f, 0.490308f, 0.474372f, 0.689943f, 0.168671f, 0.719417f, 0.188928f,
0.330464f, 0.265273f, 0.446271f, 0.171933f, 0.176133f, 0.474616f, 0.140182f,
0.114246f, 0.905043f, 0.713870f, 0.555261f, 0.951333f};

const unsigned char hash[512]= {
0xA2,0xA0,0x19,0x3B,0xF8,0xEB,0xAA,0xEE,0xF3,0x1C,0x67,0x28,0x1D,0xED,0x0,0xDE,0x95,0x2E,0xDC,0x3F,0x3A,0x82,0x35,0x4D,0x6C,0xBA,0x36,0xD0,0xF6,0xC,0x79,0x32,0xD1,0x59,0xF4,0x8,0x8B,0x63,0x89,0x2F,0xB8,0xB4,0x97,0x83,0xF2,0x8F,0x18,0xC7,0x51,0x14,0x65,0x87,0x48,0x20,0x42,0xA8,0x80,0xB5,0x40,0x13,0xB2,0x22,0x7E,0x57,
0xBC,0x7F,0x6B,0x9D,0x86,0x4C,0xC8,0xDB,0x7C,0xD5,0x25,0x4E,0x5A,0x55,0x74,0x50,0xCD,0xB3,0x7A,0xBB,0xC3,0xCB,0xB6,0xE2,0xE4,0xEC,0xFD,0x98,0xB,0x96,0xD3,0x9E,0x5C,0xA1,0x64,0xF1,0x81,0x61,0xE1,0xC4,0x24,0x72,0x49,0x8C,0x90,0x4B,0x84,0x34,0x38,0xAB,0x78,0xCA,0x1F,0x1,0xD7,0x93,0x11,0xC1,0x58,0xA9,0x31,0xF9,0x44,0x6D,
0xBF,0x33,0x9C,0x5F,0x9,0x94,0xA3,0x85,0x6,0xC6,0x9A,0x1E,0x7B,0x46,0x15,0x30,0x27,0x2B,0x1B,0x71,0x3C,0x5B,0xD6,0x6F,0x62,0xAC,0x4F,0xC2,0xC0,0xE,0xB1,0x23,0xA7,0xDF,0x47,0xB0,0x77,0x69,0x5,0xE9,0xE6,0xE7,0x76,0x73,0xF,0xFE,0x6E,0x9B,0x56,0xEF,0x12,0xA5,0x37,0xFC,0xAE,0xD9,0x3,0x8E,0xDD,0x10,0xB9,0xCE,0xC9,0x8D,
0xDA,0x2A,0xBD,0x68,0x17,0x9F,0xBE,0xD4,0xA,0xCC,0xD2,0xE8,0x43,0x3D,0x70,0xB7,0x2,0x7D,0x99,0xD8,0xD,0x60,0x8A,0x4,0x2C,0x3E,0x92,0xE5,0xAF,0x53,0x7,0xE0,0x29,0xA6,0xC5,0xE3,0xF5,0xF7,0x4A,0x41,0x26,0x6A,0x16,0x5E,0x52,0x2D,0x21,0xAD,0xF0,0x91,0xFF,0xEA,0x54,0xFA,0x66,0x1A,0x45,0x39,0xCF,0x75,0xA4,0x88,0xFB,0x5D,
0xA2,0xA0,0x19,0x3B,0xF8,0xEB,0xAA,0xEE,0xF3,0x1C,0x67,0x28,0x1D,0xED,0x0,0xDE,0x95,0x2E,0xDC,0x3F,0x3A,0x82,0x35,0x4D,0x6C,0xBA,0x36,0xD0,0xF6,0xC,0x79,0x32,0xD1,0x59,0xF4,0x8,0x8B,0x63,0x89,0x2F,0xB8,0xB4,0x97,0x83,0xF2,0x8F,0x18,0xC7,0x51,0x14,0x65,0x87,0x48,0x20,0x42,0xA8,0x80,0xB5,0x40,0x13,0xB2,0x22,0x7E,0x57,
0xBC,0x7F,0x6B,0x9D,0x86,0x4C,0xC8,0xDB,0x7C,0xD5,0x25,0x4E,0x5A,0x55,0x74,0x50,0xCD,0xB3,0x7A,0xBB,0xC3,0xCB,0xB6,0xE2,0xE4,0xEC,0xFD,0x98,0xB,0x96,0xD3,0x9E,0x5C,0xA1,0x64,0xF1,0x81,0x61,0xE1,0xC4,0x24,0x72,0x49,0x8C,0x90,0x4B,0x84,0x34,0x38,0xAB,0x78,0xCA,0x1F,0x1,0xD7,0x93,0x11,0xC1,0x58,0xA9,0x31,0xF9,0x44,0x6D,
0xBF,0x33,0x9C,0x5F,0x9,0x94,0xA3,0x85,0x6,0xC6,0x9A,0x1E,0x7B,0x46,0x15,0x30,0x27,0x2B,0x1B,0x71,0x3C,0x5B,0xD6,0x6F,0x62,0xAC,0x4F,0xC2,0xC0,0xE,0xB1,0x23,0xA7,0xDF,0x47,0xB0,0x77,0x69,0x5,0xE9,0xE6,0xE7,0x76,0x73,0xF,0xFE,0x6E,0x9B,0x56,0xEF,0x12,0xA5,0x37,0xFC,0xAE,0xD9,0x3,0x8E,0xDD,0x10,0xB9,0xCE,0xC9,0x8D,
0xDA,0x2A,0xBD,0x68,0x17,0x9F,0xBE,0xD4,0xA,0xCC,0xD2,0xE8,0x43,0x3D,0x70,0xB7,0x2,0x7D,0x99,0xD8,0xD,0x60,0x8A,0x4,0x2C,0x3E,0x92,0xE5,0xAF,0x53,0x7,0xE0,0x29,0xA6,0xC5,0xE3,0xF5,0xF7,0x4A,0x41,0x26,0x6A,0x16,0x5E,0x52,0x2D,0x21,0xAD,0xF0,0x91,0xFF,0xEA,0x54,0xFA,0x66,0x1A,0x45,0x39,0xCF,0x75,0xA4,0x88,0xFB,0x5D,
};

float hashvectf[768]= {
0.33783f,0.715698f,-0.611206f,-0.944031f,-0.326599f,-0.045624f,-0.101074f,-0.416443f,-0.903503f,0.799286f,0.49411f,-0.341949f,-0.854645f,0.518036f,0.033936f,0.42514f,-0.437866f,-0.792114f,-0.358948f,0.597046f,0.717377f,-0.985413f,0.144714f,0.089294f,-0.601776f,-0.33728f,-0.723907f,-0.449921f,0.594513f,0.666382f,0.208313f,-0.10791f,
0.972076f,0.575317f,0.060425f,0.815643f,0.293365f,-0.875702f,-0.383453f,0.293762f,0.465759f,0.834686f,-0.846008f,-0.233398f,-0.47934f,-0.115814f,0.143036f,-0.98291f,0.204681f,-0.949036f,-0.239532f,0.946716f,-0.263947f,0.184326f,-0.235596f,0.573822f,0.784332f,0.203705f,-0.372253f,-0.905487f,0.756989f,-0.651031f,0.055298f,0.497803f,
0.814697f,-0.297363f,-0.16214f,0.063995f,-0.98468f,-0.329254f,0.834381f,0.441925f,0.703827f,-0.527039f,-0.476227f,0.956421f,0.266113f,0.119781f,0.480133f,0.482849f,0.7323f,-0.18631f,0.961212f,-0.203125f,-0.748474f,-0.656921f,-0.090393f,-0.085052f,-0.165253f,0.982544f,-0.76947f,0.628174f,-0.115234f,0.383148f,0.537659f,0.751068f,
0.616486f,-0.668488f,-0.415924f,-0.259979f,-0.630005f,0.73175f,0.570953f,-0.087952f,0.816223f,-0.458008f,0.023254f,0.888611f,-0.196167f,0.976563f,-0.088287f,-0.263885f,-0.69812f,-0.665527f,0.437134f,-0.892273f,-0.112793f,-0.621674f,-0.230438f,0.748566f,0.232422f,0.900574f,-0.367249f,0.22229f,-0.796143f,0.562744f,-0.665497f,-0.73764f,
0.11377f,0.670135f,0.704803f,0.232605f,0.895599f,0.429749f,-0.114655f,-0.11557f,-0.474243f,0.872742f,0.621826f,0.604004f,-0.498444f,-0.832214f,0.012756f,0.55426f,-0.702484f,0.705994f,-0.089661f,-0.692017f,0.649292f,0.315399f,-0.175995f,-0.977997f,0.111877f,0.096954f,-0.04953f,0.994019f,0.635284f,-0.606689f,-0.477783f,-0.261261f,
-0.607422f,-0.750153f,0.983276f,0.165436f,0.075958f,-0.29837f,0.404083f,-0.864655f,-0.638672f,0.507721f,0.578156f,0.388214f,0.412079f,0.824249f,0.556183f,-0.208832f,0.804352f,0.778442f,0.562012f,0.27951f,-0.616577f,0.781921f,-0.091522f,0.196289f,0.051056f,0.979187f,-0.121216f,0.207153f,-0.970734f,-0.173401f,-0.384735f,0.906555f,
0.161499f,-0.723236f,-0.671387f,0.178497f,-0.006226f,-0.983887f,-0.126038f,0.15799f,0.97934f,0.830475f,-0.024811f,0.556458f,-0.510132f,-0.76944f,0.384247f,0.81424f,0.200104f,-0.544891f,-0.112549f,-0.393311f,-0.912445f,0.56189f,0.152222f,-0.813049f,0.198914f,-0.254517f,-0.946381f,-0.41217f,0.690979f,-0.593811f,-0.407257f,0.324524f,
0.853668f,-0.690186f,0.366119f,-0.624115f,-0.428345f,0.844147f,-0.322296f,-0.21228f,-0.297546f,-0.930756f,-0.273071f,0.516113f,0.811798f,0.928314f,0.371643f,0.007233f,0.785828f,-0.479218f,-0.390778f,-0.704895f,0.058929f,0.706818f,0.173248f,0.203583f,0.963562f,0.422211f,-0.904297f,-0.062469f,-0.363312f,-0.182465f,0.913605f,0.254028f,
-0.552307f,-0.793945f,-0.28891f,-0.765747f,-0.574554f,0.058319f,0.291382f,0.954803f,0.946136f,-0.303925f,0.111267f,-0.078156f,0.443695f,-0.892731f,0.182098f,0.89389f,0.409515f,-0.680298f,-0.213318f,0.701141f,0.062469f,0.848389f,-0.525635f,-0.72879f,-0.641846f,0.238342f,-0.88089f,0.427673f,0.202637f,-0.532501f,-0.21405f,0.818878f,
0.948975f,-0.305084f,0.07962f,0.925446f,0.374664f,0.055817f,0.820923f,0.565491f,0.079102f,0.25882f,0.099792f,-0.960724f,-0.294617f,0.910522f,0.289978f,0.137115f,0.320038f,-0.937408f,-0.908386f,0.345276f,-0.235718f,-0.936218f,0.138763f,0.322754f,0.366577f,0.925934f,-0.090637f,0.309296f,-0.686829f,-0.657684f,0.66983f,0.024445f,
0.742065f,-0.917999f,-0.059113f,-0.392059f,0.365509f,0.462158f,-0.807922f,0.083374f,0.996399f,-0.014801f,0.593842f,0.253143f,-0.763672f,0.974976f,-0.165466f,0.148285f,0.918976f,0.137299f,0.369537f,0.294952f,0.694977f,0.655731f,0.943085f,0.152618f,-0.295319f,0.58783f,-0.598236f,0.544495f,0.203796f,0.678223f,0.705994f,-0.478821f,
-0.661011f,0.577667f,0.719055f,-0.1698f,-0.673828f,-0.132172f,-0.965332f,0.225006f,-0.981873f,-0.14502f,0.121979f,0.763458f,0.579742f,0.284546f,-0.893188f,0.079681f,0.442474f,-0.795776f,-0.523804f,0.303802f,0.734955f,0.67804f,-0.007446f,0.15506f,0.986267f,-0.056183f,0.258026f,0.571503f,-0.778931f,-0.681549f,-0.702087f,-0.206116f,
-0.96286f,-0.177185f,0.203613f,-0.470978f,-0.515106f,0.716095f,-0.740326f,0.57135f,0.354095f,-0.56012f,-0.824982f,-0.074982f,-0.507874f,0.753204f,0.417969f,-0.503113f,0.038147f,0.863342f,0.594025f,0.673553f,-0.439758f,-0.119873f,-0.005524f,-0.992737f,0.098267f,-0.213776f,0.971893f,-0.615631f,0.643951f,0.454163f,0.896851f,-0.441071f,
0.032166f,-0.555023f,0.750763f,-0.358093f,0.398773f,0.304688f,0.864929f,-0.722961f,0.303589f,0.620544f,-0.63559f,-0.621948f,-0.457306f,-0.293243f,0.072327f,0.953278f,-0.491638f,0.661041f,-0.566772f,-0.304199f,-0.572083f,-0.761688f,0.908081f,-0.398956f,0.127014f,-0.523621f,-0.549683f,-0.650848f,-0.932922f,-0.19986f,0.299408f,0.099426f,
0.140869f,0.984985f,-0.020325f,-0.999756f,-0.002319f,0.952667f,0.280853f,-0.11615f,-0.971893f,0.082581f,0.220337f,0.65921f,0.705292f,-0.260651f,0.733063f,-0.175537f,0.657043f,-0.555206f,0.429504f,-0.712189f,0.400421f,-0.89859f,0.179352f,0.750885f,-0.19696f,0.630341f,0.785675f,-0.569336f,0.241821f,-0.058899f,-0.464111f,0.883789f,
0.129608f,-0.94519f,0.299622f,-0.357819f,0.907654f,0.219238f,-0.842133f,-0.439117f,-0.312927f,-0.313477f,0.84433f,0.434479f,-0.241211f,0.053253f,0.968994f,0.063873f,0.823273f,0.563965f,0.476288f,0.862152f,-0.172516f,0.620941f,-0.298126f,0.724915f,0.25238f,-0.749359f,-0.612122f,-0.577545f,0.386566f,0.718994f,-0.406342f,-0.737976f,
0.538696f,0.04718f,0.556305f,0.82959f,-0.802856f,0.587463f,0.101166f,-0.707733f,-0.705963f,0.026428f,0.374908f,0.68457f,0.625092f,0.472137f,0.208405f,-0.856506f,-0.703064f,-0.581085f,-0.409821f,-0.417206f,-0.736328f,0.532623f,-0.447876f,-0.20285f,-0.870728f,0.086945f,-0.990417f,0.107086f,0.183685f,0.018341f,-0.982788f,0.560638f,
-0.428864f,0.708282f,0.296722f,-0.952576f,-0.0672f,0.135773f,0.990265f,0.030243f,-0.068787f,0.654724f,0.752686f,0.762604f,-0.551758f,0.337585f,-0.819611f,-0.407684f,0.402466f,-0.727844f,-0.55072f,-0.408539f,-0.855774f,-0.480011f,0.19281f,0.693176f,-0.079285f,0.716339f,0.226013f,0.650116f,-0.725433f,0.246704f,0.953369f,-0.173553f,
-0.970398f,-0.239227f,-0.03244f,0.136383f,-0.394318f,0.908752f,0.813232f,0.558167f,0.164368f,0.40451f,0.549042f,-0.731323f,-0.380249f,-0.566711f,0.730865f,0.022156f,0.932739f,0.359741f,0.00824f,0.996552f,-0.082306f,0.956635f,-0.065338f,-0.283722f,-0.743561f,0.008209f,0.668579f,-0.859589f,-0.509674f,0.035767f,-0.852234f,0.363678f,
-0.375977f,-0.201965f,-0.970795f,-0.12915f,0.313477f,0.947327f,0.06546f,-0.254028f,-0.528259f,0.81015f,0.628052f,0.601105f,0.49411f,-0.494385f,0.868378f,0.037933f,0.275635f,-0.086426f,0.957336f,-0.197937f,0.468903f,-0.860748f,0.895599f,0.399384f,0.195801f,0.560791f,0.825012f,-0.069214f,0.304199f,-0.849487f,0.43103f,0.096375f,
0.93576f,0.339111f,-0.051422f,0.408966f,-0.911072f,0.330444f,0.942841f,-0.042389f,-0.452362f,-0.786407f,0.420563f,0.134308f,-0.933472f,-0.332489f,0.80191f,-0.566711f,-0.188934f,-0.987946f,-0.105988f,0.112518f,-0.24408f,0.892242f,-0.379791f,-0.920502f,0.229095f,-0.316376f,0.7789f,0.325958f,0.535706f,-0.912872f,0.185211f,-0.36377f,
-0.184784f,0.565369f,-0.803833f,-0.018463f,0.119537f,0.992615f,-0.259247f,-0.935608f,0.239532f,-0.82373f,-0.449127f,-0.345947f,-0.433105f,0.659515f,0.614349f,-0.822754f,0.378845f,-0.423676f,0.687195f,-0.674835f,-0.26889f,-0.246582f,-0.800842f,0.545715f,-0.729187f,-0.207794f,0.651978f,0.653534f,-0.610443f,-0.447388f,0.492584f,-0.023346f,
0.869934f,0.609039f,0.009094f,-0.79306f,0.962494f,-0.271088f,-0.00885f,0.2659f,-0.004913f,0.963959f,0.651245f,0.553619f,-0.518951f,0.280548f,-0.84314f,0.458618f,-0.175293f,-0.983215f,0.049805f,0.035339f,-0.979919f,0.196045f,-0.982941f,0.164307f,-0.082245f,0.233734f,-0.97226f,-0.005005f,-0.747253f,-0.611328f,0.260437f,0.645599f,
0.592773f,0.481384f,0.117706f,-0.949524f,-0.29068f,-0.535004f,-0.791901f,-0.294312f,-0.627167f,-0.214447f,0.748718f,-0.047974f,-0.813477f,-0.57959f,-0.175537f,0.477264f,-0.860992f,0.738556f,-0.414246f,-0.53183f,0.562561f,-0.704071f,0.433289f,-0.754944f,0.64801f,-0.100586f,0.114716f,0.044525f,-0.992371f,0.966003f,0.244873f,-0.082764f
};

/**************************/
/*  IMPROVED PERLIN NOISE */
/**************************/

#define lerp(t, a, b) ((a)+(t)*((b)-(a)))
#define npfade(t) ((t)*(t)*(t)*((t)*((t)*6-15)+10))

static float grad(int hash, float x, float y, float z)
{
	int h = hash & 15;                     // CONVERT LO 4 BITS OF HASH CODE
	float u = h<8 ? x : y,                 // INTO 12 GRADIENT DIRECTIONS.
				v = h<4 ? y : h==12||h==14 ? x : z;
	return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v);
}

/* instead of adding another permutation array, just use hash table defined above */
float newPerlin(float x, float y, float z)
{
	int A, AA, AB, B, BA, BB;
	float u=floor(x), v=floor(y), w=floor(z);
	int X=((int)u) & 255, Y=((int)v) & 255, Z=((int)w) & 255;	// FIND UNIT CUBE THAT CONTAINS POINT
	x -= u;             // FIND RELATIVE X,Y,Z
	y -= v;             // OF POINT IN CUBE.
	z -= w;
	u = npfade(x);      // COMPUTE FADE CURVES
	v = npfade(y);      // FOR EACH OF X,Y,Z.
	w = npfade(z);
	A = hash[X  ]+Y;  AA = hash[A]+Z;  AB = hash[A+1]+Z;      // HASH COORDINATES OF
	B = hash[X+1]+Y;  BA = hash[B]+Z;  BB = hash[B+1]+Z;      // THE 8 CUBE CORNERS,
	return lerp(w, lerp(v, lerp(u, grad(hash[AA  ], x  , y  , z   ),  // AND ADD
																grad(hash[BA  ], x-1, y  , z   )), // BLENDED
												lerp(u, grad(hash[AB  ], x  , y-1, z   ),  // RESULTS
																grad(hash[BB  ], x-1, y-1, z   ))),// FROM  8
								lerp(v, lerp(u, grad(hash[AA+1], x  , y  , z-1 ),  // CORNERS
																grad(hash[BA+1], x-1, y  , z-1 )), // OF CUBE
												lerp(u, grad(hash[AB+1], x  , y-1, z-1 ),
																grad(hash[BB+1], x-1, y-1, z-1 ))));
}

/* for use with BLI_gNoise()/BLI_gTurbulence(), returns unsigned improved perlin noise */
static float newPerlinU(float x, float y, float z)
{
	return (0.5f+0.5f*newPerlin(x, y, z));
}


/**************************/
/* END OF IMPROVED PERLIN */
/**************************/

/* Was BLI_hnoise(), removed noisesize, so other functions can call it without scaling. */
static float orgBlenderNoise(float x, float y, float z)
{
	register float cn1, cn2, cn3, cn4, cn5, cn6, i, *h;
	float ox, oy, oz, jx, jy, jz;
	float n= 0.5f;
	int ix, iy, iz, b00, b01, b10, b11, b20, b21;

	ox= (x- (ix= (int)floor(x)) );
	oy= (y- (iy= (int)floor(y)) );
	oz= (z- (iz= (int)floor(z)) );

	jx= ox-1;
	jy= oy-1;
	jz= oz-1;

	cn1=ox*ox; cn2=oy*oy; cn3=oz*oz;
	cn4=jx*jx; cn5=jy*jy; cn6=jz*jz;

	cn1= 1.f-3.f*cn1+2.f*cn1*ox;
	cn2= 1.f-3.f*cn2+2.f*cn2*oy;
	cn3= 1.f-3.f*cn3+2.f*cn3*oz;
	cn4= 1.f-3.f*cn4-2.f*cn4*jx;
	cn5= 1.f-3.f*cn5-2.f*cn5*jy;
	cn6= 1.f-3.f*cn6-2.f*cn6*jz;

	b00= hash[ hash[ix & 255]+(iy & 255)];
	b10= hash[ hash[(ix+1) & 255]+(iy & 255)];
	b01= hash[ hash[ix & 255]+((iy+1) & 255)];
	b11= hash[ hash[(ix+1) & 255]+((iy+1) & 255)];

	b20=iz & 255; b21= (iz+1) & 255;

		/* 0 */
	i= (cn1*cn2*cn3);
		h=hashvectf+ 3*hash[b20+b00];
		n+= i*(h[0]*ox+h[1]*oy+h[2]*oz);
		/* 1 */
	i= (cn1*cn2*cn6);
		h=hashvectf+ 3*hash[b21+b00];
		n+= i*(h[0]*ox+h[1]*oy+h[2]*jz);
		/* 2 */
	i= (cn1*cn5*cn3);
		h=hashvectf+ 3*hash[b20+b01];
		n+= i*(h[0]*ox+h[1]*jy+h[2]*oz);
		/* 3 */
	i= (cn1*cn5*cn6);
		h=hashvectf+ 3*hash[b21+b01];
		n+= i*(h[0]*ox+h[1]*jy+h[2]*jz);
		/* 4 */
	i= cn4*cn2*cn3;
		h=hashvectf+ 3*hash[b20+b10];
		n+= i*(h[0]*jx+h[1]*oy+h[2]*oz);
		/* 5 */
	i= cn4*cn2*cn6;
		h=hashvectf+ 3*hash[b21+b10];
		n+= i*(h[0]*jx+h[1]*oy+h[2]*jz);
		/* 6 */
	i= cn4*cn5*cn3;
		h=hashvectf+ 3*hash[b20+b11];
		n+=  i*(h[0]*jx+h[1]*jy+h[2]*oz);
		/* 7 */
	i= (cn4*cn5*cn6);
		h=hashvectf+ 3*hash[b21+b11];
		n+= i*(h[0]*jx+h[1]*jy+h[2]*jz);

	if(n<0.f) n=0.f; else if(n>1.f) n=1.f;
	return n;
}

/* as orgBlenderNoise(), returning signed noise */
static float orgBlenderNoiseS(float x, float y, float z)
{
	return (2.f*orgBlenderNoise(x, y, z)-1.f);
}

/* separated from orgBlenderNoise above, with scaling */
float BLI_hnoise(float noisesize, float x, float y, float z)
{
	if(noisesize==0.f) return 0.f;
	x= (1.f+x)/noisesize;
	y= (1.f+y)/noisesize;
	z= (1.f+z)/noisesize;
	return orgBlenderNoise(x, y, z);
}


/* original turbulence functions */
float BLI_turbulence(float noisesize, float x, float y, float z, int nr)
{
	float s, d= 0.5f, div=1.f;

	s= BLI_hnoise(noisesize, x, y, z);
	
	while(nr > 0) {
	
		s+= d*BLI_hnoise(noisesize*d, x, y, z);
		div+= d;
		d*= 0.5f;

		nr--;
	}
	return s/div;
}

float BLI_turbulence1(float noisesize, float x, float y, float z, int nr)
{
	float s, d= 0.5f, div=1.f;

	s= fabs( (-1.f+2.f*BLI_hnoise(noisesize, x, y, z)));
	
	while(nr > 0) {
	
		s+= fabs(d* (-1.f+2.f*BLI_hnoise(noisesize*d, x, y, z)));
		div+= d;
		d*= 0.5f;
		
		nr--;
	}
	return s/div;
}

/* ********************* FROM PERLIN HIMSELF: ******************** */

static unsigned char p[512+2]= {
0xA2,0xA0,0x19,0x3B,0xF8,0xEB,0xAA,0xEE,0xF3,0x1C,0x67,0x28,0x1D,0xED,0x0,0xDE,0x95,0x2E,0xDC,0x3F,0x3A,0x82,0x35,0x4D,0x6C,0xBA,0x36,0xD0,0xF6,0xC,0x79,0x32,0xD1,0x59,0xF4,0x8,0x8B,0x63,0x89,0x2F,0xB8,0xB4,0x97,0x83,0xF2,0x8F,0x18,0xC7,0x51,0x14,0x65,0x87,0x48,0x20,0x42,0xA8,0x80,0xB5,0x40,0x13,0xB2,0x22,0x7E,0x57,
0xBC,0x7F,0x6B,0x9D,0x86,0x4C,0xC8,0xDB,0x7C,0xD5,0x25,0x4E,0x5A,0x55,0x74,0x50,0xCD,0xB3,0x7A,0xBB,0xC3,0xCB,0xB6,0xE2,0xE4,0xEC,0xFD,0x98,0xB,0x96,0xD3,0x9E,0x5C,0xA1,0x64,0xF1,0x81,0x61,0xE1,0xC4,0x24,0x72,0x49,0x8C,0x90,0x4B,0x84,0x34,0x38,0xAB,0x78,0xCA,0x1F,0x1,0xD7,0x93,0x11,0xC1,0x58,0xA9,0x31,0xF9,0x44,0x6D,
0xBF,0x33,0x9C,0x5F,0x9,0x94,0xA3,0x85,0x6,0xC6,0x9A,0x1E,0x7B,0x46,0x15,0x30,0x27,0x2B,0x1B,0x71,0x3C,0x5B,0xD6,0x6F,0x62,0xAC,0x4F,0xC2,0xC0,0xE,0xB1,0x23,0xA7,0xDF,0x47,0xB0,0x77,0x69,0x5,0xE9,0xE6,0xE7,0x76,0x73,0xF,0xFE,0x6E,0x9B,0x56,0xEF,0x12,0xA5,0x37,0xFC,0xAE,0xD9,0x3,0x8E,0xDD,0x10,0xB9,0xCE,0xC9,0x8D,
0xDA,0x2A,0xBD,0x68,0x17,0x9F,0xBE,0xD4,0xA,0xCC,0xD2,0xE8,0x43,0x3D,0x70,0xB7,0x2,0x7D,0x99,0xD8,0xD,0x60,0x8A,0x4,0x2C,0x3E,0x92,0xE5,0xAF,0x53,0x7,0xE0,0x29,0xA6,0xC5,0xE3,0xF5,0xF7,0x4A,0x41,0x26,0x6A,0x16,0x5E,0x52,0x2D,0x21,0xAD,0xF0,0x91,0xFF,0xEA,0x54,0xFA,0x66,0x1A,0x45,0x39,0xCF,0x75,0xA4,0x88,0xFB,0x5D,
0xA2,0xA0,0x19,0x3B,0xF8,0xEB,0xAA,0xEE,0xF3,0x1C,0x67,0x28,0x1D,0xED,0x0,0xDE,0x95,0x2E,0xDC,0x3F,0x3A,0x82,0x35,0x4D,0x6C,0xBA,0x36,0xD0,0xF6,0xC,0x79,0x32,0xD1,0x59,0xF4,0x8,0x8B,0x63,0x89,0x2F,0xB8,0xB4,0x97,0x83,0xF2,0x8F,0x18,0xC7,0x51,0x14,0x65,0x87,0x48,0x20,0x42,0xA8,0x80,0xB5,0x40,0x13,0xB2,0x22,0x7E,0x57,
0xBC,0x7F,0x6B,0x9D,0x86,0x4C,0xC8,0xDB,0x7C,0xD5,0x25,0x4E,0x5A,0x55,0x74,0x50,0xCD,0xB3,0x7A,0xBB,0xC3,0xCB,0xB6,0xE2,0xE4,0xEC,0xFD,0x98,0xB,0x96,0xD3,0x9E,0x5C,0xA1,0x64,0xF1,0x81,0x61,0xE1,0xC4,0x24,0x72,0x49,0x8C,0x90,0x4B,0x84,0x34,0x38,0xAB,0x78,0xCA,0x1F,0x1,0xD7,0x93,0x11,0xC1,0x58,0xA9,0x31,0xF9,0x44,0x6D,
0xBF,0x33,0x9C,0x5F,0x9,0x94,0xA3,0x85,0x6,0xC6,0x9A,0x1E,0x7B,0x46,0x15,0x30,0x27,0x2B,0x1B,0x71,0x3C,0x5B,0xD6,0x6F,0x62,0xAC,0x4F,0xC2,0xC0,0xE,0xB1,0x23,0xA7,0xDF,0x47,0xB0,0x77,0x69,0x5,0xE9,0xE6,0xE7,0x76,0x73,0xF,0xFE,0x6E,0x9B,0x56,0xEF,0x12,0xA5,0x37,0xFC,0xAE,0xD9,0x3,0x8E,0xDD,0x10,0xB9,0xCE,0xC9,0x8D,
0xDA,0x2A,0xBD,0x68,0x17,0x9F,0xBE,0xD4,0xA,0xCC,0xD2,0xE8,0x43,0x3D,0x70,0xB7,0x2,0x7D,0x99,0xD8,0xD,0x60,0x8A,0x4,0x2C,0x3E,0x92,0xE5,0xAF,0x53,0x7,0xE0,0x29,0xA6,0xC5,0xE3,0xF5,0xF7,0x4A,0x41,0x26,0x6A,0x16,0x5E,0x52,0x2D,0x21,0xAD,0xF0,0x91,0xFF,0xEA,0x54,0xFA,0x66,0x1A,0x45,0x39,0xCF,0x75,0xA4,0x88,0xFB,0x5D,
0xA2,0xA0};


float g[512+2][3]= {
	{0.33783f, 0.715698f, -0.611206f},
	{-0.944031f, -0.326599f, -0.045624f},
	{-0.101074f, -0.416443f, -0.903503f},
	{0.799286f, 0.49411f, -0.341949f},
	{-0.854645f, 0.518036f, 0.033936f},
	{0.42514f, -0.437866f, -0.792114f},
	{-0.358948f, 0.597046f, 0.717377f},
	{-0.985413f, 0.144714f, 0.089294f},
	{-0.601776f, -0.33728f, -0.723907f},
	{-0.449921f, 0.594513f, 0.666382f},
	{0.208313f, -0.10791f, 0.972076f},
	{0.575317f, 0.060425f, 0.815643f},
	{0.293365f, -0.875702f, -0.383453f},
	{0.293762f, 0.465759f, 0.834686f},
	{-0.846008f, -0.233398f, -0.47934f},
	{-0.115814f, 0.143036f, -0.98291f},
	{0.204681f, -0.949036f, -0.239532f},
	{0.946716f, -0.263947f, 0.184326f},
	{-0.235596f, 0.573822f, 0.784332f},
	{0.203705f, -0.372253f, -0.905487f},
	{0.756989f, -0.651031f, 0.055298f},
	{0.497803f, 0.814697f, -0.297363f},
	{-0.16214f, 0.063995f, -0.98468f},
	{-0.329254f, 0.834381f, 0.441925f},
	{0.703827f, -0.527039f, -0.476227f},
	{0.956421f, 0.266113f, 0.119781f},
	{0.480133f, 0.482849f, 0.7323f},
	{-0.18631f, 0.961212f, -0.203125f},
	{-0.748474f, -0.656921f, -0.090393f},
	{-0.085052f, -0.165253f, 0.982544f},
	{-0.76947f, 0.628174f, -0.115234f},
	{0.383148f, 0.537659f, 0.751068f},
	{0.616486f, -0.668488f, -0.415924f},
	{-0.259979f, -0.630005f, 0.73175f},
	{0.570953f, -0.087952f, 0.816223f},
	{-0.458008f, 0.023254f, 0.888611f},
	{-0.196167f, 0.976563f, -0.088287f},
	{-0.263885f, -0.69812f, -0.665527f},
	{0.437134f, -0.892273f, -0.112793f},
	{-0.621674f, -0.230438f, 0.748566f},
	{0.232422f, 0.900574f, -0.367249f},
	{0.22229f, -0.796143f, 0.562744f},
	{-0.665497f, -0.73764f, 0.11377f},
	{0.670135f, 0.704803f, 0.232605f},
	{0.895599f, 0.429749f, -0.114655f},
	{-0.11557f, -0.474243f, 0.872742f},
	{0.621826f, 0.604004f, -0.498444f},
	{-0.832214f, 0.012756f, 0.55426f},
	{-0.702484f, 0.705994f, -0.089661f},
	{-0.692017f, 0.649292f, 0.315399f},
	{-0.175995f, -0.977997f, 0.111877f},
	{0.096954f, -0.04953f, 0.994019f},
	{0.635284f, -0.606689f, -0.477783f},
	{-0.261261f, -0.607422f, -0.750153f},
	{0.983276f, 0.165436f, 0.075958f},
	{-0.29837f, 0.404083f, -0.864655f},
	{-0.638672f, 0.507721f, 0.578156f},
	{0.388214f, 0.412079f, 0.824249f},
	{0.556183f, -0.208832f, 0.804352f},
	{0.778442f, 0.562012f, 0.27951f},
	{-0.616577f, 0.781921f, -0.091522f},
	{0.196289f, 0.051056f, 0.979187f},
	{-0.121216f, 0.207153f, -0.970734f},
	{-0.173401f, -0.384735f, 0.906555f},
	{0.161499f, -0.723236f, -0.671387f},
	{0.178497f, -0.006226f, -0.983887f},
	{-0.126038f, 0.15799f, 0.97934f},
	{0.830475f, -0.024811f, 0.556458f},
	{-0.510132f, -0.76944f, 0.384247f},
	{0.81424f, 0.200104f, -0.544891f},
	{-0.112549f, -0.393311f, -0.912445f},
	{0.56189f, 0.152222f, -0.813049f},
	{0.198914f, -0.254517f, -0.946381f},
	{-0.41217f, 0.690979f, -0.593811f},
	{-0.407257f, 0.324524f, 0.853668f},
	{-0.690186f, 0.366119f, -0.624115f},
	{-0.428345f, 0.844147f, -0.322296f},
	{-0.21228f, -0.297546f, -0.930756f},
	{-0.273071f, 0.516113f, 0.811798f},
	{0.928314f, 0.371643f, 0.007233f},
	{0.785828f, -0.479218f, -0.390778f},
	{-0.704895f, 0.058929f, 0.706818f},
	{0.173248f, 0.203583f, 0.963562f},
	{0.422211f, -0.904297f, -0.062469f},
	{-0.363312f, -0.182465f, 0.913605f},
	{0.254028f, -0.552307f, -0.793945f},
	{-0.28891f, -0.765747f, -0.574554f},
	{0.058319f, 0.291382f, 0.954803f},
	{0.946136f, -0.303925f, 0.111267f},
	{-0.078156f, 0.443695f, -0.892731f},
	{0.182098f, 0.89389f, 0.409515f},
	{-0.680298f, -0.213318f, 0.701141f},
	{0.062469f, 0.848389f, -0.525635f},
	{-0.72879f, -0.641846f, 0.238342f},
	{-0.88089f, 0.427673f, 0.202637f},
	{-0.532501f, -0.21405f, 0.818878f},
	{0.948975f, -0.305084f, 0.07962f},
	{0.925446f, 0.374664f, 0.055817f},
	{0.820923f, 0.565491f, 0.079102f},
	{0.25882f, 0.099792f, -0.960724f},
	{-0.294617f, 0.910522f, 0.289978f},
	{0.137115f, 0.320038f, -0.937408f},
	{-0.908386f, 0.345276f, -0.235718f},
	{-0.936218f, 0.138763f, 0.322754f},
	{0.366577f, 0.925934f, -0.090637f},
	{0.309296f, -0.686829f, -0.657684f},
	{0.66983f, 0.024445f, 0.742065f},
	{-0.917999f, -0.059113f, -0.392059f},
	{0.365509f, 0.462158f, -0.807922f},
	{0.083374f, 0.996399f, -0.014801f},
	{0.593842f, 0.253143f, -0.763672f},
	{0.974976f, -0.165466f, 0.148285f},
	{0.918976f, 0.137299f, 0.369537f},
	{0.294952f, 0.694977f, 0.655731f},
	{0.943085f, 0.152618f, -0.295319f},
	{0.58783f, -0.598236f, 0.544495f},
	{0.203796f, 0.678223f, 0.705994f},
	{-0.478821f, -0.661011f, 0.577667f},
	{0.719055f, -0.1698f, -0.673828f},
	{-0.132172f, -0.965332f, 0.225006f},
	{-0.981873f, -0.14502f, 0.121979f},
	{0.763458f, 0.579742f, 0.284546f},
	{-0.893188f, 0.079681f, 0.442474f},
	{-0.795776f, -0.523804f, 0.303802f},
	{0.734955f, 0.67804f, -0.007446f},
	{0.15506f, 0.986267f, -0.056183f},
	{0.258026f, 0.571503f, -0.778931f},
	{-0.681549f, -0.702087f, -0.206116f},
	{-0.96286f, -0.177185f, 0.203613f},
	{-0.470978f, -0.515106f, 0.716095f},
	{-0.740326f, 0.57135f, 0.354095f},
	{-0.56012f, -0.824982f, -0.074982f},
	{-0.507874f, 0.753204f, 0.417969f},
	{-0.503113f, 0.038147f, 0.863342f},
	{0.594025f, 0.673553f, -0.439758f},
	{-0.119873f, -0.005524f, -0.992737f},
	{0.098267f, -0.213776f, 0.971893f},
	{-0.615631f, 0.643951f, 0.454163f},
	{0.896851f, -0.441071f, 0.032166f},
	{-0.555023f, 0.750763f, -0.358093f},
	{0.398773f, 0.304688f, 0.864929f},
	{-0.722961f, 0.303589f, 0.620544f},
	{-0.63559f, -0.621948f, -0.457306f},
	{-0.293243f, 0.072327f, 0.953278f},
	{-0.491638f, 0.661041f, -0.566772f},
	{-0.304199f, -0.572083f, -0.761688f},
	{0.908081f, -0.398956f, 0.127014f},
	{-0.523621f, -0.549683f, -0.650848f},
	{-0.932922f, -0.19986f, 0.299408f},
	{0.099426f, 0.140869f, 0.984985f},
	{-0.020325f, -0.999756f, -0.002319f},
	{0.952667f, 0.280853f, -0.11615f},
	{-0.971893f, 0.082581f, 0.220337f},
	{0.65921f, 0.705292f, -0.260651f},
	{0.733063f, -0.175537f, 0.657043f},
	{-0.555206f, 0.429504f, -0.712189f},
	{0.400421f, -0.89859f, 0.179352f},
	{0.750885f, -0.19696f, 0.630341f},
	{0.785675f, -0.569336f, 0.241821f},
	{-0.058899f, -0.464111f, 0.883789f},
	{0.129608f, -0.94519f, 0.299622f},
	{-0.357819f, 0.907654f, 0.219238f},
	{-0.842133f, -0.439117f, -0.312927f},
	{-0.313477f, 0.84433f, 0.434479f},
	{-0.241211f, 0.053253f, 0.968994f},
	{0.063873f, 0.823273f, 0.563965f},
	{0.476288f, 0.862152f, -0.172516f},
	{0.620941f, -0.298126f, 0.724915f},
	{0.25238f, -0.749359f, -0.612122f},
	{-0.577545f, 0.386566f, 0.718994f},
	{-0.406342f, -0.737976f, 0.538696f},
	{0.04718f, 0.556305f, 0.82959f},
	{-0.802856f, 0.587463f, 0.101166f},
	{-0.707733f, -0.705963f, 0.026428f},
	{0.374908f, 0.68457f, 0.625092f},
	{0.472137f, 0.208405f, -0.856506f},
	{-0.703064f, -0.581085f, -0.409821f},
	{-0.417206f, -0.736328f, 0.532623f},
	{-0.447876f, -0.20285f, -0.870728f},
	{0.086945f, -0.990417f, 0.107086f},
	{0.183685f, 0.018341f, -0.982788f},
	{0.560638f, -0.428864f, 0.708282f},
	{0.296722f, -0.952576f, -0.0672f},
	{0.135773f, 0.990265f, 0.030243f},
	{-0.068787f, 0.654724f, 0.752686f},
	{0.762604f, -0.551758f, 0.337585f},
	{-0.819611f, -0.407684f, 0.402466f},
	{-0.727844f, -0.55072f, -0.408539f},
	{-0.855774f, -0.480011f, 0.19281f},
	{0.693176f, -0.079285f, 0.716339f},
	{0.226013f, 0.650116f, -0.725433f},
	{0.246704f, 0.953369f, -0.173553f},
	{-0.970398f, -0.239227f, -0.03244f},
	{0.136383f, -0.394318f, 0.908752f},
	{0.813232f, 0.558167f, 0.164368f},
	{0.40451f, 0.549042f, -0.731323f},
	{-0.380249f, -0.566711f, 0.730865f},
	{0.022156f, 0.932739f, 0.359741f},
	{0.00824f, 0.996552f, -0.082306f},
	{0.956635f, -0.065338f, -0.283722f},
	{-0.743561f, 0.008209f, 0.668579f},
	{-0.859589f, -0.509674f, 0.035767f},
	{-0.852234f, 0.363678f, -0.375977f},
	{-0.201965f, -0.970795f, -0.12915f},
	{0.313477f, 0.947327f, 0.06546f},
	{-0.254028f, -0.528259f, 0.81015f},
	{0.628052f, 0.601105f, 0.49411f},
	{-0.494385f, 0.868378f, 0.037933f},
	{0.275635f, -0.086426f, 0.957336f},
	{-0.197937f, 0.468903f, -0.860748f},
	{0.895599f, 0.399384f, 0.195801f},
	{0.560791f, 0.825012f, -0.069214f},
	{0.304199f, -0.849487f, 0.43103f},
	{0.096375f, 0.93576f, 0.339111f},
	{-0.051422f, 0.408966f, -0.911072f},
	{0.330444f, 0.942841f, -0.042389f},
	{-0.452362f, -0.786407f, 0.420563f},
	{0.134308f, -0.933472f, -0.332489f},
	{0.80191f, -0.566711f, -0.188934f},
	{-0.987946f, -0.105988f, 0.112518f},
	{-0.24408f, 0.892242f, -0.379791f},
	{-0.920502f, 0.229095f, -0.316376f},
	{0.7789f, 0.325958f, 0.535706f},
	{-0.912872f, 0.185211f, -0.36377f},
	{-0.184784f, 0.565369f, -0.803833f},
	{-0.018463f, 0.119537f, 0.992615f},
	{-0.259247f, -0.935608f, 0.239532f},
	{-0.82373f, -0.449127f, -0.345947f},
	{-0.433105f, 0.659515f, 0.614349f},
	{-0.822754f, 0.378845f, -0.423676f},
	{0.687195f, -0.674835f, -0.26889f},
	{-0.246582f, -0.800842f, 0.545715f},
	{-0.729187f, -0.207794f, 0.651978f},
	{0.653534f, -0.610443f, -0.447388f},
	{0.492584f, -0.023346f, 0.869934f},
	{0.609039f, 0.009094f, -0.79306f},
	{0.962494f, -0.271088f, -0.00885f},
	{0.2659f, -0.004913f, 0.963959f},
	{0.651245f, 0.553619f, -0.518951f},
	{0.280548f, -0.84314f, 0.458618f},
	{-0.175293f, -0.983215f, 0.049805f},
	{0.035339f, -0.979919f, 0.196045f},
	{-0.982941f, 0.164307f, -0.082245f},
	{0.233734f, -0.97226f, -0.005005f},
	{-0.747253f, -0.611328f, 0.260437f},
	{0.645599f, 0.592773f, 0.481384f},
	{0.117706f, -0.949524f, -0.29068f},
	{-0.535004f, -0.791901f, -0.294312f},
	{-0.627167f, -0.214447f, 0.748718f},
	{-0.047974f, -0.813477f, -0.57959f},
	{-0.175537f, 0.477264f, -0.860992f},
	{0.738556f, -0.414246f, -0.53183f},
	{0.562561f, -0.704071f, 0.433289f},
	{-0.754944f, 0.64801f, -0.100586f},
	{0.114716f, 0.044525f, -0.992371f},
	{0.966003f, 0.244873f, -0.082764f},
	{0.33783f, 0.715698f, -0.611206f},
	{-0.944031f, -0.326599f, -0.045624f},
	{-0.101074f, -0.416443f, -0.903503f},
	{0.799286f, 0.49411f, -0.341949f},
	{-0.854645f, 0.518036f, 0.033936f},
	{0.42514f, -0.437866f, -0.792114f},
	{-0.358948f, 0.597046f, 0.717377f},
	{-0.985413f, 0.144714f, 0.089294f},
	{-0.601776f, -0.33728f, -0.723907f},
	{-0.449921f, 0.594513f, 0.666382f},
	{0.208313f, -0.10791f, 0.972076f},
	{0.575317f, 0.060425f, 0.815643f},
	{0.293365f, -0.875702f, -0.383453f},
	{0.293762f, 0.465759f, 0.834686f},
	{-0.846008f, -0.233398f, -0.47934f},
	{-0.115814f, 0.143036f, -0.98291f},
	{0.204681f, -0.949036f, -0.239532f},
	{0.946716f, -0.263947f, 0.184326f},
	{-0.235596f, 0.573822f, 0.784332f},
	{0.203705f, -0.372253f, -0.905487f},
	{0.756989f, -0.651031f, 0.055298f},
	{0.497803f, 0.814697f, -0.297363f},
	{-0.16214f, 0.063995f, -0.98468f},
	{-0.329254f, 0.834381f, 0.441925f},
	{0.703827f, -0.527039f, -0.476227f},
	{0.956421f, 0.266113f, 0.119781f},
	{0.480133f, 0.482849f, 0.7323f},
	{-0.18631f, 0.961212f, -0.203125f},
	{-0.748474f, -0.656921f, -0.090393f},
	{-0.085052f, -0.165253f, 0.982544f},
	{-0.76947f, 0.628174f, -0.115234f},
	{0.383148f, 0.537659f, 0.751068f},
	{0.616486f, -0.668488f, -0.415924f},
	{-0.259979f, -0.630005f, 0.73175f},
	{0.570953f, -0.087952f, 0.816223f},
	{-0.458008f, 0.023254f, 0.888611f},
	{-0.196167f, 0.976563f, -0.088287f},
	{-0.263885f, -0.69812f, -0.665527f},
	{0.437134f, -0.892273f, -0.112793f},
	{-0.621674f, -0.230438f, 0.748566f},
	{0.232422f, 0.900574f, -0.367249f},
	{0.22229f, -0.796143f, 0.562744f},
	{-0.665497f, -0.73764f, 0.11377f},
	{0.670135f, 0.704803f, 0.232605f},
	{0.895599f, 0.429749f, -0.114655f},
	{-0.11557f, -0.474243f, 0.872742f},
	{0.621826f, 0.604004f, -0.498444f},
	{-0.832214f, 0.012756f, 0.55426f},
	{-0.702484f, 0.705994f, -0.089661f},
	{-0.692017f, 0.649292f, 0.315399f},
	{-0.175995f, -0.977997f, 0.111877f},
	{0.096954f, -0.04953f, 0.994019f},
	{0.635284f, -0.606689f, -0.477783f},
	{-0.261261f, -0.607422f, -0.750153f},
	{0.983276f, 0.165436f, 0.075958f},
	{-0.29837f, 0.404083f, -0.864655f},
	{-0.638672f, 0.507721f, 0.578156f},
	{0.388214f, 0.412079f, 0.824249f},
	{0.556183f, -0.208832f, 0.804352f},
	{0.778442f, 0.562012f, 0.27951f},
	{-0.616577f, 0.781921f, -0.091522f},
	{0.196289f, 0.051056f, 0.979187f},
	{-0.121216f, 0.207153f, -0.970734f},
	{-0.173401f, -0.384735f, 0.906555f},
	{0.161499f, -0.723236f, -0.671387f},
	{0.178497f, -0.006226f, -0.983887f},
	{-0.126038f, 0.15799f, 0.97934f},
	{0.830475f, -0.024811f, 0.556458f},
	{-0.510132f, -0.76944f, 0.384247f},
	{0.81424f, 0.200104f, -0.544891f},
	{-0.112549f, -0.393311f, -0.912445f},
	{0.56189f, 0.152222f, -0.813049f},
	{0.198914f, -0.254517f, -0.946381f},
	{-0.41217f, 0.690979f, -0.593811f},
	{-0.407257f, 0.324524f, 0.853668f},
	{-0.690186f, 0.366119f, -0.624115f},
	{-0.428345f, 0.844147f, -0.322296f},
	{-0.21228f, -0.297546f, -0.930756f},
	{-0.273071f, 0.516113f, 0.811798f},
	{0.928314f, 0.371643f, 0.007233f},
	{0.785828f, -0.479218f, -0.390778f},
	{-0.704895f, 0.058929f, 0.706818f},
	{0.173248f, 0.203583f, 0.963562f},
	{0.422211f, -0.904297f, -0.062469f},
	{-0.363312f, -0.182465f, 0.913605f},
	{0.254028f, -0.552307f, -0.793945f},
	{-0.28891f, -0.765747f, -0.574554f},
	{0.058319f, 0.291382f, 0.954803f},
	{0.946136f, -0.303925f, 0.111267f},
	{-0.078156f, 0.443695f, -0.892731f},
	{0.182098f, 0.89389f, 0.409515f},
	{-0.680298f, -0.213318f, 0.701141f},
	{0.062469f, 0.848389f, -0.525635f},
	{-0.72879f, -0.641846f, 0.238342f},
	{-0.88089f, 0.427673f, 0.202637f},
	{-0.532501f, -0.21405f, 0.818878f},
	{0.948975f, -0.305084f, 0.07962f},
	{0.925446f, 0.374664f, 0.055817f},
	{0.820923f, 0.565491f, 0.079102f},
	{0.25882f, 0.099792f, -0.960724f},
	{-0.294617f, 0.910522f, 0.289978f},
	{0.137115f, 0.320038f, -0.937408f},
	{-0.908386f, 0.345276f, -0.235718f},
	{-0.936218f, 0.138763f, 0.322754f},
	{0.366577f, 0.925934f, -0.090637f},
	{0.309296f, -0.686829f, -0.657684f},
	{0.66983f, 0.024445f, 0.742065f},
	{-0.917999f, -0.059113f, -0.392059f},
	{0.365509f, 0.462158f, -0.807922f},
	{0.083374f, 0.996399f, -0.014801f},
	{0.593842f, 0.253143f, -0.763672f},
	{0.974976f, -0.165466f, 0.148285f},
	{0.918976f, 0.137299f, 0.369537f},
	{0.294952f, 0.694977f, 0.655731f},
	{0.943085f, 0.152618f, -0.295319f},
	{0.58783f, -0.598236f, 0.544495f},
	{0.203796f, 0.678223f, 0.705994f},
	{-0.478821f, -0.661011f, 0.577667f},
	{0.719055f, -0.1698f, -0.673828f},
	{-0.132172f, -0.965332f, 0.225006f},
	{-0.981873f, -0.14502f, 0.121979f},
	{0.763458f, 0.579742f, 0.284546f},
	{-0.893188f, 0.079681f, 0.442474f},
	{-0.795776f, -0.523804f, 0.303802f},
	{0.734955f, 0.67804f, -0.007446f},
	{0.15506f, 0.986267f, -0.056183f},
	{0.258026f, 0.571503f, -0.778931f},
	{-0.681549f, -0.702087f, -0.206116f},
	{-0.96286f, -0.177185f, 0.203613f},
	{-0.470978f, -0.515106f, 0.716095f},
	{-0.740326f, 0.57135f, 0.354095f},
	{-0.56012f, -0.824982f, -0.074982f},
	{-0.507874f, 0.753204f, 0.417969f},
	{-0.503113f, 0.038147f, 0.863342f},
	{0.594025f, 0.673553f, -0.439758f},
	{-0.119873f, -0.005524f, -0.992737f},
	{0.098267f, -0.213776f, 0.971893f},
	{-0.615631f, 0.643951f, 0.454163f},
	{0.896851f, -0.441071f, 0.032166f},
	{-0.555023f, 0.750763f, -0.358093f},
	{0.398773f, 0.304688f, 0.864929f},
	{-0.722961f, 0.303589f, 0.620544f},
	{-0.63559f, -0.621948f, -0.457306f},
	{-0.293243f, 0.072327f, 0.953278f},
	{-0.491638f, 0.661041f, -0.566772f},
	{-0.304199f, -0.572083f, -0.761688f},
	{0.908081f, -0.398956f, 0.127014f},
	{-0.523621f, -0.549683f, -0.650848f},
	{-0.932922f, -0.19986f, 0.299408f},
	{0.099426f, 0.140869f, 0.984985f},
	{-0.020325f, -0.999756f, -0.002319f},
	{0.952667f, 0.280853f, -0.11615f},
	{-0.971893f, 0.082581f, 0.220337f},
	{0.65921f, 0.705292f, -0.260651f},
	{0.733063f, -0.175537f, 0.657043f},
	{-0.555206f, 0.429504f, -0.712189f},
	{0.400421f, -0.89859f, 0.179352f},
	{0.750885f, -0.19696f, 0.630341f},
	{0.785675f, -0.569336f, 0.241821f},
	{-0.058899f, -0.464111f, 0.883789f},
	{0.129608f, -0.94519f, 0.299622f},
	{-0.357819f, 0.907654f, 0.219238f},
	{-0.842133f, -0.439117f, -0.312927f},
	{-0.313477f, 0.84433f, 0.434479f},
	{-0.241211f, 0.053253f, 0.968994f},
	{0.063873f, 0.823273f, 0.563965f},
	{0.476288f, 0.862152f, -0.172516f},
	{0.620941f, -0.298126f, 0.724915f},
	{0.25238f, -0.749359f, -0.612122f},
	{-0.577545f, 0.386566f, 0.718994f},
	{-0.406342f, -0.737976f, 0.538696f},
	{0.04718f, 0.556305f, 0.82959f},
	{-0.802856f, 0.587463f, 0.101166f},
	{-0.707733f, -0.705963f, 0.026428f},
	{0.374908f, 0.68457f, 0.625092f},
	{0.472137f, 0.208405f, -0.856506f},
	{-0.703064f, -0.581085f, -0.409821f},
	{-0.417206f, -0.736328f, 0.532623f},
	{-0.447876f, -0.20285f, -0.870728f},
	{0.086945f, -0.990417f, 0.107086f},
	{0.183685f, 0.018341f, -0.982788f},
	{0.560638f, -0.428864f, 0.708282f},
	{0.296722f, -0.952576f, -0.0672f},
	{0.135773f, 0.990265f, 0.030243f},
	{-0.068787f, 0.654724f, 0.752686f},
	{0.762604f, -0.551758f, 0.337585f},
	{-0.819611f, -0.407684f, 0.402466f},
	{-0.727844f, -0.55072f, -0.408539f},
	{-0.855774f, -0.480011f, 0.19281f},
	{0.693176f, -0.079285f, 0.716339f},
	{0.226013f, 0.650116f, -0.725433f},
	{0.246704f, 0.953369f, -0.173553f},
	{-0.970398f, -0.239227f, -0.03244f},
	{0.136383f, -0.394318f, 0.908752f},
	{0.813232f, 0.558167f, 0.164368f},
	{0.40451f, 0.549042f, -0.731323f},
	{-0.380249f, -0.566711f, 0.730865f},
	{0.022156f, 0.932739f, 0.359741f},
	{0.00824f, 0.996552f, -0.082306f},
	{0.956635f, -0.065338f, -0.283722f},
	{-0.743561f, 0.008209f, 0.668579f},
	{-0.859589f, -0.509674f, 0.035767f},
	{-0.852234f, 0.363678f, -0.375977f},
	{-0.201965f, -0.970795f, -0.12915f},
	{0.313477f, 0.947327f, 0.06546f},
	{-0.254028f, -0.528259f, 0.81015f},
	{0.628052f, 0.601105f, 0.49411f},
	{-0.494385f, 0.868378f, 0.037933f},
	{0.275635f, -0.086426f, 0.957336f},
	{-0.197937f, 0.468903f, -0.860748f},
	{0.895599f, 0.399384f, 0.195801f},
	{0.560791f, 0.825012f, -0.069214f},
	{0.304199f, -0.849487f, 0.43103f},
	{0.096375f, 0.93576f, 0.339111f},
	{-0.051422f, 0.408966f, -0.911072f},
	{0.330444f, 0.942841f, -0.042389f},
	{-0.452362f, -0.786407f, 0.420563f},
	{0.134308f, -0.933472f, -0.332489f},
	{0.80191f, -0.566711f, -0.188934f},
	{-0.987946f, -0.105988f, 0.112518f},
	{-0.24408f, 0.892242f, -0.379791f},
	{-0.920502f, 0.229095f, -0.316376f},
	{0.7789f, 0.325958f, 0.535706f},
	{-0.912872f, 0.185211f, -0.36377f},
	{-0.184784f, 0.565369f, -0.803833f},
	{-0.018463f, 0.119537f, 0.992615f},
	{-0.259247f, -0.935608f, 0.239532f},
	{-0.82373f, -0.449127f, -0.345947f},
	{-0.433105f, 0.659515f, 0.614349f},
	{-0.822754f, 0.378845f, -0.423676f},
	{0.687195f, -0.674835f, -0.26889f},
	{-0.246582f, -0.800842f, 0.545715f},
	{-0.729187f, -0.207794f, 0.651978f},
	{0.653534f, -0.610443f, -0.447388f},
	{0.492584f, -0.023346f, 0.869934f},
	{0.609039f, 0.009094f, -0.79306f},
	{0.962494f, -0.271088f, -0.00885f},
	{0.2659f, -0.004913f, 0.963959f},
	{0.651245f, 0.553619f, -0.518951f},
	{0.280548f, -0.84314f, 0.458618f},
	{-0.175293f, -0.983215f, 0.049805f},
	{0.035339f, -0.979919f, 0.196045f},
	{-0.982941f, 0.164307f, -0.082245f},
	{0.233734f, -0.97226f, -0.005005f},
	{-0.747253f, -0.611328f, 0.260437f},
	{0.645599f, 0.592773f, 0.481384f},
	{0.117706f, -0.949524f, -0.29068f},
	{-0.535004f, -0.791901f, -0.294312f},
	{-0.627167f, -0.214447f, 0.748718f},
	{-0.047974f, -0.813477f, -0.57959f},
	{-0.175537f, 0.477264f, -0.860992f},
	{0.738556f, -0.414246f, -0.53183f},
	{0.562561f, -0.704071f, 0.433289f},
	{-0.754944f, 0.64801f, -0.100586f},
	{0.114716f, 0.044525f, -0.992371f},
	{0.966003f, 0.244873f, -0.082764f},
	{0.33783f, 0.715698f, -0.611206f},
	{-0.944031f, -0.326599f, -0.045624f},
};

#define DOT(a,b) (a[0] * b[0] + a[1] * b[1] + a[2] * b[2])

#define setup(i,b0,b1,r0,r1) \
        t = vec[i] + 10000.; \
        b0 = ((int)t) & 255; \
        b1 = (b0+1) & 255; \
        r0 = t - (int)t; \
        r1 = r0 - 1.;

float noise3_perlin(float vec[3])
{
	int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
	float rx0, rx1, ry0, ry1, rz0, rz1, *q, sx, sy, sz, a, b, c, d, t, u, v;
	register int i, j;


	setup(0, bx0,bx1, rx0,rx1);
	setup(1, by0,by1, ry0,ry1);
	setup(2, bz0,bz1, rz0,rz1);

	i = p[ bx0 ];
	j = p[ bx1 ];

	b00 = p[ i + by0 ];
	b10 = p[ j + by0 ];
	b01 = p[ i + by1 ];
	b11 = p[ j + by1 ];

#define at(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )

#define surve(t) ( t * t * (3.f - 2.f * t) )

/* lerp moved to improved perlin above */

	sx = surve(rx0);
	sy = surve(ry0);
	sz = surve(rz0);

	q = g[ b00 + bz0 ] ;
	u = at(rx0,ry0,rz0);
	q = g[ b10 + bz0 ] ;
	v = at(rx1,ry0,rz0);
	a = lerp(sx, u, v);

	q = g[ b01 + bz0 ] ;
	u = at(rx0,ry1,rz0);
	q = g[ b11 + bz0 ] ;
	v = at(rx1,ry1,rz0);
	b = lerp(sx, u, v);

	c = lerp(sy, a, b);          /* interpolate in y at lo x */

	q = g[ b00 + bz1 ] ;
	u = at(rx0,ry0,rz1);
	q = g[ b10 + bz1 ] ;
	v = at(rx1,ry0,rz1);
	a = lerp(sx, u, v);

	q = g[ b01 + bz1 ] ;
	u = at(rx0,ry1,rz1);
	q = g[ b11 + bz1 ] ;
	v = at(rx1,ry1,rz1);
	b = lerp(sx, u, v);

	d = lerp(sy, a, b);          /* interpolate in y at hi x */

	return 1.5f * lerp(sz, c, d); /* interpolate in z */
}

float turbulence_perlin(float *point, float lofreq, float hifreq)
{
	float freq, t, p[3];

	p[0] = point[0] + 123.456f;
	p[1] = point[1];
	p[2] = point[2];

	t = 0.f;
	for (freq = lofreq ; freq < hifreq ; freq *= 2.f) {
		t += fabs(noise3_perlin(p)) / freq;
		p[0] *= 2.f;
		p[1] *= 2.f;
		p[2] *= 2.f;
	}
	return t - 0.3f; /* readjust to make mean value = 0.0 */
}

/* for use with BLI_gNoise/gTurbulence, returns signed noise */
static float orgPerlinNoise(float x, float y, float z)
{
	float v[3];

	v[0] = x;
	v[1] = y;
	v[2] = z;
	return noise3_perlin(v);
}

/* for use with BLI_gNoise/gTurbulence, returns unsigned noise */
static float orgPerlinNoiseU(float x, float y, float z)
{
	float v[3];

	v[0] = x;
	v[1] = y;
	v[2] = z;
	return (0.5f+0.5f*noise3_perlin(v));
}

/* *************** CALL AS: *************** */

float BLI_hnoisep(float noisesize, float x, float y, float z)
{
	float vec[3];

	vec[0]= x/noisesize;
	vec[1]= y/noisesize;
	vec[2]= z/noisesize;

	return noise3_perlin(vec);
}

float turbulencep(float noisesize, float x, float y, float z, int nr)
{
	float vec[3];

	vec[0]= x/noisesize;
	vec[1]= y/noisesize;
	vec[2]= z/noisesize;
	nr++;
	return turbulence_perlin(vec, 1.f, (float)(1<<nr));
}

/******************/
/* VORONOI/WORLEY */
/******************/

/* distance metrics for voronoi, e parameter only used in Minkovsky */
/* Camberra omitted, didn't seem useful */

/* distance squared */
static float dist_Squared(float x, float y, float z, float e) { return (x*x + y*y + z*z); }
/* real distance */
static float dist_Real(float x, float y, float z, float e) { return sqrt(x*x + y*y + z*z); }
/* manhattan/taxicab/cityblock distance */
static float dist_Manhattan(float x, float y, float z, float e) { return (fabs(x) + fabs(y) + fabs(z)); }
/* Chebychev */
static float dist_Chebychev(float x, float y, float z, float e)
{
	float t;
	x = fabs(x);
	y = fabs(y);
	z = fabs(z);
	t = (x>y)?x:y;
	return ((z>t)?z:t);
}

/* minkovsky preset exponent 0.5 */
static float dist_MinkovskyH(float x, float y, float z, float e)
{
	float d = sqrt(fabs(x)) + sqrt(fabs(y)) + sqrt(fabs(z));
	return (d*d);
}

/* minkovsky preset exponent 4 */
static float dist_Minkovsky4(float x, float y, float z, float e)
{
	x *= x;
	y *= y;
	z *= z;
	return sqrt(sqrt(x*x + y*y + z*z));
}

/* Minkovsky, general case, slow, maybe too slow to be useful */
static float dist_Minkovsky(float x, float y, float z, float e)
{
 return powf(powf(fabs(x), e) + powf(fabs(y), e) + powf(fabs(z), e), 1.0/e);
}

/* Not 'pure' Worley, but the results are virtually the same.
	 Returns distances in da and point coords in pa */
void voronoi(float x, float y, float z, float* da, float* pa, float me, DistanceMetric dtype) {
	int xx, yy, zz, xi, yi, zi;
	float xd, yd, zd, d, *p;

	float (*distfunc)(float, float, float, float);
	switch (dtype) {
		case DISTANCE_SQUARED:
			distfunc = dist_Squared;
			break;
		case MANHATTAN:
			distfunc = dist_Manhattan;
			break;
		case CHEBYCHEV:
			distfunc = dist_Chebychev;
			break;
		case MINKOWSKI_HALF:
			distfunc = dist_MinkovskyH;
			break;
		case MINKOWSKI_FOUR:
			distfunc = dist_Minkovsky4;
			break;
		case MINKOWSKI:
			distfunc = dist_Minkovsky;
			break;
		case ACTUAL_DISTANCE:
		default:
			distfunc = dist_Real;
	}

	xi = (int)(floor(x));
	yi = (int)(floor(y));
	zi = (int)(floor(z));
	da[0] = da[1] = da[2] = da[3] = 1e10f;
	for (xx=xi-1;xx<=xi+1;xx++) {
		for (yy=yi-1;yy<=yi+1;yy++) {
			for (zz=zi-1;zz<=zi+1;zz++) {
				p = HASHPNT(xx, yy, zz);
				xd = x - (p[0] + xx);
				yd = y - (p[1] + yy);
				zd = z - (p[2] + zz);
				d = distfunc(xd, yd, zd, me);
				if (d<da[0]) {
					da[3]=da[2];  da[2]=da[1];  da[1]=da[0];  da[0]=d;
					pa[9]=pa[6];  pa[10]=pa[7];  pa[11]=pa[8];
					pa[6]=pa[3];  pa[7]=pa[4];  pa[8]=pa[5];
					pa[3]=pa[0];  pa[4]=pa[1];  pa[5]=pa[2];
					pa[0]=p[0]+xx;  pa[1]=p[1]+yy;  pa[2]=p[2]+zz;
				}
				else if (d<da[1]) {
					da[3]=da[2];  da[2]=da[1];  da[1]=d;
					pa[9]=pa[6];  pa[10]=pa[7];  pa[11]=pa[8];
					pa[6]=pa[3];  pa[7]=pa[4];  pa[8]=pa[5];
					pa[3]=p[0]+xx;  pa[4]=p[1]+yy;  pa[5]=p[2]+zz;
				}
				else if (d<da[2]) {
					da[3]=da[2];  da[2]=d;
					pa[9]=pa[6];  pa[10]=pa[7];  pa[11]=pa[8];
					pa[6]=p[0]+xx;  pa[7]=p[1]+yy;  pa[8]=p[2]+zz;
				}
				else if (d<da[3]) {
					da[3]=d;
					pa[9]=p[0]+xx;  pa[10]=p[1]+yy;  pa[11]=p[2]+zz;
				}
			}
		}
	}
}

/* returns different feature points for use in BLI_gNoise() */
static float voronoi_F1(float x, float y, float z)
{
	float da[4], pa[12];
	voronoi(x, y, z, da, pa, 1.f, ACTUAL_DISTANCE);
	return da[0];
}

static float voronoi_F2(float x, float y, float z)
{
	float da[4], pa[12];
	voronoi(x, y, z, da, pa, 1.f, ACTUAL_DISTANCE);
	return da[1];
}

static float voronoi_F3(float x, float y, float z)
{
	float da[4], pa[12];
	voronoi(x, y, z, da, pa, 1.f, ACTUAL_DISTANCE);
	return da[2];
}

static float voronoi_F4(float x, float y, float z)
{
	float da[4], pa[12];
	voronoi(x, y, z, da, pa, 1.f, ACTUAL_DISTANCE);
	return da[3];
}

static float voronoi_F1F2(float x, float y, float z)
{
	float da[4], pa[12];
	voronoi(x, y, z, da, pa, 1.f, ACTUAL_DISTANCE);
	return (da[1]-da[0]);
}

/* Crackle type pattern, just a scale/clamp of F2-F1 */
static float voronoi_Cr(float x, float y, float z)
{
	float t = 10.f*voronoi_F1F2(x, y, z);
	if (t>1.f) return 1.f;
	return t;
}


/* Signed version of all 6 of the above, just 2x-1, not really correct though (range is potentially (0, sqrt(6)).
   Used in the musgrave functions */
static float voronoi_F1S(float x, float y, float z)
{
	float da[4], pa[12];
	voronoi(x, y, z, da, pa, 1.f, ACTUAL_DISTANCE);
	return (2.f*da[0]-1.f);
}

static float voronoi_F2S(float x, float y, float z)
{
	float da[4], pa[12];
	voronoi(x, y, z, da, pa, 1.f, ACTUAL_DISTANCE);
	return (2.f*da[1]-1.f);
}

static float voronoi_F3S(float x, float y, float z)
{
	float da[4], pa[12];
	voronoi(x, y, z, da, pa, 1.f, ACTUAL_DISTANCE);
	return (2.f*da[2]-1.f);
}

static float voronoi_F4S(float x, float y, float z)
{
	float da[4], pa[12];
	voronoi(x, y, z, da, pa, 1.f, ACTUAL_DISTANCE);
	return (2.f*da[3]-1.f);
}

static float voronoi_F1F2S(float x, float y, float z)
{
	float da[4], pa[12];
	voronoi(x, y, z, da, pa, 1.f, ACTUAL_DISTANCE);
	return (2.f*(da[1]-da[0])-1.f);
}

/* Crackle type pattern, just a scale/clamp of F2-F1 */
static float voronoi_CrS(float x, float y, float z)
{
	float t = 10.f*voronoi_F1F2(x, y, z);
	if (t>1.f) return 1.f;
	return (2.f*t-1.f);
}

/***************/
/* voronoi end */
/***************/

/*************/
/* CELLNOISE */
/*************/

/* returns unsigned cellnoise */
static float cellNoiseU(float x, float y, float z)
{
  int xi = (int)(floor(x));
  int yi = (int)(floor(y));
  int zi = (int)(floor(z));
  unsigned int n = xi + yi*1301 + zi*314159;
  n ^= (n<<13);
  return ((float)(n*(n*n*15731 + 789221) + 1376312589) / 4294967296.f);
}

/* idem, signed */
float cellNoise(float x, float y, float z)
{
  return (2.f*cellNoiseU(x, y, z)-1.f);
}

/* returns a vector/point/color in ca, using point hasharray directly */
void cellNoiseV(float x, float y, float z, float *ca)
{
	int xi = (int)(floor(x));
	int yi = (int)(floor(y));
	int zi = (int)(floor(z));
	float *p = HASHPNT(xi, yi, zi);
	ca[0] = p[0];
	ca[1] = p[1];
	ca[2] = p[2];
}


/*****************/
/* end cellnoise */
/*****************/

/* newnoise: generic noise function for use with different noisebases */
float BLI_gNoise(float noisesize, float x, float y, float z, int hard, BlenderNoiseBasis noisebasis)
{
	float (*noisefunc)(float, float, float);

	switch (noisebasis) {
		case ORIGINAL_PERLIN:
			noisefunc = orgPerlinNoiseU;
			break;
		case IMPROVED_PERLIN:
			noisefunc = newPerlinU;
			break;
		case VORONOI_F1:
			noisefunc = voronoi_F1;
			break;
		case VORONOI_F2:
			noisefunc = voronoi_F2;
			break;
		case VORONOI_F3:
			noisefunc = voronoi_F3;
			break;
		case VORONOI_F4:
			noisefunc = voronoi_F4;
			break;
		case VORONOI_F2_F1:
			noisefunc = voronoi_F1F2;
			break;
		case VORONOI_CRACKLE:
			noisefunc = voronoi_Cr;
			break;
		case CELL_NOISE:
			noisefunc = cellNoiseU;
			break;
		case BLENDER_ORIGINAL:
		default: {
			noisefunc = orgBlenderNoise;
			/* add one to make return value same as BLI_hnoise */
			x += 1.f;
			y += 1.f;
			z += 1.f;
		}
	}

	if (noisesize!=0.f) {
		noisesize = 1.f/noisesize;
		x *= noisesize;
		y *= noisesize;
		z *= noisesize;
	}
	
	if (hard) return fabs(2.f*noisefunc(x, y, z)-1.f);
	return noisefunc(x, y, z);
}

/* newnoise: generic turbulence function for use with different noisebasis */
float BLI_gTurbulence(float noisesize, float x, float y, float z, int oct, int hard, BlenderNoiseBasis noisebasis)
{
	float (*noisefunc)(float, float, float);
	float sum, t, amp=1.f, fscale=1.f;
	int i;
	
	switch (noisebasis) {
		case ORIGINAL_PERLIN:
			noisefunc = orgPerlinNoise;
			break;
		case IMPROVED_PERLIN:
			noisefunc = newPerlin;
			break;
		case VORONOI_F1:
			noisefunc = voronoi_F1;
			break;
		case VORONOI_F2:
			noisefunc = voronoi_F2;
			break;
		case VORONOI_F3:
			noisefunc = voronoi_F3;
			break;
		case VORONOI_F4:
			noisefunc = voronoi_F4;
			break;
		case VORONOI_F2_F1:
			noisefunc = voronoi_F1F2;
			break;
		case VORONOI_CRACKLE:
			noisefunc = voronoi_Cr;
			break;
		case CELL_NOISE:
			noisefunc = cellNoiseU;
			break;
		case BLENDER_ORIGINAL:
		default:
			noisefunc = orgBlenderNoise;
			x += 1.f;
			y += 1.f;
			z += 1.f;
	}

	if (noisesize!=0.f) {
		noisesize = 1.f/noisesize;
		x *= noisesize;
		y *= noisesize;
		z *= noisesize;
	}

	sum = 0;
	for (i=0;i<=oct;i++, amp*=0.5f, fscale*=2.f) {
		t = noisefunc(fscale*x, fscale*y, fscale*z);
		if (hard) t = fabs(2.f*t-1.f);
		sum += t * amp;
	}
	
	sum *= ((float)(1<<oct)/(float)((1<<(oct+1))-1));

	return sum;

}


/*
 * The following code is based on Ken Musgrave's explanations and sample
 * source code in the book "Texturing and Modelling: A procedural approach"
 */

/*
 * Procedural fBm evaluated at "point"; returns value stored in "value".
 *
 * Parameters:
 *    ``H''  is the fractal increment parameter
 *    ``lacunarity''  is the gap between successive frequencies
 *    ``octaves''  is the number of frequencies in the fBm
 */
float mg_fBm(float x, float y, float z, float H, float lacunarity, float octaves, BlenderNoiseBasis noisebasis)
{
	float	rmd, value=0.f, pwr=1.f, pwHL=pow(lacunarity, -H);
	int	i;

	float (*noisefunc)(float, float, float);
	switch (noisebasis) {
		case ORIGINAL_PERLIN:
			noisefunc = orgPerlinNoise;
			break;
		case IMPROVED_PERLIN:
			noisefunc = newPerlin;
			break;
		case VORONOI_F1:
			noisefunc = voronoi_F1S;
			break;
		case VORONOI_F2:
			noisefunc = voronoi_F2S;
			break;
		case VORONOI_F3:
			noisefunc = voronoi_F3S;
			break;
		case VORONOI_F4:
			noisefunc = voronoi_F4S;
			break;
		case VORONOI_F2_F1:
			noisefunc = voronoi_F1F2S;
			break;
		case VORONOI_CRACKLE:
			noisefunc = voronoi_CrS;
			break;
		case CELL_NOISE:
			noisefunc = cellNoise;
			break;
		case BLENDER_ORIGINAL:
		default: {
			noisefunc = orgBlenderNoiseS;
		}
	}
	
	for (i=0; i<(int)octaves; i++) {
		value += noisefunc(x, y, z) * pwr;
		pwr *= pwHL;
		x *= lacunarity;
		y *= lacunarity;
		z *= lacunarity;
	}

	rmd = octaves - floor(octaves);
	if (rmd!=0.f) value += rmd * noisefunc(x, y, z) * pwr;

	return value;

} /* fBm() */


/*
 * Procedural multifractal evaluated at "point";
 * returns value stored in "value".
 *
 * Parameters:
 *    ``H''  determines the highest fractal dimension
 *    ``lacunarity''  is gap between successive frequencies
 *    ``octaves''  is the number of frequencies in the fBm
 *    ``offset''  is the zero offset, which determines multifractality (NOT USED??)
 */
 /* this one is in fact rather confusing,
 	* there seem to be errors in the original source code (in all three versions of proc.text&mod),
	* I modified it to something that made sense to me, so it might be wrong... */
float mg_MultiFractal(float x, float y, float z, float H, float lacunarity, float octaves, BlenderNoiseBasis noisebasis)
{
	float	rmd, value=1.f, pwr=1.f, pwHL=pow(lacunarity, -H);
	int i;
	
	float (*noisefunc)(float, float, float);
	switch (noisebasis) {
		case ORIGINAL_PERLIN:
			noisefunc = orgPerlinNoise;
			break;
		case IMPROVED_PERLIN:
			noisefunc = newPerlin;
			break;
		case VORONOI_F1:
			noisefunc = voronoi_F1S;
			break;
		case VORONOI_F2:
			noisefunc = voronoi_F2S;
			break;
		case VORONOI_F3:
			noisefunc = voronoi_F3S;
			break;
		case VORONOI_F4:
			noisefunc = voronoi_F4S;
			break;
		case VORONOI_F2_F1:
			noisefunc = voronoi_F1F2S;
			break;
		case VORONOI_CRACKLE:
			noisefunc = voronoi_CrS;
			break;
		case CELL_NOISE:
			noisefunc = cellNoise;
			break;
		case BLENDER_ORIGINAL:
		default: {
			noisefunc = orgBlenderNoiseS;
		}
	}

	for (i=0; i<(int)octaves; i++) {
		value *= (pwr * noisefunc(x, y, z) + 1.f);
		pwr *= pwHL;
		x *= lacunarity;
		y *= lacunarity;
		z *= lacunarity;
	}
	rmd = octaves - floor(octaves);
	if (rmd!=0.f) value *= (rmd * noisefunc(x, y, z) * pwr + 1.f);

	return value;

} /* multifractal() */

/*
 * Heterogeneous procedural terrain function: stats by altitude method.
 * Evaluated at "point"; returns value stored in "value".
 *
 * Parameters:
 *       ``H''  determines the fractal dimension of the roughest areas
 *       ``lacunarity''  is the gap between successive frequencies
 *       ``octaves''  is the number of frequencies in the fBm
 *       ``offset''  raises the terrain from `sea level'
 */
float mg_HeteroTerrain(float x, float y, float z, float H, float lacunarity, float octaves, float offset, BlenderNoiseBasis noisebasis)
{
	float	value, increment, rmd;
	int i;
	float pwHL = pow(lacunarity, -H);
	float pwr = pwHL;	/* starts with i=1 instead of 0 */

	float (*noisefunc)(float, float, float);
	switch (noisebasis) {
		case ORIGINAL_PERLIN:
			noisefunc = orgPerlinNoise;
			break;
		case IMPROVED_PERLIN:
			noisefunc = newPerlin;
			break;
		case VORONOI_F1:
			noisefunc = voronoi_F1S;
			break;
		case VORONOI_F2:
			noisefunc = voronoi_F2S;
			break;
		case VORONOI_F3:
			noisefunc = voronoi_F3S;
			break;
		case VORONOI_F4:
			noisefunc = voronoi_F4S;
			break;
		case VORONOI_F2_F1:
			noisefunc = voronoi_F1F2S;
			break;
		case VORONOI_CRACKLE:
			noisefunc = voronoi_CrS;
			break;
		case CELL_NOISE:
			noisefunc = cellNoise;
			break;
		case BLENDER_ORIGINAL:
		default: {
			noisefunc = orgBlenderNoiseS;
		}
	}

	/* first unscaled octave of function; later octaves are scaled */
	value = offset + noisefunc(x, y, z);
	x *= lacunarity;
	y *= lacunarity;
	z *= lacunarity;

	for (i=1; i<(int)octaves; i++) {
		increment = (noisefunc(x, y, z) + offset) * pwr * value;
		value += increment;
		pwr *= pwHL;
		x *= lacunarity;
		y *= lacunarity;
		z *= lacunarity;
	}

	rmd = octaves - floor(octaves);
	if (rmd!=0.f) {
		increment = (noisefunc(x, y, z) + offset) * pwr * value;
		value += rmd * increment;
	}
	return value;
}


/* Hybrid additive/multiplicative multifractal terrain model.
 *
 * Some good parameter values to start with:
 *
 *      H:           0.25
 *      offset:      0.7
 */
float mg_HybridMultiFractal(float x, float y, float z, float H, float lacunarity, float octaves, float offset, float gain, BlenderNoiseBasis noisebasis)
{
	float result, signal, weight, rmd;
	int i;
	float pwHL = pow(lacunarity, -H);
	float pwr = pwHL;	/* starts with i=1 instead of 0 */
	float (*noisefunc)(float, float, float);

	switch (noisebasis) {
		case ORIGINAL_PERLIN:
			noisefunc = orgPerlinNoise;
			break;
		case IMPROVED_PERLIN:
			noisefunc = newPerlin;
			break;
		case VORONOI_F1:
			noisefunc = voronoi_F1S;
			break;
		case VORONOI_F2:
			noisefunc = voronoi_F2S;
			break;
		case VORONOI_F3:
			noisefunc = voronoi_F3S;
			break;
		case VORONOI_F4:
			noisefunc = voronoi_F4S;
			break;
		case VORONOI_F2_F1:
			noisefunc = voronoi_F1F2S;
			break;
		case VORONOI_CRACKLE:
			noisefunc = voronoi_CrS;
			break;
		case CELL_NOISE:
			noisefunc = cellNoise;
			break;
		case BLENDER_ORIGINAL:
		default: {
			noisefunc = orgBlenderNoiseS;
		}
	}

	result = noisefunc(x, y, z) + offset;
	weight = gain * result;
	x *= lacunarity;
	y *= lacunarity;
	z *= lacunarity;

	for (i=1; (weight>0.001f) && (i<(int)octaves); i++) {
		if (weight>1.f)  weight=1.f;
		signal = (noisefunc(x, y, z) + offset) * pwr;
		pwr *= pwHL;
		result += weight * signal;
		weight *= gain * signal;
		x *= lacunarity;
		y *= lacunarity;
		z *= lacunarity;
	}

	rmd = octaves - floor(octaves);
	if (rmd!=0.f) result += rmd * ((noisefunc(x, y, z) + offset) * pwr);

	return result;

} /* HybridMultifractal() */


/* Ridged multifractal terrain model.
 *
 * Some good parameter values to start with:
 *
 *      H:           1.0
 *      offset:      1.0
 *      gain:        2.0
 */
float mg_RidgedMultiFractal(float x, float y, float z, float H, float lacunarity, float octaves, float offset, float gain, BlenderNoiseBasis noisebasis)
{
	float result, signal, weight;
	int	i;
	float pwHL = pow(lacunarity, -H);
	float pwr = pwHL;	/* starts with i=1 instead of 0 */
	
	float (*noisefunc)(float, float, float);
	switch (noisebasis) {
		case ORIGINAL_PERLIN:
			noisefunc = orgPerlinNoise;
			break;
		case IMPROVED_PERLIN:
			noisefunc = newPerlin;
			break;
		case VORONOI_F1:
			noisefunc = voronoi_F1S;
			break;
		case VORONOI_F2:
			noisefunc = voronoi_F2S;
			break;
		case VORONOI_F3:
			noisefunc = voronoi_F3S;
			break;
		case VORONOI_F4:
			noisefunc = voronoi_F4S;
			break;
		case VORONOI_F2_F1:
			noisefunc = voronoi_F1F2S;
			break;
		case VORONOI_CRACKLE:
			noisefunc = voronoi_CrS;
			break;
		case CELL_NOISE:
			noisefunc = cellNoise;
			break;
		case BLENDER_ORIGINAL:
		default: {
			noisefunc = orgBlenderNoiseS;
		}
	}

	signal = offset - fabs(noisefunc(x, y, z));
	signal *= signal;
	result = signal;
	weight = 1.f;

	for( i=1; i<(int)octaves; i++ ) {
		x *= lacunarity;
		y *= lacunarity;
		z *= lacunarity;
		weight = signal * gain;
		if (weight>1.f) weight=1.f; else if (weight<0.f) weight=0.f;
		signal = offset - fabs(noisefunc(x, y, z));
		signal *= signal;
		signal *= weight;
		result += signal * pwr;
		pwr *= pwHL;
	}

	return result;
} /* RidgedMultifractal() */

/* "Variable Lacunarity Noise"
 * A distorted variety of Perlin noise.
 */
float mg_VLNoise(float x, float y, float z, float distortion, BlenderNoiseBasis nbas1, BlenderNoiseBasis nbas2)
{
	float rv[3];
	float (*noisefunc1)(float, float, float);
	float (*noisefunc2)(float, float, float);

	switch (nbas1) {
		case ORIGINAL_PERLIN:
			noisefunc1 = orgPerlinNoise;
			break;
		case IMPROVED_PERLIN:
			noisefunc1 = newPerlin;
			break;
		case VORONOI_F1:
			noisefunc1 = voronoi_F1S;
			break;
		case VORONOI_F2:
			noisefunc1 = voronoi_F2S;
			break;
		case VORONOI_F3:
			noisefunc1 = voronoi_F3S;
			break;
		case VORONOI_F4:
			noisefunc1 = voronoi_F4S;
			break;
		case VORONOI_F2_F1:
			noisefunc1 = voronoi_F1F2S;
			break;
		case VORONOI_CRACKLE:
			noisefunc1 = voronoi_CrS;
			break;
		case CELL_NOISE:
			noisefunc1 = cellNoise;
			break;
		case BLENDER_ORIGINAL:
		default: {
			noisefunc1 = orgBlenderNoiseS;
		}
	}

	switch (nbas2) {
		case ORIGINAL_PERLIN:
			noisefunc2 = orgPerlinNoise;
			break;
		case IMPROVED_PERLIN:
			noisefunc2 = newPerlin;
			break;
		case VORONOI_F1:
			noisefunc2 = voronoi_F1S;
			break;
		case VORONOI_F2:
			noisefunc2 = voronoi_F2S;
			break;
		case VORONOI_F3:
			noisefunc2 = voronoi_F3S;
			break;
		case VORONOI_F4:
			noisefunc2 = voronoi_F4S;
			break;
		case VORONOI_F2_F1:
			noisefunc2 = voronoi_F1F2S;
			break;
		case VORONOI_CRACKLE:
			noisefunc2 = voronoi_CrS;
			break;
		case CELL_NOISE:
			noisefunc2 = cellNoise;
			break;
		case BLENDER_ORIGINAL:
		default: {
			noisefunc2 = orgBlenderNoiseS;
		}
	}

	/* get a random vector and scale the randomization */
	rv[0] = noisefunc1(x+13.5f, y+13.5f, z+13.5f) * distortion;
	rv[1] = noisefunc1(x, y, z) * distortion;
	rv[2] = noisefunc1(x-13.5f, y-13.5f, z-13.5f) * distortion;
	return noisefunc2(x+rv[0], y+rv[1], z+rv[2]);	/* distorted-domain noise */
}

/****************/
/* musgrave end */
/****************/

} // namespace blender

} // namespace slg
