Parcourir la source

Added Fisher-Yates shuffle.

Branimir Karadžić il y a 9 ans
Parent
commit
b920d6675a
1 fichiers modifiés avec 22 ajouts et 8 suppressions
  1. 22 8
      include/bx/rng.h

+ 22 - 8
include/bx/rng.h

@@ -8,6 +8,7 @@
 
 
 #include "bx.h"
 #include "bx.h"
 #include "fpumath.h"
 #include "fpumath.h"
+#include "uint32_t.h"
 
 
 namespace bx
 namespace bx
 {
 {
@@ -94,23 +95,23 @@ namespace bx
 	};
 	};
 
 
 	/// Returns random number between 0.0f and 1.0f.
 	/// Returns random number between 0.0f and 1.0f.
-	template <typename Ty>
-	inline float frnd(Ty* _rng)
+	template <typename Rng>
+	inline float frnd(Rng* _rng)
 	{
 	{
 		uint32_t rnd = _rng->gen() & UINT16_MAX;
 		uint32_t rnd = _rng->gen() & UINT16_MAX;
 		return float(rnd) * 1.0f/float(UINT16_MAX);
 		return float(rnd) * 1.0f/float(UINT16_MAX);
 	}
 	}
 
 
 	/// Returns random number between -1.0f and 1.0f.
 	/// Returns random number between -1.0f and 1.0f.
-	template <typename Ty>
-	inline float frndh(Ty* _rng)
+	template <typename Rng>
+	inline float frndh(Rng* _rng)
 	{
 	{
 		return 2.0f * bx::frnd(_rng) - 1.0f;
 		return 2.0f * bx::frnd(_rng) - 1.0f;
 	}
 	}
 
 
 	/// Generate random point on unit sphere.
 	/// Generate random point on unit sphere.
-	template <typename Ty>
-	static inline void randUnitSphere(float _result[3], Ty* _rng)
+	template <typename Rng>
+	inline void randUnitSphere(float _result[3], Rng* _rng)
 	{
 	{
 		float rand0 = frnd(_rng) * 2.0f - 1.0f;
 		float rand0 = frnd(_rng) * 2.0f - 1.0f;
 		float rand1 = frnd(_rng) * pi * 2.0f;
 		float rand1 = frnd(_rng) * pi * 2.0f;
@@ -123,7 +124,7 @@ namespace bx
 
 
 	/// Generate random point on unit hemisphere.
 	/// Generate random point on unit hemisphere.
 	template <typename Ty>
 	template <typename Ty>
-	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];
 		float dir[3];
 		randUnitSphere(dir, _rng);
 		randUnitSphere(dir, _rng);
@@ -148,7 +149,7 @@ namespace bx
 	/// Sampling with Hammersley and Halton Points
 	/// Sampling with Hammersley and Halton Points
 	/// http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html
 	/// 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;
 		uint8_t* data = (uint8_t*)_data;
 
 
@@ -177,6 +178,19 @@ namespace bx
 		}
 		}
 	}
 	}
 
 
+	/// Fisher-Yates shuffle.
+	template<typename Rng, typename Ty>
+	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
 } // namespace bx
 
 
 #endif // BX_RNG_H_HEADER_GUARD
 #endif // BX_RNG_H_HEADER_GUARD