Improve random number generation
The global RNG state is now protected from simultaneous accesses by employing a mutex. Performance sensitive code requiring generation of a large number of random numbers can utilize `LocalRNG`. This is not thread-safe but provides a much greater throughput. `LocalRNG` is seeded by the global RNG only at construction time.
This commit is contained in:
parent
995e7f2ffc
commit
585cbfce1c
@ -52,13 +52,9 @@ DEFINE_SPADES_SETTING(s_gain, "1");
|
||||
namespace spades {
|
||||
namespace audio {
|
||||
|
||||
std::uniform_real_distribution<float> real_dist_audio(0, 1);
|
||||
|
||||
static Vector3 TransformVectorToAL(Vector3 v) { return MakeVector3(v.x, v.y, v.z); }
|
||||
static Vector3 TransformVectorFromAL(Vector3 v) { return MakeVector3(v.x, v.y, v.z); }
|
||||
|
||||
static float NextRandom() { return real_dist_audio(mt_engine); }
|
||||
|
||||
namespace {
|
||||
std::vector<uint8_t> ConvertFloatBufferToSignedShort(const std::vector<uint8_t> &bytes) {
|
||||
if (bytes.size() & 3) {
|
||||
@ -562,7 +558,7 @@ namespace spades {
|
||||
ALSrc *AllocChunk() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
size_t start = mt_engine() % srcs.size();
|
||||
size_t start = SampleRandomInt<std::size_t>(0, srcs.size() - 1);
|
||||
for (size_t i = 0; i < srcs.size(); i++) {
|
||||
ALSrc *src = srcs[(i + start) % srcs.size()];
|
||||
if (src->IsPlaying())
|
||||
@ -570,7 +566,7 @@ namespace spades {
|
||||
return src;
|
||||
}
|
||||
|
||||
ALSrc *src = srcs[mt_engine() % srcs.size()];
|
||||
ALSrc *src = SampleRandomElement(srcs);
|
||||
src->Terminate();
|
||||
return src;
|
||||
}
|
||||
@ -649,9 +645,9 @@ namespace spades {
|
||||
Vector3 rayTo;
|
||||
|
||||
for (int rays = 0; rays < 4; rays++) {
|
||||
rayTo.x = NextRandom() - NextRandom();
|
||||
rayTo.y = NextRandom() - NextRandom();
|
||||
rayTo.z = NextRandom() - NextRandom();
|
||||
rayTo.x = SampleRandomFloat() - SampleRandomFloat();
|
||||
rayTo.y = SampleRandomFloat() - SampleRandomFloat();
|
||||
rayTo.z = SampleRandomFloat() - SampleRandomFloat();
|
||||
rayTo = rayTo.Normalize();
|
||||
|
||||
IntVector3 hitPos;
|
||||
@ -742,7 +738,7 @@ namespace spades {
|
||||
|
||||
for (size_t i = 0; i < srcs.size(); i++) {
|
||||
ALSrc *s = srcs[i];
|
||||
if ((mt_engine() % 8 == 0) && s->IsPlaying())
|
||||
if ((SampleRandomInt(0, 7) == 0) && s->IsPlaying())
|
||||
s->UpdateObstruction();
|
||||
}
|
||||
}
|
||||
|
@ -453,8 +453,6 @@ namespace spades {
|
||||
old->Release();
|
||||
}
|
||||
|
||||
static float NextRandom() { return real_dist(mt_engine); }
|
||||
|
||||
void YsrDevice::Respatialize(const spades::Vector3 &eye, const spades::Vector3 &front,
|
||||
const spades::Vector3 &up) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
@ -480,9 +478,9 @@ namespace spades {
|
||||
Vector3 rayTo;
|
||||
|
||||
for (int rays = 0; rays < 4; rays++) {
|
||||
rayTo.x = NextRandom() - NextRandom();
|
||||
rayTo.y = NextRandom() - NextRandom();
|
||||
rayTo.z = NextRandom() - NextRandom();
|
||||
rayTo.x = SampleRandomFloat() - SampleRandomFloat();
|
||||
rayTo.y = SampleRandomFloat() - SampleRandomFloat();
|
||||
rayTo.z = SampleRandomFloat() - SampleRandomFloat();
|
||||
rayTo = rayTo.Normalize();
|
||||
|
||||
IntVector3 hitPos;
|
||||
|
@ -65,11 +65,7 @@ SPADES_SETTING(cg_playerName);
|
||||
|
||||
namespace spades {
|
||||
namespace client {
|
||||
|
||||
std::random_device r_device_client;
|
||||
std::mt19937_64 mt_engine_client(
|
||||
r_device_client()); // Seed Mersenne twister with non-deterministic 32-bit seed
|
||||
|
||||
|
||||
Client::Client(IRenderer *r, IAudioDevice *audioDev, const ServerAddress &host,
|
||||
FontManager *fontManager)
|
||||
: playerName(cg_playerName.operator std::string().substr(0, 15)),
|
||||
|
@ -67,8 +67,6 @@ namespace spades {
|
||||
|
||||
class ClientUI;
|
||||
|
||||
extern std::mt19937_64 mt_engine_client; // randomness generator
|
||||
|
||||
class Client : public IWorldListener, public gui::View {
|
||||
friend class ScoreboardView;
|
||||
friend class LimboView;
|
||||
@ -101,6 +99,11 @@ namespace spades {
|
||||
FPSCounter fpsCounter;
|
||||
FPSCounter upsCounter;
|
||||
|
||||
/**
|
||||
* A random number generator. Only can be accessed by a main thread.
|
||||
*/
|
||||
LocalRNG rng;
|
||||
|
||||
std::unique_ptr<NetClient> net;
|
||||
std::string playerName;
|
||||
std::unique_ptr<IStream> logStream;
|
||||
|
@ -1192,7 +1192,7 @@ namespace spades {
|
||||
case RIFLE_WEAPON:
|
||||
model = renderer->RegisterModel("Models/Weapons/Rifle/Casing.kv6");
|
||||
snd =
|
||||
(mt_engine_client() & 0x1000)
|
||||
SampleRandomBool()
|
||||
? audioDevice->RegisterSound("Sounds/Weapons/Rifle/ShellDrop1.opus")
|
||||
: audioDevice->RegisterSound(
|
||||
"Sounds/Weapons/Rifle/ShellDrop2.opus");
|
||||
@ -1207,7 +1207,7 @@ namespace spades {
|
||||
case SMG_WEAPON:
|
||||
model = renderer->RegisterModel("Models/Weapons/SMG/Casing.kv6");
|
||||
snd =
|
||||
(mt_engine_client() & 0x1000)
|
||||
SampleRandomBool()
|
||||
? audioDevice->RegisterSound("Sounds/Weapons/SMG/ShellDrop1.opus")
|
||||
: audioDevice->RegisterSound("Sounds/Weapons/SMG/ShellDrop2.opus");
|
||||
snd2 = audioDevice->RegisterSound("Sounds/Weapons/SMG/ShellWater.opus");
|
||||
|
@ -151,18 +151,19 @@ namespace spades {
|
||||
|
||||
if ((int)cg_particles < 1)
|
||||
return;
|
||||
|
||||
|
||||
Handle<IImage> img = renderer->RegisterImage("Gfx/White.tga");
|
||||
Vector4 color = {0.5f, 0.02f, 0.04f, 1.f};
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ParticleSpriteEntity *ent = new ParticleSpriteEntity(this, img, color);
|
||||
ent->SetTrajectory(v,
|
||||
MakeVector3(GetRandom() - GetRandom(), GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom()) *
|
||||
MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat()) *
|
||||
10.f,
|
||||
1.f, 0.7f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.1f + GetRandom() * GetRandom() * 0.2f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.1f + rng.SampleFloat() * rng.SampleFloat() * 0.2f);
|
||||
ent->SetLifeTime(3.f, 0.f, 1.f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
@ -175,14 +176,15 @@ namespace spades {
|
||||
ParticleSpriteEntity *ent =
|
||||
new SmokeSpriteEntity(this, color, 100.f, SmokeSpriteEntity::Type::Explosion);
|
||||
ent->SetTrajectory(v,
|
||||
MakeVector3(GetRandom() - GetRandom(), GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom()) *
|
||||
MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat()) *
|
||||
.7f,
|
||||
.8f, 0.f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(.5f + GetRandom() * GetRandom() * 0.2f, 2.f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(.5f + rng.SampleFloat() * rng.SampleFloat() * 0.2f, 2.f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
ent->SetLifeTime(.20f + GetRandom() * .2f, 0.06f, .20f);
|
||||
ent->SetLifeTime(.20f + rng.SampleFloat() * .2f, 0.06f, .20f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
@ -191,14 +193,15 @@ namespace spades {
|
||||
ParticleSpriteEntity *ent =
|
||||
new SmokeSpriteEntity(this, color, 40.f, SmokeSpriteEntity::Type::Steady);
|
||||
ent->SetTrajectory(v,
|
||||
MakeVector3(GetRandom() - GetRandom(), GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom()) *
|
||||
MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat()) *
|
||||
.7f,
|
||||
.8f, 0.f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(.7f + GetRandom() * GetRandom() * 0.2f, 2.f, 0.1f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(.7f + rng.SampleFloat() * rng.SampleFloat() * 0.2f, 2.f, 0.1f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
ent->SetLifeTime(.80f + GetRandom() * 0.4f, 0.06f, 1.0f);
|
||||
ent->SetLifeTime(.80f + rng.SampleFloat() * 0.4f, 0.06f, 1.0f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
}
|
||||
@ -219,12 +222,13 @@ namespace spades {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
ParticleSpriteEntity *ent = new ParticleSpriteEntity(this, img, color);
|
||||
ent->SetTrajectory(origin,
|
||||
MakeVector3(GetRandom() - GetRandom(), GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom()) *
|
||||
MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat()) *
|
||||
7.f,
|
||||
1.f, .9f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.2f + GetRandom() * GetRandom() * 0.1f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.2f + rng.SampleFloat() * rng.SampleFloat() * 0.1f);
|
||||
ent->SetLifeTime(2.f, 0.f, 1.f);
|
||||
if (distPowered < 16.f * 16.f)
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::BounceWeak);
|
||||
@ -237,13 +241,13 @@ namespace spades {
|
||||
if (distPowered < 32.f * 32.f) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
ParticleSpriteEntity *ent = new ParticleSpriteEntity(this, img, color);
|
||||
ent->SetTrajectory(origin, MakeVector3(GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom()) *
|
||||
ent->SetTrajectory(origin, MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat()) *
|
||||
12.f,
|
||||
1.f, .9f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.1f + GetRandom() * GetRandom() * 0.14f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.1f + rng.SampleFloat() * rng.SampleFloat() * 0.14f);
|
||||
ent->SetLifeTime(2.f, 0.f, 1.f);
|
||||
if (distPowered < 16.f * 16.f)
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::BounceWeak);
|
||||
@ -256,13 +260,14 @@ namespace spades {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ParticleSpriteEntity *ent = new SmokeSpriteEntity(this, color, 100.f);
|
||||
ent->SetTrajectory(origin,
|
||||
MakeVector3(GetRandom() - GetRandom(), GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom()) *
|
||||
MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat()) *
|
||||
.7f,
|
||||
1.f, 0.f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(.6f + GetRandom() * GetRandom() * 0.2f, 0.8f);
|
||||
ent->SetLifeTime(.3f + GetRandom() * .3f, 0.06f, .4f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(.6f + rng.SampleFloat() * rng.SampleFloat() * 0.2f, 0.8f);
|
||||
ent->SetLifeTime(.3f + rng.SampleFloat() * .3f, 0.06f, .4f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
@ -285,12 +290,13 @@ namespace spades {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ParticleSpriteEntity *ent = new ParticleSpriteEntity(this, img, color);
|
||||
ent->SetTrajectory(origin,
|
||||
MakeVector3(GetRandom() - GetRandom(), GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom()) *
|
||||
MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat()) *
|
||||
7.f,
|
||||
1.f, 1.f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.3f + GetRandom() * GetRandom() * 0.2f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.3f + rng.SampleFloat() * rng.SampleFloat() * 0.2f);
|
||||
ent->SetLifeTime(2.f, 0.f, 1.f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::BounceWeak);
|
||||
localEntities.emplace_back(ent);
|
||||
@ -317,15 +323,16 @@ namespace spades {
|
||||
ParticleSpriteEntity *ent =
|
||||
new SmokeSpriteEntity(this, color, 120.f, SmokeSpriteEntity::Type::Explosion);
|
||||
ent->SetTrajectory(
|
||||
origin, (MakeVector3(GetRandom() - GetRandom(), GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom()) +
|
||||
origin, (MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat()) +
|
||||
velBias * .5f) *
|
||||
0.3f,
|
||||
1.f, 0.f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(.4f, 3.f, 0.0000005f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
ent->SetLifeTime(0.2f + GetRandom() * 0.1f, 0.f, .30f);
|
||||
ent->SetLifeTime(0.2f + rng.SampleFloat() * 0.1f, 0.f, .30f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
}
|
||||
@ -381,15 +388,16 @@ namespace spades {
|
||||
ParticleSpriteEntity *ent =
|
||||
new SmokeSpriteEntity(this, color, 60.f, SmokeSpriteEntity::Type::Explosion);
|
||||
ent->SetTrajectory(
|
||||
origin, (MakeVector3(GetRandom() - GetRandom(), GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom()) +
|
||||
origin, (MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat()) +
|
||||
velBias * .5f) *
|
||||
2.f,
|
||||
1.f, 0.f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(.6f + GetRandom() * GetRandom() * 0.4f, 2.f, .2f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(.6f + rng.SampleFloat() * rng.SampleFloat() * 0.4f, 2.f, .2f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
ent->SetLifeTime(1.8f + GetRandom() * 0.1f, 0.f, .20f);
|
||||
ent->SetLifeTime(1.8f + rng.SampleFloat() * 0.1f, 0.f, .20f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
@ -398,18 +406,19 @@ namespace spades {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ParticleSpriteEntity *ent = new SmokeSpriteEntity(this, color, 20.f);
|
||||
ent->SetTrajectory(
|
||||
origin, (MakeVector3(GetRandom() - GetRandom(), GetRandom() - GetRandom(),
|
||||
(GetRandom() - GetRandom()) * .2f)) *
|
||||
origin, (MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(),
|
||||
(rng.SampleFloat() - rng.SampleFloat()) * .2f)) *
|
||||
2.f,
|
||||
1.f, 0.f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(1.5f + GetRandom() * GetRandom() * 0.8f, 0.2f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(1.5f + rng.SampleFloat() * rng.SampleFloat() * 0.8f, 0.2f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
switch ((int)cg_particles) {
|
||||
case 1: ent->SetLifeTime(0.8f + GetRandom() * 1.f, 0.1f, 8.f); break;
|
||||
case 2: ent->SetLifeTime(1.5f + GetRandom() * 2.f, 0.1f, 8.f); break;
|
||||
case 1: ent->SetLifeTime(0.8f + rng.SampleFloat() * 1.f, 0.1f, 8.f); break;
|
||||
case 2: ent->SetLifeTime(1.5f + rng.SampleFloat() * 2.f, 0.1f, 8.f); break;
|
||||
case 3:
|
||||
default: ent->SetLifeTime(2.f + GetRandom() * 5.f, 0.1f, 8.f); break;
|
||||
default: ent->SetLifeTime(2.f + rng.SampleFloat() * 5.f, 0.1f, 8.f); break;
|
||||
}
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
@ -419,14 +428,15 @@ namespace spades {
|
||||
color = MakeVector4(0.01, 0.03, 0, 1.f);
|
||||
for (int i = 0; i < 42; i++) {
|
||||
ParticleSpriteEntity *ent = new ParticleSpriteEntity(this, img, color);
|
||||
Vector3 dir = MakeVector3(GetRandom() - GetRandom(), GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom());
|
||||
Vector3 dir = MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat());
|
||||
dir += velBias * .5f;
|
||||
float radius = 0.1f + GetRandom() * GetRandom() * 0.2f;
|
||||
float radius = 0.1f + rng.SampleFloat() * rng.SampleFloat() * 0.2f;
|
||||
ent->SetTrajectory(origin + dir * .2f, dir * 20.f, .1f + radius * 3.f, 1.f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(radius);
|
||||
ent->SetLifeTime(3.5f + GetRandom() * 2.f, 0.f, 1.f);
|
||||
ent->SetLifeTime(3.5f + rng.SampleFloat() * 2.f, 0.f, 1.f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::BounceWeak);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
@ -437,15 +447,15 @@ namespace spades {
|
||||
ParticleSpriteEntity *ent =
|
||||
new SmokeSpriteEntity(this, color, 120.f, SmokeSpriteEntity::Type::Explosion);
|
||||
ent->SetTrajectory(
|
||||
origin, (MakeVector3(GetRandom() - GetRandom(), GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom()) +
|
||||
origin, (MakeVector3(rng.SampleFloat() - rng.SampleFloat(), rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat()) +
|
||||
velBias) *
|
||||
6.f,
|
||||
1.f, 0.f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(.3f + GetRandom() * GetRandom() * 0.4f, 3.f, .1f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(.3f + rng.SampleFloat() * rng.SampleFloat() * 0.4f, 3.f, .1f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
ent->SetLifeTime(.18f + GetRandom() * 0.03f, 0.f, .10f);
|
||||
ent->SetLifeTime(.18f + rng.SampleFloat() * 0.03f, 0.f, .10f);
|
||||
// ent->SetAdditive(true);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
@ -471,14 +481,14 @@ namespace spades {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
ParticleSpriteEntity *ent = new ParticleSpriteEntity(this, img, color);
|
||||
ent->SetTrajectory(origin,
|
||||
(MakeVector3(GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom(), -GetRandom() * 7.f)) *
|
||||
(MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(), -rng.SampleFloat() * 7.f)) *
|
||||
2.5f,
|
||||
.3f, .6f);
|
||||
ent->SetRotation(0.f);
|
||||
ent->SetRadius(1.5f + GetRandom() * GetRandom() * 0.4f, 1.3f);
|
||||
ent->SetRadius(1.5f + rng.SampleFloat() * rng.SampleFloat() * 0.4f, 1.3f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
ent->SetLifeTime(3.f + GetRandom() * 0.3f, 0.f, .60f);
|
||||
ent->SetLifeTime(3.f + rng.SampleFloat() * 0.3f, 0.f, .60f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
@ -490,14 +500,14 @@ namespace spades {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
ParticleSpriteEntity *ent = new ParticleSpriteEntity(this, img, color);
|
||||
ent->SetTrajectory(origin,
|
||||
(MakeVector3(GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom(), -GetRandom() * 10.f)) *
|
||||
(MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(), -rng.SampleFloat() * 10.f)) *
|
||||
3.5f,
|
||||
1.f, 1.f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.9f + GetRandom() * GetRandom() * 0.4f, 0.7f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.9f + rng.SampleFloat() * rng.SampleFloat() * 0.4f, 0.7f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
ent->SetLifeTime(3.f + GetRandom() * 0.3f, .7f, .60f);
|
||||
ent->SetLifeTime(3.f + rng.SampleFloat() * 0.3f, .7f, .60f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
@ -508,18 +518,18 @@ namespace spades {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ParticleSpriteEntity *ent = new SmokeSpriteEntity(this, color, 20.f);
|
||||
ent->SetTrajectory(
|
||||
origin, (MakeVector3(GetRandom() - GetRandom(), GetRandom() - GetRandom(),
|
||||
(GetRandom() - GetRandom()) * .2f)) *
|
||||
origin, (MakeVector3(rng.SampleFloat() - rng.SampleFloat(), rng.SampleFloat() - rng.SampleFloat(),
|
||||
(rng.SampleFloat() - rng.SampleFloat()) * .2f)) *
|
||||
2.f,
|
||||
1.f, 0.f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(1.4f + GetRandom() * GetRandom() * 0.8f, 0.2f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(1.4f + rng.SampleFloat() * rng.SampleFloat() * 0.8f, 0.2f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
switch ((int)cg_particles) {
|
||||
case 1: ent->SetLifeTime(3.f + GetRandom() * 5.f, 0.1f, 8.f); break;
|
||||
case 1: ent->SetLifeTime(3.f + rng.SampleFloat() * 5.f, 0.1f, 8.f); break;
|
||||
case 2:
|
||||
case 3:
|
||||
default: ent->SetLifeTime(6.f + GetRandom() * 5.f, 0.1f, 8.f); break;
|
||||
default: ent->SetLifeTime(6.f + rng.SampleFloat() * 5.f, 0.1f, 8.f); break;
|
||||
}
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
@ -529,15 +539,15 @@ namespace spades {
|
||||
color = MakeVector4(1, 1, 1, 0.7f);
|
||||
for (int i = 0; i < 42; i++) {
|
||||
ParticleSpriteEntity *ent = new ParticleSpriteEntity(this, img, color);
|
||||
Vector3 dir = MakeVector3(GetRandom() - GetRandom(), GetRandom() - GetRandom(),
|
||||
-GetRandom() * 3.f);
|
||||
Vector3 dir = MakeVector3(rng.SampleFloat() - rng.SampleFloat(), rng.SampleFloat() - rng.SampleFloat(),
|
||||
-rng.SampleFloat() * 3.f);
|
||||
dir += velBias * .5f;
|
||||
float radius = 0.1f + GetRandom() * GetRandom() * 0.2f;
|
||||
float radius = 0.1f + rng.SampleFloat() * rng.SampleFloat() * 0.2f;
|
||||
ent->SetTrajectory(origin + dir * .2f + MakeVector3(0, 0, -1.2f), dir * 13.f,
|
||||
.1f + radius * 3.f, 1.f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(radius);
|
||||
ent->SetLifeTime(3.5f + GetRandom() * 2.f, 0.f, 1.f);
|
||||
ent->SetLifeTime(3.5f + rng.SampleFloat() * 2.f, 0.f, 1.f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Delete);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
@ -554,7 +564,7 @@ namespace spades {
|
||||
|
||||
if ((int)cg_particles < 1)
|
||||
return;
|
||||
|
||||
|
||||
Vector4 color;
|
||||
color = MakeVector4(.95f, .95f, .95f, .3f);
|
||||
// water1
|
||||
@ -564,14 +574,14 @@ namespace spades {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ParticleSpriteEntity *ent = new ParticleSpriteEntity(this, img, color);
|
||||
ent->SetTrajectory(origin,
|
||||
(MakeVector3(GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom(), -GetRandom() * 7.f)) *
|
||||
(MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(), -rng.SampleFloat() * 7.f)) *
|
||||
1.f,
|
||||
.3f, .6f);
|
||||
ent->SetRotation(0.f);
|
||||
ent->SetRadius(0.6f + GetRandom() * GetRandom() * 0.4f, .7f);
|
||||
ent->SetRadius(0.6f + rng.SampleFloat() * rng.SampleFloat() * 0.4f, .7f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
ent->SetLifeTime(3.f + GetRandom() * 0.3f, 0.1f, .60f);
|
||||
ent->SetLifeTime(3.f + rng.SampleFloat() * 0.3f, 0.1f, .60f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
@ -583,14 +593,14 @@ namespace spades {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
ParticleSpriteEntity *ent = new ParticleSpriteEntity(this, img, color);
|
||||
ent->SetTrajectory(origin,
|
||||
(MakeVector3(GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom(), -GetRandom() * 10.f)) *
|
||||
(MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(), -rng.SampleFloat() * 10.f)) *
|
||||
2.f,
|
||||
1.f, 1.f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.6f + GetRandom() * GetRandom() * 0.6f, 0.6f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.6f + rng.SampleFloat() * rng.SampleFloat() * 0.6f, 0.6f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
ent->SetLifeTime(3.f + GetRandom() * 0.3f, GetRandom() * 0.3f, .60f);
|
||||
ent->SetLifeTime(3.f + rng.SampleFloat() * 0.3f, rng.SampleFloat() * 0.3f, .60f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
@ -599,14 +609,15 @@ namespace spades {
|
||||
color = MakeVector4(1, 1, 1, 0.7f);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ParticleSpriteEntity *ent = new ParticleSpriteEntity(this, img, color);
|
||||
Vector3 dir = MakeVector3(GetRandom() - GetRandom(), GetRandom() - GetRandom(),
|
||||
-GetRandom() * 3.f);
|
||||
float radius = 0.03f + GetRandom() * GetRandom() * 0.05f;
|
||||
Vector3 dir = MakeVector3(rng.SampleFloat() - rng.SampleFloat(),
|
||||
rng.SampleFloat() - rng.SampleFloat(),
|
||||
-rng.SampleFloat() * 3.f);
|
||||
float radius = 0.03f + rng.SampleFloat() * rng.SampleFloat() * 0.05f;
|
||||
ent->SetTrajectory(origin + dir * .2f + MakeVector3(0, 0, -1.2f), dir * 5.f,
|
||||
.1f + radius * 3.f, 1.f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRotation(rng.SampleFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(radius);
|
||||
ent->SetLifeTime(3.5f + GetRandom() * 2.f, 0.f, 1.f);
|
||||
ent->SetLifeTime(3.5f + rng.SampleFloat() * 2.f, 0.f, 1.f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Delete);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
@ -46,10 +46,6 @@ DEFINE_SPADES_SETTING(cg_manualFocus, "0");
|
||||
DEFINE_SPADES_SETTING(cg_depthOfFieldAmount, "1");
|
||||
DEFINE_SPADES_SETTING(cg_shake, "1");
|
||||
|
||||
static float nextRandom() {
|
||||
return spades::real_dist(spades::client::mt_engine_client);
|
||||
}
|
||||
|
||||
namespace spades {
|
||||
namespace client {
|
||||
|
||||
@ -210,8 +206,8 @@ namespace spades {
|
||||
localFireVibration *= 0.4f;
|
||||
}
|
||||
|
||||
roll += (nextRandom() - nextRandom()) * 0.03f * localFireVibration;
|
||||
scale += nextRandom() * 0.04f * localFireVibration;
|
||||
roll += (SampleRandomFloat() - SampleRandomFloat()) * 0.03f * localFireVibration;
|
||||
scale += SampleRandomFloat() * 0.04f * localFireVibration;
|
||||
|
||||
vibPitch += localFireVibration * (1.f - localFireVibration) * 0.01f;
|
||||
vibYaw += sinf(localFireVibration * (float)M_PI * 2.f) * 0.001f;
|
||||
@ -391,10 +387,10 @@ namespace spades {
|
||||
grenVib *= 10.f;
|
||||
if (grenVib > 1.f)
|
||||
grenVib = 1.f;
|
||||
roll += (nextRandom() - nextRandom()) * 0.2f * grenVib;
|
||||
vibPitch += (nextRandom() - nextRandom()) * 0.1f * grenVib;
|
||||
vibYaw += (nextRandom() - nextRandom()) * 0.1f * grenVib;
|
||||
scale -= (nextRandom() - nextRandom()) * 0.1f * grenVib;
|
||||
roll += (SampleRandomFloat() - SampleRandomFloat()) * 0.2f * grenVib;
|
||||
vibPitch += (SampleRandomFloat() - SampleRandomFloat()) * 0.1f * grenVib;
|
||||
vibYaw += (SampleRandomFloat() - SampleRandomFloat()) * 0.1f * grenVib;
|
||||
scale -= (SampleRandomFloat() - SampleRandomFloat()) * 0.1f * grenVib;
|
||||
|
||||
def.radialBlur += grenVib * 0.1f;
|
||||
}
|
||||
|
@ -524,7 +524,7 @@ namespace spades {
|
||||
lastHurtTime = world->GetTime();
|
||||
|
||||
Handle<IAudioChunk> c;
|
||||
switch ((mt_engine_client() >> 3) & 3) {
|
||||
switch (SampleRandomInt(0, 3)) {
|
||||
case 0:
|
||||
c = audioDevice->RegisterSound("Sounds/Weapons/Impacts/FleshLocal1.opus");
|
||||
break;
|
||||
@ -545,10 +545,10 @@ namespace spades {
|
||||
hurtSprites.resize(std::max(cnt, 6));
|
||||
for (size_t i = 0; i < hurtSprites.size(); i++) {
|
||||
HurtSprite &spr = hurtSprites[i];
|
||||
spr.angle = GetRandom() * (2.f * static_cast<float>(M_PI));
|
||||
spr.scale = .2f + GetRandom() * GetRandom() * .7f;
|
||||
spr.horzShift = GetRandom();
|
||||
spr.strength = .3f + GetRandom() * .7f;
|
||||
spr.angle = SampleRandomFloat() * (2.f * static_cast<float>(M_PI));
|
||||
spr.scale = .2f + SampleRandomFloat() * SampleRandomFloat() * .7f;
|
||||
spr.horzShift = SampleRandomFloat();
|
||||
spr.strength = .3f + SampleRandomFloat() * .7f;
|
||||
if (hpper > .5f) {
|
||||
spr.strength *= 1.5f - hpper;
|
||||
}
|
||||
@ -605,17 +605,17 @@ namespace spades {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
if (!IsMuted()) {
|
||||
const char *snds[] = {"Sounds/Player/Footstep1.opus", "Sounds/Player/Footstep2.opus",
|
||||
std::array<const char *, 8> snds = {"Sounds/Player/Footstep1.opus", "Sounds/Player/Footstep2.opus",
|
||||
"Sounds/Player/Footstep3.opus", "Sounds/Player/Footstep4.opus",
|
||||
"Sounds/Player/Footstep5.opus", "Sounds/Player/Footstep6.opus",
|
||||
"Sounds/Player/Footstep7.opus", "Sounds/Player/Footstep8.opus"};
|
||||
const char *rsnds[] = {
|
||||
std::array<const char *, 12> rsnds = {
|
||||
"Sounds/Player/Run1.opus", "Sounds/Player/Run2.opus", "Sounds/Player/Run3.opus",
|
||||
"Sounds/Player/Run4.opus", "Sounds/Player/Run5.opus", "Sounds/Player/Run6.opus",
|
||||
"Sounds/Player/Run7.opus", "Sounds/Player/Run8.opus", "Sounds/Player/Run9.opus",
|
||||
"Sounds/Player/Run10.opus", "Sounds/Player/Run11.opus", "Sounds/Player/Run12.opus",
|
||||
};
|
||||
const char *wsnds[] = {"Sounds/Player/Wade1.opus", "Sounds/Player/Wade2.opus",
|
||||
std::array<const char *, 8> wsnds = {"Sounds/Player/Wade1.opus", "Sounds/Player/Wade2.opus",
|
||||
"Sounds/Player/Wade3.opus", "Sounds/Player/Wade4.opus",
|
||||
"Sounds/Player/Wade5.opus", "Sounds/Player/Wade6.opus",
|
||||
"Sounds/Player/Wade7.opus", "Sounds/Player/Wade8.opus"};
|
||||
@ -623,13 +623,13 @@ namespace spades {
|
||||
? clientPlayers[p->GetId()]->GetSprintState() > 0.5f
|
||||
: false;
|
||||
Handle<IAudioChunk> c =
|
||||
p->GetWade() ? audioDevice->RegisterSound(wsnds[(mt_engine_client() >> 8) % 8])
|
||||
: audioDevice->RegisterSound(snds[(mt_engine_client() >> 8) % 8]);
|
||||
p->GetWade() ? audioDevice->RegisterSound(SampleRandomElement(wsnds))
|
||||
: audioDevice->RegisterSound(SampleRandomElement(snds));
|
||||
audioDevice->Play(c, p->GetOrigin(), AudioParam());
|
||||
if (sprinting && !p->GetWade()) {
|
||||
AudioParam param;
|
||||
param.volume *= clientPlayers[p->GetId()]->GetSprintState();
|
||||
c = audioDevice->RegisterSound(rsnds[(mt_engine_client() >> 8) % 12]);
|
||||
c = audioDevice->RegisterSound(SampleRandomElement(rsnds));
|
||||
audioDevice->Play(c, p->GetOrigin(), param);
|
||||
}
|
||||
}
|
||||
@ -779,7 +779,7 @@ namespace spades {
|
||||
if (victim != world->GetLocalPlayer()) {
|
||||
if (!IsMuted()) {
|
||||
Handle<IAudioChunk> c;
|
||||
switch (mt_engine_client() % 3) {
|
||||
switch (SampleRandomInt(0, 2)) {
|
||||
case 0:
|
||||
c = audioDevice->RegisterSound("Sounds/Weapons/Impacts/Flesh1.opus");
|
||||
break;
|
||||
@ -839,7 +839,7 @@ namespace spades {
|
||||
}
|
||||
corp->AddImpulse(dir);
|
||||
} else if (kt == KillTypeGrenade) {
|
||||
corp->AddImpulse(MakeVector3(0, 0, -4.f - GetRandom() * 4.f));
|
||||
corp->AddImpulse(MakeVector3(0, 0, -4.f - SampleRandomFloat() * 4.f));
|
||||
}
|
||||
corp->AddImpulse(victim->GetVelocty() * 32.f);
|
||||
corpses.emplace_back(corp);
|
||||
@ -964,7 +964,7 @@ namespace spades {
|
||||
audioDevice->Play(c, hitPos, AudioParam());
|
||||
} else {
|
||||
Handle<IAudioChunk> c;
|
||||
switch ((mt_engine_client() >> 6) % 3) {
|
||||
switch (SampleRandomInt(0, 2)) {
|
||||
case 0:
|
||||
c = audioDevice->RegisterSound("Sounds/Weapons/Impacts/Flesh1.opus");
|
||||
break;
|
||||
@ -1019,8 +1019,8 @@ namespace spades {
|
||||
|
||||
Handle<IAudioChunk> c;
|
||||
|
||||
param.pitch = .9f + GetRandom() * 0.2f;
|
||||
switch ((mt_engine_client() >> 6) & 3) {
|
||||
param.pitch = .9f + SampleRandomFloat() * 0.2f;
|
||||
switch (SampleRandomInt(0, 3)) {
|
||||
case 0:
|
||||
c = audioDevice->RegisterSound("Sounds/Weapons/Impacts/Water1.opus");
|
||||
break;
|
||||
@ -1044,20 +1044,12 @@ namespace spades {
|
||||
param.volume = 2.f;
|
||||
|
||||
Handle<IAudioChunk> c;
|
||||
|
||||
switch ((mt_engine_client() >> 6) & 3) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
c = audioDevice->RegisterSound("Sounds/Weapons/Impacts/Block.opus");
|
||||
break;
|
||||
}
|
||||
c = audioDevice->RegisterSound("Sounds/Weapons/Impacts/Block.opus");
|
||||
audioDevice->Play(c, shiftedHitPos, param);
|
||||
|
||||
param.pitch = .9f + GetRandom() * 0.2f;
|
||||
param.pitch = .9f + SampleRandomFloat() * 0.2f;
|
||||
param.volume = 2.f;
|
||||
switch ((mt_engine_client() >> 6) & 3) {
|
||||
switch (SampleRandomInt(0, 3)) {
|
||||
case 0:
|
||||
c = audioDevice->RegisterSound("Sounds/Weapons/Impacts/Ricochet1.opus");
|
||||
break;
|
||||
@ -1170,7 +1162,7 @@ namespace spades {
|
||||
if (!IsMuted()) {
|
||||
Handle<IAudioChunk> c, cs;
|
||||
|
||||
switch ((mt_engine_client() >> 8) & 1) {
|
||||
switch (SampleRandomInt(0, 1)) {
|
||||
case 0:
|
||||
c = audioDevice->RegisterSound("Sounds/Weapons/Grenade/Explode1.opus");
|
||||
cs = audioDevice->RegisterSound(
|
||||
|
@ -54,50 +54,56 @@ namespace spades {
|
||||
|
||||
Matrix4 torso;
|
||||
|
||||
LocalRNG rng;
|
||||
|
||||
if (crouch) {
|
||||
lower = lower * Matrix4::Translate(0, 0, -0.4f);
|
||||
torso = lower * Matrix4::Translate(0, 0, -0.3f);
|
||||
|
||||
SetNode(Torso1, torso * MakeVector3(0.4f, -.15f, 0.1f));
|
||||
SetNode(Torso2, torso * MakeVector3(-0.4f, -.15f, 0.1f));
|
||||
SetNode(Torso3, torso * MakeVector3(-0.4f, .8f, 0.7f));
|
||||
SetNode(Torso4, torso * MakeVector3(0.4f, .8f, 0.7f));
|
||||
SetNode(rng, Torso1, torso * MakeVector3(0.4f, -.15f, 0.1f));
|
||||
SetNode(rng, Torso2, torso * MakeVector3(-0.4f, -.15f, 0.1f));
|
||||
SetNode(rng, Torso3, torso * MakeVector3(-0.4f, .8f, 0.7f));
|
||||
SetNode(rng, Torso4, torso * MakeVector3(0.4f, .8f, 0.7f));
|
||||
|
||||
SetNode(Leg1, lower * MakeVector3(-0.4f, .1f, 1.f));
|
||||
SetNode(Leg2, lower * MakeVector3(0.4f, .1f, 1.f));
|
||||
SetNode(rng, Leg1, lower * MakeVector3(-0.4f, .1f, 1.f));
|
||||
SetNode(rng, Leg2, lower * MakeVector3(0.4f, .1f, 1.f));
|
||||
|
||||
SetNode(Arm1, torso * MakeVector3(0.2f, -.4f, .2f));
|
||||
SetNode(Arm2, torso * MakeVector3(-0.2f, -.4f, .2f));
|
||||
SetNode(rng, Arm1, torso * MakeVector3(0.2f, -.4f, .2f));
|
||||
SetNode(rng, Arm2, torso * MakeVector3(-0.2f, -.4f, .2f));
|
||||
|
||||
} else {
|
||||
torso = lower * Matrix4::Translate(0, 0, -1.1f);
|
||||
|
||||
SetNode(Torso1, torso * MakeVector3(0.4f, 0.f, 0.1f));
|
||||
SetNode(Torso2, torso * MakeVector3(-0.4f, 0.f, 0.1f));
|
||||
SetNode(Torso3, torso * MakeVector3(-0.4f, .0f, 1.f));
|
||||
SetNode(Torso4, torso * MakeVector3(0.4f, .0f, 1.f));
|
||||
SetNode(rng, Torso1, torso * MakeVector3(0.4f, 0.f, 0.1f));
|
||||
SetNode(rng, Torso2, torso * MakeVector3(-0.4f, 0.f, 0.1f));
|
||||
SetNode(rng, Torso3, torso * MakeVector3(-0.4f, .0f, 1.f));
|
||||
SetNode(rng, Torso4, torso * MakeVector3(0.4f, .0f, 1.f));
|
||||
|
||||
SetNode(Leg1, lower * MakeVector3(-0.4f, .0f, 1.f));
|
||||
SetNode(Leg2, lower * MakeVector3(0.4f, .0f, 1.f));
|
||||
SetNode(rng, Leg1, lower * MakeVector3(-0.4f, .0f, 1.f));
|
||||
SetNode(rng, Leg2, lower * MakeVector3(0.4f, .0f, 1.f));
|
||||
|
||||
SetNode(Arm1, torso * MakeVector3(0.2f, -.4f, .2f));
|
||||
SetNode(Arm2, torso * MakeVector3(-0.2f, -.4f, .2f));
|
||||
SetNode(rng, Arm1, torso * MakeVector3(0.2f, -.4f, .2f));
|
||||
SetNode(rng, Arm2, torso * MakeVector3(-0.2f, -.4f, .2f));
|
||||
}
|
||||
|
||||
SetNode(Head, (nodes[Torso1].pos + nodes[Torso2].pos) * .5f + MakeVector3(0, 0, -0.6f));
|
||||
SetNode(rng, Head,
|
||||
(nodes[Torso1].pos + nodes[Torso2].pos) * .5f + MakeVector3(0, 0, -0.6f));
|
||||
}
|
||||
|
||||
static float VelNoise() { return (GetRandom() - GetRandom()) * 2.f; }
|
||||
void Corpse::SetNode(LocalRNG &rng, NodeType n, spades::Vector3 v) {
|
||||
auto velNoise = [&] { return (rng.SampleFloat() - rng.SampleFloat()) * 2.0f; };
|
||||
|
||||
void Corpse::SetNode(NodeType n, spades::Vector3 v) {
|
||||
SPAssert(n >= 0);
|
||||
SPAssert(n < NodeCount);
|
||||
|
||||
nodes[n].pos = v;
|
||||
nodes[n].vel = MakeVector3(VelNoise(), VelNoise(), 0.f);
|
||||
nodes[n].vel = MakeVector3(velNoise(), velNoise(), 0.f);
|
||||
nodes[n].lastPos = v;
|
||||
nodes[n].lastForce = MakeVector3(0, 0, 0);
|
||||
}
|
||||
void Corpse::SetNode(NodeType n, spades::Vector4 v) { SetNode(n, v.GetXYZ()); }
|
||||
void Corpse::SetNode(LocalRNG &rng, NodeType n, spades::Vector4 v) {
|
||||
SetNode(rng, n, v.GetXYZ());
|
||||
}
|
||||
|
||||
Corpse::~Corpse() {}
|
||||
|
||||
|
@ -69,8 +69,8 @@ namespace spades {
|
||||
Node nodes[NodeCount];
|
||||
Edge edges[8];
|
||||
|
||||
void SetNode(NodeType n, Vector3);
|
||||
void SetNode(NodeType n, Vector4);
|
||||
void SetNode(LocalRNG&, NodeType n, Vector3);
|
||||
void SetNode(LocalRNG&, NodeType n, Vector4);
|
||||
|
||||
void Spring(NodeType n1, NodeType n2, float distance, float dt);
|
||||
void Spring(NodeType n1a, NodeType n1b, NodeType n2, float distance, float dt);
|
||||
|
@ -135,6 +135,9 @@ namespace spades {
|
||||
client->grenadeVibration += impact / (dist + 5.f);
|
||||
if (client->grenadeVibration > 1.f)
|
||||
client->grenadeVibration = 1.f;
|
||||
|
||||
LocalRNG rng;
|
||||
auto getRandom = [&] { return rng.SampleFloat(); };
|
||||
|
||||
for (int x = 0; x < w; x++) {
|
||||
Vector3 p1 = vmOrigin + vmAxis1 * (float)x;
|
||||
@ -162,15 +165,15 @@ namespace spades {
|
||||
{
|
||||
ParticleSpriteEntity *ent =
|
||||
new SmokeSpriteEntity(client, col, 70.f);
|
||||
ent->SetTrajectory(p3, (MakeVector3(GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom())) *
|
||||
ent->SetTrajectory(p3, (MakeVector3(getRandom() - getRandom(),
|
||||
getRandom() - getRandom(),
|
||||
getRandom() - getRandom())) *
|
||||
0.2f,
|
||||
1.f, 0.f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRotation(getRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(1.0f, 0.5f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
ent->SetLifeTime(1.0f + GetRandom() * 0.5f, 0.f, 1.0f);
|
||||
ent->SetLifeTime(1.0f + getRandom() * 0.5f, 0.f, 1.0f);
|
||||
client->AddLocalEntity(ent);
|
||||
}
|
||||
|
||||
@ -178,13 +181,13 @@ namespace spades {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
ParticleSpriteEntity *ent =
|
||||
new ParticleSpriteEntity(client, img, col);
|
||||
ent->SetTrajectory(p3, MakeVector3(GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom()) *
|
||||
ent->SetTrajectory(p3, MakeVector3(getRandom() - getRandom(),
|
||||
getRandom() - getRandom(),
|
||||
getRandom() - getRandom()) *
|
||||
13.f,
|
||||
1.f, .6f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.35f + GetRandom() * GetRandom() * 0.1f);
|
||||
ent->SetRotation(getRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.35f + getRandom() * getRandom() * 0.1f);
|
||||
ent->SetLifeTime(2.f, 0.f, 1.f);
|
||||
if (usePrecisePhysics)
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::BounceWeak);
|
||||
@ -215,4 +218,4 @@ namespace spades {
|
||||
client->GetRenderer()->RenderModel(model, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,12 +37,14 @@ namespace spades {
|
||||
GameMap::GameMap() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
LocalRNG rng;
|
||||
|
||||
for (int x = 0; x < DefaultWidth; x++)
|
||||
for (int y = 0; y < DefaultHeight; y++) {
|
||||
solidMap[x][y] = 1; // ground only
|
||||
for (int z = 0; z < DefaultDepth; z++) {
|
||||
uint32_t col = 0x00284067;
|
||||
col ^= 0x070707 & static_cast<uint32_t>(mt_engine());
|
||||
col ^= 0x070707 & static_cast<uint32_t>(rng());
|
||||
colorMap[x][y][z] = col + (100UL * 0x1000000UL);
|
||||
}
|
||||
}
|
||||
|
@ -64,9 +64,9 @@ namespace spades {
|
||||
}
|
||||
static Vector3 RandomAxis() {
|
||||
Vector3 v;
|
||||
v.x = GetRandom() - GetRandom();
|
||||
v.y = GetRandom() - GetRandom();
|
||||
v.z = GetRandom() - GetRandom();
|
||||
v.x = SampleRandomFloat() - SampleRandomFloat();
|
||||
v.y = SampleRandomFloat() - SampleRandomFloat();
|
||||
v.z = SampleRandomFloat() - SampleRandomFloat();
|
||||
return v.Normalize();
|
||||
}
|
||||
bool GunCasing::Update(float dt) {
|
||||
@ -100,7 +100,7 @@ namespace spades {
|
||||
IAudioDevice *dev = client->GetAudioDevice();
|
||||
AudioParam param;
|
||||
param.referenceDistance = .6f;
|
||||
param.pitch = .9f + GetRandom() * .2f;
|
||||
param.pitch = .9f + SampleRandomFloat() * .2f;
|
||||
|
||||
dev->Play(waterSound, lastMat.GetOrigin(), param);
|
||||
}
|
||||
@ -108,7 +108,7 @@ namespace spades {
|
||||
}
|
||||
|
||||
if (dist < 40.f * 40.f) {
|
||||
int splats = mt_engine_client() % 3;
|
||||
int splats = SampleRandomInt(0, 2);
|
||||
|
||||
Handle<IImage> img = client->GetRenderer()->RegisterImage("Gfx/White.tga");
|
||||
|
||||
@ -117,13 +117,15 @@ namespace spades {
|
||||
pt.z = 62.99f;
|
||||
for (int i = 0; i < splats; i++) {
|
||||
ParticleSpriteEntity *ent = new ParticleSpriteEntity(client, img, col);
|
||||
ent->SetTrajectory(pt, MakeVector3(GetRandom() - GetRandom(),
|
||||
GetRandom() - GetRandom(),
|
||||
-GetRandom()) *
|
||||
2.f,
|
||||
1.f, .4f);
|
||||
ent->SetRotation(GetRandom() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.1f + GetRandom() * GetRandom() * 0.1f);
|
||||
ent->SetTrajectory(
|
||||
pt,
|
||||
MakeVector3(SampleRandomFloat() - SampleRandomFloat(),
|
||||
SampleRandomFloat() - SampleRandomFloat(),
|
||||
-SampleRandomFloat()) *
|
||||
2.f,
|
||||
1.f, .4f);
|
||||
ent->SetRotation(SampleRandomFloat() * (float)M_PI * 2.f);
|
||||
ent->SetRadius(0.1f + SampleRandomFloat() * SampleRandomFloat() * 0.1f);
|
||||
ent->SetLifeTime(2.f, 0.f, 1.f);
|
||||
client->AddLocalEntity(ent);
|
||||
}
|
||||
@ -194,9 +196,9 @@ namespace spades {
|
||||
rotAxis = RandomAxis();
|
||||
|
||||
Vector3 r;
|
||||
r.x = GetRandom() - GetRandom();
|
||||
r.y = GetRandom() - GetRandom();
|
||||
r.z = GetRandom() - GetRandom();
|
||||
r.x = SampleRandomFloat() - SampleRandomFloat();
|
||||
r.y = SampleRandomFloat() - SampleRandomFloat();
|
||||
r.z = SampleRandomFloat() - SampleRandomFloat();
|
||||
|
||||
vel += r * 0.1f;
|
||||
|
||||
|
@ -665,7 +665,7 @@ namespace spades {
|
||||
|
||||
visibleLength = shutterTime * velocity;
|
||||
curDistance = -visibleLength;
|
||||
curDistance += maxTimeSpread * GetRandom();
|
||||
curDistance += maxTimeSpread * SampleRandomFloat();
|
||||
|
||||
firstUpdate = true;
|
||||
}
|
||||
|
@ -27,9 +27,11 @@ namespace spades {
|
||||
namespace client {
|
||||
|
||||
CoherentNoiseSampler1D::CoherentNoiseSampler1D() {
|
||||
LocalRNG rng;
|
||||
|
||||
values.resize(1024);
|
||||
for (float &value : values) {
|
||||
value = GetRandom() - GetRandom();
|
||||
value = rng.SampleFloat() - rng.SampleFloat();
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,9 +56,11 @@ namespace spades {
|
||||
}
|
||||
|
||||
GradientCoherentNoiseSampler1D::GradientCoherentNoiseSampler1D() {
|
||||
LocalRNG rng;
|
||||
|
||||
derivatives.resize(1024);
|
||||
for (float &derivative : derivatives) {
|
||||
derivative = (GetRandom() - GetRandom()) * 4.f;
|
||||
derivative = (rng.SampleFloat() - rng.SampleFloat()) * 4.f;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -564,14 +564,16 @@ namespace spades {
|
||||
// pyspades takes destroying more than one block as a
|
||||
// speed hack (shotgun does this)
|
||||
bool blockDestroyed = false;
|
||||
|
||||
LocalRNG rng;
|
||||
|
||||
Vector3 dir2 = GetFront();
|
||||
for (int i = 0; i < pellets; i++) {
|
||||
|
||||
// AoS 0.75's way (dir2 shouldn't be normalized!)
|
||||
dir2.x += (GetRandom() - GetRandom()) * spread;
|
||||
dir2.y += (GetRandom() - GetRandom()) * spread;
|
||||
dir2.z += (GetRandom() - GetRandom()) * spread;
|
||||
dir2.x += (rng.SampleFloat() - rng.SampleFloat()) * spread;
|
||||
dir2.y += (rng.SampleFloat() - rng.SampleFloat()) * spread;
|
||||
dir2.z += (rng.SampleFloat() - rng.SampleFloat()) * spread;
|
||||
Vector3 dir = dir2.Normalize();
|
||||
|
||||
bulletVectors.push_back(dir);
|
||||
|
@ -25,7 +25,7 @@ namespace spades {
|
||||
|
||||
visibleLength = shutterTime * velocity;
|
||||
curDistance = -visibleLength;
|
||||
curDistance += maxTimeSpread * GetRandom();
|
||||
curDistance += maxTimeSpread * SampleRandomFloat();
|
||||
|
||||
firstUpdate = true;
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <new>
|
||||
#include <cstdlib>
|
||||
#include <mutex>
|
||||
|
||||
#include "Math.h"
|
||||
#include <Core/Debug.h>
|
||||
@ -37,11 +38,37 @@ namespace spades {
|
||||
}
|
||||
*/
|
||||
|
||||
std::random_device r_device;
|
||||
std::mt19937_64
|
||||
mt_engine(r_device()); // Seed Mersenne twister with non-deterministic 32-bit seed
|
||||
namespace {
|
||||
std::random_device r_device;
|
||||
} // namespace
|
||||
|
||||
std::uniform_real_distribution<float> real_dist(0, 1);
|
||||
ThreadSafeRNG globalThreadSafeRNG;
|
||||
|
||||
// Seed Mersenne twister with non-deterministic seed
|
||||
ThreadSafeRNG::ThreadSafeRNG() : inner{r_device()} {}
|
||||
|
||||
auto ThreadSafeRNG::operator()() -> result_type {
|
||||
std::lock_guard<std::mutex> lock{mutex};
|
||||
return inner();
|
||||
}
|
||||
|
||||
LocalRNG::LocalRNG() {
|
||||
do {
|
||||
s[0] = SampleRandom();
|
||||
} while (s[0] == 0);
|
||||
do {
|
||||
s[1] = SampleRandom();
|
||||
} while (s[1] == 0);
|
||||
}
|
||||
|
||||
auto LocalRNG::operator()() -> result_type {
|
||||
uint64_t x = s[0];
|
||||
uint64_t y = s[1];
|
||||
s[0] = y;
|
||||
x ^= x << 23; // a
|
||||
s[1] = x ^ y ^ (x >> 17) ^ (y >> 26); // b, c
|
||||
return s[1] + y;
|
||||
}
|
||||
|
||||
void Matrix4Multiply(const float a[16], const float b[16], float out[16]) {
|
||||
out[0] = b[0] * a[0] + b[1] * a[4] + b[2] * a[8] + b[3] * a[12];
|
||||
@ -634,7 +661,6 @@ namespace spades {
|
||||
return (uint32_t)str[start];
|
||||
}
|
||||
|
||||
float GetRandom() { return real_dist(mt_engine); }
|
||||
float SmoothStep(float v) { return v * v * (3.f - 2.f * v); }
|
||||
|
||||
float Mix(float a, float b, float frac) { return a + (b - a) * frac; }
|
||||
|
@ -30,9 +30,88 @@
|
||||
|
||||
namespace spades {
|
||||
|
||||
// Make mt_engine and a real dist [0,1] accesible everywhere in the spades namespace
|
||||
extern std::mt19937_64 mt_engine;
|
||||
extern std::uniform_real_distribution<float> real_dist;
|
||||
#pragma mark - Random number generation
|
||||
/**
|
||||
* A thread-safe random number generator satistying
|
||||
* `UniformRandomBitGenerator`.
|
||||
*/
|
||||
class ThreadSafeRNG {
|
||||
public:
|
||||
using inner_type = std::mt19937_64;
|
||||
using result_type = inner_type::result_type;
|
||||
|
||||
ThreadSafeRNG();
|
||||
|
||||
result_type operator()();
|
||||
|
||||
static constexpr result_type min() { return inner_type::min(); }
|
||||
static constexpr result_type max() { return inner_type::max(); }
|
||||
|
||||
private:
|
||||
inner_type inner;
|
||||
std::mutex mutex;
|
||||
};
|
||||
|
||||
extern ThreadSafeRNG globalThreadSafeRNG;
|
||||
|
||||
/** Generates a random `uint_fast64_t`. This function is thread-safe. */
|
||||
inline std::uint_fast64_t SampleRandom() { return globalThreadSafeRNG(); }
|
||||
|
||||
/** Generates a random `float`. This function is thread-safe. */
|
||||
inline float SampleRandomFloat() {
|
||||
return std::uniform_real_distribution<float>{}(globalThreadSafeRNG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an integer in a specified inclusive range.
|
||||
* This function is thread-safe.
|
||||
*/
|
||||
template <class T = int> inline T SampleRandomInt(T a, T b) {
|
||||
return std::uniform_int_distribution<T>{a, b}(globalThreadSafeRNG);
|
||||
}
|
||||
|
||||
/** Generates a random `bool`. This function is thread-safe. */
|
||||
inline bool SampleRandomBool() { return globalThreadSafeRNG() & 0x1; }
|
||||
|
||||
/** Get a mutable reference to a random element from a container. */
|
||||
template <class T> inline typename T::reference SampleRandomElement(T &container) {
|
||||
auto begin = std::begin(container);
|
||||
auto end = std::end(container);
|
||||
auto numElements = std::distance(begin, end);
|
||||
begin += SampleRandomInt<typeof(numElements)>(0, numElements - 1);
|
||||
return *begin;
|
||||
}
|
||||
|
||||
/** Get a constant reference to a random element from a container. */
|
||||
template <class T> inline typename T::const_reference SampleRandomElement(const T &container) {
|
||||
auto begin = std::begin(container);
|
||||
auto end = std::end(container);
|
||||
auto numElements = std::distance(begin, end);
|
||||
begin += SampleRandomInt(0, numElements - 1);
|
||||
return *begin;
|
||||
}
|
||||
|
||||
/** Thread-unsafe random number generator. */
|
||||
class LocalRNG {
|
||||
public:
|
||||
using result_type = std::uint64_t;
|
||||
|
||||
LocalRNG();
|
||||
|
||||
result_type operator()();
|
||||
|
||||
float SampleFloat() { return std::uniform_real_distribution<float>{}(*this); }
|
||||
|
||||
template <class T = int> inline T SampleInt(T a, T b) {
|
||||
return std::uniform_int_distribution<T>{a, b}(*this);
|
||||
}
|
||||
|
||||
static constexpr result_type min() { return 0; }
|
||||
static constexpr result_type max() { return std::numeric_limits<result_type>::max(); }
|
||||
|
||||
private:
|
||||
std::uint64_t s[2];
|
||||
};
|
||||
|
||||
#pragma mark - Integer Vector
|
||||
|
||||
@ -936,7 +1015,6 @@ namespace spades {
|
||||
|
||||
std::string TrimSpaces(const std::string &);
|
||||
|
||||
float GetRandom();
|
||||
float SmoothStep(float);
|
||||
}
|
||||
|
||||
|
@ -47,9 +47,11 @@ namespace spades {
|
||||
GLAmbientShadowRenderer::GLAmbientShadowRenderer(GLRenderer *r, client::GameMap *m)
|
||||
: renderer(r), device(r->GetGLDevice()), map(m) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
LocalRNG rng;
|
||||
|
||||
for (int i = 0; i < NumRays; i++) {
|
||||
Vector3 dir = MakeVector3(GetRandom(), GetRandom(), GetRandom());
|
||||
Vector3 dir = MakeVector3(rng.SampleFloat(), rng.SampleFloat(), rng.SampleFloat());
|
||||
dir = dir.Normalize();
|
||||
dir += 0.01f;
|
||||
rays[i] = dir;
|
||||
@ -337,10 +339,11 @@ namespace spades {
|
||||
}
|
||||
|
||||
// limit update count per frame
|
||||
LocalRNG rng;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (numDirtyChunks <= 0)
|
||||
break;
|
||||
int idx = mt_engine() % numDirtyChunks;
|
||||
int idx = rng.SampleInt(0, numDirtyChunks - 1);
|
||||
Chunk &c = chunks[dirtyChunkIds[idx]];
|
||||
|
||||
// remove from list (fast)
|
||||
|
@ -139,9 +139,10 @@ namespace spades {
|
||||
void GLLensDustFilter::UpdateNoise() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
LocalRNG rng;
|
||||
noise.resize(128 * 128);
|
||||
for (size_t i = 0; i < 128 * 128; i++) {
|
||||
noise[i] = static_cast<std::uint32_t>(mt_engine());
|
||||
noise[i] = static_cast<std::uint32_t>(rng());
|
||||
}
|
||||
|
||||
IGLDevice *dev = renderer->GetGLDevice();
|
||||
|
@ -438,10 +438,11 @@ namespace spades {
|
||||
}
|
||||
|
||||
// limit update count per frame
|
||||
LocalRNG rng;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (numDirtyChunks <= 0)
|
||||
break;
|
||||
int idx = mt_engine() % numDirtyChunks;
|
||||
int idx = rng.SampleInt(0, numDirtyChunks - 1);
|
||||
Chunk &c = chunks[dirtyChunkIds[idx]];
|
||||
|
||||
// remove from list (fast)
|
||||
|
@ -187,6 +187,9 @@ namespace spades {
|
||||
|
||||
public:
|
||||
FFTWaveTank() : IWaveTank(Size) {
|
||||
LocalRNG rng;
|
||||
auto getRandom = [&] { return rng.SampleFloat(); };
|
||||
|
||||
fft = kiss_fft_alloc(Size, 1, NULL, NULL);
|
||||
|
||||
for (int x = 0; x < Size; x++) {
|
||||
@ -207,14 +210,14 @@ namespace spades {
|
||||
mag *= expf(-scal * 3.f);
|
||||
|
||||
cell.magnitude = mag;
|
||||
cell.phase = static_cast<uint32_t>(mt_engine());
|
||||
cell.phase = static_cast<uint32_t>(rng());
|
||||
cell.phasePerSecond = dist * 1.e+9f * 128 / Size;
|
||||
}
|
||||
|
||||
cell.m00 = GetRandom() - GetRandom();
|
||||
cell.m01 = GetRandom() - GetRandom();
|
||||
cell.m10 = GetRandom() - GetRandom();
|
||||
cell.m11 = GetRandom() - GetRandom();
|
||||
cell.m00 = getRandom() - getRandom();
|
||||
cell.m01 = getRandom() - getRandom();
|
||||
cell.m10 = getRandom() - getRandom();
|
||||
cell.m11 = getRandom() - getRandom();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -420,12 +423,13 @@ namespace spades {
|
||||
int count = (int)floorf(dt * 600.f);
|
||||
if (count > 400)
|
||||
count = 400;
|
||||
LocalRNG rng;
|
||||
for (int i = 0; i < count; i++) {
|
||||
int ox = mt_engine() % (size - 2);
|
||||
int oy = mt_engine() % (size - 2);
|
||||
int ox = rng.SampleInt(0, size - 3);
|
||||
int oy = rng.SampleInt(0, size - 3);
|
||||
static const float gauss[] = {0.225610111284052f, 0.548779777431897f,
|
||||
0.225610111284052f};
|
||||
float strength = (GetRandom() - GetRandom()) * 0.15f * 100.f;
|
||||
float strength = (rng.SampleFloat() - rng.SampleFloat()) * 0.15f * 100.f;
|
||||
for (int x = 0; x < 3; x++)
|
||||
for (int y = 0; y < 3; y++) {
|
||||
velocity[(x + ox) + (y + oy) * size] += strength * gauss[x] * gauss[y];
|
||||
|
@ -35,24 +35,22 @@ namespace spades {
|
||||
case 1:
|
||||
return 0;
|
||||
case 2:
|
||||
return mt_engine() & 1;
|
||||
return SampleRandom() & 1;
|
||||
case 4:
|
||||
return mt_engine() & 3;
|
||||
return SampleRandom() & 3;
|
||||
case 8:
|
||||
return mt_engine() & 7;
|
||||
return SampleRandom() & 7;
|
||||
case 16:
|
||||
return mt_engine() & 15;
|
||||
return SampleRandom() & 15;
|
||||
case 32:
|
||||
return mt_engine() & 31;
|
||||
return SampleRandom() & 31;
|
||||
case 64:
|
||||
return mt_engine() & 63;
|
||||
return SampleRandom() & 63;
|
||||
}
|
||||
// We can't directly use the engine here, we need a distribution
|
||||
|
||||
// range - 1 because it's inclusive and we want exclusive
|
||||
std::uniform_int_distribution<unsigned int> int_dist(0, range - 1);
|
||||
|
||||
return int_dist(mt_engine);
|
||||
return SampleRandomInt<unsigned int>(0, range - 1);
|
||||
}
|
||||
static unsigned int GetRandomUIntRange(unsigned int a,
|
||||
unsigned int b){
|
||||
@ -70,7 +68,7 @@ namespace spades {
|
||||
return (int)(GetRandomInt((unsigned int)(b - a)) + (unsigned int)a);
|
||||
}
|
||||
static float GetRandomFloatRange(float a, float b) {
|
||||
return GetRandom() * (b - a) + a;
|
||||
return SampleRandomFloat() * (b - a) + a;
|
||||
}
|
||||
public:
|
||||
MathScriptObjectRegistrar():
|
||||
@ -995,7 +993,7 @@ namespace spades {
|
||||
manager->CheckError(r);
|
||||
|
||||
r = eng->RegisterGlobalFunction("float GetRandom()",
|
||||
asFUNCTION(GetRandom),
|
||||
asFUNCTION(SampleRandomFloat),
|
||||
asCALL_CDECL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user