From b920d6675a1acdc48e888594c2e22a28690a6138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Sun, 20 Nov 2016 13:41:16 -0800 Subject: [PATCH] Added Fisher-Yates shuffle. --- include/bx/rng.h | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/include/bx/rng.h b/include/bx/rng.h index 0a1976d..94b5783 100644 --- a/include/bx/rng.h +++ b/include/bx/rng.h @@ -8,6 +8,7 @@ #include "bx.h" #include "fpumath.h" +#include "uint32_t.h" namespace bx { @@ -94,23 +95,23 @@ namespace bx }; /// Returns random number between 0.0f and 1.0f. - template - inline float frnd(Ty* _rng) + template + inline float frnd(Rng* _rng) { uint32_t rnd = _rng->gen() & UINT16_MAX; return float(rnd) * 1.0f/float(UINT16_MAX); } /// Returns random number between -1.0f and 1.0f. - template - inline float frndh(Ty* _rng) + template + inline float frndh(Rng* _rng) { return 2.0f * bx::frnd(_rng) - 1.0f; } /// Generate random point on unit sphere. - template - static inline void randUnitSphere(float _result[3], Ty* _rng) + template + inline void randUnitSphere(float _result[3], Rng* _rng) { float rand0 = frnd(_rng) * 2.0f - 1.0f; float rand1 = frnd(_rng) * pi * 2.0f; @@ -123,7 +124,7 @@ namespace bx /// Generate random point on unit hemisphere. template - static inline void randUnitHemisphere(float _result[3], Ty* _rng, const float _normal[3]) + inline void randUnitHemisphere(float _result[3], Ty* _rng, const float _normal[3]) { float dir[3]; randUnitSphere(dir, _rng); @@ -148,7 +149,7 @@ namespace bx /// Sampling with Hammersley and Halton Points /// http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html /// - static inline void generateSphereHammersley(void* _data, uint32_t _stride, uint32_t _num, float _scale = 1.0f) + inline void generateSphereHammersley(void* _data, uint32_t _stride, uint32_t _num, float _scale = 1.0f) { uint8_t* data = (uint8_t*)_data; @@ -177,6 +178,19 @@ namespace bx } } + /// Fisher-Yates shuffle. + template + inline void shuffle(Rng* _rng, Ty* _array, uint32_t _num) + { + BX_CHECK(_num != 0, "Number of elements can't be 0!"); + + for (uint32_t ii = 0, num = _num-1; ii < num; ++ii) + { + uint32_t jj = ii + 1 + _rng->gen() % (num - ii); + bx::xchg(_array[ii], _array[jj]); + } + } + } // namespace bx #endif // BX_RNG_H_HEADER_GUARD