/** * $Id$ * * Blender.Noise BPython module implementation. * This submodule has functions to generate noise of various types. * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. The Blender * Foundation also sells licenses for use in proprietary software under * the Blender License. See http://www.blender.org/BL/ for information * about this. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * * This is a new part of Blender. * * Contributor(s): eeshlo * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ /************************/ /* Blender Noise Module */ /************************/ #include #include #include #include #include "constant.h" /*------------------------------------------------------------------------------------*/ /* 'mersenne twister' random number generator */ /* Period parameters */ #define N 624 #define M 397 #define MATRIX_A 0x9908b0dfUL /* constant vector a */ #define UMASK 0x80000000UL /* most significant w-r bits */ #define LMASK 0x7fffffffUL /* least significant r bits */ #define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) ) #define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL)) static unsigned long state[N]; /* the array for the state vector */ static int left = 1; static int initf = 0; static unsigned long *next; /* initializes state[N] with a seed */ static void init_genrand(unsigned long s) { int j; state[0]= s & 0xffffffffUL; for (j=1; j> 30)) + j); /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ /* In the previous versions, MSBs of the seed affect */ /* only MSBs of the array state[]. */ /* 2002/01/09 modified by Makoto Matsumoto */ state[j] &= 0xffffffffUL; /* for >32 bit machines */ } left = 1; initf = 1; } static void next_state(void) { unsigned long *p=state; int j; /* if init_genrand() has not been called, */ /* a default initial seed is used */ if (initf==0) init_genrand(5489UL); left = N; next = state; for (j=N-M+1; --j; p++) *p = p[M] ^ TWIST(p[0], p[1]); for (j=M; --j; p++) *p = p[M-N] ^ TWIST(p[0], p[1]); *p = p[M-N] ^ TWIST(p[0], state[0]); } /*------------------------------------------------------------------------------------*/ static void setRndSeed(int seed) { if (seed==0) init_genrand(time(NULL)); else init_genrand(seed); } /* float number in range [0, 1) */ static float frand() { unsigned long y; if (--left == 0) next_state(); y = *next++; /* Tempering */ y ^= (y >> 11); y ^= (y << 7) & 0x9d2c5680UL; y ^= (y << 15) & 0xefc60000UL; y ^= (y >> 18); return (float)y/4294967296.f; } /* returns random unit vector */ static void randuvec(float v[3]) { float r; v[2] = 2.f*frand()-1.f; if ((r = 1.f - v[2]*v[2])>0.f) { float a = 6.283185307f * frand(); r = sqrt(r); v[0] = r * cos(a); v[1] = r * sin(a); } else v[2] = 1.f; } static PyObject *Noise_random(PyObject *self) { return Py_BuildValue("f", frand()); } static PyObject *Noise_randuvec(PyObject *self) { float v[3]; randuvec(v); return Py_BuildValue("[fff]", v[0], v[1], v[2]); } /*------------------------------------------------------------------------------------*/ /* Random seed init. Only used for MT random() & randuvec() */ static PyObject *Noise_setRandomSeed(PyObject *self, PyObject *args) { int s; if (!PyArg_ParseTuple(args, "i", &s)) return NULL; setRndSeed(s); Py_INCREF(Py_None); return Py_None; } /*------------------------------------------------------------------------------------*/ /* General noise */ static PyObject *Noise_noise(PyObject *self, PyObject *args) { float x, y, z; int nb = 1; if (!PyArg_ParseTuple(args, "(fff)|ii", &x ,&y, &z, &nb)) return NULL; return Py_BuildValue("f", 2.0*BLI_gNoise(1.0, x, y, z, 0, nb)-1.0); } /*------------------------------------------------------------------------------------*/ /* General Vector noise */ static void vNoise(float x, float y ,float z, int nb, float v[3]) { /* Simply evaluate noise at 3 different positions */ v[0] = 2.0*BLI_gNoise(1.f, x+9.321f, y-1.531f, z-7.951f, 0, nb)-1.0; v[1] = 2.0*BLI_gNoise(1.f, x, y, z, 0, nb)-1.0; v[2] = 2.0*BLI_gNoise(1.f, x+6.327f, y+0.1671f, z-2.672f, 0, nb)-1.0; } static PyObject *Noise_vNoise(PyObject *self, PyObject *args) { float x, y, z, v[3]; int nb = 1; if (!PyArg_ParseTuple(args, "(fff)", &x ,&y, &z, &nb)) return NULL; vNoise(x, y, z, nb, v); return Py_BuildValue("[fff]", v[0], v[1], v[2]); } /*------------------------------------------------------------------------------------*/ /* General turbulence */ static float turb(float x, float y, float z, int oct, int hard, int nb, float ampscale, float freqscale) { float amp, out, t; int i; amp = 1.f; out = 2.0*BLI_gNoise(1.f, x, y, z, 0, nb)-1.0; if (hard) out = fabs(out); for (i=1;i