Pārlūkot izejas kodu

Merge pull request #49793 from Chaosus/expose_randfn

Rémi Verschelde 3 gadi atpakaļ
vecāks
revīzija
7540da622d

+ 4 - 0
core/math/math_funcs.cpp

@@ -53,6 +53,10 @@ uint32_t Math::rand() {
 	return default_rand.rand();
 }
 
+double Math::randfn(double mean, double deviation) {
+	return default_rand.randfn(mean, deviation);
+}
+
 int Math::step_decimals(double p_step) {
 	static const int maxn = 10;
 	static const double sd[maxn] = {

+ 1 - 0
core/math/math_funcs.h

@@ -318,6 +318,7 @@ public:
 	static uint32_t rand();
 	static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_32BIT_MAX; }
 	static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_32BIT_MAX; }
+	static double randfn(double mean, double deviation);
 
 	static double random(double from, double to);
 	static float random(float from, float to);

+ 5 - 0
core/variant/variant_utility.cpp

@@ -403,6 +403,10 @@ struct VariantUtilityFunctions {
 		return Math::randf();
 	}
 
+	static inline double randfn(double mean, double deviation) {
+		return Math::randfn(mean, deviation);
+	}
+
 	static inline int64_t randi_range(int64_t from, int64_t to) {
 		return Math::random((int32_t)from, (int32_t)to);
 	}
@@ -1239,6 +1243,7 @@ void Variant::_register_variant_utility_functions() {
 	FUNCBINDR(randf, sarray(), Variant::UTILITY_FUNC_TYPE_RANDOM);
 	FUNCBINDR(randi_range, sarray("from", "to"), Variant::UTILITY_FUNC_TYPE_RANDOM);
 	FUNCBINDR(randf_range, sarray("from", "to"), Variant::UTILITY_FUNC_TYPE_RANDOM);
+	FUNCBINDR(randfn, sarray("mean", "deviation"), Variant::UTILITY_FUNC_TYPE_RANDOM);
 	FUNCBIND(seed, sarray("base"), Variant::UTILITY_FUNC_TYPE_RANDOM);
 	FUNCBINDR(rand_from_seed, sarray("seed"), Variant::UTILITY_FUNC_TYPE_RANDOM);
 

+ 8 - 0
doc/classes/@GlobalScope.xml

@@ -723,6 +723,14 @@
 				[/codeblock]
 			</description>
 		</method>
+		<method name="randfn">
+			<return type="float" />
+			<argument index="0" name="mean" type="float" />
+			<argument index="1" name="deviation" type="float" />
+			<description>
+				Returns a normally-distributed pseudo-random floating point value using Box-Muller transform with the specified [code]mean[/code] and a standard [code]deviation[/code]. This is also called Gaussian distribution.
+			</description>
+		</method>
 		<method name="randi">
 			<return type="int" />
 			<description>

+ 16 - 3
modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs

@@ -322,6 +322,16 @@ namespace Godot
             return godot_icall_GD_randf();
         }
 
+        /// <summary>
+        /// Returns a normally-distributed pseudo-random number, using Box-Muller transform with the specified <c>mean</c> and a standard <c>deviation</c>.
+        /// This is also called Gaussian distribution.
+        /// </summary>
+        /// <returns>A random normally-distributed <see langword="float"/> number.</returns>
+        public static double Randfn(double mean, double deviation)
+        {
+            return godot_icall_GD_randfn(mean, deviation);
+        }
+
         /// <summary>
         /// Returns a random unsigned 32-bit integer.
         /// Use remainder to obtain a random value in the interval <c>[0, N - 1]</c> (where N is smaller than 2^32).
@@ -564,19 +574,22 @@ namespace Godot
         internal static extern void godot_icall_GD_printt(object[] what);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern float godot_icall_GD_randf();
+        internal static extern void godot_icall_GD_randomize();
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal static extern uint godot_icall_GD_randi();
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_GD_randomize();
+        internal static extern float godot_icall_GD_randf();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        internal static extern int godot_icall_GD_randi_range(int from, int to);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal static extern double godot_icall_GD_randf_range(double from, double to);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern int godot_icall_GD_randi_range(int from, int to);
+        internal static extern double godot_icall_GD_randfn(double mean, double deviation);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal static extern uint godot_icall_GD_rand_seed(ulong seed, out ulong newSeed);

+ 14 - 9
modules/mono/glue/gd_glue.cpp

@@ -182,26 +182,30 @@ void godot_icall_GD_printt(MonoArray *p_what) {
 	print_line(str);
 }
 
-float godot_icall_GD_randf() {
-	return Math::randf();
+void godot_icall_GD_randomize() {
+	Math::randomize();
 }
 
 uint32_t godot_icall_GD_randi() {
 	return Math::rand();
 }
 
-void godot_icall_GD_randomize() {
-	Math::randomize();
+float godot_icall_GD_randf() {
+	return Math::randf();
 }
 
-double godot_icall_GD_randf_range(double from, double to) {
+int32_t godot_icall_GD_randi_range(int32_t from, int32_t to) {
 	return Math::random(from, to);
 }
 
-int32_t godot_icall_GD_randi_range(int32_t from, int32_t to) {
+double godot_icall_GD_randf_range(double from, double to) {
 	return Math::random(from, to);
 }
 
+double godot_icall_GD_randfn(double mean, double deviation) {
+	return Math::randfn(mean, deviation);
+}
+
 uint32_t godot_icall_GD_rand_seed(uint64_t seed, uint64_t *newSeed) {
 	uint32_t ret = Math::rand_from_seed(&seed);
 	*newSeed = seed;
@@ -300,11 +304,12 @@ void godot_register_gd_icalls() {
 	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_printraw", godot_icall_GD_printraw);
 	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_prints", godot_icall_GD_prints);
 	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_printt", godot_icall_GD_printt);
-	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randf", godot_icall_GD_randf);
-	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randi", godot_icall_GD_randi);
 	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randomize", godot_icall_GD_randomize);
-	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randf_range", godot_icall_GD_randf_range);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randi", godot_icall_GD_randi);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randf", godot_icall_GD_randf);
 	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randi_range", godot_icall_GD_randi_range);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randf_range", godot_icall_GD_randf_range);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randfn", godot_icall_GD_randfn);
 	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_rand_seed", godot_icall_GD_rand_seed);
 	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_seed", godot_icall_GD_seed);
 	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_str", godot_icall_GD_str);

+ 38 - 35
modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml

@@ -112,104 +112,107 @@
 		<constant name="MATH_RANDF" value="32" enum="BuiltinFunc">
 			Return a random floating-point value between 0 and 1. To obtain a random value between 0 to N, you can use it with multiplication.
 		</constant>
-		<constant name="MATH_RANDF_RANGE" value="33" enum="BuiltinFunc">
+		<constant name="MATH_RANDI_RANGE" value="33" enum="BuiltinFunc">
+			Return a random 32-bit integer value between the two inputs.
+		</constant>
+		<constant name="MATH_RANDF_RANGE" value="34" enum="BuiltinFunc">
 			Return a random floating-point value between the two inputs.
 		</constant>
-		<constant name="MATH_RANDI_RANGE" value="34" enum="BuiltinFunc">
-			Return a random 32-bit integer value between the two inputs.
+		<constant name="MATH_RANDFN" value="35" enum="BuiltinFunc">
+			Returns a normally-distributed pseudo-random number, using Box-Muller transform with the specified mean and a standard deviation. This is also called Gaussian distribution.
 		</constant>
-		<constant name="MATH_SEED" value="35" enum="BuiltinFunc">
+		<constant name="MATH_SEED" value="36" enum="BuiltinFunc">
 			Set the seed for the random number generator.
 		</constant>
-		<constant name="MATH_RANDSEED" value="36" enum="BuiltinFunc">
+		<constant name="MATH_RANDSEED" value="37" enum="BuiltinFunc">
 			Return a random value from the given seed, along with the new seed.
 		</constant>
-		<constant name="MATH_DEG2RAD" value="37" enum="BuiltinFunc">
+		<constant name="MATH_DEG2RAD" value="38" enum="BuiltinFunc">
 			Convert the input from degrees to radians.
 		</constant>
-		<constant name="MATH_RAD2DEG" value="38" enum="BuiltinFunc">
+		<constant name="MATH_RAD2DEG" value="39" enum="BuiltinFunc">
 			Convert the input from radians to degrees.
 		</constant>
-		<constant name="MATH_LINEAR2DB" value="39" enum="BuiltinFunc">
+		<constant name="MATH_LINEAR2DB" value="40" enum="BuiltinFunc">
 			Convert the input from linear volume to decibel volume.
 		</constant>
-		<constant name="MATH_DB2LINEAR" value="40" enum="BuiltinFunc">
+		<constant name="MATH_DB2LINEAR" value="41" enum="BuiltinFunc">
 			Convert the input from decibel volume to linear volume.
 		</constant>
-		<constant name="MATH_WRAP" value="41" enum="BuiltinFunc">
+		<constant name="MATH_WRAP" value="42" enum="BuiltinFunc">
 		</constant>
-		<constant name="MATH_WRAPF" value="42" enum="BuiltinFunc">
+		<constant name="MATH_WRAPF" value="43" enum="BuiltinFunc">
 		</constant>
-		<constant name="MATH_PINGPONG" value="43" enum="BuiltinFunc">
+		<constant name="MATH_PINGPONG" value="44" enum="BuiltinFunc">
 			Return the [code]value[/code] wrapped between [code]0[/code] and the [code]length[/code]. If the limit is reached, the next value the function returned is decreased to the [code]0[/code] side or increased to the [code]length[/code] side (like a triangle wave). If [code]length[/code] is less than zero, it becomes positive.
 		</constant>
-		<constant name="LOGIC_MAX" value="44" enum="BuiltinFunc">
+		<constant name="LOGIC_MAX" value="45" enum="BuiltinFunc">
 			Return the greater of the two numbers, also known as their maximum.
 		</constant>
-		<constant name="LOGIC_MIN" value="45" enum="BuiltinFunc">
+		<constant name="LOGIC_MIN" value="46" enum="BuiltinFunc">
 			Return the lesser of the two numbers, also known as their minimum.
 		</constant>
-		<constant name="LOGIC_CLAMP" value="46" enum="BuiltinFunc">
+		<constant name="LOGIC_CLAMP" value="47" enum="BuiltinFunc">
 			Return the input clamped inside the given range, ensuring the result is never outside it. Equivalent to [code]min(max(input, range_low), range_high)[/code].
 		</constant>
-		<constant name="LOGIC_NEAREST_PO2" value="47" enum="BuiltinFunc">
+		<constant name="LOGIC_NEAREST_PO2" value="48" enum="BuiltinFunc">
 			Return the nearest power of 2 to the input.
 		</constant>
-		<constant name="OBJ_WEAKREF" value="48" enum="BuiltinFunc">
+		<constant name="OBJ_WEAKREF" value="49" enum="BuiltinFunc">
 			Create a [WeakRef] from the input.
 		</constant>
-		<constant name="TYPE_CONVERT" value="49" enum="BuiltinFunc">
+		<constant name="TYPE_CONVERT" value="50" enum="BuiltinFunc">
 			Convert between types.
 		</constant>
-		<constant name="TYPE_OF" value="50" enum="BuiltinFunc">
+		<constant name="TYPE_OF" value="51" enum="BuiltinFunc">
 			Return the type of the input as an integer. Check [enum Variant.Type] for the integers that might be returned.
 		</constant>
-		<constant name="TYPE_EXISTS" value="51" enum="BuiltinFunc">
+		<constant name="TYPE_EXISTS" value="52" enum="BuiltinFunc">
 			Checks if a type is registered in the [ClassDB].
 		</constant>
-		<constant name="TEXT_CHAR" value="52" enum="BuiltinFunc">
+		<constant name="TEXT_CHAR" value="53" enum="BuiltinFunc">
 			Return a character with the given ascii value.
 		</constant>
-		<constant name="TEXT_STR" value="53" enum="BuiltinFunc">
+		<constant name="TEXT_STR" value="54" enum="BuiltinFunc">
 			Convert the input to a string.
 		</constant>
-		<constant name="TEXT_PRINT" value="54" enum="BuiltinFunc">
+		<constant name="TEXT_PRINT" value="55" enum="BuiltinFunc">
 			Print the given string to the output window.
 		</constant>
-		<constant name="TEXT_PRINTERR" value="55" enum="BuiltinFunc">
+		<constant name="TEXT_PRINTERR" value="56" enum="BuiltinFunc">
 			Print the given string to the standard error output.
 		</constant>
-		<constant name="TEXT_PRINTRAW" value="56" enum="BuiltinFunc">
+		<constant name="TEXT_PRINTRAW" value="57" enum="BuiltinFunc">
 			Print the given string to the standard output, without adding a newline.
 		</constant>
-		<constant name="TEXT_PRINT_VERBOSE" value="57" enum="BuiltinFunc">
+		<constant name="TEXT_PRINT_VERBOSE" value="58" enum="BuiltinFunc">
 		</constant>
-		<constant name="VAR_TO_STR" value="58" enum="BuiltinFunc">
+		<constant name="VAR_TO_STR" value="59" enum="BuiltinFunc">
 			Serialize a [Variant] to a string.
 		</constant>
-		<constant name="STR_TO_VAR" value="59" enum="BuiltinFunc">
+		<constant name="STR_TO_VAR" value="60" enum="BuiltinFunc">
 			Deserialize a [Variant] from a string serialized using [constant VAR_TO_STR].
 		</constant>
-		<constant name="VAR_TO_BYTES" value="60" enum="BuiltinFunc">
+		<constant name="VAR_TO_BYTES" value="61" enum="BuiltinFunc">
 			Serialize a [Variant] to a [PackedByteArray].
 		</constant>
-		<constant name="BYTES_TO_VAR" value="61" enum="BuiltinFunc">
+		<constant name="BYTES_TO_VAR" value="62" enum="BuiltinFunc">
 			Deserialize a [Variant] from a [PackedByteArray] serialized using [constant VAR_TO_BYTES].
 		</constant>
-		<constant name="MATH_SMOOTHSTEP" value="62" enum="BuiltinFunc">
+		<constant name="MATH_SMOOTHSTEP" value="63" enum="BuiltinFunc">
 			Return a number smoothly interpolated between the first two inputs, based on the third input. Similar to [constant MATH_LERP], but interpolates faster at the beginning and slower at the end. Using Hermite interpolation formula:
 			[codeblock]
 			var t = clamp((weight - from) / (to - from), 0.0, 1.0)
 			return t * t * (3.0 - 2.0 * t)
 			[/codeblock]
 		</constant>
-		<constant name="MATH_POSMOD" value="63" enum="BuiltinFunc">
+		<constant name="MATH_POSMOD" value="64" enum="BuiltinFunc">
 		</constant>
-		<constant name="MATH_LERP_ANGLE" value="64" enum="BuiltinFunc">
+		<constant name="MATH_LERP_ANGLE" value="65" enum="BuiltinFunc">
 		</constant>
-		<constant name="TEXT_ORD" value="65" enum="BuiltinFunc">
+		<constant name="TEXT_ORD" value="66" enum="BuiltinFunc">
 		</constant>
-		<constant name="FUNC_MAX" value="66" enum="BuiltinFunc">
+		<constant name="FUNC_MAX" value="67" enum="BuiltinFunc">
 			Represents the size of the [enum BuiltinFunc] enum.
 		</constant>
 	</constants>

+ 19 - 7
modules/visual_script/visual_script_builtin_funcs.cpp

@@ -71,8 +71,9 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX
 	"randomize",
 	"randi",
 	"randf",
-	"randf_range",
 	"randi_range",
+	"randf_range",
+	"randfn",
 	"seed",
 	"rand_seed",
 	"deg2rad",
@@ -195,8 +196,9 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
 		case MATH_POW:
 		case MATH_EASE:
 		case MATH_SNAPPED:
-		case MATH_RANDF_RANGE:
 		case MATH_RANDI_RANGE:
+		case MATH_RANDF_RANGE:
+		case MATH_RANDFN:
 		case LOGIC_MAX:
 		case LOGIC_MIN:
 		case TYPE_CONVERT:
@@ -353,6 +355,13 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
 		case MATH_RANDI:
 		case MATH_RANDF: {
 		} break;
+		case MATH_RANDI_RANGE: {
+			if (p_idx == 0) {
+				return PropertyInfo(Variant::INT, "from");
+			} else {
+				return PropertyInfo(Variant::INT, "to");
+			}
+		} break;
 		case MATH_RANDF_RANGE: {
 			if (p_idx == 0) {
 				return PropertyInfo(Variant::FLOAT, "from");
@@ -360,11 +369,11 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
 				return PropertyInfo(Variant::FLOAT, "to");
 			}
 		} break;
-		case MATH_RANDI_RANGE: {
+		case MATH_RANDFN: {
 			if (p_idx == 0) {
-				return PropertyInfo(Variant::INT, "from");
+				return PropertyInfo(Variant::FLOAT, "mean");
 			} else {
-				return PropertyInfo(Variant::INT, "to");
+				return PropertyInfo(Variant::FLOAT, "deviation");
 			}
 		} break;
 		case MATH_SEED:
@@ -527,6 +536,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
 			t = Variant::INT;
 		} break;
 		case MATH_RANDF:
+		case MATH_RANDFN:
 		case MATH_RANDF_RANGE: {
 			t = Variant::FLOAT;
 		} break;
@@ -1211,8 +1221,9 @@ void VisualScriptBuiltinFunc::_bind_methods() {
 	BIND_ENUM_CONSTANT(MATH_RANDOMIZE);
 	BIND_ENUM_CONSTANT(MATH_RANDI);
 	BIND_ENUM_CONSTANT(MATH_RANDF);
-	BIND_ENUM_CONSTANT(MATH_RANDF_RANGE);
 	BIND_ENUM_CONSTANT(MATH_RANDI_RANGE);
+	BIND_ENUM_CONSTANT(MATH_RANDF_RANGE);
+	BIND_ENUM_CONSTANT(MATH_RANDFN);
 	BIND_ENUM_CONSTANT(MATH_SEED);
 	BIND_ENUM_CONSTANT(MATH_RANDSEED);
 	BIND_ENUM_CONSTANT(MATH_DEG2RAD);
@@ -1301,8 +1312,9 @@ void register_visual_script_builtin_func_node() {
 	VisualScriptLanguage::singleton->add_register_func("functions/built_in/randomize", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDOMIZE>);
 	VisualScriptLanguage::singleton->add_register_func("functions/built_in/randi", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDI>);
 	VisualScriptLanguage::singleton->add_register_func("functions/built_in/randf", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDF>);
-	VisualScriptLanguage::singleton->add_register_func("functions/built_in/randf_range", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDF_RANGE>);
 	VisualScriptLanguage::singleton->add_register_func("functions/built_in/randi_range", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDI_RANGE>);
+	VisualScriptLanguage::singleton->add_register_func("functions/built_in/randf_range", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDF_RANGE>);
+	VisualScriptLanguage::singleton->add_register_func("functions/built_in/randfn", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDFN>);
 
 	VisualScriptLanguage::singleton->add_register_func("functions/built_in/seed", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_SEED>);
 	VisualScriptLanguage::singleton->add_register_func("functions/built_in/randseed", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDSEED>);

+ 2 - 1
modules/visual_script/visual_script_builtin_funcs.h

@@ -71,8 +71,9 @@ public:
 		MATH_RANDOMIZE,
 		MATH_RANDI,
 		MATH_RANDF,
-		MATH_RANDF_RANGE,
 		MATH_RANDI_RANGE,
+		MATH_RANDF_RANGE,
+		MATH_RANDFN,
 		MATH_SEED,
 		MATH_RANDSEED,
 		MATH_DEG2RAD,