Skip to content

Instantly share code, notes, and snippets.

@atavener
Created October 25, 2014 00:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save atavener/d748ecb788830ce4d8d0 to your computer and use it in GitHub Desktop.
Save atavener/d748ecb788830ce4d8d0 to your computer and use it in GitHub Desktop.
Some hash functions to generate pseudo-random values per-coordinate, in C, with OCaml FFI.
/* Some hash functions to generate pseudo-random values per-coordinate.
* Useful for spatial synthesis, such as procedural textures.
*/
/*** Bob Jenkins' mix and final ***/
#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
#define mix(a,b,c) \
{ \
a -= c; a ^= rot(c, 4); c += b; \
b -= a; b ^= rot(a, 6); a += c; \
c -= b; c ^= rot(b, 8); b += a; \
a -= c; a ^= rot(c,16); c += b; \
b -= a; b ^= rot(a,19); a += c; \
c -= b; c ^= rot(b, 4); b += a; \
}
#define final(a,b,c) \
{ \
c ^= b; c -= rot(b,14); \
a ^= c; a -= rot(c,11); \
b ^= a; b -= rot(a,25); \
c ^= b; c -= rot(b,16); \
a ^= c; a -= rot(c,4); \
b ^= a; b -= rot(a,14); \
c ^= b; c -= rot(b,24); \
}
/* ------------------------------------ */
/* A portion of Paul Hsieh's hash */
/* use this to generate a PRN sequence without state */
uint32_t HsiehHashNext( uint32_t hash ){
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
return hash;
}
/* ------------------------------------ */
/*** OCaml FFI ***/
#define Uint32_val(v) (*((uint32_t *) Data_custom_val(v)))
CAMLprim value ocaml_float_of_u32( value i ){
return caml_copy_double((double)Uint32_val(i));
}
/* it's fine if we return int32 type to OCaml... so it can understand it...
* since we'll be using a C-call for float_of_u32 anyway */
CAMLprim value ocaml_init_rnd( value data, value i ){
CAMLparam2( data, i );
uint32_t *p = (uint32_t*)data;
uint32_t a = p[0];
uint32_t b = p[1];
uint32_t c = p[2];
mix(a,b,c);
a+= p[3]; b+= p[4]; c+= p[5];
mix(a,b,c);
a+= Long_val(i);
final(a,b,c);
CAMLreturn( caml_copy_int32(c) );
}
CAMLprim value ocaml_next_rnd( value i ){
return caml_copy_int32( HsiehHashNext( Uint32_val(i) ) );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment