|
@@ -31,6 +31,7 @@
|
|
|
#include "random_pcg.h"
|
|
|
|
|
|
#include "core/os/os.h"
|
|
|
+#include "core/templates/vector.h"
|
|
|
|
|
|
RandomPCG::RandomPCG(uint64_t p_seed, uint64_t p_inc) :
|
|
|
pcg(),
|
|
@@ -42,6 +43,26 @@ void RandomPCG::randomize() {
|
|
|
seed(((uint64_t)OS::get_singleton()->get_unix_time() + OS::get_singleton()->get_ticks_usec()) * pcg.state + PCG_DEFAULT_INC_64);
|
|
|
}
|
|
|
|
|
|
+int RandomPCG::rand_weighted(const Vector<float> &p_weights) {
|
|
|
+ ERR_FAIL_COND_V_MSG(p_weights.is_empty(), -1, "Weights array is empty.");
|
|
|
+ int64_t weights_size = p_weights.size();
|
|
|
+ const float *weights = p_weights.ptr();
|
|
|
+ float weights_sum = 0.0;
|
|
|
+ for (int64_t i = 0; i < weights_size; ++i) {
|
|
|
+ weights_sum += weights[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ float remaining_distance = Math::randf() * weights_sum;
|
|
|
+ for (int64_t i = 0; i < weights_size; ++i) {
|
|
|
+ remaining_distance -= weights[i];
|
|
|
+ if (remaining_distance < 0) {
|
|
|
+ return i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return -1;
|
|
|
+}
|
|
|
+
|
|
|
double RandomPCG::random(double p_from, double p_to) {
|
|
|
return randd() * (p_to - p_from) + p_from;
|
|
|
}
|