Jamie Reece Wilson
77546b5098
[*] Improve: IRandomDevice internal allocations when handling vector arrays [*] Fix: NextArrayI64RangeInView
1920 lines
58 KiB
C++
1920 lines
58 KiB
C++
/***
|
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: AuRandomDevice.cpp
|
|
Date: 2021-9-3
|
|
Author: Reece
|
|
***/
|
|
#include <AuroraRuntime.hpp>
|
|
#include "AuRandomDevice.hpp"
|
|
|
|
namespace Aurora::RNG
|
|
{
|
|
static const double kDblEpsilon = 2.2204460492503131e-16;
|
|
|
|
static thread_local char tlsScratchMemory[2048];
|
|
|
|
#define RNG_BYTES_PROLOGUE \
|
|
AuList<AuUInt64> 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<AuUInt64>()
|
|
|
|
RandomDevice::RandomDevice() :
|
|
IO::Adapters::RandomStreamReader(AuUnsafeRaiiToShared(this))
|
|
{
|
|
|
|
}
|
|
|
|
RandomDevice::RandomDevice(const RandomDef &def) :
|
|
IO::Adapters::RandomStreamReader(AuUnsafeRaiiToShared(this))
|
|
{
|
|
this->Init(def);
|
|
}
|
|
|
|
void RandomDevice::Init(const RandomDef &def)
|
|
{
|
|
this->def_ = def;
|
|
|
|
// Gross...
|
|
if (!def.bSecure)
|
|
{
|
|
if (def.seed)
|
|
{
|
|
this->fast_ = AuMove(WELL_SeedRand(def.seed.value()));
|
|
}
|
|
else if (def.seed64)
|
|
{
|
|
this->fast_ = AuMove(WELL_SeedRand64(def.seed64.value()));
|
|
}
|
|
else if (def.seedMassive)
|
|
{
|
|
this->fast_ = AuMove(WELL_SeedRandBig64(def.seedMassive.value()));
|
|
}
|
|
else
|
|
{
|
|
RNG::RngFillArray<false>(this->fast_.state);
|
|
}
|
|
}
|
|
// secure rng requires no init -> we just passthrough to the global ReadSecureRNG function
|
|
}
|
|
|
|
void RandomDevice::Read(Memory::MemoryViewWrite view)
|
|
{
|
|
if (!view)
|
|
{
|
|
SysPushErrorArg();
|
|
return;
|
|
}
|
|
|
|
if (this->def_.bSecure)
|
|
{
|
|
ReadSecureRNG(view);
|
|
}
|
|
else
|
|
{
|
|
WELL_NextBytes(&this->fast_, view.ptr, AuUInt32(view.length));
|
|
}
|
|
}
|
|
|
|
AuString RandomDevice::NextString(AuUInt32 uLength, ERngStringCharacters type)
|
|
{
|
|
AuString ret(uLength, '\00');
|
|
NextString(ret.data(), AuUInt32(ret.size()), type);
|
|
return ret;
|
|
}
|
|
|
|
static double RngConvertToDecimal(AuUInt64 uLargeInt)
|
|
{
|
|
AuUInt64 qwValue = (uLargeInt & 0xFFFFFFFFFFFFFull) | 0x3FF0000000000000ull;
|
|
return *(double *)(&qwValue) - 1.0;
|
|
}
|
|
|
|
void RandomDevice::NextString(char *pString, AuUInt32 uLength, ERngStringCharacters type)
|
|
{
|
|
static AuPair<const char *, int> rngSequence[static_cast<int>(ERngStringCharacters::eEnumCount)] =
|
|
{
|
|
{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 52},
|
|
{"abcdefghijklmnopqrstuvwxyz", 26},
|
|
{"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26},
|
|
{"1234567890", 10},
|
|
{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 62},
|
|
{"abcdefghijklmnopqrstuvwxyz1234567890", 36},
|
|
{"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 36},
|
|
{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890=-+!$%^*.[];:", 75}
|
|
};
|
|
|
|
if (!pString)
|
|
{
|
|
SysPushErrorArg();
|
|
return;
|
|
}
|
|
|
|
Read(AuMemoryViewWrite { pString, uLength });
|
|
|
|
if (!ERngStringCharactersIsValid(type))
|
|
{
|
|
SysPushErrorArg("NextString was called with an invalid ERngStringCharacters {}", (AuUInt)type);
|
|
type = ERngStringCharacters::eAlphaNumericCharacters; // guess we cant just return false
|
|
}
|
|
|
|
const auto &pair = rngSequence[static_cast<int>(type)];
|
|
|
|
for (auto i = 0u; i < uLength; i++)
|
|
{
|
|
auto uUpperBound = AuRoundUpPow2(pair.second);
|
|
AuUInt8 uNext {};
|
|
auto uWord = reinterpret_cast<const AuUInt8 *>(pString)[i];
|
|
while ((uNext = (uWord & (uUpperBound - 1))) >= pair.second)
|
|
{
|
|
uWord = AuFnv1a32Runtime(&uWord, sizeof(uWord));
|
|
}
|
|
pString[i] = pair.first[uNext];
|
|
}
|
|
}
|
|
|
|
AuUInt8 RandomDevice::NextByte()
|
|
{
|
|
if (this->def_.bSecure)
|
|
{
|
|
AuUInt8 uRet {};
|
|
ReadSecureRNG({ &uRet, 1 });
|
|
return uRet;
|
|
}
|
|
else
|
|
{
|
|
return AuUInt8(WELL_NextLong(&this->fast_) & 0xFF);
|
|
}
|
|
}
|
|
|
|
bool RandomDevice::NextBoolean()
|
|
{
|
|
if (this->def_.bSecure)
|
|
{
|
|
AuUInt8 uRet {};
|
|
ReadSecureRNG({ &uRet, 1 });
|
|
return bool(uRet & 0x1);
|
|
}
|
|
else
|
|
{
|
|
return bool(WELL_NextLong(&this->fast_) & 0x1);
|
|
}
|
|
}
|
|
|
|
AuUInt32 RandomDevice::NextU32()
|
|
{
|
|
if (this->def_.bSecure)
|
|
{
|
|
AuUInt32 uRet {};
|
|
ReadSecureRNG({ &uRet, 4 });
|
|
return uRet;
|
|
}
|
|
else
|
|
{
|
|
return WELL_NextLong(&this->fast_);
|
|
}
|
|
}
|
|
|
|
AuUInt64 RandomDevice::NextU64()
|
|
{
|
|
if (this->def_.bSecure)
|
|
{
|
|
AuUInt64 uRet {};
|
|
ReadSecureRNG({ &uRet, 8 });
|
|
return uRet;
|
|
}
|
|
else
|
|
{
|
|
return NextFillTmpl<AuUInt64>();
|
|
}
|
|
}
|
|
|
|
AuInt32 RandomDevice::NextI32Range(AuInt32 iMin, AuInt32 iMax)
|
|
{
|
|
auto uRange = AuUInt32(iMax - iMin);
|
|
auto uMassiveWord = NextU32();
|
|
auto uUpperBound = AuRoundUpPow2(uRange + 1);
|
|
AuUInt32 uNext {};
|
|
while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange)
|
|
{
|
|
uMassiveWord = AuFnv1a32Runtime<sizeof(uMassiveWord)>(&uMassiveWord);
|
|
}
|
|
return iMin + uNext;
|
|
}
|
|
|
|
AuUInt32 RandomDevice::NextU32Range(AuUInt32 uMin, AuUInt32 uMax)
|
|
{
|
|
auto uRange = uMax - uMin;
|
|
auto uMassiveWord = NextU32();
|
|
auto uUpperBound = AuRoundUpPow2(uRange + 1);
|
|
AuUInt32 uNext {};
|
|
while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange)
|
|
{
|
|
uMassiveWord = AuFnv1a32Runtime<sizeof(uMassiveWord)>(&uMassiveWord);
|
|
}
|
|
return uMin + uNext;
|
|
}
|
|
|
|
// Source: https://stackoverflow.com/a/5016867
|
|
bool RandomDevice::DecGeometric(int x)
|
|
{
|
|
if (x <= 0)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
while (true)
|
|
{
|
|
auto r = this->NextByte();
|
|
|
|
if (x < 8)
|
|
{
|
|
return (r & ((1 << x) - 1)) == 0;
|
|
}
|
|
else if (r != 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
x -= 8;
|
|
}
|
|
}
|
|
|
|
// Source: https://stackoverflow.com/a/5016867
|
|
double RandomDevice::UniformFloatInRange(double udMin, double udMax)
|
|
{
|
|
// No....
|
|
#if defined(AURNG_USE_GARBAGE_DECIMALS)
|
|
return (double(this->NextU32()) * (double(1.0) / double(AuNumericLimits<AuUInt32>::max()))) * udMax;
|
|
|
|
// No....
|
|
#elif defined(AURNG_USE_UNIFORM_DECIMALS)
|
|
|
|
union
|
|
{
|
|
double f;
|
|
AuUInt64 u;
|
|
} convert;
|
|
|
|
convert.f = udMin;
|
|
auto uABits = convert.u;
|
|
convert.f = udMax;
|
|
auto uBBits = convert.u;
|
|
|
|
auto uMask = uBBits - uABits;
|
|
uMask |= uMask >> 1;
|
|
uMask |= uMask >> 2;
|
|
uMask |= uMask >> 4;
|
|
uMask |= uMask >> 8;
|
|
uMask |= uMask >> 16;
|
|
uMask |= uMask >> 32;
|
|
|
|
int bExp {};
|
|
frexp(udMax, &bExp);
|
|
|
|
while (true)
|
|
{
|
|
int iXExp {};
|
|
double x;
|
|
|
|
auto uXBits = this->NextU64();
|
|
uXBits &= uMask;
|
|
uXBits += uABits;
|
|
if (uXBits >= uBBits)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
convert.u = uXBits;
|
|
x = convert.f;
|
|
frexp(x, &iXExp);
|
|
|
|
if (DecGeometric(bExp - iXExp))
|
|
{
|
|
return x;
|
|
}
|
|
}
|
|
|
|
// Yes...
|
|
#else
|
|
#if !defined(AURNG_USE_FAST_DECIMALS)
|
|
#define AURNG_USE_FAST_DECIMALS
|
|
return 0.0;
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
AuUInt64 RandomDevice::NextU64Range(AuUInt64 uMin, AuUInt64 uMax)
|
|
{
|
|
auto uRange = uMax - uMin;
|
|
auto uMassiveWord = NextU64();
|
|
auto uUpperBound = AuRoundUpPow2(uRange + 1);
|
|
AuUInt32 uNext {};
|
|
while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange)
|
|
{
|
|
uMassiveWord = AuFnv1a64Runtime<sizeof(uMassiveWord)>(&uMassiveWord);
|
|
}
|
|
return uMin + uNext;
|
|
}
|
|
|
|
AuInt64 RandomDevice::NextI64Range(AuInt64 iMin, AuInt64 iMax)
|
|
{
|
|
auto uRange = AuUInt64(iMax - iMin);
|
|
auto uMassiveWord = NextU64();
|
|
auto uUpperBound = AuRoundUpPow2(uRange + 1);
|
|
AuUInt32 uNext {};
|
|
while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange)
|
|
{
|
|
uMassiveWord = AuFnv1a64Runtime<sizeof(uMassiveWord)>(&uMassiveWord);
|
|
}
|
|
return iMin + uNext;
|
|
}
|
|
|
|
AuVec2 RandomDevice::NextVec2(AuVec2 boundA, AuVec2 boundB)
|
|
{
|
|
AuVec2 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 NextVec2Sorted(mins, maxs);
|
|
}
|
|
|
|
AuVec2 RandomDevice::NextVec2Sorted(AuVec2 min, AuVec2 max)
|
|
{
|
|
AuVec2 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 AuVec2 {
|
|
float((dComponentA * range[0]) + min[0]),
|
|
float((dComponentB * range[1]) + min[1])
|
|
};
|
|
}
|
|
|
|
AuVec3 RandomDevice::NextVec3(AuVec3 boundA, AuVec3 boundB)
|
|
{
|
|
AuVec3 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 NextVec3Sorted(mins, maxs);
|
|
}
|
|
|
|
AuVec3 RandomDevice::NextVec3Sorted(AuVec3 min, AuVec3 max)
|
|
{
|
|
AuVec3 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 AuVec3 {
|
|
float((dComponentA * range[0]) + min[0]),
|
|
float((dComponentB * range[1]) + min[1]),
|
|
float((dComponentC * range[2]) + min[2])
|
|
};
|
|
}
|
|
|
|
AuVec4 RandomDevice::NextVec4(AuVec4 boundA, AuVec4 boundB)
|
|
{
|
|
AuVec4 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 NextVec4Sorted(mins, maxs);
|
|
}
|
|
|
|
AuVec4 RandomDevice::NextVec4Sorted(AuVec4 min, AuVec4 max)
|
|
{
|
|
AuVec4 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 AuVec4 {
|
|
float((dComponentA * range[0]) + min[0]),
|
|
float((dComponentB * range[1]) + min[1]),
|
|
float((dComponentC * range[2]) + min[2]),
|
|
float((dComponentD * range[3]) + min[3])
|
|
};
|
|
}
|
|
|
|
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
|
|
#if defined(AURNG_USE_FAST_DECIMALS)
|
|
return RngConvertToDecimal(this->NextU64());
|
|
#elif defined(AURNG_USE_UNIFORM_DECIMALS)
|
|
return this->UniformFloatInRange(kDblEpsilon, 1.0 + kDblEpsilon) - kDblEpsilon;
|
|
#elif defined(AURNG_USE_GARBAGE_DECIMALS)
|
|
return this->UniformFloatInRange(0, 1.0);
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
AuUInt32 RandomDevice::NextIndex(AuUInt32 uCount /* = max + 1*/)
|
|
{
|
|
auto uMassiveWord = NextU32();
|
|
auto uUpperBound = AuRoundUpPow2(uCount);
|
|
AuUInt32 uNext {};
|
|
while ((uNext = (uMassiveWord & (uUpperBound - 1))) >= uCount)
|
|
{
|
|
uMassiveWord = AuFnv1a32Runtime<sizeof(uMassiveWord)>(&uMassiveWord);
|
|
}
|
|
return uNext;
|
|
}
|
|
|
|
double RandomDevice::NextNumber(double dMin, double dMax)
|
|
{
|
|
auto dRange = dMax - dMin;
|
|
#if defined(AURNG_USE_FAST_DECIMALS)
|
|
return (this->NextDecimal() * dRange) + dMin;
|
|
#else
|
|
// potentially not deterministic, thanks to runtime/platform deviations
|
|
return this->UniformFloatInRange(kDblEpsilon, dRange + kDblEpsilon) + dMin - kDblEpsilon;
|
|
#endif
|
|
}
|
|
|
|
uuids::uuid RandomDevice::NextUUID()
|
|
{
|
|
AuUInt8 bytes[16];
|
|
this->Read(bytes);
|
|
|
|
bytes[8] &= 0xBF;
|
|
bytes[8] |= 0x80;
|
|
|
|
bytes[6] &= 0x4F;
|
|
bytes[6] |= 0x40;
|
|
|
|
return uuids::uuid { bytes, bytes + 16 };
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayI32RangeInView(AuMemoryViewWrite write, AuInt32 iMin, AuInt32 iMax)
|
|
{
|
|
auto ret = write.Begin<AuInt32>();
|
|
auto uCount = write.ToCount<AuInt32>();
|
|
|
|
this->Read(write);
|
|
|
|
auto uRange = AuUInt32(iMax - iMin);
|
|
auto uUpperBound = AuRoundUpPow2(uRange + 1);
|
|
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
auto uMassiveWord = write.Begin<AuUInt32>()[uIndex];
|
|
|
|
AuUInt32 uNext {};
|
|
while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange)
|
|
{
|
|
uMassiveWord = AuFnv1a32Runtime<sizeof(uMassiveWord)>(&uMassiveWord);
|
|
}
|
|
|
|
ret[uIndex] = iMin + uNext;
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayI32RangeFastInView(AuMemoryViewWrite write, AuInt32 iMin, AuInt32 iMax)
|
|
{
|
|
auto ret = write.Begin<AuInt32>();
|
|
auto uCount = write.ToCount<AuInt32>();
|
|
|
|
auto uRange = AuUInt32(iMax - iMin);
|
|
auto uUpperBound = AuRoundUpPow2(uRange + 1);
|
|
auto uSeed = this->NextU32();
|
|
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
AuUInt32 uNext {};
|
|
|
|
uSeed = AuFnv1a32Runtime<sizeof(uSeed)>(&uSeed);
|
|
while ((uNext = (uSeed & (uUpperBound - 1))) > uRange)
|
|
{
|
|
uSeed = AuFnv1a32Runtime<sizeof(uSeed)>(&uSeed);
|
|
}
|
|
|
|
ret[uIndex] = iMin + uNext;
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayU32RangeInView(AuMemoryViewWrite write, AuUInt32 uMin, AuUInt32 uMax)
|
|
{
|
|
auto ret = write.Begin<AuUInt32>();
|
|
auto uCount = write.ToCount<AuUInt32>();
|
|
|
|
this->Read(write);
|
|
|
|
auto uRange = uMax - uMin;
|
|
auto uUpperBound = AuRoundUpPow2(uRange + 1);
|
|
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
auto uMassiveWord = ret[uIndex];
|
|
|
|
AuUInt32 uNext {};
|
|
while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange)
|
|
{
|
|
uMassiveWord = AuFnv1a32Runtime<sizeof(uMassiveWord)>(&uMassiveWord);
|
|
}
|
|
|
|
ret[uIndex] = uMin + uNext;
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayU32RangeFastInView(AuMemoryViewWrite write, AuUInt32 uMin, AuUInt32 uMax)
|
|
{
|
|
auto ret = write.Begin<AuUInt32>();
|
|
auto uCount = write.ToCount<AuUInt32>();
|
|
|
|
auto uRange = uMax - uMin;
|
|
auto uUpperBound = AuRoundUpPow2(uRange + 1);
|
|
auto uSeed = this->NextU32();
|
|
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
AuUInt32 uNext {};
|
|
|
|
uSeed = AuFnv1a32Runtime<sizeof(uSeed)>(&uSeed);
|
|
while ((uNext = (uSeed & (uUpperBound - 1))) > uRange)
|
|
{
|
|
uSeed = AuFnv1a32Runtime<sizeof(uSeed)>(&uSeed);
|
|
}
|
|
|
|
ret[uIndex] = uMin + uNext;
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayDoubleRangeInView(AuMemoryViewWrite write, double dMin, double dMax)
|
|
{
|
|
#if defined(AURNG_USE_FAST_DECIMALS)
|
|
|
|
auto ret = write.Begin<double>();
|
|
auto uCount = write.ToCount<double>();
|
|
|
|
double dRange = dMax - dMin;
|
|
|
|
if constexpr (sizeof(double) == sizeof(AuUInt64))
|
|
{
|
|
this->Read(write);
|
|
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
double dValue = RngConvertToDecimal(*(AuUInt64 *)&ret[uIndex]);
|
|
dValue *= dRange;
|
|
dValue += dMin;
|
|
ret[uIndex] = dValue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RNG_BYTES_PROLOGUE;
|
|
|
|
RNG_BYTES_RESIZE(uCount);
|
|
this->Read(rngBytes);
|
|
|
|
for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE))
|
|
{
|
|
double dValue = RngConvertToDecimal(rngBytes.Begin<AuUInt64>()[uIndex]);
|
|
dValue *= dRange;
|
|
dValue += dMin;
|
|
ret[uIndex] = dValue;
|
|
}
|
|
}
|
|
|
|
return uCount;
|
|
#else
|
|
auto ret = write.Begin<double>();
|
|
auto uCount = write.ToCount<double>();
|
|
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
ret[uIndex] = this->NextNumber(dMin, dMax);
|
|
}
|
|
|
|
return uCount;
|
|
#endif
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayDoubleRangeFastInView(AuMemoryViewWrite write, double dMin, double dMax)
|
|
{
|
|
auto ret = write.Begin<double>();
|
|
auto uCount = write.ToCount<double>();
|
|
|
|
AuUInt64 uSeed = this->NextU64();
|
|
double dRange = dMax - dMin;
|
|
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
double dValue = RngConvertToDecimal(uSeed);
|
|
dValue *= dRange;
|
|
dValue += dMin;
|
|
ret[uIndex] = dValue;
|
|
uSeed = AuFnv1a64Runtime<8>(&uSeed);
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayI32InView(AuMemoryViewWrite write)
|
|
{
|
|
auto ret = write.Begin<AuInt32>();
|
|
auto uCount = write.ToCount<AuInt32>();
|
|
this->Read(write);
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayU32InView(AuMemoryViewWrite write)
|
|
{
|
|
auto ret = write.Begin<AuUInt32>();
|
|
auto uCount = write.ToCount<AuUInt32>();
|
|
this->Read(write);
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayI64RangeFastInView(AuMemoryViewWrite write, AuInt64 iMin, AuInt64 iMax)
|
|
{
|
|
auto ret = write.Begin<AuInt64>();
|
|
auto uCount = write.ToCount<AuInt64>();
|
|
|
|
auto uRange = AuUInt64(iMax - iMin);
|
|
auto uUpperBound = AuRoundUpPow2(uRange + 1);
|
|
auto uSeed = this->NextU64();
|
|
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
AuUInt64 uNext {};
|
|
|
|
uSeed = AuFnv1a64Runtime<sizeof(uSeed)>(&uSeed);
|
|
while ((uNext = (uSeed & (uUpperBound - 1))) > uRange)
|
|
{
|
|
uSeed = AuFnv1a64Runtime<sizeof(uSeed)>(&uSeed);
|
|
}
|
|
|
|
ret[uIndex] = iMin + uNext;
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayU64RangeFastInView(AuMemoryViewWrite write, AuUInt64 uMin, AuUInt64 uMax)
|
|
{
|
|
auto ret = write.Begin<AuUInt64>();
|
|
auto uCount = write.ToCount<AuUInt64>();
|
|
|
|
auto uRange = uMax - uMin;
|
|
auto uUpperBound = AuRoundUpPow2(uRange + 1);
|
|
auto uSeed = this->NextU64();
|
|
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
AuUInt64 uNext {};
|
|
|
|
uSeed = AuFnv1a64Runtime<sizeof(uSeed)>(&uSeed);
|
|
while ((uNext = (uSeed & (uUpperBound - 1))) > uRange)
|
|
{
|
|
uSeed = AuFnv1a64Runtime<sizeof(uSeed)>(&uSeed);
|
|
}
|
|
|
|
ret[uIndex] = uMin + uNext;
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayI64RangeInView(AuMemoryViewWrite write, AuInt64 iMin, AuInt64 iMax)
|
|
{
|
|
auto ret = write.Begin<AuInt64>();
|
|
auto uCount = write.ToCount<AuInt64>();
|
|
|
|
this->Read(write);
|
|
|
|
auto uRange = AuUInt64(iMax - iMin);
|
|
auto uUpperBound = AuRoundUpPow2(uRange + 1);
|
|
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
auto uMassiveWord = write.Begin<AuUInt64>()[uIndex];
|
|
|
|
AuUInt64 uNext {};
|
|
while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange)
|
|
{
|
|
uMassiveWord = AuFnv1a64Runtime<sizeof(uMassiveWord)>(&uMassiveWord);
|
|
}
|
|
|
|
ret[uIndex] = iMin + uNext;
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayU64RangeInView(AuMemoryViewWrite write, AuUInt64 uMin, AuUInt64 uMax)
|
|
{
|
|
auto ret = write.Begin<AuUInt64>();
|
|
auto uCount = write.ToCount<AuUInt64>();
|
|
|
|
this->Read(write);
|
|
|
|
auto uRange = uMax - uMin;
|
|
auto uUpperBound = AuRoundUpPow2(uRange + 1);
|
|
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
auto uMassiveWord = ret[uIndex];
|
|
|
|
AuUInt64 uNext {};
|
|
while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange)
|
|
{
|
|
uMassiveWord = AuFnv1a64Runtime<sizeof(uMassiveWord)>(&uMassiveWord);
|
|
}
|
|
|
|
ret[uIndex] = uMin + uNext;
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayU32MaskInView(AuMemoryViewWrite write, AuUInt32 uMask)
|
|
{
|
|
auto ret = write.Begin<AuUInt32>();
|
|
auto uCount = write.ToCount<AuUInt32>();
|
|
|
|
this->Read(write);
|
|
|
|
for (AU_ITERATE_N(i, uCount))
|
|
{
|
|
auto &word = ret[i];
|
|
word &= uMask;
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayU64MaskInView(AuMemoryViewWrite write, AuUInt64 uMask)
|
|
{
|
|
auto ret = write.Begin<AuUInt64>();
|
|
auto uCount = write.ToCount<AuUInt64>();
|
|
|
|
this->Read(write);
|
|
|
|
for (AU_ITERATE_N(i, uCount))
|
|
{
|
|
auto &word = ret[i];
|
|
word &= uMask;
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayI64InView(AuMemoryViewWrite write)
|
|
{
|
|
auto uCount = write.ToCount<AuInt64>();
|
|
this->Read(write);
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayU64InView(AuMemoryViewWrite write)
|
|
{
|
|
auto uCount = write.ToCount<AuUInt64>();
|
|
this->Read(write);
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayVec2InView(AuMemoryViewWrite write, AuVec2 boundA, AuVec2 boundB)
|
|
{
|
|
AuVec2 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 NextArrayVec2SortedInView(write, mins, maxs);
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayVec2FastInView(AuMemoryViewWrite write, AuVec2 boundA, AuVec2 boundB)
|
|
{
|
|
AuVec2 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 NextArrayVec2SortedFastInView(write, mins, maxs);
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayVec2SortedInView(AuMemoryViewWrite write, AuVec2 min, AuVec2 max)
|
|
{
|
|
AuVec2 range;
|
|
RNG_BYTES_PROLOGUE;
|
|
|
|
auto ret = write.Begin<AuVec2>();
|
|
auto uCount = write.ToCount<AuVec2>();
|
|
|
|
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<AuUInt64>()[uIndex];
|
|
auto dComponentA = RngConvertToDecimal(uSeed);
|
|
auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed)));
|
|
|
|
ret[uIndex] = AuVec2 {
|
|
float((dComponentA * range[0]) + min[0]),
|
|
float((dComponentB * range[1]) + min[1])
|
|
};
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayVec2SortedFastInView(AuMemoryViewWrite write, AuVec2 min, AuVec2 max)
|
|
{
|
|
AuVec2 range;
|
|
|
|
auto ret = write.Begin<AuVec2>();
|
|
auto uCount = write.ToCount<AuVec2>();
|
|
|
|
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] = AuVec2 {
|
|
float((dComponentA * range[0]) + min[0]),
|
|
float((dComponentB * range[1]) + min[1])
|
|
};
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayVec3InView(AuMemoryViewWrite write, AuVec3 boundA, AuVec3 boundB)
|
|
{
|
|
AuVec3 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 NextArrayVec3SortedInView(write, mins, maxs);
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayVec3FastInView(AuMemoryViewWrite write, AuVec3 boundA, AuVec3 boundB)
|
|
{
|
|
AuVec3 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 NextArrayVec3SortedFastInView(write, mins, maxs);
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayVec3SortedInView(AuMemoryViewWrite write, AuVec3 min, AuVec3 max)
|
|
{
|
|
AuVec3 range;
|
|
RNG_BYTES_PROLOGUE;
|
|
|
|
auto ret = write.Begin<AuVec3>();
|
|
auto uCount = write.ToCount<AuVec3>();
|
|
|
|
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<AuUInt64>()[uIndex];
|
|
auto dComponentA = RngConvertToDecimal(uSeed);
|
|
auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed)));
|
|
auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed)));
|
|
|
|
ret[uIndex] = AuVec3 {
|
|
float((dComponentA * range[0]) + min[0]),
|
|
float((dComponentB * range[1]) + min[1]),
|
|
float((dComponentC * range[2]) + min[2])
|
|
};
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayVec3SortedFastInView(AuMemoryViewWrite write, AuVec3 min, AuVec3 max)
|
|
{
|
|
AuVec3 range;
|
|
auto ret = write.Begin<AuVec3>();
|
|
auto uCount = write.ToCount<AuVec3>();
|
|
|
|
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] = AuVec3 {
|
|
float((dComponentA * range[0]) + min[0]),
|
|
float((dComponentB * range[1]) + min[1]),
|
|
float((dComponentC * range[2]) + min[2])
|
|
};
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayVec4InView(AuMemoryViewWrite write, AuVec4 boundA, AuVec4 boundB)
|
|
{
|
|
AuVec4 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 NextArrayVec4SortedInView(write, mins, maxs);
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayVec4FastInView(AuMemoryViewWrite write, AuVec4 boundA, AuVec4 boundB)
|
|
{
|
|
AuVec4 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 NextArrayVec4SortedFastInView(write, mins, maxs);
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayVec4SortedInView(AuMemoryViewWrite write, AuVec4 min, AuVec4 max)
|
|
{
|
|
AuVec4 range;
|
|
RNG_BYTES_PROLOGUE;
|
|
|
|
auto ret = write.Begin<AuVec4>();
|
|
auto uCount = write.ToCount<AuVec4>();
|
|
|
|
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<AuUInt64>()[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] = AuVec4 {
|
|
float((dComponentA * range[0]) + min[0]),
|
|
float((dComponentB * range[1]) + min[1]),
|
|
float((dComponentC * range[2]) + min[2]),
|
|
float((dComponentD * range[3]) + min[3])
|
|
};
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayVec4SortedFastInView(AuMemoryViewWrite write, AuVec4 min, AuVec4 max)
|
|
{
|
|
AuVec4 range;
|
|
auto ret = write.Begin<AuVec4>();
|
|
auto uCount = write.ToCount<AuVec4>();
|
|
|
|
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] = AuVec4 {
|
|
float((dComponentA * range[0]) + min[0]),
|
|
float((dComponentB * range[1]) + min[1]),
|
|
float((dComponentC * range[2]) + min[2]),
|
|
float((dComponentD * range[3]) + min[3])
|
|
};
|
|
}
|
|
|
|
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<AuVecD2>();
|
|
auto uCount = write.ToCount<AuVecD2>();
|
|
|
|
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<AuUInt64>()[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<AuVecD2>();
|
|
auto uCount = write.ToCount<AuVecD2>();
|
|
|
|
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<AuVecD3>();
|
|
auto uCount = write.ToCount<AuVecD3>();
|
|
|
|
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<AuUInt64>()[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<AuVecD3>();
|
|
auto uCount = write.ToCount<AuVecD3>();
|
|
|
|
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<AuVecD4>();
|
|
auto uCount = write.ToCount<AuVecD4>();
|
|
|
|
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<AuUInt64>()[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<AuVecD4>();
|
|
auto uCount = write.ToCount<AuVecD4>();
|
|
|
|
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<double>();
|
|
auto uCount = write.ToCount<double>();
|
|
this->Read(write);
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayDecimalsInView(AuMemoryViewWrite write)
|
|
{
|
|
#if defined(AURNG_USE_FAST_DECIMALS)
|
|
auto ret = write.Begin<double>();
|
|
auto uCount = write.ToCount<double>();
|
|
|
|
if constexpr (sizeof(double) == sizeof(AuUInt64))
|
|
{
|
|
this->Read(write);
|
|
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
ret[uIndex] = RngConvertToDecimal(*(AuUInt64*)&ret[uIndex]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RNG_BYTES_PROLOGUE;
|
|
|
|
RNG_BYTES_RESIZE(uCount);
|
|
this->Read(rngBytes);
|
|
|
|
for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE))
|
|
{
|
|
ret[uIndex] = RngConvertToDecimal(rngBytes.Begin<AuUInt64>()[uIndex]);
|
|
}
|
|
}
|
|
|
|
return uCount;
|
|
#else
|
|
auto ret = write.Begin<double>();
|
|
auto uCount = write.ToCount<double>();
|
|
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
ret[uIndex] = this->NextDecimal();
|
|
}
|
|
|
|
return uCount;
|
|
#endif
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayDecimalsFastInView(AuMemoryViewWrite write)
|
|
{
|
|
auto ret = write.Begin<double>();
|
|
auto uCount = write.ToCount<double>();
|
|
|
|
AuUInt64 uSeed = this->NextU64();
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
ret[uIndex] = RngConvertToDecimal(uSeed);
|
|
uSeed = AuFnv1a64Runtime<8>(&uSeed);
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuUInt RandomDevice::NextArrayUUIDsInView(AuMemoryViewWrite write)
|
|
{
|
|
auto ret = write.Begin<uuids::uuid>();
|
|
auto uCount = write.ToCount<uuids::uuid>();
|
|
|
|
if constexpr (sizeof(uuids::uuid) == 16)
|
|
{
|
|
this->Read(write);
|
|
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
auto pBytes = write.Begin<AuUInt8>() + (uIndex * 16);
|
|
|
|
pBytes[8] &= 0xBF;
|
|
pBytes[8] |= 0x80;
|
|
|
|
pBytes[6] &= 0x4F;
|
|
pBytes[6] |= 0x40;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AuList<AuUInt8> rngBytes;
|
|
|
|
rngBytes.resize(uCount * 16);
|
|
this->Read(rngBytes);
|
|
|
|
for (AU_ITERATE_N(uIndex, uCount))
|
|
{
|
|
auto pBytes = rngBytes.data() + (uIndex * 16);
|
|
|
|
pBytes[8] &= 0xBF;
|
|
pBytes[8] |= 0x80;
|
|
|
|
pBytes[6] &= 0x4F;
|
|
pBytes[6] |= 0x40;
|
|
|
|
ret[uIndex] = uuids::uuid { pBytes, pBytes + 16 };
|
|
}
|
|
}
|
|
|
|
return uCount;
|
|
}
|
|
|
|
AuList<AuInt32> RandomDevice::NextArrayI32Range(AuUInt32 uCount, AuInt32 iMin, AuInt32 iMax)
|
|
{
|
|
AuList<AuInt32> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayI32RangeInView(ret, iMin, iMax);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuInt32> RandomDevice::NextArrayI32RangeFast(AuUInt32 uCount, AuInt32 iMin, AuInt32 iMax)
|
|
{
|
|
AuList<AuInt32> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayI32RangeFastInView(ret, iMin, iMax);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuUInt32> RandomDevice::NextArrayU32Range(AuUInt32 uCount, AuUInt32 uMin, AuUInt32 uMax)
|
|
{
|
|
AuList<AuUInt32> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayU32RangeInView(ret, uMin, uMax);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuUInt32> RandomDevice::NextArrayU32RangeFast(AuUInt32 uCount, AuUInt32 uMin, AuUInt32 uMax)
|
|
{
|
|
AuList<AuUInt32> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayU32RangeFastInView(ret, uMin, uMax);
|
|
return ret;
|
|
}
|
|
|
|
AuList<double> RandomDevice::NextArrayDoubleRange(AuUInt32 uCount, double dMin, double dMax)
|
|
{
|
|
AuList<double> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayDoubleRangeInView(ret, dMin, dMax);
|
|
return ret;
|
|
}
|
|
|
|
AuList<double> RandomDevice::NextArrayDoubleRangeFast(AuUInt32 uCount, double dMin, double dMax)
|
|
{
|
|
AuList<double> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayDoubleRangeFastInView(ret, dMin, dMax);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuInt32> RandomDevice::NextArrayI32(AuUInt32 uCount)
|
|
{
|
|
AuList<AuInt32> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayI32InView(ret);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuUInt32> RandomDevice::NextArrayU32(AuUInt32 uCount)
|
|
{
|
|
AuList<AuUInt32> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayU32InView(ret);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuInt64> RandomDevice::NextArrayI64RangeFast(AuUInt32 uCount, AuInt64 iMin, AuInt64 iMax)
|
|
{
|
|
AuList<AuInt64> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayI64RangeFastInView(ret, iMin, iMax);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuUInt64> RandomDevice::NextArrayU64RangeFast(AuUInt32 uCount, AuUInt64 uMin, AuUInt64 uMax)
|
|
{
|
|
AuList<AuUInt64> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayU64RangeFastInView(ret, uMin, uMax);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuInt64> RandomDevice::NextArrayI64Range(AuUInt32 uCount, AuInt64 iMin, AuInt64 iMax)
|
|
{
|
|
AuList<AuInt64> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayI64RangeInView(ret, iMin, iMax);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuUInt64> RandomDevice::NextArrayU64Range(AuUInt32 uCount, AuUInt64 uMin, AuUInt64 uMax)
|
|
{
|
|
AuList<AuUInt64> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayU64RangeInView(ret, uMin, uMax);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuUInt32> RandomDevice::NextArrayU32Mask(AuUInt32 uCount, AuUInt32 uMask)
|
|
{
|
|
AuList<AuUInt32> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayU32MaskInView(ret, uMask);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuUInt64> RandomDevice::NextArrayU64Mask(AuUInt32 uCount, AuUInt64 uMask)
|
|
{
|
|
AuList<AuUInt64> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayU64MaskInView(ret, uMask);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuInt64> RandomDevice::NextArrayI64(AuUInt32 uCount)
|
|
{
|
|
AuList<AuInt64> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayI64InView(ret);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuUInt64> RandomDevice::NextArrayU64(AuUInt32 uCount)
|
|
{
|
|
AuList<AuUInt64> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayU64InView(ret);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVec2> RandomDevice::NextArrayVec2(AuUInt32 uCount, AuVec2 boundA, AuVec2 boundB)
|
|
{
|
|
AuList<AuVec2> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVec2InView(ret, boundA, boundB);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVec2> RandomDevice::NextArrayVec2Fast(AuUInt32 uCount, AuVec2 boundA, AuVec2 boundB)
|
|
{
|
|
AuList<AuVec2> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVec2FastInView(ret, boundA, boundB);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVec2> RandomDevice::NextArrayVec2Sorted(AuUInt32 uCount, AuVec2 min, AuVec2 max)
|
|
{
|
|
AuList<AuVec2> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVec2SortedInView(ret, min, max);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVec2> RandomDevice::NextArrayVec2SortedFast(AuUInt32 uCount, AuVec2 min, AuVec2 max)
|
|
{
|
|
AuList<AuVec2> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVec2SortedFastInView(ret, min, max);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVec3> RandomDevice::NextArrayVec3(AuUInt32 uCount, AuVec3 boundA, AuVec3 boundB)
|
|
{
|
|
AuList<AuVec3> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVec3InView(ret, boundA, boundB);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVec3> RandomDevice::NextArrayVec3Fast(AuUInt32 uCount, AuVec3 boundA, AuVec3 boundB)
|
|
{
|
|
AuList<AuVec3> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVec3FastInView(ret, boundA, boundB);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVec3> RandomDevice::NextArrayVec3Sorted(AuUInt32 uCount, AuVec3 min, AuVec3 max)
|
|
{
|
|
AuList<AuVec3> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVec3SortedInView(ret, min, max);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVec3> RandomDevice::NextArrayVec3SortedFast(AuUInt32 uCount, AuVec3 min, AuVec3 max)
|
|
{
|
|
AuList<AuVec3> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVec3SortedFastInView(ret, min, max);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVec4> RandomDevice::NextArrayVec4(AuUInt32 uCount, AuVec4 boundA, AuVec4 boundB)
|
|
{
|
|
AuList<AuVec4> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVec4InView(ret, boundA, boundB);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVec4> RandomDevice::NextArrayVec4Fast(AuUInt32 uCount, AuVec4 boundA, AuVec4 boundB)
|
|
{
|
|
AuList<AuVec4> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVec4FastInView(ret, boundA, boundB);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVec4> RandomDevice::NextArrayVec4Sorted(AuUInt32 uCount, AuVec4 min, AuVec4 max)
|
|
{
|
|
AuList<AuVec4> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVec4SortedInView(ret, min, max);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVec4> RandomDevice::NextArrayVec4SortedFast(AuUInt32 uCount, AuVec4 min, AuVec4 max)
|
|
{
|
|
AuList<AuVec4> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVec4SortedFastInView(ret, min, max);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVecD2> RandomDevice::NextArrayVecD2(AuUInt32 uCount, AuVecD2 boundA, AuVecD2 boundB)
|
|
{
|
|
AuList<AuVecD2> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVecD2InView(ret, boundA, boundB);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVecD2> RandomDevice::NextArrayVecD2Fast(AuUInt32 uCount, AuVecD2 boundA, AuVecD2 boundB)
|
|
{
|
|
AuList<AuVecD2> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVecD2FastInView(ret, boundA, boundB);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVecD2> RandomDevice::NextArrayVecD2Sorted(AuUInt32 uCount, AuVecD2 min, AuVecD2 max)
|
|
{
|
|
AuList<AuVecD2> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVecD2SortedInView(ret, min, max);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVecD2> RandomDevice::NextArrayVecD2SortedFast(AuUInt32 uCount, AuVecD2 min, AuVecD2 max)
|
|
{
|
|
AuList<AuVecD2> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVecD2SortedFastInView(ret, min, max);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVecD3> RandomDevice::NextArrayVecD3(AuUInt32 uCount, AuVecD3 boundA, AuVecD3 boundB)
|
|
{
|
|
AuList<AuVecD3> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVecD3InView(ret, boundA, boundB);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVecD3> RandomDevice::NextArrayVecD3Fast(AuUInt32 uCount, AuVecD3 boundA, AuVecD3 boundB)
|
|
{
|
|
AuList<AuVecD3> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVecD3FastInView(ret, boundA, boundB);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVecD3> RandomDevice::NextArrayVecD3Sorted(AuUInt32 uCount, AuVecD3 min, AuVecD3 max)
|
|
{
|
|
AuList<AuVecD3> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVecD3SortedInView(ret, min, max);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVecD3> RandomDevice::NextArrayVecD3SortedFast(AuUInt32 uCount, AuVecD3 min, AuVecD3 max)
|
|
{
|
|
AuList<AuVecD3> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVecD3SortedFastInView(ret, min, max);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVecD4> RandomDevice::NextArrayVecD4(AuUInt32 uCount, AuVecD4 boundA, AuVecD4 boundB)
|
|
{
|
|
AuList<AuVecD4> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVecD4InView(ret, boundA, boundB);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVecD4> RandomDevice::NextArrayVecD4Fast(AuUInt32 uCount, AuVecD4 boundA, AuVecD4 boundB)
|
|
{
|
|
AuList<AuVecD4> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVecD4FastInView(ret, boundA, boundB);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVecD4> RandomDevice::NextArrayVecD4Sorted(AuUInt32 uCount, AuVecD4 min, AuVecD4 max)
|
|
{
|
|
AuList<AuVecD4> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVecD4SortedInView(ret, min, max);
|
|
return ret;
|
|
}
|
|
|
|
AuList<AuVecD4> RandomDevice::NextArrayVecD4SortedFast(AuUInt32 uCount, AuVecD4 min, AuVecD4 max)
|
|
{
|
|
AuList<AuVecD4> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayVecD4SortedFastInView(ret, min, max);
|
|
return ret;
|
|
}
|
|
|
|
AuList<double> RandomDevice::NextArrayDouble(AuUInt32 uCount)
|
|
{
|
|
AuList<double> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayDoubleInView(ret);
|
|
return ret;
|
|
}
|
|
|
|
AuList<double> RandomDevice::NextArrayDecimals(AuUInt32 uCount)
|
|
{
|
|
AuList<double> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayDecimalsInView(ret);
|
|
return ret;
|
|
}
|
|
|
|
AuList<double> RandomDevice::NextArrayDecimalsFast(AuUInt32 uCount)
|
|
{
|
|
AuList<double> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayDecimalsFastInView(ret);
|
|
return ret;
|
|
}
|
|
|
|
AuList<uuids::uuid> RandomDevice::NextArrayUUIDs(AuUInt32 uCount)
|
|
{
|
|
AuList<uuids::uuid> ret;
|
|
ret.resize(uCount);
|
|
(void)NextArrayUUIDsInView(ret);
|
|
return ret;
|
|
}
|
|
|
|
AuMemoryViewRead RandomDevice::ToSeed()
|
|
{
|
|
if (this->def_.bSecure)
|
|
{
|
|
return {};
|
|
}
|
|
|
|
return this->fast_.state;
|
|
}
|
|
|
|
IO::IStreamReader *RandomDevice::ToStreamReader()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
AUKN_SYM IRandomDevice *RandomNew(const Aurora::RNG::RandomDef &def)
|
|
{
|
|
auto pDevice = _new RandomDevice();
|
|
if (!pDevice)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
pDevice->Init(def);
|
|
|
|
return pDevice;
|
|
}
|
|
|
|
AUKN_SYM void RandomRelease(IRandomDevice *pDevice)
|
|
{
|
|
AuSafeDelete<RandomDevice *>(pDevice);
|
|
}
|
|
|
|
AUROXTL_INTERFACE_SOO_SRC(Random, RandomDevice, (const RandomDef &, def))
|
|
} |