Created
February 6, 2018 21:30
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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