|
|
@@ -1,7 +1,7 @@ |
|
|
|
// |
|
|
|
// Lol Engine |
|
|
|
// |
|
|
|
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net> |
|
|
|
// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net> |
|
|
|
// This program is free software; you can redistribute it and/or |
|
|
|
// modify it under the terms of the Do What The Fuck You Want To |
|
|
|
// Public License, Version 2, as published by Sam Hocevar. See |
|
|
@@ -22,23 +22,77 @@ |
|
|
|
namespace lol |
|
|
|
{ |
|
|
|
|
|
|
|
/* Random float value */ |
|
|
|
static inline float RandF() |
|
|
|
/* Random number generators */ |
|
|
|
template<typename T> static inline T rand(); |
|
|
|
template<typename T> static inline T rand(T a); |
|
|
|
template<typename T> static inline T rand(T a, T b); |
|
|
|
|
|
|
|
/* One-value random number generators */ |
|
|
|
template<typename T> static inline T rand(T a) |
|
|
|
{ |
|
|
|
using namespace std; |
|
|
|
return (float)std::rand() / RAND_MAX; |
|
|
|
return rand<T>() % a; |
|
|
|
} |
|
|
|
|
|
|
|
static inline float RandF(float val) |
|
|
|
template<> |
|
|
|
inline half rand<half>(half a) { return a * std::rand() / RAND_MAX; } |
|
|
|
template<> |
|
|
|
inline float rand<float>(float a) { return a * std::rand() / RAND_MAX; } |
|
|
|
template<> |
|
|
|
inline double rand<double>(double a) { return a * std::rand() / RAND_MAX; } |
|
|
|
template<> |
|
|
|
inline ldouble rand<ldouble>(ldouble a) { return a * std::rand() / RAND_MAX; } |
|
|
|
|
|
|
|
/* Two-value random number generator -- no need for specialisation */ |
|
|
|
template<typename T> static inline T rand(T a, T b) |
|
|
|
{ |
|
|
|
return RandF() * val; |
|
|
|
return a + rand<T>(b - a); |
|
|
|
} |
|
|
|
|
|
|
|
static inline float RandF(float min, float max) |
|
|
|
/* Default random number generator */ |
|
|
|
template<typename T> static inline T rand() |
|
|
|
{ |
|
|
|
return min + RandF() * (max - min); |
|
|
|
switch (sizeof(T)) |
|
|
|
{ |
|
|
|
case 1: |
|
|
|
return static_cast<T>(std::rand() & 0xff); |
|
|
|
case 2: |
|
|
|
if (RAND_MAX >= 0xffff) |
|
|
|
return static_cast<T>(std::rand()); |
|
|
|
else |
|
|
|
return static_cast<T>((std::rand() << 8) ^ std::rand()); |
|
|
|
case 4: |
|
|
|
if (RAND_MAX >= 0xffff) |
|
|
|
return static_cast<T>((std::rand() << 16) ^ std::rand()); |
|
|
|
else |
|
|
|
return static_cast<T>((std::rand() << 24) ^ (std::rand() << 16) |
|
|
|
^ (std::rand() << 8) ^ std::rand()); |
|
|
|
case 8: |
|
|
|
if (RAND_MAX >= 0xffff) |
|
|
|
return static_cast<T>(((uint64_t)std::rand() << 48) |
|
|
|
^ ((uint64_t)std::rand() << 32) |
|
|
|
^ ((uint64_t)std::rand() << 16) |
|
|
|
^ ((uint64_t)std::rand())); |
|
|
|
else |
|
|
|
return static_cast<T>(((uint64_t)std::rand() << 56) |
|
|
|
^ ((uint64_t)std::rand() << 48) |
|
|
|
^ ((uint64_t)std::rand() << 40) |
|
|
|
^ ((uint64_t)std::rand() << 32) |
|
|
|
^ ((uint64_t)std::rand() << 24) |
|
|
|
^ ((uint64_t)std::rand() << 16) |
|
|
|
^ ((uint64_t)std::rand() << 8) |
|
|
|
^ ((uint64_t)std::rand())); |
|
|
|
default: |
|
|
|
ASSERT(false, "rand() doesn’t support types of size %d\n", |
|
|
|
(int)sizeof(T)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
template<> inline half rand<half>() { return rand<half>(1.f); } |
|
|
|
template<> inline float rand<float>() { return rand<float>(1.f); } |
|
|
|
template<> inline double rand<double>() { return rand<double>(1.0); } |
|
|
|
template<> inline ldouble rand<ldouble>() { return rand<ldouble>(1.0); } |
|
|
|
|
|
|
|
|
|
|
|
/* Next power of two. */ |
|
|
|
template <typename T> static inline T PotUp(T val) |
|
|
|
{ |
|
|
|