Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <stdlib.h> 00034 #include <string.h> 00035 00036 #include "MEM_guardedalloc.h" 00037 00038 #include "PIL_time.h" 00039 00040 #include "BLI_threads.h" 00041 #include "BLI_rand.h" 00042 00043 #if defined(WIN32) && !defined(FREE_WINDOWS) 00044 typedef unsigned __int64 r_uint64; 00045 00046 #define MULTIPLIER 0x5DEECE66Di64 00047 #define MASK 0x0000FFFFFFFFFFFFi64 00048 #else 00049 typedef unsigned long long r_uint64; 00050 00051 #define MULTIPLIER 0x5DEECE66Dll 00052 #define MASK 0x0000FFFFFFFFFFFFll 00053 #endif 00054 00055 #define ADDEND 0xB 00056 00057 #define LOWSEED 0x330E 00058 00059 extern unsigned char hash[]; // noise.c 00060 00061 /***/ 00062 00063 struct RNG { 00064 r_uint64 X; 00065 }; 00066 00067 RNG *rng_new(unsigned int seed) 00068 { 00069 RNG *rng = MEM_mallocN(sizeof(*rng), "rng"); 00070 00071 rng_seed(rng, seed); 00072 00073 return rng; 00074 } 00075 00076 void rng_free(RNG* rng) 00077 { 00078 MEM_freeN(rng); 00079 } 00080 00081 void rng_seed(RNG *rng, unsigned int seed) 00082 { 00083 rng->X= (((r_uint64) seed)<<16) | LOWSEED; 00084 } 00085 00086 void rng_srandom(RNG *rng, unsigned int seed) 00087 { 00088 rng_seed(rng, seed + hash[seed & 255]); 00089 seed= rng_getInt(rng); 00090 rng_seed(rng, seed + hash[seed & 255]); 00091 seed= rng_getInt(rng); 00092 rng_seed(rng, seed + hash[seed & 255]); 00093 } 00094 00095 int rng_getInt(RNG *rng) 00096 { 00097 rng->X= (MULTIPLIER*rng->X + ADDEND)&MASK; 00098 return (int) (rng->X>>17); 00099 } 00100 00101 double rng_getDouble(RNG *rng) 00102 { 00103 return (double) rng_getInt(rng)/0x80000000; 00104 } 00105 00106 float rng_getFloat(RNG *rng) 00107 { 00108 return (float) rng_getInt(rng)/0x80000000; 00109 } 00110 00111 void rng_shuffleArray(RNG *rng, void *data, int elemSize, int numElems) 00112 { 00113 int i = numElems; 00114 void *temp = malloc(elemSize); 00115 00116 while (--i) { 00117 int j = rng_getInt(rng)%numElems; 00118 if(i!=j) { 00119 void *iElem = (unsigned char*)data + i*elemSize; 00120 void *jElem = (unsigned char*)data + j*elemSize; 00121 memcpy(temp, iElem, elemSize); 00122 memcpy(iElem, jElem, elemSize); 00123 memcpy(jElem, temp, elemSize); 00124 } 00125 } 00126 00127 free(temp); 00128 } 00129 00130 void rng_skip(RNG *rng, int n) 00131 { 00132 int i; 00133 00134 for(i=0; i<n; i++) 00135 rng_getInt(rng); 00136 } 00137 00138 /***/ 00139 00140 static RNG theBLI_rng = {0}; 00141 00142 /* note, this one creates periodical patterns */ 00143 void BLI_srand(unsigned int seed) 00144 { 00145 rng_seed(&theBLI_rng, seed); 00146 } 00147 00148 /* using hash table to create better seed */ 00149 void BLI_srandom(unsigned int seed) 00150 { 00151 rng_srandom(&theBLI_rng, seed); 00152 } 00153 00154 int BLI_rand(void) 00155 { 00156 return rng_getInt(&theBLI_rng); 00157 } 00158 00159 double BLI_drand(void) 00160 { 00161 return rng_getDouble(&theBLI_rng); 00162 } 00163 00164 float BLI_frand(void) 00165 { 00166 return rng_getFloat(&theBLI_rng); 00167 } 00168 00169 void BLI_fillrand(void *addr, int len) 00170 { 00171 RNG rng; 00172 unsigned char *p= addr; 00173 00174 rng_seed(&rng, (unsigned int) (PIL_check_seconds_timer()*0x7FFFFFFF)); 00175 while (len--) *p++= rng_getInt(&rng)&0xFF; 00176 } 00177 00178 void BLI_array_randomize(void *data, int elemSize, int numElems, unsigned int seed) 00179 { 00180 RNG rng; 00181 00182 rng_seed(&rng, seed); 00183 rng_shuffleArray(&rng, data, elemSize, numElems); 00184 } 00185 00186 /* ********* for threaded random ************** */ 00187 00188 static RNG rng_tab[BLENDER_MAX_THREADS]; 00189 00190 void BLI_thread_srandom(int thread, unsigned int seed) 00191 { 00192 if(thread >= BLENDER_MAX_THREADS) 00193 thread= 0; 00194 00195 rng_seed(&rng_tab[thread], seed + hash[seed & 255]); 00196 seed= rng_getInt(&rng_tab[thread]); 00197 rng_seed(&rng_tab[thread], seed + hash[seed & 255]); 00198 seed= rng_getInt(&rng_tab[thread]); 00199 rng_seed(&rng_tab[thread], seed + hash[seed & 255]); 00200 } 00201 00202 int BLI_thread_rand(int thread) 00203 { 00204 return rng_getInt(&rng_tab[thread]); 00205 } 00206 00207 float BLI_thread_frand(int thread) 00208 { 00209 return rng_getFloat(&rng_tab[thread]); 00210 } 00211