| 
									
										
										
										
											2023-01-05 13:25:55 +01:00
										 |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*  math_funcs.cpp                                                        */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*                         This file is part of:                          */ | 
					
						
							|  |  |  | /*                             GODOT ENGINE                               */ | 
					
						
							|  |  |  | /*                        https://godotengine.org                         */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ | 
					
						
							|  |  |  | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* 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.                 */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "math_funcs.h"
 | 
					
						
							| 
									
										
										
										
											2017-08-27 21:07:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-07 19:33:38 -03:00
										 |  |  | #include "core/error/error_macros.h"
 | 
					
						
							| 
									
										
										
										
											2019-10-08 10:17:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-21 14:32:17 +03:00
										 |  |  | RandomPCG Math::default_rand(RandomPCG::DEFAULT_SEED, RandomPCG::DEFAULT_INC); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-14 23:34:51 -06:00
										 |  |  | uint32_t Math::rand_from_seed(uint64_t *seed) { | 
					
						
							| 
									
										
										
										
											2018-09-21 14:32:17 +03:00
										 |  |  | 	RandomPCG rng = RandomPCG(*seed, RandomPCG::DEFAULT_INC); | 
					
						
							|  |  |  | 	uint32_t r = rng.rand(); | 
					
						
							|  |  |  | 	*seed = rng.get_seed(); | 
					
						
							| 
									
										
										
										
											2017-01-14 23:34:51 -06:00
										 |  |  | 	return r; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-14 23:34:51 -06:00
										 |  |  | void Math::seed(uint64_t x) { | 
					
						
							| 
									
										
										
										
											2018-09-21 14:32:17 +03:00
										 |  |  | 	default_rand.seed(x); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Math::randomize() { | 
					
						
							| 
									
										
										
										
											2018-09-21 14:32:17 +03:00
										 |  |  | 	default_rand.randomize(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint32_t Math::rand() { | 
					
						
							| 
									
										
										
										
											2018-09-21 14:32:17 +03:00
										 |  |  | 	return default_rand.rand(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-21 12:58:31 +03:00
										 |  |  | double Math::randfn(double mean, double deviation) { | 
					
						
							|  |  |  | 	return default_rand.randfn(mean, deviation); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-26 17:24:34 -03:00
										 |  |  | int Math::step_decimals(double p_step) { | 
					
						
							| 
									
										
										
										
											2018-09-19 20:10:06 -04:00
										 |  |  | 	static const int maxn = 10; | 
					
						
							| 
									
										
										
										
											2016-07-26 17:24:34 -03:00
										 |  |  | 	static const double sd[maxn] = { | 
					
						
							|  |  |  | 		0.9999, // somehow compensate for floating point error
 | 
					
						
							|  |  |  | 		0.09999, | 
					
						
							|  |  |  | 		0.009999, | 
					
						
							|  |  |  | 		0.0009999, | 
					
						
							|  |  |  | 		0.00009999, | 
					
						
							|  |  |  | 		0.000009999, | 
					
						
							|  |  |  | 		0.0000009999, | 
					
						
							|  |  |  | 		0.00000009999, | 
					
						
							| 
									
										
										
										
											2018-09-19 20:10:06 -04:00
										 |  |  | 		0.000000009999, | 
					
						
							|  |  |  | 		0.0000000009999 | 
					
						
							| 
									
										
										
										
											2016-07-26 17:24:34 -03:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-19 20:10:06 -04:00
										 |  |  | 	double abs = Math::abs(p_step); | 
					
						
							|  |  |  | 	double decs = abs - (int)abs; // Strip away integer part
 | 
					
						
							| 
									
										
										
										
											2016-07-26 17:24:34 -03:00
										 |  |  | 	for (int i = 0; i < maxn; i++) { | 
					
						
							| 
									
										
										
										
											2018-09-19 20:10:06 -04:00
										 |  |  | 		if (decs >= sd[i]) { | 
					
						
							| 
									
										
										
										
											2016-07-26 17:24:34 -03:00
										 |  |  | 			return i; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-19 20:10:06 -04:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-23 17:27:55 +02:00
										 |  |  | // Only meant for editor usage in float ranges, where a step of 0
 | 
					
						
							|  |  |  | // means that decimal digits should not be limited in String::num.
 | 
					
						
							|  |  |  | int Math::range_step_decimals(double p_step) { | 
					
						
							|  |  |  | 	if (p_step < 0.0000000000001) { | 
					
						
							|  |  |  | 		return 16; // Max value hardcoded in String::num
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return step_decimals(p_step); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-14 14:35:39 -06:00
										 |  |  | double Math::ease(double p_x, double p_c) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (p_x < 0) { | 
					
						
							| 
									
										
										
										
											2014-03-13 22:57:24 -03:00
										 |  |  | 		p_x = 0; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} else if (p_x > 1.0) { | 
					
						
							| 
									
										
										
										
											2014-03-13 22:57:24 -03:00
										 |  |  | 		p_x = 1.0; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (p_c > 0) { | 
					
						
							| 
									
										
										
										
											2014-03-13 22:57:24 -03:00
										 |  |  | 		if (p_c < 1.0) { | 
					
						
							|  |  |  | 			return 1.0 - Math::pow(1.0 - p_x, 1.0 / p_c); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			return Math::pow(p_x, p_c); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} else if (p_c < 0) { | 
					
						
							|  |  |  | 		//inout ease
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (p_x < 0.5) { | 
					
						
							|  |  |  | 			return Math::pow(p_x * 2.0, -p_c) * 0.5; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			return (1.0 - Math::pow(1.0 - (p_x - 0.5) * 2.0, -p_c)) * 0.5 + 0.5; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return 0; // no ease (raw)
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-21 18:02:57 +00:00
										 |  |  | double Math::snapped(double p_value, double p_step) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (p_step != 0) { | 
					
						
							| 
									
										
										
										
											2017-01-14 14:35:39 -06:00
										 |  |  | 		p_value = Math::floor(p_value / p_step + 0.5) * p_step; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return p_value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint32_t Math::larger_prime(uint32_t p_val) { | 
					
						
							| 
									
										
										
										
											2015-05-06 00:56:59 +02:00
										 |  |  | 	static const uint32_t primes[] = { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		5, | 
					
						
							|  |  |  | 		13, | 
					
						
							|  |  |  | 		23, | 
					
						
							|  |  |  | 		47, | 
					
						
							|  |  |  | 		97, | 
					
						
							|  |  |  | 		193, | 
					
						
							|  |  |  | 		389, | 
					
						
							|  |  |  | 		769, | 
					
						
							|  |  |  | 		1543, | 
					
						
							|  |  |  | 		3079, | 
					
						
							|  |  |  | 		6151, | 
					
						
							|  |  |  | 		12289, | 
					
						
							|  |  |  | 		24593, | 
					
						
							|  |  |  | 		49157, | 
					
						
							|  |  |  | 		98317, | 
					
						
							|  |  |  | 		196613, | 
					
						
							|  |  |  | 		393241, | 
					
						
							|  |  |  | 		786433, | 
					
						
							|  |  |  | 		1572869, | 
					
						
							|  |  |  | 		3145739, | 
					
						
							|  |  |  | 		6291469, | 
					
						
							|  |  |  | 		12582917, | 
					
						
							|  |  |  | 		25165843, | 
					
						
							|  |  |  | 		50331653, | 
					
						
							|  |  |  | 		100663319, | 
					
						
							|  |  |  | 		201326611, | 
					
						
							|  |  |  | 		402653189, | 
					
						
							|  |  |  | 		805306457, | 
					
						
							|  |  |  | 		1610612741, | 
					
						
							|  |  |  | 		0, | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int idx = 0; | 
					
						
							|  |  |  | 	while (true) { | 
					
						
							|  |  |  | 		ERR_FAIL_COND_V(primes[idx] == 0, 0); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (primes[idx] > p_val) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return primes[idx]; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		idx++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | double Math::random(double from, double to) { | 
					
						
							| 
									
										
										
										
											2018-09-21 14:32:17 +03:00
										 |  |  | 	return default_rand.random(from, to); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-14 14:35:39 -06:00
										 |  |  | float Math::random(float from, float to) { | 
					
						
							| 
									
										
										
										
											2018-09-21 14:32:17 +03:00
										 |  |  | 	return default_rand.random(from, to); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-07-26 13:52:24 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | int Math::random(int from, int to) { | 
					
						
							|  |  |  | 	return default_rand.random(from, to); | 
					
						
							|  |  |  | } |