|
|
@@ -8,6 +8,9 @@
|
|
|
|
|
|
#include "bx.h"
|
|
|
|
|
|
+#define _USE_MATH_DEFINES
|
|
|
+#include <math.h>
|
|
|
+
|
|
|
namespace bx
|
|
|
{
|
|
|
// George Marsaglia's MWC
|
|
|
@@ -107,6 +110,75 @@ namespace bx
|
|
|
return 2.0f * bx::frnd(_rng) - 1.0f;
|
|
|
}
|
|
|
|
|
|
+ /// Generate random point on unit sphere.
|
|
|
+ template <typename Ty>
|
|
|
+ static inline void randUnitSphere(float _result[3], Ty* _rng)
|
|
|
+ {
|
|
|
+ float rand0 = frnd(_rng) * 2.0f - 1.0f;
|
|
|
+ float rand1 = frnd(_rng) * float(M_PI) * 2.0f;
|
|
|
+
|
|
|
+ float sqrtf1 = sqrtf(1.0f - rand0*rand0);
|
|
|
+ _result[0] = sqrtf1 * cosf(rand1);
|
|
|
+ _result[1] = sqrtf1 * sinf(rand1);
|
|
|
+ _result[2] = rand0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// Generate random point on unit hemisphere.
|
|
|
+ template <typename Ty>
|
|
|
+ static inline void randUnitHemisphere(float _result[3], Ty* _rng, const float _normal[3])
|
|
|
+ {
|
|
|
+ float dir[3];
|
|
|
+ randUnitSphere(dir, _rng);
|
|
|
+
|
|
|
+ float DdotN = dir[0]*_normal[0]
|
|
|
+ + dir[1]*_normal[1]
|
|
|
+ + dir[2]*_normal[2]
|
|
|
+ ;
|
|
|
+
|
|
|
+ if (0.0f > DdotN)
|
|
|
+ {
|
|
|
+ dir[0] = -dir[0];
|
|
|
+ dir[1] = -dir[1];
|
|
|
+ dir[2] = -dir[2];
|
|
|
+ }
|
|
|
+
|
|
|
+ _result[0] = dir[0];
|
|
|
+ _result[1] = dir[1];
|
|
|
+ _result[2] = dir[2];
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 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)
|
|
|
+ {
|
|
|
+ uint8_t* data = (uint8_t*)_data;
|
|
|
+
|
|
|
+ for (uint32_t ii = 0; ii < _num; ii++)
|
|
|
+ {
|
|
|
+ float tt = 0.0f;
|
|
|
+ float pp = 0.5;
|
|
|
+ for (uint32_t jj = ii; jj; jj >>= 1)
|
|
|
+ {
|
|
|
+ tt += (jj & 1) ? pp : 0.0f;
|
|
|
+ pp *= 0.5f;
|
|
|
+ }
|
|
|
+
|
|
|
+ tt = 2.0f * tt - 1.0f;
|
|
|
+
|
|
|
+ const float phi = (ii + 0.5f) / _num;
|
|
|
+ const float phirad = phi * 2.0f * float(M_PI);
|
|
|
+ const float st = sqrtf(1.0f-tt*tt) * _scale;
|
|
|
+
|
|
|
+ float* xyz = (float*)data;
|
|
|
+ data += _stride;
|
|
|
+
|
|
|
+ xyz[0] = st * cosf(phirad);
|
|
|
+ xyz[1] = st * sinf(phirad);
|
|
|
+ xyz[2] = tt * _scale;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
} // namespace bx
|
|
|
|
|
|
#endif // __BX_RNG_H__
|