diff --git a/Include/Aurora/RNG/IRandomDevice.hpp b/Include/Aurora/RNG/IRandomDevice.hpp index ca24537b..6b758759 100644 --- a/Include/Aurora/RNG/IRandomDevice.hpp +++ b/Include/Aurora/RNG/IRandomDevice.hpp @@ -35,6 +35,12 @@ namespace Aurora::RNG virtual AuVec3 NextVec3Sorted(AuVec3 min, AuVec3 max) = 0; virtual AuVec4 NextVec4(AuVec4 boundA, AuVec4 boundB) = 0; virtual AuVec4 NextVec4Sorted(AuVec4 min, AuVec4 max) = 0; + virtual AuVecD2 NextVecD2(AuVecD2 boundA, AuVecD2 boundB) = 0; + virtual AuVecD2 NextVecD2Sorted(AuVecD2 min, AuVecD2 max) = 0; + virtual AuVecD3 NextVecD3(AuVecD3 boundA, AuVecD3 boundB) = 0; + virtual AuVecD3 NextVecD3Sorted(AuVecD3 min, AuVecD3 max) = 0; + virtual AuVecD4 NextVecD4(AuVecD4 boundA, AuVecD4 boundB) = 0; + virtual AuVecD4 NextVecD4Sorted(AuVecD4 min, AuVecD4 max) = 0; virtual double NextDecimal() = 0; virtual double NextNumber(double dMin, double dMax) = 0; virtual AuUInt32 NextIndex(AuUInt32 uCount /* = max + 1*/) = 0; @@ -63,6 +69,12 @@ namespace Aurora::RNG // by the bound[..]s or min/max vecs parameters. Some bruteforce would be required. // + // Wont add generics: if constexprs are very modern; we have slight differences between types; + // generics would needs extra tags to handle memory view (near?) alloc-less + // operations! Method is too ambigious compared to simple + // unoverloaded and verbose/self-documenting method names. Also easier to bind + // this way. + virtual AuList NextArrayI32Range(AuUInt32 uCount, AuInt32 iMin, AuInt32 iMax) = 0; virtual AuList NextArrayI32RangeFast(AuUInt32 uCount, AuInt32 iMin, AuInt32 iMax) = 0; virtual AuList NextArrayU32Range(AuUInt32 uCount, AuUInt32 uMin, AuUInt32 uMax) = 0; @@ -91,6 +103,18 @@ namespace Aurora::RNG virtual AuList NextArrayVec4Fast(AuUInt32 uCount, AuVec4 boundA, AuVec4 boundB) = 0; virtual AuList NextArrayVec4Sorted(AuUInt32 uCount, AuVec4 min, AuVec4 max) = 0; virtual AuList NextArrayVec4SortedFast(AuUInt32 uCount, AuVec4 min, AuVec4 max) = 0; + virtual AuList NextArrayVecD2(AuUInt32 uCount, AuVecD2 boundA, AuVecD2 boundB) = 0; + virtual AuList NextArrayVecD2Fast(AuUInt32 uCount, AuVecD2 boundA, AuVecD2 boundB) = 0; + virtual AuList NextArrayVecD2Sorted(AuUInt32 uCount, AuVecD2 min, AuVecD2 max) = 0; + virtual AuList NextArrayVecD2SortedFast(AuUInt32 uCount, AuVecD2 min, AuVecD2 max) = 0; + virtual AuList NextArrayVecD3(AuUInt32 uCount, AuVecD3 boundA, AuVecD3 boundB) = 0; + virtual AuList NextArrayVecD3Fast(AuUInt32 uCount, AuVecD3 boundA, AuVecD3 boundB) = 0; + virtual AuList NextArrayVecD3Sorted(AuUInt32 uCount, AuVecD3 min, AuVecD3 max) = 0; + virtual AuList NextArrayVecD3SortedFast(AuUInt32 uCount, AuVecD3 min, AuVecD3 max) = 0; + virtual AuList NextArrayVecD4(AuUInt32 uCount, AuVecD4 boundA, AuVecD4 boundB) = 0; + virtual AuList NextArrayVecD4Fast(AuUInt32 uCount, AuVecD4 boundA, AuVecD4 boundB) = 0; + virtual AuList NextArrayVecD4Sorted(AuUInt32 uCount, AuVecD4 min, AuVecD4 max) = 0; + virtual AuList NextArrayVecD4SortedFast(AuUInt32 uCount, AuVecD4 min, AuVecD4 max) = 0; virtual AuList NextArrayDouble(AuUInt32 uCount) = 0; virtual AuList NextArrayDecimals(AuUInt32 uCount) = 0; virtual AuList NextArrayDecimalsFast(AuUInt32 uCount) = 0; @@ -123,6 +147,18 @@ namespace Aurora::RNG virtual AuUInt NextArrayVec4FastInView(Memory::MemoryViewWrite write, AuVec4 boundA, AuVec4 boundB) = 0; virtual AuUInt NextArrayVec4SortedInView(Memory::MemoryViewWrite write, AuVec4 min, AuVec4 max) = 0; virtual AuUInt NextArrayVec4SortedFastInView(Memory::MemoryViewWrite write, AuVec4 min, AuVec4 max) = 0; + virtual AuUInt NextArrayVecD2InView(Memory::MemoryViewWrite write, AuVecD2 boundA, AuVecD2 boundB) = 0; + virtual AuUInt NextArrayVecD2FastInView(Memory::MemoryViewWrite write, AuVecD2 boundA, AuVecD2 boundB) = 0; + virtual AuUInt NextArrayVecD2SortedInView(Memory::MemoryViewWrite write, AuVecD2 min, AuVecD2 max) = 0; + virtual AuUInt NextArrayVecD2SortedFastInView(Memory::MemoryViewWrite write, AuVecD2 min, AuVecD2 max) = 0; + virtual AuUInt NextArrayVecD3InView(Memory::MemoryViewWrite write, AuVecD3 boundA, AuVecD3 boundB) = 0; + virtual AuUInt NextArrayVecD3FastInView(Memory::MemoryViewWrite write, AuVecD3 boundA, AuVecD3 boundB) = 0; + virtual AuUInt NextArrayVecD3SortedInView(Memory::MemoryViewWrite write, AuVecD3 min, AuVecD3 max) = 0; + virtual AuUInt NextArrayVecD3SortedFastInView(Memory::MemoryViewWrite write, AuVecD3 min, AuVecD3 max) = 0; + virtual AuUInt NextArrayVecD4InView(Memory::MemoryViewWrite write, AuVecD4 boundA, AuVecD4 boundB) = 0; + virtual AuUInt NextArrayVecD4FastInView(Memory::MemoryViewWrite write, AuVecD4 boundA, AuVecD4 boundB) = 0; + virtual AuUInt NextArrayVecD4SortedInView(Memory::MemoryViewWrite write, AuVecD4 min, AuVecD4 max) = 0; + virtual AuUInt NextArrayVecD4SortedFastInView(Memory::MemoryViewWrite write, AuVecD4 min, AuVecD4 max) = 0; virtual AuUInt NextArrayDoubleInView(Memory::MemoryViewWrite write) = 0; virtual AuUInt NextArrayDecimalsInView(Memory::MemoryViewWrite write) = 0; virtual AuUInt NextArrayDecimalsFastInView(Memory::MemoryViewWrite write) = 0; @@ -207,6 +243,8 @@ namespace Aurora::RNG template inline void ShuffleIterators(T begin, T end) { + // Hitting TLS through the IAT is as dumb as throwing OOM to shuffle + // DUMB either way AU_DEBUG_MEMCRUNCH; auto uCount = std::distance(begin, end); diff --git a/Source/RNG/AuRandomDevice.cpp b/Source/RNG/AuRandomDevice.cpp index 14004b25..ceedaead 100644 --- a/Source/RNG/AuRandomDevice.cpp +++ b/Source/RNG/AuRandomDevice.cpp @@ -12,6 +12,26 @@ namespace Aurora::RNG { static const double kDblEpsilon = 2.2204460492503131e-16; + static thread_local char tlsScratchMemory[2048]; + +#define RNG_BYTES_PROLOGUE \ + AuList rngBytes_; \ + AuMemoryViewWrite rngBytes; + +#define RNG_BYTES_RESIZE(n) \ + if (n * sizeof(AuUInt64) < AuArraySize(tlsScratchMemory)) \ + { \ + rngBytes = AuMemoryViewWrite(tlsScratchMemory).Take(n * sizeof(AuUInt64)); \ + } \ + else \ + { \ + rngBytes_.resize(n); \ + rngBytes = rngBytes_; \ + } + +#define RNG_BYTES_SIZE \ + rngBytes.ToCount() + RandomDevice::RandomDevice() : IO::Adapters::RandomStreamReader(AuUnsafeRaiiToShared(this)) { @@ -415,6 +435,99 @@ namespace Aurora::RNG }; } + AuVecD2 RandomDevice::NextVecD2(AuVecD2 boundA, AuVecD2 boundB) + { + AuVecD2 mins, maxs; + mins[0] = AuMin(boundA[0], boundB[0]); + mins[1] = AuMin(boundA[1], boundB[1]); + maxs[0] = AuMax(boundA[0], boundB[0]); + maxs[1] = AuMax(boundA[1], boundB[1]); + return NextVecD2Sorted(mins, maxs); + } + + AuVecD2 RandomDevice::NextVecD2Sorted(AuVecD2 min, AuVecD2 max) + { + AuVecD2 range; + range[0] = max[0] - min[0]; + range[1] = max[1] - min[1]; + + auto uSeed = this->NextU64(); + auto dComponentA = RngConvertToDecimal(uSeed); + auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + + return AuVecD2 { + (dComponentA * range[0]) + min[0], + (dComponentB * range[1]) + min[1] + }; + } + + AuVecD3 RandomDevice::NextVecD3(AuVecD3 boundA, AuVecD3 boundB) + { + AuVecD3 mins, maxs; + mins[0] = AuMin(boundA[0], boundB[0]); + mins[1] = AuMin(boundA[1], boundB[1]); + mins[2] = AuMin(boundA[2], boundB[2]); + maxs[0] = AuMax(boundA[0], boundB[0]); + maxs[1] = AuMax(boundA[1], boundB[1]); + maxs[2] = AuMax(boundA[2], boundB[2]); + return NextVecD3Sorted(mins, maxs); + } + + AuVecD3 RandomDevice::NextVecD3Sorted(AuVecD3 min, AuVecD3 max) + { + AuVecD3 range; + range[0] = max[0] - min[0]; + range[1] = max[1] - min[1]; + range[2] = max[2] - min[2]; + + auto uSeed = this->NextU64(); + auto dComponentA = RngConvertToDecimal(uSeed); + auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + + return AuVecD3 { + (dComponentA * range[0]) + min[0], + (dComponentB * range[1]) + min[1], + (dComponentC * range[2]) + min[2] + }; + } + + AuVecD4 RandomDevice::NextVecD4(AuVecD4 boundA, AuVecD4 boundB) + { + AuVecD4 mins, maxs; + mins[0] = AuMin(boundA[0], boundB[0]); + mins[1] = AuMin(boundA[1], boundB[1]); + mins[2] = AuMin(boundA[2], boundB[2]); + mins[3] = AuMin(boundA[3], boundB[3]); + maxs[0] = AuMax(boundA[0], boundB[0]); + maxs[1] = AuMax(boundA[1], boundB[1]); + maxs[2] = AuMax(boundA[2], boundB[2]); + maxs[3] = AuMax(boundA[3], boundB[3]); + return NextVecD4Sorted(mins, maxs); + } + + AuVecD4 RandomDevice::NextVecD4Sorted(AuVecD4 min, AuVecD4 max) + { + AuVecD4 range; + range[0] = max[0] - min[0]; + range[1] = max[1] - min[1]; + range[2] = max[2] - min[2]; + range[3] = max[3] - min[3]; + + auto uSeed = this->NextU64(); + auto dComponentA = RngConvertToDecimal(uSeed); + auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + auto dComponentD = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + + return AuVecD4 { + (dComponentA * range[0]) + min[0], + (dComponentB * range[1]) + min[1], + (dComponentC * range[2]) + min[2], + (dComponentD * range[3]) + min[3] + }; + } + double RandomDevice::NextDecimal() { // fast decimals are the default @@ -468,19 +581,18 @@ namespace Aurora::RNG AuUInt RandomDevice::NextArrayI32RangeInView(AuMemoryViewWrite write, AuInt32 iMin, AuInt32 iMax) { - AuList rngBytes; - auto ret = write.Begin(); auto uCount = write.ToCount(); - rngBytes.resize(uCount); - this->Read(rngBytes); + this->Read(write); auto uRange = AuUInt32(iMax - iMin); auto uUpperBound = AuRoundUpPow2(uRange + 1); - for (AU_ITERATE_N(uIndex, rngBytes.size())) + + for (AU_ITERATE_N(uIndex, uCount)) { - auto uMassiveWord = rngBytes[uIndex]; + auto uMassiveWord = write.Begin()[uIndex]; + AuUInt32 uNext {}; while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange) { @@ -520,20 +632,18 @@ namespace Aurora::RNG AuUInt RandomDevice::NextArrayU32RangeInView(AuMemoryViewWrite write, AuUInt32 uMin, AuUInt32 uMax) { - AuList rngBytes; - auto ret = write.Begin(); auto uCount = write.ToCount(); - rngBytes.resize(uCount); - this->Read(rngBytes); + this->Read(write); auto uRange = uMax - uMin; auto uUpperBound = AuRoundUpPow2(uRange + 1); - for (AU_ITERATE_N(uIndex, rngBytes.size())) + for (AU_ITERATE_N(uIndex, uCount)) { - auto uMassiveWord = rngBytes[uIndex]; + auto uMassiveWord = ret[uIndex]; + AuUInt32 uNext {}; while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange) { @@ -594,14 +704,14 @@ namespace Aurora::RNG } else { - AuList rngBytes; + RNG_BYTES_PROLOGUE; - rngBytes.resize(uCount); + RNG_BYTES_RESIZE(uCount); this->Read(rngBytes); - for (AU_ITERATE_N(uIndex, rngBytes.size())) + for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) { - double dValue = RngConvertToDecimal(rngBytes[uIndex]); + double dValue = RngConvertToDecimal(rngBytes.Begin()[uIndex]); dValue *= dRange; dValue += dMin; ret[uIndex] = dValue; @@ -710,27 +820,25 @@ namespace Aurora::RNG AuUInt RandomDevice::NextArrayI64RangeInView(AuMemoryViewWrite write, AuInt64 iMin, AuInt64 iMax) { - AuList rngBytes; - auto ret = write.Begin(); auto uCount = write.ToCount(); - rngBytes.resize(uCount); - this->Read(rngBytes); + this->Read(write); auto uRange = AuUInt64(iMax - iMin); auto uUpperBound = AuRoundUpPow2(uRange + 1); - for (AU_ITERATE_N(uIndex, rngBytes.size())) + for (AU_ITERATE_N(uIndex, uCount)) { - auto uMassiveWord = rngBytes[uIndex]; + auto uMassiveWord = write.Begin()[uIndex]; + AuUInt64 uNext {}; while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange) { uMassiveWord = AuFnv1a64Runtime(&uMassiveWord); } - ret[uIndex] = iMin + uRange; + ret[uIndex] = iMin + uNext; } return uCount; @@ -738,20 +846,18 @@ namespace Aurora::RNG AuUInt RandomDevice::NextArrayU64RangeInView(AuMemoryViewWrite write, AuUInt64 uMin, AuUInt64 uMax) { - AuList rngBytes; - auto ret = write.Begin(); auto uCount = write.ToCount(); - rngBytes.resize(uCount); - this->Read(rngBytes); + this->Read(write); auto uRange = uMax - uMin; auto uUpperBound = AuRoundUpPow2(uRange + 1); - for (AU_ITERATE_N(uIndex, rngBytes.size())) + for (AU_ITERATE_N(uIndex, uCount)) { - auto uMassiveWord = rngBytes[uIndex]; + auto uMassiveWord = ret[uIndex]; + AuUInt64 uNext {}; while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange) { @@ -776,6 +882,7 @@ namespace Aurora::RNG auto &word = ret[i]; word &= uMask; } + return uCount; } @@ -791,6 +898,7 @@ namespace Aurora::RNG auto &word = ret[i]; word &= uMask; } + return uCount; } @@ -831,20 +939,20 @@ namespace Aurora::RNG AuUInt RandomDevice::NextArrayVec2SortedInView(AuMemoryViewWrite write, AuVec2 min, AuVec2 max) { AuVec2 range; - AuList rngBytes; + RNG_BYTES_PROLOGUE; auto ret = write.Begin(); auto uCount = write.ToCount(); - rngBytes.resize(uCount); + RNG_BYTES_RESIZE(uCount); this->Read(rngBytes); range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; - for (AU_ITERATE_N(uIndex, rngBytes.size())) + for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) { - auto uSeed = rngBytes[uIndex]; + auto uSeed = rngBytes.Begin()[uIndex]; auto dComponentA = RngConvertToDecimal(uSeed); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); @@ -910,21 +1018,21 @@ namespace Aurora::RNG AuUInt RandomDevice::NextArrayVec3SortedInView(AuMemoryViewWrite write, AuVec3 min, AuVec3 max) { AuVec3 range; - AuList rngBytes; + RNG_BYTES_PROLOGUE; auto ret = write.Begin(); auto uCount = write.ToCount(); - rngBytes.resize(uCount); + RNG_BYTES_RESIZE(uCount); this->Read(rngBytes); range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; range[2] = max[2] - min[2]; - for (AU_ITERATE_N(uIndex, rngBytes.size())) + for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) { - auto uSeed = rngBytes[uIndex]; + auto uSeed = rngBytes.Begin()[uIndex]; auto dComponentA = RngConvertToDecimal(uSeed); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); @@ -998,12 +1106,12 @@ namespace Aurora::RNG AuUInt RandomDevice::NextArrayVec4SortedInView(AuMemoryViewWrite write, AuVec4 min, AuVec4 max) { AuVec4 range; - AuList rngBytes; + RNG_BYTES_PROLOGUE; auto ret = write.Begin(); auto uCount = write.ToCount(); - rngBytes.resize(uCount); + RNG_BYTES_RESIZE(uCount); this->Read(rngBytes); range[0] = max[0] - min[0]; @@ -1011,9 +1119,9 @@ namespace Aurora::RNG range[2] = max[2] - min[2]; range[3] = max[3] - min[3]; - for (AU_ITERATE_N(uIndex, rngBytes.size())) + for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) { - auto uSeed = rngBytes[uIndex]; + auto uSeed = rngBytes.Begin()[uIndex]; auto dComponentA = RngConvertToDecimal(uSeed); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); @@ -1061,6 +1169,259 @@ namespace Aurora::RNG return uCount; } + AuUInt RandomDevice::NextArrayVecD2InView(AuMemoryViewWrite write, AuVecD2 boundA, AuVecD2 boundB) + { + AuVecD2 mins, maxs; + mins[0] = AuMin(boundA[0], boundB[0]); + mins[1] = AuMin(boundA[1], boundB[1]); + maxs[0] = AuMax(boundA[0], boundB[0]); + maxs[1] = AuMax(boundA[1], boundB[1]); + return NextArrayVecD2SortedInView(write, mins, maxs); + } + + AuUInt RandomDevice::NextArrayVecD2FastInView(AuMemoryViewWrite write, AuVecD2 boundA, AuVecD2 boundB) + { + AuVecD2 mins, maxs; + mins[0] = AuMin(boundA[0], boundB[0]); + mins[1] = AuMin(boundA[1], boundB[1]); + maxs[0] = AuMax(boundA[0], boundB[0]); + maxs[1] = AuMax(boundA[1], boundB[1]); + return NextArrayVecD2SortedFastInView(write, mins, maxs); + } + + AuUInt RandomDevice::NextArrayVecD2SortedInView(AuMemoryViewWrite write, AuVecD2 min, AuVecD2 max) + { + AuVecD2 range; + RNG_BYTES_PROLOGUE; + + auto ret = write.Begin(); + auto uCount = write.ToCount(); + + RNG_BYTES_RESIZE(uCount); + this->Read(rngBytes); + + range[0] = max[0] - min[0]; + range[1] = max[1] - min[1]; + + for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) + { + auto uSeed = rngBytes.Begin()[uIndex]; + auto dComponentA = RngConvertToDecimal(uSeed); + auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + + ret[uIndex] = AuVecD2 { + (dComponentA * range[0]) + min[0], + (dComponentB * range[1]) + min[1] + }; + } + + return uCount; + } + + AuUInt RandomDevice::NextArrayVecD2SortedFastInView(AuMemoryViewWrite write, AuVecD2 min, AuVecD2 max) + { + AuVecD2 range; + + auto ret = write.Begin(); + auto uCount = write.ToCount(); + + range[0] = max[0] - min[0]; + range[1] = max[1] - min[1]; + + AuUInt64 uSeed = this->NextU64(); + + for (AU_ITERATE_N(uIndex, uCount)) + { + auto dComponentA = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + + ret[uIndex] = AuVecD2 { + (dComponentA * range[0]) + min[0], + (dComponentB * range[1]) + min[1] + }; + } + + return uCount; + } + + AuUInt RandomDevice::NextArrayVecD3InView(AuMemoryViewWrite write, AuVecD3 boundA, AuVecD3 boundB) + { + AuVecD3 mins, maxs; + mins[0] = AuMin(boundA[0], boundB[0]); + mins[1] = AuMin(boundA[1], boundB[1]); + mins[2] = AuMin(boundA[2], boundB[2]); + maxs[0] = AuMax(boundA[0], boundB[0]); + maxs[1] = AuMax(boundA[1], boundB[1]); + maxs[2] = AuMax(boundA[2], boundB[2]); + return NextArrayVecD3SortedInView(write, mins, maxs); + } + + AuUInt RandomDevice::NextArrayVecD3FastInView(AuMemoryViewWrite write, AuVecD3 boundA, AuVecD3 boundB) + { + AuVecD3 mins, maxs; + mins[0] = AuMin(boundA[0], boundB[0]); + mins[1] = AuMin(boundA[1], boundB[1]); + mins[2] = AuMin(boundA[2], boundB[2]); + maxs[0] = AuMax(boundA[0], boundB[0]); + maxs[1] = AuMax(boundA[1], boundB[1]); + maxs[2] = AuMax(boundA[2], boundB[2]); + return NextArrayVecD3SortedFastInView(write, mins, maxs); + } + + AuUInt RandomDevice::NextArrayVecD3SortedInView(AuMemoryViewWrite write, AuVecD3 min, AuVecD3 max) + { + AuVecD3 range; + RNG_BYTES_PROLOGUE; + + auto ret = write.Begin(); + auto uCount = write.ToCount(); + + RNG_BYTES_RESIZE(uCount); + this->Read(rngBytes); + + range[0] = max[0] - min[0]; + range[1] = max[1] - min[1]; + range[2] = max[2] - min[2]; + + for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) + { + auto uSeed = rngBytes.Begin()[uIndex]; + auto dComponentA = RngConvertToDecimal(uSeed); + auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + + ret[uIndex] = AuVecD3 { + (dComponentA * range[0]) + min[0], + (dComponentB * range[1]) + min[1], + (dComponentC * range[2]) + min[2] + }; + } + + return uCount; + } + + AuUInt RandomDevice::NextArrayVecD3SortedFastInView(AuMemoryViewWrite write, AuVecD3 min, AuVecD3 max) + { + AuVecD3 range; + auto ret = write.Begin(); + auto uCount = write.ToCount(); + + range[0] = max[0] - min[0]; + range[1] = max[1] - min[1]; + range[2] = max[2] - min[2]; + + AuUInt64 uSeed = this->NextU64(); + + for (AU_ITERATE_N(uIndex, uCount)) + { + auto dComponentA = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + + ret[uIndex] = AuVecD3 { + (dComponentA * range[0]) + min[0], + (dComponentB * range[1]) + min[1], + (dComponentC * range[2]) + min[2] + }; + } + + return uCount; + } + + AuUInt RandomDevice::NextArrayVecD4InView(AuMemoryViewWrite write, AuVecD4 boundA, AuVecD4 boundB) + { + AuVecD4 mins, maxs; + mins[0] = AuMin(boundA[0], boundB[0]); + mins[1] = AuMin(boundA[1], boundB[1]); + mins[2] = AuMin(boundA[2], boundB[2]); + mins[3] = AuMin(boundA[3], boundB[3]); + maxs[0] = AuMax(boundA[0], boundB[0]); + maxs[1] = AuMax(boundA[1], boundB[1]); + maxs[2] = AuMax(boundA[2], boundB[2]); + maxs[3] = AuMax(boundA[3], boundB[3]); + return NextArrayVecD4SortedInView(write, mins, maxs); + } + + AuUInt RandomDevice::NextArrayVecD4FastInView(AuMemoryViewWrite write, AuVecD4 boundA, AuVecD4 boundB) + { + AuVecD4 mins, maxs; + mins[0] = AuMin(boundA[0], boundB[0]); + mins[1] = AuMin(boundA[1], boundB[1]); + mins[2] = AuMin(boundA[2], boundB[2]); + mins[3] = AuMin(boundA[3], boundB[3]); + maxs[0] = AuMax(boundA[0], boundB[0]); + maxs[1] = AuMax(boundA[1], boundB[1]); + maxs[2] = AuMax(boundA[2], boundB[2]); + maxs[3] = AuMax(boundA[3], boundB[3]); + return NextArrayVecD4SortedFastInView(write, mins, maxs); + } + + AuUInt RandomDevice::NextArrayVecD4SortedInView(AuMemoryViewWrite write, AuVecD4 min, AuVecD4 max) + { + AuVecD4 range; + RNG_BYTES_PROLOGUE; + + auto ret = write.Begin(); + auto uCount = write.ToCount(); + + RNG_BYTES_RESIZE(uCount); + this->Read(rngBytes); + + range[0] = max[0] - min[0]; + range[1] = max[1] - min[1]; + range[2] = max[2] - min[2]; + range[3] = max[3] - min[3]; + + for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) + { + auto uSeed = rngBytes.Begin()[uIndex]; + auto dComponentA = RngConvertToDecimal(uSeed); + auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + auto dComponentD = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + + ret[uIndex] = AuVecD4 { + (dComponentA * range[0]) + min[0], + (dComponentB * range[1]) + min[1], + (dComponentC * range[2]) + min[2], + (dComponentD * range[3]) + min[3] + }; + } + + return uCount; + } + + AuUInt RandomDevice::NextArrayVecD4SortedFastInView(AuMemoryViewWrite write, AuVecD4 min, AuVecD4 max) + { + AuVecD4 range; + auto ret = write.Begin(); + auto uCount = write.ToCount(); + + range[0] = max[0] - min[0]; + range[1] = max[1] - min[1]; + range[2] = max[2] - min[2]; + range[3] = max[3] - min[3]; + + AuUInt64 uSeed = this->NextU64(); + + for (AU_ITERATE_N(uIndex, uCount)) + { + auto dComponentA = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + auto dComponentD = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); + + ret[uIndex] = AuVecD4 { + (dComponentA * range[0]) + min[0], + (dComponentB * range[1]) + min[1], + (dComponentC * range[2]) + min[2], + (dComponentD * range[3]) + min[3] + }; + } + + return uCount; + } + AuUInt RandomDevice::NextArrayDoubleInView(AuMemoryViewWrite write) { auto ret = write.Begin(); @@ -1086,14 +1447,14 @@ namespace Aurora::RNG } else { - AuList rngBytes; + RNG_BYTES_PROLOGUE; - rngBytes.resize(uCount); + RNG_BYTES_RESIZE(uCount); this->Read(rngBytes); - for (AU_ITERATE_N(uIndex, rngBytes.size())) + for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) { - ret[uIndex] = RngConvertToDecimal(rngBytes[uIndex]); + ret[uIndex] = RngConvertToDecimal(rngBytes.Begin()[uIndex]); } } @@ -1394,6 +1755,102 @@ namespace Aurora::RNG return ret; } + AuList RandomDevice::NextArrayVecD2(AuUInt32 uCount, AuVecD2 boundA, AuVecD2 boundB) + { + AuList ret; + ret.resize(uCount); + (void)NextArrayVecD2InView(ret, boundA, boundB); + return ret; + } + + AuList RandomDevice::NextArrayVecD2Fast(AuUInt32 uCount, AuVecD2 boundA, AuVecD2 boundB) + { + AuList ret; + ret.resize(uCount); + (void)NextArrayVecD2FastInView(ret, boundA, boundB); + return ret; + } + + AuList RandomDevice::NextArrayVecD2Sorted(AuUInt32 uCount, AuVecD2 min, AuVecD2 max) + { + AuList ret; + ret.resize(uCount); + (void)NextArrayVecD2SortedInView(ret, min, max); + return ret; + } + + AuList RandomDevice::NextArrayVecD2SortedFast(AuUInt32 uCount, AuVecD2 min, AuVecD2 max) + { + AuList ret; + ret.resize(uCount); + (void)NextArrayVecD2SortedFastInView(ret, min, max); + return ret; + } + + AuList RandomDevice::NextArrayVecD3(AuUInt32 uCount, AuVecD3 boundA, AuVecD3 boundB) + { + AuList ret; + ret.resize(uCount); + (void)NextArrayVecD3InView(ret, boundA, boundB); + return ret; + } + + AuList RandomDevice::NextArrayVecD3Fast(AuUInt32 uCount, AuVecD3 boundA, AuVecD3 boundB) + { + AuList ret; + ret.resize(uCount); + (void)NextArrayVecD3FastInView(ret, boundA, boundB); + return ret; + } + + AuList RandomDevice::NextArrayVecD3Sorted(AuUInt32 uCount, AuVecD3 min, AuVecD3 max) + { + AuList ret; + ret.resize(uCount); + (void)NextArrayVecD3SortedInView(ret, min, max); + return ret; + } + + AuList RandomDevice::NextArrayVecD3SortedFast(AuUInt32 uCount, AuVecD3 min, AuVecD3 max) + { + AuList ret; + ret.resize(uCount); + (void)NextArrayVecD3SortedFastInView(ret, min, max); + return ret; + } + + AuList RandomDevice::NextArrayVecD4(AuUInt32 uCount, AuVecD4 boundA, AuVecD4 boundB) + { + AuList ret; + ret.resize(uCount); + (void)NextArrayVecD4InView(ret, boundA, boundB); + return ret; + } + + AuList RandomDevice::NextArrayVecD4Fast(AuUInt32 uCount, AuVecD4 boundA, AuVecD4 boundB) + { + AuList ret; + ret.resize(uCount); + (void)NextArrayVecD4FastInView(ret, boundA, boundB); + return ret; + } + + AuList RandomDevice::NextArrayVecD4Sorted(AuUInt32 uCount, AuVecD4 min, AuVecD4 max) + { + AuList ret; + ret.resize(uCount); + (void)NextArrayVecD4SortedInView(ret, min, max); + return ret; + } + + AuList RandomDevice::NextArrayVecD4SortedFast(AuUInt32 uCount, AuVecD4 min, AuVecD4 max) + { + AuList ret; + ret.resize(uCount); + (void)NextArrayVecD4SortedFastInView(ret, min, max); + return ret; + } + AuList RandomDevice::NextArrayDouble(AuUInt32 uCount) { AuList ret; diff --git a/Source/RNG/AuRandomDevice.hpp b/Source/RNG/AuRandomDevice.hpp index dafe42c4..8318c576 100644 --- a/Source/RNG/AuRandomDevice.hpp +++ b/Source/RNG/AuRandomDevice.hpp @@ -37,6 +37,12 @@ namespace Aurora::RNG AuVec4 NextVec4Sorted(AuVec4 min, AuVec4 max) override; AuInt32 NextI32Range(AuInt32 iMin, AuInt32 iMax) override; AuUInt32 NextU32Range(AuUInt32 uMin, AuUInt32 uMax) override; + AuVecD2 NextVecD2(AuVecD2 boundA, AuVecD2 boundB) override; + AuVecD2 NextVecD2Sorted(AuVecD2 min, AuVecD2 max) override; + AuVecD3 NextVecD3(AuVecD3 boundA, AuVecD3 boundB) override; + AuVecD3 NextVecD3Sorted(AuVecD3 min, AuVecD3 max) override; + AuVecD4 NextVecD4(AuVecD4 boundA, AuVecD4 boundB) override; + AuVecD4 NextVecD4Sorted(AuVecD4 min, AuVecD4 max) override; AuList NextArrayI32Range(AuUInt32 uCount, AuInt32 iMin, AuInt32 iMax) override; AuList NextArrayU32Range(AuUInt32 uCount, AuUInt32 uMin, AuUInt32 uMax) override; AuList NextArrayI64Range(AuUInt32 uCount, AuInt64 uMin, AuInt64 uMax) override; @@ -61,6 +67,18 @@ namespace Aurora::RNG AuList NextArrayVec4Fast(AuUInt32 uCount, AuVec4 boundA, AuVec4 boundB) override; AuList NextArrayVec4Sorted(AuUInt32 uCount, AuVec4 min, AuVec4 max) override; AuList NextArrayVec4SortedFast(AuUInt32 uCount, AuVec4 min, AuVec4 max) override; + AuList NextArrayVecD2(AuUInt32 uCount, AuVecD2 boundA, AuVecD2 boundB) override; + AuList NextArrayVecD2Fast(AuUInt32 uCount, AuVecD2 boundA, AuVecD2 boundB) override; + AuList NextArrayVecD2Sorted(AuUInt32 uCount, AuVecD2 min, AuVecD2 max) override; + AuList NextArrayVecD2SortedFast(AuUInt32 uCount, AuVecD2 min, AuVecD2 max) override; + AuList NextArrayVecD3(AuUInt32 uCount, AuVecD3 boundA, AuVecD3 boundB) override; + AuList NextArrayVecD3Fast(AuUInt32 uCount, AuVecD3 boundA, AuVecD3 boundB) override; + AuList NextArrayVecD3Sorted(AuUInt32 uCount, AuVecD3 min, AuVecD3 max) override; + AuList NextArrayVecD3SortedFast(AuUInt32 uCount, AuVecD3 min, AuVecD3 max) override; + AuList NextArrayVecD4(AuUInt32 uCount, AuVecD4 boundA, AuVecD4 boundB) override; + AuList NextArrayVecD4Fast(AuUInt32 uCount, AuVecD4 boundA, AuVecD4 boundB) override; + AuList NextArrayVecD4Sorted(AuUInt32 uCount, AuVecD4 min, AuVecD4 max) override; + AuList NextArrayVecD4SortedFast(AuUInt32 uCount, AuVecD4 min, AuVecD4 max) override; AuList NextArrayDouble(AuUInt32 uCount) override; AuList NextArrayDecimals(AuUInt32 uCount) override; AuList NextArrayDecimalsFast(AuUInt32 uCount) override; @@ -97,6 +115,18 @@ namespace Aurora::RNG AuUInt NextArrayVec4FastInView(Memory::MemoryViewWrite write, AuVec4 boundA, AuVec4 boundB) override; AuUInt NextArrayVec4SortedInView(Memory::MemoryViewWrite write, AuVec4 min, AuVec4 max) override; AuUInt NextArrayVec4SortedFastInView(Memory::MemoryViewWrite write, AuVec4 min, AuVec4 max) override; + AuUInt NextArrayVecD2InView(Memory::MemoryViewWrite write, AuVecD2 boundA, AuVecD2 boundB) override; + AuUInt NextArrayVecD2FastInView(Memory::MemoryViewWrite write, AuVecD2 boundA, AuVecD2 boundB) override; + AuUInt NextArrayVecD2SortedInView(Memory::MemoryViewWrite write, AuVecD2 min, AuVecD2 max) override; + AuUInt NextArrayVecD2SortedFastInView(Memory::MemoryViewWrite write, AuVecD2 min, AuVecD2 max) override; + AuUInt NextArrayVecD3InView(Memory::MemoryViewWrite write, AuVecD3 boundA, AuVecD3 boundB) override; + AuUInt NextArrayVecD3FastInView(Memory::MemoryViewWrite write, AuVecD3 boundA, AuVecD3 boundB) override; + AuUInt NextArrayVecD3SortedInView(Memory::MemoryViewWrite write, AuVecD3 min, AuVecD3 max) override; + AuUInt NextArrayVecD3SortedFastInView(Memory::MemoryViewWrite write, AuVecD3 min, AuVecD3 max) override; + AuUInt NextArrayVecD4InView(Memory::MemoryViewWrite write, AuVecD4 boundA, AuVecD4 boundB) override; + AuUInt NextArrayVecD4FastInView(Memory::MemoryViewWrite write, AuVecD4 boundA, AuVecD4 boundB) override; + AuUInt NextArrayVecD4SortedInView(Memory::MemoryViewWrite write, AuVecD4 min, AuVecD4 max) override; + AuUInt NextArrayVecD4SortedFastInView(Memory::MemoryViewWrite write, AuVecD4 min, AuVecD4 max) override; AuUInt NextArrayDoubleInView(Memory::MemoryViewWrite write) override; AuUInt NextArrayDecimalsInView(Memory::MemoryViewWrite write) override; AuUInt NextArrayDecimalsFastInView(Memory::MemoryViewWrite write) override;