diff options
-rw-r--r-- | core/math/a_star.cpp | 11 | ||||
-rw-r--r-- | core/math/a_star.h | 1 | ||||
-rw-r--r-- | doc/base/classes.xml | 363 | ||||
-rw-r--r-- | editor/editor_settings.cpp | 10 | ||||
-rw-r--r-- | editor/import/resource_importer_scene.cpp | 45 | ||||
-rw-r--r-- | editor/import/resource_importer_scene.h | 9 | ||||
-rw-r--r-- | editor/plugins/spatial_editor_plugin.cpp | 77 | ||||
-rw-r--r-- | editor/plugins/spatial_editor_plugin.h | 4 | ||||
-rw-r--r-- | modules/gdscript/gd_functions.cpp | 4 |
9 files changed, 392 insertions, 132 deletions
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index 21516ac768..d1afcec18f 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -129,6 +129,16 @@ bool AStar::has_point(int p_id) const { return points.has(p_id); } +Array AStar::get_points() { + Array point_list; + + for (const Map<int, Point *>::Element *E = points.front(); E; E = E->next()) { + point_list.push_back(E->key()); + } + + return point_list; +} + bool AStar::are_points_connected(int p_id, int p_with_id) const { Segment s(p_id, p_with_id); @@ -407,6 +417,7 @@ void AStar::_bind_methods() { ClassDB::bind_method(D_METHOD("get_point_weight_scale", "id"), &AStar::get_point_weight_scale); ClassDB::bind_method(D_METHOD("remove_point", "id"), &AStar::remove_point); ClassDB::bind_method(D_METHOD("has_point", "id"), &AStar::has_point); + ClassDB::bind_method(D_METHOD("get_points"), &AStar::get_points); ClassDB::bind_method(D_METHOD("connect_points", "id", "to_id", "bidirectional"), &AStar::connect_points, DEFVAL(true)); ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id"), &AStar::disconnect_points); diff --git a/core/math/a_star.h b/core/math/a_star.h index 75b860d0a4..38d13d510b 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -105,6 +105,7 @@ public: real_t get_point_weight_scale(int p_id) const; void remove_point(int p_id); bool has_point(int p_id) const; + Array get_points(); void connect_points(int p_id, int p_with_id, bool bidirectional = true); void disconnect_points(int p_id, int p_with_id); diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 6f20be3694..ea74007482 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -20,7 +20,14 @@ <argument index="3" name="a8" type="int"> </argument> <description> - Make a color from red, green, blue and alpha. Arguments can range from 0 to 255. + Returns a 32 bit color with red, green, blue and alpha channels. Each channel has 8bits of information ranging from 0 to 255. + 'r8' red channel + 'g8' green channel + 'b8' blue channel + 'a8' alpha channel + [codeblock] + red = Color8(255, 0, 0) + [/codeblock] </description> </method> <method name="ColorN"> @@ -31,7 +38,10 @@ <argument index="1" name="alpha" type="float"> </argument> <description> - Make a color from color name (color_names.inc) and alpha ranging from 0 to 1. + Returns color 'name' with alpha ranging from 0 to 1. Note: 'name' is defined in color_names.inc. + [codeblock] + red = ColorN('red') + [/codeblock] </description> </method> <method name="abs"> @@ -40,7 +50,11 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the absolute value of parameter s (i.e. unsigned value, works for integer and float). + Returns the absolute value of parameter 's' (i.e. unsigned value, works for integer and float). + [codeblock] + # a is 1 + a = abs(-1) + [/codeblock] </description> </method> <method name="acos"> @@ -49,7 +63,11 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the principal value of the arc cosine of s, expressed in radians. In trigonometrics, arc cosine is the inverse operation of cosine. + Returns the arc cosine of 's' in radians. Use to get the angle of cosine 's'. + [codeblock] + # c is 0.523599 or 30 degrees if converted with rad2deg(s) + c = acos(0.866025) + [/codeblock] </description> </method> <method name="asin"> @@ -58,7 +76,11 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the principal value of the arc sine of s, expressed in radians. In trigonometrics, arc sine is the inverse operation of sine. + Returns the arc sine of 's' in radians. Use to get the angle of sine 's'. + [codeblock] + # s is 0.523599 or 30 degrees if converted with rad2deg(s) + s = asin(0.5) + [/codeblock] </description> </method> <method name="assert"> @@ -67,7 +89,18 @@ <argument index="0" name="condition" type="bool"> </argument> <description> - Assert that the condition is true. If the condition is false, generates an error. + Assert that the condition is true. If the condition is false a fatal error is generated and the program is halted. + Useful for debugging to make sure a value is always true. + [codeblock] + # Speed should always be between 0 and 20 + speed = -10 + # Is true + assert(speed < 20) + # Is false and program stops + assert(speed >= 0) + # or simply + assert(speed >= 0 && speed < 20) + [/codeblock] </description> </method> <method name="atan"> @@ -76,7 +109,11 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the principal value of the arc tangent of s, expressed in radians. In trigonometrics, arc tangent is the inverse operation of tangent. Notice that because of the sign ambiguity, the function cannot determine with certainty in which quadrant the angle falls only by its tangent value. See [method atan2] for an alternative that takes a fractional argument instead. + Returns the arc tangent of 's' in radians. Use to get the angle of tangent 's'. Notice that because of the sign ambiguity, the function cannot determine with certainty in which quadrant the angle falls only by its tangent value. See [method atan2] for an alternative that takes a fractional argument instead. + [codeblock] + # a is 0.463648 + a = atan(0.5) + [/codeblock] </description> </method> <method name="atan2"> @@ -87,7 +124,11 @@ <argument index="1" name="y" type="float"> </argument> <description> - Returns the principal value of the arc tangent of y/x, expressed in radians. To compute the value, the function takes into account the sign of both arguments in order to determine the quadrant. + Returns the arc tangent of y/x in radians. Use to get the angle of tangent y/x. To compute the value, the function takes into account the sign of both arguments in order to determine the quadrant. + [codeblock] + # a is 3.141593 + a = atan(0,-1) + [/codeblock] </description> </method> <method name="bytes2var"> @@ -105,7 +146,13 @@ <argument index="0" name="s" type="float"> </argument> <description> - Rounds s upward, returning the smallest integral value that is not less than s. + Rounds 's' upward, returning the smallest integral value that is not less than 's'. + [codeblock] + # i is 2 + i = ceil(1.45) + # i is 2 + i = ceil(1.001) + [/codeblock] </description> </method> <method name="char"> @@ -115,6 +162,12 @@ </argument> <description> Returns a character as String of the given ASCII code. + [codeblock] + # a is 'A' + a = char(65) + # a is 'a' + a = char(65+32) + [/codeblock] </description> </method> <method name="clamp"> @@ -127,7 +180,16 @@ <argument index="2" name="max" type="float"> </argument> <description> - Clamps a value between a minimum and maximum value. + Clamp 'val' and return a value not less than 'min' and not more than 'max'. + [codeblock] + speed = 1000 + # a is 20 + a = clamp(speed, 1, 20) + + speed = -10 + # a is 1 + a = clamp(speed, 1, 20) + [/codeblock] </description> </method> <method name="convert"> @@ -139,6 +201,15 @@ </argument> <description> Convert from a type to another in the best way possible. The "type" parameter uses the enum TYPE_* in [@Global Scope]. + [codeblock] + a = Vector2(1, 0) + # prints 1 + print(a.length()) + a = convert(a, TYPE_STRING) + # prints 6 + # (1, 0) is 6 characters + print(a.length()) + [/codeblock] </description> </method> <method name="cos"> @@ -147,7 +218,12 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the cosine of an angle of s radians. + Returns the cosine of angle 's' in radians. + [codeblock] + # prints 1 and -1 + print(cos(PI*2)) + print(cos(PI)) + [/codeblock] </description> </method> <method name="cosh"> @@ -156,7 +232,11 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the hyperbolic cosine of s. + Returns the hyperbolic cosine of 's' in radians. + [codeblock] + # prints 1.543081 + print(cosh(1)) + [/codeblock] </description> </method> <method name="db2linear"> @@ -174,7 +254,11 @@ <argument index="0" name="step" type="float"> </argument> <description> - Return the amount of decimals in the floating point value. + Returns the number of digit places after the decimal that the first non-zero digit occurs. + [codeblock] + # n is 2 + n = decimals(0.035) + [/codeblock] </description> </method> <method name="dectime"> @@ -187,7 +271,11 @@ <argument index="2" name="step" type="float"> </argument> <description> - Decreases time by a specified amount. + Returns the result of 'value' decreased by 'step' * 'amount'. + [codeblock] + # a = 59 + a = dectime(60, 10, 0.1)) + [/codeblock] </description> </method> <method name="deg2rad"> @@ -196,7 +284,11 @@ <argument index="0" name="deg" type="float"> </argument> <description> - Convert from degrees to radians. + Returns degrees converted to radians. + [codeblock] + # r is 3.141593 + r = deg2rad(180) + [/codeblock] </description> </method> <method name="dict2inst"> @@ -205,7 +297,7 @@ <argument index="0" name="dict" type="Dictionary"> </argument> <description> - Convert a previously converted instances to dictionary back into an instance. Useful for deserializing. + Convert a previously converted instance to dictionary back into an instance. Useful for deserializing. </description> </method> <method name="ease"> @@ -225,8 +317,12 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the base-e exponential function of s, which is e raised to the power s: e^s. + Returns [b]e[/b] raised to the power of 's'. [b]e[/b] sometimes called "Euler's number" is a mathematical constant whose value is approximately 2.71828. </description> + [codeblock] + # a is 2.71828 + a = exp(2) + [/codeblock] </method> <method name="floor"> <return type="float"> @@ -234,8 +330,14 @@ <argument index="0" name="s" type="float"> </argument> <description> - Rounds s downward, returning the largest integral value that is not greater than s. + Returns the largest integer value (rounded down) that is less than or equal to 's'. </description> + [codeblock] + # a is 2 + a = floor(2.99) + # a is -3 + a = floor(-2.99) + [/codeblock] </method> <method name="fmod"> <return type="float"> @@ -260,7 +362,26 @@ <argument index="1" name="y" type="float"> </argument> <description> - Module (remainder of x/y) that wraps equally in positive and negative. + Returns the floating-point remainder of x/y that wraps equally in positive and negative. + [codeblock] + var i = -10; + while i < 0: + prints(i, fposmod(i, 10)) + i += 1 + [/codeblock] + Produces: + [codeblock] + -10 10 + -9 1 + -8 2 + -7 3 + -6 4 + -5 5 + -4 6 + -3 7 + -2 8 + -1 9 + [/codeblock] </description> </method> <method name="funcref"> @@ -271,7 +392,15 @@ <argument index="1" name="funcname" type="String"> </argument> <description> - Return a reference to the specified function. + Returns a reference to the specified function 'funcname' in object 'instance'. + [codeblock] + a = funcref(self, "foo") + a.call_func() + + func foo(): + print("bar") + [/codeblock] + Prints out "bar". This is a trivial example, the real power is that variable 'a' can be passed around to functions. </description> </method> <method name="hash"> @@ -280,7 +409,11 @@ <argument index="0" name="var" type="Variant"> </argument> <description> - Hash the variable passed and return an integer. + Returns the integer hash of the variable passed. + [codeblock] + # print 177670 + print(hash("a")) + [/codeblock] </description> </method> <method name="inst2dict"> @@ -289,7 +422,19 @@ <argument index="0" name="inst" type="Object"> </argument> <description> - Convert a script class instance to a dictionary (useful for serializing). + Returns the passed instance converted a dictionary (useful for serializing). + [codeblock] + var foo = "bar" + func _ready(): + var d = inst2dict(self) + print(d.keys()) + print(d.values()) + [/codeblock] + Prints out: + [codeblock] + [@subpath, @path, foo] + [, res://test.gd, bar] + [/codeblock] </description> </method> <method name="instance_from_id"> @@ -298,7 +443,15 @@ <argument index="0" name="instance_id" type="int"> </argument> <description> - Get an object by its ID. + Returns the Object that corresponds to 'instance_id'. All Objects have a unique instance ID. + [codeblock] + var foo = "bar" + func _ready(): + var id = get_instance_id() + var inst = instance_from_id(id) + print(inst.foo) + [/codeblock] + Prints "bar" </description> </method> <method name="inverse_lerp"> @@ -323,7 +476,7 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns whether s is an infinity value (either positive infinity or negative infinity). + Returns True/False whether 's' is an infinity value (either positive infinity or negative infinity). </description> </method> <method name="is_nan"> @@ -332,7 +485,7 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns whether s is a NaN (Not-A-Number) value. + Returns True/False whether 's' is a NaN (Not-A-Number) value. </description> </method> <method name="len"> @@ -341,7 +494,16 @@ <argument index="0" name="var" type="Variant"> </argument> <description> - Returns the length of the given Variant if applicable. It will return character count of a String, element count of an Array, etc. +<<<<<<< HEAD + Returns length of Variant 'var'. Length is the character count of String, element count of Array, size of Dictionary, etc. Note: Generates a fatal error if Variant can not provide a length. +======= + Returns length of Variant 'var'. Length is the element count of an Array, size of a Dictionary, etc. Note: Generates a fatal error if Variant can not provide a length. +>>>>>>> 75b92e809dc95aefd3afab5a9efbd582a1a8d953 + [codeblock] + a = [1, 2, 3, 4] + print(len(a)) + [/codeblock] + Prints 4 </description> </method> <method name="lerp"> @@ -372,7 +534,11 @@ <argument index="0" name="path" type="String"> </argument> <description> - Load a resource from the filesystem, pass a valid path as argument. + Load a resource from the filesystem located at 'path'. Note: resource paths can be obtained by right clicking on a resource in the Assets Pannel and choosing "Copy Path". + [codeblock] + # load a scene called main located in the root of the project directory + var main = load("res://main.tscn") + [/codeblock] </description> </method> <method name="log"> @@ -381,7 +547,11 @@ <argument index="0" name="s" type="float"> </argument> <description> - Natural logarithm. + Natural logarithm. The amount of time needed to reach a certain level of continuous growth. Note: This is not the same as the log funcation on your calculator which is a base 10 logarithm. + [codeblock] + # a is 2.302585 + a = log(10) + [/codeblock] </description> </method> <method name="max"> @@ -392,7 +562,13 @@ <argument index="1" name="b" type="float"> </argument> <description> - Return the maximum of two values. + Returns the maximum of two values. + [codeblock] + # a is 2 + a = max(1,2) + # a is -3.99 + a = max(-3.99, -4) + [/codeblock] </description> </method> <method name="min"> @@ -403,7 +579,13 @@ <argument index="1" name="b" type="float"> </argument> <description> - Return the minimum of two values. + Returns the minimum of two values. + [codeblock] + # a is 1 + a = min(1,2) + # a is -4 + a = min(-3.99, -4) + [/codeblock] </description> </method> <method name="nearest_po2"> @@ -412,7 +594,15 @@ <argument index="0" name="val" type="int"> </argument> <description> - Return the nearest larger power of 2 for an integer. + Returns the nearest larger power of 2 for an integer. + [codeblock] + # a is 4 + a = nearest_po2(3) + # a is 4 + a = nearest_po2(4) + # a is 8 + a = nearest_po2(5) + [/codeblock] </description> </method> <method name="parse_json"> @@ -423,6 +613,13 @@ <description> Parse JSON text to a Variant (use [method typeof] to check if it is what you expect). Be aware that the JSON specification does not define integer or float types, but only a number type. Therefore, parsing a JSON text will convert every numerical values to [float] types. + [codeblock] + p = parse_json('["a", "b", "c"]') + if typeof(p) == TYPE_ARRAY: + print(p[0]) + else: + print("unexpected results") + [/codeblock] </description> </method> <method name="pow"> @@ -433,7 +630,11 @@ <argument index="1" name="y" type="float"> </argument> <description> - Power function, x elevate to y. + Returns the result of 'x' raised to the power of 'y'. + [codeblock] + # a is 32 + a = pow(2,5) + [/codeblock] </description> </method> <method name="preload"> @@ -442,14 +643,22 @@ <argument index="0" name="path" type="String"> </argument> <description> - Preload a resource from the filesystem. The resource is loaded during script parsing. + Returns a resource from the filesystem that is loaded during script parsing. Note: resource paths can be obtained by right clicking on a resource in the Assets Pannel and choosing "Copy Path". + [codeblock] + # load a scene called main located in the root of the project directory + var main = preload("res://main.tscn") </description> </method> <method name="print" qualifiers="vararg"> <return type="void"> </return> <description> - Print one or more arguments to strings in the best way possible to a console line. + Converts one or more arguments to strings in the best way possible and prints them to the console. + [codeblock] + a = [1,2,3] + print("a","b",a) + [/codeblock] + Prints ab[1, 2, 3] </description> </method> <method name="print_stack"> @@ -30334,10 +30543,10 @@ </class> <class name="Node2D" inherits="CanvasItem" category="Core"> <brief_description> - Base node for 2D system. + A 2D game object, parent of all 2D related nodes. Has a position, rotation, scale and Z-index. </brief_description> <description> - Base node for 2D system. Node2D contains a position, rotation and scale, which is used to position and animate. It can alternatively be used with a custom 2D transform ([Transform2D]). A tree of Node2Ds allows complex hierarchies for animation and positioning. + A 2D game object, with a position, rotation and scale. All 2D physics nodes and sprites inherit from Node2D. Use Node2D as a parent node to move, scale and rotate children in a 2D project. Also gives control on the node's render order. </description> <methods> <method name="apply_scale"> @@ -30346,7 +30555,7 @@ <argument index="0" name="ratio" type="Vector2"> </argument> <description> - Apply the 'ratio' scale to the 2D node, according to its current scale value. + Multiplies the current scale by the 'ratio' vector. </description> </method> <method name="edit_set_pivot"> @@ -30355,7 +30564,7 @@ <argument index="0" name="pivot" type="Vector2"> </argument> <description> - Set the pivot position of the 2D node to 'pivot' value. This method is implemented only in some nodes that inherit Node2D. + Set the pivot position of the 2D node to 'pivot' value. Only some Node2Ds implement this method. </description> </method> <method name="get_angle_to" qualifiers="const"> @@ -30364,42 +30573,42 @@ <argument index="0" name="point" type="Vector2"> </argument> <description> - Return the rotation angle in radians needed for the 2d node to point at 'point' position. + Returns the angle between the node and the 'point' in radians. </description> </method> <method name="get_global_position" qualifiers="const"> <return type="Vector2"> </return> <description> - Return the global position of the 2D node. + Returns the node's global position. </description> </method> <method name="get_global_rotation" qualifiers="const"> <return type="float"> </return> <description> - Return the global rotation in radians of the 2D node. + Returns the node's global rotation in radians. </description> </method> <method name="get_global_rotation_in_degrees" qualifiers="const"> <return type="float"> </return> <description> - Return the global rotation in degrees of the 2D node. + Return the node's global rotation in degrees. </description> </method> <method name="get_global_scale" qualifiers="const"> <return type="Vector2"> </return> <description> - Return the global scale of the 2D node. + Returns the node's global scale. </description> </method> <method name="get_position" qualifiers="const"> <return type="Vector2"> </return> <description> - Return the position of the 2D node. + Returns the node's position. </description> </method> <method name="get_relative_transform_to_parent" qualifiers="const"> @@ -30408,35 +30617,35 @@ <argument index="0" name="parent" type="Node"> </argument> <description> - Return the transform [Transform2D] calculated relatively to the parent of this 2D node. + Returns the [Transform2D] relative to this node's parent. </description> </method> <method name="get_rotation" qualifiers="const"> <return type="float"> </return> <description> - Return the rotation in radians of the 2D node. + Returns the node's rotation in radians. </description> </method> <method name="get_rotation_in_degrees" qualifiers="const"> <return type="float"> </return> <description> - Return the rotation in degrees of the 2D node. + Returns the node's rotation in degrees. </description> </method> <method name="get_scale" qualifiers="const"> <return type="Vector2"> </return> <description> - Return the scale of the 2D node. + Returns the node's scale. </description> </method> <method name="get_z" qualifiers="const"> <return type="int"> </return> <description> - Return the Z-index of the 2D node. + Returns the node's Z-index. </description> </method> <method name="global_translate"> @@ -30445,14 +30654,14 @@ <argument index="0" name="offset" type="Vector2"> </argument> <description> - Apply a global translation of 'offset' to the 2D node, starting from its current global position. + Adds the 'offset' vector to the node's global position. </description> </method> <method name="is_z_relative" qualifiers="const"> <return type="bool"> </return> <description> - Return true if the Z-index value of this 2D node is relative to its parent's. Else, return false. + Returns true if this node's Z-index is relative to its parent's. Else, returns false. </description> </method> <method name="look_at"> @@ -30461,7 +30670,7 @@ <argument index="0" name="point" type="Vector2"> </argument> <description> - Rotate the 2d node so it points at 'point' position. + Rotates the node so it points towards the 'point'. </description> </method> <method name="move_local_x"> @@ -30472,7 +30681,7 @@ <argument index="1" name="scaled" type="bool" default="false"> </argument> <description> - Apply a local translation on X axis to the 2D node according to the 'delta' of the process. If 'scaled' is false, the movement is normalized. + Apply a local translation on the node's X axis based on the process's 'delta'. If 'scaled' is false, normalizes the movement. </description> </method> <method name="move_local_y"> @@ -30483,7 +30692,7 @@ <argument index="1" name="scaled" type="bool" default="false"> </argument> <description> - Apply a local translation on Y axis to the 2D node according to the 'delta' of the process. If 'scaled' is false, the movement is normalized. + Apply a local translation on the node's Y axis based on the process's 'delta'. If 'scaled' is false, normalizes the movement. </description> </method> <method name="rotate"> @@ -30492,7 +30701,7 @@ <argument index="0" name="radians" type="float"> </argument> <description> - Apply a rotation (in radians) to the 2D node, starting from its current rotation. + Apply a rotation to the node, in radians, starting from its current rotation. </description> </method> <method name="set_global_position"> @@ -30501,7 +30710,7 @@ <argument index="0" name="pos" type="Vector2"> </argument> <description> - Set the global position of the 2D node. + Set the node's global position. </description> </method> <method name="set_global_rotation"> @@ -30510,7 +30719,7 @@ <argument index="0" name="radians" type="float"> </argument> <description> - Set the global rotation in radians of the 2D node + Set the node's global rotation in radians. </description> </method> <method name="set_global_rotation_in_degrees"> @@ -30519,7 +30728,7 @@ <argument index="0" name="degrees" type="float"> </argument> <description> - Set the global rotation in degrees of the 2D node + Set the node's global rotation in degrees. </description> </method> <method name="set_global_scale"> @@ -30528,7 +30737,7 @@ <argument index="0" name="scale" type="Vector2"> </argument> <description> - Set the global scale of the 2D node. + Set the node's global scale. </description> </method> <method name="set_global_transform"> @@ -30537,7 +30746,7 @@ <argument index="0" name="xform" type="Transform2D"> </argument> <description> - Set the global transform [Transform2D] of the 2D node. + Set the node's global [Transform2D]. </description> </method> <method name="set_position"> @@ -30546,7 +30755,7 @@ <argument index="0" name="pos" type="Vector2"> </argument> <description> - Set the position of the 2D node. + Set the node's position. </description> </method> <method name="set_rotation"> @@ -30555,7 +30764,7 @@ <argument index="0" name="radians" type="float"> </argument> <description> - Set the rotation in radians of the 2D node. + Set the node's rotation in radians. </description> </method> <method name="set_rotation_in_degrees"> @@ -30564,7 +30773,7 @@ <argument index="0" name="degrees" type="float"> </argument> <description> - Set the rotation in degrees of the 2D node. + Set the node's rotation in degrees. </description> </method> <method name="set_scale"> @@ -30573,7 +30782,7 @@ <argument index="0" name="scale" type="Vector2"> </argument> <description> - Set the scale of the 2D node. + Set the node's scale. </description> </method> <method name="set_transform"> @@ -30582,7 +30791,7 @@ <argument index="0" name="xform" type="Transform2D"> </argument> <description> - Set the local transform [Transform2D] of the 2D node. + Set the node's local [Transform2D]. </description> </method> <method name="set_z"> @@ -30591,7 +30800,7 @@ <argument index="0" name="z" type="int"> </argument> <description> - Set the Z-index value of the 2D node. + Set the node's Z-index. </description> </method> <method name="set_z_as_relative"> @@ -30600,7 +30809,7 @@ <argument index="0" name="enable" type="bool"> </argument> <description> - Set the Z-index value as relative to the parent node of this 2D node. Thus, if this 2D node's Z-index value is 2 and its parent's effective Z-index is 3, then the effective Z-index value of this 2D node would be 3 + 2 = 5. + Make the node's Z-index relative to its parent's Z-index. If this node's Z-index is 2 and its parent's effective Z-index is 3, then this node's effective Z-index will be 2 + 3 = 5. </description> </method> <method name="to_global" qualifiers="const"> @@ -30625,34 +30834,46 @@ <argument index="0" name="offset" type="Vector2"> </argument> <description> - Apply a local translation of 'offset' to the 2D node, starting from its current local position. + Translate the node locally by the 'offset' vector, starting from its current local position. </description> </method> </methods> <members> <member name="global_position" type="Vector2" setter="set_global_position" getter="get_global_position" brief=""> + Global position. </member> <member name="global_rotation" type="float" setter="set_global_rotation" getter="get_global_rotation" brief=""> + Global rotation in radians. </member> <member name="global_rotation_deg" type="float" setter="set_global_rotation_in_degrees" getter="get_global_rotation_in_degrees" brief=""> + Global rotation in degrees. </member> <member name="global_scale" type="Vector2" setter="set_global_scale" getter="get_global_scale" brief=""> + Global scale. </member> <member name="global_transform" type="Transform2D" setter="set_global_transform" getter="get_global_transform" brief=""> + Global [Transform2D]. </member> <member name="position" type="Vector2" setter="set_position" getter="get_position" brief=""> + Position, relative to the node's parent. </member> <member name="rotation" type="float" setter="set_rotation" getter="get_rotation" brief=""> + Rotation in radians. </member> <member name="rotation_deg" type="float" setter="set_rotation_in_degrees" getter="get_rotation_in_degrees" brief=""> + Rotation in degrees. </member> <member name="scale" type="Vector2" setter="set_scale" getter="get_scale" brief=""> + Rotation in degrees. </member> <member name="transform" type="Transform2D" setter="set_transform" getter="get_transform" brief=""> + Local [Transform2D]. </member> <member name="z" type="int" setter="set_z" getter="get_z" brief=""> + Z-index. Controls the order in which the nodes render. A node with a higher Z-index will display in front of others. </member> <member name="z_as_relative" type="bool" setter="set_z_as_relative" getter="is_z_relative" brief=""> + Make the node's Z-index relative to its parent's Z-index. If this node's Z-index is 2 and its parent's effective Z-index is 3, then this node's effective Z-index will be 2 + 3 = 5. </member> </members> <constants> @@ -52541,14 +52762,14 @@ <return type="String"> </return> <description> - Return the id of the thread, uniquely identifying it among all threads. + Returns the current [Thread]\ s id, uniquely identifying it among all threads. </description> </method> <method name="is_active" qualifiers="const"> <return type="bool"> </return> <description> - Whether this thread is currently active, an active Thread cannot start work on a new method but can be joined with [method wait_to_finish]. + Returns true if this [Thread] is currently active. An active [Thread] cannot start work on a new method but can be joined with [method wait_to_finish]. </description> </method> <method name="start"> @@ -52563,7 +52784,7 @@ <argument index="3" name="priority" type="int" default="1"> </argument> <description> - Start a new [Thread], it will run "method" on object "instance" using "userdata" as an argument and running with "priority", one of PRIORITY_* enum. + Starts a new [Thread] that runs "method" on object "instance" with "userdata" passed as an argument. The "priority" of the [Thread] can be changed by passing a PRIORITY_* enum. Returns OK on success, or ERR_CANT_CREATE on failure. </description> </method> diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index db76a27f5f..50cee6d892 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -676,9 +676,15 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { set("editors/3d/warped_mouse_panning", true); set("editors/3d/orbit_sensitivity", 0.4); - set("editors/3d/freelook_inertia", 3); - set("editors/3d/freelook_base_speed", 1); + set("editors/3d/orbit_inertia", 0.2); + hints["editors/3d/orbit_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/orbit_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); + + set("editors/3d/freelook_inertia", 0.2); + hints["editors/3d/freelook_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/freelook_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); + + set("editors/3d/freelook_base_speed", 0.5); + hints["editors/3d/freelook_base_speed"] = PropertyInfo(Variant::REAL, "editors/3d/freelook_base_speed", PROPERTY_HINT_RANGE, "0.0, 10, 0.1"); set("editors/3d/freelook_activation_modifier", 0); hints["editors/3d/freelook_activation_modifier"] = PropertyInfo(Variant::INT, "editors/3d/freelook_activation_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl"); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 0bbe287e2b..cc519c1c4b 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -40,6 +40,8 @@ #include "scene/3d/portal.h" #include "scene/3d/room_instance.h" #include "scene/3d/vehicle_body.h" +#include "scene/animation/animation_player.h" +#include "scene/resources/animation.h" #include "scene/resources/box_shape.h" #include "scene/resources/plane_shape.h" #include "scene/resources/ray_shape.h" @@ -118,9 +120,13 @@ String ResourceImporterScene::get_preset_name(int p_idx) const { switch (p_idx) { case PRESET_SINGLE_SCENE: return TTR("Import as Single Scene"); + case PRESET_SEPERATE_ANIMATIONS: return TTR("Import with Seperate Animations"); case PRESET_SEPARATE_MATERIALS: return TTR("Import with Separate Materials"); case PRESET_SEPARATE_MESHES: return TTR("Import with Separate Objects"); case PRESET_SEPARATE_MESHES_AND_MATERIALS: return TTR("Import with Separate Objects+Materials"); + case PRESET_SEPARATE_MESHES_AND_ANIMATIONS: return TTR("Import with Seperate Objects+Animations"); + case PRESET_SEPERATE_MATERIALS_AND_ANIMATIONS: return TTR("Import with Seperate Materials+Animations"); + case PRESET_SEPERATE_MESHES_MATERIALS_AND_ANIMATIONS: return TTR("Import with Seperate Objects+Materials+Animations"); case PRESET_MULTIPLE_SCENES: return TTR("Import as Multiple Scenes"); case PRESET_MULTIPLE_SCENES_AND_MATERIALS: return TTR("Import as Multiple Scenes+Materials"); } @@ -810,12 +816,33 @@ static String _make_extname(const String &p_str) { return ext_name; } -void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) { +void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) { List<PropertyInfo> pi; print_line("node: " + String(p_node->get_name())); + if (p_make_animations) { + if (Object::cast_to<AnimationPlayer>(p_node)) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node); + + List<StringName> anims; + ap->get_animation_list(&anims); + for (List<StringName>::Element *E = anims.front(); E; E = E->next()) { + + Ref<Animation> anim = ap->get_animation(E->get()); + ERR_CONTINUE(anim.is_null()); + + if (!p_animations.has(anim)) { + + String ext_name = p_base_path.plus_file(_make_extname(E->get()) + ".anim"); + ResourceSaver::save(ext_name, anim, ResourceSaver::FLAG_CHANGE_PATH); + p_animations[anim] = anim; + } + } + } + } + p_node->get_property_list(&pi); for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) { @@ -907,7 +934,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String for (int i = 0; i < p_node->get_child_count(); i++) { - _make_external_resources(p_node->get_child(i), p_base_path, p_make_materials, p_keep_materials, p_make_meshes, p_materials, p_meshes); + _make_external_resources(p_node->get_child(i), p_base_path, p_make_animations, p_make_materials, p_keep_materials, p_make_meshes, p_animations, p_materials, p_meshes); } } @@ -927,9 +954,10 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in script_ext_hint += "*." + E->get(); } - bool materials_out = p_preset == PRESET_SEPARATE_MATERIALS || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS; - bool meshes_out = p_preset == PRESET_SEPARATE_MESHES || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS; + bool materials_out = p_preset == PRESET_SEPARATE_MATERIALS || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS || p_preset == PRESET_SEPERATE_MATERIALS_AND_ANIMATIONS || p_preset == PRESET_SEPERATE_MESHES_MATERIALS_AND_ANIMATIONS; + bool meshes_out = p_preset == PRESET_SEPARATE_MESHES || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || PRESET_SEPARATE_MESHES_AND_ANIMATIONS || PRESET_SEPERATE_MESHES_MATERIALS_AND_ANIMATIONS; bool scenes_out = p_preset == PRESET_MULTIPLE_SCENES || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS; + bool animations_out = p_preset == PRESET_SEPERATE_ANIMATIONS || PRESET_SEPARATE_MESHES_AND_ANIMATIONS || p_preset == PRESET_SEPERATE_MATERIALS_AND_ANIMATIONS || p_preset == PRESET_SEPERATE_MESHES_MATERIALS_AND_ANIMATIONS; r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/custom_script", PROPERTY_HINT_FILE, script_ext_hint), "")); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "nodes/storage", PROPERTY_HINT_ENUM, "Single Scene,Instanced Sub-Scenes"), scenes_out ? 1 : 0)); @@ -943,6 +971,7 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 15)); r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "animation/filter_script", PROPERTY_HINT_MULTILINE_TEXT), "")); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "animation/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), animations_out ? true : false)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/optimizer/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/optimizer/max_linear_error"), 0.05)); r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/optimizer/max_angular_error"), 0.01)); @@ -1078,13 +1107,14 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p _filter_tracks(scene, animation_filter); } + bool external_animations = int(p_options["animation/storage"]) == 1; bool external_materials = p_options["materials/storage"]; bool external_meshes = p_options["meshes/storage"]; bool external_scenes = int(p_options["nodes/storage"]) == 1; String base_path = p_source_file.get_base_dir(); - if (external_materials || external_meshes || external_scenes) { + if (external_animations || external_materials || external_meshes || external_scenes) { if (bool(p_options["external_files/store_in_subdir"])) { String subdir_name = p_source_file.get_file().get_basename(); @@ -1097,13 +1127,14 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p } } - if (external_materials || external_meshes) { + if (external_animations || external_materials || external_meshes) { + Map<Ref<Animation>, Ref<Animation> > anim_map; Map<Ref<Material>, Ref<Material> > mat_map; Map<Ref<ArrayMesh>, Ref<ArrayMesh> > mesh_map; bool keep_materials = bool(p_options["materials/keep_on_reimport"]); - _make_external_resources(scene, base_path, external_materials, keep_materials, external_meshes, mat_map, mesh_map); + _make_external_resources(scene, base_path, external_animations, external_materials, keep_materials, external_meshes, anim_map, mat_map, mesh_map); } progress.step(TTR("Running Custom Script.."), 2); diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 9c3d5e7876..a483c3776f 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -85,8 +85,15 @@ class ResourceImporterScene : public ResourceImporter { enum Presets { PRESET_SEPARATE_MATERIALS, PRESET_SEPARATE_MESHES, + PRESET_SEPERATE_ANIMATIONS, + PRESET_SINGLE_SCENE, + PRESET_SEPARATE_MESHES_AND_MATERIALS, + PRESET_SEPARATE_MESHES_AND_ANIMATIONS, + PRESET_SEPERATE_MATERIALS_AND_ANIMATIONS, + PRESET_SEPERATE_MESHES_MATERIALS_AND_ANIMATIONS, + PRESET_MULTIPLE_SCENES, PRESET_MULTIPLE_SCENES_AND_MATERIALS, }; @@ -112,7 +119,7 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes); + void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animation, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes); Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<ArrayMesh>, Ref<Shape> > &collision_map); diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 235700a3c3..93d12fd3d2 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -76,40 +76,35 @@ void SpatialEditorViewport::_update_camera(float p_interp_delta) { } else camera->set_perspective(get_fov(), get_znear(), get_zfar()); - Transform new_transform = to_camera_transform(cursor); - Transform old_transform = camera->get_global_transform(); - Transform transform; + float inertia = EDITOR_DEF("editors/3d/orbit_inertia", 0.5); + inertia = MAX(0, inertia); - bool disable_interp = orthogonal || (Input::get_singleton()->get_mouse_button_mask() & (2 | 4)) || Input::get_singleton()->is_key_pressed(KEY_SHIFT) || Input::get_singleton()->is_key_pressed(KEY_ALT) || Input::get_singleton()->is_key_pressed(KEY_CONTROL); + Cursor old_camera_cursor = camera_cursor; + camera_cursor = cursor; - if (p_interp_delta && !disable_interp) { - //interpolate - float interp_speed = 14; //maybe should be made configuration - transform = old_transform.interpolate_with(new_transform, MIN(1.0, p_interp_delta * interp_speed)); - } else { - transform = new_transform; + camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, p_interp_delta * (1 / inertia)); + camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, p_interp_delta * (1 / inertia)); + + bool disable_interp = (Input::get_singleton()->get_mouse_button_mask() & (2 | 4)) || Input::get_singleton()->is_key_pressed(KEY_SHIFT) || Input::get_singleton()->is_key_pressed(KEY_ALT) || Input::get_singleton()->is_key_pressed(KEY_CONTROL); + + if (p_interp_delta == 0 || disable_interp || is_freelook_active()) { + camera_cursor = cursor; } float tolerance = 0.0001; bool equal = true; - for (int i = 0; i < 3; i++) { - if (transform.basis[i].distance_to(old_transform.basis[i]) > tolerance) { - equal = false; - break; - } - } + if (Math::abs(old_camera_cursor.x_rot - camera_cursor.x_rot) > tolerance || Math::abs(old_camera_cursor.y_rot - camera_cursor.y_rot) > tolerance) + equal = false; - if (equal && transform.origin.distance_to(old_transform.origin) > tolerance) { + if (equal && old_camera_cursor.pos.distance_squared_to(camera_cursor.pos) > tolerance * tolerance) equal = false; - } - if (equal) { - transform = new_transform; - } + if (equal && Math::abs(old_camera_cursor.distance - camera_cursor.distance) > tolerance) + equal = false; - if (!equal || p_interp_delta == 0) { - //print_line(transform); - camera->set_global_transform(transform); + if (!equal || p_interp_delta == 0 || is_freelook_active()) { + + camera->set_global_transform(to_camera_transform(camera_cursor)); update_transform_gizmo_view(); } } @@ -1540,6 +1535,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { Vector3 pos = camera_transform.xform(Vector3(0, 0, 0)); Vector3 diff = camera->get_translation() - pos; cursor.pos += diff; + freelook_target_position += diff; name = ""; _update_name(); @@ -1661,7 +1657,7 @@ void SpatialEditorViewport::scale_cursor_distance(real_t scale) { Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const { Point2i relative; - if (bool(EditorSettings::get_singleton()->get("editors/3d/warped_mouse_panning"))) { + if (bool(EDITOR_DEF("editors/3d/warped_mouse_panning", false))) { relative = Input::get_singleton()->warp_mouse_motion(p_ev_mouse_motion, surface->get_global_rect()); } else { relative = p_ev_mouse_motion->get_relative(); @@ -1672,7 +1668,7 @@ Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMous void SpatialEditorViewport::_update_freelook(real_t delta) { if (!is_freelook_active()) { - freelook_velocity = Vector3(); + freelook_target_position = cursor.pos; return; } @@ -1689,60 +1685,47 @@ void SpatialEditorViewport::_update_freelook(real_t delta) { int key_speed_modifier = Object::cast_to<InputEventKey>(ED_GET_SHORTCUT("spatial_editor/freelook_speed_modifier")->get_shortcut().ptr())->get_scancode(); Vector3 direction; - bool pressed = false; bool speed_modifier = false; const Input &input = *Input::get_singleton(); if (input.is_key_pressed(key_left)) { direction -= right; - pressed = true; } if (input.is_key_pressed(key_right)) { direction += right; - pressed = true; } if (input.is_key_pressed(key_forward)) { direction += forward; - pressed = true; } if (input.is_key_pressed(key_backwards)) { direction -= forward; - pressed = true; } if (input.is_key_pressed(key_up)) { direction += up; - pressed = true; } if (input.is_key_pressed(key_down)) { direction -= up; - pressed = true; } if (input.is_key_pressed(key_speed_modifier)) { speed_modifier = true; } - const EditorSettings &s = *EditorSettings::get_singleton(); - real_t inertia = s.get("editors/3d/freelook_inertia"); - if (inertia < 0) - inertia = 0; - - const real_t base_speed = s.get("editors/3d/freelook_base_speed"); - const real_t modifier_speed_factor = s.get("editors/3d/freelook_modifier_speed_factor"); + real_t inertia = EDITOR_DEF("editors/3d/freelook_inertia", 0.2); + inertia = MAX(0, inertia); + const real_t base_speed = EDITOR_DEF("editors/3d/freelook_base_speed", 0.5); + const real_t modifier_speed_factor = EDITOR_DEF("editors/3d/freelook_modifier_speed_factor", 5); real_t speed = base_speed * cursor.distance; if (speed_modifier) speed *= modifier_speed_factor; - Vector3 instant_velocity = direction * speed; - // Higher inertia should increase "lag" (lerp with factor between 0 and 1) - // Inertia of zero should produce instant movement (lerp with factor of 1) - // Takes reference of 60fps for units, so that inertia of 1 gives approximate lerp factor of 0.5 - real_t factor = 1.0 / (1.0 + inertia * delta * 60.f); - freelook_velocity = freelook_velocity.linear_interpolate(instant_velocity, CLAMP(factor, 0, 1)); + // Inertia of zero should produce instant movement (lerp with factor of 1) in this case it returns a really high value and gets clamped to 1. - cursor.pos += freelook_velocity * delta; + freelook_target_position += direction * speed; + real_t factor = (1.0 / (inertia + 0.001)) * delta; + cursor.pos = cursor.pos.linear_interpolate(freelook_target_position, CLAMP(factor, 0, 1)); } void SpatialEditorViewport::set_message(String p_message, float p_time) { diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index db5abe2b53..5f3ef2dbee 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -131,7 +131,7 @@ private: float gizmo_scale; bool freelook_active; - Vector3 freelook_velocity; + Vector3 freelook_target_position; PanelContainer *info; Label *info_label; @@ -239,7 +239,7 @@ private: distance = 4; region_select = false; } - } cursor; + } cursor, camera_cursor; void scale_cursor_distance(real_t scale); diff --git a/modules/gdscript/gd_functions.cpp b/modules/gdscript/gd_functions.cpp index 04752dc71a..34d01c6beb 100644 --- a/modules/gdscript/gd_functions.cpp +++ b/modules/gdscript/gd_functions.cpp @@ -1420,12 +1420,12 @@ MethodInfo GDFunctions::get_info(Function p_func) { } break; case MATH_ISNAN: { MethodInfo mi("is_nan", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + mi.return_val.type = Variant::BOOL; return mi; } break; case MATH_ISINF: { MethodInfo mi("is_inf", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + mi.return_val.type = Variant::BOOL; return mi; } break; case MATH_EASE: { |