ソースを参照

Added new wrap functions

Chaosus 8 年 前
コミット
216a8aa643

+ 15 - 0
core/math/math_funcs.cpp

@@ -176,3 +176,18 @@ float Math::random(float from, float to) {
 	float ret = (float)r / (float)RANDOM_MAX;
 	return (ret) * (to - from) + from;
 }
+
+int Math::wrapi(int value, int min, int max) {
+	--max;
+	int rng = max - min + 1;
+	value = ((value - min) % rng);
+	if (value < 0)
+		return max + 1 + value;
+	else
+		return min + value;
+}
+
+float Math::wrapf(float value, float min, float max) {
+	float rng = max - min;
+	return min + (value - min) - (rng * floor((value - min) / rng));
+}

+ 4 - 1
core/math/math_funcs.h

@@ -207,6 +207,9 @@ public:
 	static _ALWAYS_INLINE_ double round(double p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); }
 	static _ALWAYS_INLINE_ float round(float p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); }
 
+	static int wrapi(int value, int min, int max);
+	static float wrapf(float value, float min, float max);
+
 	// double only, as these functions are mainly used by the editor and not performance-critical,
 	static double ease(double p_x, double p_c);
 	static int step_decimals(double p_step);
@@ -268,7 +271,7 @@ public:
 
 #elif defined(_MSC_VER) && _MSC_VER < 1800
 		__asm fld a __asm fistp b
-/*#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
+		/*#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
 		// use AT&T inline assembly style, document that
 		// we use memory as output (=m) and input (m)
 		__asm__ __volatile__ (

+ 22 - 0
modules/gdscript/gd_functions.cpp

@@ -83,6 +83,8 @@ const char *GDFunctions::get_func_name(Function p_func) {
 		"rad2deg",
 		"linear2db",
 		"db2linear",
+		"wrapi",
+		"wrapf",
 		"max",
 		"min",
 		"clamp",
@@ -405,6 +407,14 @@ void GDFunctions::call(Function p_func, const Variant **p_args, int p_arg_count,
 			VALIDATE_ARG_NUM(0);
 			r_ret = Math::db2linear((double)*p_args[0]);
 		} break;
+		case MATH_WRAP: {
+			VALIDATE_ARG_COUNT(3);
+			r_ret = Math::wrapi((int64_t)*p_args[0], (int64_t)*p_args[1], (int64_t)*p_args[2]);
+		} break;
+		case MATH_WRAPF: {
+			VALIDATE_ARG_COUNT(3);
+			r_ret = Math::wrapf((double)*p_args[0], (double)*p_args[1], (double)*p_args[2]);
+		} break;
 		case LOGIC_MAX: {
 			VALIDATE_ARG_COUNT(2);
 			if (p_args[0]->get_type() == Variant::INT && p_args[1]->get_type() == Variant::INT) {
@@ -1285,6 +1295,8 @@ bool GDFunctions::is_deterministic(Function p_func) {
 		case MATH_RAD2DEG:
 		case MATH_LINEAR2DB:
 		case MATH_DB2LINEAR:
+		case MATH_WRAP:
+		case MATH_WRAPF:
 		case LOGIC_MAX:
 		case LOGIC_MIN:
 		case LOGIC_CLAMP:
@@ -1513,6 +1525,16 @@ MethodInfo GDFunctions::get_info(Function p_func) {
 			mi.return_val.type = Variant::REAL;
 			return mi;
 		} break;
+		case MATH_WRAP: {
+			MethodInfo mi("wrapi", PropertyInfo(Variant::INT, "value"), PropertyInfo(Variant::INT, "min"), PropertyInfo(Variant::INT, "max"));
+			mi.return_val.type = Variant::INT;
+			return mi;
+		} break;
+		case MATH_WRAPF: {
+			MethodInfo mi("wrapf", PropertyInfo(Variant::REAL, "value"), PropertyInfo(Variant::REAL, "min"), PropertyInfo(Variant::REAL, "max"));
+			mi.return_val.type = Variant::REAL;
+			return mi;
+		} break;
 		case LOGIC_MAX: {
 			MethodInfo mi("max", PropertyInfo(Variant::REAL, "a"), PropertyInfo(Variant::REAL, "b"));
 			mi.return_val.type = Variant::REAL;

+ 2 - 0
modules/gdscript/gd_functions.h

@@ -75,6 +75,8 @@ public:
 		MATH_RAD2DEG,
 		MATH_LINEAR2DB,
 		MATH_DB2LINEAR,
+		MATH_WRAP,
+		MATH_WRAPF,
 		LOGIC_MAX,
 		LOGIC_MIN,
 		LOGIC_CLAMP,

+ 40 - 0
modules/visual_script/visual_script_builtin_funcs.cpp

@@ -76,6 +76,8 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX
 	"rad2deg",
 	"linear2db",
 	"db2linear",
+	"wrapi",
+	"wrapf",
 	"max",
 	"min",
 	"clamp",
@@ -195,6 +197,8 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
 			return 2;
 		case MATH_LERP:
 		case MATH_DECTIME:
+		case MATH_WRAP:
+		case MATH_WRAPF:
 		case LOGIC_CLAMP:
 			return 3;
 		case FUNC_MAX: {
@@ -340,6 +344,22 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
 		case MATH_DB2LINEAR: {
 			return PropertyInfo(Variant::REAL, "db");
 		} break;
+		case MATH_WRAP: {
+			if (p_idx == 0)
+				return PropertyInfo(Variant::INT, "value");
+			else if (p_idx == 1)
+				return PropertyInfo(Variant::INT, "min");
+			else
+				return PropertyInfo(Variant::INT, "max");
+		} break;
+		case MATH_WRAPF: {
+			if (p_idx == 0)
+				return PropertyInfo(Variant::REAL, "value");
+			else if (p_idx == 1)
+				return PropertyInfo(Variant::REAL, "min");
+			else
+				return PropertyInfo(Variant::REAL, "max");
+		} break;
 		case LOGIC_MAX: {
 			if (p_idx == 0)
 				return PropertyInfo(Variant::REAL, "a");
@@ -523,9 +543,13 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
 		case MATH_DEG2RAD:
 		case MATH_RAD2DEG:
 		case MATH_LINEAR2DB:
+		case MATH_WRAPF:
 		case MATH_DB2LINEAR: {
 			t = Variant::REAL;
 		} break;
+		case MATH_WRAP: {
+			t = Variant::INT;
+		} break;
 		case LOGIC_MAX:
 		case LOGIC_MIN:
 		case LOGIC_CLAMP: {
@@ -856,6 +880,18 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
 			VALIDATE_ARG_NUM(0);
 			*r_return = Math::db2linear((double)*p_inputs[0]);
 		} break;
+		case VisualScriptBuiltinFunc::MATH_WRAP: {
+			VALIDATE_ARG_NUM(0);
+			VALIDATE_ARG_NUM(1);
+			VALIDATE_ARG_NUM(2);
+			*r_return = Math::wrapi((int64_t)*p_inputs[0], (int64_t)*p_inputs[1], (int64_t)*p_inputs[2]);
+		} break;
+		case VisualScriptBuiltinFunc::MATH_WRAPF: {
+			VALIDATE_ARG_NUM(0);
+			VALIDATE_ARG_NUM(1);
+			VALIDATE_ARG_NUM(2);
+			*r_return = Math::wrapf((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
+		} break;
 		case VisualScriptBuiltinFunc::LOGIC_MAX: {
 
 			if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT) {
@@ -1214,6 +1250,8 @@ void VisualScriptBuiltinFunc::_bind_methods() {
 	BIND_ENUM_CONSTANT(MATH_RAD2DEG);
 	BIND_ENUM_CONSTANT(MATH_LINEAR2DB);
 	BIND_ENUM_CONSTANT(MATH_DB2LINEAR);
+	BIND_ENUM_CONSTANT(MATH_WRAP);
+	BIND_ENUM_CONSTANT(MATH_WRAPF);
 	BIND_ENUM_CONSTANT(LOGIC_MAX);
 	BIND_ENUM_CONSTANT(LOGIC_MIN);
 	BIND_ENUM_CONSTANT(LOGIC_CLAMP);
@@ -1294,6 +1332,8 @@ void register_visual_script_builtin_func_node() {
 	VisualScriptLanguage::singleton->add_register_func("functions/built_in/rad2deg", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RAD2DEG>);
 	VisualScriptLanguage::singleton->add_register_func("functions/built_in/linear2db", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LINEAR2DB>);
 	VisualScriptLanguage::singleton->add_register_func("functions/built_in/db2linear", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_DB2LINEAR>);
+	VisualScriptLanguage::singleton->add_register_func("functions/built_in/wrapi", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_WRAP>);
+	VisualScriptLanguage::singleton->add_register_func("functions/built_in/wrapf", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_WRAPF>);
 
 	VisualScriptLanguage::singleton->add_register_func("functions/built_in/max", create_builtin_func_node<VisualScriptBuiltinFunc::LOGIC_MAX>);
 	VisualScriptLanguage::singleton->add_register_func("functions/built_in/min", create_builtin_func_node<VisualScriptBuiltinFunc::LOGIC_MIN>);

+ 2 - 0
modules/visual_script/visual_script_builtin_funcs.h

@@ -75,6 +75,8 @@ public:
 		MATH_RAD2DEG,
 		MATH_LINEAR2DB,
 		MATH_DB2LINEAR,
+		MATH_WRAP,
+		MATH_WRAPF,
 		LOGIC_MAX,
 		LOGIC_MIN,
 		LOGIC_CLAMP,