/* * $Id$ * * ***** BEGIN GPL 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. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * * The Original Code is: all of this file. * * Contributor(s): none yet. * * ***** END GPL LICENSE BLOCK ***** */ /** \file blender/blenlib/intern/rand.c * \ingroup bli */ #include #include #include "MEM_guardedalloc.h" #include "PIL_time.h" #include "BLI_threads.h" #include "BLI_rand.h" #if defined(WIN32) && !defined(FREE_WINDOWS) typedef unsigned __int64 r_uint64; #define MULTIPLIER 0x5DEECE66Di64 #define MASK 0x0000FFFFFFFFFFFFi64 #else typedef unsigned long long r_uint64; #define MULTIPLIER 0x5DEECE66Dll #define MASK 0x0000FFFFFFFFFFFFll #endif #define ADDEND 0xB #define LOWSEED 0x330E extern unsigned char hash[]; // noise.c /***/ struct RNG { r_uint64 X; }; RNG *rng_new(unsigned int seed) { RNG *rng = MEM_mallocN(sizeof(*rng), "rng"); rng_seed(rng, seed); return rng; } void rng_free(RNG* rng) { MEM_freeN(rng); } void rng_seed(RNG *rng, unsigned int seed) { rng->X= (((r_uint64) seed)<<16) | LOWSEED; } void rng_srandom(RNG *rng, unsigned int seed) { rng_seed(rng, seed + hash[seed & 255]); seed= rng_getInt(rng); rng_seed(rng, seed + hash[seed & 255]); seed= rng_getInt(rng); rng_seed(rng, seed + hash[seed & 255]); } int rng_getInt(RNG *rng) { rng->X= (MULTIPLIER*rng->X + ADDEND)&MASK; return (int) (rng->X>>17); } double rng_getDouble(RNG *rng) { return (double) rng_getInt(rng)/0x80000000; } float rng_getFloat(RNG *rng) { return (float) rng_getInt(rng)/0x80000000; } void rng_shuffleArray(RNG *rng, void *data, int elemSize, int numElems) { int i = numElems; void *temp = malloc(elemSize); while (--i) { int j = rng_getInt(rng)%numElems; if(i!=j) { void *iElem = (unsigned char*)data + i*elemSize; void *jElem = (unsigned char*)data + j*elemSize; memcpy(temp, iElem, elemSize); memcpy(iElem, jElem, elemSize); memcpy(jElem, temp, elemSize); } } free(temp); } void rng_skip(RNG *rng, int n) { int i; for(i=0; i= BLENDER_MAX_THREADS) thread= 0; rng_seed(&rng_tab[thread], seed + hash[seed & 255]); seed= rng_getInt(&rng_tab[thread]); rng_seed(&rng_tab[thread], seed + hash[seed & 255]); seed= rng_getInt(&rng_tab[thread]); rng_seed(&rng_tab[thread], seed + hash[seed & 255]); } int BLI_thread_rand(int thread) { return rng_getInt(&rng_tab[thread]); } float BLI_thread_frand(int thread) { return rng_getFloat(&rng_tab[thread]); }