summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.pre-commit-config.yaml13
-rw-r--r--core/object/class_db.cpp2
-rw-r--r--editor/import/3d/resource_importer_scene.cpp3
-rw-r--r--editor/import_dock.cpp14
-rw-r--r--editor/plugins/script_text_editor.cpp5
-rw-r--r--editor/plugins/tiles/tile_atlas_view.cpp4
-rw-r--r--modules/fbx/editor/editor_scene_importer_ufbx.cpp2
-rw-r--r--modules/navigation/3d/nav_mesh_generator_3d.cpp26
-rw-r--r--modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml6
-rw-r--r--modules/openxr/extensions/openxr_extension_wrapper.h1
-rw-r--r--modules/openxr/extensions/openxr_extension_wrapper_extension.cpp5
-rw-r--r--modules/openxr/extensions/openxr_extension_wrapper_extension.h2
-rw-r--r--modules/openxr/extensions/openxr_fb_foveation_extension.cpp37
-rw-r--r--modules/openxr/extensions/openxr_fb_foveation_extension.h12
-rw-r--r--modules/openxr/openxr_api.cpp4
-rw-r--r--modules/openxr/scene/openxr_composition_layer.cpp4
-rw-r--r--scene/2d/tile_map.cpp85
-rw-r--r--scene/2d/tile_map.h4
-rw-r--r--scene/2d/tile_map_layer.cpp95
-rw-r--r--scene/2d/tile_map_layer.h4
20 files changed, 207 insertions, 121 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index cff3d2a22e..dd51d7b419 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -146,6 +146,7 @@ repos:
exclude: |
(?x)^(
core/math/bvh_.*\.inc$|
+ platform/(?!android|ios|linuxbsd|macos|web|windows)\w+/.*|
platform/android/java/lib/src/com/.*|
platform/android/java/lib/src/org/godotengine/godot/gl/GLSurfaceView\.java$|
platform/android/java/lib/src/org/godotengine/godot/gl/EGLLogWrapper\.java$|
@@ -186,3 +187,15 @@ repos:
language: python
entry: python3 misc/scripts/dotnet_format.py
types_or: [c#]
+
+# End of upstream Godot pre-commit hooks.
+#
+# Keep this separation to let downstream forks add their own hooks to this file,
+# without running into merge conflicts when rebasing on latest upstream.
+#
+# Start of downstream pre-commit hooks.
+#
+# This is still the "repo: local" scope, so new local hooks can be defined directly at this indentation:
+# - id: new-local-hook
+# To add external repo hooks, bring the indentation back to:
+# - repo: my-remote-hook
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index e25703b93f..3d93ce8e73 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -522,7 +522,7 @@ Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require
#ifdef TOOLS_ENABLED
if (!p_require_real_class && ti->is_runtime && Engine::get_singleton()->is_editor_hint()) {
if (!ti->inherits_ptr || !ti->inherits_ptr->creation_func) {
- ERR_PRINT_ONCE(vformat("Cannot make a placeholder instance of runtime class %s because its parent cannot be constructed.", ti->name));
+ ERR_PRINT(vformat("Cannot make a placeholder instance of runtime class %s because its parent cannot be constructed.", ti->name));
} else {
ObjectGDExtension *extension = get_placeholder_extension(ti->name);
return (Object *)extension->create_instance(extension->class_userdata);
diff --git a/editor/import/3d/resource_importer_scene.cpp b/editor/import/3d/resource_importer_scene.cpp
index 070c44419a..23c22a8049 100644
--- a/editor/import/3d/resource_importer_scene.cpp
+++ b/editor/import/3d/resource_importer_scene.cpp
@@ -2329,6 +2329,7 @@ void ResourceImporterScene::get_import_options(const String &p_path, List<Import
}
script_ext_hint += "*." + E;
}
+ bool trimming_defaults_on = p_path.get_extension().to_lower() == "fbx";
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "nodes/apply_root_scale"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "nodes/root_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001"), 1.0));
@@ -2342,7 +2343,7 @@ void ResourceImporterScene::get_import_options(const String &p_path, List<Import
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "skins/use_named_skins"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 30));
- r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/trimming"), false));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/trimming"), trimming_defaults_on));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/remove_immutable_tracks"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import_rest_as_RESET"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "import_script/path", PROPERTY_HINT_FILE, script_ext_hint), ""));
diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp
index fbe76e1d5c..2d87e6592f 100644
--- a/editor/import_dock.cpp
+++ b/editor/import_dock.cpp
@@ -188,10 +188,20 @@ void ImportDock::_update_options(const String &p_path, const Ref<ConfigFile> &p_
params->checked.clear();
params->base_options_path = p_path;
+ HashMap<StringName, Variant> import_options;
+ List<String> section_keys;
+ p_config->get_section_keys("params", &section_keys);
+ for (const String &section_key : section_keys) {
+ import_options[section_key] = p_config->get_value("params", section_key);
+ }
+ if (params->importer.is_valid()) {
+ params->importer->handle_compatibility_options(import_options);
+ }
+
for (const ResourceImporter::ImportOption &E : options) {
params->properties.push_back(E.option);
- if (p_config.is_valid() && p_config->has_section_key("params", E.option.name)) {
- params->values[E.option.name] = p_config->get_value("params", E.option.name);
+ if (p_config.is_valid() && import_options.has(E.option.name)) {
+ params->values[E.option.name] = import_options[E.option.name];
} else {
params->values[E.option.name] = E.default_value;
}
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 191d58228b..f3f6fc91a9 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -2133,10 +2133,11 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
void ScriptTextEditor::_color_changed(const Color &p_color) {
String new_args;
+ const int decimals = 3;
if (p_color.a == 1.0f) {
- new_args = String("(" + rtos(p_color.r) + ", " + rtos(p_color.g) + ", " + rtos(p_color.b) + ")");
+ new_args = String("(" + String::num(p_color.r, decimals) + ", " + String::num(p_color.g, decimals) + ", " + String::num(p_color.b, decimals) + ")");
} else {
- new_args = String("(" + rtos(p_color.r) + ", " + rtos(p_color.g) + ", " + rtos(p_color.b) + ", " + rtos(p_color.a) + ")");
+ new_args = String("(" + String::num(p_color.r, decimals) + ", " + String::num(p_color.g, decimals) + ", " + String::num(p_color.b, decimals) + ", " + String::num(p_color.a, decimals) + ")");
}
String line = code_editor->get_text_editor()->get_line(color_position.x);
diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp
index 2ee0dc0316..2b86268414 100644
--- a/editor/plugins/tiles/tile_atlas_view.cpp
+++ b/editor/plugins/tiles/tile_atlas_view.cpp
@@ -250,7 +250,7 @@ void TileAtlasView::_draw_base_tiles() {
Vector2 offset_pos = Rect2(base_frame_rect).get_center() + Vector2(tile_set_atlas_source->get_tile_data(atlas_coords, 0)->get_texture_origin());
// Draw the tile.
- TileMap::draw_tile(ci_rid, offset_pos, tile_set, source_id, atlas_coords, 0, frame);
+ TileMapLayer::draw_tile(ci_rid, offset_pos, tile_set, source_id, atlas_coords, 0, frame);
}
}
@@ -411,7 +411,7 @@ void TileAtlasView::_draw_alternatives() {
}
// Draw the tile.
- TileMap::draw_tile(ci_rid, offset_pos, tile_set, source_id, atlas_coords, alternative_id);
+ TileMapLayer::draw_tile(ci_rid, offset_pos, tile_set, source_id, atlas_coords, alternative_id);
// Increment the x position.
current_pos.x += transposed ? texture_region_size.y : texture_region_size.x;
diff --git a/modules/fbx/editor/editor_scene_importer_ufbx.cpp b/modules/fbx/editor/editor_scene_importer_ufbx.cpp
index 3cc919fae2..e0f60fe998 100644
--- a/modules/fbx/editor/editor_scene_importer_ufbx.cpp
+++ b/modules/fbx/editor/editor_scene_importer_ufbx.cpp
@@ -111,7 +111,7 @@ void EditorSceneFormatImporterUFBX::get_import_options(const String &p_path,
void EditorSceneFormatImporterUFBX::handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const {
if (!p_import_params.has("fbx/importer")) {
- p_import_params["fbx/importer"] = EditorSceneFormatImporterUFBX::FBX_IMPORTER_UFBX;
+ p_import_params["fbx/importer"] = EditorSceneFormatImporterUFBX::FBX_IMPORTER_FBX2GLTF;
}
}
diff --git a/modules/navigation/3d/nav_mesh_generator_3d.cpp b/modules/navigation/3d/nav_mesh_generator_3d.cpp
index cc3bbdbf01..df0bdc9537 100644
--- a/modules/navigation/3d/nav_mesh_generator_3d.cpp
+++ b/modules/navigation/3d/nav_mesh_generator_3d.cpp
@@ -895,9 +895,22 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
Vector<Vector3> nav_vertices;
+ HashMap<Vector3, int> recast_vertex_to_native_index;
+ LocalVector<int> recast_index_to_native_index;
+ recast_index_to_native_index.resize(detail_mesh->nverts);
+
for (int i = 0; i < detail_mesh->nverts; i++) {
const float *v = &detail_mesh->verts[i * 3];
- nav_vertices.push_back(Vector3(v[0], v[1], v[2]));
+ const Vector3 vertex = Vector3(v[0], v[1], v[2]);
+ int *existing_index_ptr = recast_vertex_to_native_index.getptr(vertex);
+ if (!existing_index_ptr) {
+ int new_index = recast_vertex_to_native_index.size();
+ recast_index_to_native_index[i] = new_index;
+ recast_vertex_to_native_index[vertex] = new_index;
+ nav_vertices.push_back(vertex);
+ } else {
+ recast_index_to_native_index[i] = *existing_index_ptr;
+ }
}
p_navigation_mesh->set_vertices(nav_vertices);
p_navigation_mesh->clear_polygons();
@@ -912,9 +925,14 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
Vector<int> nav_indices;
nav_indices.resize(3);
// Polygon order in recast is opposite than godot's
- nav_indices.write[0] = ((int)(detail_mesh_bverts + detail_mesh_tris[j * 4 + 0]));
- nav_indices.write[1] = ((int)(detail_mesh_bverts + detail_mesh_tris[j * 4 + 2]));
- nav_indices.write[2] = ((int)(detail_mesh_bverts + detail_mesh_tris[j * 4 + 1]));
+ int index1 = ((int)(detail_mesh_bverts + detail_mesh_tris[j * 4 + 0]));
+ int index2 = ((int)(detail_mesh_bverts + detail_mesh_tris[j * 4 + 2]));
+ int index3 = ((int)(detail_mesh_bverts + detail_mesh_tris[j * 4 + 1]));
+
+ nav_indices.write[0] = recast_index_to_native_index[index1];
+ nav_indices.write[1] = recast_index_to_native_index[index2];
+ nav_indices.write[2] = recast_index_to_native_index[index3];
+
p_navigation_mesh->add_polygon(nav_indices);
}
}
diff --git a/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml b/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml
index 79aa547c52..338d632524 100644
--- a/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml
+++ b/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml
@@ -84,6 +84,12 @@
Called right before the OpenXR instance is destroyed.
</description>
</method>
+ <method name="_on_main_swapchains_created" qualifiers="virtual">
+ <return type="void" />
+ <description>
+ Called right after the main swapchains are (re)created.
+ </description>
+ </method>
<method name="_on_pre_render" qualifiers="virtual">
<return type="void" />
<description>
diff --git a/modules/openxr/extensions/openxr_extension_wrapper.h b/modules/openxr/extensions/openxr_extension_wrapper.h
index ce03df0b30..8d05657afc 100644
--- a/modules/openxr/extensions/openxr_extension_wrapper.h
+++ b/modules/openxr/extensions/openxr_extension_wrapper.h
@@ -84,6 +84,7 @@ public:
// This is when controller data is queried and made available to game logic.
virtual void on_process() {}
virtual void on_pre_render() {} // `on_pre_render` is called right before we start rendering our XR viewports.
+ virtual void on_main_swapchains_created() {} // `on_main_swapchains_created` is called right after our main swapchains are (re)created.
virtual void on_pre_draw_viewport(RID p_render_target) {} // `on_pre_draw_viewport` is called right before we start rendering this viewport
virtual void on_post_draw_viewport(RID p_render_target) {} // `on_port_draw_viewport` is called right after we start rendering this viewport (note that on Vulkan draw commands may only be queued)
diff --git a/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp b/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp
index 3b31e1b1f6..e09ca484d5 100644
--- a/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp
+++ b/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp
@@ -50,6 +50,7 @@ void OpenXRExtensionWrapperExtension::_bind_methods() {
GDVIRTUAL_BIND(_on_session_created, "session");
GDVIRTUAL_BIND(_on_process);
GDVIRTUAL_BIND(_on_pre_render);
+ GDVIRTUAL_BIND(_on_main_swapchains_created);
GDVIRTUAL_BIND(_on_session_destroyed);
GDVIRTUAL_BIND(_on_state_idle);
GDVIRTUAL_BIND(_on_state_ready);
@@ -198,6 +199,10 @@ void OpenXRExtensionWrapperExtension::on_pre_render() {
GDVIRTUAL_CALL(_on_pre_render);
}
+void OpenXRExtensionWrapperExtension::on_main_swapchains_created() {
+ GDVIRTUAL_CALL(_on_main_swapchains_created);
+}
+
void OpenXRExtensionWrapperExtension::on_session_destroyed() {
GDVIRTUAL_CALL(_on_session_destroyed);
}
diff --git a/modules/openxr/extensions/openxr_extension_wrapper_extension.h b/modules/openxr/extensions/openxr_extension_wrapper_extension.h
index 71d2a57ff8..e37853903b 100644
--- a/modules/openxr/extensions/openxr_extension_wrapper_extension.h
+++ b/modules/openxr/extensions/openxr_extension_wrapper_extension.h
@@ -86,6 +86,7 @@ public:
virtual void on_session_created(const XrSession p_session) override;
virtual void on_process() override;
virtual void on_pre_render() override;
+ virtual void on_main_swapchains_created() override;
virtual void on_session_destroyed() override;
GDVIRTUAL0(_on_register_metadata);
@@ -95,6 +96,7 @@ public:
GDVIRTUAL1(_on_session_created, uint64_t);
GDVIRTUAL0(_on_process);
GDVIRTUAL0(_on_pre_render);
+ GDVIRTUAL0(_on_main_swapchains_created);
GDVIRTUAL0(_on_session_destroyed);
virtual void on_state_idle() override;
diff --git a/modules/openxr/extensions/openxr_fb_foveation_extension.cpp b/modules/openxr/extensions/openxr_fb_foveation_extension.cpp
index bbdd2e3c8a..8ce808dd3c 100644
--- a/modules/openxr/extensions/openxr_fb_foveation_extension.cpp
+++ b/modules/openxr/extensions/openxr_fb_foveation_extension.cpp
@@ -101,7 +101,7 @@ void *OpenXRFBFoveationExtension::set_swapchain_create_info_and_get_next_pointer
}
}
-void OpenXRFBFoveationExtension::on_state_ready() {
+void OpenXRFBFoveationExtension::on_main_swapchains_created() {
update_profile();
}
@@ -127,26 +127,41 @@ void OpenXRFBFoveationExtension::set_foveation_dynamic(XrFoveationDynamicFB p_fo
update_profile();
}
-void OpenXRFBFoveationExtension::update_profile() {
- if (!is_enabled()) {
+void OpenXRFBFoveationExtension::_update_profile() {
+ // Must be called from rendering thread!
+ ERR_NOT_ON_RENDER_THREAD;
+
+ OpenXRFBFoveationExtension *fov_ext = OpenXRFBFoveationExtension::get_singleton();
+ ERR_FAIL_NULL(fov_ext);
+
+ if (!fov_ext->is_enabled()) {
+ return;
+ }
+
+ OpenXRAPI *openxr_api = OpenXRAPI::get_singleton();
+ ERR_FAIL_NULL(openxr_api);
+
+ XrSwapchain main_color_swapchain = openxr_api->get_color_swapchain();
+ if (main_color_swapchain == XR_NULL_HANDLE) {
+ // Our swapchain hasn't been created yet, we'll call this again once it has.
return;
}
XrFoveationLevelProfileCreateInfoFB level_profile_create_info;
level_profile_create_info.type = XR_TYPE_FOVEATION_LEVEL_PROFILE_CREATE_INFO_FB;
level_profile_create_info.next = nullptr;
- level_profile_create_info.level = foveation_level;
+ level_profile_create_info.level = fov_ext->foveation_level;
level_profile_create_info.verticalOffset = 0.0f;
- level_profile_create_info.dynamic = foveation_dynamic;
+ level_profile_create_info.dynamic = fov_ext->foveation_dynamic;
XrFoveationProfileCreateInfoFB profile_create_info;
profile_create_info.type = XR_TYPE_FOVEATION_PROFILE_CREATE_INFO_FB;
profile_create_info.next = &level_profile_create_info;
XrFoveationProfileFB foveation_profile;
- XrResult result = xrCreateFoveationProfileFB(OpenXRAPI::get_singleton()->get_session(), &profile_create_info, &foveation_profile);
+ XrResult result = fov_ext->xrCreateFoveationProfileFB(openxr_api->get_session(), &profile_create_info, &foveation_profile);
if (XR_FAILED(result)) {
- print_line("OpenXR: Unable to create the foveation profile [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
+ print_line("OpenXR: Unable to create the foveation profile [", openxr_api->get_error_string(result), "]");
return;
}
@@ -154,15 +169,15 @@ void OpenXRFBFoveationExtension::update_profile() {
foveation_update_state.type = XR_TYPE_SWAPCHAIN_STATE_FOVEATION_FB;
foveation_update_state.profile = foveation_profile;
- result = swapchain_update_state_ext->xrUpdateSwapchainFB(OpenXRAPI::get_singleton()->get_color_swapchain(), (XrSwapchainStateBaseHeaderFB *)&foveation_update_state);
+ result = fov_ext->swapchain_update_state_ext->xrUpdateSwapchainFB(main_color_swapchain, (XrSwapchainStateBaseHeaderFB *)&foveation_update_state);
if (XR_FAILED(result)) {
- print_line("OpenXR: Unable to update the swapchain [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
+ print_line("OpenXR: Unable to update the swapchain [", openxr_api->get_error_string(result), "]");
// We still want to destroy our profile so keep going...
}
- result = xrDestroyFoveationProfileFB(foveation_profile);
+ result = fov_ext->xrDestroyFoveationProfileFB(foveation_profile);
if (XR_FAILED(result)) {
- print_line("OpenXR: Unable to destroy the foveation profile [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
+ print_line("OpenXR: Unable to destroy the foveation profile [", openxr_api->get_error_string(result), "]");
}
}
diff --git a/modules/openxr/extensions/openxr_fb_foveation_extension.h b/modules/openxr/extensions/openxr_fb_foveation_extension.h
index 1c5e722731..84bd7011b5 100644
--- a/modules/openxr/extensions/openxr_fb_foveation_extension.h
+++ b/modules/openxr/extensions/openxr_fb_foveation_extension.h
@@ -60,7 +60,7 @@ public:
virtual void *set_swapchain_create_info_and_get_next_pointer(void *p_next_pointer) override;
- virtual void on_state_ready() override;
+ virtual void on_main_swapchains_created() override;
bool is_enabled() const;
@@ -82,7 +82,15 @@ private:
XrFoveationLevelFB foveation_level = XR_FOVEATION_LEVEL_NONE_FB;
XrFoveationDynamicFB foveation_dynamic = XR_FOVEATION_DYNAMIC_DISABLED_FB;
- void update_profile();
+ static void _update_profile();
+
+ void update_profile() {
+ // If we're rendering on a separate thread, we may still be processing the last frame, don't communicate this till we're ready...
+ RenderingServer *rendering_server = RenderingServer::get_singleton();
+ ERR_FAIL_NULL(rendering_server);
+
+ rendering_server->call_on_render_thread(callable_mp_static(&OpenXRFBFoveationExtension::_update_profile));
+ }
// Enable foveation on this swapchain
XrSwapchainCreateInfoFoveationFB swapchain_create_info_foveation_fb;
diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp
index 32512070d6..541e369925 100644
--- a/modules/openxr/openxr_api.cpp
+++ b/modules/openxr/openxr_api.cpp
@@ -1220,6 +1220,10 @@ bool OpenXRAPI::create_main_swapchains(Size2i p_size) {
}
};
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_main_swapchains_created();
+ }
+
return true;
};
diff --git a/modules/openxr/scene/openxr_composition_layer.cpp b/modules/openxr/scene/openxr_composition_layer.cpp
index 50cc7b9e7b..b02f3082ab 100644
--- a/modules/openxr/scene/openxr_composition_layer.cpp
+++ b/modules/openxr/scene/openxr_composition_layer.cpp
@@ -165,7 +165,9 @@ void OpenXRCompositionLayer::set_layer_viewport(SubViewport *p_viewport) {
return;
}
- ERR_FAIL_COND_EDMSG(is_viewport_in_use(p_viewport), RTR("Cannot use the same SubViewport with multiple OpenXR composition layers. Clear it from its current layer first."));
+ if (p_viewport != nullptr) {
+ ERR_FAIL_COND_EDMSG(is_viewport_in_use(p_viewport), RTR("Cannot use the same SubViewport with multiple OpenXR composition layers. Clear it from its current layer first."));
+ }
layer_viewport = p_viewport;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 523d81e874..f7d672620d 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -225,91 +225,6 @@ int TileMap::get_rendering_quadrant_size() const {
return rendering_quadrant_size;
}
-void TileMap::draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame, Color p_modulation, const TileData *p_tile_data_override, real_t p_normalized_animation_offset) {
- ERR_FAIL_COND(!p_tile_set.is_valid());
- ERR_FAIL_COND(!p_tile_set->has_source(p_atlas_source_id));
- ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_tile(p_atlas_coords));
- ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_alternative_tile(p_atlas_coords, p_alternative_tile));
- TileSetSource *source = *p_tile_set->get_source(p_atlas_source_id);
- TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
- if (atlas_source) {
- // Check for the frame.
- if (p_frame >= 0) {
- ERR_FAIL_INDEX(p_frame, atlas_source->get_tile_animation_frames_count(p_atlas_coords));
- }
-
- // Get the texture.
- Ref<Texture2D> tex = atlas_source->get_runtime_texture();
- if (!tex.is_valid()) {
- return;
- }
-
- // Check if we are in the texture, return otherwise.
- Vector2i grid_size = atlas_source->get_atlas_grid_size();
- if (p_atlas_coords.x >= grid_size.x || p_atlas_coords.y >= grid_size.y) {
- return;
- }
-
- // Get tile data.
- const TileData *tile_data = p_tile_data_override ? p_tile_data_override : atlas_source->get_tile_data(p_atlas_coords, p_alternative_tile);
-
- // Get the tile modulation.
- Color modulate = tile_data->get_modulate() * p_modulation;
-
- // Compute the offset.
- Vector2 tile_offset = tile_data->get_texture_origin();
-
- // Get destination rect.
- Rect2 dest_rect;
- dest_rect.size = atlas_source->get_runtime_tile_texture_region(p_atlas_coords).size;
- dest_rect.size.x += FP_ADJUST;
- dest_rect.size.y += FP_ADJUST;
-
- bool transpose = tile_data->get_transpose() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_TRANSPOSE);
- if (transpose) {
- dest_rect.position = (p_position - Vector2(dest_rect.size.y, dest_rect.size.x) / 2 - tile_offset);
- } else {
- dest_rect.position = (p_position - dest_rect.size / 2 - tile_offset);
- }
-
- if (tile_data->get_flip_h() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_H)) {
- dest_rect.size.x = -dest_rect.size.x;
- }
-
- if (tile_data->get_flip_v() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_V)) {
- dest_rect.size.y = -dest_rect.size.y;
- }
-
- // Draw the tile.
- if (p_frame >= 0) {
- Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, p_frame);
- tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
- } else if (atlas_source->get_tile_animation_frames_count(p_atlas_coords) == 1) {
- Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, 0);
- tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
- } else {
- real_t speed = atlas_source->get_tile_animation_speed(p_atlas_coords);
- real_t animation_duration = atlas_source->get_tile_animation_total_duration(p_atlas_coords) / speed;
- real_t animation_offset = p_normalized_animation_offset * animation_duration;
- // Accumulate durations unaffected by the speed to avoid accumulating floating point division errors.
- // Aka do `sum(duration[i]) / speed` instead of `sum(duration[i] / speed)`.
- real_t time_unscaled = 0.0;
- for (int frame = 0; frame < atlas_source->get_tile_animation_frames_count(p_atlas_coords); frame++) {
- real_t frame_duration_unscaled = atlas_source->get_tile_animation_frame_duration(p_atlas_coords, frame);
- real_t slice_start = time_unscaled / speed;
- real_t slice_end = (time_unscaled + frame_duration_unscaled) / speed;
- RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, animation_duration, slice_start, slice_end, animation_offset);
-
- Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, frame);
- tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
-
- time_unscaled += frame_duration_unscaled;
- }
- RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, 1.0, 0.0, 1.0, 0.0);
- }
- }
-}
-
void TileMap::set_tileset(const Ref<TileSet> &p_tileset) {
if (p_tileset == tile_set) {
return;
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 45604bfb8a..690102f730 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -63,8 +63,6 @@ private:
// A compatibility enum to specify how is the data if formatted.
mutable TileMapDataFormat format = TileMapDataFormat::TILE_MAP_DATA_FORMAT_3;
- static constexpr float FP_ADJUST = 0.00001;
-
// Properties.
Ref<TileSet> tile_set;
int rendering_quadrant_size = 16;
@@ -123,8 +121,6 @@ public:
void set_rendering_quadrant_size(int p_size);
int get_rendering_quadrant_size() const;
- static void draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame = -1, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0), const TileData *p_tile_data_override = nullptr, real_t p_normalized_animation_offset = 0.0);
-
// Accessors.
void set_tileset(const Ref<TileSet> &p_tileset);
Ref<TileSet> get_tileset() const;
diff --git a/scene/2d/tile_map_layer.cpp b/scene/2d/tile_map_layer.cpp
index fe51171744..0ac236eaa7 100644
--- a/scene/2d/tile_map_layer.cpp
+++ b/scene/2d/tile_map_layer.cpp
@@ -340,7 +340,7 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
}
// Drawing the tile in the canvas item.
- TileMap::draw_tile(ci, local_tile_pos - rendering_quadrant->canvas_items_position, tile_set, cell_data.cell.source_id, cell_data.cell.get_atlas_coords(), cell_data.cell.alternative_tile, -1, get_self_modulate(), tile_data, random_animation_offset);
+ draw_tile(ci, local_tile_pos - rendering_quadrant->canvas_items_position, tile_set, cell_data.cell.source_id, cell_data.cell.get_atlas_coords(), cell_data.cell.alternative_tile, -1, get_self_modulate(), tile_data, random_animation_offset);
}
// Reset physics interpolation for any recreated canvas items.
@@ -1696,18 +1696,18 @@ void TileMapLayer::_notification(int p_what) {
_internal_update(true);
} break;
- case TileMap::NOTIFICATION_ENTER_CANVAS: {
+ case NOTIFICATION_ENTER_CANVAS: {
dirty.flags[DIRTY_FLAGS_LAYER_IN_CANVAS] = true;
_queue_internal_update();
} break;
- case TileMap::NOTIFICATION_EXIT_CANVAS: {
+ case NOTIFICATION_EXIT_CANVAS: {
dirty.flags[DIRTY_FLAGS_LAYER_IN_CANVAS] = true;
// Update immediately on exiting, and force cleanup.
_internal_update(true);
} break;
- case TileMap::NOTIFICATION_VISIBILITY_CHANGED: {
+ case NOTIFICATION_VISIBILITY_CHANGED: {
dirty.flags[DIRTY_FLAGS_LAYER_VISIBILITY] = true;
_queue_internal_update();
} break;
@@ -2162,6 +2162,91 @@ TileMapCell TileMapLayer::get_cell(const Vector2i &p_coords) const {
}
}
+void TileMapLayer::draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame, Color p_modulation, const TileData *p_tile_data_override, real_t p_normalized_animation_offset) {
+ ERR_FAIL_COND(p_tile_set.is_null());
+ ERR_FAIL_COND(!p_tile_set->has_source(p_atlas_source_id));
+ ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_tile(p_atlas_coords));
+ ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_alternative_tile(p_atlas_coords, p_alternative_tile));
+ TileSetSource *source = *p_tile_set->get_source(p_atlas_source_id);
+ TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
+ if (atlas_source) {
+ // Check for the frame.
+ if (p_frame >= 0) {
+ ERR_FAIL_INDEX(p_frame, atlas_source->get_tile_animation_frames_count(p_atlas_coords));
+ }
+
+ // Get the texture.
+ Ref<Texture2D> tex = atlas_source->get_runtime_texture();
+ if (tex.is_null()) {
+ return;
+ }
+
+ // Check if we are in the texture, return otherwise.
+ Vector2i grid_size = atlas_source->get_atlas_grid_size();
+ if (p_atlas_coords.x >= grid_size.x || p_atlas_coords.y >= grid_size.y) {
+ return;
+ }
+
+ // Get tile data.
+ const TileData *tile_data = p_tile_data_override ? p_tile_data_override : atlas_source->get_tile_data(p_atlas_coords, p_alternative_tile);
+
+ // Get the tile modulation.
+ Color modulate = tile_data->get_modulate() * p_modulation;
+
+ // Compute the offset.
+ Vector2 tile_offset = tile_data->get_texture_origin();
+
+ // Get destination rect.
+ Rect2 dest_rect;
+ dest_rect.size = atlas_source->get_runtime_tile_texture_region(p_atlas_coords).size;
+ dest_rect.size.x += FP_ADJUST;
+ dest_rect.size.y += FP_ADJUST;
+
+ bool transpose = tile_data->get_transpose() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_TRANSPOSE);
+ if (transpose) {
+ dest_rect.position = (p_position - Vector2(dest_rect.size.y, dest_rect.size.x) / 2 - tile_offset);
+ } else {
+ dest_rect.position = (p_position - dest_rect.size / 2 - tile_offset);
+ }
+
+ if (tile_data->get_flip_h() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_H)) {
+ dest_rect.size.x = -dest_rect.size.x;
+ }
+
+ if (tile_data->get_flip_v() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_V)) {
+ dest_rect.size.y = -dest_rect.size.y;
+ }
+
+ // Draw the tile.
+ if (p_frame >= 0) {
+ Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, p_frame);
+ tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
+ } else if (atlas_source->get_tile_animation_frames_count(p_atlas_coords) == 1) {
+ Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, 0);
+ tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
+ } else {
+ real_t speed = atlas_source->get_tile_animation_speed(p_atlas_coords);
+ real_t animation_duration = atlas_source->get_tile_animation_total_duration(p_atlas_coords) / speed;
+ real_t animation_offset = p_normalized_animation_offset * animation_duration;
+ // Accumulate durations unaffected by the speed to avoid accumulating floating point division errors.
+ // Aka do `sum(duration[i]) / speed` instead of `sum(duration[i] / speed)`.
+ real_t time_unscaled = 0.0;
+ for (int frame = 0; frame < atlas_source->get_tile_animation_frames_count(p_atlas_coords); frame++) {
+ real_t frame_duration_unscaled = atlas_source->get_tile_animation_frame_duration(p_atlas_coords, frame);
+ real_t slice_start = time_unscaled / speed;
+ real_t slice_end = (time_unscaled + frame_duration_unscaled) / speed;
+ RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, animation_duration, slice_start, slice_end, animation_offset);
+
+ Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, frame);
+ tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
+
+ time_unscaled += frame_duration_unscaled;
+ }
+ RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, 1.0, 0.0, 1.0, 0.0);
+ }
+ }
+}
+
void TileMapLayer::set_cell(const Vector2i &p_coords, int p_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile) {
// Set the current cell tile (using integer position).
Vector2i pk(p_coords);
@@ -2212,7 +2297,7 @@ void TileMapLayer::erase_cell(const Vector2i &p_coords) {
}
void TileMapLayer::fix_invalid_tiles() {
- ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot call fix_invalid_tiles() on a TileMap without a valid TileSet.");
+ ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot call fix_invalid_tiles() on a TileMapLayer without a valid TileSet.");
RBSet<Vector2i> coords;
for (const KeyValue<Vector2i, CellData> &E : tile_map_layer_data) {
diff --git a/scene/2d/tile_map_layer.h b/scene/2d/tile_map_layer.h
index 5861433c8a..57c83d7c4c 100644
--- a/scene/2d/tile_map_layer.h
+++ b/scene/2d/tile_map_layer.h
@@ -269,6 +269,8 @@ public:
};
private:
+ static constexpr float FP_ADJUST = 0.00001;
+
// Properties.
HashMap<Vector2i, CellData> tile_map_layer_data;
@@ -407,6 +409,8 @@ public:
// Not exposed to users.
TileMapCell get_cell(const Vector2i &p_coords) const;
+ static void draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame = -1, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0), const TileData *p_tile_data_override = nullptr, real_t p_normalized_animation_offset = 0.0);
+
////////////// Exposed functions //////////////
// --- Cells manipulation ---