diff options
51 files changed, 455 insertions, 291 deletions
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index 4498efeb41..7c5dbc895a 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -459,7 +459,7 @@ void AStar::_bind_methods() { 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("get_point_connections"), &AStar::get_point_connections); + ClassDB::bind_method(D_METHOD("get_point_connections", "id"), &AStar::get_point_connections); 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/math_2d.cpp b/core/math/math_2d.cpp index 11003c1cd5..8ad164d4dc 100644 --- a/core/math/math_2d.cpp +++ b/core/math/math_2d.cpp @@ -102,69 +102,6 @@ Vector2 Vector2::cross(real_t p_other) const { return Vector2(p_other * y, -p_other * x); } -Vector2 Vector2::operator+(const Vector2 &p_v) const { - - return Vector2(x + p_v.x, y + p_v.y); -} -void Vector2::operator+=(const Vector2 &p_v) { - - x += p_v.x; - y += p_v.y; -} -Vector2 Vector2::operator-(const Vector2 &p_v) const { - - return Vector2(x - p_v.x, y - p_v.y); -} -void Vector2::operator-=(const Vector2 &p_v) { - - x -= p_v.x; - y -= p_v.y; -} - -Vector2 Vector2::operator*(const Vector2 &p_v1) const { - - return Vector2(x * p_v1.x, y * p_v1.y); -}; - -Vector2 Vector2::operator*(const real_t &rvalue) const { - - return Vector2(x * rvalue, y * rvalue); -}; -void Vector2::operator*=(const real_t &rvalue) { - - x *= rvalue; - y *= rvalue; -}; - -Vector2 Vector2::operator/(const Vector2 &p_v1) const { - - return Vector2(x / p_v1.x, y / p_v1.y); -}; - -Vector2 Vector2::operator/(const real_t &rvalue) const { - - return Vector2(x / rvalue, y / rvalue); -}; - -void Vector2::operator/=(const real_t &rvalue) { - - x /= rvalue; - y /= rvalue; -}; - -Vector2 Vector2::operator-() const { - - return Vector2(-x, -y); -} - -bool Vector2::operator==(const Vector2 &p_vec2) const { - - return x == p_vec2.x && y == p_vec2.y; -} -bool Vector2::operator!=(const Vector2 &p_vec2) const { - - return x != p_vec2.x || y != p_vec2.y; -} Vector2 Vector2::floor() const { return Vector2(Math::floor(x), Math::floor(y)); diff --git a/core/math/math_2d.h b/core/math/math_2d.h index bbef19de7a..4635a4da55 100644 --- a/core/math/math_2d.h +++ b/core/math/math_2d.h @@ -187,6 +187,70 @@ _FORCE_INLINE_ Vector2 operator*(real_t p_scalar, const Vector2 &p_vec) { return p_vec * p_scalar; } +_FORCE_INLINE_ Vector2 Vector2::operator+(const Vector2 &p_v) const { + + return Vector2(x + p_v.x, y + p_v.y); +} +_FORCE_INLINE_ void Vector2::operator+=(const Vector2 &p_v) { + + x += p_v.x; + y += p_v.y; +} +_FORCE_INLINE_ Vector2 Vector2::operator-(const Vector2 &p_v) const { + + return Vector2(x - p_v.x, y - p_v.y); +} +_FORCE_INLINE_ void Vector2::operator-=(const Vector2 &p_v) { + + x -= p_v.x; + y -= p_v.y; +} + +_FORCE_INLINE_ Vector2 Vector2::operator*(const Vector2 &p_v1) const { + + return Vector2(x * p_v1.x, y * p_v1.y); +}; + +_FORCE_INLINE_ Vector2 Vector2::operator*(const real_t &rvalue) const { + + return Vector2(x * rvalue, y * rvalue); +}; +_FORCE_INLINE_ void Vector2::operator*=(const real_t &rvalue) { + + x *= rvalue; + y *= rvalue; +}; + +_FORCE_INLINE_ Vector2 Vector2::operator/(const Vector2 &p_v1) const { + + return Vector2(x / p_v1.x, y / p_v1.y); +}; + +_FORCE_INLINE_ Vector2 Vector2::operator/(const real_t &rvalue) const { + + return Vector2(x / rvalue, y / rvalue); +}; + +_FORCE_INLINE_ void Vector2::operator/=(const real_t &rvalue) { + + x /= rvalue; + y /= rvalue; +}; + +_FORCE_INLINE_ Vector2 Vector2::operator-() const { + + return Vector2(-x, -y); +} + +_FORCE_INLINE_ bool Vector2::operator==(const Vector2 &p_vec2) const { + + return x == p_vec2.x && y == p_vec2.y; +} +_FORCE_INLINE_ bool Vector2::operator!=(const Vector2 &p_vec2) const { + + return x != p_vec2.x || y != p_vec2.y; +} + Vector2 Vector2::linear_interpolate(const Vector2 &p_b, real_t p_t) const { Vector2 res = *this; diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp index ab3bca79ae..5346141470 100644 --- a/core/math/matrix3.cpp +++ b/core/math/matrix3.cpp @@ -311,6 +311,15 @@ void Basis::rotate(const Vector3 &p_axis, real_t p_phi) { *this = rotated(p_axis, p_phi); } +void Basis::rotate_local(const Vector3 &p_axis, real_t p_phi) { + + *this = rotated_local(p_axis, p_phi); +} +Basis Basis::rotated_local(const Vector3 &p_axis, real_t p_phi) const { + + return (*this) * Basis(p_axis, p_phi); +} + Basis Basis::rotated(const Vector3 &p_euler) const { return Basis(p_euler) * (*this); } diff --git a/core/math/matrix3.h b/core/math/matrix3.h index 9a33b8203d..9a75308f08 100644 --- a/core/math/matrix3.h +++ b/core/math/matrix3.h @@ -75,6 +75,9 @@ public: void rotate(const Vector3 &p_axis, real_t p_phi); Basis rotated(const Vector3 &p_axis, real_t p_phi) const; + void rotate_local(const Vector3 &p_axis, real_t p_phi); + Basis rotated_local(const Vector3 &p_axis, real_t p_phi) const; + void rotate(const Vector3 &p_euler); Basis rotated(const Vector3 &p_euler) const; diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp index 9b2bd30868..0cab8c10ef 100644 --- a/core/os/input_event.cpp +++ b/core/os/input_event.cpp @@ -32,14 +32,6 @@ #include "input_map.h" #include "os/keyboard.h" -void InputEvent::set_id(uint32_t p_id) { - id = p_id; -} - -uint32_t InputEvent::get_id() const { - return id; -} - void InputEvent::set_device(int p_device) { device = p_device; } @@ -99,9 +91,6 @@ bool InputEvent::is_action_type() const { void InputEvent::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_id", "id"), &InputEvent::set_id); - ClassDB::bind_method(D_METHOD("get_id"), &InputEvent::get_id); - ClassDB::bind_method(D_METHOD("set_device", "device"), &InputEvent::set_device); ClassDB::bind_method(D_METHOD("get_device"), &InputEvent::get_device); @@ -125,7 +114,6 @@ void InputEvent::_bind_methods() { InputEvent::InputEvent() { - id = 0; device = 0; } @@ -441,7 +429,6 @@ Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, co Ref<InputEventMouseButton> mb; mb.instance(); - mb->set_id(get_id()); mb->set_device(get_device()); mb->set_modifiers_from_event(this); @@ -557,7 +544,6 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co Ref<InputEventMouseMotion> mm; mm.instance(); - mm->set_id(get_id()); mm->set_device(get_device()); mm->set_modifiers_from_event(this); @@ -764,7 +750,6 @@ Ref<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, co Ref<InputEventScreenTouch> st; st.instance(); - st->set_id(get_id()); st->set_device(get_device()); st->set_index(index); st->set_position(p_xform.xform(pos + p_local_ofs)); @@ -845,7 +830,6 @@ Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, con sd.instance(); - sd->set_id(get_id()); sd->set_device(get_device()); sd->set_index(index); @@ -968,7 +952,6 @@ Ref<InputEvent> InputEventMagnifyGesture::xformed_by(const Transform2D &p_xform, Ref<InputEventMagnifyGesture> ev; ev.instance(); - ev->set_id(get_id()); ev->set_device(get_device()); ev->set_modifiers_from_event(this); @@ -1006,7 +989,6 @@ Ref<InputEvent> InputEventPanGesture::xformed_by(const Transform2D &p_xform, con Ref<InputEventPanGesture> ev; ev.instance(); - ev->set_id(get_id()); ev->set_device(get_device()); ev->set_modifiers_from_event(this); diff --git a/core/os/input_event.h b/core/os/input_event.h index 614a3289ba..9b1a2736b1 100644 --- a/core/os/input_event.h +++ b/core/os/input_event.h @@ -144,16 +144,12 @@ enum JoystickList { class InputEvent : public Resource { GDCLASS(InputEvent, Resource) - uint32_t id; int device; protected: static void _bind_methods(); public: - void set_id(uint32_t p_id); - uint32_t get_id() const; - void set_device(int p_device); int get_device() const; diff --git a/doc/classes/ColorPickerButton.xml b/doc/classes/ColorPickerButton.xml index 185460eef2..87d00b7600 100644 --- a/doc/classes/ColorPickerButton.xml +++ b/doc/classes/ColorPickerButton.xml @@ -11,14 +11,14 @@ <demos> </demos> <methods> - <method name="get_picker"> + <method name="get_picker" qualifiers="const"> <return type="ColorPicker"> </return> <description> Returns the [code]ColorPicker[/code] that this [code]ColorPickerButton[/code] toggles. </description> </method> - <method name="get_popup"> + <method name="get_popup" qualifiers="const"> <return type="PopupPanel"> </return> <description> diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml index c41c86d693..22231cfdf3 100644 --- a/doc/classes/MenuButton.xml +++ b/doc/classes/MenuButton.xml @@ -11,7 +11,7 @@ <demos> </demos> <methods> - <method name="get_popup"> + <method name="get_popup" qualifiers="const"> <return type="PopupMenu"> </return> <description> diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml index 76265e700a..ff3e513c79 100644 --- a/doc/classes/OptionButton.xml +++ b/doc/classes/OptionButton.xml @@ -91,6 +91,13 @@ Return the text of the item at index "idx". </description> </method> + <method name="get_popup" qualifiers="const"> + <return type="PopupMenu"> + </return> + <description> + Return the [PopupMenu] contained in this button. + </description> + </method> <method name="get_selected_id" qualifiers="const"> <return type="int"> </return> diff --git a/doc/classes/Physics2DDirectSpaceState.xml b/doc/classes/Physics2DDirectSpaceState.xml index f63b8f17bc..2e2d8e95f9 100644 --- a/doc/classes/Physics2DDirectSpaceState.xml +++ b/doc/classes/Physics2DDirectSpaceState.xml @@ -17,8 +17,8 @@ <argument index="0" name="shape" type="Physics2DShapeQueryParameters"> </argument> <description> - Check whether the shape can travel to a point. If it can, the method will return an array with two floats: The first is the distance the shape can move in that direction without colliding, and the second is the distance at which it will collide. - If the shape can not move, the array will be empty. + Checks how far the shape can travel toward a point. Note that both the shape and the motion are supplied through a [Physics2DShapeQueryParameters] object. The method will return an array with two floats between 0 and 1, both representing a fraction of [code]motion[/code]. The first is how far the shape can move without triggering a collision, and the second is the point at which a collision will occur. If no collision is detected, the returned array will be [1, 1]. + If the shape can not move, the array will be empty ([code]dir.empty()==true[/code]). </description> </method> <method name="collide_shape"> @@ -29,7 +29,7 @@ <argument index="1" name="max_results" type="int" default="32"> </argument> <description> - Check the intersections of a shape, given through a [Physics2DShapeQueryParameters] object, against the space. The resulting array contains a list of points where the shape intersects another. Like with [method intersect_shape], the number of returned results can be limited to save processing time. + Checks the intersections of a shape, given through a [Physics2DShapeQueryParameters] object, against the space. The resulting array contains a list of points where the shape intersects another. Like with [method intersect_shape], the number of returned results can be limited to save processing time. </description> </method> <method name="get_rest_info"> @@ -38,16 +38,15 @@ <argument index="0" name="shape" type="Physics2DShapeQueryParameters"> </argument> <description> - Check the intersections of a shape, given through a [Physics2DShapeQueryParameters] object, against the space. If it collides with more than a shape, the nearest one is selected. The returned object is a dictionary containing the following fields: - pointo: Place where the shapes intersect. - normal: Normal of the object at the point where the shapes intersect. - shape: Shape index within the object against which the shape intersected. - metadata: Metadata of the shape against which the shape intersected. This metadata is different from [method Object.get_meta], and is set with [method Physics2DServer.shape_set_data]. - collider_id: Id of the object against which the shape intersected. - collider: Object against which the shape intersected. - rid: [RID] of the object against which the shape intersected. - linear_velocity: The movement vector of the object the shape intersected, if it was a body. If it was an area, it is (0,0). - If the shape did not intersect anything, then an empty dictionary (dir.empty()==true) is returned instead. + Checks the intersections of a shape, given through a [Physics2DShapeQueryParameters] object, against the space. If it collides with more than one shape, the nearest one is selected. Note that this method does not take into account the [code]motion[/code] property of the object. The returned object is a dictionary containing the following fields: + [code]collider_id[/code]: The colliding object's ID. + [code]linear_velocity[/code]: The colliding object's velocity [Vector2]. If the object is an [Area2D], the result is [code](0, 0)[/code]. + [code]metadata[/code]: The intersecting shape's metadata. This metadata is different from [method Object.get_meta], and is set with [method Physics2DServer.shape_set_data]. + [code]normal[/code]: The object's surface normal at the intersection point. + [code]point[/code]: The intersection point. + [code]rid[/code]: The intersecting object's [RID]. + [code]shape[/code]: The shape index of the colliding shape. + If the shape did not intersect anything, then an empty dictionary ([code]dir.empty()==true[/code]) is returned instead. </description> </method> <method name="intersect_point"> @@ -62,12 +61,12 @@ <argument index="3" name="collision_layer" type="int" default="2147483647"> </argument> <description> - Check whether a point is inside any shape. The shapes the point is inside of are returned in an array containing dictionaries with the following fields: - shape: Shape index within the object the point is in. - metadata: Metadata of the shape the point is in. This metadata is different from [method Object.get_meta], and is set with [method Physics2DServer.shape_set_data]. - collider_id: Id of the object the point is in. - collider: Object the point is inside of. - rid: [RID] of the object the point is in. + Checks whether a point is inside any shape. The shapes the point is inside of are returned in an array containing dictionaries with the following fields: + [code]collider[/code]: The colliding object. + [code]collider_id[/code]: The colliding object's ID. + [code]metadata[/code]: The intersecting shape's metadata. This metadata is different from [method Object.get_meta], and is set with [method Physics2DServer.shape_set_data]. + [code]rid[/code]: The intersecting object's [RID]. + [code]shape[/code]: The shape index of the colliding shape. Additionally, the method can take an array of objects or [RID]s that are to be excluded from collisions, or a bitmask representing the physics layers to check in. </description> </method> @@ -83,15 +82,15 @@ <argument index="3" name="collision_layer" type="int" default="2147483647"> </argument> <description> - Intersect a ray in a given space. The returned object is a dictionary with the following fields: - position: Place where ray is stopped. - normal: Normal of the object at the point where the ray was stopped. - shape: Shape index within the object against which the ray was stopped. - metadata: Metadata of the shape against which the ray was stopped. This metadata is different from [method Object.get_meta], and is set with [method Physics2DServer.shape_set_data]. - collider_id: Id of the object against which the ray was stopped. - collider: Object against which the ray was stopped. - rid: [RID] of the object against which the ray was stopped. - If the ray did not intersect anything, then an empty dictionary (dir.empty()==true) is returned instead. + Intersects a ray in a given space. The returned object is a dictionary with the following fields: + [code]collider[/code]: The colliding object. + [code]collider_id[/code]: The colliding object's ID. + [code]metadata[/code]: The intersecting shape's metadata. This metadata is different from [method Object.get_meta], and is set with [method Physics2DServer.shape_set_data]. + [code]normal[/code]: The object's surface normal at the intersection point. + [code]position[/code]: The intersection point. + [code]rid[/code]: The intersecting object's [RID]. + [code]shape[/code]: The shape index of the colliding shape. + If the ray did not intersect anything, then an empty dictionary ([code]dir.empty()==true[/code]) is returned instead. Additionally, the method can take an array of objects or [RID]s that are to be excluded from collisions, or a bitmask representing the physics layers to check in. </description> </method> @@ -103,12 +102,12 @@ <argument index="1" name="max_results" type="int" default="32"> </argument> <description> - Check the intersections of a shape, given through a [Physics2DShapeQueryParameters] object, against the space. The intersected shapes are returned in an array containing dictionaries with the following fields: - shape: Shape index within the object the shape intersected. - metadata: Metadata of the shape intersected by the shape given through the [Physics2DShapeQueryParameters]. This metadata is different from [method Object.get_meta], and is set with [method Physics2DServer.shape_set_data]. - collider_id: Id of the object the shape intersected. - collider: Object the shape intersected. - rid: [RID] of the object the shape intersected. + Checks the intersections of a shape, given through a [Physics2DShapeQueryParameters] object, against the space. Note that this method does not take into account the [code]motion[/code] property of the object. The intersected shapes are returned in an array containing dictionaries with the following fields: + [code]collider[/code]: The colliding object. + [code]collider_id[/code]: The colliding object's ID. + [code]metadata[/code]: The intersecting shape's metadata. This metadata is different from [method Object.get_meta], and is set with [method Physics2DServer.shape_set_data]. + [code]rid[/code]: The intersecting object's [RID]. + [code]shape[/code]: The shape index of the colliding shape. The number of intersections can be limited with the second parameter, to reduce the processing time. </description> </method> diff --git a/doc/classes/PhysicsDirectSpaceState.xml b/doc/classes/PhysicsDirectSpaceState.xml index 56acd34f0a..d93550eb47 100644 --- a/doc/classes/PhysicsDirectSpaceState.xml +++ b/doc/classes/PhysicsDirectSpaceState.xml @@ -19,8 +19,8 @@ <argument index="1" name="motion" type="Vector3"> </argument> <description> - Check whether the shape can travel to a point. If it can, the method will return an array with two floats between 0 and 1: The first is how far the shape can move toward the point without colliding, and the second is the distance at which it will collide. If no collision is detected, the returned array will be [1, 1]. - If the shape can not move, the array will be empty (dir.empty()==true). + Checks whether the shape can travel to a point. The method will return an array with two floats between 0 and 1, both representing a fraction of [code]motion[/code]. The first is how far the shape can move without triggering a collision, and the second is the point at which a collision will occur. If no collision is detected, the returned array will be [1, 1]. + If the shape can not move, the array will be empty ([code]dir.empty()==true[/code]). </description> </method> <method name="collide_shape"> @@ -31,7 +31,7 @@ <argument index="1" name="max_results" type="int" default="32"> </argument> <description> - Check the intersections of a shape, given through a [PhysicsShapeQueryParameters] object, against the space. The resulting array contains a list of points where the shape intersects another. Like with [method intersect_shape], the number of returned results can be limited to save processing time. + Checks the intersections of a shape, given through a [PhysicsShapeQueryParameters] object, against the space. The resulting array contains a list of points where the shape intersects another. Like with [method intersect_shape], the number of returned results can be limited to save processing time. </description> </method> <method name="get_rest_info"> @@ -40,14 +40,14 @@ <argument index="0" name="shape" type="PhysicsShapeQueryParameters"> </argument> <description> - Check the intersections of a shape, given through a [PhysicsShapeQueryParameters] object, against the space. If it collides with more than a shape, the nearest one is selected. The returned object is a dictionary containing the following fields: - collider_id: ID of the object against which the shape intersected. - linear_velocity: The movement vector of the object the shape intersected, if it was a body. If it was an area, it is (0,0). - normal: Normal of the object at the point where the shapes intersect. - point: Place where the shapes intersect. - rid: [RID] of the object against which the shape intersected. - shape: Shape index within the object against which the shape intersected. - If the shape did not intersect anything, then an empty dictionary (dir.empty()==true) is returned instead. + Checks the intersections of a shape, given through a [PhysicsShapeQueryParameters] object, against the space. If it collides with more than a shape, the nearest one is selected. The returned object is a dictionary containing the following fields: + [code]collider_id[/code]: The colliding object's ID. + [code]linear_velocity[/code]: The colliding object's velocity [Vector3]. If the object is an [Area], the result is [code](0, 0, 0)[/code]. + [code]normal[/code]: The object's surface normal at the intersection point. + [code]point[/code]: The intersection point. + [code]rid[/code]: The intersecting object's [RID]. + [code]shape[/code]: The shape index of the colliding shape. + If the shape did not intersect anything, then an empty dictionary ([code]dir.empty()==true[/code]) is returned instead. </description> </method> <method name="intersect_ray"> @@ -62,14 +62,14 @@ <argument index="3" name="collision_layer" type="int" default="2147483647"> </argument> <description> - Intersect a ray in a given space. The returned object is a dictionary with the following fields: - collider: Object against which the ray was stopped. - collider_id: ID of the object against which the ray was stopped. - normal: Normal of the object at the point where the ray was stopped. - position: Place where ray is stopped. - rid: [RID] of the object against which the ray was stopped. - shape: Shape index within the object against which the ray was stopped. - If the ray did not intersect anything, then an empty dictionary (dir.empty()==true) is returned instead. + Intersects a ray in a given space. The returned object is a dictionary with the following fields: + [code]collider[/code]: The colliding object. + [code]collider_id[/code]: The colliding object's ID. + [code]normal[/code]: The object's surface normal at the intersection point. + [code]position[/code]: The intersection point. + [code]rid[/code]: The intersecting object's [RID]. + [code]shape[/code]: The shape index of the colliding shape. + If the ray did not intersect anything, then an empty dictionary ([code]dir.empty()==true[/code]) is returned instead. Additionally, the method can take an array of objects or [RID]s that are to be excluded from collisions, or a bitmask representing the physics layers to check in. </description> </method> @@ -81,11 +81,11 @@ <argument index="1" name="max_results" type="int" default="32"> </argument> <description> - Check the intersections of a shape, given through a [PhysicsShapeQueryParameters] object, against the space. The intersected shapes are returned in an array containing dictionaries with the following fields: - collider: Object the shape intersected. - collider_id: ID of the object the shape intersected. - rid: [RID] of the object the shape intersected. - shape: Shape index within the object the shape intersected. + Checks the intersections of a shape, given through a [PhysicsShapeQueryParameters] object, against the space. The intersected shapes are returned in an array containing dictionaries with the following fields: + [code]collider[/code]: The colliding object. + [code]collider_id[/code]: The colliding object's ID. + [code]rid[/code]: The intersecting object's [RID]. + [code]shape[/code]: The shape index of the colliding shape. The number of intersections can be limited with the second parameter, to reduce the processing time. </description> </method> diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index a4daa77b50..86415ea740 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -1086,19 +1086,22 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons } } - if (shader_ptr && shader_ptr != shader_cache) { + if (shader_ptr) { if (shader_ptr->canvas_item.uses_screen_texture && !state.canvas_texscreen_used) { //copy if not copied before _copy_texscreen(Rect2()); } - if (shader_ptr->canvas_item.uses_time) { - VisualServerRaster::redraw_request(); - } + if (shader_ptr != shader_cache) { - state.canvas_shader.set_custom_shader(shader_ptr->custom_code_id); - state.canvas_shader.bind(); + if (shader_ptr->canvas_item.uses_time) { + VisualServerRaster::redraw_request(); + } + + state.canvas_shader.set_custom_shader(shader_ptr->custom_code_id); + state.canvas_shader.bind(); + } if (material_ptr->ubo_id) { glBindBufferBase(GL_UNIFORM_BUFFER, 2, material_ptr->ubo_id); @@ -1147,7 +1150,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons glBindTexture(t->target, t->tex_id); } - } else if (!shader_ptr) { + } else { state.canvas_shader.set_custom_shader(0); state.canvas_shader.bind(); } diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index b777f9343a..1c3361d2de 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1541,7 +1541,19 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { if (c.texture.is_valid() && storage->texture_owner.owns(c.texture)) { - const RasterizerStorageGLES3::Texture *t = storage->texture_owner.get(c.texture); + RasterizerStorageGLES3::Texture *t = storage->texture_owner.get(c.texture); + + t = t->get_ptr(); //resolve for proxies +#ifdef TOOLS_ENABLED + if (t->detect_3d) { + t->detect_3d(t->detect_3d_ud); + } +#endif + + if (t->render_target) { + t->render_target->used_in_frame = true; + } + glActiveTexture(GL_TEXTURE0); glBindTexture(t->target, t->tex_id); restore_tex = true; diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index 101978548d..ec00c057b2 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -806,7 +806,6 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv"; actions[VS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture"; actions[VS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer"; - actions[VS::SHADER_SPATIAL].renames["SIDE"] = "side"; actions[VS::SHADER_SPATIAL].renames["ALPHA_SCISSOR"] = "alpha_scissor"; //for light @@ -847,6 +846,8 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n"; diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index bb9ff29a8e..6427e3d967 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -174,7 +174,7 @@ void light_compute(vec3 N, vec3 L,vec3 V, vec3 light_color, float roughness, ino vec3 H = normalize(V + L); float dotNH = max(dot(N,H), 0.0 ); - float intensity = pow( dotNH, (1.0-roughness) * 256.0); + float intensity = (roughness >= 1.0 ? 1.0 : pow( dotNH, (1.0-roughness) * 256.0)); specular += light_color * intensity; } @@ -1615,7 +1615,7 @@ void main() { float alpha = 1.0; -#ifdef METERIAL_DOUBLESIDED +#if defined(DO_SIDE_CHECK) float side=float(gl_FrontFacing)*2.0-1.0; #else float side=1.0; diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index 5f026abb6d..6db3c09673 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -145,7 +145,7 @@ EditorAbout::EditorAbout() { List<String> dev_sections; dev_sections.push_back(TTR("Project Founders")); dev_sections.push_back(TTR("Lead Developer")); - dev_sections.push_back(TTR("Project Manager")); + dev_sections.push_back(TTR("Project Manager ")); // " " appended to distinguish between 'project supervisor' and 'project list' dev_sections.push_back(TTR("Developers")); const char **dev_src[] = { dev_founders, dev_lead, dev_manager, dev_names }; tc->add_child(_populate_list(TTR("Authors"), dev_sections, dev_src, 1)); diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 49d55e6305..214b1cac89 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -701,6 +701,15 @@ String EditorData::get_scene_title(int p_idx) const { return name; } +void EditorData::set_scene_path(int p_idx, const String &p_path) { + + ERR_FAIL_INDEX(p_idx, edited_scene.size()); + + if (!edited_scene[p_idx].root) + return; + edited_scene[p_idx].root->set_filename(p_path); +} + String EditorData::get_scene_path(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), String()); diff --git a/editor/editor_data.h b/editor/editor_data.h index 33a4091a65..f15b7e37f1 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -185,6 +185,7 @@ public: String get_scene_title(int p_idx) const; String get_scene_path(int p_idx) const; String get_scene_type(int p_idx) const; + void set_scene_path(int p_idx, const String &p_path); Ref<Script> get_scene_root_script(int p_idx) const; void set_edited_scene_version(uint64_t version, int p_scene_idx = -1); uint64_t get_edited_scene_version() const; diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index 8aca007e6b..a76c419152 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -173,11 +173,12 @@ void editor_register_fonts(Ref<Theme> p_theme) { p_theme->set_font("output_source", "EditorFonts", df_output_code); Ref<DynamicFont> df_text_editor_status_code; - df_output_code.instance(); - df_output_code->set_size(14 * EDSCALE); - df_output_code->set_spacing(DynamicFont::SPACING_TOP, -EDSCALE); - df_output_code->set_spacing(DynamicFont::SPACING_BOTTOM, -EDSCALE); - df_output_code->set_font_data(dfmono); - MAKE_FALLBACKS(df_output_code); - p_theme->set_font("status_source", "EditorFonts", df_output_code); + df_text_editor_status_code.instance(); + df_text_editor_status_code->set_size(14 * EDSCALE); + df_text_editor_status_code->set_spacing(DynamicFont::SPACING_TOP, -EDSCALE); + df_text_editor_status_code->set_spacing(DynamicFont::SPACING_BOTTOM, -EDSCALE); + df_text_editor_status_code->set_font_data(dfmono); + MAKE_FALLBACKS(df_text_editor_status_code); + + p_theme->set_font("status_source", "EditorFonts", df_text_editor_status_code); } diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 75e4f39e25..dce5a10d67 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -834,6 +834,58 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin memdelete(da); } +void FileSystemDock::_update_resource_paths_after_move(const Map<String, String> &p_renames) const { + + //Rename all resources loaded, be it subresources or actual resources + List<Ref<Resource> > cached; + ResourceCache::get_cached_resources(&cached); + + for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) { + + Ref<Resource> r = E->get(); + + String base_path = r->get_path(); + String extra_path; + int sep_pos = r->get_path().find("::"); + if (sep_pos >= 0) { + extra_path = base_path.substr(sep_pos, base_path.length()); + base_path = base_path.substr(0, sep_pos); + } + + if (p_renames.has(base_path)) { + base_path = p_renames[base_path]; + } + + r->set_path(base_path + extra_path); + } + + for (int i = 0; i < EditorNode::get_editor_data().get_edited_scene_count(); i++) { + + String path; + if (i == EditorNode::get_editor_data().get_edited_scene()) { + if (!get_tree()->get_edited_scene_root()) + continue; + + path = get_tree()->get_edited_scene_root()->get_filename(); + } else { + + path = EditorNode::get_editor_data().get_scene_path(i); + } + + if (p_renames.has(path)) { + path = p_renames[path]; + } + + if (i == EditorNode::get_editor_data().get_edited_scene()) { + + get_tree()->get_edited_scene_root()->set_filename(path); + } else { + + EditorNode::get_editor_data().set_scene_path(i, path); + } + } +} + void FileSystemDock::_update_dependencies_after_move(const Map<String, String> &p_renames) const { //The following code assumes that the following holds: // 1) EditorFileSystem contains the old paths/folder structure from before the rename/move. @@ -910,6 +962,7 @@ void FileSystemDock::_rename_operation_confirm() { Map<String, String> renames; _try_move_item(to_rename, new_path, renames); _update_dependencies_after_move(renames); + _update_resource_paths_after_move(renames); //Rescan everything print_line("call rescan!"); @@ -959,6 +1012,8 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path) { } _update_dependencies_after_move(renames); + _update_resource_paths_after_move(renames); + print_line("call rescan!"); _rescan(); } diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index bc8d835ba1..65a71b86e0 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -178,6 +178,7 @@ private: void _try_move_item(const FileOrFolder &p_item, const String &p_new_path, Map<String, String> &p_renames) const; void _try_duplicate_item(const FileOrFolder &p_item, const String &p_new_path) const; void _update_dependencies_after_move(const Map<String, String> &p_renames) const; + void _update_resource_paths_after_move(const Map<String, String> &p_renames) const; void _make_dir_confirm(); void _rename_operation_confirm(); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index ceb1ec09fc..1241441d43 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -4344,7 +4344,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { additive_selection = false; // Update the menus checkboxes - call_deferred("set_state", get_state()); + set_state(get_state()); } CanvasItemEditor *CanvasItemEditor::singleton = NULL; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index c1c75656c5..2f0f21cc0e 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -2517,9 +2517,9 @@ void ScriptEditor::_bind_methods() { ClassDB::bind_method("_script_changed", &ScriptEditor::_script_changed); ClassDB::bind_method("_update_recent_scripts", &ScriptEditor::_update_recent_scripts); - ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &ScriptEditor::get_drag_data_fw); - ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &ScriptEditor::can_drop_data_fw); - ClassDB::bind_method(D_METHOD("drop_data_fw"), &ScriptEditor::drop_data_fw); + ClassDB::bind_method(D_METHOD("get_drag_data_fw", "point", "from"), &ScriptEditor::get_drag_data_fw); + ClassDB::bind_method(D_METHOD("can_drop_data_fw", "point", "data", "from"), &ScriptEditor::can_drop_data_fw); + ClassDB::bind_method(D_METHOD("drop_data_fw", "point", "data", "from"), &ScriptEditor::drop_data_fw); ClassDB::bind_method(D_METHOD("get_current_script"), &ScriptEditor::_get_current_script); ClassDB::bind_method(D_METHOD("get_open_scripts"), &ScriptEditor::_get_open_scripts); diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index 64351dec4f..24275f4d88 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -335,6 +335,8 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: easing_draw->hide(); spinbox->hide(); slider->hide(); + menu->clear(); + menu->set_size(Size2(1, 1) * EDSCALE); for (int i = 0; i < MAX_VALUE_EDITORS; i++) { @@ -413,7 +415,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: } else if (hint == PROPERTY_HINT_ENUM) { - menu->clear(); Vector<String> options = hint_text.split(","); for (int i = 0; i < options.size(); i++) { if (options[i].find(":") != -1) { @@ -494,7 +495,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: easing_draw->show(); set_size(Size2(200, 150) * EDSCALE); } else if (hint == PROPERTY_HINT_FLAGS) { - menu->clear(); Vector<String> flags = hint_text.split(","); for (int i = 0; i < flags.size(); i++) { String flag = flags[i]; @@ -536,7 +536,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: config_action_buttons(names); } else if (hint == PROPERTY_HINT_ENUM) { - menu->clear(); Vector<String> options = hint_text.split(","); for (int i = 0; i < options.size(); i++) { menu->add_item(options[i], i); @@ -869,9 +868,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: if (hint != PROPERTY_HINT_RESOURCE_TYPE) break; - menu->clear(); - menu->set_size(Size2(1, 1) * EDSCALE); - if (p_name == "script" && hint_text == "Script" && Object::cast_to<Node>(owner)) { menu->add_icon_item(get_icon("Script", "EditorIcons"), TTR("New Script"), OBJ_MENU_NEW_SCRIPT); menu->add_separator(); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 7b30ddaa56..a83c1c1cad 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -1527,7 +1527,7 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("_recreate_quadrants"), &TileMap::_recreate_quadrants); ClassDB::bind_method(D_METHOD("_update_dirty_quadrants"), &TileMap::_update_dirty_quadrants); - ClassDB::bind_method(D_METHOD("update_bitmask_area"), &TileMap::update_bitmask_area); + ClassDB::bind_method(D_METHOD("update_bitmask_area", "position"), &TileMap::update_bitmask_area); ClassDB::bind_method(D_METHOD("update_bitmask_region", "start", "end"), &TileMap::update_bitmask_region, DEFVAL(Vector2()), DEFVAL(Vector2())); ClassDB::bind_method(D_METHOD("_set_tile_data"), &TileMap::_set_tile_data); diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index c74abb7e2d..7143310036 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -70,6 +70,9 @@ void Camera::_validate_property(PropertyInfo &p_property) const { void Camera::_update_camera() { + if (!is_inside_tree()) + return; + Transform tr = get_camera_transform(); tr.origin += tr.basis.get_axis(1) * v_offset; tr.origin += tr.basis.get_axis(0) * h_offset; @@ -81,7 +84,7 @@ void Camera::_update_camera() { get_viewport()->_camera_transform_changed_notify(); */ - if (!is_inside_tree() || get_tree()->is_node_being_edited(this) || !is_current()) + if (get_tree()->is_node_being_edited(this) || !is_current()) return; get_viewport()->_camera_transform_changed_notify(); diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp index d9f88ac693..e890533ab7 100644 --- a/scene/3d/spatial.cpp +++ b/scene/3d/spatial.cpp @@ -558,27 +558,27 @@ bool Spatial::is_visible() const { void Spatial::rotate(const Vector3 &p_normal, float p_radians) { Transform t = get_transform(); - t.basis.rotate(p_normal, p_radians); + t.basis.rotate_local(p_normal, p_radians); //use local rotation here, as it makes more sense here in tree hierarchy set_transform(t); } void Spatial::rotate_x(float p_radians) { Transform t = get_transform(); - t.basis.rotate(Vector3(1, 0, 0), p_radians); + t.basis.rotate_local(Vector3(1, 0, 0), p_radians); set_transform(t); } void Spatial::rotate_y(float p_radians) { Transform t = get_transform(); - t.basis.rotate(Vector3(0, 1, 0), p_radians); + t.basis.rotate_local(Vector3(0, 1, 0), p_radians); set_transform(t); } void Spatial::rotate_z(float p_radians) { Transform t = get_transform(); - t.basis.rotate(Vector3(0, 0, 1), p_radians); + t.basis.rotate_local(Vector3(0, 0, 1), p_radians); set_transform(t); } diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp index 17aa649dff..bd7e52d947 100644 --- a/scene/3d/voxel_light_baker.cpp +++ b/scene/3d/voxel_light_baker.cpp @@ -1799,7 +1799,6 @@ Vector3 VoxelLightBaker::_compute_ray_trace_at_pos(const Vector3 &p_pos, const V void VoxelLightBaker::_lightmap_bake_point(uint32_t p_x, LightMap *p_line) { - LightMap *pixel = &p_line[p_x]; if (pixel->pos == Vector3()) return; @@ -1814,7 +1813,6 @@ void VoxelLightBaker::_lightmap_bake_point(uint32_t p_x, LightMap *p_line) { // pixel->light = Vector3(1, 1, 1); //} } - } Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh, LightMapData &r_lightmap, bool (*p_bake_time_func)(void *, float, float), void *p_bake_time_ud) { @@ -1882,7 +1880,7 @@ Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh for (int i = 0; i < height; i++) { - thread_process_array(width,this,&VoxelLightBaker::_lightmap_bake_point,&lightmap_ptr[i*width]); + thread_process_array(width, this, &VoxelLightBaker::_lightmap_bake_point, &lightmap_ptr[i * width]); lines = MAX(lines, i); //for multithread if (p_bake_time_func) { diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index 32f82fe6b8..fceca55c3e 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -386,8 +386,6 @@ bool AnimationTreePlayer::_get(const StringName &p_name, Variant &r_ret) const { void AnimationTreePlayer::_get_property_list(List<PropertyInfo> *p_list) const { - p_list->push_back(PropertyInfo(Variant::NODE_PATH, "base_path")); - p_list->push_back(PropertyInfo(Variant::NODE_PATH, "master_player")); p_list->push_back(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NETWORK)); } diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index cb6283507e..446676e80d 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -39,33 +39,32 @@ void ColorPicker::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - //sample->set_texture(get_icon("color_sample")); + btn_pick->set_icon(get_icon("screen_picker", "ColorPicker")); bt_add_preset->set_icon(get_icon("add_preset")); _update_controls(); } break; - case NOTIFICATION_ENTER_TREE: { + btn_pick->set_icon(get_icon("screen_picker", "ColorPicker")); bt_add_preset->set_icon(get_icon("add_preset")); _update_color(); } break; - case NOTIFICATION_PARENTED: { + for (int i = 0; i < 4; i++) set_margin((Margin)i, get_constant("margin")); } break; - case NOTIFICATION_VISIBILITY_CHANGED: { Popup *p = Object::cast_to<Popup>(get_parent()); if (p) p->set_size(Size2(get_combined_minimum_size().width + get_constant("margin") * 2, get_combined_minimum_size().height + get_constant("margin") * 2)); } break; - case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: { + if (screen != NULL) { if (screen->is_visible()) { screen->hide(); @@ -523,7 +522,6 @@ ColorPicker::ColorPicker() : add_child(hb_edit); w_edit = memnew(Control); - //w_edit->set_ignore_mouse(false); w_edit->set_custom_minimum_size(Size2(get_constant("h_width"), 0)); w_edit->set_h_size_flags(SIZE_FILL); w_edit->set_v_size_flags(SIZE_EXPAND_FILL); @@ -589,7 +587,6 @@ ColorPicker::ColorPicker() : c_text->set_h_size_flags(SIZE_EXPAND_FILL); _update_controls(); - //_update_color(); updating = false; set_pick_color(Color(1, 1, 1)); @@ -599,7 +596,6 @@ ColorPicker::ColorPicker() : preset = memnew(TextureRect); bbc->add_child(preset); - //preset->set_ignore_mouse(false); preset->connect("gui_input", this, "_preset_input"); preset->connect("draw", this, "_update_presets"); @@ -660,11 +656,13 @@ bool ColorPickerButton::is_editing_alpha() const { return picker->is_editing_alpha(); } -ColorPicker *ColorPickerButton::get_picker() { +ColorPicker *ColorPickerButton::get_picker() const { + return picker; } -PopupPanel *ColorPickerButton::get_popup() { +PopupPanel *ColorPickerButton::get_popup() const { + return popup; } diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index c02cdc8608..2bae279ed5 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -129,8 +129,8 @@ public: void set_edit_alpha(bool p_show); bool is_editing_alpha() const; - ColorPicker *get_picker(); - PopupPanel *get_popup(); + ColorPicker *get_picker() const; + PopupPanel *get_popup() const; ColorPickerButton(); }; diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 1d18c6504c..c235797bef 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -63,25 +63,10 @@ void MenuButton::pressed() { void MenuButton::_gui_input(Ref<InputEvent> p_event) { - /*if (p_event.type==InputEvent::MOUSE_BUTTON && p_event->get_button_index()==BUTTON_LEFT) { - clicked=p_event->is_pressed(); - } - if (clicked && p_event.type==InputEvent::MOUSE_MOTION && popup->is_visible_in_tree()) { - - Point2 gt = Point2(p_event.mouse_motion.x,p_event.mouse_motion.y); - gt = get_global_transform().xform(gt); - Point2 lt = popup->get_transform().affine_inverse().xform(gt); - if (popup->has_point(lt)) { - //print_line("HAS POINT!!!"); - popup->call_deferred("grab_click_focus"); - } - - }*/ - BaseButton::_gui_input(p_event); } -PopupMenu *MenuButton::get_popup() { +PopupMenu *MenuButton::get_popup() const { return popup; } diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h index 08a8a43f55..1bd9b155b2 100644 --- a/scene/gui/menu_button.h +++ b/scene/gui/menu_button.h @@ -54,7 +54,7 @@ protected: static void _bind_methods(); public: - PopupMenu *get_popup(); + PopupMenu *get_popup() const; void set_disable_shortcuts(bool p_disabled); MenuButton(); diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 70f3d9ca83..6f784b56de 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -42,38 +42,35 @@ Size2 OptionButton::get_minimum_size() const { void OptionButton::_notification(int p_what) { - switch (p_what) { - - case NOTIFICATION_DRAW: { - - if (!has_icon("arrow")) - return; - - RID ci = get_canvas_item(); - Ref<Texture> arrow = Control::get_icon("arrow"); - Ref<StyleBox> normal = get_stylebox("normal"); - Color clr = Color(1, 1, 1); - if (get_constant("modulate_arrow")) - switch (get_draw_mode()) { - case DRAW_PRESSED: - clr = get_color("font_color_pressed"); - break; - case DRAW_HOVER: - clr = get_color("font_color_hover"); - break; - case DRAW_DISABLED: - clr = get_color("font_color_disabled"); - break; - default: - clr = get_color("font_color"); - } - - Size2 size = get_size(); - - Point2 ofs(size.width - arrow->get_width() - get_constant("arrow_margin"), int(Math::abs((size.height - arrow->get_height()) / 2))); - arrow->draw(ci, ofs, clr); - - } break; + if (p_what == NOTIFICATION_DRAW) { + + if (!has_icon("arrow")) + return; + + RID ci = get_canvas_item(); + Ref<Texture> arrow = Control::get_icon("arrow"); + Ref<StyleBox> normal = get_stylebox("normal"); + Color clr = Color(1, 1, 1); + if (get_constant("modulate_arrow")) { + switch (get_draw_mode()) { + case DRAW_PRESSED: + clr = get_color("font_color_pressed"); + break; + case DRAW_HOVER: + clr = get_color("font_color_hover"); + break; + case DRAW_DISABLED: + clr = get_color("font_color_disabled"); + break; + default: + clr = get_color("font_color"); + } + } + + Size2 size = get_size(); + + Point2 ofs(size.width - arrow->get_width() - get_constant("arrow_margin"), int(Math::abs((size.height - arrow->get_height()) / 2))); + arrow->draw(ci, ofs, clr); } } @@ -244,6 +241,11 @@ void OptionButton::remove_item(int p_idx) { popup->remove_item(p_idx); } +PopupMenu *OptionButton::get_popup() const { + + return popup; +} + Array OptionButton::_get_items() const { Array items; @@ -310,6 +312,8 @@ void OptionButton::_bind_methods() { ClassDB::bind_method(D_METHOD("remove_item", "idx"), &OptionButton::remove_item); ClassDB::bind_method(D_METHOD("_select_int"), &OptionButton::_select_int); + ClassDB::bind_method(D_METHOD("get_popup"), &OptionButton::get_popup); + ClassDB::bind_method(D_METHOD("_set_items"), &OptionButton::_set_items); ClassDB::bind_method(D_METHOD("_get_items"), &OptionButton::_get_items); @@ -320,15 +324,16 @@ void OptionButton::_bind_methods() { OptionButton::OptionButton() { + current = -1; + set_text_align(ALIGN_LEFT); + set_action_mode(ACTION_MODE_BUTTON_PRESS); + popup = memnew(PopupMenu); popup->hide(); + add_child(popup); popup->set_as_toplevel(true); popup->set_pass_on_modal_close_click(false); - add_child(popup); popup->connect("id_pressed", this, "_selected"); - - current = -1; - set_text_align(ALIGN_LEFT); } OptionButton::~OptionButton() { diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h index a06c540678..b09942b072 100644 --- a/scene/gui/option_button.h +++ b/scene/gui/option_button.h @@ -85,6 +85,8 @@ public: void remove_item(int p_idx); + PopupMenu *get_popup() const; + virtual void get_translatable_strings(List<String> *p_strings) const; OptionButton(); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index f735d7bf48..0fba4a6f94 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1695,10 +1695,9 @@ void TextEdit::indent_right() { // fix selection and cursor being off by one on the last line if (is_selection_active()) { - selection.to_column++; - selection.from_column++; + select(selection.from_line, selection.from_column + 1, selection.to_line, selection.to_column + 1); } - cursor.column++; + cursor_set_column(cursor.column + 1, false); end_complex_operation(); update(); } @@ -1737,14 +1736,9 @@ void TextEdit::indent_left() { // fix selection and cursor being off by one on the last line if (is_selection_active() && last_line_text != get_line(end_line)) { - if (selection.to_column > 0) - selection.to_column--; - if (selection.from_column > 0) - selection.from_column--; - } - if (cursor.column > 0) { - cursor.column--; + select(selection.from_line, selection.from_column - 1, selection.to_line, selection.to_column - 1); } + cursor_set_column(cursor.column - 1, false); end_complex_operation(); update(); } @@ -4201,11 +4195,15 @@ void TextEdit::select(int p_from_line, int p_from_column, int p_to_line, int p_t p_from_line = text.size() - 1; if (p_from_column >= text[p_from_line].length()) p_from_column = text[p_from_line].length(); + if (p_from_column < 0) + p_from_column = 0; if (p_to_line >= text.size()) p_to_line = text.size() - 1; if (p_to_column >= text[p_to_line].length()) p_to_column = text[p_to_line].length(); + if (p_to_column < 0) + p_to_column = 0; selection.from_line = p_from_line; selection.from_column = p_from_column; @@ -5528,7 +5526,7 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_hiding_enabled", "enable"), &TextEdit::set_hiding_enabled); ClassDB::bind_method(D_METHOD("is_hiding_enabled"), &TextEdit::is_hiding_enabled); ClassDB::bind_method(D_METHOD("set_line_as_hidden", "line", "enable"), &TextEdit::set_line_as_hidden); - ClassDB::bind_method(D_METHOD("is_line_hidden"), &TextEdit::is_line_hidden); + ClassDB::bind_method(D_METHOD("is_line_hidden", "line"), &TextEdit::is_line_hidden); ClassDB::bind_method(D_METHOD("fold_all_lines"), &TextEdit::fold_all_lines); ClassDB::bind_method(D_METHOD("unhide_all_lines"), &TextEdit::unhide_all_lines); ClassDB::bind_method(D_METHOD("fold_line", "line"), &TextEdit::fold_line); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 6879aa1ce7..51ad22e271 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1775,7 +1775,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool case TreeItem::CELL_MODE_STRING: { //nothing in particular - if (select_mode == SELECT_MULTI && (get_tree()->get_last_event_id() == focus_in_id || !already_cursor)) { + if (select_mode == SELECT_MULTI && (get_tree()->get_event_count() == focus_in_id || !already_cursor)) { bring_up_editor = false; } @@ -1863,7 +1863,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool } else { editor_text = String::num(p_item->cells[col].val, Math::step_decimals(p_item->cells[col].step)); - if (select_mode == SELECT_MULTI && get_tree()->get_last_event_id() == focus_in_id) + if (select_mode == SELECT_MULTI && get_tree()->get_event_count() == focus_in_id) bring_up_editor = false; } } @@ -2786,7 +2786,7 @@ void Tree::_notification(int p_what) { if (p_what == NOTIFICATION_FOCUS_ENTER) { - focus_in_id = get_tree()->get_last_event_id(); + focus_in_id = get_tree()->get_event_count(); } if (p_what == NOTIFICATION_MOUSE_EXIT) { diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 85c07e192b..b8d94bcffb 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -359,7 +359,7 @@ private: LineEdit *text_editor; HSlider *value_editor; bool updating_value_editor; - uint32_t focus_in_id; + int64_t focus_in_id; PopupMenu *popup_menu; Vector<ColumnInfo> columns; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index de1ab9959a..942a6d5428 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -340,7 +340,8 @@ void Node::move_child(Node *p_child, int p_pos) { data.children[i]->notification(NOTIFICATION_MOVED_IN_PARENT); } for (const Map<StringName, GroupData>::Element *E = p_child->data.grouped.front(); E; E = E->next()) { - E->get().group->changed = true; + if (E->get().group) + E->get().group->changed = true; } data.blocked--; diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 7c31b72bb5..db39b37bd5 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -391,13 +391,12 @@ void SceneTree::input_event(const Ref<InputEvent> &p_event) { if (Engine::get_singleton()->is_editor_hint() && (Object::cast_to<InputEventJoypadButton>(p_event.ptr()) || Object::cast_to<InputEventJoypadMotion>(*p_event))) return; //avoid joy input on editor + current_event++; root_lock++; - //last_id=p_event.ID; input_handled = false; Ref<InputEvent> ev = p_event; - ev->set_id(++last_id); //this should work better MainLoop::input_event(ev); @@ -941,11 +940,6 @@ void SceneMainLoop::_update_listener_2d() { } */ -uint32_t SceneTree::get_last_event_id() const { - - return last_id; -} - Variant SceneTree::_call_group_flags(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { r_error.error = Variant::CallError::CALL_OK; @@ -994,6 +988,10 @@ int64_t SceneTree::get_frame() const { return current_frame; } +int64_t SceneTree::get_event_count() const { + + return current_event; +} Array SceneTree::_get_nodes_in_group(const StringName &p_group) { @@ -2287,9 +2285,10 @@ SceneTree::SceneTree() { tree_version = 1; physics_process_time = 1; idle_process_time = 1; - last_id = 1; + root = NULL; current_frame = 0; + current_event = 0; tree_changed_name = "tree_changed"; node_added_name = "node_added"; node_removed_name = "node_removed"; diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 9c5b0f69cb..a6f641647f 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -109,7 +109,6 @@ private: float idle_process_time; bool accept_quit; bool quit_on_go_back; - uint32_t last_id; #ifdef DEBUG_ENABLED bool debug_collisions_hint; @@ -130,6 +129,7 @@ private: bool use_font_oversampling; int64_t current_frame; + int64_t current_event; int node_count; #ifdef TOOLS_ENABLED @@ -335,8 +335,6 @@ public: _FORCE_INLINE_ Viewport *get_root() const { return root; } - uint32_t get_last_event_id() const; - void call_group_flags(uint32_t p_call_flags, const StringName &p_group, const StringName &p_function, VARIANT_ARG_LIST); void notify_group_flags(uint32_t p_call_flags, const StringName &p_group, int p_notification); void set_group_flags(uint32_t p_call_flags, const StringName &p_group, const String &p_name, const Variant &p_value); @@ -412,6 +410,7 @@ public: int get_collision_debug_contact_count() { return collision_debug_contacts; } int64_t get_frame() const; + int64_t get_event_count() const; int get_node_count() const; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 76af70f32f..fa6a7832f5 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -184,7 +184,6 @@ Viewport::GUI::GUI() { key_focus = NULL; mouse_over = NULL; - cancelled_input_ID = 0; tooltip = NULL; tooltip_popup = NULL; tooltip_label = NULL; @@ -1620,9 +1619,6 @@ bool Viewport::_gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_che void Viewport::_gui_input_event(Ref<InputEvent> p_event) { - if (p_event->get_id() == gui.cancelled_input_ID) { - return; - } //? /* if (!is_visible()) { @@ -1752,7 +1748,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { _gui_call_input(gui.mouse_focus, mb); } - get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, "windows", "_cancel_input_ID", mb->get_id()); get_tree()->set_input_as_handled(); if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == BUTTON_LEFT) { @@ -1825,7 +1820,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { gui.drag_data=Variant(); //always clear }*/ - get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, "windows", "_cancel_input_ID", mb->get_id()); get_tree()->set_input_as_handled(); } } diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 0835e3f69a..c084e348b5 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -269,7 +269,6 @@ private: float tooltip_timer; float tooltip_delay; List<Control *> modal_stack; - unsigned int cancelled_input_ID; Transform2D focus_inv_xform; bool subwindow_order_dirty; List<Control *> subwindows; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 39e6698725..0c8837ee1a 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -200,6 +200,9 @@ static ResourceFormatLoaderDynamicFont *resource_loader_dynamic_font = NULL; static ResourceFormatLoaderStreamTexture *resource_loader_stream_texture = NULL; +static ResourceFormatSaverShader *resource_saver_shader = NULL; +static ResourceFormatLoaderShader *resource_loader_shader = NULL; + void register_scene_types() { SceneStringNames::create(); @@ -607,6 +610,12 @@ void register_scene_types() { resource_loader_text = memnew(ResourceFormatLoaderText); ResourceLoader::add_resource_format_loader(resource_loader_text, true); + resource_saver_shader = memnew(ResourceFormatSaverShader); + ResourceSaver::add_resource_format_saver(resource_saver_shader, true); + + resource_loader_shader = memnew(ResourceFormatLoaderShader); + ResourceLoader::add_resource_format_loader(resource_loader_shader, true); + for (int i = 0; i < 20; i++) { GLOBAL_DEF("layer_names/2d_render/layer_" + itos(i + 1), ""); GLOBAL_DEF("layer_names/2d_physics/layer_" + itos(i + 1), ""); @@ -632,6 +641,13 @@ void unregister_scene_types() { memdelete(resource_loader_text); } + if (resource_saver_shader) { + memdelete(resource_saver_shader); + } + if (resource_loader_shader) { + memdelete(resource_loader_shader); + } + SpatialMaterial::finish_shaders(); ParticlesMaterial::finish_shaders(); CanvasItemMaterial::finish_shaders(); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 326320c60f..cc9fde58e2 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -753,7 +753,7 @@ void SpatialMaterial::_update_shader() { if (features[FEATURE_REFRACTION] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //refraction not supported with triplanar if (features[FEATURE_NORMAL_MAPPING]) { - code += "\tvec3 ref_normal = normalize( mix(NORMAL,TANGENT * NORMALMAP.x + BINORMAL * NORMALMAP.y + NORMAL * NORMALMAP.z,NORMALMAP_DEPTH) ) * SIDE;\n"; + code += "\tvec3 ref_normal = normalize( mix(NORMAL,TANGENT * NORMALMAP.x + BINORMAL * NORMALMAP.y + NORMAL * NORMALMAP.z,NORMALMAP_DEPTH) );\n"; } else { code += "\tvec3 ref_normal = NORMAL;\n"; } diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 66df7dfda8..207c50f673 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -151,3 +151,80 @@ Shader::~Shader() { VisualServer::get_singleton()->free(shader); } +//////////// + +RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error) { + + if (r_error) + *r_error = ERR_FILE_CANT_OPEN; + + Ref<Shader> shader; + shader.instance(); + + Vector<uint8_t> buffer = FileAccess::get_file_as_array(p_path); + + String str; + str.parse_utf8((const char *)buffer.ptr(), buffer.size()); + + shader->set_code(str); + + if (r_error) + *r_error = OK; + + return shader; +} + +void ResourceFormatLoaderShader::get_recognized_extensions(List<String> *p_extensions) const { + + p_extensions->push_back("shader"); +} + +bool ResourceFormatLoaderShader::handles_type(const String &p_type) const { + + return (p_type == "Shader"); +} + +String ResourceFormatLoaderShader::get_resource_type(const String &p_path) const { + + String el = p_path.get_extension().to_lower(); + if (el == "shader") + return "Shader"; + return ""; +} + +Error ResourceFormatSaverShader::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { + + Ref<Shader> shader = p_resource; + ERR_FAIL_COND_V(shader.is_null(), ERR_INVALID_PARAMETER); + + String source = shader->get_code(); + + Error err; + FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err); + + if (err) { + + ERR_FAIL_COND_V(err, err); + } + + file->store_string(source); + if (file->get_error() != OK && file->get_error() != ERR_FILE_EOF) { + memdelete(file); + return ERR_CANT_CREATE; + } + file->close(); + memdelete(file); + + return OK; +} + +void ResourceFormatSaverShader::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { + + if (Object::cast_to<Shader>(*p_resource)) { + p_extensions->push_back("shader"); + } +} +bool ResourceFormatSaverShader::recognize(const RES &p_resource) const { + + return Object::cast_to<Shader>(*p_resource) != NULL; +} diff --git a/scene/resources/shader.h b/scene/resources/shader.h index 5cc70629c7..78d73a33e2 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -31,6 +31,7 @@ #define SHADER_H #include "io/resource_loader.h" +#include "io/resource_saver.h" #include "resource.h" #include "scene/resources/texture.h" @@ -38,7 +39,6 @@ class Shader : public Resource { GDCLASS(Shader, Resource); OBJ_SAVE_TYPE(Shader); - RES_BASE_EXTENSION("shd"); public: enum Mode { @@ -95,4 +95,19 @@ public: VARIANT_ENUM_CAST(Shader::Mode); +class ResourceFormatLoaderShader : public ResourceFormatLoader { +public: + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); + virtual void get_recognized_extensions(List<String> *p_extensions) const; + virtual bool handles_type(const String &p_type) const; + virtual String get_resource_type(const String &p_path) const; +}; + +class ResourceFormatSaverShader : public ResourceFormatSaver { +public: + virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); + virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const; + virtual bool recognize(const RES &p_resource) const; +}; + #endif // SHADER_H diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 987d6c5f6a..35d0d55d85 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -707,6 +707,8 @@ Ref<Image> StreamTexture::get_data() const { } void StreamTexture::set_flags(uint32_t p_flags) { + flags = p_flags; + VS::get_singleton()->texture_set_flags(texture, flags); } void StreamTexture::reload_from_file() { diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index bd6b917d4e..144c208c07 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -893,8 +893,8 @@ void TileSet::clear() { void TileSet::_bind_methods() { ClassDB::bind_method(D_METHOD("create_tile", "id"), &TileSet::create_tile); - ClassDB::bind_method(D_METHOD("autotile_set_bitmask_mode", "mode"), &TileSet::autotile_set_bitmask_mode); - ClassDB::bind_method(D_METHOD("autotile_get_bitmask_mode"), &TileSet::autotile_get_bitmask_mode); + ClassDB::bind_method(D_METHOD("autotile_set_bitmask_mode", "id", "mode"), &TileSet::autotile_set_bitmask_mode); + ClassDB::bind_method(D_METHOD("autotile_get_bitmask_mode", "id"), &TileSet::autotile_get_bitmask_mode); ClassDB::bind_method(D_METHOD("tile_set_name", "id", "name"), &TileSet::tile_set_name); ClassDB::bind_method(D_METHOD("tile_get_name", "id"), &TileSet::tile_get_name); ClassDB::bind_method(D_METHOD("tile_set_texture", "id", "texture"), &TileSet::tile_set_texture); diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp index a25c5ca65e..96f981ab5e 100644 --- a/servers/visual/shader_types.cpp +++ b/servers/visual/shader_types.cpp @@ -109,7 +109,6 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["DEPTH_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2); - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["SIDE"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ALPHA_SCISSOR"] = ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["WORLD_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); |