diff options
Diffstat (limited to 'scene')
138 files changed, 1302 insertions, 1101 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 28ddf6b5f8..f8384bd1e4 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -93,7 +93,7 @@ Rect2 AnimatedSprite::_get_rect() const { Point2 ofs = offset; if (centered) - ofs -= s / 2; + ofs -= Size2(s) / 2; if (s == Size2(0, 0)) s = Size2(1, 1); @@ -276,9 +276,9 @@ void SpriteFrames::_set_animations(const Array &p_animations) { anim.speed = d["speed"]; anim.loop = d["loop"]; Array frames = d["frames"]; - for (int i = 0; i < frames.size(); i++) { + for (int j = 0; j < frames.size(); j++) { - RES res = frames[i]; + RES res = frames[j]; anim.frames.push_back(res); } diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 63c4758a34..2a225e5797 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -426,10 +426,10 @@ bool Area2D::is_monitoring() const { void Area2D::set_monitorable(bool p_enable) { - if (locked || Physics2DServer::get_singleton()->is_flushing_queries()) { + if (locked || (is_inside_tree() && Physics2DServer::get_singleton()->is_flushing_queries())) { ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitorable\",true/false)"); + ERR_FAIL(); } - ERR_FAIL_COND(locked || Physics2DServer::get_singleton()->is_flushing_queries()); if (p_enable == monitorable) return; diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 961d2b00ef..7b28ad2c12 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -37,7 +37,7 @@ void AudioStreamPlayer2D::_mix_audio() { if (!stream_playback.is_valid() || !active || - (stream_paused && !stream_paused_fade_out)) { + (stream_paused && !stream_fade_out)) { return; } @@ -50,7 +50,7 @@ void AudioStreamPlayer2D::_mix_audio() { AudioFrame *buffer = mix_buffer.ptrw(); int buffer_size = mix_buffer.size(); - if (stream_paused_fade_out) { + if (stream_fade_out) { // Short fadeout ramp buffer_size = MIN(buffer_size, 128); } @@ -84,10 +84,10 @@ void AudioStreamPlayer2D::_mix_audio() { } //mix! - AudioFrame target_volume = stream_paused_fade_out ? AudioFrame(0.f, 0.f) : current.vol; - AudioFrame vol_prev = stream_paused_fade_in ? AudioFrame(0.f, 0.f) : prev_outputs[i].vol; + AudioFrame target_volume = stream_fade_out ? AudioFrame(0.f, 0.f) : current.vol; + AudioFrame vol_prev = stream_fade_in ? AudioFrame(0.f, 0.f) : prev_outputs[i].vol; AudioFrame vol_inc = (target_volume - vol_prev) / float(buffer_size); - AudioFrame vol = stream_paused_fade_in ? AudioFrame(0.f, 0.f) : current.vol; + AudioFrame vol = stream_fade_in ? AudioFrame(0.f, 0.f) : current.vol; int cc = AudioServer::get_singleton()->get_channel_count(); @@ -139,9 +139,15 @@ void AudioStreamPlayer2D::_mix_audio() { active = false; } + if (stream_stop) { + active = false; + set_physics_process_internal(false); + setplay = -1; + } + output_ready = false; - stream_paused_fade_in = false; - stream_paused_fade_out = false; + stream_fade_in = false; + stream_fade_out = false; } void AudioStreamPlayer2D::_notification(int p_what) { @@ -323,6 +329,7 @@ void AudioStreamPlayer2D::play(float p_from_pos) { } if (stream_playback.is_valid()) { + stream_stop = false; active = true; setplay = p_from_pos; output_ready = false; @@ -340,9 +347,8 @@ void AudioStreamPlayer2D::seek(float p_seconds) { void AudioStreamPlayer2D::stop() { if (stream_playback.is_valid()) { - active = false; - set_physics_process_internal(false); - setplay = -1; + stream_stop = true; + stream_fade_out = true; } } @@ -457,8 +463,8 @@ void AudioStreamPlayer2D::set_stream_paused(bool p_pause) { if (p_pause != stream_paused) { stream_paused = p_pause; - stream_paused_fade_in = p_pause ? false : true; - stream_paused_fade_out = p_pause ? true : false; + stream_fade_in = p_pause ? false : true; + stream_fade_out = p_pause ? true : false; } } @@ -537,8 +543,9 @@ AudioStreamPlayer2D::AudioStreamPlayer2D() { output_ready = false; area_mask = 1; stream_paused = false; - stream_paused_fade_in = false; - stream_paused_fade_out = false; + stream_fade_in = false; + stream_fade_out = false; + stream_stop = false; AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); } diff --git a/scene/2d/audio_stream_player_2d.h b/scene/2d/audio_stream_player_2d.h index cc00b59010..caf5c6ee49 100644 --- a/scene/2d/audio_stream_player_2d.h +++ b/scene/2d/audio_stream_player_2d.h @@ -73,8 +73,9 @@ private: float pitch_scale; bool autoplay; bool stream_paused; - bool stream_paused_fade_in; - bool stream_paused_fade_out; + bool stream_fade_in; + bool stream_fade_out; + bool stream_stop; StringName bus; void _mix_audio(); diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index dced688899..2739f71543 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -131,19 +131,15 @@ void CanvasItemMaterial::_update_shader() { code += "\tVERTEX.xy /= vec2(h_frames, v_frames);\n"; - code += "\tint total_frames = particles_anim_h_frames * particles_anim_v_frames;\n"; - code += "\tint frame = int(float(total_frames) * INSTANCE_CUSTOM.z);\n"; - code += "\tif (particles_anim_loop) {\n"; - code += "\t\tframe = abs(frame) % total_frames;\n"; + code += "\tfloat particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n"; + code += "\tfloat particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n"; + code += "\tif (!particles_anim_loop) {\n"; + code += "\t\tparticle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n"; code += "\t} else {\n"; - code += "\t\tframe = clamp(frame, 0, total_frames - 1);\n"; - code += "\t}\n"; - - code += "\tfloat frame_w = 1.0 / h_frames;\n"; - code += "\tfloat frame_h = 1.0 / v_frames;\n"; - code += "\tUV.x = UV.x * frame_w + frame_w * float(frame % particles_anim_h_frames);\n"; - code += "\tUV.y = UV.y * frame_h + frame_h * float(frame / particles_anim_h_frames);\n"; - + code += "\t\tparticle_frame = mod(particle_frame, particle_total_frames);\n"; + code += "\t}"; + code += "\tUV /= vec2(h_frames, v_frames);\n"; + code += "\tUV += vec2(mod(particle_frame, h_frames) / h_frames, floor(particle_frame / h_frames) / v_frames);\n"; code += "}\n"; } diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 5edd49b3a3..ef7644fcab 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -78,40 +78,7 @@ void CollisionPolygon2D::_build_polygon() { } Vector<Vector<Vector2> > CollisionPolygon2D::_decompose_in_convex() { - - Vector<Vector<Vector2> > decomp; - List<TriangulatorPoly> in_poly, out_poly; - - TriangulatorPoly inp; - inp.Init(polygon.size()); - for (int i = 0; i < polygon.size(); i++) { - inp.GetPoint(i) = polygon[i]; - } - inp.SetOrientation(TRIANGULATOR_CCW); - in_poly.push_back(inp); - TriangulatorPartition tpart; - if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { //failed! - ERR_PRINT("Convex decomposing failed!"); - return decomp; - } - - decomp.resize(out_poly.size()); - int idx = 0; - - for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) { - - TriangulatorPoly &tp = I->get(); - - decomp.write[idx].resize(tp.GetNumPoints()); - - for (int i = 0; i < tp.GetNumPoints(); i++) { - - decomp.write[idx].write[i] = tp.GetPoint(i); - } - - idx++; - } - + Vector<Vector<Vector2> > decomp = Geometry::decompose_polygon_in_convex(polygon); return decomp; } diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index c756f49bbd..5440a1d8c3 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -36,9 +36,9 @@ #include "scene/resources/circle_shape_2d.h" #include "scene/resources/concave_polygon_shape_2d.h" #include "scene/resources/convex_polygon_shape_2d.h" +#include "scene/resources/line_shape_2d.h" #include "scene/resources/rectangle_shape_2d.h" #include "scene/resources/segment_shape_2d.h" -#include "scene/resources/shape_line_2d.h" void CollisionShape2D::_shape_changed() { diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 21feb6e226..05c2253a5b 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -37,20 +37,7 @@ void CPUParticles2D::set_emitting(bool p_emitting) { emitting = p_emitting; - if (!is_processing_internal()) { - set_process_internal(true); - if (is_inside_tree()) { -#ifndef NO_THREADS - update_mutex->lock(); -#endif - VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread"); - VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true); - -#ifndef NO_THREADS - update_mutex->unlock(); -#endif - } - } + set_process_internal(true); } void CPUParticles2D::set_amount(int p_amount) { @@ -365,7 +352,8 @@ void CPUParticles2D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curv } break; case PARAM_ANIM_OFFSET: { } break; - default: {} + default: { + } } } Ref<Curve> CPUParticles2D::get_param_curve(Parameter p_param) const { @@ -586,7 +574,7 @@ void CPUParticles2D::_particles_process(float p_delta) { if (restart_time >= prev_time && restart_time < time) { restart = true; if (fractional_delta) { - local_delta = (time - restart_time) * lifetime; + local_delta = time - restart_time; } } @@ -594,13 +582,13 @@ void CPUParticles2D::_particles_process(float p_delta) { if (restart_time >= prev_time) { restart = true; if (fractional_delta) { - local_delta = (1.0 - restart_time + time) * lifetime; + local_delta = lifetime - restart_time + time; } } else if (restart_time < time) { restart = true; if (fractional_delta) { - local_delta = (time - restart_time) * lifetime; + local_delta = time - restart_time; } } } @@ -941,6 +929,26 @@ void CPUParticles2D::_update_particle_data_buffer() { #endif } +void CPUParticles2D::_set_redraw(bool p_redraw) { + if (redraw == p_redraw) + return; + redraw = p_redraw; +#ifndef NO_THREADS + update_mutex->lock(); +#endif + if (redraw) { + VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread"); + VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true); + } else { + VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread"); + VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false); + } +#ifndef NO_THREADS + update_mutex->unlock(); +#endif + update(); // redraw to update render list +} + void CPUParticles2D::_update_render_thread() { #ifndef NO_THREADS @@ -957,38 +965,19 @@ void CPUParticles2D::_update_render_thread() { void CPUParticles2D::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { - if (is_processing_internal()) { - -#ifndef NO_THREADS - update_mutex->lock(); -#endif - VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread"); - VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true); - -#ifndef NO_THREADS - update_mutex->unlock(); -#endif - } + _set_redraw(true); } if (p_what == NOTIFICATION_EXIT_TREE) { - if (is_processing_internal()) { - -#ifndef NO_THREADS - update_mutex->lock(); -#endif - VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread"); - VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false); -#ifndef NO_THREADS - update_mutex->unlock(); -#endif - } + _set_redraw(false); } if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) { } if (p_what == NOTIFICATION_DRAW) { + if (!redraw) + return; // dont add to render list RID texrid; if (texture.is_valid()) { @@ -1005,26 +994,21 @@ void CPUParticles2D::_notification(int p_what) { if (p_what == NOTIFICATION_INTERNAL_PROCESS) { - if (particles.size() == 0 || !is_visible_in_tree()) + if (particles.size() == 0 || !is_visible_in_tree()) { + _set_redraw(false); return; + } float delta = get_process_delta_time(); if (emitting) { - + _set_redraw(true); inactive_time = 0; } else { inactive_time += delta; if (inactive_time > lifetime * 1.2) { set_process_internal(false); -#ifndef NO_THREADS - update_mutex->lock(); -#endif - VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread"); - VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false); + _set_redraw(false); -#ifndef NO_THREADS - update_mutex->unlock(); -#endif //reset variables time = 0; inactive_time = 0; @@ -1189,7 +1173,7 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount"); ADD_GROUP("Time", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01"), "set_lifetime", "get_lifetime"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_EXP_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); @@ -1354,6 +1338,7 @@ CPUParticles2D::CPUParticles2D() { inactive_time = 0; frame_remainder = 0; cycle = 0; + redraw = false; mesh = VisualServer::get_singleton()->mesh_create(); multimesh = VisualServer::get_singleton()->multimesh_create(); diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index b1adf62980..23d2586331 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -103,6 +103,7 @@ private: float inactive_time; float frame_remainder; int cycle; + bool redraw; RID mesh; RID multimesh; @@ -179,6 +180,8 @@ private: void _update_mesh_texture(); + void _set_redraw(bool p_redraw); + protected: static void _bind_methods(); void _notification(int p_what); diff --git a/scene/2d/line_builder.h b/scene/2d/line_builder.h index 2ca28d09c4..b961385e33 100644 --- a/scene/2d/line_builder.h +++ b/scene/2d/line_builder.h @@ -34,7 +34,7 @@ #include "core/color.h" #include "core/math/vector2.h" #include "line_2d.h" -#include "scene/resources/color_ramp.h" +#include "scene/resources/gradient.h" class LineBuilder { public: diff --git a/scene/2d/navigation2d.cpp b/scene/2d/navigation_2d.cpp index 1c0e924433..57e0a5b118 100644 --- a/scene/2d/navigation2d.cpp +++ b/scene/2d/navigation_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* navigation2d.cpp */ +/* navigation_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "navigation2d.h" +#include "navigation_2d.h" #define USE_ENTRY_POINT diff --git a/scene/2d/navigation2d.h b/scene/2d/navigation_2d.h index fc1762221c..b4d659ff5c 100644 --- a/scene/2d/navigation2d.h +++ b/scene/2d/navigation_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* navigation2d.h */ +/* navigation_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -171,4 +171,4 @@ public: Navigation2D(); }; -#endif // Navigation2D2D_H +#endif // NAVIGATION_2D_H diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp index 50618c6baa..0f6af358bd 100644 --- a/scene/2d/navigation_polygon.cpp +++ b/scene/2d/navigation_polygon.cpp @@ -32,7 +32,7 @@ #include "core/core_string_names.h" #include "core/engine.h" -#include "navigation2d.h" +#include "navigation_2d.h" #include "thirdparty/misc/triangulator.h" diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 9a94092840..f4430d93f6 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -376,7 +376,7 @@ void Node2D::look_at(const Vector2 &p_pos) { float Node2D::get_angle_to(const Vector2 &p_pos) const { - return (get_global_transform().affine_inverse().xform(p_pos)).angle(); + return (to_local(p_pos) * get_scale()).angle(); } Point2 Node2D::to_local(Point2 p_global) const { diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index c005c33a19..9701998f5d 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -30,6 +30,7 @@ #include "particles_2d.h" +#include "core/os/os.h" #include "scene/resources/particles_material.h" #include "scene/scene_string_names.h" @@ -213,6 +214,10 @@ bool Particles2D::get_fractional_delta() const { String Particles2D::get_configuration_warning() const { + if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) { + return TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles2D node instead. You can use the \"Convert to CPUParticles\" option for this purpose."); + } + String warnings; if (process_material.is_null()) { diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index 271e132002..fec861ad2f 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -170,6 +170,9 @@ void PathFollow2D::_update_transform() { return; float path_length = c->get_baked_length(); + if (path_length == 0) { + return; + } float bounded_offset = offset; if (loop) bounded_offset = Math::fposmod(bounded_offset, path_length); diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index f4bc8ad6b9..1b7e1a6b8b 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -1198,6 +1198,9 @@ bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) { + if (sync_to_physics) { + ERR_PRINT("Functions move_and_slide and move_and_collide do not work together with 'sync to physics' option. Please read the documentation."); + } Transform2D gt = get_global_transform(); Physics2DServer::MotionResult result; bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, margin, &result, p_exclude_raycast_shapes); @@ -1290,7 +1293,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const floor_velocity = collision.collider_vel; if (p_stop_on_slope) { - if (Vector2() == lv_n + p_floor_direction && collision.travel.length() < 1) { + if ((lv_n + p_floor_direction).length() < 0.01 && collision.travel.length() < 1) { Transform2D gt = get_global_transform(); gt.elements[2] -= collision.travel.project(p_floor_direction.tangent()); set_global_transform(gt); @@ -1309,9 +1312,6 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const motion = motion.slide(n); lv = lv.slide(n); } - - if (p_stop_on_slope) - break; } if (!found_collision) { @@ -1338,13 +1338,27 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci Transform2D gt = get_global_transform(); if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) { - gt.elements[2] += col.travel; - if (p_floor_direction != Vector2() && Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) { - on_floor = true; - on_floor_body = col.collider_rid; - floor_velocity = col.collider_vel; + bool apply = true; + if (p_floor_direction != Vector2()) { + if (Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) { + on_floor = true; + on_floor_body = col.collider_rid; + floor_velocity = col.collider_vel; + 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); + } + + } else { + apply = false; + } + } + + if (apply) { + gt.elements[2] += col.travel; + set_global_transform(gt); } - set_global_transform(gt); } return ret; diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 54b304f851..f6f1bad581 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -88,6 +88,10 @@ bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toler return Geometry::is_point_in_polygon(p_point - get_offset(), polygon2d); } +void Polygon2D::_skeleton_bone_setup_changed() { + update(); +} + void Polygon2D::_notification(int p_what) { switch (p_what) { @@ -102,10 +106,27 @@ void Polygon2D::_notification(int p_what) { skeleton_node = Object::cast_to<Skeleton2D>(get_node(skeleton)); } - if (skeleton_node) + ObjectID new_skeleton_id = 0; + + if (skeleton_node) { VS::get_singleton()->canvas_item_attach_skeleton(get_canvas_item(), skeleton_node->get_skeleton()); - else + new_skeleton_id = skeleton_node->get_instance_id(); + } else { VS::get_singleton()->canvas_item_attach_skeleton(get_canvas_item(), RID()); + } + + if (new_skeleton_id != current_skeleton_id) { + Object *old_skeleton = ObjectDB::get_instance(current_skeleton_id); + if (old_skeleton) { + old_skeleton->disconnect("bone_setup_changed", this, "_skeleton_bone_setup_changed"); + } + + if (skeleton_node) { + skeleton_node->connect("bone_setup_changed", this, "_skeleton_bone_setup_changed"); + } + + current_skeleton_id = new_skeleton_id; + } Vector<Vector2> points; Vector<Vector2> uvs; @@ -286,7 +307,9 @@ void Polygon2D::_notification(int p_what) { if (invert || polygons.size() == 0) { Vector<int> indices = Geometry::triangulate_polygon(points); - VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID()); + if (indices.size()) { + VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID()); + } } else { //draw individual polygons Vector<int> total_indices; @@ -809,6 +832,8 @@ void Polygon2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_bones", "bones"), &Polygon2D::_set_bones); ClassDB::bind_method(D_METHOD("_get_bones"), &Polygon2D::_get_bones); + ClassDB::bind_method(D_METHOD("_skeleton_bone_setup_changed"), &Polygon2D::_skeleton_bone_setup_changed); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "get_antialiased"); @@ -846,4 +871,5 @@ Polygon2D::Polygon2D() { color = Color(1, 1, 1); rect_cache_dirty = true; internal_vertices = 0; + current_skeleton_id = 0; } diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h index c1d6ebe46e..f25b3885b0 100644 --- a/scene/2d/polygon_2d.h +++ b/scene/2d/polygon_2d.h @@ -65,10 +65,13 @@ class Polygon2D : public Node2D { mutable Rect2 item_rect; NodePath skeleton; + ObjectID current_skeleton_id; Array _get_bones() const; void _set_bones(const Array &p_bones); + void _skeleton_bone_setup_changed(); + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index 2a674e64e6..aa15255384 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -203,6 +203,7 @@ void Skeleton2D::_update_bone_setup() { transform_dirty = true; _update_transform(); + emit_signal("bone_setup_changed"); } void Skeleton2D::_make_transform_dirty() { @@ -291,6 +292,8 @@ void Skeleton2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_bone", "idx"), &Skeleton2D::get_bone); ClassDB::bind_method(D_METHOD("get_skeleton"), &Skeleton2D::get_skeleton); + + ADD_SIGNAL(MethodInfo("bone_setup_changed")); } Skeleton2D::Skeleton2D() { diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index ba103a8bf0..a8c7622828 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -363,7 +363,7 @@ Rect2 Sprite::get_rect() const { Point2 ofs = offset; if (centered) - ofs -= s / 2; + ofs -= Size2(s) / 2; if (s == Size2(0, 0)) s = Size2(1, 1); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 44730062c4..ed0a9c4915 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -75,15 +75,15 @@ void TileMap::_notification(int p_what) { Quadrant &q = E->get(); if (navigation) { - for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) { + for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) { - navigation->navpoly_remove(E->get().id); + navigation->navpoly_remove(F->get().id); } q.navpoly_ids.clear(); } - for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) { - VS::get_singleton()->free(E->get().id); + for (Map<PosKey, Quadrant::Occluder>::Element *F = q.occluder_instances.front(); F; F = F->next()) { + VS::get_singleton()->free(F->get().id); } q.occluder_instances.clear(); } @@ -129,14 +129,14 @@ void TileMap::_update_quadrant_transform() { Physics2DServer::get_singleton()->body_set_state(q.body, Physics2DServer::BODY_STATE_TRANSFORM, xform); if (navigation) { - for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) { + for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) { - navigation->navpoly_set_transform(E->get().id, nav_rel * E->get().xform); + navigation->navpoly_set_transform(F->get().id, nav_rel * F->get().xform); } } - for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) { - VS::get_singleton()->canvas_light_occluder_set_transform(E->get().id, global_transform * E->get().xform); + for (Map<PosKey, Quadrant::Occluder>::Element *F = q.occluder_instances.front(); F; F = F->next()) { + VS::get_singleton()->canvas_light_occluder_set_transform(F->get().id, global_transform * F->get().xform); } } } @@ -462,27 +462,45 @@ void TileMap::update_dirty_quadrants() { Vector<TileSet::ShapeData> shapes = tile_set->tile_get_shapes(c.id); - for (int i = 0; i < shapes.size(); i++) { - Ref<Shape2D> shape = shapes[i].shape; + for (int j = 0; j < shapes.size(); j++) { + Ref<Shape2D> shape = shapes[j].shape; if (shape.is_valid()) { - if (tile_set->tile_get_tile_mode(c.id) == TileSet::SINGLE_TILE || (shapes[i].autotile_coord.x == c.autotile_coord_x && shapes[i].autotile_coord.y == c.autotile_coord_y)) { + if (tile_set->tile_get_tile_mode(c.id) == TileSet::SINGLE_TILE || (shapes[j].autotile_coord.x == c.autotile_coord_x && shapes[j].autotile_coord.y == c.autotile_coord_y)) { Transform2D xform; xform.set_origin(offset.floor()); - Vector2 shape_ofs = shapes[i].shape_transform.get_origin(); + Vector2 shape_ofs = shapes[j].shape_transform.get_origin(); _fix_cell_transform(xform, c, shape_ofs + center_ofs, s); - xform *= shapes[i].shape_transform.untranslated(); + xform *= shapes[j].shape_transform.untranslated(); if (debug_canvas_item.is_valid()) { vs->canvas_item_add_set_transform(debug_canvas_item, xform); shape->draw(debug_canvas_item, debug_collision_color); } - ps->body_add_shape(q.body, shape->get_rid(), xform); - ps->body_set_shape_metadata(q.body, shape_idx, Vector2(E->key().x, E->key().y)); - ps->body_set_shape_as_one_way_collision(q.body, shape_idx, shapes[i].one_way_collision, shapes[i].one_way_collision_margin); - shape_idx++; + + if (shape->has_meta("decomposed")) { + Array _shapes = shape->get_meta("decomposed"); + for (int k = 0; k < _shapes.size(); k++) { + Ref<ConvexPolygonShape2D> convex = _shapes[k]; + if (convex.is_valid()) { + ps->body_add_shape(q.body, convex->get_rid(), xform); + ps->body_set_shape_metadata(q.body, shape_idx, Vector2(E->key().x, E->key().y)); + ps->body_set_shape_as_one_way_collision(q.body, shape_idx, shapes[j].one_way_collision, shapes[j].one_way_collision_margin); + shape_idx++; +#ifdef DEBUG_ENABLED + } else { + print_error("The TileSet asigned to the TileMap " + get_name() + " has an invalid convex shape."); +#endif + } + } + } else { + ps->body_add_shape(q.body, shape->get_rid(), xform); + ps->body_set_shape_metadata(q.body, shape_idx, Vector2(E->key().x, E->key().y)); + ps->body_set_shape_as_one_way_collision(q.body, shape_idx, shapes[j].one_way_collision, shapes[j].one_way_collision_margin); + shape_idx++; + } } } } @@ -531,23 +549,23 @@ void TileMap::update_dirty_quadrants() { colors.resize(vsize); { PoolVector<Vector2>::Read vr = navigation_polygon_vertices.read(); - for (int i = 0; i < vsize; i++) { - vertices.write[i] = vr[i]; - colors.write[i] = debug_navigation_color; + for (int j = 0; j < vsize; j++) { + vertices.write[j] = vr[j]; + colors.write[j] = debug_navigation_color; } } Vector<int> indices; - for (int i = 0; i < navpoly->get_polygon_count(); i++) { - Vector<int> polygon = navpoly->get_polygon(i); + for (int j = 0; j < navpoly->get_polygon_count(); j++) { + Vector<int> polygon = navpoly->get_polygon(j); - for (int j = 2; j < polygon.size(); j++) { + for (int k = 2; k < polygon.size(); k++) { - int kofs[3] = { 0, j - 1, j }; - for (int k = 0; k < 3; k++) { + int kofs[3] = { 0, k - 1, k }; + for (int l = 0; l < 3; l++) { - int idx = polygon[kofs[k]]; + int idx = polygon[kofs[l]]; ERR_FAIL_INDEX(idx, vsize); indices.push_back(idx); } @@ -601,9 +619,9 @@ void TileMap::update_dirty_quadrants() { for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { Quadrant &q = E->get(); - for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) { + for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) { - VS::get_singleton()->canvas_item_set_draw_index(E->get(), index++); + VS::get_singleton()->canvas_item_set_draw_index(F->get(), index++); } } @@ -1053,9 +1071,9 @@ void TileMap::_update_all_items_material_state() { for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { Quadrant &q = E->get(); - for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) { + for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) { - _update_item_material_state(E->get()); + _update_item_material_state(F->get()); } } } @@ -1453,7 +1471,7 @@ Vector2 TileMap::world_to_map(const Vector2 &p_pos) const { } // Account for precision errors on the border (GH-23250). - // 0.00005 is 5*CMP_EPSILON, results would start being unpredictible if + // 0.00005 is 5*CMP_EPSILON, results would start being unpredictable if // cell size is > 15,000, but we can hardly have more precision anyway with // floating point. ret += Vector2(0.00005, 0.00005); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index a44098fd77..e450e1e256 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -33,7 +33,7 @@ #include "core/self_list.h" #include "core/vset.h" -#include "scene/2d/navigation2d.h" +#include "scene/2d/navigation_2d.h" #include "scene/2d/node_2d.h" #include "scene/resources/tile_set.h" diff --git a/scene/2d/screen_button.cpp b/scene/2d/touch_screen_button.cpp index fb1558a404..9a1a759e72 100644 --- a/scene/2d/screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* screen_button.cpp */ +/* touch_screen_button.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "screen_button.h" +#include "touch_screen_button.h" + #include "core/input_map.h" #include "core/os/input.h" #include "core/os/os.h" diff --git a/scene/2d/screen_button.h b/scene/2d/touch_screen_button.h index fd944ead64..df54e5340b 100644 --- a/scene/2d/screen_button.h +++ b/scene/2d/touch_screen_button.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* screen_button.h */ +/* touch_screen_button.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SCREEN_BUTTON_H -#define SCREEN_BUTTON_H +#ifndef TOUCH_SCREEN_BUTTON_H +#define TOUCH_SCREEN_BUTTON_H #include "scene/2d/node_2d.h" -#include "scene/resources/bit_mask.h" +#include "scene/resources/bit_map.h" #include "scene/resources/rectangle_shape_2d.h" #include "scene/resources/texture.h" @@ -112,4 +112,4 @@ public: VARIANT_ENUM_CAST(TouchScreenButton::VisibilityMode); -#endif // SCREEN_BUTTON_H +#endif // TOUCH_SCREEN_BUTTON_H diff --git a/scene/3d/SCsub b/scene/3d/SCsub index 35cc7479d8..200cf4316f 100644 --- a/scene/3d/SCsub +++ b/scene/3d/SCsub @@ -7,6 +7,6 @@ if env['disable_3d']: env.scene_sources.append("3d/skeleton.cpp") env.scene_sources.append("3d/particles.cpp") env.scene_sources.append("3d/visual_instance.cpp") - env.scene_sources.append("3d/scenario_fx.cpp") + env.scene_sources.append("3d/world_environment.cpp") else: env.add_source_files(env.scene_sources, "*.cpp") diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp index 99f43b1242..e58e26d2d1 100644 --- a/scene/3d/area.cpp +++ b/scene/3d/area.cpp @@ -439,10 +439,10 @@ Array Area::get_overlapping_bodies() const { void Area::set_monitorable(bool p_enable) { - if (locked || PhysicsServer::get_singleton()->is_flushing_queries()) { + if (locked || (is_inside_tree() && PhysicsServer::get_singleton()->is_flushing_queries())) { ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitorable\",true/false)"); + ERR_FAIL(); } - ERR_FAIL_COND(locked || PhysicsServer::get_singleton()->is_flushing_queries()); if (p_enable == monitorable) return; diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 0f4d0383a4..4b3934c4ea 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -32,12 +32,13 @@ #include "core/engine.h" #include "scene/3d/area.h" #include "scene/3d/camera.h" +#include "scene/3d/listener.h" #include "scene/main/viewport.h" void AudioStreamPlayer3D::_mix_audio() { if (!stream_playback.is_valid() || !active || - (stream_paused && !stream_paused_fade_out)) { + (stream_paused && !stream_fade_out)) { return; } @@ -52,7 +53,7 @@ void AudioStreamPlayer3D::_mix_audio() { AudioFrame *buffer = mix_buffer.ptrw(); int buffer_size = mix_buffer.size(); - if (stream_paused_fade_out) { + if (stream_fade_out) { // Short fadeout ramp buffer_size = MIN(buffer_size, 128); } @@ -108,10 +109,10 @@ void AudioStreamPlayer3D::_mix_audio() { int buffers = AudioServer::get_singleton()->get_channel_count(); for (int k = 0; k < buffers; k++) { - AudioFrame target_volume = stream_paused_fade_out ? AudioFrame(0.f, 0.f) : current.vol[k]; - AudioFrame vol_prev = stream_paused_fade_in ? AudioFrame(0.f, 0.f) : prev_outputs[i].vol[k]; + AudioFrame target_volume = stream_fade_out ? AudioFrame(0.f, 0.f) : current.vol[k]; + AudioFrame vol_prev = stream_fade_in ? AudioFrame(0.f, 0.f) : prev_outputs[i].vol[k]; AudioFrame vol_inc = (target_volume - vol_prev) / float(buffer_size); - AudioFrame vol = stream_paused_fade_in ? AudioFrame(0.f, 0.f) : current.vol[k]; + AudioFrame vol = stream_fade_in ? AudioFrame(0.f, 0.f) : current.vol[k]; if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, k)) continue; //may have been deleted, will be updated on process @@ -197,9 +198,15 @@ void AudioStreamPlayer3D::_mix_audio() { active = false; } + if (stream_stop) { + active = false; + set_physics_process_internal(false); + setplay = -1; + } + output_ready = false; - stream_paused_fade_in = false; - stream_paused_fade_out = false; + stream_fade_in = false; + stream_fade_out = false; } float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const { @@ -324,16 +331,25 @@ void AudioStreamPlayer3D::_notification(int p_what) { if (!vp->is_audio_listener()) continue; - Vector3 local_pos = camera->get_global_transform().orthonormalized().affine_inverse().xform(global_pos); + bool listener_is_camera = true; + Spatial *listener_node = camera; + + Listener *listener = vp->get_listener(); + if (listener) { + listener_node = listener; + listener_is_camera = false; + } + + Vector3 local_pos = listener_node->get_global_transform().orthonormalized().affine_inverse().xform(global_pos); float dist = local_pos.length(); Vector3 area_sound_pos; - Vector3 cam_area_pos; + Vector3 listener_area_pos; if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) { - area_sound_pos = space_state->get_closest_point_to_object_volume(area->get_rid(), camera->get_global_transform().origin); - cam_area_pos = camera->get_global_transform().affine_inverse().xform(area_sound_pos); + area_sound_pos = space_state->get_closest_point_to_object_volume(area->get_rid(), listener_node->get_global_transform().origin); + listener_area_pos = listener_node->get_global_transform().affine_inverse().xform(area_sound_pos); } if (max_distance > 0) { @@ -341,10 +357,10 @@ void AudioStreamPlayer3D::_notification(int p_what) { float total_max = max_distance; if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) { - total_max = MAX(total_max, cam_area_pos.length()); + total_max = MAX(total_max, listener_area_pos.length()); } if (total_max > max_distance) { - continue; //can't hear this sound in this camera + continue; //can't hear this sound in this listener } } @@ -361,8 +377,8 @@ void AudioStreamPlayer3D::_notification(int p_what) { float db_att = (1.0 - MIN(1.0, multiplier)) * attenuation_filter_db; if (emission_angle_enabled) { - Vector3 camtopos = global_pos - camera->get_global_transform().origin; - float c = camtopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative + Vector3 listenertopos = global_pos - listener_node->get_global_transform().origin; + float c = listenertopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative float angle = Math::rad2deg(Math::acos(c)); if (angle > emission_angle) db_att -= -emission_angle_filter_attenuation_db; @@ -382,8 +398,8 @@ void AudioStreamPlayer3D::_notification(int p_what) { output.vol[0].l = 1.0 - c; output.vol[0].r = c; } else { - Vector3 camtopos = global_pos - camera->get_global_transform().origin; - float c = camtopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative + Vector3 listenertopos = global_pos - listener_node->get_global_transform().origin; + float c = listenertopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative float angle = Math::rad2deg(Math::acos(c)); float av = angle * (flat_pos.x < 0 ? -1 : 1) / 180.0; @@ -406,20 +422,20 @@ void AudioStreamPlayer3D::_notification(int p_what) { if (cc >= 3) { // Side pair - float sl = Math::abs(1.0 - Math::abs(-0.4 - av)); - float sr = Math::abs(1.0 - Math::abs(0.4 - av)); + float sleft = Math::abs(1.0 - Math::abs(-0.4 - av)); + float sright = Math::abs(1.0 - Math::abs(0.4 - av)); - output.vol[2].l = sl; - output.vol[2].r = sr; + output.vol[2].l = sleft; + output.vol[2].r = sright; } if (cc >= 4) { // Rear pair - float rl = Math::abs(1.0 - Math::abs(-0.2 - av)); - float rr = Math::abs(1.0 - Math::abs(0.2 - av)); + float rleft = Math::abs(1.0 - Math::abs(-0.2 - av)); + float rright = Math::abs(1.0 - Math::abs(0.2 - av)); - output.vol[3].l = rl; - output.vol[3].r = rr; + output.vol[3].l = rleft; + output.vol[3].r = rright; } } @@ -449,7 +465,7 @@ void AudioStreamPlayer3D::_notification(int p_what) { if (uniformity > 0.0) { - float distance = cam_area_pos.length(); + float distance = listener_area_pos.length(); float attenuation = Math::db2linear(_get_attenuation_db(distance)); //float dist_att_db = -20 * Math::log(dist + 0.00001); //logarithmic attenuation, like in real life @@ -459,7 +475,7 @@ void AudioStreamPlayer3D::_notification(int p_what) { if (attenuation < 1.0) { //pan the uniform sound - Vector3 rev_pos = cam_area_pos; + Vector3 rev_pos = listener_area_pos; rev_pos.y = 0; rev_pos.normalize(); @@ -518,9 +534,13 @@ void AudioStreamPlayer3D::_notification(int p_what) { if (doppler_tracking != DOPPLER_TRACKING_DISABLED) { - Vector3 camera_velocity = camera->get_doppler_tracked_velocity(); + Vector3 listener_velocity; - Vector3 local_velocity = camera->get_global_transform().orthonormalized().basis.xform_inv(linear_velocity - camera_velocity); + if (listener_is_camera) { + listener_velocity = camera->get_doppler_tracked_velocity(); + } + + Vector3 local_velocity = listener_node->get_global_transform().orthonormalized().basis.xform_inv(linear_velocity - listener_velocity); if (local_velocity == Vector3()) { output.pitch_scale = 1.0; @@ -642,6 +662,7 @@ float AudioStreamPlayer3D::get_pitch_scale() const { void AudioStreamPlayer3D::play(float p_from_pos) { if (stream_playback.is_valid()) { + stream_stop = false; active = true; setplay = p_from_pos; output_ready = false; @@ -659,9 +680,8 @@ void AudioStreamPlayer3D::seek(float p_seconds) { void AudioStreamPlayer3D::stop() { if (stream_playback.is_valid()) { - active = false; - set_physics_process_internal(false); - setplay = -1; + stream_stop = true; + stream_fade_out = true; } } @@ -840,7 +860,9 @@ void AudioStreamPlayer3D::set_doppler_tracking(DopplerTracking p_tracking) { if (doppler_tracking != DOPPLER_TRACKING_DISABLED) { set_notify_transform(true); velocity_tracker->set_track_physics_step(doppler_tracking == DOPPLER_TRACKING_PHYSICS_STEP); - velocity_tracker->reset(get_global_transform().origin); + if (is_inside_tree()) { + velocity_tracker->reset(get_global_transform().origin); + } } else { set_notify_transform(false); } @@ -855,8 +877,8 @@ void AudioStreamPlayer3D::set_stream_paused(bool p_pause) { if (p_pause != stream_paused) { stream_paused = p_pause; - stream_paused_fade_in = stream_paused ? false : true; - stream_paused_fade_out = stream_paused ? true : false; + stream_fade_in = stream_paused ? false : true; + stream_fade_out = stream_paused ? true : false; } } @@ -994,8 +1016,9 @@ AudioStreamPlayer3D::AudioStreamPlayer3D() { out_of_range_mode = OUT_OF_RANGE_MIX; doppler_tracking = DOPPLER_TRACKING_DISABLED; stream_paused = false; - stream_paused_fade_in = false; - stream_paused_fade_out = false; + stream_fade_in = false; + stream_fade_out = false; + stream_stop = false; velocity_tracker.instance(); AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h index 881652da64..e467c170fb 100644 --- a/scene/3d/audio_stream_player_3d.h +++ b/scene/3d/audio_stream_player_3d.h @@ -109,8 +109,9 @@ private: float pitch_scale; bool autoplay; bool stream_paused; - bool stream_paused_fade_in; - bool stream_paused_fade_out; + bool stream_fade_in; + bool stream_fade_out; + bool stream_stop; StringName bus; void _mix_audio(); diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index ed9374e422..368cebeeab 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -449,7 +449,9 @@ void Camera::set_doppler_tracking(DopplerTracking p_tracking) { doppler_tracking = p_tracking; if (p_tracking != DOPPLER_TRACKING_DISABLED) { velocity_tracker->set_track_physics_step(doppler_tracking == DOPPLER_TRACKING_PHYSICS_STEP); - velocity_tracker->reset(get_global_transform().origin); + if (is_inside_tree()) { + velocity_tracker->reset(get_global_transform().origin); + } } _update_camera_mode(); } diff --git a/scene/3d/collision_shape.cpp b/scene/3d/collision_shape.cpp index daee291ba3..ac33e2b714 100644 --- a/scene/3d/collision_shape.cpp +++ b/scene/3d/collision_shape.cpp @@ -124,6 +124,10 @@ String CollisionShape::get_configuration_warning() const { return TTR("A shape must be provided for CollisionShape to function. Please create a shape resource for it!"); } + if (shape->is_class("PlaneShape")) { + return TTR("Plane shapes don't work well and will be removed in future versions. Please don't use them."); + } + return String(); } diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index 29610cb0bf..85bc2dd529 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -47,20 +47,7 @@ PoolVector<Face3> CPUParticles::get_faces(uint32_t p_usage_flags) const { void CPUParticles::set_emitting(bool p_emitting) { emitting = p_emitting; - if (!is_processing_internal()) { - set_process_internal(true); - if (is_inside_tree()) { -#ifndef NO_THREADS - update_mutex->lock(); -#endif - VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread"); - VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true); - -#ifndef NO_THREADS - update_mutex->unlock(); -#endif - } - } + set_process_internal(true); } void CPUParticles::set_amount(int p_amount) { @@ -343,7 +330,8 @@ void CPUParticles::set_param_curve(Parameter p_param, const Ref<Curve> &p_curve) } break; case PARAM_ANIM_OFFSET: { } break; - default: {} + default: { + } } } Ref<Curve> CPUParticles::get_param_curve(Parameter p_param) const { @@ -556,7 +544,7 @@ void CPUParticles::_particles_process(float p_delta) { if (restart_time >= prev_time && restart_time < time) { restart = true; if (fractional_delta) { - local_delta = (time - restart_time) * lifetime; + local_delta = time - restart_time; } } @@ -564,13 +552,13 @@ void CPUParticles::_particles_process(float p_delta) { if (restart_time >= prev_time) { restart = true; if (fractional_delta) { - local_delta = (1.0 - restart_time + time) * lifetime; + local_delta = lifetime - restart_time + time; } } else if (restart_time < time) { restart = true; if (fractional_delta) { - local_delta = (time - restart_time) * lifetime; + local_delta = time - restart_time; } } } @@ -1004,6 +992,25 @@ void CPUParticles::_update_particle_data_buffer() { #endif } +void CPUParticles::_set_redraw(bool p_redraw) { + if (redraw == p_redraw) + return; + redraw = p_redraw; +#ifndef NO_THREADS + update_mutex->lock(); +#endif + if (redraw) { + VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread"); + VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true); + } else { + 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); + } +#ifndef NO_THREADS + update_mutex->unlock(); +#endif +} + void CPUParticles::_update_render_thread() { #ifndef NO_THREADS @@ -1022,31 +1029,11 @@ void CPUParticles::_update_render_thread() { void CPUParticles::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { - if (is_processing_internal()) { - -#ifndef NO_THREADS - update_mutex->lock(); -#endif - VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread"); - VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true); -#ifndef NO_THREADS - update_mutex->unlock(); -#endif - } + _set_redraw(true); } if (p_what == NOTIFICATION_EXIT_TREE) { - if (is_processing_internal()) { - -#ifndef NO_THREADS - update_mutex->lock(); -#endif - 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); -#ifndef NO_THREADS - update_mutex->unlock(); -#endif - } + _set_redraw(false); } if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) { @@ -1054,26 +1041,22 @@ void CPUParticles::_notification(int p_what) { if (p_what == NOTIFICATION_INTERNAL_PROCESS) { - if (particles.size() == 0 || !is_visible_in_tree()) + if (particles.size() == 0 || !is_visible_in_tree()) { + _set_redraw(false); return; + } float delta = get_process_delta_time(); if (emitting) { + _set_redraw(true); inactive_time = 0; } else { inactive_time += delta; if (inactive_time > lifetime * 1.2) { set_process_internal(false); -#ifndef NO_THREADS - update_mutex->lock(); -#endif - 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); + _set_redraw(false); -#ifndef NO_THREADS - update_mutex->unlock(); -#endif //reset variables time = 0; inactive_time = 0; @@ -1238,7 +1221,7 @@ void CPUParticles::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount"); ADD_GROUP("Time", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01"), "set_lifetime", "get_lifetime"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_EXP_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); @@ -1406,6 +1389,7 @@ CPUParticles::CPUParticles() { inactive_time = 0; frame_remainder = 0; cycle = 0; + redraw = false; multimesh = VisualServer::get_singleton()->multimesh_create(); set_base(multimesh); diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h index b50befe7be..b863a3cb3f 100644 --- a/scene/3d/cpu_particles.h +++ b/scene/3d/cpu_particles.h @@ -104,6 +104,7 @@ private: float inactive_time; float frame_remainder; int cycle; + bool redraw; RID multimesh; @@ -178,6 +179,8 @@ private: void _update_render_thread(); + void _set_redraw(bool p_redraw); + protected: static void _bind_methods(); void _notification(int p_what); diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index 5b08ea7790..c491275f00 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -30,6 +30,8 @@ #include "gi_probe.h" +#include "core/os/os.h" + #include "mesh_instance.h" #include "voxel_light_baker.h" @@ -490,6 +492,14 @@ PoolVector<Face3> GIProbe::get_faces(uint32_t p_usage_flags) const { return PoolVector<Face3>(); } +String GIProbe::get_configuration_warning() const { + + if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) { + return TTR("GIProbes are not supported by the GLES2 video driver.\nUse a BakedLightmap instead."); + } + return String(); +} + void GIProbe::_bind_methods() { ClassDB::bind_method(D_METHOD("set_probe_data", "data"), &GIProbe::set_probe_data); diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h index 87664e06b8..4badabbadf 100644 --- a/scene/3d/gi_probe.h +++ b/scene/3d/gi_probe.h @@ -168,6 +168,8 @@ public: virtual AABB get_aabb() const; virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; + virtual String get_configuration_warning() const; + GIProbe(); ~GIProbe(); }; diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index 3b514dab8c..cf1af918f7 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -210,6 +210,13 @@ bool Light::is_editor_only() const { return editor_only; } +void Light::_validate_property(PropertyInfo &property) const { + + if (VisualServer::get_singleton()->is_low_end() && property.name == "shadow_contact") { + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + } +} + void Light::_bind_methods() { ClassDB::bind_method(D_METHOD("set_editor_only", "editor_only"), &Light::set_editor_only); diff --git a/scene/3d/light.h b/scene/3d/light.h index 85e0ce3c24..ddd5bc6b3a 100644 --- a/scene/3d/light.h +++ b/scene/3d/light.h @@ -92,6 +92,7 @@ protected: static void _bind_methods(); void _notification(int p_what); + virtual void _validate_property(PropertyInfo &property) const; Light(VisualServer::LightType p_type); diff --git a/scene/3d/navigation_mesh.cpp b/scene/3d/navigation_mesh.cpp index 75301af657..93731c4023 100644 --- a/scene/3d/navigation_mesh.cpp +++ b/scene/3d/navigation_mesh.cpp @@ -292,11 +292,11 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() { if (ek.from < ek.to) SWAP(ek.from, ek.to); - Map<_EdgeKey, bool>::Element *E = edge_map.find(ek); + Map<_EdgeKey, bool>::Element *F = edge_map.find(ek); - if (E) { + if (F) { - E->get() = false; + F->get() = false; } else { diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp index 2add50dd5d..57ab01f7be 100644 --- a/scene/3d/particles.cpp +++ b/scene/3d/particles.cpp @@ -29,6 +29,8 @@ /*************************************************************************/ #include "particles.h" + +#include "core/os/os.h" #include "scene/resources/particles_material.h" #include "servers/visual_server.h" @@ -224,6 +226,10 @@ bool Particles::get_fractional_delta() const { String Particles::get_configuration_warning() const { + if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) { + return TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles node instead. You can use the \"Convert to CPUParticles\" option for this purpose."); + } + String warnings; bool meshes_found = false; @@ -348,7 +354,7 @@ void Particles::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount"); ADD_GROUP("Time", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01"), "set_lifetime", "get_lifetime"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_EXP_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); diff --git a/scene/3d/path.cpp b/scene/3d/path.cpp index 9fae5a9a54..190967d76c 100644 --- a/scene/3d/path.cpp +++ b/scene/3d/path.cpp @@ -107,6 +107,9 @@ void PathFollow::_update_transform() { } float bl = c->get_baked_length(); + if (bl == 0.0) { + return; + } float bi = c->get_bake_interval(); float o = offset; float o_next = offset + bi; @@ -122,11 +125,10 @@ void PathFollow::_update_transform() { Vector3 pos = c->interpolate_baked(o, cubic); Transform t = get_transform(); // Vector3 pos_offset = Vector3(h_offset, v_offset, 0); not used in all cases - // will be replaced by "Vector3(h_offset, v_offset, 0)" where it was formely used + // will be replaced by "Vector3(h_offset, v_offset, 0)" where it was formerly used if (rotation_mode == ROTATION_ORIENTED) { - Vector3 pos = c->interpolate_baked(o, cubic); Vector3 forward = c->interpolate_baked(o_next, cubic) - pos; if (forward.length_squared() < CMP_EPSILON2) diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 50abbd483a..05214ed669 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -1104,10 +1104,10 @@ void RigidBody::_reload_physics_characteristics() { ////////////////////////////////////////////////////// ////////////////////////// -Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_test_only) { +Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only) { Collision col; - if (move_and_collide(p_motion, p_infinite_inertia, col, p_test_only)) { + if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_test_only)) { if (motion_cache.is_null()) { motion_cache.instance(); motion_cache->owner = this; @@ -1121,11 +1121,11 @@ Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_inf return Ref<KinematicCollision>(); } -bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_test_only) { +bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) { Transform gt = get_global_transform(); PhysicsServer::MotionResult result; - bool colliding = PhysicsServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, &result); + bool colliding = PhysicsServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, &result, p_exclude_raycast_shapes); if (colliding) { r_collision.collider_metadata = result.collider_metadata; @@ -1222,7 +1222,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve floor_velocity = collision.collider_vel; if (p_stop_on_slope) { - if (Vector3() == lv_n + p_floor_direction) { + if ((lv_n + p_floor_direction).length() < 0.01) { Transform gt = get_global_transform(); gt.origin -= collision.travel; set_global_transform(gt); @@ -1243,6 +1243,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve motion = motion.slide(p_floor_direction); lv = lv.slide(p_floor_direction); } else { + Vector3 n = collision.normal; motion = motion.slide(n); lv = lv.slide(n); @@ -1279,14 +1280,27 @@ Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity Collision col; Transform gt = get_global_transform(); - if (move_and_collide(p_snap, p_infinite_inertia, col, true)) { - gt.origin += col.travel; - if (p_floor_direction != Vector3() && Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) { - on_floor = true; - on_floor_body = col.collider_rid; - floor_velocity = col.collider_vel; + if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) { + + bool apply = true; + if (p_floor_direction != Vector3()) { + if (Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) { + on_floor = true; + on_floor_body = col.collider_rid; + floor_velocity = col.collider_vel; + 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); + } + } else { + apply = false; //snapped with floor direction, but did not snap to a floor, do not snap. + } + } + if (apply) { + gt.origin += col.travel; + set_global_transform(gt); } - set_global_transform(gt); } return ret; @@ -1401,7 +1415,7 @@ Ref<KinematicCollision> KinematicBody::_get_slide_collision(int p_bounce) { void KinematicBody::_bind_methods() { - ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "test_only"), &KinematicBody::_move, DEFVAL(true), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h index 5570d0c86b..589af98062 100644 --- a/scene/3d/physics_body.h +++ b/scene/3d/physics_body.h @@ -310,14 +310,14 @@ private: _FORCE_INLINE_ bool _ignores_mode(PhysicsServer::BodyMode) const; - Ref<KinematicCollision> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_test_only = false); + Ref<KinematicCollision> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false); Ref<KinematicCollision> _get_slide_collision(int p_bounce); protected: static void _bind_methods(); public: - bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collisionz, bool p_test_only = false); + bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collisionz, bool p_exclude_raycast_shapes = true, bool p_test_only = false); bool test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia); bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision); diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h index 2921a3a881..48d65b79f7 100644 --- a/scene/3d/reflection_probe.h +++ b/scene/3d/reflection_probe.h @@ -32,7 +32,7 @@ #define REFLECTIONPROBE_H #include "scene/3d/visual_instance.h" -#include "scene/resources/sky_box.h" +#include "scene/resources/sky.h" #include "scene/resources/texture.h" #include "servers/visual_server.h" diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp index 8caf4e8e39..b7279e4d4f 100644 --- a/scene/3d/skeleton.cpp +++ b/scene/3d/skeleton.cpp @@ -70,9 +70,9 @@ bool Skeleton::_set(const StringName &p_path, const Variant &p_value) { for (int i = 0; i < children.size(); i++) { - NodePath path = children[i]; - ERR_CONTINUE(path.operator String() == ""); - Node *node = get_node(path); + NodePath npath = children[i]; + ERR_CONTINUE(npath.operator String() == ""); + Node *node = get_node(npath); ERR_CONTINUE(!node); bind_child_node_to_bone(which, node); } @@ -115,8 +115,8 @@ bool Skeleton::_get(const StringName &p_path, Variant &r_ret) const { ERR_CONTINUE(!obj); Node *node = Object::cast_to<Node>(obj); ERR_CONTINUE(!node); - NodePath path = get_path_to(node); - children.push_back(path); + NodePath npath = get_path_to(node); + children.push_back(npath); } r_ret = children; @@ -198,11 +198,7 @@ void Skeleton::_notification(int p_what) { case NOTIFICATION_ENTER_WORLD: { - if (dirty) { - - dirty = false; - _make_dirty(); // property make it dirty - } + VS::get_singleton()->skeleton_set_world_transform(skeleton, use_bones_in_world_transform, get_global_transform()); } break; case NOTIFICATION_EXIT_WORLD: { @@ -210,21 +206,7 @@ void Skeleton::_notification(int p_what) { } break; case NOTIFICATION_TRANSFORM_CHANGED: { - if (dirty) - break; //will be eventually updated - - //if moved, just update transforms - VisualServer *vs = VisualServer::get_singleton(); - const Bone *bonesptr = bones.ptr(); - int len = bones.size(); - Transform global_transform = get_global_transform(); - Transform global_transform_inverse = global_transform.affine_inverse(); - - for (int i = 0; i < len; i++) { - - const Bone &b = bonesptr[i]; - vs->skeleton_bone_set_transform(skeleton, i, global_transform * (b.transform_final * global_transform_inverse)); - } + VS::get_singleton()->skeleton_set_world_transform(skeleton, use_bones_in_world_transform, get_global_transform()); } break; case NOTIFICATION_UPDATE_SKELETON: { @@ -232,7 +214,7 @@ void Skeleton::_notification(int p_what) { Bone *bonesptr = bones.ptrw(); int len = bones.size(); - vs->skeleton_allocate(skeleton, len); // if same size, nothin really happens + vs->skeleton_allocate(skeleton, len); // if same size, nothing really happens _update_process_order(); @@ -257,9 +239,6 @@ void Skeleton::_notification(int p_what) { rest_global_inverse_dirty = false; } - Transform global_transform = get_global_transform(); - Transform global_transform_inverse = global_transform.affine_inverse(); - for (int i = 0; i < len; i++) { Bone &b = bonesptr[order[i]]; @@ -320,7 +299,7 @@ void Skeleton::_notification(int p_what) { } b.transform_final = b.pose_global * b.rest_global_inverse; - vs->skeleton_bone_set_transform(skeleton, order[i], global_transform * (b.transform_final * global_transform_inverse)); + vs->skeleton_bone_set_transform(skeleton, order[i], b.transform_final); for (List<uint32_t>::Element *E = b.nodes_bound.front(); E; E = E->next()) { @@ -594,10 +573,6 @@ void Skeleton::_make_dirty() { if (dirty) return; - if (!is_inside_tree()) { - dirty = true; - return; - } MessageQueue::get_singleton()->push_notification(this, NOTIFICATION_UPDATE_SKELETON); dirty = true; } @@ -771,6 +746,16 @@ void Skeleton::physical_bones_remove_collision_exception(RID p_exception) { #endif // _3D_DISABLED +void Skeleton::set_use_bones_in_world_transform(bool p_enable) { + use_bones_in_world_transform = p_enable; + if (is_inside_tree()) { + VS::get_singleton()->skeleton_set_world_transform(skeleton, use_bones_in_world_transform, get_global_transform()); + } +} +bool Skeleton::is_using_bones_in_world_transform() const { + return use_bones_in_world_transform; +} + void Skeleton::_bind_methods() { ClassDB::bind_method(D_METHOD("add_bone", "name"), &Skeleton::add_bone); @@ -807,6 +792,9 @@ void Skeleton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_bone_transform", "bone_idx"), &Skeleton::get_bone_transform); + ClassDB::bind_method(D_METHOD("set_use_bones_in_world_transform", "enable"), &Skeleton::set_use_bones_in_world_transform); + ClassDB::bind_method(D_METHOD("is_using_bones_in_world_transform"), &Skeleton::is_using_bones_in_world_transform); + #ifndef _3D_DISABLED ClassDB::bind_method(D_METHOD("physical_bones_stop_simulation"), &Skeleton::physical_bones_stop_simulation); @@ -818,6 +806,7 @@ void Skeleton::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bone_ignore_animation", "bone", "ignore"), &Skeleton::set_bone_ignore_animation); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bones_in_world_transform"), "set_use_bones_in_world_transform", "is_using_bones_in_world_transform"); BIND_CONSTANT(NOTIFICATION_UPDATE_SKELETON); } @@ -828,6 +817,7 @@ Skeleton::Skeleton() { process_order_dirty = true; skeleton = VisualServer::get_singleton()->skeleton_create(); set_notify_transform(true); + use_bones_in_world_transform = false; } Skeleton::~Skeleton() { diff --git a/scene/3d/skeleton.h b/scene/3d/skeleton.h index 0f463c9ea7..5f43b3c6c3 100644 --- a/scene/3d/skeleton.h +++ b/scene/3d/skeleton.h @@ -100,6 +100,7 @@ class Skeleton : public Spatial { void _make_dirty(); bool dirty; + bool use_bones_in_world_transform; // bind helpers Array _get_bound_child_nodes_to_bone(int p_bone) const { @@ -179,6 +180,9 @@ public: void localize_rests(); // used for loaders and tools int get_process_order(int p_idx); + void set_use_bones_in_world_transform(bool p_enable); + bool is_using_bones_in_world_transform() const; + #ifndef _3D_DISABLED // Physical bone API diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp index d6544c39da..83f99a2e3c 100644 --- a/scene/3d/spatial.cpp +++ b/scene/3d/spatial.cpp @@ -178,7 +178,7 @@ void Spatial::_notification(int p_what) { get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_enter_world, NULL, 0); } #ifdef TOOLS_ENABLED - if (Engine::get_singleton()->is_editor_hint()) { + if (Engine::get_singleton()->is_editor_hint() && get_tree()->is_node_being_edited(this)) { //get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,SceneStringNames::get_singleton()->_spatial_editor_group,SceneStringNames::get_singleton()->_request_gizmo,this); get_tree()->call_group_flags(0, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this); diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index a3fa2ac98d..6b70eef662 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -382,36 +382,30 @@ void Sprite3D::_draw() { VS::get_singleton()->immediate_clear(immediate); if (!texture.is_valid()) - return; //no texuture no life + return; Vector2 tsize = texture->get_size(); if (tsize.x == 0 || tsize.y == 0) return; - Size2i s; - Rect2 src_rect; - - if (region) { - - s = region_rect.size; - src_rect = region_rect; - } else { - s = texture->get_size(); - s = s / Size2(hframes, vframes); + Rect2 base_rect; + if (region) + base_rect = region_rect; + else + base_rect = Rect2(0, 0, texture->get_width(), texture->get_height()); - src_rect.size = s; - src_rect.position.x += (frame % hframes) * s.x; - src_rect.position.y += (frame / hframes) * s.y; - } + Size2 frame_size = base_rect.size / Size2(hframes, vframes); + Point2 frame_offset = Point2(frame % hframes, frame / hframes); + frame_offset *= frame_size; - Point2 ofs = get_offset(); + Point2 dest_offset = get_offset(); if (is_centered()) - ofs -= s / 2; - - Rect2 dst_rect(ofs, s); + dest_offset -= frame_size / 2; + Rect2 src_rect(base_rect.position + frame_offset, frame_size); + Rect2 final_dst_rect(dest_offset, frame_size); Rect2 final_rect; Rect2 final_src_rect; - if (!texture->get_rect_region(dst_rect, src_rect, final_rect, final_src_rect)) + if (!texture->get_rect_region(final_dst_rect, src_rect, final_rect, final_src_rect)) return; if (final_rect.size.x == 0 || final_rect.size.y == 0) diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp index 30e38c8ee2..750ed97ae6 100644 --- a/scene/3d/voxel_light_baker.cpp +++ b/scene/3d/voxel_light_baker.cpp @@ -887,7 +887,7 @@ void VoxelLightBaker::plot_light_directional(const Vector3 &p_direction, const C distance -= distance_adv; } - if (result == idx) { + if (result == (uint32_t)idx) { //cell hit itself! hooray! Vector3 normal(cells[idx].normal[0], cells[idx].normal[1], cells[idx].normal[2]); @@ -1018,7 +1018,7 @@ void VoxelLightBaker::plot_light_omni(const Vector3 &p_pos, const Color &p_color distance -= distance_adv; } - if (result == idx) { + if (result == (uint32_t)idx) { //cell hit itself! hooray! if (normal == Vector3()) { @@ -1152,7 +1152,7 @@ void VoxelLightBaker::plot_light_spot(const Vector3 &p_pos, const Vector3 &p_axi distance -= distance_adv; } - if (result == idx) { + if (result == (uint32_t)idx) { //cell hit itself! hooray! if (normal == Vector3()) { @@ -1730,7 +1730,7 @@ Vector3 VoxelLightBaker::_compute_ray_trace_at_pos(const Vector3 &p_pos, const V //int level_limit = max_level; cell = 0; //start from root - for (int i = 0; i < max_level; i++) { + for (int j = 0; j < max_level; j++) { const Cell *bc = &cells[cell]; @@ -1759,14 +1759,14 @@ Vector3 VoxelLightBaker::_compute_ray_trace_at_pos(const Vector3 &p_pos, const V } if (unlikely(cell != CHILD_EMPTY)) { - for (int i = 0; i < 6; i++) { + for (int j = 0; j < 6; j++) { //anisotropic read light - float amount = direction.dot(aniso_normal[i]); + float amount = direction.dot(aniso_normal[j]); if (amount <= 0) continue; - accum.x += light[cell].accum[i][0] * amount; - accum.y += light[cell].accum[i][1] * amount; - accum.z += light[cell].accum[i][2] * amount; + accum.x += light[cell].accum[j][0] * amount; + accum.y += light[cell].accum[j][1] * amount; + accum.z += light[cell].accum[j][2] * amount; } accum.x += cells[cell].emission[0]; accum.y += cells[cell].emission[1]; @@ -1833,16 +1833,16 @@ Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh } int faces = ic ? ic / 3 : vc / 3; - for (int i = 0; i < faces; i++) { + for (int j = 0; j < faces; j++) { Vector3 vertex[3]; Vector3 normal[3]; Vector2 uv[3]; - for (int j = 0; j < 3; j++) { - int idx = ic ? ir[i * 3 + j] : i * 3 + j; - vertex[j] = xform.xform(vr[idx]); - normal[j] = xform.basis.xform(nr[idx]).normalized(); - uv[j] = u2r[idx]; + for (int k = 0; k < 3; k++) { + int idx = ic ? ir[j * 3 + k] : j * 3 + k; + vertex[k] = xform.xform(vr[idx]); + normal[k] = xform.basis.xform(nr[idx]).normalized(); + uv[k] = u2r[idx]; } _plot_triangle(uv, vertex, normal, lightmap.ptrw(), width, height); @@ -2208,7 +2208,7 @@ PoolVector<int> VoxelLightBaker::create_gi_probe_data() { } { - uint16_t alpha = CLAMP(uint32_t(bake_cells[i].alpha * 65535.0), 0, 65535); + uint16_t alpha = MIN(uint32_t(bake_cells[i].alpha * 65535.0), 65535); uint16_t level = bake_cells[i].level; w32[ofs++] = (uint32_t(level) << 16) | uint32_t(alpha); @@ -2252,7 +2252,7 @@ void VoxelLightBaker::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Re uint32_t child = bake_cells[p_idx].children[i]; - if (child == CHILD_EMPTY || child >= max_original_cells) + if (child == CHILD_EMPTY || child >= (uint32_t)max_original_cells) continue; AABB aabb = p_aabb; diff --git a/scene/3d/scenario_fx.cpp b/scene/3d/world_environment.cpp index ad9b61e1ff..3cd43cbf5b 100644 --- a/scene/3d/scenario_fx.cpp +++ b/scene/3d/world_environment.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* scenario_fx.cpp */ +/* world_environment.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "scenario_fx.h" +#include "world_environment.h" #include "scene/main/viewport.h" void WorldEnvironment::_notification(int p_what) { diff --git a/scene/3d/scenario_fx.h b/scene/3d/world_environment.h index 6317dae75d..bf36a0a532 100644 --- a/scene/3d/scenario_fx.h +++ b/scene/3d/world_environment.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* scenario_fx.h */ +/* world_environment.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp index 1fe14e633b..95d4644004 100644 --- a/scene/animation/animation_blend_space_2d.cpp +++ b/scene/animation/animation_blend_space_2d.cpp @@ -461,9 +461,9 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) { points[j], points[(j + 1) % 3] }; - Vector2 closest = Geometry::get_closest_point_to_segment_2d(blend_pos, s); - if (first || closest.distance_to(blend_pos) < best_point.distance_to(blend_pos)) { - best_point = closest; + Vector2 closest2 = Geometry::get_closest_point_to_segment_2d(blend_pos, s); + if (first || closest2.distance_to(blend_pos) < best_point.distance_to(blend_pos)) { + best_point = closest2; blend_triangle = i; first = false; float d = s[0].distance_to(s[1]); @@ -472,7 +472,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) { blend_weights[(j + 1) % 3] = 0.0; blend_weights[(j + 2) % 3] = 0.0; } else { - float c = s[0].distance_to(closest) / d; + float c = s[0].distance_to(closest2) / d; blend_weights[j] = 1.0 - c; blend_weights[(j + 1) % 3] = c; diff --git a/scene/animation/animation_cache.cpp b/scene/animation/animation_cache.cpp index 6c67af5777..feefe3ddd4 100644 --- a/scene/animation/animation_cache.cpp +++ b/scene/animation/animation_cache.cpp @@ -133,19 +133,19 @@ void AnimationCache::_update_cache() { } else { if (np.get_subname_count() > 0) { - RES res; + RES res2; Vector<StringName> leftover_subpath; // We don't want to cache the last resource unless it is a method call bool is_method = animation->track_get_type(i) == Animation::TYPE_METHOD; - root->get_node_and_resource(np, res, leftover_subpath, is_method); + root->get_node_and_resource(np, res2, leftover_subpath, is_method); - if (res.is_valid()) { - path.resource = res; + if (res2.is_valid()) { + path.resource = res2; } else { path.node = node; } - path.object = res.is_valid() ? res.ptr() : (Object *)node; + path.object = res2.is_valid() ? res2.ptr() : (Object *)node; path.subpath = leftover_subpath; } else { diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 08cc655cdd..5df3da93e1 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -421,7 +421,8 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *sm, if (sm->transitions[i].from == current && auto_advance) { - if (sm->transitions[i].transition->get_priority() < priority_best) { + if (sm->transitions[i].transition->get_priority() <= priority_best) { + priority_best = sm->transitions[i].transition->get_priority(); auto_advance_to = i; } } diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 1d2001c30d..016db15b73 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -287,7 +287,6 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) { // broken track (nonexistent bone) p_anim->node_cache[i]->skeleton = NULL; p_anim->node_cache[i]->spatial = NULL; - printf("bone is %ls\n", String(bone_name).c_str()); ERR_CONTINUE(p_anim->node_cache[i]->bone_idx < 0); } } else { @@ -344,10 +343,16 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float for (int i = 0; i < a->get_track_count(); i++) { + // If an animation changes this animation (or it animates itself) + // we need to recreate our animation cache + if (p_anim->node_cache.size() != a->get_track_count()) { + _ensure_node_caches(p_anim); + } + TrackNodeCache *nc = p_anim->node_cache[i]; - if (!nc) // no node cache for this track, skip it - continue; + if (!nc) + continue; // no node cache for this track, skip it if (!a->track_is_enabled(i)) continue; // do nothing if the track is disabled @@ -985,25 +990,12 @@ void AnimationPlayer::remove_animation(const StringName &p_name) { void AnimationPlayer::_ref_anim(const Ref<Animation> &p_anim) { - if (used_anims.has(p_anim)) - used_anims[p_anim]++; - else { - used_anims[p_anim] = 1; - Ref<Animation>(p_anim)->connect("changed", this, "_animation_changed"); - } + Ref<Animation>(p_anim)->connect(SceneStringNames::get_singleton()->tracks_changed, this, "_animation_changed", varray(), CONNECT_REFERENCE_COUNTED); } void AnimationPlayer::_unref_anim(const Ref<Animation> &p_anim) { - ERR_FAIL_COND(!used_anims.has(p_anim)); - - int &n = used_anims[p_anim]; - n--; - if (n == 0) { - - Ref<Animation>(p_anim)->disconnect("changed", this, "_animation_changed"); - used_anims.erase(p_anim); - } + Ref<Animation>(p_anim)->disconnect(SceneStringNames::get_singleton()->tracks_changed, this, "_animation_changed"); } void AnimationPlayer::rename_animation(const StringName &p_name, const StringName &p_new_name) { @@ -1140,8 +1132,6 @@ void AnimationPlayer::play_backwards(const StringName &p_name, float p_custom_bl void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float p_custom_scale, bool p_from_end) { - //printf("animation is %ls\n", String(p_name).c_str()); - //ERR_FAIL_COND(!is_inside_scene()); StringName name = p_name; if (String(name) == "") @@ -1199,9 +1189,21 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float _stop_playing_caches(); c.current.from = &animation_set[name]; - c.current.pos = p_from_end ? c.current.from->animation->get_length() : 0; + + if (c.assigned != name) { // reset + c.current.pos = p_from_end ? c.current.from->animation->get_length() : 0; + } else { + if (p_from_end && c.current.pos == 0) { + // Animation reset BUT played backwards, set position to the end + c.current.pos = c.current.from->animation->get_length(); + } else if (!p_from_end && c.current.pos == c.current.from->animation->get_length()) { + // Animation resumed but already ended, set position to the beggining + c.current.pos = 0; + } + } + c.current.speed_scale = p_custom_scale; - c.assigned = p_name; + c.assigned = name; c.seeked = false; c.started = true; @@ -1280,6 +1282,7 @@ void AnimationPlayer::stop(bool p_reset) { if (p_reset) { c.current.from = NULL; c.current.speed_scale = 1; + c.current.pos = 0; } _set_process(false); queued.clear(); diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 175072edcf..fea4819821 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -114,10 +114,12 @@ private: Variant value_accum; uint64_t accum_pass; Variant capture; - PropertyAnim() { - accum_pass = 0; - object = NULL; - } + + PropertyAnim() : + owner(NULL), + special(SP_NONE), + object(NULL), + accum_pass(0) {} }; Map<StringName, PropertyAnim> property_anim; @@ -129,25 +131,28 @@ private: float bezier_accum; Object *object; uint64_t accum_pass; - BezierAnim() { - accum_pass = 0; - bezier_accum = 0; - object = NULL; - } + + BezierAnim() : + owner(NULL), + bezier_accum(0.0), + object(NULL), + accum_pass(0) {} }; Map<StringName, BezierAnim> bezier_anim; - TrackNodeCache() { - skeleton = NULL; - spatial = NULL; - node = NULL; - accum_pass = 0; - bone_idx = -1; - node_2d = NULL; - audio_playing = false; - animation_playing = false; - } + TrackNodeCache() : + id(0), + node(NULL), + spatial(NULL), + node_2d(NULL), + skeleton(NULL), + bone_idx(-1), + accum_pass(0), + audio_playing(false), + audio_start(0.0), + audio_len(0.0), + animation_playing(false) {} }; struct TrackNodeCacheKey { @@ -176,8 +181,6 @@ private: int cache_update_bezier_size; Set<TrackNodeCache *> playing_caches; - Map<Ref<Animation>, int> used_anims; - uint64_t accum_pass; float speed_scale; float default_blend_time; diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index c32001dbcd..0b6fa26bfc 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -1009,10 +1009,10 @@ void AnimationTree::_process_graph(float p_delta) { a->method_track_get_key_indices(i, time, delta, &indices); - for (List<int>::Element *E = indices.front(); E; E = E->next()) { + for (List<int>::Element *F = indices.front(); F; F = F->next()) { - StringName method = a->method_track_get_name(i, E->get()); - Vector<Variant> params = a->method_track_get_params(i, E->get()); + StringName method = a->method_track_get_name(i, F->get()); + Vector<Variant> params = a->method_track_get_params(i, F->get()); int s = params.size(); @@ -1151,9 +1151,9 @@ void AnimationTree::_process_graph(float p_delta) { TrackCacheAnimation *t = static_cast<TrackCacheAnimation *>(track); - AnimationPlayer *player = Object::cast_to<AnimationPlayer>(t->object); + AnimationPlayer *player2 = Object::cast_to<AnimationPlayer>(t->object); - if (!player) + if (!player2) continue; if (delta == 0 || seeked) { @@ -1165,10 +1165,10 @@ void AnimationTree::_process_graph(float p_delta) { float pos = a->track_get_key_time(i, idx); StringName anim_name = a->animation_track_get_key_animation(i, idx); - if (String(anim_name) == "[stop]" || !player->has_animation(anim_name)) + if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name)) continue; - Ref<Animation> anim = player->get_animation(anim_name); + Ref<Animation> anim = player2->get_animation(anim_name); float at_anim_pos; @@ -1178,14 +1178,14 @@ void AnimationTree::_process_graph(float p_delta) { at_anim_pos = MAX(anim->get_length(), time - pos); //seek to end } - if (player->is_playing() || seeked) { - player->play(anim_name); - player->seek(at_anim_pos); + if (player2->is_playing() || seeked) { + player2->play(anim_name); + player2->seek(at_anim_pos); t->playing = true; playing_caches.insert(t); } else { - player->set_assigned_animation(anim_name); - player->seek(at_anim_pos, true); + player2->set_assigned_animation(anim_name); + player2->seek(at_anim_pos, true); } } else { //find stuff to play @@ -1195,15 +1195,15 @@ void AnimationTree::_process_graph(float p_delta) { int idx = to_play.back()->get(); StringName anim_name = a->animation_track_get_key_animation(i, idx); - if (String(anim_name) == "[stop]" || !player->has_animation(anim_name)) { + if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name)) { if (playing_caches.has(t)) { playing_caches.erase(t); - player->stop(); + player2->stop(); t->playing = false; } } else { - player->play(anim_name); + player2->play(anim_name); t->playing = true; playing_caches.insert(t); } diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index e3a21d8b46..3420b48ae3 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -136,9 +136,9 @@ bool AnimationTreePlayer::_set(const StringName &p_name, const Variant &p_value) else animation_node_set_animation(id, node.get_valid("animation")); Array filters = node.get_valid("filter"); - for (int i = 0; i < filters.size(); i++) { + for (int j = 0; j < filters.size(); j++) { - animation_node_set_filter_path(id, filters[i], true); + animation_node_set_filter_path(id, filters[j], true); } } break; case NODE_ONESHOT: { @@ -150,9 +150,9 @@ bool AnimationTreePlayer::_set(const StringName &p_name, const Variant &p_value) oneshot_node_set_autorestart_delay(id, node.get_valid("autorestart_delay")); oneshot_node_set_autorestart_random_delay(id, node.get_valid("autorestart_random_delay")); Array filters = node.get_valid("filter"); - for (int i = 0; i < filters.size(); i++) { + for (int j = 0; j < filters.size(); j++) { - oneshot_node_set_filter_path(id, filters[i], true); + oneshot_node_set_filter_path(id, filters[j], true); } } break; @@ -162,9 +162,9 @@ bool AnimationTreePlayer::_set(const StringName &p_name, const Variant &p_value) case NODE_BLEND2: { blend2_node_set_amount(id, node.get_valid("blend")); Array filters = node.get_valid("filter"); - for (int i = 0; i < filters.size(); i++) { + for (int j = 0; j < filters.size(); j++) { - blend2_node_set_filter_path(id, filters[i], true); + blend2_node_set_filter_path(id, filters[j], true); } } break; case NODE_BLEND3: { @@ -278,8 +278,8 @@ bool AnimationTreePlayer::_get(const StringName &p_name, Variant &r_ret) const { an->filter.get_key_list(&keys); k.resize(keys.size()); int i = 0; - for (List<NodePath>::Element *E = keys.front(); E; E = E->next()) { - k[i++] = E->get(); + for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) { + k[i++] = F->get(); } node["filter"] = k; } break; @@ -297,8 +297,8 @@ bool AnimationTreePlayer::_get(const StringName &p_name, Variant &r_ret) const { osn->filter.get_key_list(&keys); k.resize(keys.size()); int i = 0; - for (List<NodePath>::Element *E = keys.front(); E; E = E->next()) { - k[i++] = E->get(); + for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) { + k[i++] = F->get(); } node["filter"] = k; @@ -315,8 +315,8 @@ bool AnimationTreePlayer::_get(const StringName &p_name, Variant &r_ret) const { bn->filter.get_key_list(&keys); k.resize(keys.size()); int i = 0; - for (List<NodePath>::Element *E = keys.front(); E; E = E->next()) { - k[i++] = E->get(); + for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) { + k[i++] = F->get(); } node["filter"] = k; @@ -874,10 +874,10 @@ void AnimationTreePlayer::_process_animation(float p_delta) { List<int> indices; a->method_track_get_key_indices(tr.local_track, anim_list->time, anim_list->step, &indices); - for (List<int>::Element *E = indices.front(); E; E = E->next()) { + for (List<int>::Element *F = indices.front(); F; F = F->next()) { - StringName method = a->method_track_get_name(tr.local_track, E->get()); - Vector<Variant> args = a->method_track_get_params(tr.local_track, E->get()); + StringName method = a->method_track_get_name(tr.local_track, F->get()); + Vector<Variant> args = a->method_track_get_params(tr.local_track, F->get()); args.resize(VARIANT_ARG_MAX); tr.track->object->call(method, args[0], args[1], args[2], args[3], args[4]); } diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h index 12e514f7d5..9ec6325969 100644 --- a/scene/animation/animation_tree_player.h +++ b/scene/animation/animation_tree_player.h @@ -109,6 +109,14 @@ private: Variant value; bool skip; + + Track() : + id(0), + object(NULL), + spatial(NULL), + skeleton(NULL), + bone_idx(-1), + skip(false) {} }; typedef Map<TrackKey, Track> TrackMap; diff --git a/scene/audio/audio_player.cpp b/scene/audio/audio_stream_player.cpp index 4eae3b04e7..2688041d18 100644 --- a/scene/audio/audio_player.cpp +++ b/scene/audio/audio_stream_player.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* audio_player.cpp */ +/* audio_stream_player.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "audio_player.h" +#include "audio_stream_player.h" #include "core/engine.h" @@ -91,13 +91,19 @@ void AudioStreamPlayer::_mix_internal(bool p_fadeout) { void AudioStreamPlayer::_mix_audio() { - if (!stream_playback.is_valid() || !active) + if (!stream_playback.is_valid() || !active || + (stream_paused && !stream_fade)) { return; + } - if (stream_paused) { - if (stream_paused_fade) { - _mix_internal(true); - stream_paused_fade = false; + if (stream_fade) { + _mix_internal(true); + stream_fade = false; + + if (stream_stop) { + stream_playback->stop(); + active = false; + set_process_internal(false); } return; } @@ -203,6 +209,7 @@ void AudioStreamPlayer::play(float p_from_pos) { if (stream_playback.is_valid()) { //mix_volume_db = volume_db; do not reset volume ramp here, can cause clicks + stream_stop = false; setseek = p_from_pos; active = true; set_process_internal(true); @@ -219,9 +226,8 @@ void AudioStreamPlayer::seek(float p_seconds) { void AudioStreamPlayer::stop() { if (stream_playback.is_valid()) { - stream_playback->stop(); - active = false; - set_process_internal(false); + stream_stop = true; + stream_fade = true; } } @@ -295,7 +301,7 @@ void AudioStreamPlayer::set_stream_paused(bool p_pause) { if (p_pause != stream_paused) { stream_paused = p_pause; - stream_paused_fade = p_pause ? true : false; + stream_fade = p_pause ? true : false; } } @@ -385,7 +391,8 @@ AudioStreamPlayer::AudioStreamPlayer() { setseek = -1; active = false; stream_paused = false; - stream_paused_fade = false; + stream_fade = false; + stream_stop = false; mix_target = MIX_TARGET_STEREO; AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); diff --git a/scene/audio/audio_player.h b/scene/audio/audio_stream_player.h index 2e9526c335..fba8ce7dd3 100644 --- a/scene/audio/audio_player.h +++ b/scene/audio/audio_stream_player.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* audio_player.h */ +/* audio_stream_player.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIOPLAYER_H -#define AUDIOPLAYER_H +#ifndef AUDIO_STREAM_PLAYER_H +#define AUDIO_STREAM_PLAYER_H #include "scene/main/node.h" #include "servers/audio/audio_stream.h" @@ -58,7 +58,8 @@ private: float volume_db; bool autoplay; bool stream_paused; - bool stream_paused_fade; + bool stream_fade; + bool stream_stop; StringName bus; MixTarget mix_target; @@ -110,4 +111,5 @@ public: }; VARIANT_ENUM_CAST(AudioStreamPlayer::MixTarget) -#endif // AUDIOPLAYER_H + +#endif // AUDIO_STREAM_PLAYER_H diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index b77b57ddd4..c734136895 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -140,8 +140,8 @@ void Button::_notification(int p_what) { if (has_focus()) { - Ref<StyleBox> style = get_stylebox("focus"); - style->draw(ci, Rect2(Point2(), size)); + Ref<StyleBox> style2 = get_stylebox("focus"); + style2->draw(ci, Rect2(Point2(), size)); } Ref<Font> font = get_font("font"); diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 4b1c7b3db7..7aca6acd00 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -737,7 +737,7 @@ ColorPicker::ColorPicker() : bt_add_preset = memnew(Button); bbc->add_child(bt_add_preset); - bt_add_preset->set_tooltip(TTR("Add current color as a preset")); + bt_add_preset->set_tooltip(TTR("Add current color as a preset.")); bt_add_preset->connect("pressed", this, "_add_preset_pressed"); } diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index 2579321773..7f1ca58d58 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -169,6 +169,19 @@ void Container::_notification(int p_what) { } } +String Container::get_configuration_warning() const { + + String warning = Control::get_configuration_warning(); + + if (get_class() == "Container" && get_script().is_null()) { + if (warning != String()) { + warning += "\n"; + } + warning += TTR("Container by itself serves no purpose unless a script configures it's children placement behavior.\nIf you dont't intend to add a script, then please use a plain 'Control' node instead."); + } + return warning; +} + void Container::_bind_methods() { ClassDB::bind_method(D_METHOD("_sort_children"), &Container::_sort_children); diff --git a/scene/gui/container.h b/scene/gui/container.h index 0b014137f4..80d3f6ee5d 100644 --- a/scene/gui/container.h +++ b/scene/gui/container.h @@ -57,6 +57,8 @@ public: void fit_child_in_rect(Control *p_child, const Rect2 &p_rect); + virtual String get_configuration_warning() const; + Container(); }; diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 513befb8f3..86894ce070 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -206,65 +206,62 @@ bool Control::_set(const StringName &p_name, const Variant &p_value) { if (name.begins_with("custom_icons/")) { String dname = name.get_slicec('/', 1); + if (data.icon_override.has(dname)) { + data.icon_override[dname]->disconnect("changed", this, "_override_changed"); + } data.icon_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - update(); } else if (name.begins_with("custom_shaders/")) { String dname = name.get_slicec('/', 1); + if (data.shader_override.has(dname)) { + data.shader_override[dname]->disconnect("changed", this, "_override_changed"); + } data.shader_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - update(); } else if (name.begins_with("custom_styles/")) { String dname = name.get_slicec('/', 1); + if (data.style_override.has(dname)) { + data.style_override[dname]->disconnect("changed", this, "_override_changed"); + } data.style_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - update(); } else if (name.begins_with("custom_fonts/")) { String dname = name.get_slicec('/', 1); if (data.font_override.has(dname)) { - _unref_font(data.font_override[dname]); + data.font_override[dname]->disconnect("changed", this, "_override_changed"); } data.font_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - update(); } else if (name.begins_with("custom_colors/")) { String dname = name.get_slicec('/', 1); data.color_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - update(); } else if (name.begins_with("custom_constants/")) { String dname = name.get_slicec('/', 1); data.constant_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - update(); } else return false; } else { if (name.begins_with("custom_icons/")) { String dname = name.get_slicec('/', 1); - notification(NOTIFICATION_THEME_CHANGED); add_icon_override(dname, p_value); } else if (name.begins_with("custom_shaders/")) { String dname = name.get_slicec('/', 1); add_shader_override(dname, p_value); - notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("custom_styles/")) { String dname = name.get_slicec('/', 1); add_style_override(dname, p_value); - notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("custom_fonts/")) { String dname = name.get_slicec('/', 1); add_font_override(dname, p_value); - notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("custom_colors/")) { String dname = name.get_slicec('/', 1); add_color_override(dname, p_value); - notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("custom_constants/")) { String dname = name.get_slicec('/', 1); add_constant_override(dname, p_value); - notification(NOTIFICATION_THEME_CHANGED); } else return false; } @@ -1800,51 +1797,63 @@ Rect2 Control::get_anchorable_rect() const { void Control::add_icon_override(const StringName &p_name, const Ref<Texture> &p_icon) { ERR_FAIL_COND(p_icon.is_null()); + if (data.icon_override.has(p_name)) { + data.icon_override[p_name]->disconnect("changed", this, "_override_changed"); + } data.icon_override[p_name] = p_icon; + if (data.icon_override[p_name].is_valid()) { + data.icon_override[p_name]->connect("changed", this, "_override_changed", Vector<Variant>(), CONNECT_REFERENCE_COUNTED); + } notification(NOTIFICATION_THEME_CHANGED); - update(); } void Control::add_shader_override(const StringName &p_name, const Ref<Shader> &p_shader) { ERR_FAIL_COND(p_shader.is_null()); + if (data.shader_override.has(p_name)) { + data.shader_override[p_name]->disconnect("changed", this, "_override_changed"); + } data.shader_override[p_name] = p_shader; + if (data.shader_override[p_name].is_valid()) { + data.shader_override[p_name]->connect("changed", this, "_override_changed", Vector<Variant>(), CONNECT_REFERENCE_COUNTED); + } notification(NOTIFICATION_THEME_CHANGED); - update(); } void Control::add_style_override(const StringName &p_name, const Ref<StyleBox> &p_style) { ERR_FAIL_COND(p_style.is_null()); + if (data.style_override.has(p_name)) { + data.style_override[p_name]->disconnect("changed", this, "_override_changed"); + } data.style_override[p_name] = p_style; + if (data.style_override[p_name].is_valid()) { + data.style_override[p_name]->connect("changed", this, "_override_changed", Vector<Variant>(), CONNECT_REFERENCE_COUNTED); + } + notification(NOTIFICATION_THEME_CHANGED); - update(); } void Control::add_font_override(const StringName &p_name, const Ref<Font> &p_font) { ERR_FAIL_COND(p_font.is_null()); if (data.font_override.has(p_name)) { - _unref_font(data.font_override[p_name]); + data.font_override[p_name]->disconnect("changed", this, "_override_changed"); } data.font_override[p_name] = p_font; - - if (p_font.is_valid()) { - _ref_font(p_font); + if (data.font_override[p_name].is_valid()) { + data.font_override[p_name]->connect("changed", this, "_override_changed", Vector<Variant>(), CONNECT_REFERENCE_COUNTED); } notification(NOTIFICATION_THEME_CHANGED); - update(); } void Control::add_color_override(const StringName &p_name, const Color &p_color) { data.color_override[p_name] = p_color; notification(NOTIFICATION_THEME_CHANGED); - update(); } void Control::add_constant_override(const StringName &p_name, int p_constant) { data.constant_override[p_name] = p_constant; notification(NOTIFICATION_THEME_CHANGED); - update(); } void Control::set_focus_mode(FocusMode p_focus_mode) { @@ -2143,7 +2152,6 @@ void Control::_propagate_theme_changed(CanvasItem *p_at, Control *p_owner, bool c->data.theme_owner = p_owner; } c->notification(NOTIFICATION_THEME_CHANGED); - c->update(); } } @@ -2550,32 +2558,10 @@ float Control::get_rotation_degrees() const { return Math::rad2deg(get_rotation()); } -//needed to update the control if the font changes.. -void Control::_ref_font(Ref<Font> p_sc) { +void Control::_override_changed() { - if (!data.font_refcount.has(p_sc)) { - data.font_refcount[p_sc] = 1; - p_sc->connect("changed", this, "_font_changed"); - } else { - data.font_refcount[p_sc] += 1; - } -} - -void Control::_unref_font(Ref<Font> p_sc) { - - ERR_FAIL_COND(!data.font_refcount.has(p_sc)); - data.font_refcount[p_sc]--; - if (data.font_refcount[p_sc] == 0) { - p_sc->disconnect("changed", this, "_font_changed"); - data.font_refcount.erase(p_sc); - } -} - -void Control::_font_changed() { - - update(); notification(NOTIFICATION_THEME_CHANGED); - minimum_size_changed(); //fonts affect minimum size pretty much almost always + minimum_size_changed(); // overrides are likely to affect minimum size } void Control::set_pivot_offset(const Vector2 &p_pivot) { @@ -2735,7 +2721,7 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("get_scale"), &Control::get_scale); ClassDB::bind_method(D_METHOD("get_pivot_offset"), &Control::get_pivot_offset); ClassDB::bind_method(D_METHOD("get_custom_minimum_size"), &Control::get_custom_minimum_size); - ClassDB::bind_method(D_METHOD("get_parent_area_size"), &Control::get_size); + ClassDB::bind_method(D_METHOD("get_parent_area_size"), &Control::get_parent_area_size); ClassDB::bind_method(D_METHOD("get_global_position"), &Control::get_global_position); ClassDB::bind_method(D_METHOD("get_rect"), &Control::get_rect); ClassDB::bind_method(D_METHOD("get_global_rect"), &Control::get_global_rect); @@ -2829,7 +2815,7 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("_theme_changed"), &Control::_theme_changed); - ClassDB::bind_method(D_METHOD("_font_changed"), &Control::_font_changed); + ClassDB::bind_method(D_METHOD("_override_changed"), &Control::_override_changed); BIND_VMETHOD(MethodInfo("_gui_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); BIND_VMETHOD(MethodInfo(Variant::VECTOR2, "_get_minimum_size")); diff --git a/scene/gui/control.h b/scene/gui/control.h index 0812457bd2..5e33f6ba43 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -207,7 +207,6 @@ private: HashMap<StringName, Ref<Font> > font_override; HashMap<StringName, Color> color_override; HashMap<StringName, int> constant_override; - Map<Ref<Font>, int> font_refcount; } data; @@ -234,9 +233,7 @@ private: void _size_changed(); String _get_tooltip() const; - void _ref_font(Ref<Font> p_sc); - void _unref_font(Ref<Font> p_sc); - void _font_changed(); + void _override_changed(); void _update_canvas_item_transform(); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 5599c64daa..059e59ea21 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -861,7 +861,7 @@ FileDialog::FileDialog() { HBoxContainer *hbc = memnew(HBoxContainer); dir_up = memnew(ToolButton); - dir_up->set_tooltip(RTR("Go to parent folder")); + dir_up->set_tooltip(RTR("Go to parent folder.")); hbc->add_child(dir_up); dir_up->connect("pressed", this, "_go_up"); @@ -871,6 +871,7 @@ FileDialog::FileDialog() { dir->set_h_size_flags(SIZE_EXPAND_FILL); refresh = memnew(ToolButton); + refresh->set_tooltip(RTR("Refresh")); refresh->connect("pressed", this, "_update_file_list"); hbc->add_child(refresh); diff --git a/scene/gui/gradient_edit.h b/scene/gui/gradient_edit.h index fd340b3f6c..662278a17b 100644 --- a/scene/gui/gradient_edit.h +++ b/scene/gui/gradient_edit.h @@ -33,8 +33,8 @@ #include "scene/gui/color_picker.h" #include "scene/gui/popup.h" -#include "scene/resources/color_ramp.h" #include "scene/resources/default_theme/theme_data.h" +#include "scene/resources/gradient.h" #define POINT_WIDTH (8 * EDSCALE) diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 94c65b3e64..68e734502b 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -221,8 +221,8 @@ void GraphEdit::_graph_node_raised(Node *p_gn) { } int first_not_comment = 0; for (int i = 0; i < get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); - if (gn && !gn->is_comment()) { + GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); + if (gn2 && !gn2->is_comment()) { first_not_comment = i; break; } @@ -261,8 +261,9 @@ void GraphEdit::add_child_notify(Node *p_child) { void GraphEdit::remove_child_notify(Node *p_child) { Control::remove_child_notify(p_child); - - top_layer->call_deferred("raise"); //top layer always on top! + if (is_inside_tree()) { + top_layer->call_deferred("raise"); //top layer always on top! + } GraphNode *gn = Object::cast_to<GraphNode>(p_child); if (gn) { gn->disconnect("offset_changed", this, "_graph_node_moved"); @@ -958,33 +959,33 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { - GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); - if (!gn || !gn->is_selected()) + GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); + if (!gn2 || !gn2->is_selected()) continue; - previus_selected.push_back(gn); + previus_selected.push_back(gn2); } } else if (b->get_shift()) { box_selection_mode_aditive = false; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { - GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); - if (!gn || !gn->is_selected()) + GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); + if (!gn2 || !gn2->is_selected()) continue; - previus_selected.push_back(gn); + previus_selected.push_back(gn2); } } else { box_selection_mode_aditive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { - GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); - if (!gn) + GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); + if (!gn2) continue; - gn->set_selected(false); + gn2->set_selected(false); } } } diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 8c588109d6..e8692d56d2 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -164,7 +164,6 @@ void GraphNode::_resort() { vofs += size.y; } - _change_notify(); update(); connpos_dirty = true; } @@ -409,9 +408,12 @@ Size2 GraphNode::get_minimum_size() const { void GraphNode::set_title(const String &p_title) { + if (title == p_title) + return; title = p_title; - minimum_size_changed(); update(); + _change_notify("title"); + minimum_size_changed(); } String GraphNode::get_title() const { diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index efe452305b..026374ded1 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -1094,7 +1094,7 @@ void ItemList::_notification(int p_what) { if (items[i].disabled) modulate.a *= 0.5; - // If the icon is transposed, we have to swith the size so that it is drawn correctly + // If the icon is transposed, we have to switch the size so that it is drawn correctly if (items[i].icon_transposed) { Size2 size_tmp = draw_rect.size; draw_rect.size.x = size_tmp.y; @@ -1114,13 +1114,13 @@ void ItemList::_notification(int p_what) { int max_len = -1; - Vector2 size = font->get_string_size(items[i].text); + Vector2 size2 = font->get_string_size(items[i].text); if (fixed_column_width) max_len = fixed_column_width; else if (same_column_width) max_len = items[i].rect_cache.size.x; else - max_len = size.x; + max_len = size2.x; Color modulate = items[i].selected ? font_color_selected : (items[i].custom_fg != Color() ? items[i].custom_fg : font_color); if (items[i].disabled) @@ -1170,12 +1170,12 @@ void ItemList::_notification(int p_what) { } else { if (fixed_column_width > 0) - size.x = MIN(size.x, fixed_column_width); + size2.x = MIN(size2.x, fixed_column_width); if (icon_mode == ICON_MODE_TOP) { - text_ofs.x += (items[i].rect_cache.size.width - size.x) / 2; + text_ofs.x += (items[i].rect_cache.size.width - size2.x) / 2; } else { - text_ofs.y += (items[i].rect_cache.size.height - size.y) / 2; + text_ofs.y += (items[i].rect_cache.size.height - size2.y) / 2; } text_ofs.y += font->get_ascent(); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 4a2bb3dad1..bf6833e512 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -1154,9 +1154,7 @@ void LineEdit::set_cursor_position(int p_pos) { if (cursor_pos <= window_pos) { /* Adjust window if cursor goes too much to the left */ - if (window_pos > 0) - set_window_pos(window_pos - 1); - + set_window_pos(MAX(0, cursor_pos - 1)); } else if (cursor_pos > window_pos) { /* Adjust window if cursor goes too much to the right */ int window_width = get_size().width - style->get_minimum_size().width; diff --git a/scene/gui/link_button.h b/scene/gui/link_button.h index ffe248ac5e..17c4bca67b 100644 --- a/scene/gui/link_button.h +++ b/scene/gui/link_button.h @@ -32,7 +32,7 @@ #define LINKBUTTON_H #include "scene/gui/base_button.h" -#include "scene/resources/bit_mask.h" +#include "scene/resources/bit_map.h" class LinkButton : public BaseButton { diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 98f427cc07..b9b270ce0c 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -160,6 +160,12 @@ int OptionButton::get_item_id(int p_idx) const { return popup->get_item_id(p_idx); } + +int OptionButton::get_item_index(int p_id) const { + + return popup->get_item_index(p_id); +} + Variant OptionButton::get_item_metadata(int p_idx) const { return popup->get_item_metadata(p_idx); @@ -306,6 +312,7 @@ void OptionButton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_text", "idx"), &OptionButton::get_item_text); ClassDB::bind_method(D_METHOD("get_item_icon", "idx"), &OptionButton::get_item_icon); ClassDB::bind_method(D_METHOD("get_item_id", "idx"), &OptionButton::get_item_id); + ClassDB::bind_method(D_METHOD("get_item_index", "id"), &OptionButton::get_item_index); ClassDB::bind_method(D_METHOD("get_item_metadata", "idx"), &OptionButton::get_item_metadata); ClassDB::bind_method(D_METHOD("is_item_disabled", "idx"), &OptionButton::is_item_disabled); ClassDB::bind_method(D_METHOD("get_item_count"), &OptionButton::get_item_count); diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h index 121b4c002d..63b451377a 100644 --- a/scene/gui/option_button.h +++ b/scene/gui/option_button.h @@ -71,6 +71,7 @@ public: String get_item_text(int p_idx) const; Ref<Texture> get_item_icon(int p_idx) const; int get_item_id(int p_idx) const; + int get_item_index(int p_id) const; Variant get_item_metadata(int p_idx) const; bool is_item_disabled(int p_idx) const; diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index 2d2c54594a..80ec7049fc 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -124,49 +124,22 @@ void Popup::popup_centered_minsize(const Size2 &p_minsize) { void Popup::popup_centered(const Size2 &p_size) { - Point2 window_size = get_viewport_rect().size; - - emit_signal("about_to_show"); Rect2 rect; + Size2 window_size = get_viewport_rect().size; rect.size = p_size == Size2() ? get_size() : p_size; - rect.position = ((window_size - rect.size) / 2.0).floor(); - set_position(rect.position); - set_size(rect.size); - - show_modal(exclusive); - _fix_size(); - Control *focusable = find_next_valid_focus(); - if (focusable) - focusable->grab_focus(); - - _post_popup(); - notification(NOTIFICATION_POST_POPUP); - popped_up = true; + popup(rect); } void Popup::popup_centered_ratio(float p_screen_ratio) { - emit_signal("about_to_show"); - Rect2 rect; - Point2 window_size = get_viewport_rect().size; + Size2 window_size = get_viewport_rect().size; rect.size = (window_size * p_screen_ratio).floor(); rect.position = ((window_size - rect.size) / 2.0).floor(); - set_position(rect.position); - set_size(rect.size); - show_modal(exclusive); - _fix_size(); - - Control *focusable = find_next_valid_focus(); - if (focusable) - focusable->grab_focus(); - - _post_popup(); - notification(NOTIFICATION_POST_POPUP); - popped_up = true; + popup(rect); } void Popup::popup(const Rect2 &p_bounds) { diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index ac94ac63ec..28b124d143 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -519,9 +519,9 @@ void PopupMenu::_notification(int p_what) { if (items[i].accel || (items[i].shortcut.is_valid() && items[i].shortcut->is_valid())) { //accelerator - String text = _get_accel_text(i); - item_ofs.x = size.width - style->get_margin(MARGIN_RIGHT) - font->get_string_size(text).width; - font->draw(ci, item_ofs + Point2(0, Math::floor((h - font_h) / 2.0)), text, i == mouse_over ? font_color_hover : font_color_accel); + String text2 = _get_accel_text(i); + item_ofs.x = size.width - style->get_margin(MARGIN_RIGHT) - font->get_string_size(text2).width; + font->draw(ci, item_ofs + Point2(0, Math::floor((h - font_h) / 2.0)), text2, i == mouse_over ? font_color_hover : font_color_accel); } items.write[i]._ofs_cache = ofs.y; diff --git a/scene/gui/progress_bar.cpp b/scene/gui/progress_bar.cpp index 2195ec9778..264eda4035 100644 --- a/scene/gui/progress_bar.cpp +++ b/scene/gui/progress_bar.cpp @@ -39,9 +39,12 @@ Size2 ProgressBar::get_minimum_size() const { Size2 minimum_size = bg->get_minimum_size(); minimum_size.height = MAX(minimum_size.height, fg->get_minimum_size().height); minimum_size.width = MAX(minimum_size.width, fg->get_minimum_size().width); - //if (percent_visible) { this is needed, else the progressbar will collapse - minimum_size.height = MAX(minimum_size.height, bg->get_minimum_size().height + font->get_height()); - //} + if (percent_visible) { + minimum_size.height = MAX(minimum_size.height, bg->get_minimum_size().height + font->get_height()); + } else { // this is needed, else the progressbar will collapse + minimum_size.width = MAX(minimum_size.width, 1); + minimum_size.height = MAX(minimum_size.height, 1); + } return minimum_size; } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 2e466fd582..8968923b2c 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -544,7 +544,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & Vector2 draw_ofs = Point2(wofs, y); Color font_color_shadow = get_color("font_color_shadow"); bool use_outline = get_constant("shadow_as_outline"); - Point2 shadow_ofs(get_constant("shadow_offset_x"), get_constant("shadow_offset_y")); + Point2 shadow_ofs2(get_constant("shadow_offset_x"), get_constant("shadow_offset_y")); if (p_mode == PROCESS_CACHE) { @@ -568,7 +568,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & for (int i = 0; i < frame->lines.size(); i++) { - _process_line(frame, Point2(), ly, available_width, i, PROCESS_CACHE, cfont, Color(), font_color_shadow, use_outline, shadow_ofs); + _process_line(frame, Point2(), ly, available_width, i, PROCESS_CACHE, cfont, Color(), font_color_shadow, use_outline, shadow_ofs2); table->columns.write[column].min_width = MAX(table->columns[column].min_width, frame->lines[i].minimum_width); table->columns.write[column].max_width = MAX(table->columns[column].max_width, frame->lines[i].maximum_width); } @@ -641,7 +641,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & for (int i = 0; i < frame->lines.size(); i++) { int ly = 0; - _process_line(frame, Point2(), ly, table->columns[column].width, i, PROCESS_CACHE, cfont, Color(), font_color_shadow, use_outline, shadow_ofs); + _process_line(frame, Point2(), ly, table->columns[column].width, i, PROCESS_CACHE, cfont, Color(), font_color_shadow, use_outline, shadow_ofs2); frame->lines.write[i].height_cache = ly; //actual height frame->lines.write[i].height_accum_cache = ly; //actual height } @@ -674,9 +674,9 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & if (visible) { if (p_mode == PROCESS_DRAW) { - nonblank_line_count += _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_DRAW, cfont, ccolor, font_color_shadow, use_outline, shadow_ofs); + nonblank_line_count += _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_DRAW, cfont, ccolor, font_color_shadow, use_outline, shadow_ofs2); } else if (p_mode == PROCESS_POINTER) { - _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_POINTER, cfont, ccolor, font_color_shadow, use_outline, shadow_ofs, p_click_pos, r_click_item, r_click_char, r_outside); + _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_POINTER, cfont, ccolor, font_color_shadow, use_outline, shadow_ofs2, p_click_pos, r_click_item, r_click_char, r_outside); if (r_click_item && *r_click_item) { RETURN; // exit early } @@ -900,21 +900,13 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item Control::CursorShape RichTextLabel::get_cursor_shape(const Point2 &p_pos) const { - if (!underline_meta || selection.click) + if (selection.click) return CURSOR_ARROW; if (main->first_invalid_line < main->lines.size()) return CURSOR_ARROW; //invalid - int line = 0; - Item *item = NULL; - - ((RichTextLabel *)(this))->_find_click(main, p_pos, &item, &line); - - if (item && ((RichTextLabel *)(this))->_find_meta(item, NULL)) - return CURSOR_POINTING_HAND; - - return CURSOR_ARROW; + return get_default_cursor_shape(); } void RichTextLabel::_gui_input(Ref<InputEvent> p_event) { @@ -1133,12 +1125,13 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) { } Variant meta; - if (item && !outside && _find_meta(item, &meta)) { - if (meta_hovering != item) { + ItemMeta *item_meta; + if (item && !outside && _find_meta(item, &meta, &item_meta)) { + if (meta_hovering != item_meta) { if (meta_hovering) { emit_signal("meta_hover_ended", current_meta); } - meta_hovering = static_cast<ItemMeta *>(item); + meta_hovering = item_meta; current_meta = meta; emit_signal("meta_hover_started", meta); } @@ -1269,7 +1262,7 @@ bool RichTextLabel::_find_strikethrough(Item *p_item) { return false; } -bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta) { +bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item) { Item *item = p_item; @@ -1280,6 +1273,8 @@ bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta) { ItemMeta *meta = static_cast<ItemMeta *>(item); if (r_meta) *r_meta = meta->meta; + if (r_item) + *r_item = meta; return true; } diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index bec2c5ac02..114c6103e2 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -285,7 +285,7 @@ private: Color _find_color(Item *p_item, const Color &p_default_color); bool _find_underline(Item *p_item); bool _find_strikethrough(Item *p_item); - bool _find_meta(Item *p_item, Variant *r_meta); + bool _find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item = NULL); void _update_scroll(); void _scroll_changed(double); diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 28292309b9..e50a71b0ff 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -368,8 +368,10 @@ void ScrollContainer::update_scrollbars() { Ref<StyleBox> sb = get_stylebox("bg"); size -= sb->get_minimum_size(); - Size2 hmin = h_scroll->get_combined_minimum_size(); - Size2 vmin = v_scroll->get_combined_minimum_size(); + Size2 hmin; + Size2 vmin; + if (scroll_h) hmin = h_scroll->get_combined_minimum_size(); + if (scroll_v) vmin = v_scroll->get_combined_minimum_size(); Size2 min = child_max_size; diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index d6a93238b2..e5d1844d39 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -164,34 +164,31 @@ void SplitContainer::_notification(int p_what) { _resort(); } break; - case NOTIFICATION_MOUSE_ENTER: { - - mouse_inside = true; - update(); - } break; case NOTIFICATION_MOUSE_EXIT: { mouse_inside = false; - update(); + if (get_constant("autohide")) + update(); } break; case NOTIFICATION_DRAW: { if (!_getch(0) || !_getch(1)) return; - if (collapsed || (!mouse_inside && get_constant("autohide"))) + if (collapsed || (!dragging && !mouse_inside && get_constant("autohide"))) + return; + + if (dragger_visibility != DRAGGER_VISIBLE) return; int sep = dragger_visibility != DRAGGER_HIDDEN_COLLAPSED ? get_constant("separation") : 0; Ref<Texture> tex = get_icon("grabber"); Size2 size = get_size(); - if (dragger_visibility == DRAGGER_VISIBLE) { - if (vertical) - draw_texture(tex, Point2i((size.x - tex->get_width()) / 2, middle_sep + (sep - tex->get_height()) / 2)); - else - draw_texture(tex, Point2i(middle_sep + (sep - tex->get_width()) / 2, (size.y - tex->get_height()) / 2)); - } + if (vertical) + draw_texture(tex, Point2i((size.x - tex->get_width()) / 2, middle_sep + (sep - tex->get_height()) / 2)); + else + draw_texture(tex, Point2i(middle_sep + (sep - tex->get_width()) / 2, (size.y - tex->get_height()) / 2)); } break; case NOTIFICATION_THEME_CHANGED: { @@ -241,7 +238,23 @@ void SplitContainer::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> mm = p_event; - if (mm.is_valid() && dragging) { + if (mm.is_valid()) { + + bool mouse_inside_state = false; + if (vertical) + mouse_inside_state = mm->get_position().y > middle_sep && mm->get_position().y < middle_sep + get_constant("separation"); + else + mouse_inside_state = mm->get_position().x > middle_sep && mm->get_position().x < middle_sep + get_constant("separation"); + + if (mouse_inside != mouse_inside_state) { + + mouse_inside = mouse_inside_state; + if (get_constant("autohide")) + update(); + } + + if (!dragging) + return; split_offset = drag_ofs + ((vertical ? mm->get_position().y : mm->get_position().x) - drag_from); should_clamp_split_offset = true; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 09fbb39866..2bf2364873 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -666,7 +666,7 @@ void TextEdit::_notification(int p_what) { bool brace_close_matching = false; bool brace_close_mismatch = false; - if (brace_matching_enabled) { + if (brace_matching_enabled && cursor.line >= 0 && cursor.line < text.size() && cursor.column >= 0) { if (cursor.column < text[cursor.line].length()) { //check for open @@ -861,6 +861,9 @@ void TextEdit::_notification(int p_what) { const String &str = wrap_rows[line_wrap_index]; int indent_px = line_wrap_index != 0 ? get_indent_level(line) * cache.font->get_char_size(' ').width : 0; + if (indent_px >= wrap_at) { + indent_px = 0; + } if (line_wrap_index > 0) last_wrap_column += wrap_rows[line_wrap_index - 1].length(); @@ -1381,8 +1384,8 @@ void TextEdit::_notification(int p_what) { } } - Size2 size = Size2(max_w, sc * font->get_height() + spacing); - Size2 minsize = size + sb->get_minimum_size(); + Size2 size2 = Size2(max_w, sc * font->get_height() + spacing); + Size2 minsize = size2 + sb->get_minimum_size(); if (completion_hint_offset == -0xFFFF) { completion_hint_offset = cursor_pos.x - offset; @@ -1714,10 +1717,10 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co col = get_char_pos_for_line(colx, row, wrap_index); if (is_wrap_enabled() && wrap_index < times_line_wraps(row)) { // move back one if we are at the end of the row - Vector<String> rows = get_wrap_rows_text(row); + Vector<String> rows2 = get_wrap_rows_text(row); int row_end_col = 0; for (int i = 0; i < wrap_index + 1; i++) { - row_end_col += rows[i].length(); + row_end_col += rows2[i].length(); } if (col >= row_end_col) col -= 1; @@ -2202,10 +2205,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { bool had_selection = selection.active; // stuff to do when selection is active.. - if (selection.active) { - - if (readonly) - return; + if (!readonly && selection.active) { bool clear = false; bool unselect = false; @@ -2645,24 +2645,26 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } case KEY_UP: { - if (k->get_shift()) - _pre_shift_selection(); if (k->get_alt()) { scancode_handled = false; break; } #ifndef APPLE_STYLE_KEYS if (k->get_command()) { - _scroll_lines_up(); - break; - } #else if (k->get_command() && k->get_alt()) { +#endif _scroll_lines_up(); break; } + if (k->get_shift()) { + _pre_shift_selection(); + } + +#ifdef APPLE_STYLE_KEYS if (k->get_command()) { + cursor_set_line(0); } else #endif @@ -2696,24 +2698,24 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } case KEY_DOWN: { - if (k->get_shift()) - _pre_shift_selection(); if (k->get_alt()) { scancode_handled = false; break; } #ifndef APPLE_STYLE_KEYS if (k->get_command()) { - _scroll_lines_down(); - break; - } - #else if (k->get_command() && k->get_alt()) { +#endif _scroll_lines_down(); break; } + if (k->get_shift()) { + _pre_shift_selection(); + } + +#ifdef APPLE_STYLE_KEYS if (k->get_command()) { cursor_set_line(get_last_unhidden_line(), true, false, 9999); } else @@ -3373,20 +3375,20 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i String preinsert_text = text[p_line].substr(0, p_char); String postinsert_text = text[p_line].substr(p_char, text[p_line].size()); - for (int i = 0; i < substrings.size(); i++) { + for (int j = 0; j < substrings.size(); j++) { //insert the substrings - if (i == 0) { + if (j == 0) { - text.set(p_line, preinsert_text + substrings[i]); + text.set(p_line, preinsert_text + substrings[j]); } else { - text.insert(p_line + i, substrings[i]); + text.insert(p_line + j, substrings[j]); } - if (i == substrings.size() - 1) { + if (j == substrings.size() - 1) { - text.set(p_line + i, text[p_line + i] + postinsert_text); + text.set(p_line + j, text[p_line + j] + postinsert_text); } } @@ -3789,6 +3791,9 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const { int cur_wrap_index = 0; int tab_offset_px = get_indent_level(p_line) * cache.font->get_char_size(' ').width; + if (tab_offset_px >= wrap_at) { + tab_offset_px = 0; + } while (col < line_text.length()) { CharType c = line_text[col]; @@ -3796,29 +3801,36 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const { int indent_ofs = (cur_wrap_index != 0 ? tab_offset_px : 0); - word_str += c; - word_px += w; - if (c == ' ') { - // end of a word; add this word to the substring + if (indent_ofs + word_px + w > wrap_at) { + // not enough space to add this char; start next line wrap_substring += word_str; - px += word_px; - word_str = ""; - word_px = 0; - } + lines.push_back(wrap_substring); + cur_wrap_index++; + wrap_substring = ""; + px = 0; - if ((indent_ofs + px + word_px) > wrap_at) { - // do not want to add this word - if (indent_ofs + word_px > wrap_at) { - // not enough space; add it anyway + word_str = ""; + word_str += c; + word_px = w; + } else { + word_str += c; + word_px += w; + if (c == ' ') { + // end of a word; add this word to the substring wrap_substring += word_str; + px += word_px; word_str = ""; word_px = 0; } - lines.push_back(wrap_substring); - // reset for next wrap - cur_wrap_index++; - wrap_substring = ""; - px = 0; + + if (indent_ofs + px + word_px > wrap_at) { + // this word will be moved to the next line + lines.push_back(wrap_substring); + // reset for next wrap + cur_wrap_index++; + wrap_substring = ""; + px = 0; + } } col++; } @@ -4031,6 +4043,9 @@ int TextEdit::get_char_pos_for_line(int p_px, int p_line, int p_wrap_index) cons int line_wrap_amount = times_line_wraps(p_line); int wrap_offset_px = get_indent_level(p_line) * cache.font->get_char_size(' ').width; + if (wrap_offset_px >= wrap_at) { + wrap_offset_px = 0; + } if (p_wrap_index > line_wrap_amount) p_wrap_index = line_wrap_amount; if (p_wrap_index > 0) @@ -4072,6 +4087,9 @@ int TextEdit::get_column_x_offset_for_line(int p_char, int p_line) const { int px = get_column_x_offset(n_char, rows[wrap_index]); int wrap_offset_px = get_indent_level(p_line) * cache.font->get_char_size(' ').width; + if (wrap_offset_px >= wrap_at) { + wrap_offset_px = 0; + } if (wrap_index != 0) px += wrap_offset_px; diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index 95aab95253..19bef9fdf5 100644 --- a/scene/gui/texture_button.cpp +++ b/scene/gui/texture_button.cpp @@ -64,7 +64,9 @@ bool TextureButton::has_point(const Point2 &p_point) const { Rect2 rect = Rect2(); Size2 mask_size = click_mask->get_size(); - if (_tile) { + if (_position_rect.no_area()) { + rect.size = mask_size; + } else if (_tile) { // if the stretch mode is tile we offset the point to keep it inside the mask size rect.size = mask_size; if (_position_rect.has_point(point)) { @@ -206,8 +208,8 @@ void TextureButton::_notification(int p_what) { Size2 scaleSize(size.width / tex_size.width, size.height / tex_size.height); float scale = scaleSize.width > scaleSize.height ? scaleSize.width : scaleSize.height; Size2 scaledTexSize = tex_size * scale; - Point2 ofs = ((scaledTexSize - size) / scale).abs() / 2.0f; - _texture_region = Rect2(ofs, size / scale); + Point2 ofs2 = ((scaledTexSize - size) / scale).abs() / 2.0f; + _texture_region = Rect2(ofs2, size / scale); } break; } } @@ -216,6 +218,8 @@ void TextureButton::_notification(int p_what) { draw_texture_rect(texdraw, _position_rect, _tile); else draw_texture_rect_region(texdraw, _position_rect, _texture_region); + } else { + _position_rect = Rect2(); } if (has_focus() && focused.is_valid()) { diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h index 4dc0de5358..d9224de686 100644 --- a/scene/gui/texture_button.h +++ b/scene/gui/texture_button.h @@ -32,7 +32,7 @@ #define TEXTURE_BUTTON_H #include "scene/gui/base_button.h" -#include "scene/resources/bit_mask.h" +#include "scene/resources/bit_map.h" class TextureButton : public BaseButton { GDCLASS(TextureButton, BaseButton); diff --git a/scene/gui/texture_progress.cpp b/scene/gui/texture_progress.cpp index 778d86d546..c534df5cbe 100644 --- a/scene/gui/texture_progress.cpp +++ b/scene/gui/texture_progress.cpp @@ -160,23 +160,27 @@ Point2 TextureProgress::unit_val_to_uv(float val) { if (edge == 0) { if (dir.x > 0) continue; - cp = -dir.x; cq = -(edgeLeft - p.x); + dir.x *= 2.0 * cq; + cp = -dir.x; } else if (edge == 1) { if (dir.x < 0) continue; - cp = dir.x; cq = (edgeRight - p.x); + dir.x *= 2.0 * cq; + cp = dir.x; } else if (edge == 2) { if (dir.y > 0) continue; - cp = -dir.y; cq = -(edgeBottom - p.y); + dir.y *= 2.0 * cq; + cp = -dir.y; } else if (edge == 3) { if (dir.y < 0) continue; - cp = dir.y; cq = (edgeTop - p.y); + dir.y *= 2.0 * cq; + cp = dir.y; } cr = cq / cp; if (cr >= 0 && cr < t1) @@ -247,12 +251,14 @@ void TextureProgress::draw_nine_patch_stretched(const Ref<Texture> &p_texture, F middle_section_size *= MIN(1.0, (MAX(0.0, width_filled - first_section_size) / MAX(1.0, width_total - first_section_size - last_section_size))); last_section_size = MAX(0.0, last_section_size - (width_total - width_filled)); + first_section_size = MIN(first_section_size, width_filled); width_texture = MIN(width_texture, first_section_size + middle_section_size + last_section_size); switch (mode) { case FILL_LEFT_TO_RIGHT: { src_rect.size.x = width_texture; dst_rect.size.x = width_filled; + topleft.x = first_section_size; bottomright.x = last_section_size; } break; case FILL_RIGHT_TO_LEFT: { @@ -261,11 +267,13 @@ void TextureProgress::draw_nine_patch_stretched(const Ref<Texture> &p_texture, F dst_rect.position.x += width_total - width_filled; dst_rect.size.x = width_filled; topleft.x = last_section_size; + bottomright.x = first_section_size; } break; case FILL_TOP_TO_BOTTOM: { src_rect.size.y = width_texture; dst_rect.size.y = width_filled; bottomright.y = last_section_size; + topleft.y = first_section_size; } break; case FILL_BOTTOM_TO_TOP: { src_rect.position.y += src_rect.size.y - width_texture; @@ -273,6 +281,7 @@ void TextureProgress::draw_nine_patch_stretched(const Ref<Texture> &p_texture, F dst_rect.position.y += width_total - width_filled; dst_rect.size.y = width_filled; topleft.y = last_section_size; + bottomright.y = first_section_size; } break; case FILL_BILINEAR_LEFT_AND_RIGHT: { // TODO: Implement diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 514be00227..49cad6fccf 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1071,11 +1071,11 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 int font_ascent = font->get_ascent(); int ofs = p_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); - int skip = 0; + int skip2 = 0; for (int i = 0; i < columns.size(); i++) { - if (skip) { - skip--; + if (skip2) { + skip2--; continue; } @@ -1102,7 +1102,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 while (i + plus < columns.size() && !p_item->cells[i + plus].editable && p_item->cells[i + plus].mode == TreeItem::CELL_MODE_STRING && p_item->cells[i + plus].text == "" && p_item->cells[i + plus].icon.is_null()) { w += get_column_width(i + plus); plus++; - skip++; + skip2++; } } @@ -1165,8 +1165,8 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 cache.selected->draw(ci, r); } if (text_editor->is_visible_in_tree()) { - Vector2 ofs(0, (text_editor->get_size().height - r.size.height) / 2); - text_editor->set_position(get_global_position() + r.position - ofs); + Vector2 ofs2(0, (text_editor->get_size().height - r.size.height) / 2); + text_editor->set_position(get_global_position() + r.position - ofs2); } } @@ -1416,12 +1416,15 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 TreeItem *c = p_item->children; + int prev_ofs = children_pos.y - cache.offset.y + p_draw_ofs.y; + while (c) { if (cache.draw_relationship_lines > 0 && (!hide_root || c->parent != root)) { int root_ofs = children_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); int parent_ofs = p_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); Point2i root_pos = Point2i(root_ofs, children_pos.y + label_h / 2) - cache.offset + p_draw_ofs; + if (c->get_children() != NULL) root_pos -= Point2i(cache.arrow->get_width(), 0); @@ -1434,12 +1437,13 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (root_pos.y + line_width >= 0) { VisualServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x - Math::floor(line_width / 2), root_pos.y), cache.relationship_line_color, line_width); - VisualServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y), parent_pos, cache.relationship_line_color, line_width); + VisualServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y), Point2i(parent_pos.x, prev_ofs), cache.relationship_line_color, line_width); } if (htotal < 0) { return -1; } + prev_ofs = root_pos.y; } if (htotal >= 0) { @@ -1601,7 +1605,7 @@ void Tree::_range_click_timeout() { mb.instance(); ; - propagate_mouse_activated = false; //done from outside, so signal handler cant clear the tree in the middle of emit(which is a common case) + propagate_mouse_activated = false; // done from outside, so signal handler can't clear the tree in the middle of emit (which is a common case) blocked++; propagate_mouse_event(pos + cache.offset, 0, 0, false, root, BUTTON_LEFT, mb); blocked--; @@ -2698,8 +2702,8 @@ bool Tree::edit_selected() { popup_menu->clear(); for (int i = 0; i < c.text.get_slice_count(","); i++) { - String s = c.text.get_slicec(',', i); - popup_menu->add_item(s.get_slicec(':', 0), s.get_slicec(':', 1).empty() ? i : s.get_slicec(':', 1).to_int()); + String s2 = c.text.get_slicec(',', i); + popup_menu->add_item(s2.get_slicec(':', 0), s2.get_slicec(':', 1).empty() ? i : s2.get_slicec(':', 1).to_int()); } popup_menu->set_size(Size2(rect.size.width, 0)); @@ -2951,14 +2955,14 @@ void Tree::_notification(int p_what) { if (show_column_titles) { //title buttons - int ofs = cache.bg->get_margin(MARGIN_LEFT); + int ofs2 = cache.bg->get_margin(MARGIN_LEFT); for (int i = 0; i < columns.size(); i++) { Ref<StyleBox> sb = (cache.click_type == Cache::CLICK_TITLE && cache.click_index == i) ? cache.title_button_pressed : ((cache.hover_type == Cache::CLICK_TITLE && cache.hover_index == i) ? cache.title_button_hover : cache.title_button); Ref<Font> f = cache.tb_font; - Rect2 tbrect = Rect2(ofs - cache.offset.x, bg->get_margin(MARGIN_TOP), get_column_width(i), tbh); + Rect2 tbrect = Rect2(ofs2 - cache.offset.x, bg->get_margin(MARGIN_TOP), get_column_width(i), tbh); sb->draw(ci, tbrect); - ofs += tbrect.size.width; + ofs2 += tbrect.size.width; //text int clip_w = tbrect.size.width - sb->get_minimum_size().width; f->draw_halign(ci, tbrect.position + Point2i(sb->get_offset().x, (tbrect.size.height - f->get_height()) / 2 + f->get_ascent()), HALIGN_CENTER, clip_w, columns[i].title, cache.title_button_color); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 6aa3891035..04d7107fa4 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1311,7 +1311,7 @@ Node *Node::_get_child_by_name(const StringName &p_name) const { return NULL; } -Node *Node::_get_node(const NodePath &p_path) const { +Node *Node::get_node_or_null(const NodePath &p_path) const { if (!data.inside_tree && p_path.is_absolute()) { ERR_EXPLAIN("Can't use get_node() with absolute paths from outside the active scene tree."); @@ -1376,7 +1376,7 @@ Node *Node::_get_node(const NodePath &p_path) const { Node *Node::get_node(const NodePath &p_path) const { - Node *node = _get_node(p_path); + Node *node = get_node_or_null(p_path); if (!node) { ERR_EXPLAIN("Node not found: " + p_path); ERR_FAIL_COND_V(!node, NULL); @@ -1386,7 +1386,7 @@ Node *Node::get_node(const NodePath &p_path) const { bool Node::has_node(const NodePath &p_path) const { - return _get_node(p_path) != NULL; + return get_node_or_null(p_path) != NULL; } Node *Node::find_node(const String &p_mask, bool p_recursive, bool p_owned) const { @@ -2709,6 +2709,7 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("get_child", "idx"), &Node::get_child); ClassDB::bind_method(D_METHOD("has_node", "path"), &Node::has_node); ClassDB::bind_method(D_METHOD("get_node", "path"), &Node::get_node); + ClassDB::bind_method(D_METHOD("get_node_or_null", "path"), &Node::get_node_or_null); ClassDB::bind_method(D_METHOD("get_parent"), &Node::get_parent); ClassDB::bind_method(D_METHOD("find_node", "mask", "recursive", "owned"), &Node::find_node, DEFVAL(true), DEFVAL(true)); ClassDB::bind_method(D_METHOD("find_parent", "mask"), &Node::find_parent); diff --git a/scene/main/node.h b/scene/main/node.h index 1c451ef567..e6189389cb 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -153,7 +153,6 @@ private: void _print_tree_pretty(const String prefix, const bool last); void _print_tree(const Node *p_node); - Node *_get_node(const NodePath &p_path) const; Node *_get_child_by_name(const StringName &p_name) const; void _replace_connections_target(Node *p_new_target); @@ -252,6 +251,7 @@ public: Node *get_child(int p_index) const; bool has_node(const NodePath &p_path) const; Node *get_node(const NodePath &p_path) const; + Node *get_node_or_null(const NodePath &p_path) const; Node *find_node(const String &p_mask, bool p_recursive = true, bool p_owned = true) const; bool has_node_and_resource(const NodePath &p_path) const; Node *get_node_and_resource(const NodePath &p_path, RES &r_res, Vector<StringName> &r_leftover_subpath, bool p_last_is_property = true) const; diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index f713851090..689f18a09d 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -1154,13 +1154,14 @@ void SceneTree::_update_root_rect() { float viewport_aspect = desired_res.aspect(); float video_mode_aspect = video_mode.aspect(); + if (use_font_oversampling && stretch_aspect == STRETCH_ASPECT_IGNORE) { + WARN_PRINT("Font oversampling only works with the resize modes 'Keep Width', 'Keep Height', and 'Expand'."); + } + if (stretch_aspect == STRETCH_ASPECT_IGNORE || ABS(viewport_aspect - video_mode_aspect) < CMP_EPSILON) { //same aspect or ignore aspect viewport_size = desired_res; screen_size = video_mode; - if (use_font_oversampling) { - WARN_PRINT("Font oversampling only works with the following resize modes 'Keep Width', 'Keep Height', and 'Expand'.") - } } else if (viewport_aspect < video_mode_aspect) { // screen ratio is smaller vertically diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 3a1ff5cb06..e15a64604d 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -43,7 +43,6 @@ @author Juan Linietsky <reduzio@gmail.com> */ -class SceneTree; class PackedScene; class Node; class Viewport; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 61d6fc7401..a5d86c3e1a 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -37,8 +37,8 @@ #include "scene/3d/camera.h" #include "scene/3d/collision_object.h" #include "scene/3d/listener.h" -#include "scene/3d/scenario_fx.h" #include "scene/3d/spatial.h" +#include "scene/3d/world_environment.h" #include "scene/gui/control.h" #include "scene/gui/label.h" #include "scene/gui/menu_button.h" @@ -232,16 +232,16 @@ void Viewport::update_worlds() { find_world()->_update(get_tree()->get_frame()); } -void Viewport::_collision_object_input_event(CollisionObject *p_object, Camera *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape, bool p_discard_empty_motion) { +void Viewport::_collision_object_input_event(CollisionObject *p_object, Camera *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) { Transform object_transform = p_object->get_global_transform(); Transform camera_transform = p_camera->get_global_transform(); ObjectID id = p_object->get_instance_id(); - if (p_discard_empty_motion) { - //avoid sending the event unnecesarily if nothing really changed in the context + //avoid sending the fake event unnecessarily if nothing really changed in the context + if (object_transform == physics_last_object_transform && camera_transform == physics_last_camera_transform && physics_last_id == id) { Ref<InputEventMouseMotion> mm = p_input_event; - if (mm.is_valid() && object_transform == physics_last_object_transform && camera_transform == physics_last_camera_transform && physics_last_id == id) { + if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) { return; //discarded } } @@ -251,31 +251,6 @@ void Viewport::_collision_object_input_event(CollisionObject *p_object, Camera * physics_last_id = id; } -void Viewport::_test_new_mouseover(ObjectID new_collider) { -#ifndef _3D_DISABLED - if (new_collider != physics_object_over) { - - if (physics_object_over) { - - CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(physics_object_over)); - if (co) { - co->_mouse_exit(); - } - } - - if (new_collider) { - - CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(new_collider)); - if (co) { - co->_mouse_enter(); - } - } - - physics_object_over = new_collider; - } -#endif -} - void Viewport::_notification(int p_what) { switch (p_what) { @@ -422,22 +397,22 @@ void Viewport::_notification(int p_what) { PhysicsDirectSpaceState::RayResult result; Physics2DDirectSpaceState *ss2d = Physics2DServer::get_singleton()->space_get_direct_state(find_world_2d()->get_space()); - bool discard_empty_motion = false; - - { // if no motion event exists, create a new one. This is necessary because objects or camera may have moved. - // while this extra event is sent, it is checked if both camera and last object and last ID did not move. If nothing changed, the event is discarded to avoid flooding with unnecesary motion events every frame - bool has_mouse_motion = false; + if (physics_has_last_mousepos) { + // if no mouse event exists, create a motion one. This is necessary because objects or camera may have moved. + // while this extra event is sent, it is checked if both camera and last object and last ID did not move. If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame + bool has_mouse_event = false; for (List<Ref<InputEvent> >::Element *E = physics_picking_events.front(); E; E = E->next()) { - Ref<InputEventMouseMotion> mm = E->get(); - if (mm.is_valid()) { - has_mouse_motion = true; + Ref<InputEventMouse> m = E->get(); + if (m.is_valid()) { + has_mouse_event = true; break; } } - if (!has_mouse_motion && physics_has_last_mousepos) { + if (!has_mouse_event) { Ref<InputEventMouseMotion> mm; mm.instance(); + mm->set_device(InputEvent::DEVICE_ID_INTERNAL); mm->set_global_position(physics_last_mousepos); mm->set_position(physics_last_mousepos); mm->set_alt(physics_last_mouse_state.alt); @@ -446,25 +421,24 @@ void Viewport::_notification(int p_what) { mm->set_metakey(physics_last_mouse_state.meta); mm->set_button_mask(physics_last_mouse_state.mouse_mask); physics_picking_events.push_back(mm); - discard_empty_motion = true; } } - bool motion_tested = false; - while (physics_picking_events.size()) { Ref<InputEvent> ev = physics_picking_events.front()->get(); physics_picking_events.pop_front(); Vector2 pos; + bool is_mouse = false; Ref<InputEventMouseMotion> mm = ev; if (mm.is_valid()) { pos = mm->get_position(); - motion_tested = true; + is_mouse = true; + physics_has_last_mousepos = true; physics_last_mousepos = pos; physics_last_mouse_state.alt = mm->get_alt(); @@ -477,7 +451,12 @@ void Viewport::_notification(int p_what) { Ref<InputEventMouseButton> mb = ev; if (mb.is_valid()) { + pos = mb->get_position(); + is_mouse = true; + + physics_has_last_mousepos = true; + physics_last_mousepos = pos; physics_last_mouse_state.alt = mb->get_alt(); physics_last_mouse_state.shift = mb->get_shift(); physics_last_mouse_state.control = mb->get_control(); @@ -487,6 +466,11 @@ void Viewport::_notification(int p_what) { physics_last_mouse_state.mouse_mask |= (1 << (mb->get_button_index() - 1)); } else { physics_last_mouse_state.mouse_mask &= ~(1 << (mb->get_button_index() - 1)); + + // If touch mouse raised, assume we don't know last mouse pos until new events come + if (mb->get_device() == InputEvent::DEVICE_ID_TOUCH_MOUSE) { + physics_has_last_mousepos = false; + } } } @@ -539,40 +523,51 @@ void Viewport::_notification(int p_what) { if (res[i].collider_id && res[i].collider) { CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider); if (co) { - - Map<ObjectID, uint64_t>::Element *E = physics_2d_mouseover.find(res[i].collider_id); - if (!E) { - E = physics_2d_mouseover.insert(res[i].collider_id, frame); - co->_mouse_enter(); - } else { - E->get() = frame; + bool send_event = true; + if (is_mouse) { + Map<ObjectID, uint64_t>::Element *F = physics_2d_mouseover.find(res[i].collider_id); + + if (!F) { + F = physics_2d_mouseover.insert(res[i].collider_id, frame); + co->_mouse_enter(); + } else { + F->get() = frame; + // It was already hovered, so don't send the event if it's faked + if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) { + send_event = false; + } + } } - co->_input_event(this, ev, res[i].shape); + if (send_event) { + co->_input_event(this, ev, res[i].shape); + } } } } } - List<Map<ObjectID, uint64_t>::Element *> to_erase; + if (is_mouse) { + List<Map<ObjectID, uint64_t>::Element *> to_erase; - for (Map<ObjectID, uint64_t>::Element *E = physics_2d_mouseover.front(); E; E = E->next()) { - if (E->get() != frame) { - Object *o = ObjectDB::get_instance(E->key()); - if (o) { + for (Map<ObjectID, uint64_t>::Element *E = physics_2d_mouseover.front(); E; E = E->next()) { + if (E->get() != frame) { + Object *o = ObjectDB::get_instance(E->key()); + if (o) { - CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o); - if (co) { - co->_mouse_exit(); + CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o); + if (co) { + co->_mouse_exit(); + } } + to_erase.push_back(E); } - to_erase.push_back(E); } - } - while (to_erase.size()) { - physics_2d_mouseover.erase(to_erase.front()->get()); - to_erase.pop_front(); + while (to_erase.size()) { + physics_2d_mouseover.erase(to_erase.front()->get()); + to_erase.pop_front(); + } } } @@ -583,7 +578,7 @@ void Viewport::_notification(int p_what) { CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(physics_object_capture)); if (co) { - _collision_object_input_event(co, camera, ev, Vector3(), Vector3(), 0, discard_empty_motion); + _collision_object_input_event(co, camera, ev, Vector3(), Vector3(), 0); captured = true; if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) { physics_object_capture = 0; @@ -601,7 +596,7 @@ void Viewport::_notification(int p_what) { if (last_id) { if (ObjectDB::get_instance(last_id) && last_object) { //good, exists - _collision_object_input_event(last_object, camera, ev, result.position, result.normal, result.shape, discard_empty_motion); + _collision_object_input_event(last_object, camera, ev, result.position, result.normal, result.shape); if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { physics_object_capture = last_id; } @@ -624,7 +619,7 @@ void Viewport::_notification(int p_what) { CollisionObject *co = Object::cast_to<CollisionObject>(result.collider); if (co) { - _collision_object_input_event(co, camera, ev, result.position, result.normal, result.shape, discard_empty_motion); + _collision_object_input_event(co, camera, ev, result.position, result.normal, result.shape); last_object = co; last_id = result.collider_id; new_collider = last_id; @@ -634,35 +629,30 @@ void Viewport::_notification(int p_what) { } } - if (mm.is_valid()) { - _test_new_mouseover(new_collider); - } - } + if (is_mouse && new_collider != physics_object_over) { - last_pos = pos; - } - } - } + if (physics_object_over) { - if (!motion_tested && camera && physics_has_last_mousepos) { + CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(physics_object_over)); + if (co) { + co->_mouse_exit(); + } + } - //test anyway for mouseenter/exit because objects might move - Vector3 from = camera->project_ray_origin(physics_last_mousepos); - Vector3 dir = camera->project_ray_normal(physics_last_mousepos); + if (new_collider) { - PhysicsDirectSpaceState *space = PhysicsServer::get_singleton()->space_get_direct_state(find_world()->get_space()); - if (space) { + CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(new_collider)); + if (co) { + co->_mouse_enter(); + } + } - bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true); - ObjectID new_collider = 0; - if (col) { - CollisionObject *co = Object::cast_to<CollisionObject>(result.collider); - if (co) { - new_collider = result.collider_id; + physics_object_over = new_collider; + } } - } - _test_new_mouseover(new_collider); + last_pos = pos; + } } #endif } @@ -1486,7 +1476,8 @@ void Viewport::_gui_show_tooltip() { gui.tooltip_popup->set_as_toplevel(true); //gui.tooltip_popup->hide(); - Rect2 r(gui.tooltip_pos + Point2(10, 10), gui.tooltip_popup->get_minimum_size()); + Point2 tooltip_offset = ProjectSettings::get_singleton()->get("display/mouse_cursor/tooltip_position_offset"); + Rect2 r(gui.tooltip_pos + tooltip_offset, gui.tooltip_popup->get_minimum_size()); Rect2 vr = gui.tooltip_popup->get_viewport_rect(); if (r.size.x + r.position.x > vr.size.x) r.position.x = vr.size.x - r.size.x; @@ -1747,8 +1738,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { while (!gui.modal_stack.empty()) { Control *top = gui.modal_stack.back()->get(); - Vector2 pos = top->get_global_transform_with_canvas().affine_inverse().xform(mpos); - if (!top->has_point(pos)) { + Vector2 pos2 = top->get_global_transform_with_canvas().affine_inverse().xform(mpos); + if (!top->has_point(pos2)) { if (top->data.modal_exclusive || top->data.modal_frame == Engine::get_singleton()->get_frames_drawn()) { //cancel event, sorry, modal exclusive EATS UP ALL @@ -1783,13 +1774,15 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { */ gui.mouse_focus = _gui_find_control(pos); - gui.mouse_focus_mask = 1 << (mb->get_button_index() - 1); gui.last_mouse_focus = gui.mouse_focus; if (!gui.mouse_focus) { + gui.mouse_focus_mask = 0; return; } + gui.mouse_focus_mask = 1 << (mb->get_button_index() - 1); + if (mb->get_button_index() == BUTTON_LEFT) { gui.drag_accum = Vector2(); gui.drag_attempted = false; @@ -2303,32 +2296,32 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (from && p_event->is_pressed()) { Control *next = NULL; - if (p_event->is_action("ui_focus_next")) { + if (p_event->is_action_pressed("ui_focus_next")) { next = from->find_next_valid_focus(); } - if (p_event->is_action("ui_focus_prev")) { + if (p_event->is_action_pressed("ui_focus_prev")) { next = from->find_prev_valid_focus(); } - if (!mods && p_event->is_action("ui_up")) { + if (!mods && p_event->is_action_pressed("ui_up")) { next = from->_get_focus_neighbour(MARGIN_TOP); } - if (!mods && p_event->is_action("ui_left")) { + if (!mods && p_event->is_action_pressed("ui_left")) { next = from->_get_focus_neighbour(MARGIN_LEFT); } - if (!mods && p_event->is_action("ui_right")) { + if (!mods && p_event->is_action_pressed("ui_right")) { next = from->_get_focus_neighbour(MARGIN_RIGHT); } - if (!mods && p_event->is_action("ui_down")) { + if (!mods && p_event->is_action_pressed("ui_down")) { next = from->_get_focus_neighbour(MARGIN_BOTTOM); } @@ -2496,6 +2489,9 @@ void Viewport::_gui_remove_control(Control *p_control) { gui.mouse_focus = NULL; gui.mouse_focus_mask = 0; } + if (gui.last_mouse_focus == p_control) { + gui.last_mouse_focus = NULL; + } if (gui.key_focus == p_control) gui.key_focus = NULL; if (gui.mouse_over == p_control) @@ -2920,6 +2916,13 @@ bool Viewport::is_handling_input_locally() const { return handle_input_locally; } +void Viewport::_validate_property(PropertyInfo &property) const { + + if (VisualServer::get_singleton()->is_low_end() && property.name == "hdr") { + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + } +} + void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_use_arvr", "use"), &Viewport::set_use_arvr); @@ -3199,6 +3202,8 @@ Viewport::Viewport() { gui.drag_attempted = false; gui.canvas_sort_index = 0; gui.roots_order_dirty = false; + gui.mouse_focus = NULL; + gui.last_mouse_focus = NULL; msaa = MSAA_DISABLED; hdr = true; diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 4d0a4e8c87..831c285517 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -221,12 +221,11 @@ private: } physics_last_mouse_state; - void _collision_object_input_event(CollisionObject *p_object, Camera *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape, bool p_discard_empty_motion); + void _collision_object_input_event(CollisionObject *p_object, Camera *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape); bool handle_input_locally; bool local_input_handled; - void _test_new_mouseover(ObjectID new_collider); Map<ObjectID, uint64_t> physics_2d_mouseover; Ref<World2D> world_2d; @@ -390,6 +389,7 @@ private: protected: void _notification(int p_what); static void _bind_methods(); + virtual void _validate_property(PropertyInfo &property) const; public: Listener *get_listener() const; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index a50a09f095..49c9c4c23c 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -48,7 +48,7 @@ #include "scene/2d/light_occluder_2d.h" #include "scene/2d/line_2d.h" #include "scene/2d/mesh_instance_2d.h" -#include "scene/2d/navigation2d.h" +#include "scene/2d/navigation_2d.h" #include "scene/2d/parallax_background.h" #include "scene/2d/parallax_layer.h" #include "scene/2d/particles_2d.h" @@ -58,10 +58,10 @@ #include "scene/2d/position_2d.h" #include "scene/2d/ray_cast_2d.h" #include "scene/2d/remote_transform_2d.h" -#include "scene/2d/screen_button.h" #include "scene/2d/skeleton_2d.h" #include "scene/2d/sprite.h" #include "scene/2d/tile_map.h" +#include "scene/2d/touch_screen_button.h" #include "scene/2d/visibility_notifier_2d.h" #include "scene/2d/y_sort.h" #include "scene/animation/animation_blend_space_1d.h" @@ -73,7 +73,7 @@ #include "scene/animation/animation_tree_player.h" #include "scene/animation/root_motion_view.h" #include "scene/animation/tween.h" -#include "scene/audio/audio_player.h" +#include "scene/audio/audio_stream_player.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" #include "scene/gui/center_container.h" @@ -125,12 +125,11 @@ #include "scene/main/timer.h" #include "scene/main/viewport.h" #include "scene/resources/audio_stream_sample.h" -#include "scene/resources/bit_mask.h" +#include "scene/resources/bit_map.h" #include "scene/resources/box_shape.h" #include "scene/resources/capsule_shape.h" #include "scene/resources/capsule_shape_2d.h" #include "scene/resources/circle_shape_2d.h" -#include "scene/resources/color_ramp.h" #include "scene/resources/concave_polygon_shape.h" #include "scene/resources/concave_polygon_shape_2d.h" #include "scene/resources/convex_polygon_shape.h" @@ -139,21 +138,23 @@ #include "scene/resources/default_theme/default_theme.h" #include "scene/resources/dynamic_font.h" #include "scene/resources/dynamic_font_stb.h" +#include "scene/resources/gradient.h" +#include "scene/resources/line_shape_2d.h" #include "scene/resources/material.h" #include "scene/resources/mesh.h" #include "scene/resources/mesh_data_tool.h" #include "scene/resources/mesh_library.h" #include "scene/resources/packed_scene.h" #include "scene/resources/particles_material.h" +#include "scene/resources/physics_material.h" #include "scene/resources/plane_shape.h" #include "scene/resources/polygon_path_finder.h" #include "scene/resources/primitive_meshes.h" #include "scene/resources/ray_shape.h" #include "scene/resources/rectangle_shape_2d.h" -#include "scene/resources/scene_format_text.h" +#include "scene/resources/resource_format_text.h" #include "scene/resources/segment_shape_2d.h" -#include "scene/resources/shape_line_2d.h" -#include "scene/resources/sky_box.h" +#include "scene/resources/sky.h" #include "scene/resources/sphere_shape.h" #include "scene/resources/surface_tool.h" #include "scene/resources/text_file.h" @@ -166,8 +167,8 @@ #include "scene/resources/world_2d.h" #include "scene/scene_string_names.h" -#include "scene/3d/scenario_fx.h" #include "scene/3d/spatial.h" +#include "scene/3d/world_environment.h" #ifndef _3D_DISABLED #include "scene/3d/area.h" @@ -207,7 +208,6 @@ #include "scene/3d/visibility_notifier.h" #include "scene/animation/skeleton_ik.h" #include "scene/resources/environment.h" -#include "scene/resources/physics_material.h" #endif static Ref<ResourceFormatSaverText> resource_saver_text; @@ -602,8 +602,8 @@ void register_scene_types() { ClassDB::register_class<SpatialVelocityTracker>(); - ClassDB::register_class<PhysicsMaterial>(); #endif + ClassDB::register_class<PhysicsMaterial>(); ClassDB::register_class<World>(); ClassDB::register_class<Environment>(); ClassDB::register_class<World2D>(); diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 3156e12c50..3eb16c544c 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "animation.h" +#include "scene/scene_string_names.h" #include "core/math/geometry.h" @@ -268,19 +269,19 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { for (int i = 0; i < valcount; i++) { - Dictionary d = clips[i]; - if (!d.has("start_offset")) + Dictionary d2 = clips[i]; + if (!d2.has("start_offset")) continue; - if (!d.has("end_offset")) + if (!d2.has("end_offset")) continue; - if (!d.has("stream")) + if (!d2.has("stream")) continue; TKey<AudioKey> ak; ak.time = rt[i]; - ak.value.start_offset = d["start_offset"]; - ak.value.end_offset = d["end_offset"]; - ak.value.stream = d["stream"]; + ak.value.start_offset = d2["start_offset"]; + ak.value.end_offset = d2["end_offset"]; + ak.value.stream = d2["stream"]; ad->values.push_back(ak); } @@ -668,6 +669,7 @@ int Animation::add_track(TrackType p_type, int p_at_pos) { } } emit_changed(); + emit_signal(SceneStringNames::get_singleton()->tracks_changed); return p_at_pos; } @@ -719,6 +721,7 @@ void Animation::remove_track(int p_track) { memdelete(t); tracks.remove(p_track); emit_changed(); + emit_signal(SceneStringNames::get_singleton()->tracks_changed); } int Animation::get_track_count() const { @@ -737,6 +740,7 @@ void Animation::track_set_path(int p_track, const NodePath &p_path) { ERR_FAIL_INDEX(p_track, tracks.size()); tracks[p_track]->path = p_path; emit_changed(); + emit_signal(SceneStringNames::get_singleton()->tracks_changed); } NodePath Animation::track_get_path(int p_track) const { @@ -1410,6 +1414,8 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p } break; } + + emit_changed(); } void Animation::track_set_key_transition(int p_track, int p_key_idx, float p_transition) { @@ -1445,6 +1451,8 @@ void Animation::track_set_key_transition(int p_track, int p_key_idx, float p_tra // they don't use transition } break; } + + emit_changed(); } template <class K> @@ -1828,9 +1836,14 @@ Variant Animation::value_track_interpolate(int p_track, float p_time) const { void Animation::_value_track_get_key_indices_in_range(const ValueTrack *vt, float from_time, float to_time, List<int> *p_indices) const { if (from_time != length && to_time == length) - to_time = length * 1.01; //include a little more if at the end + to_time = length * 1.001; //include a little more if at the end int to = _find(vt->values, to_time); + if (to >= 0 && from_time == to_time && vt->values[to].time == from_time) { + //find exact (0 delta), return if found + p_indices->push_back(to); + return; + } // can't really send the events == time, will be sent in the next frame. // if event>=len then it will probably never be requested by the anim player. @@ -1876,7 +1889,7 @@ void Animation::value_track_get_key_indices(int p_track, float p_time, float p_d if (from_time > to_time) { // handle loop by splitting - _value_track_get_key_indices_in_range(vt, length - from_time, length, p_indices); + _value_track_get_key_indices_in_range(vt, from_time, length, p_indices); _value_track_get_key_indices_in_range(vt, 0, to_time, p_indices); return; } @@ -2554,6 +2567,7 @@ void Animation::track_move_up(int p_track) { } emit_changed(); + emit_signal(SceneStringNames::get_singleton()->tracks_changed); } void Animation::track_set_imported(int p_track, bool p_imported) { @@ -2588,6 +2602,7 @@ void Animation::track_move_down(int p_track) { SWAP(tracks.write[p_track], tracks.write[p_track - 1]); } emit_changed(); + emit_signal(SceneStringNames::get_singleton()->tracks_changed); } void Animation::track_swap(int p_track, int p_with_track) { @@ -2598,6 +2613,7 @@ void Animation::track_swap(int p_track, int p_with_track) { return; SWAP(tracks.write[p_track], tracks.write[p_with_track]); emit_changed(); + emit_signal(SceneStringNames::get_singleton()->tracks_changed); } void Animation::set_step(float p_step) { @@ -2716,6 +2732,8 @@ void Animation::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "step", PROPERTY_HINT_RANGE, "0,4096,0.001"), "set_step", "get_step"); + ADD_SIGNAL(MethodInfo("tracks_changed")); + BIND_ENUM_CONSTANT(TYPE_VALUE); BIND_ENUM_CONSTANT(TYPE_TRANSFORM); BIND_ENUM_CONSTANT(TYPE_METHOD); @@ -2740,6 +2758,8 @@ void Animation::clear() { tracks.clear(); loop = false; length = 1; + emit_changed(); + emit_signal(SceneStringNames::get_singleton()->tracks_changed); } bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, const TKey<TransformKey> &t1, const TKey<TransformKey> &t2, float p_alowed_linear_err, float p_alowed_angular_err, float p_max_optimizable_angle, const Vector3 &p_norm) { diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp index a89cf108bc..4b3e392013 100644 --- a/scene/resources/audio_stream_sample.cpp +++ b/scene/resources/audio_stream_sample.cpp @@ -515,10 +515,10 @@ PoolVector<uint8_t> AudioStreamSample::get_data() const { return pv; } -void AudioStreamSample::save_to_wav(String p_path) { +Error AudioStreamSample::save_to_wav(const String &p_path) { if (format == AudioStreamSample::FORMAT_IMA_ADPCM) { WARN_PRINTS("Saving IMA_ADPC samples are not supported yet"); - return; + return ERR_UNAVAILABLE; } int sub_chunk_2_size = data_bytes; //Subchunk2Size = Size of data in bytes @@ -544,8 +544,9 @@ void AudioStreamSample::save_to_wav(String p_path) { file_path += ".wav"; } - Error err; - FileAccess *file = FileAccess::open(file_path, FileAccess::WRITE, &err); //Overrides existing file if present + FileAccessRef file = FileAccess::open(file_path, FileAccess::WRITE); //Overrides existing file if present + + ERR_FAIL_COND_V(!file, ERR_FILE_CANT_WRITE); // Create WAV Header file->store_string("RIFF"); //ChunkID @@ -583,6 +584,8 @@ void AudioStreamSample::save_to_wav(String p_path) { } file->close(); + + return OK; } Ref<AudioStreamPlayback> AudioStreamSample::instance_playback() { diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h index bd701ddd12..d4c5511f34 100644 --- a/scene/resources/audio_stream_sample.h +++ b/scene/resources/audio_stream_sample.h @@ -141,7 +141,7 @@ public: void set_data(const PoolVector<uint8_t> &p_data); PoolVector<uint8_t> get_data() const; - void save_to_wav(String p_path); + Error save_to_wav(const String &p_path); virtual Ref<AudioStreamPlayback> instance_playback(); virtual String get_stream_name() const; diff --git a/scene/resources/bit_mask.cpp b/scene/resources/bit_map.cpp index 0e2152f244..d2e4d28b44 100644 --- a/scene/resources/bit_mask.cpp +++ b/scene/resources/bit_map.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* bit_mask.cpp */ +/* bit_map.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "bit_mask.h" +#include "bit_map.h" #include "core/io/image_loader.h" @@ -332,7 +332,7 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) prevx = stepx; prevy = stepy; - ERR_FAIL_COND_V(count > width * height, _points); + ERR_FAIL_COND_V((int)count > width * height, _points); } while (curx != startx || cury != starty); return _points; } diff --git a/scene/resources/bit_mask.h b/scene/resources/bit_map.h index 4575064260..b3c86afd38 100644 --- a/scene/resources/bit_mask.h +++ b/scene/resources/bit_map.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* bit_mask.h */ +/* bit_map.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BIT_MASK_H -#define BIT_MASK_H +#ifndef BIT_MAP_H +#define BIT_MAP_H #include "core/image.h" #include "core/io/resource_loader.h" @@ -72,4 +72,4 @@ public: BitMap(); }; -#endif // BIT_MASK_H +#endif // BIT_MAP_H diff --git a/scene/resources/bounds.cpp b/scene/resources/bounds.cpp deleted file mode 100644 index e6fa5b818d..0000000000 --- a/scene/resources/bounds.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************/ -/* bounds.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "bounds.h" - -void Bounds::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_bsp_tree", "bsp_tree"), &Bounds::set_bsp_tree); - ClassDB::bind_method(D_METHOD("get_bsp_tree"), &Bounds::get_bsp_tree); - - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "bsp_tree"), "set_bsp_tree", "get_bsp_tree"); -} - -void Bounds::set_bsp_tree(const BSP_Tree &p_bsp_tree) { - - bsp_tree = p_bsp_tree; -} - -BSP_Tree Bounds::get_bsp_tree() const { - - return bsp_tree; -} - -Bounds::Bounds() { -} diff --git a/scene/resources/bounds.h b/scene/resources/bounds.h deleted file mode 100644 index 9a1801f23d..0000000000 --- a/scene/resources/bounds.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************/ -/* bounds.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef BOUNDS_H -#define BOUNDS_H - -#include "core/math/bsp_tree.h" -#include "core/resource.h" - -class Bounds : public Resource { - - GDCLASS(Bounds, Resource); - BSP_Tree bsp_tree; - -protected: - static void _bind_methods(); - -public: - void set_bsp_tree(const BSP_Tree &p_bsp_tree); - BSP_Tree get_bsp_tree() const; - - Bounds(); -}; - -#endif // BOUNDS_H diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 7ed51a2f8f..c7a815d8a4 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -682,6 +682,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("tab_fg", "TabContainer", sb_expand(make_stylebox(tab_current_png, 4, 4, 4, 1, 16, 4, 16, 4), 2, 2, 2, 2)); theme->set_stylebox("tab_bg", "TabContainer", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); + theme->set_stylebox("tab_disabled", "TabContainer", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); theme->set_stylebox("panel", "TabContainer", tc_sb); theme->set_icon("increment", "TabContainer", make_icon(scroll_button_right_png)); @@ -707,6 +708,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("tab_fg", "Tabs", sb_expand(make_stylebox(tab_current_png, 4, 3, 4, 1, 16, 3, 16, 2), 2, 2, 2, 2)); theme->set_stylebox("tab_bg", "Tabs", sb_expand(make_stylebox(tab_behind_png, 5, 4, 5, 1, 16, 5, 16, 2), 3, 3, 3, 3)); + theme->set_stylebox("tab_disabled", "Tabs", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); theme->set_stylebox("panel", "Tabs", tc_sb); theme->set_stylebox("button_pressed", "Tabs", make_stylebox(button_pressed_png, 4, 4, 4, 4)); theme->set_stylebox("button", "Tabs", make_stylebox(button_normal_png, 4, 4, 4, 4)); diff --git a/scene/resources/default_theme/tab_disabled.png b/scene/resources/default_theme/tab_disabled.png Binary files differnew file mode 100644 index 0000000000..97157a58dd --- /dev/null +++ b/scene/resources/default_theme/tab_disabled.png diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index 353e7eddbe..2b251e5f81 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -71,7 +71,7 @@ static const unsigned char dropdown_png[] = { }; static const unsigned char error_icon_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x4, 0x0, 0x0, 0x0, 0xd9, 0x73, 0xb2, 0x7f, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x36, 0x18, 0x5, 0xa3, 0x60, 0x14, 0xfc, 0x87, 0x40, 0x38, 0xb, 0x21, 0x6, 0x6, 0x18, 0x62, 0x98, 0x6, 0xa0, 0xb1, 0xfe, 0xe3, 0x67, 0xd1, 0xc2, 0x0, 0x10, 0xc4, 0xc5, 0x82, 0x91, 0x43, 0xc0, 0xb, 0xb8, 0x15, 0x63, 0x78, 0x6, 0x5, 0x8c, 0x82, 0x51, 0x30, 0xa, 0x0, 0x35, 0xa3, 0x4c, 0xb4, 0x7c, 0x8a, 0x7, 0x6, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe2, 0xb, 0xf, 0x0, 0x22, 0x18, 0xc, 0x35, 0xef, 0x18, 0x0, 0x0, 0x0, 0xe, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0x18, 0x5, 0xa3, 0x0, 0x1, 0x0, 0x2, 0x10, 0x0, 0x1, 0x14, 0xc2, 0xc0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char focus_png[] = { @@ -386,6 +386,10 @@ static const unsigned char tab_current_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x99, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x3d, 0x48, 0x5b, 0x58, 0x66, 0x5b, 0x57, 0x65, 0x57, 0x54, 0x62, 0x55, 0x53, 0x62, 0x4a, 0x46, 0x52, 0x46, 0x41, 0x4e, 0x45, 0x41, 0x4d, 0x55, 0x52, 0x60, 0x44, 0x41, 0x4c, 0x53, 0x50, 0x5e, 0x43, 0x40, 0x4b, 0x52, 0x4e, 0x5d, 0x41, 0x3e, 0x4a, 0x4f, 0x4d, 0x5a, 0x3f, 0x3d, 0x48, 0x4e, 0x4b, 0x59, 0x3e, 0x3c, 0x47, 0x4d, 0x4a, 0x58, 0x3d, 0x3b, 0x46, 0x4b, 0x49, 0x54, 0x3c, 0x3a, 0x44, 0x4b, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x3b, 0x39, 0x42, 0x3b, 0x38, 0x43, 0x3b, 0x38, 0x42, 0x3a, 0x37, 0x41, 0x39, 0x37, 0x41, 0x3a, 0x38, 0x41, 0x39, 0x36, 0x3f, 0x38, 0x36, 0x3f, 0x39, 0x36, 0x40, 0x38, 0x36, 0x40, 0x37, 0x35, 0x3e, 0x37, 0x34, 0x3e, 0x36, 0x35, 0x3d, 0xd7, 0x41, 0xa4, 0x19, 0x0, 0x0, 0x0, 0x11, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xa3, 0x31, 0x6b, 0xc2, 0x0, 0x0, 0x0, 0x60, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x55, 0xca, 0x85, 0xd, 0xc0, 0x40, 0x14, 0xc3, 0x50, 0x27, 0xf7, 0xd5, 0xfd, 0xd7, 0x2d, 0xa6, 0x4c, 0x16, 0x3f, 0xb9, 0xd0, 0x11, 0x90, 0xa3, 0x52, 0x77, 0x49, 0x8e, 0x86, 0xd2, 0x26, 0x16, 0x7b, 0x59, 0x32, 0x68, 0x3, 0x37, 0x5d, 0xe0, 0x59, 0x3b, 0x74, 0x31, 0x67, 0x4b, 0x3b, 0xf, 0x71, 0xe5, 0xe8, 0xf, 0xec, 0xc0, 0x1f, 0x28, 0xf8, 0x2, 0x14, 0xf9, 0x42, 0xa8, 0xfc, 0x21, 0x3b, 0xe4, 0x1, 0x6f, 0x0, 0x18, 0x11, 0xac, 0x99, 0xc0, 0xe, 0x25, 0x22, 0x2d, 0x76, 0xc6, 0x13, 0x1a, 0x8, 0xac, 0x78, 0xfc, 0x1c, 0x70, 0x30, 0x2b, 0xba, 0xe9, 0x31, 0x70, 0xc1, 0x7f, 0x3b, 0x77, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; +static const unsigned char tab_disabled_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x3, 0xa7, 0x7a, 0x54, 0x58, 0x74, 0x52, 0x61, 0x77, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x65, 0x78, 0x69, 0x66, 0x0, 0x0, 0x78, 0xda, 0xcd, 0x96, 0x59, 0x92, 0xe3, 0x2a, 0x10, 0x45, 0xff, 0x59, 0x45, 0x2f, 0x81, 0xcc, 0x24, 0x19, 0x96, 0x83, 0x18, 0x22, 0x7a, 0x7, 0x6f, 0xf9, 0x7d, 0xc1, 0x48, 0x1e, 0xab, 0x5c, 0x65, 0xfb, 0xe3, 0x89, 0xb0, 0x40, 0x29, 0x48, 0xae, 0xee, 0x41, 0xc8, 0xa6, 0xfd, 0xf7, 0xb7, 0x9b, 0x3f, 0x38, 0x28, 0x45, 0x6f, 0x9c, 0x86, 0xe8, 0x93, 0xf7, 0x16, 0x87, 0x4b, 0x2e, 0x71, 0x46, 0x23, 0xda, 0xd3, 0x71, 0xaa, 0xc9, 0xba, 0x79, 0x5e, 0x17, 0x76, 0x6f, 0x5c, 0xc5, 0xcd, 0x71, 0x83, 0x11, 0x12, 0xd4, 0x72, 0xba, 0xf4, 0x6d, 0xf5, 0xcf, 0x88, 0xeb, 0x79, 0x40, 0x70, 0x2b, 0xbe, 0x5d, 0xc7, 0x4d, 0x28, 0x2b, 0x4f, 0x5c, 0x89, 0xe8, 0x48, 0x3c, 0xf, 0x19, 0x33, 0x8f, 0xf6, 0xea, 0x17, 0x57, 0x22, 0xe1, 0x53, 0x9c, 0xd6, 0xb5, 0x49, 0x6b, 0x5c, 0x76, 0x17, 0x8f, 0xb3, 0x7e, 0x5c, 0x56, 0xda, 0x95, 0xfc, 0xf6, 0xda, 0x5, 0x98, 0x51, 0x15, 0xf9, 0x84, 0xd, 0x37, 0x21, 0xb1, 0x38, 0xc7, 0x31, 0x8b, 0x40, 0x81, 0x24, 0xc9, 0x32, 0xda, 0x79, 0xde, 0x19, 0x91, 0x80, 0xb6, 0x43, 0x9d, 0x45, 0x84, 0x1e, 0x7b, 0x67, 0x8e, 0xe6, 0x8d, 0x79, 0x47, 0xeb, 0xc6, 0x3b, 0x9b, 0x57, 0x5c, 0xae, 0xad, 0x30, 0xd6, 0xaf, 0xe, 0xfe, 0xc6, 0xa3, 0x15, 0x27, 0xbd, 0x89, 0xcb, 0x31, 0xd, 0xdf, 0x52, 0xdb, 0x67, 0xbe, 0xba, 0x91, 0xcb, 0x31, 0xc5, 0x9d, 0x77, 0xbd, 0xd7, 0xd8, 0x7b, 0x3b, 0x3d, 0x5d, 0x76, 0x1e, 0x4e, 0x79, 0xb3, 0x1e, 0x6a, 0x7f, 0x94, 0xd9, 0x42, 0xc7, 0xd, 0x56, 0xca, 0x1c, 0xe6, 0x51, 0x2, 0x7e, 0x8a, 0x76, 0x98, 0x25, 0xa1, 0x44, 0x3c, 0x62, 0x1, 0xb1, 0xa, 0x9a, 0x1b, 0x4a, 0x31, 0x94, 0x88, 0xe1, 0x69, 0x27, 0x47, 0x95, 0x32, 0x75, 0x6a, 0xb3, 0x2e, 0x54, 0x20, 0xd1, 0x71, 0xe3, 0x80, 0x9a, 0xb9, 0xb0, 0xcc, 0x58, 0x94, 0xc0, 0x89, 0xcb, 0x84, 0xe2, 0x46, 0xa1, 0xce, 0x1, 0x78, 0xaa, 0x91, 0x8, 0x3e, 0x5, 0xd4, 0x4, 0x61, 0x3e, 0xb4, 0xd0, 0x9c, 0x37, 0xcd, 0xf9, 0xa, 0x45, 0xcc, 0x5c, 0x9, 0x3d, 0x99, 0x90, 0x8c, 0x30, 0xe2, 0xae, 0x98, 0x47, 0xc1, 0x57, 0xca, 0x91, 0xa8, 0xf7, 0xb1, 0x74, 0x89, 0x6c, 0x3c, 0xbc, 0x82, 0x2e, 0x1e, 0x6b, 0x1a, 0x32, 0x6, 0xb9, 0x71, 0x46, 0x2f, 0x0, 0xa1, 0xbe, 0x3c, 0xd5, 0xe9, 0xef, 0x2c, 0xe6, 0x62, 0xdd, 0xd8, 0xb, 0xb0, 0x2, 0x82, 0x3a, 0x6d, 0x8e, 0x78, 0xc0, 0x6c, 0xb7, 0x53, 0x8a, 0x4d, 0xe9, 0xbc, 0xb6, 0x64, 0x72, 0x16, 0xf4, 0x53, 0xeb, 0x8c, 0x3d, 0xbd, 0x1a, 0x14, 0xea, 0x4a, 0x0, 0x8b, 0x30, 0xb7, 0x42, 0xc, 0x9, 0x8, 0x58, 0x4f, 0xa2, 0xe4, 0xc9, 0x6, 0xe6, 0x40, 0x4, 0x1f, 0x23, 0xf8, 0x64, 0x28, 0x67, 0x71, 0xbc, 0x81, 0x0, 0xa9, 0x72, 0x25, 0xd3, 0xc1, 0x46, 0xc4, 0x3, 0x4e, 0xe4, 0x31, 0x37, 0xc6, 0x4, 0x9a, 0x7d, 0x59, 0xf9, 0x14, 0xc6, 0xd6, 0x2, 0x10, 0x2a, 0x1e, 0xaf, 0x4a, 0x1c, 0x2f, 0x10, 0x60, 0x39, 0xa7, 0x58, 0x3f, 0xc1, 0x45, 0xac, 0xa1, 0xac, 0xa2, 0xce, 0xa8, 0xaa, 0xd7, 0xa0, 0x51, 0x93, 0x66, 0x2f, 0xde, 0x79, 0xf5, 0xde, 0x7, 0x3f, 0xf6, 0xa8, 0x1c, 0x24, 0xb8, 0xa0, 0xc1, 0x87, 0x10, 0x62, 0x48, 0x21, 0x47, 0x89, 0x2e, 0x6a, 0xf4, 0x31, 0xc4, 0x18, 0x53, 0xcc, 0x89, 0x93, 0x60, 0xb, 0xd3, 0xe4, 0x53, 0x30, 0x29, 0xa6, 0x94, 0x72, 0xc6, 0xa4, 0x19, 0xa9, 0x33, 0x46, 0x67, 0xf4, 0xc8, 0x79, 0xe3, 0x4d, 0x36, 0xb7, 0xe9, 0xe6, 0xb7, 0xb0, 0xc5, 0x2d, 0x6d, 0xb9, 0x60, 0xf9, 0x14, 0x57, 0xb4, 0xf8, 0x12, 0x4a, 0x2c, 0xa9, 0xe4, 0xca, 0x55, 0x2a, 0x5e, 0xff, 0xea, 0x6b, 0x30, 0x35, 0xd6, 0x54, 0x73, 0xa3, 0x86, 0xa5, 0xd4, 0x5c, 0xd3, 0xe6, 0x5b, 0x68, 0xb1, 0xa5, 0x96, 0x3b, 0xd6, 0x5a, 0x97, 0xee, 0xba, 0x76, 0xdf, 0x43, 0x8f, 0x3d, 0xf5, 0x7c, 0x50, 0x5b, 0x54, 0xaf, 0xa9, 0xd1, 0xd, 0xb9, 0xef, 0xa9, 0xd1, 0xa2, 0x36, 0x88, 0xb9, 0xd9, 0x2f, 0x9c, 0xa9, 0x21, 0x1c, 0xc2, 0x9e, 0x82, 0xc6, 0x76, 0xa2, 0x83, 0x19, 0x88, 0xb1, 0x23, 0x10, 0xf, 0x83, 0x0, 0x16, 0x34, 0xf, 0x66, 0x36, 0x92, 0x73, 0x3c, 0xc8, 0xd, 0x66, 0x36, 0x31, 0x5e, 0xa, 0x65, 0x50, 0x23, 0x1d, 0x70, 0x2a, 0xd, 0x62, 0x20, 0xe8, 0x1a, 0xb1, 0x76, 0x3a, 0xd8, 0x9d, 0xc9, 0x7d, 0xcb, 0xcd, 0xa8, 0xfb, 0x15, 0x37, 0xfe, 0x8a, 0x9c, 0x19, 0xe8, 0x3e, 0x41, 0xce, 0xc, 0x74, 0x8b, 0xdc, 0x3d, 0xb7, 0x7, 0xd4, 0x6a, 0x9e, 0x5f, 0x14, 0x99, 0x80, 0xc6, 0x5b, 0x38, 0x3c, 0xb5, 0xd2, 0xb1, 0xb1, 0xa1, 0x43, 0x8b, 0x99, 0x63, 0x1e, 0xdf, 0xa4, 0x97, 0x6b, 0xf3, 0x6e, 0x82, 0xff, 0x59, 0xa2, 0x76, 0x98, 0x52, 0xcd, 0x96, 0x67, 0xd4, 0xe2, 0x7b, 0x78, 0x6a, 0xd8, 0xd7, 0x6a, 0x83, 0x5d, 0x64, 0x45, 0x84, 0x8e, 0x89, 0x9e, 0x4a, 0xe9, 0x9a, 0xf6, 0x51, 0x92, 0x67, 0xc, 0xd4, 0xe2, 0x2e, 0xcf, 0xfd, 0x52, 0xb, 0xf9, 0x35, 0x30, 0x1d, 0x1e, 0xe1, 0x3, 0xb4, 0xf2, 0x97, 0x94, 0x9f, 0x8a, 0x71, 0x37, 0x62, 0x3e, 0x48, 0xd, 0x42, 0xcc, 0xae, 0x24, 0xb7, 0xa7, 0x4a, 0xf8, 0x50, 0xd2, 0x3e, 0x8d, 0xbf, 0xda, 0xc3, 0x12, 0xb3, 0xf9, 0xa7, 0x4a, 0xe8, 0x91, 0x27, 0x9f, 0x51, 0x74, 0x1, 0x67, 0x5b, 0xc9, 0xcd, 0xd7, 0x4a, 0x5c, 0xff, 0xce, 0x93, 0xf7, 0x14, 0x5d, 0x78, 0x52, 0x6e, 0xee, 0x99, 0x7, 0x4a, 0xea, 0xfe, 0xd6, 0x44, 0x25, 0xa7, 0xe3, 0x6f, 0xeb, 0xf, 0x6a, 0xf3, 0x93, 0x8e, 0x14, 0xf6, 0x67, 0xeb, 0xc2, 0x5f, 0x2c, 0x73, 0x73, 0x88, 0xad, 0xb2, 0x6b, 0xca, 0x73, 0xb8, 0x8e, 0xff, 0xd0, 0x3f, 0xaf, 0xcd, 0x77, 0x1d, 0xb4, 0x9f, 0x2d, 0x79, 0xe6, 0xb7, 0xe9, 0x2e, 0xbf, 0x62, 0xc9, 0x5d, 0x6d, 0x9e, 0x58, 0xa2, 0x4f, 0x76, 0x0, 0xa9, 0xec, 0xf7, 0x6d, 0xe4, 0x25, 0x4b, 0xee, 0x6a, 0xf3, 0xd8, 0x92, 0xfa, 0x74, 0x33, 0x71, 0xe9, 0x7a, 0xb9, 0x9a, 0xcf, 0x6c, 0xfd, 0xa7, 0x44, 0x17, 0xeb, 0xf5, 0xf7, 0x4a, 0x2e, 0x13, 0xbd, 0xbd, 0xad, 0xd9, 0x99, 0xe8, 0x4d, 0x25, 0x9f, 0x50, 0x74, 0x65, 0x89, 0x79, 0x57, 0xc9, 0x3b, 0x8a, 0x1e, 0xc2, 0xd9, 0x15, 0x75, 0xfc, 0x61, 0x49, 0xe6, 0x1f, 0xbf, 0x1c, 0xa8, 0x52, 0x2b, 0xb1, 0xc9, 0xd4, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0x2e, 0x23, 0x0, 0x0, 0x2e, 0x23, 0x1, 0x78, 0xa5, 0x3f, 0x76, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe3, 0x2, 0xa, 0x13, 0x29, 0x21, 0x5f, 0x36, 0xe2, 0x14, 0x0, 0x0, 0x0, 0xaf, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x7d, 0x91, 0x41, 0xa, 0xc2, 0x40, 0x10, 0x4, 0x6b, 0x92, 0x61, 0x37, 0xb0, 0x87, 0xec, 0x39, 0x3e, 0xc6, 0x3f, 0xf8, 0x9a, 0x3c, 0xc1, 0xd7, 0xf8, 0x3, 0xf, 0x3e, 0xc6, 0xab, 0x44, 0x50, 0x30, 0x26, 0x66, 0x3c, 0x2c, 0x6, 0x3, 0xd9, 0xf4, 0x69, 0xa0, 0xab, 0x9b, 0x86, 0x11, 0x14, 0x87, 0xa7, 0xc2, 0x51, 0x52, 0x90, 0x34, 0xf1, 0xe1, 0xcd, 0x8b, 0x9e, 0xb7, 0xe2, 0x8, 0x44, 0x6a, 0x2, 0x1e, 0x41, 0x0, 0xc3, 0xe8, 0x79, 0x72, 0xa7, 0x3, 0xc5, 0x13, 0xf7, 0x87, 0x5d, 0x3b, 0x46, 0x16, 0xd2, 0xee, 0x7a, 0xbc, 0x9c, 0x18, 0x95, 0x8a, 0xba, 0x69, 0x6f, 0x71, 0xc4, 0xfe, 0x6c, 0x41, 0x63, 0xd3, 0x72, 0xe6, 0xa1, 0x38, 0xc2, 0x10, 0x87, 0x65, 0x1c, 0x63, 0x60, 0x88, 0x4, 0x9c, 0x52, 0xe2, 0xa7, 0x45, 0x9a, 0x79, 0x29, 0x9e, 0x52, 0x29, 0x10, 0x63, 0x5a, 0x1, 0xc, 0x84, 0x42, 0x1, 0xc9, 0x36, 0x8, 0x68, 0x3a, 0x33, 0x0, 0x9, 0x30, 0x5b, 0x5, 0xc, 0x6c, 0x6e, 0x98, 0x36, 0x1b, 0x24, 0xdb, 0xf0, 0xdb, 0xc0, 0x2a, 0x90, 0x54, 0x6c, 0xba, 0x96, 0x0, 0xc9, 0x2, 0xc2, 0xfc, 0xe0, 0xac, 0xbe, 0xe, 0x38, 0x38, 0x83, 0xbf, 0x35, 0x30, 0x94, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; + static const unsigned char tab_menu_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x40, 0x5, 0xa3, 0xe0, 0xc1, 0x7f, 0x54, 0x48, 0x3, 0x5, 0xf, 0xe3, 0x1e, 0x7c, 0x81, 0x4b, 0x7f, 0x7b, 0x98, 0x86, 0xc5, 0x15, 0xf7, 0x35, 0xee, 0x5f, 0x2, 0x4b, 0x5f, 0x7f, 0xac, 0x8b, 0xc3, 0xa1, 0x2f, 0xb8, 0x1f, 0xce, 0x7f, 0x38, 0xff, 0x5, 0x37, 0x75, 0xbd, 0xf, 0x0, 0x52, 0xd4, 0x48, 0xb8, 0x2d, 0x78, 0x5a, 0x91, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index 39e81ca43d..887c7b42c8 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -54,8 +54,9 @@ public: struct { uint32_t size : 16; uint32_t outline_size : 8; - bool mipmaps : 1; - bool filter : 1; + uint32_t mipmaps : 1; + uint32_t filter : 1; + uint32_t unused : 6; }; uint32_t key; }; diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index a57b7bbb42..17609ed505 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -303,7 +303,7 @@ Ref<Texture> Environment::get_adjustment_color_correction() const { void Environment::_validate_property(PropertyInfo &property) const { - if (property.name == "background_sky" || property.name == "background_sky_custom_fov" || property.name == "background_sky_orientation" || property.name == "ambient_light/sky_contribution") { + if (property.name == "background_sky" || property.name == "background_sky_custom_fov" || property.name == "background_sky_orientation" || property.name == "background_sky_rotation" || property.name == "background_sky_rotation_degrees" || property.name == "ambient_light/sky_contribution") { if (bg_mode != BG_SKY && bg_mode != BG_COLOR_SKY) { property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; } @@ -1291,7 +1291,14 @@ void Environment::_bind_methods() { BIND_ENUM_CONSTANT(SSAO_QUALITY_HIGH); } -Environment::Environment() { +Environment::Environment() : + bg_mode(BG_CLEAR_COLOR), + tone_mapper(TONE_MAPPER_LINEAR), + ssao_blur(SSAO_BLUR_DISABLED), + ssao_quality(SSAO_QUALITY_LOW), + glow_blend_mode(GLOW_BLEND_MODE_ADDITIVE), + dof_blur_far_quality(DOF_BLUR_QUALITY_LOW), + dof_blur_near_quality(DOF_BLUR_QUALITY_LOW) { environment = VS::get_singleton()->environment_create(); diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 666112b473..a54f13a88f 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -32,7 +32,7 @@ #define ENVIRONMENT_H #include "core/resource.h" -#include "scene/resources/sky_box.h" +#include "scene/resources/sky.h" #include "scene/resources/texture.h" #include "servers/visual_server.h" diff --git a/scene/resources/color_ramp.cpp b/scene/resources/gradient.cpp index 845a1474a4..99ce8ef821 100644 --- a/scene/resources/color_ramp.cpp +++ b/scene/resources/gradient.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* color_ramp.cpp */ +/* gradient.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "color_ramp.h" +#include "gradient.h" + #include "core/core_string_names.h" //setter and getter names for property serialization diff --git a/scene/resources/color_ramp.h b/scene/resources/gradient.h index 7a96bb429b..a51a0ca0d0 100644 --- a/scene/resources/color_ramp.h +++ b/scene/resources/gradient.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* color_ramp.h */ +/* gradient.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SCENE_RESOURCES_COLOR_RAMP_H_ -#define SCENE_RESOURCES_COLOR_RAMP_H_ +#ifndef GRADIENT_H +#define GRADIENT_H #include "core/resource.h" @@ -126,4 +126,4 @@ public: int get_points_count() const; }; -#endif /* SCENE_RESOURCES_COLOR_RAMP_H_ */ +#endif // GRADIENT_H diff --git a/scene/resources/shape_line_2d.cpp b/scene/resources/line_shape_2d.cpp index 4ca535658f..f5d5fb561a 100644 --- a/scene/resources/shape_line_2d.cpp +++ b/scene/resources/line_shape_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* shape_line_2d.cpp */ +/* line_shape_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "shape_line_2d.h" +#include "line_shape_2d.h" + #include "servers/physics_2d_server.h" #include "servers/visual_server.h" diff --git a/scene/resources/shape_line_2d.h b/scene/resources/line_shape_2d.h index dd3dbe3a43..f684862025 100644 --- a/scene/resources/shape_line_2d.h +++ b/scene/resources/line_shape_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* shape_line_2d.h */ +/* line_shape_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SHAPE_LINE_2D_H -#define SHAPE_LINE_2D_H +#ifndef LINE_SHAPE_2D_H +#define LINE_SHAPE_2D_H #include "scene/resources/shape_2d.h" @@ -59,4 +59,4 @@ public: LineShape2D(); }; -#endif // SHAPE_LINE_2D_H +#endif // LINE_SHAPE_2D_H diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 5ffaf41581..536eb11a27 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -113,6 +113,9 @@ bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) { if (n.find("param/") == 0) { //backwards compatibility pr = n.substr(6, n.length()); } + if (n.find("shader_param/") == 0) { //backwards compatibility + pr = n.replace_first("shader_param/", ""); + } } if (pr) { VisualServer::get_singleton()->material_set_param(_get_material(), pr, p_value); @@ -128,6 +131,16 @@ bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const { if (shader.is_valid()) { StringName pr = shader->remap_param(p_name); + if (!pr) { + String n = p_name; + if (n.find("param/") == 0) { //backwards compatibility + pr = n.substr(6, n.length()); + } + if (n.find("shader_param/") == 0) { //backwards compatibility + pr = n.replace_first("shader_param/", ""); + } + } + if (pr) { r_ret = VisualServer::get_singleton()->material_get_param(_get_material(), pr); return true; @@ -594,17 +607,17 @@ void SpatialMaterial::_update_shader() { code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],CAMERA_MATRIX[1],CAMERA_MATRIX[2],WORLD_MATRIX[3]);\n"; if (flags[FLAG_BILLBOARD_KEEP_SCALE]) { - code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz),0,0,0),vec4(0,length(WORLD_MATRIX[1].xyz),0,0),vec4(0,0,length(WORLD_MATRIX[2].xyz),0),vec4(0,0,0,1));\n"; + code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, length(WORLD_MATRIX[1].xyz), 0.0, 0.0),vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0),vec4(0.0, 0.0, 0.0, 1.0));\n"; } } break; case BILLBOARD_FIXED_Y: { - code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],WORLD_MATRIX[1],vec4(normalize(cross(CAMERA_MATRIX[0].xyz,WORLD_MATRIX[1].xyz)),0.0),WORLD_MATRIX[3]);\n"; + code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],WORLD_MATRIX[1],vec4(normalize(cross(CAMERA_MATRIX[0].xyz,WORLD_MATRIX[1].xyz)), 0.0),WORLD_MATRIX[3]);\n"; if (flags[FLAG_BILLBOARD_KEEP_SCALE]) { - code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz),0,0,0),vec4(0,1,0,0),vec4(0,0,length(WORLD_MATRIX[2].xyz),0),vec4(0,0,0,1));\n"; + code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, 1.0, 0.0, 0.0),vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; } else { - code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(1,0,0,0),vec4(0,1.0/length(WORLD_MATRIX[1].xyz),0,0),vec4(0,0,1,0),vec4(0,0,0,1));\n"; + code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(1.0, 0.0, 0.0, 0.0),vec4(0.0, 1.0/length(WORLD_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0),vec4(0.0, 0.0, 0.0 ,1.0));\n"; } } break; case BILLBOARD_PARTICLES: { @@ -612,16 +625,22 @@ void SpatialMaterial::_update_shader() { //make billboard code += "\tmat4 mat_world = mat4(normalize(CAMERA_MATRIX[0])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[1])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[2])*length(WORLD_MATRIX[2]),WORLD_MATRIX[3]);\n"; //rotate by rotation - code += "\tmat_world = mat_world * mat4( vec4(cos(INSTANCE_CUSTOM.x),-sin(INSTANCE_CUSTOM.x),0.0,0.0), vec4(sin(INSTANCE_CUSTOM.x),cos(INSTANCE_CUSTOM.x),0.0,0.0),vec4(0.0,0.0,1.0,0.0),vec4(0.0,0.0,0.0,1.0));\n"; + code += "\tmat_world = mat_world * mat4( vec4(cos(INSTANCE_CUSTOM.x),-sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0),vec4(0.0, 0.0, 1.0, 0.0),vec4(0.0, 0.0, 0.0, 1.0));\n"; //set modelview code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat_world;\n"; //handle animation + code += "\tfloat h_frames = float(particles_anim_h_frames);\n"; + code += "\tfloat v_frames = float(particles_anim_v_frames);\n"; code += "\tfloat particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n"; code += "\tfloat particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n"; - code += "\tif (!particles_anim_loop) particle_frame=clamp(particle_frame,0.0,particle_total_frames-1.0); else particle_frame=mod(particle_frame,float(particle_total_frames));\n"; - code += "\tUV /= vec2(float(particles_anim_h_frames),float(particles_anim_v_frames));\n"; - code += "\tUV += vec2(mod(particle_frame,float(particles_anim_h_frames)) / float(particles_anim_h_frames), floor(particle_frame / float(particles_anim_h_frames)) / float(particles_anim_v_frames));\n"; + code += "\tif (!particles_anim_loop) {\n"; + code += "\t\tparticle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n"; + code += "\t} else {\n"; + code += "\t\tparticle_frame = mod(particle_frame, particle_total_frames);\n"; + code += "\t}"; + code += "\tUV /= vec2(h_frames, v_frames);\n"; + code += "\tUV += vec2(mod(particle_frame, h_frames) / h_frames, floor(particle_frame / h_frames) / v_frames);\n"; } break; } @@ -702,7 +721,7 @@ void SpatialMaterial::_update_shader() { code += "\tvec2 base_uv2 = UV2;\n"; } - if (features[FEATURE_DEPTH_MAPPING] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //depthmap not supported with triplanar + if (!VisualServer::get_singleton()->is_low_end() && features[FEATURE_DEPTH_MAPPING] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //depthmap not supported with triplanar code += "\t{\n"; code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*depth_flip.x,-BINORMAL*depth_flip.y,NORMAL));\n"; // binormal is negative due to mikktspace, flip 'unflips' it ;-) @@ -824,7 +843,7 @@ void SpatialMaterial::_update_shader() { code += "\tALPHA = albedo.a * albedo_tex.a;\n"; } - if (!VisualServer::get_singleton()->is_low_end() && proximity_fade_enabled) { + if (proximity_fade_enabled) { code += "\tfloat depth_tex = textureLod(DEPTH_TEXTURE,SCREEN_UV,0.0).r;\n"; code += "\tvec4 world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV*2.0-1.0,depth_tex*2.0-1.0,1.0);\n"; code += "\tworld_pos.xyz/=world_pos.w;\n"; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 805d30245a..85018f38d7 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -84,15 +84,15 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { PoolVector<int> indices = a[ARRAY_INDEX]; PoolVector<int>::Read ir = indices.read(); - for (int i = 0; i < ic; i++) { - int index = ir[i]; + for (int j = 0; j < ic; j++) { + int index = ir[j]; facesw[widx++] = vr[index]; } } else { - for (int i = 0; i < vc; i++) - facesw[widx++] = vr[i]; + for (int j = 0; j < vc; j++) + facesw[widx++] = vr[j]; } } @@ -787,7 +787,6 @@ void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array & Surface s; VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh, (VisualServer::PrimitiveType)p_primitive, p_arrays, p_blend_shapes, p_flags); - surfaces.push_back(s); /* make aABB? */ { @@ -808,8 +807,9 @@ void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array & aabb.expand_to(vtx[i]); } - surfaces.write[surfaces.size() - 1].aabb = aabb; - surfaces.write[surfaces.size() - 1].is_2d = arr.get_type() == Variant::POOL_VECTOR2_ARRAY; + s.aabb = aabb; + s.is_2d = arr.get_type() == Variant::POOL_VECTOR2_ARRAY; + surfaces.push_back(s); _recompute_aabb(); } @@ -1028,34 +1028,6 @@ AABB ArrayMesh::get_custom_aabb() const { return custom_aabb; } -void ArrayMesh::center_geometry() { - - /* - Vector3 ofs = aabb.pos+aabb.size*0.5; - - for(int i=0;i<get_surface_count();i++) { - - PoolVector<Vector3> geom = surface_get_array(i,ARRAY_VERTEX); - int gc =geom.size(); - PoolVector<Vector3>::Write w = geom.write(); - surfaces[i].aabb.pos-=ofs; - - for(int i=0;i<gc;i++) { - - w[i]-=ofs; - } - - w = PoolVector<Vector3>::Write(); - - surface_set_array(i,ARRAY_VERTEX,geom); - - } - - aabb.pos-=ofs; - -*/ -} - void ArrayMesh::regen_normalmaps() { Vector<Ref<SurfaceTool> > surfs; @@ -1295,8 +1267,6 @@ void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("create_trimesh_shape"), &ArrayMesh::create_trimesh_shape); ClassDB::bind_method(D_METHOD("create_convex_shape"), &ArrayMesh::create_convex_shape); ClassDB::bind_method(D_METHOD("create_outline", "margin"), &ArrayMesh::create_outline); - ClassDB::bind_method(D_METHOD("center_geometry"), &ArrayMesh::center_geometry); - ClassDB::set_method_flags(get_class_static(), _scs_create("center_geometry"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); ClassDB::bind_method(D_METHOD("regen_normalmaps"), &ArrayMesh::regen_normalmaps); ClassDB::set_method_flags(get_class_static(), _scs_create("regen_normalmaps"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); ClassDB::bind_method(D_METHOD("lightmap_unwrap", "transform", "texel_size"), &ArrayMesh::lightmap_unwrap); diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 2d0aef8ab0..dabfc6ea60 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -223,7 +223,6 @@ public: AABB get_aabb() const; virtual RID get_rid() const; - void center_geometry(); void regen_normalmaps(); Error lightmap_unwrap(const Transform &p_base_transform = Transform(), float p_texel_size = 0.05); diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp index c5125d576d..d40a5dee2e 100644 --- a/scene/resources/mesh_library.cpp +++ b/scene/resources/mesh_library.cpp @@ -56,6 +56,8 @@ bool MeshLibrary::_set(const StringName &p_name, const Variant &p_value) { set_item_preview(idx, p_value); else if (what == "navmesh") set_item_navmesh(idx, p_value); + else if (what == "navmesh_transform") + set_item_navmesh_transform(idx, p_value); else return false; @@ -80,6 +82,8 @@ bool MeshLibrary::_get(const StringName &p_name, Variant &r_ret) const { r_ret = _get_item_shapes(idx); else if (what == "navmesh") r_ret = get_item_navmesh(idx); + else if (what == "navmesh_transform") + r_ret = get_item_navmesh_transform(idx); else if (what == "preview") r_ret = get_item_preview(idx); else @@ -95,8 +99,10 @@ void MeshLibrary::_get_property_list(List<PropertyInfo> *p_list) const { String name = "item/" + itos(E->key()) + "/"; p_list->push_back(PropertyInfo(Variant::STRING, name + "name")); p_list->push_back(PropertyInfo(Variant::OBJECT, name + "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh")); + p_list->push_back(PropertyInfo(Variant::TRANSFORM, name + "mesh_transform")); p_list->push_back(PropertyInfo(Variant::ARRAY, name + "shapes")); p_list->push_back(PropertyInfo(Variant::OBJECT, name + "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh")); + p_list->push_back(PropertyInfo(Variant::TRANSFORM, name + "navmesh_transform")); p_list->push_back(PropertyInfo(Variant::OBJECT, name + "preview", PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_HELPER)); } } @@ -116,6 +122,7 @@ void MeshLibrary::set_item_name(int p_item, const String &p_name) { emit_changed(); _change_notify(); } + void MeshLibrary::set_item_mesh(int p_item, const Ref<Mesh> &p_mesh) { ERR_FAIL_COND(!item_map.has(p_item)); @@ -145,6 +152,15 @@ void MeshLibrary::set_item_navmesh(int p_item, const Ref<NavigationMesh> &p_navm _change_notify(); } +void MeshLibrary::set_item_navmesh_transform(int p_item, const Transform &p_transform) { + + ERR_FAIL_COND(!item_map.has(p_item)); + item_map[p_item].navmesh_transform = p_transform; + notify_change_to_owners(); + emit_changed(); + _change_notify(); +} + void MeshLibrary::set_item_preview(int p_item, const Ref<Texture> &p_preview) { ERR_FAIL_COND(!item_map.has(p_item)); @@ -152,11 +168,13 @@ void MeshLibrary::set_item_preview(int p_item, const Ref<Texture> &p_preview) { emit_changed(); _change_notify(); } + String MeshLibrary::get_item_name(int p_item) const { ERR_FAIL_COND_V(!item_map.has(p_item), ""); return item_map[p_item].name; } + Ref<Mesh> MeshLibrary::get_item_mesh(int p_item) const { ERR_FAIL_COND_V(!item_map.has(p_item), Ref<Mesh>()); @@ -175,6 +193,12 @@ Ref<NavigationMesh> MeshLibrary::get_item_navmesh(int p_item) const { return item_map[p_item].navmesh; } +Transform MeshLibrary::get_item_navmesh_transform(int p_item) const { + + ERR_FAIL_COND_V(!item_map.has(p_item), Transform()); + return item_map[p_item].navmesh_transform; +} + Ref<Texture> MeshLibrary::get_item_preview(int p_item) const { ERR_FAIL_COND_V(!item_map.has(p_item), Ref<Texture>()); @@ -268,11 +292,13 @@ void MeshLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("set_item_name", "id", "name"), &MeshLibrary::set_item_name); ClassDB::bind_method(D_METHOD("set_item_mesh", "id", "mesh"), &MeshLibrary::set_item_mesh); ClassDB::bind_method(D_METHOD("set_item_navmesh", "id", "navmesh"), &MeshLibrary::set_item_navmesh); + ClassDB::bind_method(D_METHOD("set_item_navmesh_transform", "id", "navmesh"), &MeshLibrary::set_item_navmesh_transform); ClassDB::bind_method(D_METHOD("set_item_shapes", "id", "shapes"), &MeshLibrary::_set_item_shapes); ClassDB::bind_method(D_METHOD("set_item_preview", "id", "texture"), &MeshLibrary::set_item_preview); ClassDB::bind_method(D_METHOD("get_item_name", "id"), &MeshLibrary::get_item_name); ClassDB::bind_method(D_METHOD("get_item_mesh", "id"), &MeshLibrary::get_item_mesh); ClassDB::bind_method(D_METHOD("get_item_navmesh", "id"), &MeshLibrary::get_item_navmesh); + ClassDB::bind_method(D_METHOD("get_item_navmesh_transform", "id"), &MeshLibrary::get_item_navmesh_transform); ClassDB::bind_method(D_METHOD("get_item_shapes", "id"), &MeshLibrary::_get_item_shapes); ClassDB::bind_method(D_METHOD("get_item_preview", "id"), &MeshLibrary::get_item_preview); ClassDB::bind_method(D_METHOD("remove_item", "id"), &MeshLibrary::remove_item); diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index 849a0577eb..4ae4fc6483 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -52,6 +52,7 @@ public: Ref<Mesh> mesh; Vector<ShapeData> shapes; Ref<Texture> preview; + Transform navmesh_transform; Ref<NavigationMesh> navmesh; }; @@ -72,11 +73,13 @@ public: void set_item_name(int p_item, const String &p_name); void set_item_mesh(int p_item, const Ref<Mesh> &p_mesh); void set_item_navmesh(int p_item, const Ref<NavigationMesh> &p_navmesh); + void set_item_navmesh_transform(int p_item, const Transform &p_transform); void set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes); void set_item_preview(int p_item, const Ref<Texture> &p_preview); String get_item_name(int p_item) const; Ref<Mesh> get_item_mesh(int p_item) const; Ref<NavigationMesh> get_item_navmesh(int p_item) const; + Transform get_item_navmesh_transform(int p_item) const; Vector<ShapeData> get_item_shapes(int p_item) const; Ref<Texture> get_item_preview(int p_item) const; diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp index 7084c3b4e1..1b406551ab 100644 --- a/scene/resources/multimesh.cpp +++ b/scene/resources/multimesh.cpp @@ -166,11 +166,22 @@ void MultiMesh::set_instance_transform(int p_instance, const Transform &p_transf VisualServer::get_singleton()->multimesh_instance_set_transform(multimesh, p_instance, p_transform); } + +void MultiMesh::set_instance_transform_2d(int p_instance, const Transform2D &p_transform) { + + VisualServer::get_singleton()->multimesh_instance_set_transform_2d(multimesh, p_instance, p_transform); +} + Transform MultiMesh::get_instance_transform(int p_instance) const { return VisualServer::get_singleton()->multimesh_instance_get_transform(multimesh, p_instance); } +Transform2D MultiMesh::get_instance_transform_2d(int p_instance) const { + + return VisualServer::get_singleton()->multimesh_instance_get_transform_2d(multimesh, p_instance); +} + void MultiMesh::set_instance_color(int p_instance, const Color &p_color) { VisualServer::get_singleton()->multimesh_instance_set_color(multimesh, p_instance, p_color); @@ -245,7 +256,9 @@ void MultiMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_instance_count", "count"), &MultiMesh::set_instance_count); ClassDB::bind_method(D_METHOD("get_instance_count"), &MultiMesh::get_instance_count); ClassDB::bind_method(D_METHOD("set_instance_transform", "instance", "transform"), &MultiMesh::set_instance_transform); + ClassDB::bind_method(D_METHOD("set_instance_transform_2d", "instance", "transform"), &MultiMesh::set_instance_transform_2d); ClassDB::bind_method(D_METHOD("get_instance_transform", "instance"), &MultiMesh::get_instance_transform); + ClassDB::bind_method(D_METHOD("get_instance_transform_2d", "instance"), &MultiMesh::get_instance_transform_2d); ClassDB::bind_method(D_METHOD("set_instance_color", "instance", "color"), &MultiMesh::set_instance_color); ClassDB::bind_method(D_METHOD("get_instance_color", "instance"), &MultiMesh::get_instance_color); ClassDB::bind_method(D_METHOD("set_instance_custom_data", "instance", "custom_data"), &MultiMesh::set_instance_custom_data); diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h index 4e70907399..ac2c69e022 100644 --- a/scene/resources/multimesh.h +++ b/scene/resources/multimesh.h @@ -94,7 +94,9 @@ public: int get_instance_count() const; void set_instance_transform(int p_instance, const Transform &p_transform); + void set_instance_transform_2d(int p_instance, const Transform2D &p_transform); Transform get_instance_transform(int p_instance) const; + Transform2D get_instance_transform_2d(int p_instance) const; void set_instance_color(int p_instance, const Color &p_color); Color get_instance_color(int p_instance) const; diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index ea810edf8c..626ed9f5b4 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -55,7 +55,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const { Node *p_name; \ if (p_id & FLAG_ID_IS_PATH) { \ NodePath np = node_paths[p_id & FLAG_MASK]; \ - p_name = ret_nodes[0]->_get_node(np); \ + p_name = ret_nodes[0]->get_node_or_null(np); \ } else { \ ERR_FAIL_INDEX_V(p_id &FLAG_MASK, nc, NULL); \ p_name = ret_nodes[p_id & FLAG_MASK]; \ @@ -92,6 +92,8 @@ Node *SceneState::instance(GenEditState p_edit_state) const { if (i > 0) { + ERR_EXPLAIN(vformat("Invalid scene: node %s does not specify its parent node.", snames[n.name])) + ERR_FAIL_COND_V(n.parent == -1, NULL) NODE_FROM_ID(nparent, n.parent); #ifdef DEBUG_ENABLED if (!nparent && (n.parent & FLAG_ID_IS_PATH)) { @@ -175,8 +177,8 @@ Node *SceneState::instance(GenEditState p_edit_state) const { node = Object::cast_to<Node>(obj); } else { - print_line("Class is disabled for: " + itos(n.type)); - print_line("name: " + String(snames[n.type])); + //print_line("Class is disabled for: " + itos(n.type)); + //print_line("name: " + String(snames[n.type])); } if (node) { @@ -236,8 +238,8 @@ Node *SceneState::instance(GenEditState p_edit_state) const { } else { //for instances, a copy must be made - Node *base = i == 0 ? node : ret_nodes[0]; - Ref<Resource> local_dupe = res->duplicate_for_local_scene(base, resources_local_to_scene); + Node *base2 = i == 0 ? node : ret_nodes[0]; + Ref<Resource> local_dupe = res->duplicate_for_local_scene(base2, resources_local_to_scene); resources_local_to_scene[res] = local_dupe; res = local_dupe; value = local_dupe; @@ -296,8 +298,8 @@ Node *SceneState::instance(GenEditState p_edit_state) const { ret_nodes[i] = node; if (node && gen_node_path_cache && ret_nodes[0]) { - NodePath n = ret_nodes[0]->get_path_to(node); - node_path_cache[n] = i; + NodePath n2 = ret_nodes[0]->get_path_to(node); + node_path_cache[n2] = i; } } @@ -342,7 +344,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const { } for (int i = 0; i < editable_instances.size(); i++) { - Node *ei = ret_nodes[0]->_get_node(editable_instances[i]); + Node *ei = ret_nodes[0]->get_node_or_null(editable_instances[i]); if (ei) { ret_nodes[0]->set_editable_instance(ei, true); } @@ -749,7 +751,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName { Node *nl = p_node; - bool exists = false; + bool exists2 = false; while (nl) { @@ -763,7 +765,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName if (from_node >= 0 && to_node >= 0) { //this one has state for this node, save if (state->is_connection(from_node, c.signal, to_node, c.method)) { - exists = true; + exists2 = true; break; } } @@ -781,7 +783,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName if (from_node >= 0 && to_node >= 0) { //this one has state for this node, save if (state->is_connection(from_node, c.signal, to_node, c.method)) { - exists = true; + exists2 = true; break; } } @@ -791,7 +793,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName } } - if (exists) { + if (exists2) { continue; } } diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index 59fde7787e..ef67e6ea80 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -311,8 +311,8 @@ void ParticlesMaterial::_update_shader() { //initiate velocity spread in 3D code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n"; - code += " vec3 direction_xz = vec3(sin(angle1_rad), 0, cos(angle1_rad));\n"; - code += " vec3 direction_yz = vec3(0, sin(angle2_rad), cos(angle2_rad));\n"; + code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n"; + code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n"; code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n"; code += " vec3 direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n"; code += " direction = normalize(direction);\n"; @@ -347,7 +347,7 @@ void ParticlesMaterial::_update_shader() { code += " VELOCITY.xy = rotm * VELOCITY.xy;\n"; } else { code += " vec3 normal = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xyz;\n"; - code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0, 1.0, 0.0);\n"; + code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);\n"; code += " vec3 tangent = normalize(cross(v0, normal));\n"; code += " vec3 bitangent = normalize(cross(tangent, normal));\n"; code += " VELOCITY = mat3(tangent, bitangent, normal) * VELOCITY;\n"; diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp index a45a55a258..52fc21ac11 100644 --- a/scene/resources/polygon_path_finder.cpp +++ b/scene/resources/polygon_path_finder.cpp @@ -441,9 +441,9 @@ void PolygonPathFinder::_set_data(const Dictionary &p_data) { PoolVector<float> penalties = p_data["penalties"]; if (penalties.size() == pc) { - PoolVector<float>::Read pr = penalties.read(); + PoolVector<float>::Read pr2 = penalties.read(); for (int i = 0; i < pc; i++) { - points.write[i].penalty = pr[i]; + points.write[i].penalty = pr2[i]; } } } diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 9ef12aa4e6..db58fe7823 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -376,17 +376,17 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { z = radius * cos(0.5 * Math_PI * v); for (i = 0; i <= radial_segments; i++) { - float u = i; - u /= radial_segments; + float u2 = i; + u2 /= radial_segments; - x = sin(u * (Math_PI * 2.0)); - y = -cos(u * (Math_PI * 2.0)); + x = sin(u2 * (Math_PI * 2.0)); + y = -cos(u2 * (Math_PI * 2.0)); Vector3 p = Vector3(x * radius * w, y * radius * w, z); points.push_back(p + Vector3(0.0, 0.0, -0.5 * mid_height)); normals.push_back(p.normalized()); ADD_TANGENT(-y, x, 0.0, 1.0) - uvs.push_back(Vector2(u, twothirds + ((v - 1.0) * onethird))); + uvs.push_back(Vector2(u2, twothirds + ((v - 1.0) * onethird))); point++; if (i > 0 && j > 0) { diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/resource_format_text.cpp index 558810d92a..b6efca9acc 100644 --- a/scene/resources/scene_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* scene_format_text.cpp */ +/* resource_format_text.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "scene_format_text.h" +#include "resource_format_text.h" + #include "core/io/resource_format_binary.h" #include "core/os/dir_access.h" #include "core/project_settings.h" @@ -1360,7 +1361,9 @@ String ResourceFormatSaverTextInstance::_write_resource(const RES &res) { if (internal_resources.has(res)) { return "SubResource( " + itos(internal_resources[res]) + " )"; } else if (res->get_path().length() && res->get_path().find("::") == -1) { - + if (res->get_path() == local_path) { //circular reference attempt + return "null"; + } //external resource String path = relative_paths ? local_path.path_to_file(res->get_path()) : res->get_path(); return "Resource( \"" + path + "\" )"; @@ -1385,6 +1388,10 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, return; if (!p_main && (!bundle_resources) && res->get_path().length() && res->get_path().find("::") == -1) { + if (res->get_path() == local_path) { + ERR_PRINTS("Circular reference to resource being saved found: '" + local_path + "' will be null next time it's loaded."); + return; + } int index = external_resources.size(); external_resources[res] = index; return; @@ -1407,7 +1414,20 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, if (pi.usage & PROPERTY_USAGE_STORAGE) { Variant v = res->get(I->get().name); - _find_resources(v); + + if (pi.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { + RES sres = v; + if (sres.is_valid()) { + NonPersistentKey npk; + npk.base = res; + npk.property = pi.name; + non_persistent_map[npk] = sres; + resource_set.insert(sres); + saved_resources.push_back(sres); + } + } else { + _find_resources(v); + } } I = I->next(); @@ -1562,7 +1582,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r break; //save as a scene if (main) { - f->store_line("[resource]\n"); + f->store_line("[resource]"); } else { String line = "[sub_resource "; if (res->get_subindex() == 0) { @@ -1577,7 +1597,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r int idx = res->get_subindex(); line += "type=\"" + res->get_class() + "\" id=" + itos(idx); - f->store_line(line + "]\n"); + f->store_line(line + "]"); if (takeover_paths) { res->set_path(p_path + "::" + itos(idx), true); } @@ -1599,7 +1619,17 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r if (PE->get().usage & PROPERTY_USAGE_STORAGE) { String name = PE->get().name; - Variant value = res->get(name); + Variant value; + if (PE->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { + NonPersistentKey npk; + npk.base = res; + npk.property = name; + if (non_persistent_map.has(npk)) { + value = non_persistent_map[npk]; + } + } else { + value = res->get(name); + } Variant default_value = ClassDB::class_get_default_property_value(res->get_class(), name); if (default_value.get_type() != Variant::NIL && bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value))) { @@ -1615,7 +1645,8 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r } } - f->store_string("\n"); + if (E->next()) + f->store_line(String()); } if (packed_scene.is_valid()) { @@ -1684,7 +1715,8 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r f->store_string(_valprop(String(state->get_node_property_name(i, j))) + " = " + vars + "\n"); } - f->store_line(String()); + if (i < state->get_node_count() - 1) + f->store_line(String()); } for (int i = 0; i < state->get_connection_count(); i++) { diff --git a/scene/resources/scene_format_text.h b/scene/resources/resource_format_text.h index 8fedbd0dd6..8d78ab33b0 100644 --- a/scene/resources/scene_format_text.h +++ b/scene/resources/resource_format_text.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* scene_format_text.h */ +/* resource_format_text.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SCENE_FORMAT_TEXT_H -#define SCENE_FORMAT_TEXT_H +#ifndef RESOURCE_FORMAT_TEXT_H +#define RESOURCE_FORMAT_TEXT_H #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" @@ -155,6 +155,15 @@ class ResourceFormatSaverTextInstance { bool bundle_resources; bool skip_editor; FileAccess *f; + + struct NonPersistentKey { //for resource properties generated on the fly + RES base; + StringName property; + bool operator<(const NonPersistentKey &p_key) const { return base == p_key.base ? property < p_key.property : base < p_key.base; } + }; + + Map<NonPersistentKey, RES> non_persistent_map; + Set<RES> resource_set; List<RES> saved_resources; Map<RES, int> external_resources; @@ -180,4 +189,4 @@ public: ResourceFormatSaverText(); }; -#endif // SCENE_FORMAT_TEXT_H +#endif // RESOURCE_FORMAT_TEXT_H diff --git a/scene/resources/sky_box.cpp b/scene/resources/sky.cpp index d9da85310e..f9f8ff19e4 100644 --- a/scene/resources/sky_box.cpp +++ b/scene/resources/sky.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* sky_box.cpp */ +/* sky.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "sky_box.h" +#include "sky.h" + #include "core/io/image_loader.h" void Sky::set_radiance_size(RadianceSize p_size) { @@ -155,7 +156,10 @@ Ref<Image> ProceduralSky::_generate_sky() { Color ground_bottom_linear = ground_bottom_color.to_linear(); Color ground_horizon_linear = ground_horizon_color.to_linear(); - //Color sun_linear = sun_color.to_linear(); + Color sun_linear; + sun_linear.r = sun_color.r * sun_energy; + sun_linear.g = sun_color.g * sun_energy; + sun_linear.b = sun_color.b * sun_energy; Vector3 sun(0, 0, -1); @@ -203,13 +207,13 @@ Ref<Image> ProceduralSky::_generate_sky() { float sun_angle = Math::rad2deg(Math::acos(CLAMP(sun.dot(normal), -1.0, 1.0))); if (sun_angle < sun_angle_min) { - color = color.blend(sun_color); + color = color.blend(sun_linear); } else if (sun_angle < sun_angle_max) { float c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min); c2 = Math::ease(c2, sun_curve); - color = color.blend(sun_color).linear_interpolate(color, c2); + color = color.blend(sun_linear).linear_interpolate(color, c2); } } @@ -532,7 +536,7 @@ void ProceduralSky::_bind_methods() { BIND_ENUM_CONSTANT(TEXTURE_SIZE_MAX); } -ProceduralSky::ProceduralSky() { +ProceduralSky::ProceduralSky(bool p_desaturate) { sky = VS::get_singleton()->sky_create(); texture = VS::get_singleton()->texture_create(); @@ -548,13 +552,19 @@ ProceduralSky::ProceduralSky() { ground_curve = 0.02; ground_energy = 1; + if (p_desaturate) { + sky_top_color.set_hsv(sky_top_color.get_h(),0,sky_top_color.get_v()); + sky_horizon_color.set_hsv(sky_horizon_color.get_h(),0,sky_horizon_color.get_v()); + ground_bottom_color.set_hsv(ground_bottom_color.get_h(),0,ground_bottom_color.get_v()); + ground_horizon_color.set_hsv(ground_horizon_color.get_h(),0,ground_horizon_color.get_v()); + } sun_color = Color(1, 1, 1); sun_latitude = 35; sun_longitude = 0; sun_angle_min = 1; sun_angle_max = 100; sun_curve = 0.05; - sun_energy = 16; + sun_energy = 1; texture_size = TEXTURE_SIZE_1024; sky_thread = NULL; diff --git a/scene/resources/sky_box.h b/scene/resources/sky.h index af10803b36..7327b2a627 100644 --- a/scene/resources/sky_box.h +++ b/scene/resources/sky.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* sky_box.h */ +/* sky.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKY_BOX_H -#define SKY_BOX_H +#ifndef SKY_H +#define SKY_H #include "core/os/thread.h" #include "scene/resources/texture.h" + class Sky : public Resource { GDCLASS(Sky, Resource); @@ -190,10 +191,10 @@ public: virtual RID get_rid() const; - ProceduralSky(); + ProceduralSky(bool p_desaturate=false); ~ProceduralSky(); }; VARIANT_ENUM_CAST(ProceduralSky::TextureSize) -#endif // SKY_BOX_H +#endif // SKY_H diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index affe9a3e24..cdd65c7642 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -903,6 +903,7 @@ int StyleBoxLine::get_thickness() const { void StyleBoxLine::set_vertical(bool p_vertical) { vertical = p_vertical; + emit_changed(); } bool StyleBoxLine::is_vertical() const { return vertical; diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 2116dd0b1e..83f29503fa 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -190,10 +190,10 @@ void SurfaceTool::add_smooth_group(bool p_smooth) { } } -void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertexes, const Vector<Vector2> &p_uvs, const Vector<Color> &p_colors, const Vector<Vector2> &p_uv2s, const Vector<Vector3> &p_normals, const Vector<Plane> &p_tangents) { +void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs, const Vector<Color> &p_colors, const Vector<Vector2> &p_uv2s, const Vector<Vector3> &p_normals, const Vector<Plane> &p_tangents) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(primitive != Mesh::PRIMITIVE_TRIANGLES); - ERR_FAIL_COND(p_vertexes.size() < 3); + ERR_FAIL_COND(p_vertices.size() < 3); #define ADD_POINT(n) \ { \ @@ -207,10 +207,10 @@ void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertexes, const Vect add_normal(p_normals[n]); \ if (p_tangents.size() > n) \ add_tangent(p_tangents[n]); \ - add_vertex(p_vertexes[n]); \ + add_vertex(p_vertices[n]); \ } - for (int i = 0; i < p_vertexes.size() - 2; i++) { + for (int i = 0; i < p_vertices.size() - 2; i++) { ADD_POINT(0); ADD_POINT(i + 1); ADD_POINT(i + 2); @@ -1012,7 +1012,7 @@ void SurfaceTool::_bind_methods() { ClassDB::bind_method(D_METHOD("add_weights", "weights"), &SurfaceTool::add_weights); ClassDB::bind_method(D_METHOD("add_smooth_group", "smooth"), &SurfaceTool::add_smooth_group); - ClassDB::bind_method(D_METHOD("add_triangle_fan", "vertexes", "uvs", "colors", "uv2s", "normals", "tangents"), &SurfaceTool::add_triangle_fan, DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Color>()), DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Vector3>()), DEFVAL(Vector<Plane>())); + ClassDB::bind_method(D_METHOD("add_triangle_fan", "vertices", "uvs", "colors", "uv2s", "normals", "tangents"), &SurfaceTool::add_triangle_fan, DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Color>()), DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Vector3>()), DEFVAL(Vector<Plane>())); ClassDB::bind_method(D_METHOD("add_index", "index"), &SurfaceTool::add_index); diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index ef13238c13..a3b110f0d8 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -109,7 +109,7 @@ public: void add_weights(const Vector<float> &p_weights); void add_smooth_group(bool p_smooth); - void add_triangle_fan(const Vector<Vector3> &p_vertexes, const Vector<Vector2> &p_uvs = Vector<Vector2>(), const Vector<Color> &p_colors = Vector<Color>(), const Vector<Vector2> &p_uv2s = Vector<Vector2>(), const Vector<Vector3> &p_normals = Vector<Vector3>(), const Vector<Plane> &p_tangents = Vector<Plane>()); + void add_triangle_fan(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs = Vector<Vector2>(), const Vector<Color> &p_colors = Vector<Color>(), const Vector<Vector2> &p_uv2s = Vector<Vector2>(), const Vector<Vector3> &p_normals = Vector<Vector3>(), const Vector<Plane> &p_tangents = Vector<Plane>()); void add_index(int p_index); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index ff5900cd3e..3ca2b56d08 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -34,7 +34,7 @@ #include "core/io/image_loader.h" #include "core/method_bind_ext.gen.inc" #include "core/os/os.h" -#include "scene/resources/bit_mask.h" +#include "scene/resources/bit_map.h" Size2 Texture::get_size() const { @@ -157,7 +157,7 @@ bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const { void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic,sRGB,Mirrored Repeat")); - p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image")); + p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT)); p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, "")); } @@ -178,12 +178,6 @@ void ImageTexture::_reload_hook(const RID &p_hook) { _change_notify(); } -bool ImageTexture::keep_images_cached = false; - -void ImageTexture::set_keep_images_cached(bool p_enable) { - keep_images_cached = p_enable; -} - void ImageTexture::create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags) { flags = p_flags; @@ -205,9 +199,7 @@ void ImageTexture::create_from_image(const Ref<Image> &p_image, uint32_t p_flags VisualServer::get_singleton()->texture_set_data(texture, p_image); _change_notify(); - if (keep_images_cached) { - image_cache = p_image; - } + image_stored = true; } void ImageTexture::set_flags(uint32_t p_flags) { @@ -255,10 +247,7 @@ void ImageTexture::set_data(const Ref<Image> &p_image) { _change_notify(); alpha_cache.unref(); - - if (keep_images_cached) { - image_cache = p_image; - } + image_stored = true; } void ImageTexture::_resource_path_changed() { @@ -268,10 +257,10 @@ void ImageTexture::_resource_path_changed() { Ref<Image> ImageTexture::get_data() const { - if (image_cache.is_valid()) { - return image_cache; - } else { + if (image_stored) { return VisualServer::get_singleton()->texture_get_data(texture); + } else { + return Ref<Image>(); } } @@ -437,6 +426,8 @@ ImageTexture::ImageTexture() { texture = VisualServer::get_singleton()->texture_create(); storage = STORAGE_RAW; lossy_storage_quality = 0.7; + image_stored = false; + format = Image::FORMAT_L8; } ImageTexture::~ImageTexture() { @@ -492,7 +483,7 @@ Image::Format StreamTexture::get_format() const { return format; } -Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &flags, Ref<Image> &image, int p_size_limit) { +Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, int &flags, Ref<Image> &image, int p_size_limit) { alpha_cache.unref(); @@ -508,8 +499,11 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla ERR_FAIL_COND_V(header[0] != 'G' || header[1] != 'D' || header[2] != 'S' || header[3] != 'T', ERR_FILE_CORRUPT); } - tw = f->get_32(); - th = f->get_32(); + tw = f->get_16(); + tw_custom = f->get_16(); + th = f->get_16(); + th_custom = f->get_16(); + flags = f->get_32(); //texture flags! uint32_t df = f->get_32(); //data format @@ -662,16 +656,16 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla int sw = tw; int sh = th; - int mipmaps = Image::get_image_required_mipmaps(tw, th, format); + int mipmaps2 = Image::get_image_required_mipmaps(tw, th, format); int total_size = Image::get_image_data_size(tw, th, format, true); int idx = 0; int ofs = 0; - while (mipmaps > 1 && p_size_limit > 0 && (sw > p_size_limit || sh > p_size_limit)) { + while (mipmaps2 > 1 && p_size_limit > 0 && (sw > p_size_limit || sh > p_size_limit)) { sw = MAX(sw >> 1, 1); sh = MAX(sh >> 1, 1); - mipmaps--; + mipmaps2--; idx++; } @@ -698,7 +692,7 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla int expected = total_size - ofs; if (bytes < expected) { - //this is a compatibility workaround for older format, which saved less mipmaps. It is still recommended the image is reimported. + //this is a compatibility workaround for older format, which saved less mipmaps2. It is still recommended the image is reimported. zeromem(w.ptr() + bytes, (expected - bytes)); } else if (bytes != expected) { ERR_FAIL_V(ERR_FILE_CORRUPT); @@ -716,18 +710,26 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla Error StreamTexture::load(const String &p_path) { - int lw, lh, lflags; + int lw, lh, lwc, lhc, lflags; Ref<Image> image; image.instance(); - Error err = _load_data(p_path, lw, lh, lflags, image); + Error err = _load_data(p_path, lw, lh, lwc, lhc, lflags, image); if (err) return err; + if (get_path() == String()) { + //temporarily set path if no path set for resource, helps find errors + VisualServer::get_singleton()->texture_set_path(texture, p_path); + } VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), 0, image->get_format(), VS::TEXTURE_TYPE_2D, lflags); VS::get_singleton()->texture_set_data(texture, image); + if (lwc || lhc) { + VS::get_singleton()->texture_set_size_override(texture, lwc, lhc, 0); + } else { + } - w = lw; - h = lh; + w = lwc ? lwc : lw; + h = lhc ? lhc : lh; flags = lflags; path_to_file = p_path; format = image->get_format(); @@ -795,6 +797,7 @@ bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const { decom->decompress(); img = decom; } + alpha_cache.instance(); alpha_cache->create_from_image_alpha(img); } @@ -839,6 +842,12 @@ void StreamTexture::reload_from_file() { load(path); } +void StreamTexture::_validate_property(PropertyInfo &property) const { + if (property.name == "flags") { + property.usage = PROPERTY_USAGE_NOEDITOR; + } +} + void StreamTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("load", "path"), &StreamTexture::load); @@ -1513,6 +1522,7 @@ CubeMap::CubeMap() { cubemap = VisualServer::get_singleton()->texture_create(); storage = STORAGE_RAW; lossy_storage_quality = 0.7; + format = Image::FORMAT_BPTC_RGBA; } CubeMap::~CubeMap() { diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 4b5b504510..281a33929c 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -37,8 +37,8 @@ #include "core/os/rw_lock.h" #include "core/os/thread_safe.h" #include "core/resource.h" -#include "scene/resources/color_ramp.h" #include "scene/resources/curve.h" +#include "scene/resources/gradient.h" #include "servers/visual_server.h" /** @@ -111,7 +111,7 @@ private: Size2 size_override; float lossy_storage_quality; mutable Ref<BitMap> alpha_cache; - Ref<Image> image_cache; + bool image_stored; protected: virtual void reload_from_file(); @@ -126,11 +126,7 @@ protected: void _set_data(Dictionary p_data); - static bool keep_images_cached; - public: - static void set_keep_images_cached(bool p_enable); - void create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags = FLAGS_DEFAULT); void create_from_image(const Ref<Image> &p_image, uint32_t p_flags = FLAGS_DEFAULT); @@ -191,7 +187,7 @@ public: }; private: - Error _load_data(const String &p_path, int &tw, int &th, int &flags, Ref<Image> &image, int p_size_limit = 0); + Error _load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, int &flags, Ref<Image> &image, int p_size_limit = 0); String path_to_file; RID texture; Image::Format format; @@ -207,6 +203,7 @@ private: protected: static void _bind_methods(); + void _validate_property(PropertyInfo &property) const; public: typedef void (*TextureFormatRequestCallback)(const Ref<StreamTexture> &); diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 8d1a24dbf8..69258bc834 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -621,8 +621,8 @@ void Theme::clear() { void Theme::copy_default_theme() { - Ref<Theme> default_theme = get_default(); - copy_theme(default_theme); + Ref<Theme> default_theme2 = get_default(); + copy_theme(default_theme2); } void Theme::copy_theme(const Ref<Theme> &p_other) { diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 5a2e7245a2..4ddfc0331b 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -30,6 +30,7 @@ #include "tile_set.h" #include "core/array.h" +#include "core/engine.h" bool TileSet::_set(const StringName &p_name, const Variant &p_value) { @@ -614,7 +615,7 @@ Vector2 TileSet::autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, if (coords.size() == 0) { return autotile_get_icon_coordinate(p_id); } else { - return coords[Math::random(0, (int)coords.size())]; + return coords[Math::rand() % coords.size()]; } } @@ -662,6 +663,7 @@ void TileSet::tile_set_shape(int p_id, int p_shape_id, const Ref<Shape2D> &p_sha if (tile_map[p_id].shapes_data.size() <= p_shape_id) tile_map[p_id].shapes_data.resize(p_shape_id + 1); tile_map[p_id].shapes_data.write[p_shape_id].shape = p_shape; + _decompose_convex_shape(p_shape); emit_changed(); } @@ -844,6 +846,9 @@ void TileSet::tile_set_shapes(int p_id, const Vector<ShapeData> &p_shapes) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].shapes_data = p_shapes; + for (int i = 0; i < p_shapes.size(); i++) { + _decompose_convex_shape(p_shapes[i].shape); + } emit_changed(); } @@ -888,9 +893,10 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) { } else if (p_shapes[i].get_type() == Variant::DICTIONARY) { Dictionary d = p_shapes[i]; - if (d.has("shape") && d["shape"].get_type() == Variant::OBJECT) + if (d.has("shape") && d["shape"].get_type() == Variant::OBJECT) { s.shape = d["shape"]; - else + _decompose_convex_shape(s.shape); + } else continue; if (d.has("shape_transform") && d["shape_transform"].get_type() == Variant::TRANSFORM2D) @@ -956,6 +962,26 @@ Array TileSet::_get_tiles_ids() const { return arr; } +void TileSet::_decompose_convex_shape(Ref<Shape2D> p_shape) { + if (Engine::get_singleton()->is_editor_hint()) + return; + Ref<ConvexPolygonShape2D> convex = p_shape; + if (!convex.is_valid()) + return; + Vector<Vector<Vector2> > decomp = Geometry::decompose_polygon_in_convex(convex->get_points()); + if (decomp.size() > 1) { + Array sub_shapes; + for (int i = 0; i < decomp.size(); i++) { + Ref<ConvexPolygonShape2D> _convex = memnew(ConvexPolygonShape2D); + _convex->set_points(decomp[i]); + sub_shapes.append(_convex); + } + convex->set_meta("decomposed", sub_shapes); + } else { + convex->set_meta("decomposed", Variant()); + } +} + void TileSet::get_tile_list(List<int> *p_tiles) const { for (Map<int, TileData>::Element *E = tile_map.front(); E; E = E->next()) { diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 4800371d3c..fac48243d0 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -35,6 +35,7 @@ #include "core/resource.h" #include "scene/2d/light_occluder_2d.h" #include "scene/2d/navigation_polygon.h" +#include "scene/resources/convex_polygon_shape_2d.h" #include "scene/resources/shape_2d.h" #include "scene/resources/texture.h" @@ -134,6 +135,7 @@ protected: void _tile_set_shapes(int p_id, const Array &p_shapes); Array _tile_get_shapes(int p_id) const; Array _get_tiles_ids() const; + void _decompose_convex_shape(Ref<Shape2D> p_shape); static void _bind_methods(); diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index d96b37938f..4e5909eb2e 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -569,7 +569,7 @@ bool VisualShader::_set(const StringName &p_name, const Variant &p_value) { String mode = name.get_slicec('/', 1); int value = p_value; if (value == 0) { - modes.erase(mode); //means its default anyway, so dont store it + modes.erase(mode); //means it's default anyway, so don't store it } else { modes[mode] = value; } @@ -1087,6 +1087,8 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "attenuation", "ATTENUATION" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "albedo", "ALBEDO" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "transmission", "TRANSMISSION" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "diffuse", "DIFFUSE_LIGHT" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "specular", "SPECULAR_LIGHT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "roughness", "ROUGHNESS" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index a89b70d1ea..e47069d723 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -324,7 +324,7 @@ String VisualShaderNodeTexture::generate_global(Shader::Mode p_mode, VisualShade String u = "uniform sampler2D " + make_unique_id(p_type, p_id, "tex"); switch (texture_type) { case TYPE_DATA: break; - case TYPE_COLOR: u += " : hint_color"; break; + case TYPE_COLOR: u += " : hint_albedo"; break; case TYPE_NORMALMAP: u += " : hint_normal"; break; } return u + ";"; @@ -554,7 +554,7 @@ String VisualShaderNodeCubeMap::generate_global(Shader::Mode p_mode, VisualShade String u = "uniform sampler2DCube " + make_unique_id(p_type, p_id, "cube"); switch (texture_type) { case TYPE_DATA: break; - case TYPE_COLOR: u += " : hint_color"; break; + case TYPE_COLOR: u += " : hint_albedo"; break; case TYPE_NORMALMAP: u += " : hint_normal"; break; } return u + ";"; @@ -1136,7 +1136,7 @@ String VisualShaderNodeScalarFunc::generate_code(Shader::Mode p_mode, VisualShad "round($)", "ceil($)", "fract($)", - "min(max($,0),1)", + "min(max($,0.0),1.0)", "-($)", }; diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index 305e4fc735..634f4d7160 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -203,4 +203,6 @@ SceneStringNames::SceneStringNames() { _mesh_changed = StaticCString::create("_mesh_changed"); parameters_base_path = "parameters/"; + + tracks_changed = "tracks_changed"; } diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 103b06dbc1..bc75165b8c 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -32,7 +32,7 @@ #define SCENE_STRING_NAMES_H #include "core/node_path.h" -#include "core/string_db.h" +#include "core/string_name.h" class SceneStringNames { friend void register_scene_types(); @@ -205,6 +205,8 @@ public: StringName parameters_base_path; + StringName tracks_changed; + enum { MAX_MATERIALS = 32 }; |