forked from Mirrors/openclonk
Fix randomness in particles with identical properties
Several issues: - The RNG wasn't copied with the value provider (which is always copied), resulting in unseeded RNGs. - Separate PCG streams with the same seed start with identical values. As particles often draw only a single value, we just always advance the RNG a bit to make the streams diverge. - The C++ specification requires a <= b for its distributions, but that wasn't guaranteed by the particle startValue/endValue.liquid_container
parent
cea685f7ea
commit
5471fe6cff
|
@ -218,6 +218,7 @@ C4ParticleValueProvider & C4ParticleValueProvider::operator= (const C4ParticleVa
|
|||
valueFunction = other.valueFunction;
|
||||
isConstant = other.isConstant;
|
||||
keyFrameCount = other.keyFrameCount;
|
||||
rng = other.rng;
|
||||
|
||||
if (keyFrameCount > 0)
|
||||
{
|
||||
|
@ -419,7 +420,9 @@ float C4ParticleValueProvider::Random(C4Particle *forParticle)
|
|||
// particles lie on the heap we just use the address here.
|
||||
const std::uintptr_t ourAddress = reinterpret_cast<std::uintptr_t>(forParticle);
|
||||
rng.set_stream(ourAddress);
|
||||
std::uniform_real_distribution<float> distribution(startValue, endValue);
|
||||
// We need to advance the RNG a bit to make streams with the same seed diverge.
|
||||
rng.advance(5);
|
||||
std::uniform_real_distribution<float> distribution(std::min(startValue, endValue), std::max(startValue, endValue));
|
||||
currentValue = distribution(rng);
|
||||
}
|
||||
return currentValue;
|
||||
|
|
Loading…
Reference in New Issue