Skip to content

Instantly share code, notes, and snippets.

@BlackJar72
Created February 6, 2018 21:30
Show Gist options
  • Save BlackJar72/0f5b6d363406493418494e910b22390f to your computer and use it in GitHub Desktop.
Save BlackJar72/0f5b6d363406493418494e910b22390f to your computer and use it in GitHub Desktop.
A simple, self-contained way to generate location-specific, on-demand pseudorandon number for procedural content generation by hash coordinates
/*
* A code snippet (not the whole thing) or a system for
* generating sequences of random number at points in
* space and "time" (sequence order) by hashing 4-dimensional
* coordinates. The purpose of this is for use in
* procedural content generation, as an alternative to
* complex systems of region / chunk / area seed calculations.
* This allows for any of the needed pseudorandom numbers
* to be generated on demand, in any order, as many times
* as required -- easily adapting to worlds generating in
* unpredictable order based on player actions and location.
*
* As a side benefit and instance (class static or global)
* with a hardcoded magic number for a seed can be used
* to has location specific data for storage in a hashmap
* style cache.
*
* For fewer dimension, of course, it can be simplified.
*
* Other data types are easily dirived, of course. For
* example, taking only lower order bits for smaller
* integral types or dividing by 0xffffffffffffffff to
* get floating point types.
*
* Fuller implementations can be found at:
* https://github.com/BlackJar72/MyLibraries/blob/master/GameMath/src/SpatialRandom.cpp
*
* ...and for a Java version at:
* https://github.com/BlackJar72/ProcGenLab/blob/master/src/jaredbgreat/procgenlab/api/util/SpatialNoise.java
*
*/
inline long rrotate(const long &in, const int &by) const {
return ((in >> by) | (in << (64 - by)));
}
inline long lrotate(const long &in, const int &by) const {
return ((in << by) | (in >> (64 - by)));
}
unsigned long long SpatialNoise::longFor(const int &x, const int &y, const int &z, const int &t) const {
long long out = seed1 + (15485077L * (long long)t)
+ (12338621L * (long long)x)
+ (15485863L * (long long)y)
+ (14416417L * (long long)z);
long long alt = seed2 + (179424743L * (long long)t)
+ (154858637L * (long long)y)
+ (179426003L * (long long)x)
+ (179425819L * (long long)z);
alt ^= lrotate(alt, (x % 29) + 13);
alt ^= rrotate(alt, (y % 31) + 7);
alt ^= lrotate(alt, (z % 23) + 19);
alt ^= rrotate(alt, (t % 43) + 11);
out ^= lrotate(out, ((x & 0x7fffffff) % 13) + 5);
out ^= rrotate(out, ((y & 0x7fffffff) % 11) + 28);
out ^= lrotate(out, ((z & 0x7fffffff) % 7) + 13);
out ^= rrotate(out, ((t & 0x7ffffff)% 17) + 45);
return (out ^ alt);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment