diff --git a/Source/Engine/Engine/RandomStream.cs b/Source/Engine/Engine/RandomStream.cs new file mode 100644 index 000000000..342faeb9c --- /dev/null +++ b/Source/Engine/Engine/RandomStream.cs @@ -0,0 +1,199 @@ +// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved. + +using System; +using System.Runtime.CompilerServices; + +#pragma warning disable 675 + +namespace FlaxEngine +{ + /// + /// Very basic pseudo numbers generator. + /// + [HideInEditor] + public class RandomStream + { + /// + /// Holds the initial seed. + /// + private int _initialSeed = 0; + + /// + /// Holds the current seed. + /// + private int _seed = 0; + + /// + /// Init + /// + public RandomStream() + { + _initialSeed = 0; + _seed = 0; + } + + /// + /// Creates and initializes a new random stream from the specified seed value. + /// + /// The seed value. + public RandomStream(int seed) + { + _initialSeed = seed; + _seed = seed; + } + + /// + /// Gets initial seed value + /// + public int GetInitialSeed() + { + return _initialSeed; + } + + + /// + /// Gets the current seed. + /// + public int GetCurrentSeed() + { + return _seed; + } + + /// + /// Initializes this random stream with the specified seed value. + /// + /// The seed value. + public void Initialize(int seed) + { + _initialSeed = seed; + _seed = seed; + } + + /// + /// Resets this random stream to the initial seed value. + /// + public void Reset() + { + _seed = _initialSeed; + } + + /// + /// Generates a new random seed. + /// + public void GenerateNewSeed() + { + Initialize(new System.Random().Next()); + } + + /// + /// Returns a random boolean. + /// + public unsafe bool GetBool() + { + MutateSeed(); + fixed (int* seedPtr= &_seed) + return *seedPtr < (uint.MaxValue/ 2); + } + + /// + /// Returns a random number between 0 and uint.MaxValue. + /// + public unsafe uint GetUnsignedInt() + { + MutateSeed(); + fixed (int* seedPtr = &_seed) + return (uint)*seedPtr; + } + + /// + /// Returns a random number between 0 and 1. + /// + public unsafe float GetFraction() + { + MutateSeed(); + float temp = 1.0f; + float result = 0.0f; + *(int*)&result = (int)((*(int*)&temp & 0xff800000) | (_seed & 0x007fffff)); + return Mathf.Frac(result); + } + + /// + /// Returns a random number between 0 and 1. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Rand() + { + return GetFraction(); + } + + /// + /// Returns a random vector of unit size. + /// + public Float3 GetUnitVector() + { + Float3 result; + float l; + do + { + result.X = GetFraction() * 2.0f - 1.0f; + result.Y = GetFraction() * 2.0f - 1.0f; + result.Z = GetFraction() * 2.0f - 1.0f; + l = result.LengthSquared; + } while (l > 1.0f || l < Mathf.Epsilon); + return Float3.Normalize(result); + } + + /// + /// Gets a random with components in a range between [0;1]. + /// + public Vector3 GetVector3() + { + return new Vector3(GetFraction(), GetFraction(), GetFraction()); + } + + /// + /// Helper function for rand implementations. + /// + /// Top border + /// A random number in [0..A) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int RandHelper(int a) + { + return a > 0 ? Mathf.FloorToInt(GetFraction() *((float)a - Mathf.Epsilon)) : 0; + } + + /// + /// Helper function for rand implementations + /// + /// Minimum value + /// Maximum value + /// A random number in [min; max] range + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int RandRange(int min, int max) + { + int range = max - min + 1; + return min + RandHelper(range); + } + + /// + /// Helper function for rand implementations + /// + /// Minimum value + /// Maximum value + /// A random number in [min; max] range + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float RandRange(float min, float max) + { + return min + (max - min) * Rand(); + } + + /// + /// Mutates the current seed into the next seed. + /// + protected void MutateSeed() + { + // This can be modified to provide better randomization + _seed = _seed * 196314165 + 907633515; + } + } +} diff --git a/Source/Engine/Engine/RandomUtil.cs b/Source/Engine/Engine/RandomUtil.cs new file mode 100644 index 000000000..aaeed860d --- /dev/null +++ b/Source/Engine/Engine/RandomUtil.cs @@ -0,0 +1,26 @@ +// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved. + +using System; +using System.Runtime.CompilerServices; + +namespace FlaxEngine +{ + /// + /// Basic pseudo numbers generator utility. + /// + [HideInEditor] + public class RandomUtil + { + private static readonly Random _random = new Random(); + + /// + /// Generates a pseudo-random number from normalized range [0;1]. + /// + /// The random number. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Rand() + { + return _random.Next(0, int.MaxValue) / (float)int.MaxValue; + } + } +}