diff options
42 files changed, 232 insertions, 484 deletions
diff --git a/doc/classes/Curve3D.xml b/doc/classes/Curve3D.xml index b2e64f96a6..e9ee1c6974 100644 --- a/doc/classes/Curve3D.xml +++ b/doc/classes/Curve3D.xml @@ -225,7 +225,7 @@ </argument> <description> Sets the tilt angle in radians for the point [code]idx[/code]. If the index is out of bounds, the function sends an error to the console. - The tilt controls the rotation along the look-at axis an object traveling the path would have. In the case of a curve controlling a [PathFollow] or [OrientedPathFollow], this tilt is an offset over the natural tilt the [PathFollow] or [OrientedPathFollow] calculates. + The tilt controls the rotation along the look-at axis an object traveling the path would have. In the case of a curve controlling a [PathFollow], this tilt is an offset over the natural tilt the [PathFollow] calculates. </description> </method> <method name="tessellate" qualifiers="const"> @@ -248,7 +248,7 @@ The distance in meters between two adjacent cached points. Changing it forces the cache to be recomputed the next time the [method get_baked_points] or [method get_baked_length] function is called. The smaller the distance, the more points in the cache and the more memory it will consume, so use with care. </member> <member name="up_vector_enabled" type="bool" setter="set_up_vector_enabled" getter="is_up_vector_enabled"> - If [code]true[/code], the curve will bake up vectors used for orientation. See [OrientedPathFollow]. Changing it forces the cache to be recomputed. + If [code]true[/code], the curve will bake up vectors used for orientation. This is used when a [member PathFollow.rotation_mode] is set to [code]ROTATION_ORIENTED[/code], see [PathFollow] for details. Changing it forces the cache to be recomputed. </member> </members> <constants> diff --git a/doc/classes/KinematicBody2D.xml b/doc/classes/KinematicBody2D.xml index 12d2bcec77..986010f832 100644 --- a/doc/classes/KinematicBody2D.xml +++ b/doc/classes/KinematicBody2D.xml @@ -94,7 +94,7 @@ [i]TODO: Update for stop_on_slope argument.[/i] If the body is standing on a slope and the horizontal speed (relative to the floor's speed) goes below [code]slope_stop_min_velocity[/code], the body will stop completely. This prevents the body from sliding down slopes when you include gravity in [code]linear_velocity[/code]. When set to lower values, the body will not be able to stand still on steep slopes. If the body collides, it will change direction a maximum of [code]max_slides[/code] times before it stops. [code]floor_max_angle[/code] is the maximum angle (in radians) where a slope is still considered a floor (or a ceiling), rather than a wall. The default value equals 45 degrees. - Returns the movement that remained when the body stopped. To get more detailed information about collisions that occurred, use [method get_slide_collision]. + Returns the [code]linear_velocity[/code] vector, rotated and/or scaled if a slide collision occurred. To get more detailed information about collisions that occurred, use [method get_slide_collision]. </description> </method> <method name="move_and_slide_with_snap"> diff --git a/doc/classes/OrientedPathFollow.xml b/doc/classes/OrientedPathFollow.xml deleted file mode 100644 index 665e3af6b2..0000000000 --- a/doc/classes/OrientedPathFollow.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="OrientedPathFollow" inherits="Spatial" category="Core" version="3.1"> - <brief_description> - Oriented point sampler for a [Path]. - </brief_description> - <description> - This node behaves like [PathFollow], except it uses its parent [Path] up vector information to enforce orientation. - Make sure to check if the curve of this node's parent [Path] has up vectors enabled. See [PathFollow] and [Curve3D] for further information. - </description> - <tutorials> - </tutorials> - <demos> - </demos> - <methods> - </methods> - <members> - <member name="cubic_interp" type="bool" setter="set_cubic_interpolation" getter="get_cubic_interpolation"> - If [code]true[/code], the position between two cached points is interpolated cubically, and linearly otherwise. - The points along the [Curve3D] of the [Path] are precomputed before use, for faster calculations. The point at the requested offset is then calculated interpolating between two adjacent cached points. This may present a problem if the curve makes sharp turns, as the cached points may not follow the curve closely enough. - There are two answers to this problem: Either increase the number of cached points and increase memory consumption, or make a cubic interpolation between two points at the cost of (slightly) slower calculations. - </member> - <member name="h_offset" type="float" setter="set_h_offset" getter="get_h_offset"> - The node's offset along the curve. - </member> - <member name="loop" type="bool" setter="set_loop" getter="has_loop"> - If [code]true[/code], any offset outside the path's length will wrap around, instead of stopping at the ends. Use it for cyclic paths. - </member> - <member name="offset" type="float" setter="set_offset" getter="get_offset"> - The distance from the first vertex, measured in 3D units along the path. This sets this node's position to a point within the path. - </member> - <member name="unit_offset" type="float" setter="set_unit_offset" getter="get_unit_offset"> - The distance from the first vertex, considering 0.0 as the first vertex and 1.0 as the last. This is just another way of expressing the offset within the path, as the offset supplied is multiplied internally by the path's length. - </member> - <member name="v_offset" type="float" setter="set_v_offset" getter="get_v_offset"> - The node's offset perpendicular to the curve. - </member> - </members> - <constants> - </constants> -</class> diff --git a/doc/classes/PathFollow.xml b/doc/classes/PathFollow.xml index ed4a805a00..da4782a7c3 100644 --- a/doc/classes/PathFollow.xml +++ b/doc/classes/PathFollow.xml @@ -51,5 +51,8 @@ <constant name="ROTATION_XYZ" value="3" enum="RotationMode"> Allows the PathFollow to rotate in any axis. </constant> + <constant name="ROTATION_ORIENTED" value="4" enum="RotationMode"> + Uses the up vector information in a [Curve3D] to enforce orientation. This rotation mode requires the [Path]'s [member Curve3D.up_vector_enabled] property to be set to [code]true[/code]. + </constant> </constants> </class> diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp index bbae3d3d22..e6ec6fb4fd 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_gles2.cpp @@ -93,6 +93,7 @@ void RasterizerCanvasGLES2::_set_uniforms() { glBindTexture(GL_TEXTURE_2D, cls->distance); state.canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_MATRIX, light->shadow_matrix_cache); state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_SHADOW_COLOR, light->shadow_color); + state.canvas_shader.set_uniform(CanvasShaderGLES2::SHADOWPIXEL_SIZE, (1.0 / light->shadow_buffer_size) * (1.0 + light->shadow_smooth)); if (light->radius_cache == 0) { state.canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_GRADIENT, 0.0); @@ -1446,25 +1447,20 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_SHADOWS, has_shadow); if (has_shadow) { state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_USE_GRADIENT, light->shadow_gradient_length > 0); - switch (light->shadow_filter) { - - case VS::CANVAS_LIGHT_FILTER_NONE: state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_NEAREST, true); break; - case VS::CANVAS_LIGHT_FILTER_PCF3: state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF3, true); break; - case VS::CANVAS_LIGHT_FILTER_PCF5: state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF5, true); break; - case VS::CANVAS_LIGHT_FILTER_PCF7: state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF7, true); break; - case VS::CANVAS_LIGHT_FILTER_PCF9: state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF9, true); break; - case VS::CANVAS_LIGHT_FILTER_PCF13: state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF13, true); break; - } + state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_NEAREST, light->shadow_filter == VS::CANVAS_LIGHT_FILTER_NONE); + state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF3, light->shadow_filter == VS::CANVAS_LIGHT_FILTER_PCF3); + state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF5, light->shadow_filter == VS::CANVAS_LIGHT_FILTER_PCF5); + state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF7, light->shadow_filter == VS::CANVAS_LIGHT_FILTER_PCF7); + state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF9, light->shadow_filter == VS::CANVAS_LIGHT_FILTER_PCF9); + state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF13, light->shadow_filter == VS::CANVAS_LIGHT_FILTER_PCF13); } - bool light_rebind = state.canvas_shader.bind(); + state.canvas_shader.bind(); state.using_light = light; state.using_shadow = has_shadow; - if (light_rebind) { - - _set_uniforms(); - } + //always re-set uniforms, since light parameters changed + _set_uniforms(); glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4); RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(light->texture); diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index aef12b58d2..af698f3988 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -4204,6 +4204,7 @@ void RasterizerStorageGLES2::render_target_set_msaa(RID p_render_target, VS::Vie RID RasterizerStorageGLES2::canvas_light_shadow_buffer_create(int p_width) { CanvasLightShadow *cls = memnew(CanvasLightShadow); + if (p_width > config.max_texture_size) p_width = config.max_texture_size; diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 06b84aeab4..79fec63db0 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -158,7 +158,10 @@ void RasterizerCanvasGLES3::canvas_begin() { state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_LIGHTING, false); state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SHADOWS, false); state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_NEAREST, false); + state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF3, false); state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF5, false); + state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF7, false); + state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF9, false); state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF13, false); state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_DISTANCE_FIELD, false); state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_NINEPATCH, false); @@ -1558,15 +1561,12 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SHADOWS, has_shadow); if (has_shadow) { state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_USE_GRADIENT, light->shadow_gradient_length > 0); - switch (light->shadow_filter) { - - case VS::CANVAS_LIGHT_FILTER_NONE: state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_NEAREST, true); break; - case VS::CANVAS_LIGHT_FILTER_PCF3: state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF3, true); break; - case VS::CANVAS_LIGHT_FILTER_PCF5: state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF5, true); break; - case VS::CANVAS_LIGHT_FILTER_PCF7: state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF7, true); break; - case VS::CANVAS_LIGHT_FILTER_PCF9: state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF9, true); break; - case VS::CANVAS_LIGHT_FILTER_PCF13: state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF13, true); break; - } + state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_NEAREST, light->shadow_filter == VS::CANVAS_LIGHT_FILTER_NONE); + state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF3, light->shadow_filter == VS::CANVAS_LIGHT_FILTER_PCF3); + state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF5, light->shadow_filter == VS::CANVAS_LIGHT_FILTER_PCF5); + state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF7, light->shadow_filter == VS::CANVAS_LIGHT_FILTER_PCF7); + state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF9, light->shadow_filter == VS::CANVAS_LIGHT_FILTER_PCF9); + state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF13, light->shadow_filter == VS::CANVAS_LIGHT_FILTER_PCF13); } bool light_rebind = state.canvas_shader.bind(); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 920c587f2b..24673c8755 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -634,14 +634,14 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_ #ifndef GLES_OVER_GL switch (p_format) { - case Image::Format::FORMAT_RF: - case Image::Format::FORMAT_RGF: - case Image::Format::FORMAT_RGBF: - case Image::Format::FORMAT_RGBAF: - case Image::Format::FORMAT_RH: - case Image::Format::FORMAT_RGH: - case Image::Format::FORMAT_RGBH: - case Image::Format::FORMAT_RGBAH: { + case Image::FORMAT_RF: + case Image::FORMAT_RGF: + case Image::FORMAT_RGBF: + case Image::FORMAT_RGBAF: + case Image::FORMAT_RH: + case Image::FORMAT_RGH: + case Image::FORMAT_RGBH: + case Image::FORMAT_RGBAH: { if (!config.texture_float_linear_supported) { // disable linear texture filtering when not supported for float format on some devices (issue #24295) p_flags &= ~VS::TEXTURE_FLAG_FILTER; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 9169227e8a..719130621e 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -494,7 +494,7 @@ void EditorNode::_fs_changed() { } } - get_tree()->quit(); + _exit_editor(); } } @@ -1120,7 +1120,7 @@ void EditorNode::save_all_scenes_and_restart() { to_reopen = get_tree()->get_edited_scene_root()->get_filename(); } - get_tree()->quit(); + _exit_editor(); String exec = OS::get_singleton()->get_executable_path(); List<String> args; @@ -2356,6 +2356,12 @@ int EditorNode::_next_unsaved_scene(bool p_valid_filename, int p_start) { return -1; } +void EditorNode::_exit_editor() { + exiting = true; + resource_preview->stop(); //stop early to avoid crashes + get_tree()->quit(); +} + void EditorNode::_discard_changes(const String &p_str) { switch (current_option) { @@ -2383,14 +2389,13 @@ void EditorNode::_discard_changes(const String &p_str) { case FILE_QUIT: { _menu_option_confirm(RUN_STOP, true); - exiting = true; - get_tree()->quit(); + _exit_editor(); + } break; case RUN_PROJECT_MANAGER: { _menu_option_confirm(RUN_STOP, true); - exiting = true; - get_tree()->quit(); + _exit_editor(); String exec = OS::get_singleton()->get_executable_path(); List<String> args; diff --git a/editor/editor_node.h b/editor/editor_node.h index d7d969fb16..13bebea5f0 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -470,6 +470,8 @@ private: void _dropped_files(const Vector<String> &p_files, int p_screen); String _recent_scene; + void _exit_editor(); + bool convert_old; void _unhandled_input(const Ref<InputEvent> &p_event); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 72545f6b19..e33b26d9cb 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -2397,7 +2397,7 @@ void EditorPropertyResource::_update_menu() { void EditorPropertyResource::_sub_inspector_property_keyed(const String &p_property, const Variant &p_value, bool) { - emit_signal("property_keyed_with_value", String(get_edited_property()) + ":" + p_property, p_value); + emit_signal("property_keyed_with_value", String(get_edited_property()) + ":" + p_property, p_value, false); } void EditorPropertyResource::_sub_inspector_resource_selected(const RES &p_resource, const String &p_property) { diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index 25139b0163..368efbc48f 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -416,6 +416,16 @@ void EditorResourcePreview::check_for_invalidation(const String &p_path) { } } +void EditorResourcePreview::stop() { + if (thread) { + exit = true; + preview_sem->post(); + Thread::wait_to_finish(thread); + memdelete(thread); + thread = NULL; + } +} + EditorResourcePreview::EditorResourcePreview() { singleton = this; preview_mutex = Mutex::create(); @@ -428,10 +438,7 @@ EditorResourcePreview::EditorResourcePreview() { EditorResourcePreview::~EditorResourcePreview() { - exit = true; - preview_sem->post(); - Thread::wait_to_finish(thread); - memdelete(thread); + stop(); memdelete(preview_mutex); memdelete(preview_sem); } diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h index 055ecc6bbf..85ac78d58f 100644 --- a/editor/editor_resource_preview.h +++ b/editor/editor_resource_preview.h @@ -126,6 +126,8 @@ public: void remove_preview_generator(const Ref<EditorResourcePreviewGenerator> &p_generator); void check_for_invalidation(const String &p_path); + void stop(); + EditorResourcePreview(); ~EditorResourcePreview(); }; diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 58af5285b9..1ac66fdd1d 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -51,7 +51,7 @@ Ref<Texture> FileSystemDock::_get_tree_item_icon(EditorFileSystemDirectory *p_di return file_icon; } -bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths) { +bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites) { bool parent_should_expand = false; @@ -66,7 +66,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory subdirectory_item->set_selectable(0, true); String lpath = p_dir->get_path(); subdirectory_item->set_metadata(0, lpath); - if (path == lpath || ((display_mode_setting == DISPLAY_MODE_SETTING_SPLIT) && path.get_base_dir() == lpath)) { + if (!p_select_in_favorites && (path == lpath || ((display_mode_setting == DISPLAY_MODE_SETTING_SPLIT) && path.get_base_dir() == lpath))) { subdirectory_item->select(0); } @@ -81,7 +81,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory // Create items for all subdirectories for (int i = 0; i < p_dir->get_subdir_count(); i++) - parent_should_expand = (_create_tree(subdirectory_item, p_dir->get_subdir(i), uncollapsed_paths) || parent_should_expand); + parent_should_expand = (_create_tree(subdirectory_item, p_dir->get_subdir(i), uncollapsed_paths, p_select_in_favorites) || parent_should_expand); // Create all items for the files in the subdirectory if (display_mode_setting == DISPLAY_MODE_SETTING_TREE_ONLY) { @@ -103,7 +103,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory file_item->set_icon(0, _get_tree_item_icon(p_dir, i)); String file_metadata = lpath.plus_file(file_name); file_item->set_metadata(0, file_metadata); - if (path == file_metadata) { + if (!p_select_in_favorites && path == file_metadata) { file_item->select(0); file_item->set_as_cursor(0); } @@ -156,7 +156,7 @@ Vector<String> FileSystemDock::_compute_uncollapsed_paths() { return uncollapsed_paths; } -void FileSystemDock::_update_tree(const Vector<String> p_uncollapsed_paths, bool p_uncollapse_root) { +void FileSystemDock::_update_tree(const Vector<String> p_uncollapsed_paths, bool p_uncollapse_root, bool p_select_in_favorites) { // Recreate the tree tree->clear(); @@ -205,6 +205,10 @@ void FileSystemDock::_update_tree(const Vector<String> p_uncollapsed_paths, bool ti->set_tooltip(0, fave); ti->set_selectable(0, true); ti->set_metadata(0, fave); + if (p_select_in_favorites && fave == path) { + ti->select(0); + ti->set_as_cursor(0); + } if (!fave.ends_with("/")) { Array udata; udata.push_back(tree_update_id); @@ -220,7 +224,7 @@ void FileSystemDock::_update_tree(const Vector<String> p_uncollapsed_paths, bool } // Create the remaining of the tree - _create_tree(root, EditorFileSystem::get_singleton()->get_filesystem(), uncollapsed_paths); + _create_tree(root, EditorFileSystem::get_singleton()->get_filesystem(), uncollapsed_paths, p_select_in_favorites); tree->ensure_cursor_is_visible(); updating_tree = false; } @@ -296,7 +300,7 @@ void FileSystemDock::_notification(int p_what) { file_list_popup->connect("id_pressed", this, "_file_list_rmb_option"); tree_popup->connect("id_pressed", this, "_tree_rmb_option"); - current_path->connect("text_entered", this, "navigate_to_path"); + current_path->connect("text_entered", this, "_navigate_to_path"); display_mode_setting = DisplayModeSetting(int(EditorSettings::get_singleton()->get("docks/filesystem/display_mode"))); always_show_folders = bool(EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders")); @@ -442,8 +446,7 @@ void FileSystemDock::_set_current_path_text(const String &p_path) { } } -void FileSystemDock::navigate_to_path(const String &p_path) { - +void FileSystemDock::_navigate_to_path(const String &p_path, bool p_select_in_favorites) { if (p_path == "Favorites") { path = p_path; } else { @@ -466,7 +469,7 @@ void FileSystemDock::navigate_to_path(const String &p_path) { _set_current_path_text(path); _push_to_history(); - _update_tree(_compute_uncollapsed_paths()); + _update_tree(_compute_uncollapsed_paths(), false, p_select_in_favorites); if (display_mode == DISPLAY_MODE_SPLIT) { _update_file_list(false); } @@ -483,6 +486,10 @@ void FileSystemDock::navigate_to_path(const String &p_path) { } } +void FileSystemDock::navigate_to_path(const String &p_path) { + _navigate_to_path(p_path); +} + void FileSystemDock::_file_list_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata) { if ((file_list_vb->is_visible_in_tree() || path == p_path.get_base_dir()) && p_preview.is_valid()) { @@ -790,7 +797,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { } } -void FileSystemDock::_select_file(const String p_path) { +void FileSystemDock::_select_file(const String p_path, bool p_select_in_favorites) { String fpath = p_path; if (fpath.ends_with("/")) { if (fpath != "res://") { @@ -803,17 +810,21 @@ void FileSystemDock::_select_file(const String p_path) { editor->load_resource(fpath); } } - navigate_to_path(fpath); + _navigate_to_path(fpath, p_select_in_favorites); } void FileSystemDock::_tree_activate_file() { TreeItem *selected = tree->get_selected(); if (selected) { - call_deferred("_select_file", selected->get_metadata(0)); + String path = selected->get_metadata(0); + TreeItem *parent = selected->get_parent(); + bool is_favorite = parent != NULL && parent->get_metadata(0) == "Favorites"; - if (path.ends_with("/") || path == "Favorites") { + if ((!is_favorite && path.ends_with("/")) || path == "Favorites") { bool collapsed = selected->is_collapsed(); selected->set_collapsed(!collapsed); + } else { + _select_file(path, is_favorite && !path.ends_with("/")); } } } @@ -2141,7 +2152,7 @@ void FileSystemDock::_file_list_rmb_pressed(const Vector2 &p_pos) { void FileSystemDock::select_file(const String &p_file) { - navigate_to_path(p_file); + _navigate_to_path(p_file); } void FileSystemDock::_file_multi_selected(int p_index, bool p_selected) { @@ -2292,7 +2303,7 @@ void FileSystemDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_file_list_activate_file"), &FileSystemDock::_file_list_activate_file); ClassDB::bind_method(D_METHOD("_tree_activate_file"), &FileSystemDock::_tree_activate_file); ClassDB::bind_method(D_METHOD("_select_file"), &FileSystemDock::_select_file); - ClassDB::bind_method(D_METHOD("navigate_to_path"), &FileSystemDock::navigate_to_path); + ClassDB::bind_method(D_METHOD("_navigate_to_path"), &FileSystemDock::_navigate_to_path); ClassDB::bind_method(D_METHOD("_change_file_display"), &FileSystemDock::_change_file_display); ClassDB::bind_method(D_METHOD("_fw_history"), &FileSystemDock::_fw_history); ClassDB::bind_method(D_METHOD("_bw_history"), &FileSystemDock::_bw_history); @@ -2310,6 +2321,7 @@ void FileSystemDock::_bind_methods() { ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &FileSystemDock::get_drag_data_fw); ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &FileSystemDock::can_drop_data_fw); ClassDB::bind_method(D_METHOD("drop_data_fw"), &FileSystemDock::drop_data_fw); + ClassDB::bind_method(D_METHOD("navigate_to_path"), &FileSystemDock::navigate_to_path); ClassDB::bind_method(D_METHOD("_preview_invalidated"), &FileSystemDock::_preview_invalidated); ClassDB::bind_method(D_METHOD("_file_multi_selected"), &FileSystemDock::_file_multi_selected); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 1f8ae698a3..237413acc4 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -178,9 +178,10 @@ private: bool import_dock_needs_update; Ref<Texture> _get_tree_item_icon(EditorFileSystemDirectory *p_dir, int p_idx); - bool _create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths); + bool _create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites); Vector<String> _compute_uncollapsed_paths(); - void _update_tree(const Vector<String> p_uncollapsed_paths = Vector<String>(), bool p_uncollapse_root = false); + void _update_tree(const Vector<String> p_uncollapsed_paths = Vector<String>(), bool p_uncollapse_root = false, bool p_select_in_favorites = false); + void _navigate_to_path(const String &p_path, bool p_select_in_favorites = false); void _file_list_gui_input(Ref<InputEvent> p_event); void _tree_gui_input(Ref<InputEvent> p_event); @@ -192,7 +193,7 @@ private: void _tree_toggle_collapsed(); - void _select_file(const String p_path); + void _select_file(const String p_path, bool p_select_in_favorites = false); void _tree_activate_file(); void _file_list_activate_file(int p_idx); void _file_multi_selected(int p_index, bool p_selected); diff --git a/editor/icons/icon_oriented_path_follow.svg b/editor/icons/icon_oriented_path_follow.svg deleted file mode 100644 index bd3f585e54..0000000000 --- a/editor/icons/icon_oriented_path_follow.svg +++ /dev/null @@ -1,5 +0,0 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m13 0l-3 4h1.9473c-0.1385 1.3203-0.5583 1.9074-1.084 2.2754-0.64426 0.451-1.7129 0.60547-2.9629 0.73047s-2.6814 0.22053-3.9121 1.082c-0.89278 0.62493-1.5321 1.6522-1.8184 3.0957a2 2 0 0 0 -1.1699 1.8164 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -0.84961 -1.6328c0.19235-0.88496 0.55306-1.3373 0.98633-1.6406 0.64426-0.451 1.7129-0.60547 2.9629-0.73047s2.6814-0.22053 3.9121-1.082c1.0528-0.73697 1.7552-2.032 1.9375-3.9141h2.0508l-3-4z" fill="#fc9c9c" fill-opacity=".99608"/> -</g> -</svg> diff --git a/editor/plugins/item_list_editor_plugin.cpp b/editor/plugins/item_list_editor_plugin.cpp index d9861c91e0..db0816064c 100644 --- a/editor/plugins/item_list_editor_plugin.cpp +++ b/editor/plugins/item_list_editor_plugin.cpp @@ -109,7 +109,7 @@ void ItemListPlugin::_get_property_list(List<PropertyInfo> *p_list) const { int flags = get_flags(); if (flags & FLAG_CHECKABLE) { - p_list->push_back(PropertyInfo(Variant::BOOL, base + "checkable", PROPERTY_HINT_ENUM, "No,As checkbox,As radio button")); + p_list->push_back(PropertyInfo(Variant::INT, base + "checkable", PROPERTY_HINT_ENUM, "No,As checkbox,As radio button")); p_list->push_back(PropertyInfo(Variant::BOOL, base + "checked")); } diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index daa7f92dcf..be1c4a36bd 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -563,6 +563,20 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (node == root) return; + //check that from node to root, all owners are right + + if (node->get_owner() != root) { + accept->set_text(TTR("Node must belong to the edited scene to become root.")); + accept->popup_centered_minsize(); + return; + } + + if (node->get_filename() != String()) { + accept->set_text(TTR("Instantiated scenes can't become root")); + accept->popup_centered_minsize(); + return; + } + editor_data->get_undo_redo().create_action("Make node as Root"); editor_data->get_undo_redo().add_do_method(node->get_parent(), "remove_child", node); editor_data->get_undo_redo().add_do_method(root->get_parent(), "remove_child", root); diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 2b6b66d7b6..e59b57b39a 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -486,7 +486,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: script = codegen.script; } else { StringName name = cn->cast_type.class_type->name; - if (class_map[name] == codegen.script->subclasses[name]) { + if (codegen.script->subclasses.has(name) && class_map[name] == codegen.script->subclasses[name]) { idx = codegen.get_name_map_pos(name); idx |= GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT << GDScriptFunction::ADDR_BITS; } else { @@ -1183,7 +1183,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: script = codegen.script; } else { StringName name = assign_type.class_type->name; - if (class_map[name] == codegen.script->subclasses[name]) { + if (codegen.script->subclasses.has(name) && class_map[name] == codegen.script->subclasses[name]) { idx = codegen.get_name_map_pos(name); idx |= GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT << GDScriptFunction::ADDR_BITS; } else { diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 1292e11209..a012ccad30 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -5062,7 +5062,7 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class) { if (ScriptServer::is_global_class(base)) { base_script = ResourceLoader::load(ScriptServer::get_global_class_path(base)); if (!base_script.is_valid()) { - _set_error("Class '" + base + "' could not be fully loaded (script error or cyclic inheritance).", p_class->line); + _set_error("Class '" + base + "' could not be fully loaded (script error or cyclic dependency).", p_class->line); return; } p = NULL; @@ -5391,7 +5391,7 @@ GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source, Ref<GDScript> gds = script; if (gds.is_valid()) { if (!gds->is_valid()) { - _set_error("Class '" + id + "' could not be fully loaded (script error or cyclic inheritance).", p_line); + _set_error("Class '" + id + "' could not be fully loaded (script error or cyclic dependency).", p_line); return DataType(); } result.kind = DataType::GDSCRIPT; @@ -5936,7 +5936,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { int idx = current_function->arguments.find(id->name); node_type = current_function->argument_types[idx]; } else { - node_type = _reduce_identifier_type(NULL, id->name, id->line); + node_type = _reduce_identifier_type(NULL, id->name, id->line, false); } } break; case Node::TYPE_CAST: { @@ -6186,7 +6186,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { result.is_constant = false; node_type = result; } else { - node_type = _reduce_identifier_type(&base_type, member_id->name, op->line); + node_type = _reduce_identifier_type(&base_type, member_id->name, op->line, true); #ifdef DEBUG_ENABLED if (!node_type.has_type) { _add_warning(GDScriptWarning::UNSAFE_PROPERTY_ACCESS, op->line, member_id->name.operator String(), base_type.to_string()); @@ -6902,9 +6902,9 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN if (!base_type.is_meta_type) { for (int i = 0; i < base->variables.size(); i++) { - ClassNode::Member m = base->variables[i]; - if (m.identifier == p_member) { - r_member_type = m.data_type; + if (base->variables[i].identifier == p_member) { + r_member_type = base->variables[i].data_type; + base->variables.write[i].usages += 1; return true; } } @@ -7099,43 +7099,33 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN return false; } -GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line) { +GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line, bool p_is_indexing) { if (p_base_type && !p_base_type->has_type) { return DataType(); } DataType base_type; + DataType member_type; - // Check classes in current file - ClassNode *base = NULL; if (!p_base_type) { - base = current_class; base_type.has_type = true; base_type.is_constant = true; base_type.kind = DataType::CLASS; - base_type.class_type = base; + base_type.class_type = current_class; } else { base_type = DataType(*p_base_type); - if (base_type.kind == DataType::CLASS) { - base = base_type.class_type; - } - } - - DataType member_type; - - for (int i = 0; i < current_class->variables.size(); i++) { - if (current_class->variables[i].identifier == p_identifier) { - member_type = current_class->variables[i].data_type; - current_class->variables.write[i].usages += 1; - return member_type; - } } if (_get_member_type(base_type, p_identifier, member_type)) { return member_type; } + if (p_is_indexing) { + // Don't look for globals since this is an indexed identifier + return DataType(); + } + if (!p_base_type) { // Possibly this is a global, check before failing @@ -7193,7 +7183,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType Ref<GDScript> gds = scr; if (gds.is_valid()) { if (!gds->is_valid()) { - _set_error("Class '" + p_identifier + "' could not be fully loaded (script error or cyclic inheritance)."); + _set_error("Class '" + p_identifier + "' could not be fully loaded (script error or cyclic dependency)."); return DataType(); } result.kind = DataType::GDSCRIPT; diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 63e02ddc6a..b4a705c9e7 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -607,7 +607,7 @@ private: DataType _reduce_node_type(Node *p_node); DataType _reduce_function_call_type(const OperatorNode *p_call); - DataType _reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line); + DataType _reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line, bool p_is_indexing); void _check_class_level_types(ClassNode *p_class); void _check_class_blocks_types(ClassNode *p_class); void _check_function_types(FunctionNode *p_function); diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 3aaed4fb27..6ed008cf9c 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -64,6 +64,7 @@ void CanvasItemMaterial::init_shaders() { void CanvasItemMaterial::finish_shaders() { memdelete(dirty_materials); + memdelete(shader_names); dirty_materials = NULL; #ifndef NO_THREADS diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 240dbe1a89..d7ed6f8f49 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -450,7 +450,7 @@ void Light2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_buffer_size", PROPERTY_HINT_RANGE, "32,16384,1"), "set_shadow_buffer_size", "get_shadow_buffer_size"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_gradient_length", PROPERTY_HINT_RANGE, "0,4096,0.1"), "set_shadow_gradient_length", "get_shadow_gradient_length"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF3,PCF5,PCF7,PCF9,PCF13"), "set_shadow_filter", "get_shadow_filter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF3,PCF5,PCF7,PCF9,PCF13"), "set_shadow_filter", "get_shadow_filter"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_shadow_cull_mask", "get_item_shadow_cull_mask"); diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index bfa82fa12e..54b304f851 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -224,15 +224,12 @@ void Polygon2D::_notification(int p_what) { for (int i = 0; i < bone_weights.size(); i++) { if (bone_weights[i].weights.size() != points.size()) { continue; //different number of vertices, sorry not using. - print_line("wrong weight size"); } if (!skeleton_node->has_node(bone_weights[i].path)) { - print_line("no node"); continue; //node does not exist } Bone2D *bone = Object::cast_to<Bone2D>(skeleton_node->get_node(bone_weights[i].path)); if (!bone) { - print_line("no bone"); continue; } diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index cac59bddff..d61296b13f 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -377,13 +377,12 @@ void TileMap::update_dirty_quadrants() { r.size = tile_set->autotile_get_size(c.id); r.position += (r.size + Vector2(spacing, spacing)) * Vector2(c.autotile_coord_x, c.autotile_coord_y); } - Size2 s = tex->get_size(); + Size2 s; if (r == Rect2()) s = tex->get_size(); - else { + else s = r.size; - } Rect2 rect; rect.position = offset.floor(); diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp index 27bace9529..99f43b1242 100644 --- a/scene/3d/area.cpp +++ b/scene/3d/area.cpp @@ -753,6 +753,7 @@ Area::Area() : angular_damp = 1; priority = 0; monitoring = false; + monitorable = false; collision_mask = 1; collision_layer = 1; set_ray_pickable(false); diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index cad7ff47c1..0f4d0383a4 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -33,6 +33,7 @@ #include "scene/3d/area.h" #include "scene/3d/camera.h" #include "scene/main/viewport.h" + void AudioStreamPlayer3D::_mix_audio() { if (!stream_playback.is_valid() || !active || @@ -206,15 +207,15 @@ float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const { float att = 0; switch (attenuation_model) { case ATTENUATION_INVERSE_DISTANCE: { - att = Math::linear2db(1.0 / ((p_distance / unit_size) + 000001)); + att = Math::linear2db(1.0 / ((p_distance / unit_size) + CMP_EPSILON)); } break; case ATTENUATION_INVERSE_SQUARE_DISTANCE: { float d = (p_distance / unit_size); d *= d; - att = Math::linear2db(1.0 / (d + 0.00001)); + att = Math::linear2db(1.0 / (d + CMP_EPSILON)); } break; case ATTENUATION_LOGARITHMIC: { - att = -20 * Math::log(p_distance / unit_size + 000001); + att = -20 * Math::log(p_distance / unit_size + CMP_EPSILON); } break; default: { ERR_PRINT("Unknown attenuation type"); diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index 0bf5983dd1..29610cb0bf 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -605,19 +605,14 @@ void CPUParticles::_particles_process(float p_delta) { p.hue_rot_rand = Math::randf(); p.anim_offset_rand = Math::randf(); - float angle1_rad; - float angle2_rad; - if (flags[FLAG_DISABLE_Z]) { - - angle1_rad = (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; + float angle1_rad = (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0); p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); - } else { //initiate velocity spread in 3D - angle1_rad = (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; - angle2_rad = (Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * Math_PI * spread / 180.0; + float angle1_rad = (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; + float angle2_rad = (Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * Math_PI * spread / 180.0; Vector3 direction_xz = Vector3(Math::sin(angle1_rad), 0, Math::cos(angle1_rad)); Vector3 direction_yz = Vector3(0, Math::sin(angle2_rad), Math::cos(angle2_rad)); diff --git a/scene/3d/path.cpp b/scene/3d/path.cpp index 4e027f43f6..9fae5a9a54 100644 --- a/scene/3d/path.cpp +++ b/scene/3d/path.cpp @@ -44,10 +44,11 @@ void Path::_curve_changed() { emit_signal("curve_changed"); } - // update the configuration warnings of all children of type OrientedPathFollows + // update the configuration warnings of all children of type PathFollow + // previously used for PathFollowOriented (now enforced orientation is done in PathFollow) if (is_inside_tree()) { for (int i = 0; i < get_child_count(); i++) { - OrientedPathFollow *child = Object::cast_to<OrientedPathFollow>(get_child(i)); + PathFollow *child = Object::cast_to<PathFollow>(get_child(i)); if (child) { child->update_configuration_warning(); } @@ -105,24 +106,64 @@ void PathFollow::_update_transform() { return; } + float bl = c->get_baked_length(); + float bi = c->get_bake_interval(); float o = offset; + float o_next = offset + bi; if (loop) { - o = Math::fposmod(o, c->get_baked_length()); + o = Math::fposmod(o, bl); + o_next = Math::fposmod(o_next, bl); + } else if (rotation_mode == ROTATION_ORIENTED && o_next >= bl) { + o = bl - bi; + o_next = bl; } 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 + + 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) + forward = Vector3(0, 0, 1); + else + forward.normalize(); + + Vector3 up = c->interpolate_baked_up_vector(o, true); + + if (o_next < o) { + Vector3 up1 = c->interpolate_baked_up_vector(o_next, true); + Vector3 axis = up.cross(up1); - t.origin = pos; - Vector3 pos_offset = Vector3(h_offset, v_offset, 0); + if (axis.length_squared() < CMP_EPSILON2) + axis = forward; + else + axis.normalize(); - if (rotation_mode != ROTATION_NONE) { + up.rotate(axis, up.angle_to(up1) * 0.5f); + } + + Vector3 scale = t.basis.get_scale(); + Vector3 sideways = up.cross(forward).normalized(); + up = forward.cross(sideways).normalized(); + + t.basis.set(sideways, up, forward); + t.basis.scale_local(scale); + + t.origin = pos + sideways * h_offset + up * v_offset; + } else if (rotation_mode != ROTATION_NONE) { // perform parallel transport // // see C. Dougan, The Parallel Transport Frame, Game Programming Gems 2 for example // for a discussion about why not Frenet frame. + t.origin = pos; + Vector3 t_prev = (pos - c->interpolate_baked(o - delta_offset, cubic)).normalized(); Vector3 t_cur = (c->interpolate_baked(o + delta_offset, cubic) - pos).normalized(); @@ -165,9 +206,9 @@ void PathFollow::_update_transform() { } } - t.translate(pos_offset); + t.translate(Vector3(h_offset, v_offset, 0)); } else { - t.origin += pos_offset; + t.origin = pos + Vector3(h_offset, v_offset, 0); } set_transform(t); @@ -224,6 +265,11 @@ String PathFollow::get_configuration_warning() const { if (!Object::cast_to<Path>(get_parent())) { return TTR("PathFollow only works when set as a child of a Path node."); + } else { + Path *path = Object::cast_to<Path>(get_parent()); + if (path->get_curve().is_valid() && !path->get_curve()->is_up_vector_enabled() && rotation_mode == ROTATION_ORIENTED) { + return TTR("PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent Path's Curve resource."); + } } return String(); @@ -256,7 +302,7 @@ void PathFollow::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_greater", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "h_offset"), "set_h_offset", "get_h_offset"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_offset"), "set_v_offset", "get_v_offset"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_mode", PROPERTY_HINT_ENUM, "None,Y,XY,XYZ"), "set_rotation_mode", "get_rotation_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_mode", PROPERTY_HINT_ENUM, "None,Y,XY,XYZ,Oriented"), "set_rotation_mode", "get_rotation_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cubic_interp"), "set_cubic_interpolation", "get_cubic_interpolation"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); @@ -264,6 +310,7 @@ void PathFollow::_bind_methods() { BIND_ENUM_CONSTANT(ROTATION_Y); BIND_ENUM_CONSTANT(ROTATION_XY); BIND_ENUM_CONSTANT(ROTATION_XYZ); + BIND_ENUM_CONSTANT(ROTATION_ORIENTED); } void PathFollow::set_offset(float p_offset) { @@ -322,6 +369,8 @@ float PathFollow::get_unit_offset() const { void PathFollow::set_rotation_mode(RotationMode p_rotation_mode) { rotation_mode = p_rotation_mode; + + update_configuration_warning(); _update_transform(); } @@ -351,236 +400,3 @@ PathFollow::PathFollow() { cubic = true; loop = true; } - -////////////// - -void OrientedPathFollow::_update_transform() { - - if (!path) - return; - - Ref<Curve3D> c = path->get_curve(); - if (!c.is_valid()) - return; - - int count = c->get_point_count(); - if (count < 2) - return; - - if (delta_offset == 0) { - return; - } - - float offset = get_offset(); - float bl = c->get_baked_length(); - float bi = c->get_bake_interval(); - float o = offset; - float o_next = offset + bi; - - if (has_loop()) { - o = Math::fposmod(o, bl); - o_next = Math::fposmod(o_next, bl); - } else if (o_next >= bl) { - o = bl - bi; - o_next = bl; - } - - bool cubic = get_cubic_interpolation(); - Vector3 pos = c->interpolate_baked(o, cubic); - Vector3 forward = c->interpolate_baked(o_next, cubic) - pos; - - if (forward.length_squared() < CMP_EPSILON2) - forward = Vector3(0, 0, 1); - else - forward.normalize(); - - Vector3 up = c->interpolate_baked_up_vector(o, true); - - if (o_next < o) { - Vector3 up1 = c->interpolate_baked_up_vector(o_next, true); - Vector3 axis = up.cross(up1); - - if (axis.length_squared() < CMP_EPSILON2) - axis = forward; - else - axis.normalize(); - - up.rotate(axis, up.angle_to(up1) * 0.5f); - } - - Transform t = get_transform(); - Vector3 scale = t.basis.get_scale(); - - Vector3 sideways = up.cross(forward).normalized(); - up = forward.cross(sideways).normalized(); - - t.basis.set(sideways, up, forward); - t.basis.scale_local(scale); - - t.origin = pos + sideways * get_h_offset() + up * get_v_offset(); - - set_transform(t); -} - -void OrientedPathFollow::_notification(int p_what) { - - switch (p_what) { - - case NOTIFICATION_ENTER_TREE: { - - Node *parent = get_parent(); - if (parent) { - path = Object::cast_to<Path>(parent); - if (path) { - _update_transform(); - } - } - - } break; - case NOTIFICATION_EXIT_TREE: { - - path = NULL; - } break; - } -} - -void OrientedPathFollow::set_cubic_interpolation(bool p_enable) { - - cubic = p_enable; -} - -bool OrientedPathFollow::get_cubic_interpolation() const { - - return cubic; -} - -void OrientedPathFollow::_validate_property(PropertyInfo &property) const { - - if (property.name == "offset") { - - float max = 10000; - if (path && path->get_curve().is_valid()) - max = path->get_curve()->get_baked_length(); - - property.hint_string = "0," + rtos(max) + ",0.01"; - } -} - -String OrientedPathFollow::get_configuration_warning() const { - - if (!is_visible_in_tree() || !is_inside_tree()) - return String(); - - if (!Object::cast_to<Path>(get_parent())) { - return TTR("OrientedPathFollow only works when set as a child of a Path node."); - } else { - Path *path = Object::cast_to<Path>(get_parent()); - if (path->get_curve().is_valid() && !path->get_curve()->is_up_vector_enabled()) { - return TTR("OrientedPathFollow requires \"Up Vector\" enabled in its parent Path's Curve resource."); - } - } - - return String(); -} - -void OrientedPathFollow::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_offset", "offset"), &OrientedPathFollow::set_offset); - ClassDB::bind_method(D_METHOD("get_offset"), &OrientedPathFollow::get_offset); - - ClassDB::bind_method(D_METHOD("set_h_offset", "h_offset"), &OrientedPathFollow::set_h_offset); - ClassDB::bind_method(D_METHOD("get_h_offset"), &OrientedPathFollow::get_h_offset); - - ClassDB::bind_method(D_METHOD("set_v_offset", "v_offset"), &OrientedPathFollow::set_v_offset); - ClassDB::bind_method(D_METHOD("get_v_offset"), &OrientedPathFollow::get_v_offset); - - ClassDB::bind_method(D_METHOD("set_unit_offset", "unit_offset"), &OrientedPathFollow::set_unit_offset); - ClassDB::bind_method(D_METHOD("get_unit_offset"), &OrientedPathFollow::get_unit_offset); - - ClassDB::bind_method(D_METHOD("set_cubic_interpolation", "enable"), &OrientedPathFollow::set_cubic_interpolation); - ClassDB::bind_method(D_METHOD("get_cubic_interpolation"), &OrientedPathFollow::get_cubic_interpolation); - - ClassDB::bind_method(D_METHOD("set_loop", "loop"), &OrientedPathFollow::set_loop); - ClassDB::bind_method(D_METHOD("has_loop"), &OrientedPathFollow::has_loop); - - ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01"), "set_offset", "get_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "h_offset"), "set_h_offset", "get_h_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_offset"), "set_v_offset", "get_v_offset"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cubic_interp"), "set_cubic_interpolation", "get_cubic_interpolation"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); -} - -void OrientedPathFollow::set_offset(float p_offset) { - delta_offset = p_offset - offset; - offset = p_offset; - - if (path) - _update_transform(); - _change_notify("offset"); - _change_notify("unit_offset"); -} - -void OrientedPathFollow::set_h_offset(float p_h_offset) { - - h_offset = p_h_offset; - if (path) - _update_transform(); -} - -float OrientedPathFollow::get_h_offset() const { - - return h_offset; -} - -void OrientedPathFollow::set_v_offset(float p_v_offset) { - - v_offset = p_v_offset; - if (path) - _update_transform(); -} - -float OrientedPathFollow::get_v_offset() const { - - return v_offset; -} - -float OrientedPathFollow::get_offset() const { - - return offset; -} - -void OrientedPathFollow::set_unit_offset(float p_unit_offset) { - - if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) - set_offset(p_unit_offset * path->get_curve()->get_baked_length()); -} - -float OrientedPathFollow::get_unit_offset() const { - - if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) - return get_offset() / path->get_curve()->get_baked_length(); - else - return 0; -} - -void OrientedPathFollow::set_loop(bool p_loop) { - - loop = p_loop; -} - -bool OrientedPathFollow::has_loop() const { - - return loop; -} - -OrientedPathFollow::OrientedPathFollow() { - - offset = 0; - delta_offset = 0; - h_offset = 0; - v_offset = 0; - path = NULL; - cubic = true; - loop = true; -} diff --git a/scene/3d/path.h b/scene/3d/path.h index c514811c62..2a12c4a826 100644 --- a/scene/3d/path.h +++ b/scene/3d/path.h @@ -63,7 +63,8 @@ public: ROTATION_NONE, ROTATION_Y, ROTATION_XY, - ROTATION_XYZ + ROTATION_XYZ, + ROTATION_ORIENTED }; private: @@ -113,49 +114,4 @@ public: VARIANT_ENUM_CAST(PathFollow::RotationMode); -class OrientedPathFollow : public Spatial { - - GDCLASS(OrientedPathFollow, Spatial); - -private: - Path *path; - real_t delta_offset; // change in offset since last _update_transform - real_t offset; - real_t h_offset; - real_t v_offset; - bool cubic; - bool loop; - - void _update_transform(); - -protected: - virtual void _validate_property(PropertyInfo &property) const; - - void _notification(int p_what); - static void _bind_methods(); - -public: - void set_offset(float p_offset); - float get_offset() const; - - void set_h_offset(float p_h_offset); - float get_h_offset() const; - - void set_v_offset(float p_v_offset); - float get_v_offset() const; - - void set_unit_offset(float p_unit_offset); - float get_unit_offset() const; - - void set_loop(bool p_loop); - bool has_loop() const; - - void set_cubic_interpolation(bool p_enable); - bool get_cubic_interpolation() const; - - String get_configuration_warning() const; - - OrientedPathFollow(); -}; - #endif // PATH_H diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp index 4b910e4463..30e38c8ee2 100644 --- a/scene/3d/voxel_light_baker.cpp +++ b/scene/3d/voxel_light_baker.cpp @@ -342,8 +342,8 @@ void VoxelLightBaker::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p if (lnormal == Vector3()) //just in case normal as nor provided lnormal = normal; - int uv_x = CLAMP(Math::fposmod(uv.x, 1.0f) * bake_texture_size, 0, bake_texture_size - 1); - int uv_y = CLAMP(Math::fposmod(uv.y, 1.0f) * bake_texture_size, 0, bake_texture_size - 1); + int uv_x = CLAMP(int(Math::fposmod(uv.x, 1.0f) * bake_texture_size), 0, bake_texture_size - 1); + int uv_y = CLAMP(int(Math::fposmod(uv.y, 1.0f) * bake_texture_size), 0, bake_texture_size - 1); int ofs = uv_y * bake_texture_size + uv_x; albedo_accum.r += p_material.albedo[ofs].r; @@ -1931,7 +1931,6 @@ Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh //add directional light (do this after blur) { - LightMap *lightmap_ptr = lightmap.ptrw(); const Cell *cells = bake_cells.ptr(); const Light *light = bake_light.ptr(); #ifdef _OPENMP diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 4d638b50c6..4a2bb3dad1 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -1290,13 +1290,11 @@ int LineEdit::get_max_length() const { void LineEdit::selection_fill_at_cursor() { - int aux; - selection.begin = cursor_pos; selection.end = selection.cursor_start; if (selection.end < selection.begin) { - aux = selection.end; + int aux = selection.end; selection.end = selection.begin; selection.begin = aux; } diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index f99f5e4d4b..28292309b9 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -271,7 +271,6 @@ void ScrollContainer::_notification(int p_what) { } if (!scroll_v || (!v_scroll->is_visible_in_tree() && c->get_v_size_flags() & SIZE_EXPAND)) { r.position.y = 0; - r.size.height = size.height; if (c->get_v_size_flags() & SIZE_EXPAND) r.size.height = MAX(size.height, minsize.height); else diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 19c054fa43..09fbb39866 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -3811,7 +3811,6 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const { if (indent_ofs + word_px > wrap_at) { // not enough space; add it anyway wrap_substring += word_str; - px += word_px; word_str = ""; word_px = 0; } diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index 8e96873672..8b68b3215c 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -220,13 +220,12 @@ bool HTTPRequest::_handle_response(bool *ret_value) { Error err; if (new_request.begins_with("http")) { // New url, request all again - err = _parse_url(new_request); + _parse_url(new_request); } else { request_string = new_request; } err = _request(); - if (err == OK) { request_sent = false; got_response = false; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 3281081897..a50a09f095 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -452,7 +452,6 @@ void register_scene_types() { ClassDB::register_class<Curve3D>(); ClassDB::register_class<Path>(); ClassDB::register_class<PathFollow>(); - ClassDB::register_class<OrientedPathFollow>(); ClassDB::register_class<VisibilityNotifier>(); ClassDB::register_class<VisibilityEnabler>(); ClassDB::register_class<WorldEnvironment>(); diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 5c6b0ac91a..383f3f5d4e 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -2332,7 +2332,7 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const { float duration = bt->values[idx + 1].time - bt->values[idx].time; // time duration between our two keyframes float low = 0; // 0% of the current animation segment float high = 1; // 100% of the current animation segment - float middle = 0; + float middle; Vector2 start(0, bt->values[idx].value.value); Vector2 start_out = start + bt->values[idx].value.out_handle; diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index e136181136..464ca60d31 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -761,8 +761,8 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const { //validate// int pc = baked_point_cache.size(); if (pc == 0) { - ERR_EXPLAIN("No points in Curve2D"); - ERR_FAIL_COND_V(pc == 0, Vector2()); + ERR_EXPLAIN("No points in Curve2D."); + ERR_FAIL_V(Vector2()); } if (pc == 1) @@ -826,8 +826,8 @@ Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const { //validate// int pc = baked_point_cache.size(); if (pc == 0) { - ERR_EXPLAIN("No points in Curve2D"); - ERR_FAIL_COND_V(pc == 0, Vector2()); + ERR_EXPLAIN("No points in Curve2D."); + ERR_FAIL_V(Vector2()); } if (pc == 1) @@ -865,8 +865,8 @@ float Curve2D::get_closest_offset(const Vector2 &p_to_point) const { //validate// int pc = baked_point_cache.size(); if (pc == 0) { - ERR_EXPLAIN("No points in Curve2D"); - ERR_FAIL_COND_V(pc == 0, 0.0f); + ERR_EXPLAIN("No points in Curve2D."); + ERR_FAIL_V(0.0f); } if (pc == 1) @@ -1331,8 +1331,8 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const { //validate// int pc = baked_point_cache.size(); if (pc == 0) { - ERR_EXPLAIN("No points in Curve3D"); - ERR_FAIL_COND_V(pc == 0, Vector3()); + ERR_EXPLAIN("No points in Curve3D."); + ERR_FAIL_V(Vector3()); } if (pc == 1) @@ -1375,8 +1375,8 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const { //validate// int pc = baked_tilt_cache.size(); if (pc == 0) { - ERR_EXPLAIN("No tilts in Curve3D"); - ERR_FAIL_COND_V(pc == 0, 0); + ERR_EXPLAIN("No tilts in Curve3D."); + ERR_FAIL_V(0); } if (pc == 1) @@ -1413,8 +1413,8 @@ Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt) // curve may not have baked up vectors int count = baked_up_vector_cache.size(); if (count == 0) { - ERR_EXPLAIN("No up vectors in Curve3D"); - ERR_FAIL_COND_V(count == 0, Vector3(0, 1, 0)); + ERR_EXPLAIN("No up vectors in Curve3D."); + ERR_FAIL_V(Vector3(0, 1, 0)); } if (count == 1) @@ -1484,8 +1484,8 @@ Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const { //validate// int pc = baked_point_cache.size(); if (pc == 0) { - ERR_EXPLAIN("No points in Curve3D"); - ERR_FAIL_COND_V(pc == 0, Vector3()); + ERR_EXPLAIN("No points in Curve3D."); + ERR_FAIL_V(Vector3()); } if (pc == 1) @@ -1523,8 +1523,8 @@ float Curve3D::get_closest_offset(const Vector3 &p_to_point) const { //validate// int pc = baked_point_cache.size(); if (pc == 0) { - ERR_EXPLAIN("No points in Curve3D"); - ERR_FAIL_COND_V(pc == 0, 0.0f); + ERR_EXPLAIN("No points in Curve3D."); + ERR_FAIL_V(0.0f); } if (pc == 1) diff --git a/scene/resources/shape_2d.cpp b/scene/resources/shape_2d.cpp index 0254945c00..e2407e4423 100644 --- a/scene/resources/shape_2d.cpp +++ b/scene/resources/shape_2d.cpp @@ -59,37 +59,37 @@ bool Shape2D::collide(const Transform2D &p_local_xform, const Ref<Shape2D> &p_sh return Physics2DServer::get_singleton()->shape_collide(get_rid(), p_local_xform, Vector2(), p_shape->get_rid(), p_shape_xform, Vector2(), NULL, 0, r); } -Variant Shape2D::collide_with_motion_and_get_contacts(const Transform2D &p_local_xform, const Vector2 &p_local_motion, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform, const Vector2 &p_shape_motion) { +Array Shape2D::collide_with_motion_and_get_contacts(const Transform2D &p_local_xform, const Vector2 &p_local_motion, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform, const Vector2 &p_shape_motion) { - ERR_FAIL_COND_V(p_shape.is_null(), Variant()); + ERR_FAIL_COND_V(p_shape.is_null(), Array()); const int max_contacts = 16; Vector2 result[max_contacts * 2]; int contacts = 0; if (!Physics2DServer::get_singleton()->shape_collide(get_rid(), p_local_xform, p_local_motion, p_shape->get_rid(), p_shape_xform, p_shape_motion, result, max_contacts, contacts)) - return Variant(); + return Array(); Array results; results.resize(contacts * 2); - for (int i = 0; i < contacts; i++) { + for (int i = 0; i < contacts * 2; i++) { results[i] = result[i]; } return results; } -Variant Shape2D::collide_and_get_contacts(const Transform2D &p_local_xform, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform) { +Array Shape2D::collide_and_get_contacts(const Transform2D &p_local_xform, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform) { - ERR_FAIL_COND_V(p_shape.is_null(), Variant()); + ERR_FAIL_COND_V(p_shape.is_null(), Array()); const int max_contacts = 16; Vector2 result[max_contacts * 2]; int contacts = 0; if (!Physics2DServer::get_singleton()->shape_collide(get_rid(), p_local_xform, Vector2(), p_shape->get_rid(), p_shape_xform, Vector2(), result, max_contacts, contacts)) - return Variant(); + return Array(); Array results; results.resize(contacts * 2); - for (int i = 0; i < contacts; i++) { + for (int i = 0; i < contacts * 2; i++) { results[i] = result[i]; } diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h index cf6b38ddda..da9b80477c 100644 --- a/scene/resources/shape_2d.h +++ b/scene/resources/shape_2d.h @@ -53,8 +53,8 @@ public: bool collide_with_motion(const Transform2D &p_local_xform, const Vector2 &p_local_motion, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform, const Vector2 &p_shape_motion); bool collide(const Transform2D &p_local_xform, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform); - Variant collide_with_motion_and_get_contacts(const Transform2D &p_local_xform, const Vector2 &p_local_motion, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform, const Vector2 &p_shape_motion); - Variant collide_and_get_contacts(const Transform2D &p_local_xform, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform); + Array collide_with_motion_and_get_contacts(const Transform2D &p_local_xform, const Vector2 &p_local_motion, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform, const Vector2 &p_shape_motion); + Array collide_and_get_contacts(const Transform2D &p_local_xform, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform); virtual void draw(const RID &p_to_rid, const Color &p_color) {} virtual Rect2 get_rect() const { return Rect2(); } diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 773c1d1ad9..394592ec64 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -656,7 +656,7 @@ public: next_ptr = NULL; mask_next_ptr = NULL; filter_next_ptr = NULL; - shadow_buffer_size = 256; + shadow_buffer_size = 2048; shadow_gradient_length = 0; shadow_filter = VS::CANVAS_LIGHT_FILTER_NONE; shadow_smooth = 0.0; diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp index bb02027479..84338bccca 100644 --- a/servers/visual/visual_server_canvas.cpp +++ b/servers/visual/visual_server_canvas.cpp @@ -1110,6 +1110,7 @@ void VisualServerCanvas::canvas_light_set_shadow_buffer_size(RID p_light, int p_ if (new_size == clight->shadow_buffer_size) return; + print_line("create shadow buffer: " + itos(p_size)); clight->shadow_buffer_size = next_power_of_2(p_size); if (clight->shadow_buffer.is_valid()) { |