Merge pull request #22314 from Chaosus/rng
Random number generator(remake)
This commit is contained in:
commit
a9f6bbe1fb
8 changed files with 287 additions and 17 deletions
|
@ -30,30 +30,27 @@
|
|||
|
||||
#include "math_funcs.h"
|
||||
|
||||
#include "core/os/os.h"
|
||||
|
||||
pcg32_random_t Math::default_pcg = { 12047754176567800795ULL, PCG_DEFAULT_INC_64 };
|
||||
RandomPCG Math::default_rand(RandomPCG::DEFAULT_SEED, RandomPCG::DEFAULT_INC);
|
||||
|
||||
#define PHI 0x9e3779b9
|
||||
|
||||
// TODO: we should eventually expose pcg.inc too
|
||||
uint32_t Math::rand_from_seed(uint64_t *seed) {
|
||||
pcg32_random_t pcg = { *seed, PCG_DEFAULT_INC_64 };
|
||||
uint32_t r = pcg32_random_r(&pcg);
|
||||
*seed = pcg.state;
|
||||
RandomPCG rng = RandomPCG(*seed, RandomPCG::DEFAULT_INC);
|
||||
uint32_t r = rng.rand();
|
||||
*seed = rng.get_seed();
|
||||
return r;
|
||||
}
|
||||
|
||||
void Math::seed(uint64_t x) {
|
||||
default_pcg.state = x;
|
||||
default_rand.seed(x);
|
||||
}
|
||||
|
||||
void Math::randomize() {
|
||||
seed(OS::get_singleton()->get_ticks_usec() * default_pcg.state + PCG_DEFAULT_INC_64);
|
||||
default_rand.randomize();
|
||||
}
|
||||
|
||||
uint32_t Math::rand() {
|
||||
return pcg32_random_r(&default_pcg);
|
||||
return default_rand.rand();
|
||||
}
|
||||
|
||||
int Math::step_decimals(double p_step) {
|
||||
|
@ -169,13 +166,9 @@ uint32_t Math::larger_prime(uint32_t p_val) {
|
|||
}
|
||||
|
||||
double Math::random(double from, double to) {
|
||||
unsigned int r = Math::rand();
|
||||
double ret = (double)r / (double)RANDOM_MAX;
|
||||
return (ret) * (to - from) + from;
|
||||
return default_rand.random(from, to);
|
||||
}
|
||||
|
||||
float Math::random(float from, float to) {
|
||||
unsigned int r = Math::rand();
|
||||
float ret = (float)r / (float)RANDOM_MAX;
|
||||
return (ret) * (to - from) + from;
|
||||
return default_rand.random(from, to);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#define MATH_FUNCS_H
|
||||
|
||||
#include "core/math/math_defs.h"
|
||||
#include "core/math/random_pcg.h"
|
||||
#include "core/typedefs.h"
|
||||
|
||||
#include "thirdparty/misc/pcg.h"
|
||||
|
@ -41,7 +42,7 @@
|
|||
|
||||
class Math {
|
||||
|
||||
static pcg32_random_t default_pcg;
|
||||
static RandomPCG default_rand;
|
||||
|
||||
public:
|
||||
Math() {} // useless to instance
|
||||
|
|
45
core/math/random_number_generator.cpp
Normal file
45
core/math/random_number_generator.cpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*************************************************************************/
|
||||
/* random_number_generator.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "random_number_generator.h"
|
||||
|
||||
RandomNumberGenerator::RandomNumberGenerator() :
|
||||
randbase() {}
|
||||
|
||||
void RandomNumberGenerator::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_seed", "seed"), &RandomNumberGenerator::set_seed);
|
||||
ClassDB::bind_method(D_METHOD("get_seed"), &RandomNumberGenerator::get_seed);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("randi"), &RandomNumberGenerator::randi);
|
||||
ClassDB::bind_method(D_METHOD("randf"), &RandomNumberGenerator::randf);
|
||||
ClassDB::bind_method(D_METHOD("rand_range", "from", "to"), &RandomNumberGenerator::rand_range);
|
||||
ClassDB::bind_method(D_METHOD("randomize"), &RandomNumberGenerator::randomize);
|
||||
}
|
61
core/math/random_number_generator.h
Normal file
61
core/math/random_number_generator.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*************************************************************************/
|
||||
/* random_number_generator.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef RANDOM_NUMBER_GENERATOR_H
|
||||
#define RANDOM_NUMBER_GENERATOR_H
|
||||
|
||||
#include "core/math/random_pcg.h"
|
||||
#include "core/reference.h"
|
||||
|
||||
class RandomNumberGenerator : public Reference {
|
||||
GDCLASS(RandomNumberGenerator, Reference);
|
||||
|
||||
RandomPCG randbase;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
_FORCE_INLINE_ void set_seed(uint64_t seed) { randbase.seed(seed); }
|
||||
|
||||
_FORCE_INLINE_ uint64_t get_seed() { return randbase.get_seed(); }
|
||||
|
||||
_FORCE_INLINE_ void randomize() { return randbase.randomize(); }
|
||||
|
||||
_FORCE_INLINE_ uint32_t randi() { return randbase.rand(); }
|
||||
|
||||
_FORCE_INLINE_ real_t randf() { return randbase.randf(); }
|
||||
|
||||
_FORCE_INLINE_ real_t rand_range(real_t from, real_t to) { return randbase.random(from, to); }
|
||||
|
||||
RandomNumberGenerator();
|
||||
};
|
||||
|
||||
#endif // RANDOM_NUMBER_GENERATOR_H
|
55
core/math/random_pcg.cpp
Normal file
55
core/math/random_pcg.cpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*************************************************************************/
|
||||
/* random_pcg.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "random_pcg.h"
|
||||
|
||||
#include "core/os/os.h"
|
||||
|
||||
RandomPCG::RandomPCG(uint64_t seed, uint64_t inc) :
|
||||
pcg() {
|
||||
pcg.state = seed;
|
||||
pcg.inc = inc;
|
||||
}
|
||||
|
||||
void RandomPCG::randomize() {
|
||||
seed(OS::get_singleton()->get_ticks_usec() * pcg.state + PCG_DEFAULT_INC_64);
|
||||
}
|
||||
|
||||
double RandomPCG::random(double from, double to) {
|
||||
unsigned int r = rand();
|
||||
double ret = (double)r / (double)RANDOM_MAX;
|
||||
return (ret) * (to - from) + from;
|
||||
}
|
||||
|
||||
float RandomPCG::random(float from, float to) {
|
||||
unsigned int r = rand();
|
||||
float ret = (float)r / (float)RANDOM_MAX;
|
||||
return (ret) * (to - from) + from;
|
||||
}
|
61
core/math/random_pcg.h
Normal file
61
core/math/random_pcg.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*************************************************************************/
|
||||
/* random_pcg.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef RANDOM_PCG_H
|
||||
#define RANDOM_PCG_H
|
||||
|
||||
#include "core/math/math_defs.h"
|
||||
|
||||
#include "thirdparty/misc/pcg.h"
|
||||
|
||||
class RandomPCG {
|
||||
pcg32_random_t pcg;
|
||||
|
||||
public:
|
||||
static const uint64_t DEFAULT_SEED = 12047754176567800795ULL;
|
||||
static const uint64_t DEFAULT_INC = PCG_DEFAULT_INC_64;
|
||||
static const uint64_t RANDOM_MAX = 4294967295;
|
||||
|
||||
RandomPCG(uint64_t seed = DEFAULT_SEED, uint64_t inc = PCG_DEFAULT_INC_64);
|
||||
|
||||
_FORCE_INLINE_ void seed(uint64_t seed) { pcg.state = seed; }
|
||||
_FORCE_INLINE_ uint64_t get_seed() { return pcg.state; }
|
||||
|
||||
void randomize();
|
||||
_FORCE_INLINE_ uint32_t rand() { return pcg32_random_r(&pcg); }
|
||||
_FORCE_INLINE_ double randf() { return (double)rand() / (double)RANDOM_MAX; }
|
||||
_FORCE_INLINE_ float randd() { return (float)rand() / (float)RANDOM_MAX; }
|
||||
|
||||
double random(double from, double to);
|
||||
float random(float from, float to);
|
||||
real_t random(int from, int to) { return (real_t)random((real_t)from, (real_t)to); }
|
||||
};
|
||||
|
||||
#endif // RANDOM_PCG_H
|
|
@ -55,6 +55,7 @@
|
|||
#include "core/math/a_star.h"
|
||||
#include "core/math/expression.h"
|
||||
#include "core/math/geometry.h"
|
||||
#include "core/math/random_number_generator.h"
|
||||
#include "core/math/triangle_mesh.h"
|
||||
#include "core/os/input.h"
|
||||
#include "core/os/main_loop.h"
|
||||
|
@ -180,6 +181,7 @@ void register_core_types() {
|
|||
ClassDB::register_virtual_class<PackedDataContainerRef>();
|
||||
ClassDB::register_class<AStar>();
|
||||
ClassDB::register_class<EncodedObjectAsID>();
|
||||
ClassDB::register_class<RandomNumberGenerator>();
|
||||
|
||||
ClassDB::register_class<JSONParseResult>();
|
||||
|
||||
|
|
52
doc/classes/RandomNumberGenerator.xml
Normal file
52
doc/classes/RandomNumberGenerator.xml
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="RandomNumberGenerator" inherits="Reference" category="Core" version="3.1">
|
||||
<brief_description>
|
||||
A class for generation pseudo-random numbers.
|
||||
</brief_description>
|
||||
<description>
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<demos>
|
||||
</demos>
|
||||
<methods>
|
||||
<method name="randi">
|
||||
<return type="int">
|
||||
</return>
|
||||
<description>
|
||||
Generates pseudo-random 32-bit integer between '0' and '4294967295'.
|
||||
</description>
|
||||
</method>
|
||||
<method name="randf">
|
||||
<return type="float">
|
||||
</return>
|
||||
<description>
|
||||
Generates pseudo-random float between '0.0' and '1.0'.
|
||||
</description>
|
||||
</method>
|
||||
<method name="rand_range">
|
||||
<return type="float">
|
||||
</return>
|
||||
<argument index="0" name="from" type="float">
|
||||
</argument>
|
||||
<argument index="1" name="to" type="float">
|
||||
</argument>
|
||||
<description>
|
||||
Generates pseudo-random float between [code]from[/code] and [code]to[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="randomize">
|
||||
<return type="void">
|
||||
</return>
|
||||
<description>
|
||||
Setups a time-based seed to generator.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="seed" type="int" setter="set_seed" getter="get_seed">
|
||||
</member>
|
||||
</members>
|
||||
<constants>
|
||||
</constants>
|
||||
</class>
|
Loading…
Reference in a new issue