diff options
Diffstat (limited to 'scene')
32 files changed, 396 insertions, 152 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 20ec06f033..9d02408641 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -604,10 +604,14 @@ bool AnimatedSprite::_is_playing() const { void AnimatedSprite::play(const StringName &p_animation, const bool p_backwards) { - if (p_animation) + backwards = p_backwards; + + if (p_animation) { set_animation(p_animation); + if (backwards && get_frame() == 0) + set_frame(frames->get_frame_count(p_animation) - 1); + } - backwards = p_backwards; _set_playing(true); } diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index d584492737..fa23e3fd39 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -360,6 +360,10 @@ bool CanvasItem::_edit_is_selected_on_click(const Point2 &p_point, double p_tole } } +Transform2D CanvasItem::_edit_get_transform() const { + return Transform2D(_edit_get_rotation(), _edit_get_position() + _edit_get_pivot()); +} + bool CanvasItem::is_visible_in_tree() const { if (!is_inside_tree()) @@ -790,29 +794,29 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil VisualServer::get_singleton()->canvas_item_add_line( canvas_item, - p_rect.position + Point2(-offset, 0), + p_rect.position + Size2(-offset, 0), p_rect.position + Size2(p_rect.size.width + offset, 0), p_color, p_width, p_antialiased); VisualServer::get_singleton()->canvas_item_add_line( canvas_item, - p_rect.position + Point2(0, offset), - p_rect.position + Size2(0, p_rect.size.height - offset), + p_rect.position + Size2(p_rect.size.width, offset), + p_rect.position + Size2(p_rect.size.width, p_rect.size.height - offset), p_color, p_width, p_antialiased); VisualServer::get_singleton()->canvas_item_add_line( canvas_item, - p_rect.position + Point2(-offset, p_rect.size.height), p_rect.position + Size2(p_rect.size.width + offset, p_rect.size.height), + p_rect.position + Size2(-offset, p_rect.size.height), p_color, p_width, p_antialiased); VisualServer::get_singleton()->canvas_item_add_line( canvas_item, - p_rect.position + Point2(p_rect.size.width, offset), - p_rect.position + Size2(p_rect.size.width, p_rect.size.height - offset), + p_rect.position + Size2(0, p_rect.size.height - offset), + p_rect.position + Size2(0, offset), p_color, p_width, p_antialiased); @@ -1133,6 +1137,7 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("_edit_set_pivot", "pivot"), &CanvasItem::_edit_set_pivot); ClassDB::bind_method(D_METHOD("_edit_get_pivot"), &CanvasItem::_edit_get_pivot); ClassDB::bind_method(D_METHOD("_edit_use_pivot"), &CanvasItem::_edit_use_pivot); + ClassDB::bind_method(D_METHOD("_edit_get_transform"), &CanvasItem::_edit_get_transform); ClassDB::bind_method(D_METHOD("get_canvas_item"), &CanvasItem::get_canvas_item); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 581adf1396..e51ee601e2 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -281,6 +281,8 @@ public: virtual void _edit_set_pivot(const Point2 &p_pivot){}; virtual Point2 _edit_get_pivot() const { return Point2(); }; + virtual Transform2D _edit_get_transform() const; + /* VISIBILITY */ void set_visible(bool p_visible); diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 9da41914d7..372d8f614b 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -260,8 +260,7 @@ void CPUParticles2D::restart() { inactive_time = 0; frame_remainder = 0; cycle = 0; - - set_emitting(true); + emitting = false; { int pc = particles.size(); @@ -271,6 +270,8 @@ void CPUParticles2D::restart() { w[i].active = false; } } + + set_emitting(true); } void CPUParticles2D::set_direction(Vector2 p_direction) { @@ -1036,7 +1037,9 @@ void CPUParticles2D::_set_redraw(bool p_redraw) { VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); } else { - VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread"); + if (VS::get_singleton()->is_connected("frame_pre_draw", this, "_update_render_thread")) { + VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread"); + } VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false); VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); @@ -1422,6 +1425,7 @@ CPUParticles2D::CPUParticles2D() { frame_remainder = 0; cycle = 0; redraw = false; + emitting = false; mesh = VisualServer::get_singleton()->mesh_create(); multimesh = VisualServer::get_singleton()->multimesh_create(); diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp index 5cf28d6c89..c7d2dabbae 100644 --- a/scene/2d/navigation_2d.cpp +++ b/scene/2d/navigation_2d.cpp @@ -541,7 +541,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect if (CLOCK_TANGENT(apex_point, portal_left, left) >= 0) { //process - if (Math::is_zero_approx(portal_left.distance_squared_to(apex_point)) || CLOCK_TANGENT(apex_point, left, portal_right) > 0) { + if (portal_left.is_equal_approx(apex_point) || CLOCK_TANGENT(apex_point, left, portal_right) > 0) { left_poly = p; portal_left = left; } else { @@ -551,7 +551,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect left_poly = p; portal_left = apex_point; portal_right = apex_point; - if (!path.size() || path[path.size() - 1] != apex_point) + if (!path.size() || !path[path.size() - 1].is_equal_approx(apex_point)) path.push_back(apex_point); skip = true; } @@ -559,7 +559,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect if (!skip && CLOCK_TANGENT(apex_point, portal_right, right) <= 0) { //process - if (Math::is_zero_approx(portal_right.distance_squared_to(apex_point)) || CLOCK_TANGENT(apex_point, right, portal_left) < 0) { + if (portal_right.is_equal_approx(apex_point) || CLOCK_TANGENT(apex_point, right, portal_left) < 0) { right_poly = p; portal_right = right; } else { @@ -569,7 +569,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect right_poly = p; portal_right = apex_point; portal_left = apex_point; - if (!path.size() || path[path.size() - 1] != apex_point) + if (!path.size() || !path[path.size() - 1].is_equal_approx(apex_point)) path.push_back(apex_point); } } @@ -595,7 +595,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect } } - if (!path.size() || !Math::is_zero_approx(path[path.size() - 1].distance_squared_to(begin_point))) { + if (!path.size() || !path[path.size() - 1].is_equal_approx(begin_point)) { path.push_back(begin_point); // Add the begin point } else { path.write[path.size() - 1] = begin_point; // Replace first midpoint by the exact begin point @@ -603,7 +603,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect path.invert(); - if (path.size() <= 1 || !Math::is_zero_approx(path[path.size() - 1].distance_squared_to(end_point))) { + if (path.size() <= 1 || !path[path.size() - 1].is_equal_approx(end_point)) { path.push_back(end_point); // Add the end point } else { path.write[path.size() - 1] = end_point; // Replace last midpoint by the exact end point diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index 5c895ecf22..86daabefd2 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -240,8 +240,7 @@ void CPUParticles::restart() { inactive_time = 0; frame_remainder = 0; cycle = 0; - - set_emitting(true); + emitting = false; { int pc = particles.size(); @@ -251,6 +250,8 @@ void CPUParticles::restart() { w[i].active = false; } } + + set_emitting(true); } void CPUParticles::set_direction(Vector3 p_direction) { @@ -1123,7 +1124,9 @@ void CPUParticles::_set_redraw(bool p_redraw) { VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true); VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); } else { - VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread"); + if (VS::get_singleton()->is_connected("frame_pre_draw", this, "_update_render_thread")) { + VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread"); + } VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false); VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); } @@ -1494,6 +1497,7 @@ CPUParticles::CPUParticles() { frame_remainder = 0; cycle = 0; redraw = false; + emitting = false; set_notify_transform(true); diff --git a/scene/3d/navigation_mesh.h b/scene/3d/navigation_mesh.h index 8467f80f0e..d5de653e40 100644 --- a/scene/3d/navigation_mesh.h +++ b/scene/3d/navigation_mesh.h @@ -124,7 +124,7 @@ public: void set_collision_mask_bit(int p_bit, bool p_value); bool get_collision_mask_bit(int p_bit) const; - void set_source_geometry_mode(int p_source_mode); + void set_source_geometry_mode(int p_geometry_mode); int get_source_geometry_mode() const; void set_source_group_name(StringName p_group_name); diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index a02cc4bee6..a107c3bf7a 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -1201,7 +1201,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve if (p_stop_on_slope) { if ((lv_n + p_floor_direction).length() < 0.01 && collision.travel.length() < 1) { Transform gt = get_global_transform(); - gt.origin -= collision.travel; + gt.origin -= collision.travel.slide(p_floor_direction); set_global_transform(gt); return Vector3(); } @@ -1265,7 +1265,7 @@ Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity if (p_stop_on_slope) { // move and collide may stray the object a bit because of pre un-stucking, // so only ensure that motion happens on floor direction in this case. - col.travel = p_floor_direction * p_floor_direction.dot(col.travel); + col.travel = col.travel.project(p_floor_direction); } } else { apply = false; //snapped with floor direction, but did not snap to a floor, do not snap. diff --git a/scene/3d/soft_body.cpp b/scene/3d/soft_body.cpp index 6c3949a0a8..6883da7f6d 100644 --- a/scene/3d/soft_body.cpp +++ b/scene/3d/soft_body.cpp @@ -115,7 +115,7 @@ SoftBody::PinnedPoint SoftBody::PinnedPoint::operator=(const PinnedPoint &obj) { void SoftBody::_update_pickable() { if (!is_inside_tree()) return; - bool pickable = ray_pickable && is_inside_tree() && is_visible_in_tree(); + bool pickable = ray_pickable && is_visible_in_tree(); PhysicsServer::get_singleton()->soft_body_set_ray_pickable(physics_rid, pickable); } @@ -395,6 +395,8 @@ void SoftBody::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "damping_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_damping_coefficient", "get_damping_coefficient"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "drag_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_coefficient", "get_drag_coefficient"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "pose_matching_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_pose_matching_coefficient", "get_pose_matching_coefficient"); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ray_pickable"), "set_ray_pickable", "is_ray_pickable"); } String SoftBody::get_configuration_warning() const { @@ -460,7 +462,9 @@ void SoftBody::update_physics_server() { } else { PhysicsServer::get_singleton()->soft_body_set_mesh(physics_rid, NULL); - VS::get_singleton()->disconnect("frame_pre_draw", this, "_draw_soft_mesh"); + if (VS::get_singleton()->is_connected("frame_pre_draw", this, "_draw_soft_mesh")) { + VS::get_singleton()->disconnect("frame_pre_draw", this, "_draw_soft_mesh"); + } } } @@ -698,7 +702,8 @@ SoftBody::SoftBody() : collision_mask(1), collision_layer(1), simulation_started(false), - pinned_points_cache_dirty(true) { + pinned_points_cache_dirty(true), + ray_pickable(true) { PhysicsServer::get_singleton()->body_attach_object_instance_id(physics_rid, get_instance_id()); //set_notify_transform(true); diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp index 416a291da1..7fe544eaab 100644 --- a/scene/animation/animation_blend_space_1d.cpp +++ b/scene/animation/animation_blend_space_1d.cpp @@ -157,6 +157,7 @@ Ref<AnimationRootNode> AnimationNodeBlendSpace1D::get_blend_point_node(int p_poi void AnimationNodeBlendSpace1D::remove_blend_point(int p_point) { ERR_FAIL_INDEX(p_point, blend_points_used); + ERR_FAIL_COND(blend_points[p_point].node.is_null()); blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed"); for (int i = p_point; i < blend_points_used - 1; i++) { diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp index 75031f0149..b04eefbe31 100644 --- a/scene/animation/animation_blend_space_2d.cpp +++ b/scene/animation/animation_blend_space_2d.cpp @@ -113,6 +113,7 @@ Ref<AnimationRootNode> AnimationNodeBlendSpace2D::get_blend_point_node(int p_poi void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) { ERR_FAIL_INDEX(p_point, blend_points_used); + ERR_FAIL_COND(blend_points[p_point].node.is_null()); blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed"); for (int i = 0; i < triangles.size(); i++) { diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 1f9793190d..a7d936fcd3 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -281,7 +281,7 @@ void Tween::_bind_methods() { BIND_ENUM_CONSTANT(EASE_OUT_IN); } -Variant &Tween::_get_initial_val(InterpolateData &p_data) { +Variant Tween::_get_initial_val(const InterpolateData &p_data) const { // What type of data are we interpolating? switch (p_data.type) { @@ -299,7 +299,7 @@ Variant &Tween::_get_initial_val(InterpolateData &p_data) { ERR_FAIL_COND_V(object == NULL, p_data.initial_val); // Are we targeting a property or a method? - static Variant initial_val; + Variant initial_val; if (p_data.type == TARGETING_PROPERTY) { // Get the property from the target object bool valid = false; @@ -322,6 +322,41 @@ Variant &Tween::_get_initial_val(InterpolateData &p_data) { return p_data.delta_val; } +Variant Tween::_get_final_val(const InterpolateData &p_data) const { + switch (p_data.type) { + case FOLLOW_PROPERTY: + case FOLLOW_METHOD: { + // Get the object that is being followed + Object *target = ObjectDB::get_instance(p_data.target_id); + ERR_FAIL_COND_V(target == NULL, p_data.initial_val); + + // We want to figure out the final value + Variant final_val; + if (p_data.type == FOLLOW_PROPERTY) { + // Read the property as-is + bool valid = false; + final_val = target->get_indexed(p_data.target_key, &valid); + ERR_FAIL_COND_V(!valid, p_data.initial_val); + } else { + // We're looking at a method. Call the method on the target object + Variant::CallError error; + final_val = target->call(p_data.target_key[0], NULL, 0, error); + ERR_FAIL_COND_V(error.error != Variant::CallError::CALL_OK, p_data.initial_val); + } + + // If we're looking at an INT value, instead convert it to a REAL + // This is better for interpolation + if (final_val.get_type() == Variant::INT) final_val = final_val.operator real_t(); + + return final_val; + } + default: { + // If we're not following a final value/method, use the final value from the data + return p_data.final_val; + } + } +} + Variant &Tween::_get_delta_val(InterpolateData &p_data) { // What kind of data are we interpolating? @@ -384,7 +419,7 @@ Variant &Tween::_get_delta_val(InterpolateData &p_data) { Variant Tween::_run_equation(InterpolateData &p_data) { // Get the initial and delta values from the data - Variant &initial_val = _get_initial_val(p_data); + Variant initial_val = _get_initial_val(p_data); Variant &delta_val = _get_delta_val(p_data); Variant result; @@ -718,7 +753,8 @@ void Tween::_tween_process(float p_delta) { // Is the tween now finished? if (data.finish) { // Set it to the final value directly - _apply_tween_value(data, data.final_val); + Variant final_val = _get_final_val(data); + _apply_tween_value(data, final_val); // Mark the tween as completed and emit the signal data.elapsed = 0; diff --git a/scene/animation/tween.h b/scene/animation/tween.h index 64ce099ecd..574238f5c9 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -127,7 +127,8 @@ private: real_t _run_equation(TransitionType p_trans_type, EaseType p_ease_type, real_t t, real_t b, real_t c, real_t d); Variant &_get_delta_val(InterpolateData &p_data); - Variant &_get_initial_val(InterpolateData &p_data); + Variant _get_initial_val(const InterpolateData &p_data) const; + Variant _get_final_val(const InterpolateData &p_data) const; Variant _run_equation(InterpolateData &p_data); bool _calc_delta_val(const Variant &p_initial_val, const Variant &p_final_val, Variant &p_delta_val); bool _apply_tween_value(InterpolateData &p_data, Variant &value); diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index 31551d6257..a1b584bad6 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -239,12 +239,14 @@ void WindowDialog::_notification(int p_what) { #ifdef TOOLS_ENABLED case NOTIFICATION_POST_POPUP: { - if (get_tree() && Engine::get_singleton()->is_editor_hint() && EditorNode::get_singleton()) + if (get_tree() && Engine::get_singleton()->is_editor_hint() && EditorNode::get_singleton()) { + was_editor_dimmed = EditorNode::get_singleton()->is_editor_dimmed(); EditorNode::get_singleton()->dim_editor(true); + } } break; case NOTIFICATION_POPUP_HIDE: { - if (get_tree() && Engine::get_singleton()->is_editor_hint() && EditorNode::get_singleton() && !get_viewport()->gui_has_modal_stack()) + if (get_tree() && Engine::get_singleton()->is_editor_hint() && EditorNode::get_singleton() && !was_editor_dimmed) EditorNode::get_singleton()->dim_editor(false); } break; #endif @@ -345,6 +347,10 @@ WindowDialog::WindowDialog() { close_button = memnew(TextureButton); add_child(close_button); close_button->connect("pressed", this, "_closed"); + +#ifdef TOOLS_ENABLED + was_editor_dimmed = false; +#endif } WindowDialog::~WindowDialog() { @@ -356,7 +362,7 @@ void PopupDialog::_notification(int p_what) { if (p_what == NOTIFICATION_DRAW) { RID ci = get_canvas_item(); - get_stylebox("panel", "PopupMenu")->draw(ci, Rect2(Point2(), get_size())); + get_stylebox("panel")->draw(ci, Rect2(Point2(), get_size())); } } diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index afd1173f28..2eb0978e9b 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -59,6 +59,10 @@ class WindowDialog : public Popup { Point2 drag_offset_far; bool resizable; +#ifdef TOOLS_ENABLED + bool was_editor_dimmed; +#endif + void _gui_input(const Ref<InputEvent> &p_event); void _closed(); int _drag_hit_test(const Point2 &pos) const; @@ -106,7 +110,6 @@ class AcceptDialog : public WindowDialog { HBoxContainer *hbc; Label *label; Button *ok; - //Button *cancel; no more cancel (there is X on that titlebar) bool hide_on_ok; void _custom_action(const String &p_action); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 5cb4bcc64f..6400061309 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -178,8 +178,12 @@ void FileDialog::_post_popup() { set_process_unhandled_input(true); // For open dir mode, deselect all items on file dialog open. - if (mode == MODE_OPEN_DIR) + if (mode == MODE_OPEN_DIR) { deselect_items(); + file_box->set_visible(false); + } else { + file_box->set_visible(true); + } } void FileDialog::_action_pressed() { @@ -413,6 +417,10 @@ void FileDialog::update_file_name() { void FileDialog::update_file_list() { tree->clear(); + + // Scroll back to the top after opening a directory + tree->get_vscroll_bar()->set_value(0); + dir_access->list_dir_begin(); TreeItem *root = tree->create_item(); @@ -894,6 +902,10 @@ FileDialog::FileDialog() { hbc->add_child(dir_up); dir_up->connect("pressed", this, "_go_up"); + drives = memnew(OptionButton); + hbc->add_child(drives); + drives->connect("item_selected", this, "_select_drive"); + hbc->add_child(memnew(Label(RTR("Path:")))); dir = memnew(LineEdit); hbc->add_child(dir); @@ -911,10 +923,6 @@ FileDialog::FileDialog() { show_hidden->connect("toggled", this, "set_show_hidden_files"); hbc->add_child(show_hidden); - drives = memnew(OptionButton); - hbc->add_child(drives); - drives->connect("item_selected", this, "_select_drive"); - makedir = memnew(Button); makedir->set_text(RTR("Create Folder")); makedir->connect("pressed", this, "_make_dir"); @@ -925,18 +933,18 @@ FileDialog::FileDialog() { tree->set_hide_root(true); vbc->add_margin_child(RTR("Directories & Files:"), tree, true); - hbc = memnew(HBoxContainer); - hbc->add_child(memnew(Label(RTR("File:")))); + file_box = memnew(HBoxContainer); + file_box->add_child(memnew(Label(RTR("File:")))); file = memnew(LineEdit); file->set_stretch_ratio(4); file->set_h_size_flags(SIZE_EXPAND_FILL); - hbc->add_child(file); + file_box->add_child(file); filter = memnew(OptionButton); filter->set_stretch_ratio(3); filter->set_h_size_flags(SIZE_EXPAND_FILL); filter->set_clip_text(true); // too many extensions overflows it - hbc->add_child(filter); - vbc->add_child(hbc); + file_box->add_child(filter); + vbc->add_child(file_box); dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES); access = ACCESS_RESOURCES; diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 4fd6d0d13c..687ebc8036 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -78,10 +78,11 @@ private: LineEdit *dir; OptionButton *drives; Tree *tree; + HBoxContainer *file_box; LineEdit *file; + OptionButton *filter; AcceptDialog *mkdirerr; AcceptDialog *exterr; - OptionButton *filter; DirAccess *dir_access; ConfirmationDialog *confirm_save; diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 1a0539effa..1406586361 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -411,6 +411,7 @@ void ItemList::set_max_columns(int p_amount) { ERR_FAIL_COND(p_amount < 0); max_columns = p_amount; update(); + shape_changed = true; } int ItemList::get_max_columns() const { diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 4edd4b8530..9e2cd9e941 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -296,8 +296,9 @@ Size2 Label::get_minimum_size() const { Size2 min_style = get_stylebox("normal")->get_minimum_size(); // don't want to mutable everything - if (word_cache_dirty) + if (word_cache_dirty) { const_cast<Label *>(this)->regenerate_word_cache(); + } if (autowrap) return Size2(1, clip ? 1 : minsize.height) + min_style; @@ -377,8 +378,14 @@ void Label::regenerate_word_cache() { memdelete(current); } - Ref<StyleBox> style = get_stylebox("normal"); - int width = autowrap ? (get_size().width - style->get_minimum_size().width) : get_longest_line_width(); + int width; + if (autowrap) { + Ref<StyleBox> style = get_stylebox("normal"); + width = MAX(get_size().width, get_custom_minimum_size().width) - style->get_minimum_size().width; + } else { + width = get_longest_line_width(); + } + Ref<Font> font = get_font("font"); int current_word_size = 0; diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 8c19255fd0..0331046492 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1721,6 +1721,41 @@ void RichTextLabel::push_font(const Ref<Font> &p_font) { _add_item(item, true); } +void RichTextLabel::push_normal() { + Ref<Font> normal_font = get_font("normal_font"); + ERR_FAIL_COND(normal_font.is_null()); + + push_font(normal_font); +} + +void RichTextLabel::push_bold() { + Ref<Font> bold_font = get_font("bold_font"); + ERR_FAIL_COND(bold_font.is_null()); + + push_font(bold_font); +} + +void RichTextLabel::push_bold_italics() { + Ref<Font> bold_italics_font = get_font("bold_italics_font"); + ERR_FAIL_COND(bold_italics_font.is_null()); + + push_font(bold_italics_font); +} + +void RichTextLabel::push_italics() { + Ref<Font> italics_font = get_font("italics_font"); + ERR_FAIL_COND(italics_font.is_null()); + + push_font(italics_font); +} + +void RichTextLabel::push_mono() { + Ref<Font> mono_font = get_font("mono_font"); + ERR_FAIL_COND(mono_font.is_null()); + + push_font(mono_font); +} + void RichTextLabel::push_color(const Color &p_color) { ERR_FAIL_COND(current->type == ITEM_TABLE); @@ -2636,6 +2671,11 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("newline"), &RichTextLabel::add_newline); ClassDB::bind_method(D_METHOD("remove_line", "line"), &RichTextLabel::remove_line); ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font); + ClassDB::bind_method(D_METHOD("push_normal"), &RichTextLabel::push_normal); + ClassDB::bind_method(D_METHOD("push_bold"), &RichTextLabel::push_bold); + ClassDB::bind_method(D_METHOD("push_bold_italics"), &RichTextLabel::push_bold_italics); + ClassDB::bind_method(D_METHOD("push_italics"), &RichTextLabel::push_italics); + ClassDB::bind_method(D_METHOD("push_mono"), &RichTextLabel::push_mono); ClassDB::bind_method(D_METHOD("push_color", "color"), &RichTextLabel::push_color); ClassDB::bind_method(D_METHOD("push_align", "align"), &RichTextLabel::push_align); ClassDB::bind_method(D_METHOD("push_indent", "level"), &RichTextLabel::push_indent); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 6cd69b9187..b9837fdfcc 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -411,6 +411,11 @@ public: void add_newline(); bool remove_line(const int p_line); void push_font(const Ref<Font> &p_font); + void push_normal(); + void push_bold(); + void push_bold_italics(); + void push_italics(); + void push_mono(); void push_color(const Color &p_color); void push_underline(); void push_strikethrough(); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 4e45f86d38..c818633f48 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -161,57 +161,58 @@ void TextEdit::Text::_update_line_cache(int p_line) const { /* BEGIN */ int lr = cr.begin_key.length(); - if (lr == 0 || lr > left) - continue; + const CharType *kc; + bool match; - const CharType *kc = cr.begin_key.c_str(); + if (lr != 0 && lr <= left) { + kc = cr.begin_key.c_str(); - bool match = true; + match = true; - for (int k = 0; k < lr; k++) { - if (kc[k] != str[i + k]) { - match = false; - break; + for (int k = 0; k < lr; k++) { + if (kc[k] != str[i + k]) { + match = false; + break; + } } - } - if (match) { + if (match) { - ColorRegionInfo cri; - cri.end = false; - cri.region = j; - text.write[p_line].region_info[i] = cri; - i += lr - 1; + ColorRegionInfo cri; + cri.end = false; + cri.region = j; + text.write[p_line].region_info[i] = cri; + i += lr - 1; - break; + break; + } } /* END */ lr = cr.end_key.length(); - if (lr == 0 || lr > left) - continue; + if (lr != 0 && lr <= left) { + kc = cr.end_key.c_str(); - kc = cr.end_key.c_str(); + match = true; - match = true; - - for (int k = 0; k < lr; k++) { - if (kc[k] != str[i + k]) { - match = false; - break; + for (int k = 0; k < lr; k++) { + if (kc[k] != str[i + k]) { + match = false; + break; + } } - } - if (match) { + if (match) { - ColorRegionInfo cri; - cri.end = true; - cri.region = j; - text.write[p_line].region_info[i] = cri; - i += lr - 1; + ColorRegionInfo cri; + cri.end = true; + cri.region = j; + text.write[p_line].region_info[i] = cri; + i += lr - 1; - break; + break; + } } } } @@ -268,6 +269,12 @@ void TextEdit::Text::clear_wrap_cache() { } } +void TextEdit::Text::clear_info_icons() { + for (int i = 0; i < text.size(); i++) { + text.write[i].has_info = false; + } +} + void TextEdit::Text::clear() { text.clear(); @@ -302,6 +309,7 @@ void TextEdit::Text::insert(int p_at, const String &p_text) { line.breakpoint = false; line.bookmark = false; line.hidden = false; + line.has_info = false; line.width_cache = -1; line.wrap_amount_cache = -1; line.data = p_text; @@ -957,6 +965,10 @@ void TextEdit::_notification(int p_what) { } } + if (minimap_line < 0 || minimap_line >= (int)text.size()) { + break; + } + Map<int, HighlighterInfo> color_map; if (syntax_coloring) { color_map = _get_line_syntax_highlighting(minimap_line); @@ -2848,27 +2860,48 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { // Indent once again if previous line will end with ':','{','[','(' and the line is not a comment // (i.e. colon/brace precedes current cursor position). if (cursor.column > 0) { - char prev_char = text[cursor.line][cursor.column - 1]; - switch (prev_char) { - case ':': - case '{': - case '[': - case '(': { - if (!is_line_comment(cursor.line)) { - if (indent_using_spaces) { - ins += space_indent; - } else { - ins += "\t"; - } + const Map<int, Text::ColorRegionInfo> &cri_map = text.get_color_region_info(cursor.line); + bool indent_char_found = false; + bool should_indent = false; + char indent_char = ':'; + char c = text[cursor.line][cursor.column]; + + for (int i = 0; i < cursor.column; i++) { + c = text[cursor.line][i]; + switch (c) { + case ':': + case '{': + case '[': + case '(': + indent_char_found = true; + should_indent = true; + indent_char = c; + continue; + } - // No need to move the brace below if we are not taking the text with us. - char closing_char = _get_right_pair_symbol(prev_char); - if ((closing_char != 0) && (closing_char == text[cursor.line][cursor.column]) && !k->get_command()) { - brace_indent = true; - ins += "\n" + ins.substr(1, ins.length() - 2); - } - } - } break; + if (indent_char_found && cri_map.has(i) && (color_regions[cri_map[i].region].begin_key == "#" || color_regions[cri_map[i].region].begin_key == "//")) { + + should_indent = true; + break; + } else if (indent_char_found && !_is_whitespace(c)) { + should_indent = false; + indent_char_found = false; + } + } + + if (!is_line_comment(cursor.line) && should_indent) { + if (indent_using_spaces) { + ins += space_indent; + } else { + ins += "\t"; + } + + // No need to move the brace below if we are not taking the text with us. + char closing_char = _get_right_pair_symbol(indent_char); + if ((closing_char != 0) && (closing_char == text[cursor.line][cursor.column]) && !k->get_command()) { + brace_indent = true; + ins += "\n" + ins.substr(1, ins.length() - 2); + } } } } @@ -3895,7 +3928,9 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i if (shift_first_line) { text.set_breakpoint(p_line + 1, text.is_breakpoint(p_line)); text.set_hidden(p_line + 1, text.is_hidden(p_line)); - text.set_info_icon(p_line + 1, text.get_info_icon(p_line), text.get_info(p_line)); + if (text.has_info_icon(p_line)) { + text.set_info_icon(p_line + 1, text.get_info_icon(p_line), text.get_info(p_line)); + } text.set_breakpoint(p_line, false); text.set_hidden(p_line, false); @@ -5410,11 +5445,11 @@ int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_searc PoolVector<int> TextEdit::_search_bind(const String &p_key, uint32_t p_search_flags, int p_from_line, int p_from_column) const { int col, line; - if (search(p_key, p_search_flags, p_from_line, p_from_column, col, line)) { + if (search(p_key, p_search_flags, p_from_line, p_from_column, line, col)) { PoolVector<int> result; result.resize(2); - result.set(0, line); - result.set(1, col); + result.set(SEARCH_RESULT_COLUMN, col); + result.set(SEARCH_RESULT_LINE, line); return result; } else { @@ -5658,9 +5693,7 @@ void TextEdit::set_line_info_icon(int p_line, Ref<Texture> p_icon, String p_info } void TextEdit::clear_info_icons() { - for (int i = 0; i < text.size(); i++) { - text.set_info_icon(i, NULL, ""); - } + text.clear_info_icons(); update(); } @@ -6355,8 +6388,9 @@ void TextEdit::_confirm_completion() { String line = text[cursor.line]; CharType next_char = line[cursor.column]; CharType last_completion_char = completion_current.insert_text[completion_current.insert_text.length() - 1]; + CharType last_completion_char_display = completion_current.display[completion_current.display.length() - 1]; - if ((last_completion_char == '"' || last_completion_char == '\'') && last_completion_char == next_char) { + if ((last_completion_char == '"' || last_completion_char == '\'') && (last_completion_char == next_char || last_completion_char_display == next_char)) { _remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1); } @@ -6503,6 +6537,7 @@ void TextEdit::_update_completion_candidates() { if (inquote && restore_quotes == 1 && !option.display.is_quoted()) { String quote = single_quote ? "'" : "\""; option.display = option.display.quote(quote); + option.insert_text = option.insert_text.quote(quote); } if (option.display.begins_with(s)) { @@ -6928,6 +6963,9 @@ void TextEdit::_bind_methods() { BIND_ENUM_CONSTANT(SEARCH_WHOLE_WORDS); BIND_ENUM_CONSTANT(SEARCH_BACKWARDS); + BIND_ENUM_CONSTANT(SEARCH_RESULT_COLUMN); + BIND_ENUM_CONSTANT(SEARCH_RESULT_LINE); + /* ClassDB::bind_method(D_METHOD("delete_char"),&TextEdit::delete_char); ClassDB::bind_method(D_METHOD("delete_line"),&TextEdit::delete_line); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index e5d9b006fe..594366de7d 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -78,6 +78,7 @@ public: bool bookmark : 1; bool hidden : 1; bool safe : 1; + bool has_info : 1; int wrap_amount_cache : 24; Map<int, ColorRegionInfo> region_info; Ref<Texture> info_icon; @@ -115,10 +116,15 @@ public: void set_safe(int p_line, bool p_safe) { text.write[p_line].safe = p_safe; } bool is_safe(int p_line) const { return text[p_line].safe; } void set_info_icon(int p_line, Ref<Texture> p_icon, String p_info) { + if (p_icon.is_null()) { + text.write[p_line].has_info = false; + return; + } text.write[p_line].info_icon = p_icon; text.write[p_line].info = p_info; + text.write[p_line].has_info = true; } - bool has_info_icon(int p_line) const { return text[p_line].info_icon.is_valid(); } + bool has_info_icon(int p_line) const { return text[p_line].has_info; } const Ref<Texture> &get_info_icon(int p_line) const { return text[p_line].info_icon; } const String &get_info(int p_line) const { return text[p_line].info; } void insert(int p_at, const String &p_text); @@ -127,6 +133,7 @@ public: void clear(); void clear_width_cache(); void clear_wrap_cache(); + void clear_info_icons(); _FORCE_INLINE_ const String &operator[](int p_line) const { return text[p_line].data; } Text() { indent_size = 4; } }; @@ -497,12 +504,16 @@ public: }; enum SearchFlags { - SEARCH_MATCH_CASE = 1, SEARCH_WHOLE_WORDS = 2, SEARCH_BACKWARDS = 4 }; + enum SearchResult { + SEARCH_RESULT_COLUMN, + SEARCH_RESULT_LINE, + }; + virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const; void _get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) const; @@ -761,6 +772,7 @@ public: VARIANT_ENUM_CAST(TextEdit::MenuItems); VARIANT_ENUM_CAST(TextEdit::SearchFlags); +VARIANT_ENUM_CAST(TextEdit::SearchResult); class SyntaxHighlighter { protected: diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index c9d1295557..2c38676c83 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1234,7 +1234,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } } - if (select_mode != SELECT_ROW && (p_item->cells[i].selected || selected_item == p_item)) { + if ((select_mode == SELECT_ROW && selected_item == p_item) || p_item->cells[i].selected) { Rect2i r(cell_rect.position, cell_rect.size); if (p_item->cells[i].text.size() > 0) { @@ -2765,7 +2765,6 @@ bool Tree::edit_selected() { return false; Rect2 rect = s->get_meta("__focus_rect"); - popup_edited_item = s; popup_edited_item_col = col; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 95536bbb23..d060ac273d 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2298,12 +2298,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Input *input = Input::get_singleton(); - if (p_event->is_action_pressed("ui_focus_next") && input->is_action_just_pressed("ui_focus_next")) { + if (!mods && p_event->is_action_pressed("ui_focus_next") && input->is_action_just_pressed("ui_focus_next")) { next = from->find_next_valid_focus(); } - if (p_event->is_action_pressed("ui_focus_prev") && input->is_action_just_pressed("ui_focus_prev")) { + if (!mods && p_event->is_action_pressed("ui_focus_prev") && input->is_action_just_pressed("ui_focus_prev")) { next = from->find_prev_valid_focus(); } diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index d932545da4..f4ac277d00 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -2870,9 +2870,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons const Vector3 &v1 = t1.value.loc; const Vector3 &v2 = t2.value.loc; - if (v0 == v2) { + if (v0.is_equal_approx(v2)) { //0 and 2 are close, let's see if 1 is close - if (v0 != v1) { + if (!v0.is_equal_approx(v1)) { //not close, not optimizable return false; } @@ -2909,9 +2909,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons //localize both to rotation from q0 - if (Math::is_zero_approx((q0 - q2).length())) { + if (q0.is_equal_approx(q2)) { - if (!Math::is_zero_approx((q0 - q1).length())) + if (!q0.is_equal_approx(q1)) return false; } else { @@ -2959,9 +2959,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons const Vector3 &v1 = t1.value.scale; const Vector3 &v2 = t2.value.scale; - if (v0 == v2) { + if (v0.is_equal_approx(v2)) { //0 and 2 are close, let's see if 1 is close - if (v0 != v1) { + if (!v0.is_equal_approx(v1)) { //not close, not optimizable return false; } diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 0dcc184a1d..e82819f270 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -432,7 +432,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font("font", "TextEdit", default_font); - theme->set_color("background_color", "TextEdit", Color(0, 0, 0)); + theme->set_color("background_color", "TextEdit", Color(0, 0, 0, 0)); theme->set_color("completion_background_color", "TextEdit", Color(0.17, 0.16, 0.2)); theme->set_color("completion_selected_color", "TextEdit", Color(0.26, 0.26, 0.27)); theme->set_color("completion_existing_color", "TextEdit", Color(0.87, 0.87, 0.87, 0.13)); @@ -558,9 +558,14 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("panel", "PopupPanel", style_pp); + // PopupDialog + + Ref<StyleBoxTexture> style_pd = make_stylebox(popup_bg_png, 4, 4, 4, 4, 10, 10, 10, 10); + theme->set_stylebox("panel", "PopupDialog", style_pd); + // PopupMenu - theme->set_stylebox("panel", "PopupMenu", make_stylebox(popup_bg_png, 4, 4, 4, 4, 10, 10, 10, 10)); + theme->set_stylebox("panel", "PopupMenu", style_pd); theme->set_stylebox("panel_disabled", "PopupMenu", make_stylebox(popup_bg_disabled_png, 4, 4, 4, 4)); theme->set_stylebox("hover", "PopupMenu", selected); theme->set_stylebox("separator", "PopupMenu", make_stylebox(vseparator_png, 3, 3, 3, 3)); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 31d294b7ca..fab0aace14 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -496,10 +496,16 @@ void SpatialMaterial::_update_shader() { } code += "uniform float roughness : hint_range(0,1);\n"; code += "uniform float point_size : hint_range(0,128);\n"; - code += "uniform sampler2D texture_metallic : hint_white;\n"; - code += "uniform vec4 metallic_texture_channel;\n"; - code += "uniform sampler2D texture_roughness : hint_white;\n"; - code += "uniform vec4 roughness_texture_channel;\n"; + + if (textures[TEXTURE_METALLIC] != NULL) { + code += "uniform sampler2D texture_metallic : hint_white;\n"; + code += "uniform vec4 metallic_texture_channel;\n"; + } + + if (textures[TEXTURE_ROUGHNESS] != NULL) { + code += "uniform sampler2D texture_roughness : hint_white;\n"; + code += "uniform vec4 roughness_texture_channel;\n"; + } if (billboard_mode == BILLBOARD_PARTICLES) { code += "uniform int particles_anim_h_frames;\n"; code += "uniform int particles_anim_v_frames;\n"; @@ -790,20 +796,30 @@ void SpatialMaterial::_update_shader() { if (flags[FLAG_ALBEDO_FROM_VERTEX_COLOR]) { code += "\talbedo_tex *= COLOR;\n"; } - code += "\tALBEDO = albedo.rgb * albedo_tex.rgb;\n"; - if (flags[FLAG_UV1_USE_TRIPLANAR]) { - code += "\tfloat metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_triplanar_pos),metallic_texture_channel);\n"; + + if (textures[TEXTURE_METALLIC] != NULL) { + if (flags[FLAG_UV1_USE_TRIPLANAR]) { + code += "\tfloat metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_triplanar_pos),metallic_texture_channel);\n"; + } else { + code += "\tfloat metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);\n"; + } + code += "\tMETALLIC = metallic_tex * metallic;\n"; } else { - code += "\tfloat metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);\n"; + code += "\tMETALLIC = metallic;\n"; } - code += "\tMETALLIC = metallic_tex * metallic;\n"; - if (flags[FLAG_UV1_USE_TRIPLANAR]) { - code += "\tfloat roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_triplanar_pos),roughness_texture_channel);\n"; + + if (textures[TEXTURE_ROUGHNESS] != NULL) { + if (flags[FLAG_UV1_USE_TRIPLANAR]) { + code += "\tfloat roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_triplanar_pos),roughness_texture_channel);\n"; + } else { + code += "\tfloat roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);\n"; + } + code += "\tROUGHNESS = roughness_tex * roughness;\n"; } else { - code += "\tfloat roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);\n"; + code += "\tROUGHNESS = roughness;\n"; } - code += "\tROUGHNESS = roughness_tex * roughness;\n"; + code += "\tSPECULAR = specular;\n"; if (features[FEATURE_NORMAL_MAPPING]) { @@ -1389,6 +1405,8 @@ void SpatialMaterial::set_texture(TextureParam p_param, const Ref<Texture> &p_te textures[p_param] = p_texture; RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); VS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid); + _queue_shader_change(); + _change_notify(); } Ref<Texture> SpatialMaterial::get_texture(TextureParam p_param) const { @@ -1754,6 +1772,7 @@ SpatialMaterial::TextureChannel SpatialMaterial::get_roughness_texture_channel() void SpatialMaterial::set_ao_texture_channel(TextureChannel p_channel) { + ERR_FAIL_INDEX(p_channel, 5); ao_texture_channel = p_channel; VS::get_singleton()->material_set_param(_get_material(), shader_names->ao_texture_channel, _get_texture_mask(p_channel)); } @@ -1764,6 +1783,7 @@ SpatialMaterial::TextureChannel SpatialMaterial::get_ao_texture_channel() const void SpatialMaterial::set_refraction_texture_channel(TextureChannel p_channel) { + ERR_FAIL_INDEX(p_channel, 5); refraction_texture_channel = p_channel; VS::get_singleton()->material_set_param(_get_material(), shader_names->refraction_texture_channel, _get_texture_mask(p_channel)); } diff --git a/scene/resources/ray_shape.cpp b/scene/resources/ray_shape.cpp index 5a696aee23..f185263a36 100644 --- a/scene/resources/ray_shape.cpp +++ b/scene/resources/ray_shape.cpp @@ -90,6 +90,12 @@ void RayShape::_bind_methods() { RayShape::RayShape() : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_RAY)) { - set_length(1.0); - set_slips_on_slope(false); + length = 1.0; + slips_on_slope = false; + + /* Code copied from setters to prevent the use of uninitialized variables */ + _update_shape(); + notify_change_to_owners(); + _change_notify("length"); + _change_notify("slips_on_slope"); } diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index bd6835f816..9f99732714 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -1064,10 +1064,11 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui String src_var = "n_out" + itos(from_node) + "p" + itos(from_port); if (in_type == VisualShaderNode::PORT_TYPE_SAMPLER && out_type == VisualShaderNode::PORT_TYPE_SAMPLER) { - - VisualShaderNodeUniform *uniform = (VisualShaderNodeUniform *)graph[type].nodes[from_node].node.ptr(); - if (uniform) { - inputs[i] = uniform->get_uniform_name(); + VisualShaderNode *ptr = const_cast<VisualShaderNode *>(graph[type].nodes[from_node].node.ptr()); + if (ptr->has_method("get_input_real_name")) { + inputs[i] = ptr->call("get_input_real_name"); + } else if (ptr->has_method("get_uniform_name")) { + inputs[i] = ptr->call("get_uniform_name"); } else { inputs[i] = ""; } @@ -1442,6 +1443,8 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "front_facing", "FRONT_FACING" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "screen_texture", "SCREEN_TEXTURE" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "depth_texture", "DEPTH_TEXTURE" }, // Spatial, Light { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, @@ -1488,6 +1491,9 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "light_pass", "float(AT_LIGHT_PASS ? 1.0 : 0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "texture", "TEXTURE" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "normal_texture", "NORMAL_TEXTURE" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "screen_texture", "SCREEN_TEXTURE" }, // Canvas Item, Light { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, @@ -1504,6 +1510,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SAMPLER, "texture", "TEXTURE" }, // Particles, Vertex { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, @@ -1599,11 +1606,15 @@ String VisualShaderNodeInput::get_output_port_name(int p_port) const { } String VisualShaderNodeInput::get_caption() const { - return TTR("Input"); + return "Input"; } String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + if (get_output_port_type(0) == PORT_TYPE_SAMPLER) { + return ""; + } + if (p_for_preview) { int idx = 0; @@ -1672,6 +1683,20 @@ String VisualShaderNodeInput::get_input_name() const { return input_name; } +String VisualShaderNodeInput::get_input_real_name() const { + + int idx = 0; + + while (ports[idx].mode != Shader::MODE_MAX) { + if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type && ports[idx].name == input_name) { + return String(ports[idx].string); + } + idx++; + } + + return ""; +} + VisualShaderNodeInput::PortType VisualShaderNodeInput::get_input_type_by_name(String p_name) const { int idx = 0; @@ -1768,6 +1793,7 @@ void VisualShaderNodeInput::_bind_methods() { ClassDB::bind_method(D_METHOD("set_input_name", "name"), &VisualShaderNodeInput::set_input_name); ClassDB::bind_method(D_METHOD("get_input_name"), &VisualShaderNodeInput::get_input_name); + ClassDB::bind_method(D_METHOD("get_input_real_name"), &VisualShaderNodeInput::get_input_real_name); ADD_PROPERTY(PropertyInfo(Variant::STRING, "input_name", PROPERTY_HINT_ENUM, ""), "set_input_name", "get_input_name"); ADD_SIGNAL(MethodInfo("input_type_changed")); @@ -1921,7 +1947,7 @@ bool VisualShaderNodeOutput::is_port_separator(int p_index) const { } String VisualShaderNodeOutput::get_caption() const { - return TTR("Output"); + return "Output"; } String VisualShaderNodeOutput::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 4f73316404..09222c8d81 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -299,6 +299,7 @@ public: void set_input_name(String p_name); String get_input_name() const; + String get_input_real_name() const; int get_input_index_count() const; PortType get_input_index_type(int p_index) const; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index a7df736c78..a94fdd9d7b 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -475,27 +475,29 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: String id = p_input_vars[2]; String code; + code += "\t{\n"; if (id == String()) { - code += "\tvec4 " + id + "_tex_read = vec4(0.0);\n"; + code += "\t\tvec4 " + id + "_tex_read = vec4(0.0);\n"; } else { if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\tvec4 " + id + "_tex_read = texture( " + id + " , UV.xy );\n"; + code += "\t\tvec4 " + id + "_tex_read = texture( " + id + " , UV.xy );\n"; } else { - code += "\tvec4 " + id + "_tex_read = textureLod( " + id + " , UV.xy , " + p_input_vars[1] + " );\n"; + code += "\t\tvec4 " + id + "_tex_read = textureLod( " + id + " , UV.xy , " + p_input_vars[1] + " );\n"; } } else if (p_input_vars[1] == String()) { //no lod - code += "\tvec4 " + id + "_tex_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n"; + code += "\t\tvec4 " + id + "_tex_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n"; } else { - code += "\tvec4 " + id + "_tex_read = textureLod( " + id + " , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n"; + code += "\t\tvec4 " + id + "_tex_read = textureLod( " + id + " , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n"; } - code += "\t" + p_output_vars[0] + " = " + id + "_tex_read.rgb;\n"; - code += "\t" + p_output_vars[1] + " = " + id + "_tex_read.a;\n"; + code += "\t\t" + p_output_vars[0] + " = " + id + "_tex_read.rgb;\n"; + code += "\t\t" + p_output_vars[1] + " = " + id + "_tex_read.a;\n"; } + code += "\t}\n"; return code; } @@ -905,6 +907,7 @@ void VisualShaderNodeCubeMap::_bind_methods() { VisualShaderNodeCubeMap::VisualShaderNodeCubeMap() { texture_type = TYPE_DATA; + source = SOURCE_TEXTURE; } ////////////// Scalar Op |