summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/windows_builds.yml2
-rw-r--r--.gitignore4
-rw-r--r--core/io/marshalls.cpp6
-rw-r--r--core/io/resource_format_binary.cpp64
-rw-r--r--core/math/delaunay_3d.h38
-rw-r--r--core/math/math_fieldwise.cpp32
-rw-r--r--core/math/projection.cpp212
-rw-r--r--core/math/projection.h16
-rw-r--r--core/variant/variant.cpp48
-rw-r--r--core/variant/variant_parser.cpp2
-rw-r--r--core/variant/variant_setget.cpp2
-rw-r--r--core/variant/variant_setget.h8
-rw-r--r--doc/classes/@GlobalScope.xml8
-rw-r--r--doc/classes/AtlasTexture.xml4
-rw-r--r--doc/classes/Camera2D.xml7
-rw-r--r--doc/classes/Control.xml26
-rw-r--r--doc/classes/DisplayServer.xml45
-rw-r--r--doc/classes/Image.xml1
-rw-r--r--doc/classes/OS.xml2
-rw-r--r--doc/classes/Window.xml41
-rw-r--r--doc/classes/World2D.xml2
-rw-r--r--doc/classes/World3D.xml2
-rw-r--r--doc/classes/XRInterfaceExtension.xml33
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp6
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp4
-rw-r--r--drivers/gles3/storage/material_storage.cpp2
-rw-r--r--drivers/gles3/storage/material_storage.h2
-rw-r--r--drivers/gles3/storage/texture_storage.cpp152
-rw-r--r--drivers/gles3/storage/texture_storage.h38
-rw-r--r--editor/action_map_editor.cpp289
-rw-r--r--editor/action_map_editor.h61
-rw-r--r--editor/code_editor.cpp37
-rw-r--r--editor/code_editor.h1
-rw-r--r--editor/editor_properties.cpp64
-rw-r--r--editor/editor_settings_dialog.cpp71
-rw-r--r--editor/editor_settings_dialog.h6
-rw-r--r--editor/plugins/input_event_editor_plugin.cpp8
-rw-r--r--editor/plugins/script_editor_plugin.cpp15
-rw-r--r--editor/plugins/script_editor_plugin.h1
-rw-r--r--editor/plugins/script_text_editor.cpp4
-rw-r--r--editor/plugins/script_text_editor.h1
-rw-r--r--editor/plugins/text_editor.cpp4
-rw-r--r--editor/plugins/text_editor.h1
-rw-r--r--editor/plugins/tiles/tile_set_atlas_source_editor.cpp7
-rw-r--r--gles3_builders.py10
-rw-r--r--methods.py10
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.cpp8
-rw-r--r--modules/gdscript/tests/scripts/parser/features/dictionary.out4
-rw-r--r--modules/gdscript/tests/scripts/parser/features/dictionary_lua_style.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/dictionary_mixed_syntax.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/nested_dictionary.out4
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out4
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/stringify.out2
-rw-r--r--modules/gltf/editor/editor_scene_importer_blend.cpp13
-rw-r--r--modules/mono/editor/bindings_generator.cpp6
-rw-r--r--modules/openxr/SCsub1
-rw-r--r--modules/openxr/extensions/openxr_composition_layer_depth_extension.cpp58
-rw-r--r--modules/openxr/extensions/openxr_composition_layer_depth_extension.h53
-rw-r--r--modules/openxr/extensions/openxr_composition_layer_provider.h1
-rw-r--r--modules/openxr/extensions/openxr_extension_wrapper.h3
-rw-r--r--modules/openxr/extensions/openxr_vulkan_extension.cpp76
-rw-r--r--modules/openxr/extensions/openxr_vulkan_extension.h6
-rw-r--r--modules/openxr/openxr_api.cpp200
-rw-r--r--modules/openxr/openxr_api.h31
-rw-r--r--modules/openxr/openxr_interface.cpp18
-rw-r--r--modules/openxr/openxr_interface.h3
-rw-r--r--modules/webxr/webxr_interface_js.cpp6
-rw-r--r--platform/linuxbsd/detect.py6
-rw-r--r--platform/web/package-lock.json1221
-rw-r--r--platform/web/package.json6
-rw-r--r--platform/web/serve.json21
-rwxr-xr-xplatform/web/serve.py52
-rw-r--r--scene/2d/camera_2d.cpp62
-rw-r--r--scene/2d/camera_2d.h13
-rw-r--r--scene/gui/line_edit.h3
-rw-r--r--scene/resources/texture.cpp10
-rw-r--r--servers/rendering/dummy/storage/texture_storage.h24
-rw-r--r--servers/rendering/renderer_rd/effects/ss_effects.cpp30
-rw-r--r--servers/rendering/renderer_rd/environment/gi.cpp16
-rw-r--r--servers/rendering/renderer_rd/environment/sky.cpp8
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp6
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp6
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp6
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp10
-rw-r--r--servers/rendering/renderer_rd/storage_rd/material_storage.cpp2
-rw-r--r--servers/rendering/renderer_rd/storage_rd/material_storage.h2
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp58
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h12
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.cpp166
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.h64
-rw-r--r--servers/rendering/renderer_viewport.cpp10
-rw-r--r--servers/rendering/storage/texture_storage.h26
-rw-r--r--servers/rendering_server.cpp1
-rw-r--r--servers/xr/xr_interface.cpp13
-rw-r--r--servers/xr/xr_interface.h5
-rw-r--r--servers/xr/xr_interface_extension.cpp38
-rw-r--r--servers/xr/xr_interface_extension.h6
97 files changed, 1676 insertions, 2127 deletions
diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml
index b35c811763..507bb21a46 100644
--- a/.github/workflows/windows_builds.yml
+++ b/.github/workflows/windows_builds.yml
@@ -27,7 +27,7 @@ jobs:
target: editor
tests: true
# Skip debug symbols, they're way too big with MSVC.
- sconsflags: debug_symbols=no
+ sconsflags: debug_symbols=no vsproj=yes
bin: "./bin/godot.windows.editor.x86_64.exe"
- name: Template (target=template_release, tools=no)
diff --git a/.gitignore b/.gitignore
index 539003ca6b..1a83e4707e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -82,9 +82,9 @@ platform/android/java/*/libs/
# iOS
*.dSYM
-# Javascript
+# Web platform
*.bc
-platform/javascript/node_modules/
+platform/web/node_modules/
# Misc
*.debug
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index b24c49f58d..9ba653e1a9 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -503,7 +503,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
ERR_FAIL_COND_V((size_t)len < sizeof(double) * 16, ERR_INVALID_DATA);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- val.matrix[i][j] = decode_double(&buf[(i * 4 + j) * sizeof(double)]);
+ val.columns[i][j] = decode_double(&buf[(i * 4 + j) * sizeof(double)]);
}
}
if (r_len) {
@@ -513,7 +513,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
ERR_FAIL_COND_V((size_t)len < sizeof(float) * 16, ERR_INVALID_DATA);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- val.matrix[i][j] = decode_float(&buf[(i * 4 + j) * sizeof(float)]);
+ val.columns[i][j] = decode_float(&buf[(i * 4 + j) * sizeof(float)]);
}
}
@@ -1450,7 +1450,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
Projection val = p_variant;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- memcpy(&buf[(i * 4 + j) * sizeof(real_t)], &val.matrix[i][j], sizeof(real_t));
+ memcpy(&buf[(i * 4 + j) * sizeof(real_t)], &val.columns[i][j], sizeof(real_t));
}
}
}
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 36fa77626e..9ab45f85b8 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -327,22 +327,22 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_PROJECTION: {
Projection v;
- v.matrix[0].x = f->get_real();
- v.matrix[0].y = f->get_real();
- v.matrix[0].z = f->get_real();
- v.matrix[0].w = f->get_real();
- v.matrix[1].x = f->get_real();
- v.matrix[1].y = f->get_real();
- v.matrix[1].z = f->get_real();
- v.matrix[1].w = f->get_real();
- v.matrix[2].x = f->get_real();
- v.matrix[2].y = f->get_real();
- v.matrix[2].z = f->get_real();
- v.matrix[2].w = f->get_real();
- v.matrix[3].x = f->get_real();
- v.matrix[3].y = f->get_real();
- v.matrix[3].z = f->get_real();
- v.matrix[3].w = f->get_real();
+ v.columns[0].x = f->get_real();
+ v.columns[0].y = f->get_real();
+ v.columns[0].z = f->get_real();
+ v.columns[0].w = f->get_real();
+ v.columns[1].x = f->get_real();
+ v.columns[1].y = f->get_real();
+ v.columns[1].z = f->get_real();
+ v.columns[1].w = f->get_real();
+ v.columns[2].x = f->get_real();
+ v.columns[2].y = f->get_real();
+ v.columns[2].z = f->get_real();
+ v.columns[2].w = f->get_real();
+ v.columns[3].x = f->get_real();
+ v.columns[3].y = f->get_real();
+ v.columns[3].z = f->get_real();
+ v.columns[3].w = f->get_real();
r_v = v;
} break;
case VARIANT_COLOR: {
@@ -1630,22 +1630,22 @@ void ResourceFormatSaverBinaryInstance::write_variant(Ref<FileAccess> f, const V
case Variant::PROJECTION: {
f->store_32(VARIANT_PROJECTION);
Projection val = p_property;
- f->store_real(val.matrix[0].x);
- f->store_real(val.matrix[0].y);
- f->store_real(val.matrix[0].z);
- f->store_real(val.matrix[0].w);
- f->store_real(val.matrix[1].x);
- f->store_real(val.matrix[1].y);
- f->store_real(val.matrix[1].z);
- f->store_real(val.matrix[1].w);
- f->store_real(val.matrix[2].x);
- f->store_real(val.matrix[2].y);
- f->store_real(val.matrix[2].z);
- f->store_real(val.matrix[2].w);
- f->store_real(val.matrix[3].x);
- f->store_real(val.matrix[3].y);
- f->store_real(val.matrix[3].z);
- f->store_real(val.matrix[3].w);
+ f->store_real(val.columns[0].x);
+ f->store_real(val.columns[0].y);
+ f->store_real(val.columns[0].z);
+ f->store_real(val.columns[0].w);
+ f->store_real(val.columns[1].x);
+ f->store_real(val.columns[1].y);
+ f->store_real(val.columns[1].z);
+ f->store_real(val.columns[1].w);
+ f->store_real(val.columns[2].x);
+ f->store_real(val.columns[2].y);
+ f->store_real(val.columns[2].z);
+ f->store_real(val.columns[2].w);
+ f->store_real(val.columns[3].x);
+ f->store_real(val.columns[3].y);
+ f->store_real(val.columns[3].z);
+ f->store_real(val.columns[3].w);
} break;
case Variant::COLOR: {
diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h
index 898c3c2d91..13d93d7f67 100644
--- a/core/math/delaunay_3d.h
+++ b/core/math/delaunay_3d.h
@@ -186,25 +186,25 @@ class Delaunay3D {
Projection cm;
- cm.matrix[0][0] = p_points[p_simplex.points[0]].x;
- cm.matrix[0][1] = p_points[p_simplex.points[1]].x;
- cm.matrix[0][2] = p_points[p_simplex.points[2]].x;
- cm.matrix[0][3] = p_points[p_simplex.points[3]].x;
-
- cm.matrix[1][0] = p_points[p_simplex.points[0]].y;
- cm.matrix[1][1] = p_points[p_simplex.points[1]].y;
- cm.matrix[1][2] = p_points[p_simplex.points[2]].y;
- cm.matrix[1][3] = p_points[p_simplex.points[3]].y;
-
- cm.matrix[2][0] = p_points[p_simplex.points[0]].z;
- cm.matrix[2][1] = p_points[p_simplex.points[1]].z;
- cm.matrix[2][2] = p_points[p_simplex.points[2]].z;
- cm.matrix[2][3] = p_points[p_simplex.points[3]].z;
-
- cm.matrix[3][0] = 1.0;
- cm.matrix[3][1] = 1.0;
- cm.matrix[3][2] = 1.0;
- cm.matrix[3][3] = 1.0;
+ cm.columns[0][0] = p_points[p_simplex.points[0]].x;
+ cm.columns[0][1] = p_points[p_simplex.points[1]].x;
+ cm.columns[0][2] = p_points[p_simplex.points[2]].x;
+ cm.columns[0][3] = p_points[p_simplex.points[3]].x;
+
+ cm.columns[1][0] = p_points[p_simplex.points[0]].y;
+ cm.columns[1][1] = p_points[p_simplex.points[1]].y;
+ cm.columns[1][2] = p_points[p_simplex.points[2]].y;
+ cm.columns[1][3] = p_points[p_simplex.points[3]].y;
+
+ cm.columns[2][0] = p_points[p_simplex.points[0]].z;
+ cm.columns[2][1] = p_points[p_simplex.points[1]].z;
+ cm.columns[2][2] = p_points[p_simplex.points[2]].z;
+ cm.columns[2][3] = p_points[p_simplex.points[3]].z;
+
+ cm.columns[3][0] = 1.0;
+ cm.columns[3][1] = 1.0;
+ cm.columns[3][2] = 1.0;
+ cm.columns[3][3] = 1.0;
return ABS(cm.determinant()) <= CMP_EPSILON;
}
diff --git a/core/math/math_fieldwise.cpp b/core/math/math_fieldwise.cpp
index 726a2aeb97..7b30b9a98c 100644
--- a/core/math/math_fieldwise.cpp
+++ b/core/math/math_fieldwise.cpp
@@ -215,22 +215,22 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const
case Variant::PROJECTION: {
SETUP_TYPE(Projection)
- /**/ TRY_TRANSFER_FIELD("xx", matrix[0].x)
- else TRY_TRANSFER_FIELD("xy", matrix[0].y)
- else TRY_TRANSFER_FIELD("xz", matrix[0].z)
- else TRY_TRANSFER_FIELD("xw", matrix[0].w)
- else TRY_TRANSFER_FIELD("yx", matrix[1].x)
- else TRY_TRANSFER_FIELD("yy", matrix[1].y)
- else TRY_TRANSFER_FIELD("yz", matrix[1].z)
- else TRY_TRANSFER_FIELD("yw", matrix[1].w)
- else TRY_TRANSFER_FIELD("zx", matrix[2].x)
- else TRY_TRANSFER_FIELD("zy", matrix[2].y)
- else TRY_TRANSFER_FIELD("zz", matrix[2].z)
- else TRY_TRANSFER_FIELD("zw", matrix[2].w)
- else TRY_TRANSFER_FIELD("xo", matrix[3].x)
- else TRY_TRANSFER_FIELD("yo", matrix[3].y)
- else TRY_TRANSFER_FIELD("zo", matrix[3].z)
- else TRY_TRANSFER_FIELD("wo", matrix[3].w)
+ /**/ TRY_TRANSFER_FIELD("xx", columns[0].x)
+ else TRY_TRANSFER_FIELD("xy", columns[0].y)
+ else TRY_TRANSFER_FIELD("xz", columns[0].z)
+ else TRY_TRANSFER_FIELD("xw", columns[0].w)
+ else TRY_TRANSFER_FIELD("yx", columns[1].x)
+ else TRY_TRANSFER_FIELD("yy", columns[1].y)
+ else TRY_TRANSFER_FIELD("yz", columns[1].z)
+ else TRY_TRANSFER_FIELD("yw", columns[1].w)
+ else TRY_TRANSFER_FIELD("zx", columns[2].x)
+ else TRY_TRANSFER_FIELD("zy", columns[2].y)
+ else TRY_TRANSFER_FIELD("zz", columns[2].z)
+ else TRY_TRANSFER_FIELD("zw", columns[2].w)
+ else TRY_TRANSFER_FIELD("xo", columns[3].x)
+ else TRY_TRANSFER_FIELD("yo", columns[3].y)
+ else TRY_TRANSFER_FIELD("zo", columns[3].z)
+ else TRY_TRANSFER_FIELD("wo", columns[3].w)
return target;
}
diff --git a/core/math/projection.cpp b/core/math/projection.cpp
index 863fe6ee79..d579b641a7 100644
--- a/core/math/projection.cpp
+++ b/core/math/projection.cpp
@@ -38,24 +38,24 @@
#include "core/string/print_string.h"
float Projection::determinant() const {
- return matrix[0][3] * matrix[1][2] * matrix[2][1] * matrix[3][0] - matrix[0][2] * matrix[1][3] * matrix[2][1] * matrix[3][0] -
- matrix[0][3] * matrix[1][1] * matrix[2][2] * matrix[3][0] + matrix[0][1] * matrix[1][3] * matrix[2][2] * matrix[3][0] +
- matrix[0][2] * matrix[1][1] * matrix[2][3] * matrix[3][0] - matrix[0][1] * matrix[1][2] * matrix[2][3] * matrix[3][0] -
- matrix[0][3] * matrix[1][2] * matrix[2][0] * matrix[3][1] + matrix[0][2] * matrix[1][3] * matrix[2][0] * matrix[3][1] +
- matrix[0][3] * matrix[1][0] * matrix[2][2] * matrix[3][1] - matrix[0][0] * matrix[1][3] * matrix[2][2] * matrix[3][1] -
- matrix[0][2] * matrix[1][0] * matrix[2][3] * matrix[3][1] + matrix[0][0] * matrix[1][2] * matrix[2][3] * matrix[3][1] +
- matrix[0][3] * matrix[1][1] * matrix[2][0] * matrix[3][2] - matrix[0][1] * matrix[1][3] * matrix[2][0] * matrix[3][2] -
- matrix[0][3] * matrix[1][0] * matrix[2][1] * matrix[3][2] + matrix[0][0] * matrix[1][3] * matrix[2][1] * matrix[3][2] +
- matrix[0][1] * matrix[1][0] * matrix[2][3] * matrix[3][2] - matrix[0][0] * matrix[1][1] * matrix[2][3] * matrix[3][2] -
- matrix[0][2] * matrix[1][1] * matrix[2][0] * matrix[3][3] + matrix[0][1] * matrix[1][2] * matrix[2][0] * matrix[3][3] +
- matrix[0][2] * matrix[1][0] * matrix[2][1] * matrix[3][3] - matrix[0][0] * matrix[1][2] * matrix[2][1] * matrix[3][3] -
- matrix[0][1] * matrix[1][0] * matrix[2][2] * matrix[3][3] + matrix[0][0] * matrix[1][1] * matrix[2][2] * matrix[3][3];
+ return columns[0][3] * columns[1][2] * columns[2][1] * columns[3][0] - columns[0][2] * columns[1][3] * columns[2][1] * columns[3][0] -
+ columns[0][3] * columns[1][1] * columns[2][2] * columns[3][0] + columns[0][1] * columns[1][3] * columns[2][2] * columns[3][0] +
+ columns[0][2] * columns[1][1] * columns[2][3] * columns[3][0] - columns[0][1] * columns[1][2] * columns[2][3] * columns[3][0] -
+ columns[0][3] * columns[1][2] * columns[2][0] * columns[3][1] + columns[0][2] * columns[1][3] * columns[2][0] * columns[3][1] +
+ columns[0][3] * columns[1][0] * columns[2][2] * columns[3][1] - columns[0][0] * columns[1][3] * columns[2][2] * columns[3][1] -
+ columns[0][2] * columns[1][0] * columns[2][3] * columns[3][1] + columns[0][0] * columns[1][2] * columns[2][3] * columns[3][1] +
+ columns[0][3] * columns[1][1] * columns[2][0] * columns[3][2] - columns[0][1] * columns[1][3] * columns[2][0] * columns[3][2] -
+ columns[0][3] * columns[1][0] * columns[2][1] * columns[3][2] + columns[0][0] * columns[1][3] * columns[2][1] * columns[3][2] +
+ columns[0][1] * columns[1][0] * columns[2][3] * columns[3][2] - columns[0][0] * columns[1][1] * columns[2][3] * columns[3][2] -
+ columns[0][2] * columns[1][1] * columns[2][0] * columns[3][3] + columns[0][1] * columns[1][2] * columns[2][0] * columns[3][3] +
+ columns[0][2] * columns[1][0] * columns[2][1] * columns[3][3] - columns[0][0] * columns[1][2] * columns[2][1] * columns[3][3] -
+ columns[0][1] * columns[1][0] * columns[2][2] * columns[3][3] + columns[0][0] * columns[1][1] * columns[2][2] * columns[3][3];
}
void Projection::set_identity() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- matrix[i][j] = (i == j) ? 1 : 0;
+ columns[i][j] = (i == j) ? 1 : 0;
}
}
}
@@ -63,7 +63,7 @@ void Projection::set_identity() {
void Projection::set_zero() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- matrix[i][j] = 0;
+ columns[i][j] = 0;
}
}
}
@@ -71,26 +71,26 @@ void Projection::set_zero() {
Plane Projection::xform4(const Plane &p_vec4) const {
Plane ret;
- ret.normal.x = matrix[0][0] * p_vec4.normal.x + matrix[1][0] * p_vec4.normal.y + matrix[2][0] * p_vec4.normal.z + matrix[3][0] * p_vec4.d;
- ret.normal.y = matrix[0][1] * p_vec4.normal.x + matrix[1][1] * p_vec4.normal.y + matrix[2][1] * p_vec4.normal.z + matrix[3][1] * p_vec4.d;
- ret.normal.z = matrix[0][2] * p_vec4.normal.x + matrix[1][2] * p_vec4.normal.y + matrix[2][2] * p_vec4.normal.z + matrix[3][2] * p_vec4.d;
- ret.d = matrix[0][3] * p_vec4.normal.x + matrix[1][3] * p_vec4.normal.y + matrix[2][3] * p_vec4.normal.z + matrix[3][3] * p_vec4.d;
+ ret.normal.x = columns[0][0] * p_vec4.normal.x + columns[1][0] * p_vec4.normal.y + columns[2][0] * p_vec4.normal.z + columns[3][0] * p_vec4.d;
+ ret.normal.y = columns[0][1] * p_vec4.normal.x + columns[1][1] * p_vec4.normal.y + columns[2][1] * p_vec4.normal.z + columns[3][1] * p_vec4.d;
+ ret.normal.z = columns[0][2] * p_vec4.normal.x + columns[1][2] * p_vec4.normal.y + columns[2][2] * p_vec4.normal.z + columns[3][2] * p_vec4.d;
+ ret.d = columns[0][3] * p_vec4.normal.x + columns[1][3] * p_vec4.normal.y + columns[2][3] * p_vec4.normal.z + columns[3][3] * p_vec4.d;
return ret;
}
Vector4 Projection::xform(const Vector4 &p_vec4) const {
return Vector4(
- matrix[0][0] * p_vec4.x + matrix[1][0] * p_vec4.y + matrix[2][0] * p_vec4.z + matrix[3][0] * p_vec4.w,
- matrix[0][1] * p_vec4.x + matrix[1][1] * p_vec4.y + matrix[2][1] * p_vec4.z + matrix[3][1] * p_vec4.w,
- matrix[0][2] * p_vec4.x + matrix[1][2] * p_vec4.y + matrix[2][2] * p_vec4.z + matrix[3][2] * p_vec4.w,
- matrix[0][3] * p_vec4.x + matrix[1][3] * p_vec4.y + matrix[2][3] * p_vec4.z + matrix[3][3] * p_vec4.w);
+ columns[0][0] * p_vec4.x + columns[1][0] * p_vec4.y + columns[2][0] * p_vec4.z + columns[3][0] * p_vec4.w,
+ columns[0][1] * p_vec4.x + columns[1][1] * p_vec4.y + columns[2][1] * p_vec4.z + columns[3][1] * p_vec4.w,
+ columns[0][2] * p_vec4.x + columns[1][2] * p_vec4.y + columns[2][2] * p_vec4.z + columns[3][2] * p_vec4.w,
+ columns[0][3] * p_vec4.x + columns[1][3] * p_vec4.y + columns[2][3] * p_vec4.z + columns[3][3] * p_vec4.w);
}
Vector4 Projection::xform_inv(const Vector4 &p_vec4) const {
return Vector4(
- matrix[0][0] * p_vec4.x + matrix[0][1] * p_vec4.y + matrix[0][2] * p_vec4.z + matrix[0][3] * p_vec4.w,
- matrix[1][0] * p_vec4.x + matrix[1][1] * p_vec4.y + matrix[1][2] * p_vec4.z + matrix[1][3] * p_vec4.w,
- matrix[2][0] * p_vec4.x + matrix[2][1] * p_vec4.y + matrix[2][2] * p_vec4.z + matrix[2][3] * p_vec4.w,
- matrix[3][0] * p_vec4.x + matrix[3][1] * p_vec4.y + matrix[3][2] * p_vec4.z + matrix[3][3] * p_vec4.w);
+ columns[0][0] * p_vec4.x + columns[0][1] * p_vec4.y + columns[0][2] * p_vec4.z + columns[0][3] * p_vec4.w,
+ columns[1][0] * p_vec4.x + columns[1][1] * p_vec4.y + columns[1][2] * p_vec4.z + columns[1][3] * p_vec4.w,
+ columns[2][0] * p_vec4.x + columns[2][1] * p_vec4.y + columns[2][2] * p_vec4.z + columns[2][3] * p_vec4.w,
+ columns[3][0] * p_vec4.x + columns[3][1] * p_vec4.y + columns[3][2] * p_vec4.z + columns[3][3] * p_vec4.w);
}
void Projection::adjust_perspective_znear(real_t p_new_znear) {
@@ -98,8 +98,8 @@ void Projection::adjust_perspective_znear(real_t p_new_znear) {
real_t znear = p_new_znear;
real_t deltaZ = zfar - znear;
- matrix[2][2] = -(zfar + znear) / deltaZ;
- matrix[3][2] = -2 * znear * zfar / deltaZ;
+ columns[2][2] = -(zfar + znear) / deltaZ;
+ columns[3][2] = -2 * znear * zfar / deltaZ;
}
Projection Projection::create_depth_correction(bool p_flip_y) {
@@ -169,7 +169,7 @@ Projection Projection::perspective_znear_adjusted(real_t p_new_znear) const {
}
Plane Projection::get_projection_plane(Planes p_plane) const {
- const real_t *matrix = (const real_t *)this->matrix;
+ const real_t *matrix = (const real_t *)this->columns;
switch (p_plane) {
case PLANE_NEAR: {
@@ -267,12 +267,12 @@ void Projection::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t
set_identity();
- matrix[0][0] = cotangent / p_aspect;
- matrix[1][1] = cotangent;
- matrix[2][2] = -(p_z_far + p_z_near) / deltaZ;
- matrix[2][3] = -1;
- matrix[3][2] = -2 * p_z_near * p_z_far / deltaZ;
- matrix[3][3] = 0;
+ columns[0][0] = cotangent / p_aspect;
+ columns[1][1] = cotangent;
+ columns[2][2] = -(p_z_far + p_z_near) / deltaZ;
+ columns[2][3] = -1;
+ columns[3][2] = -2 * p_z_near * p_z_far / deltaZ;
+ columns[3][3] = 0;
}
void Projection::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist) {
@@ -309,7 +309,7 @@ void Projection::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t
// translate matrix by (modeltranslation, 0.0, 0.0)
Projection cm;
cm.set_identity();
- cm.matrix[3][0] = modeltranslation;
+ cm.columns[3][0] = modeltranslation;
*this = *this * cm;
}
@@ -344,13 +344,13 @@ void Projection::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_di
void Projection::set_orthogonal(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_znear, real_t p_zfar) {
set_identity();
- matrix[0][0] = 2.0 / (p_right - p_left);
- matrix[3][0] = -((p_right + p_left) / (p_right - p_left));
- matrix[1][1] = 2.0 / (p_top - p_bottom);
- matrix[3][1] = -((p_top + p_bottom) / (p_top - p_bottom));
- matrix[2][2] = -2.0 / (p_zfar - p_znear);
- matrix[3][2] = -((p_zfar + p_znear) / (p_zfar - p_znear));
- matrix[3][3] = 1.0;
+ columns[0][0] = 2.0 / (p_right - p_left);
+ columns[3][0] = -((p_right + p_left) / (p_right - p_left));
+ columns[1][1] = 2.0 / (p_top - p_bottom);
+ columns[3][1] = -((p_top + p_bottom) / (p_top - p_bottom));
+ columns[2][2] = -2.0 / (p_zfar - p_znear);
+ columns[3][2] = -((p_zfar + p_znear) / (p_zfar - p_znear));
+ columns[3][3] = 1.0;
}
void Projection::set_orthogonal(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov) {
@@ -366,7 +366,7 @@ void Projection::set_frustum(real_t p_left, real_t p_right, real_t p_bottom, rea
ERR_FAIL_COND(p_top <= p_bottom);
ERR_FAIL_COND(p_far <= p_near);
- real_t *te = &matrix[0][0];
+ real_t *te = &columns[0][0];
real_t x = 2 * p_near / (p_right - p_left);
real_t y = 2 * p_near / (p_top - p_bottom);
@@ -402,7 +402,7 @@ void Projection::set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, r
}
real_t Projection::get_z_far() const {
- const real_t *matrix = (const real_t *)this->matrix;
+ const real_t *matrix = (const real_t *)this->columns;
Plane new_plane = Plane(matrix[3] - matrix[2],
matrix[7] - matrix[6],
matrix[11] - matrix[10],
@@ -415,7 +415,7 @@ real_t Projection::get_z_far() const {
}
real_t Projection::get_z_near() const {
- const real_t *matrix = (const real_t *)this->matrix;
+ const real_t *matrix = (const real_t *)this->columns;
Plane new_plane = Plane(matrix[3] + matrix[2],
matrix[7] + matrix[6],
matrix[11] + matrix[10],
@@ -426,7 +426,7 @@ real_t Projection::get_z_near() const {
}
Vector2 Projection::get_viewport_half_extents() const {
- const real_t *matrix = (const real_t *)this->matrix;
+ const real_t *matrix = (const real_t *)this->columns;
///////--- Near Plane ---///////
Plane near_plane = Plane(matrix[3] + matrix[2],
matrix[7] + matrix[6],
@@ -454,7 +454,7 @@ Vector2 Projection::get_viewport_half_extents() const {
}
Vector2 Projection::get_far_plane_half_extents() const {
- const real_t *matrix = (const real_t *)this->matrix;
+ const real_t *matrix = (const real_t *)this->columns;
///////--- Far Plane ---///////
Plane far_plane = Plane(matrix[3] - matrix[2],
matrix[7] - matrix[6],
@@ -514,7 +514,7 @@ Vector<Plane> Projection::get_projection_planes(const Transform3D &p_transform)
Vector<Plane> planes;
planes.resize(6);
- const real_t *matrix = (const real_t *)this->matrix;
+ const real_t *matrix = (const real_t *)this->columns;
Plane new_plane;
@@ -601,15 +601,15 @@ void Projection::invert() {
real_t determinant = 1.0f;
for (k = 0; k < 4; k++) {
/** Locate k'th pivot element **/
- pvt_val = matrix[k][k]; /** Initialize for search **/
+ pvt_val = columns[k][k]; /** Initialize for search **/
pvt_i[k] = k;
pvt_j[k] = k;
for (i = k; i < 4; i++) {
for (j = k; j < 4; j++) {
- if (Math::abs(matrix[i][j]) > Math::abs(pvt_val)) {
+ if (Math::abs(columns[i][j]) > Math::abs(pvt_val)) {
pvt_i[k] = i;
pvt_j[k] = j;
- pvt_val = matrix[i][j];
+ pvt_val = columns[i][j];
}
}
}
@@ -624,9 +624,9 @@ void Projection::invert() {
i = pvt_i[k];
if (i != k) { /** If rows are different **/
for (j = 0; j < 4; j++) {
- hold = -matrix[k][j];
- matrix[k][j] = matrix[i][j];
- matrix[i][j] = hold;
+ hold = -columns[k][j];
+ columns[k][j] = columns[i][j];
+ columns[i][j] = hold;
}
}
@@ -634,25 +634,25 @@ void Projection::invert() {
j = pvt_j[k];
if (j != k) { /** If columns are different **/
for (i = 0; i < 4; i++) {
- hold = -matrix[i][k];
- matrix[i][k] = matrix[i][j];
- matrix[i][j] = hold;
+ hold = -columns[i][k];
+ columns[i][k] = columns[i][j];
+ columns[i][j] = hold;
}
}
/** Divide column by minus pivot value **/
for (i = 0; i < 4; i++) {
if (i != k) {
- matrix[i][k] /= (-pvt_val);
+ columns[i][k] /= (-pvt_val);
}
}
/** Reduce the matrix **/
for (i = 0; i < 4; i++) {
- hold = matrix[i][k];
+ hold = columns[i][k];
for (j = 0; j < 4; j++) {
if (i != k && j != k) {
- matrix[i][j] += hold * matrix[k][j];
+ columns[i][j] += hold * columns[k][j];
}
}
}
@@ -660,12 +660,12 @@ void Projection::invert() {
/** Divide row by pivot **/
for (j = 0; j < 4; j++) {
if (j != k) {
- matrix[k][j] /= pvt_val;
+ columns[k][j] /= pvt_val;
}
}
/** Replace pivot by reciprocal (at last we can touch it). **/
- matrix[k][k] = 1.0 / pvt_val;
+ columns[k][k] = 1.0 / pvt_val;
}
/* That was most of the work, one final pass of row/column interchange */
@@ -674,18 +674,18 @@ void Projection::invert() {
i = pvt_j[k]; /* Rows to swap correspond to pivot COLUMN */
if (i != k) { /* If rows are different */
for (j = 0; j < 4; j++) {
- hold = matrix[k][j];
- matrix[k][j] = -matrix[i][j];
- matrix[i][j] = hold;
+ hold = columns[k][j];
+ columns[k][j] = -columns[i][j];
+ columns[i][j] = hold;
}
}
j = pvt_i[k]; /* Columns to swap correspond to pivot ROW */
if (j != k) { /* If columns are different */
for (i = 0; i < 4; i++) {
- hold = matrix[i][k];
- matrix[i][k] = -matrix[i][j];
- matrix[i][j] = hold;
+ hold = columns[i][k];
+ columns[i][k] = -columns[i][j];
+ columns[i][j] = hold;
}
}
}
@@ -693,7 +693,7 @@ void Projection::invert() {
void Projection::flip_y() {
for (int i = 0; i < 4; i++) {
- matrix[1][i] = -matrix[1][i];
+ columns[1][i] = -columns[1][i];
}
}
@@ -708,9 +708,9 @@ Projection Projection::operator*(const Projection &p_matrix) const {
for (int i = 0; i < 4; i++) {
real_t ab = 0;
for (int k = 0; k < 4; k++) {
- ab += matrix[k][i] * p_matrix.matrix[j][k];
+ ab += columns[k][i] * p_matrix.columns[j][k];
}
- new_matrix.matrix[j][i] = ab;
+ new_matrix.columns[j][i] = ab;
}
}
@@ -718,7 +718,7 @@ Projection Projection::operator*(const Projection &p_matrix) const {
}
void Projection::set_depth_correction(bool p_flip_y) {
- real_t *m = &matrix[0][0];
+ real_t *m = &columns[0][0];
m[0] = 1;
m[1] = 0.0;
@@ -739,7 +739,7 @@ void Projection::set_depth_correction(bool p_flip_y) {
}
void Projection::set_light_bias() {
- real_t *m = &matrix[0][0];
+ real_t *m = &columns[0][0];
m[0] = 0.5;
m[1] = 0.0;
@@ -760,7 +760,7 @@ void Projection::set_light_bias() {
}
void Projection::set_light_atlas_rect(const Rect2 &p_rect) {
- real_t *m = &matrix[0][0];
+ real_t *m = &columns[0][0];
m[0] = p_rect.size.width;
m[1] = 0.0;
@@ -784,7 +784,7 @@ Projection::operator String() const {
String str;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- str += String((j > 0) ? ", " : "\n") + rtos(matrix[i][j]);
+ str += String((j > 0) ? ", " : "\n") + rtos(columns[i][j]);
}
}
@@ -803,11 +803,11 @@ int Projection::get_pixels_per_meter(int p_for_pixel_width) const {
}
bool Projection::is_orthogonal() const {
- return matrix[3][3] == 1.0;
+ return columns[3][3] == 1.0;
}
real_t Projection::get_fov() const {
- const real_t *matrix = (const real_t *)this->matrix;
+ const real_t *matrix = (const real_t *)this->columns;
Plane right_plane = Plane(matrix[3] - matrix[0],
matrix[7] - matrix[4],
@@ -842,44 +842,44 @@ float Projection::get_lod_multiplier() const {
}
void Projection::make_scale(const Vector3 &p_scale) {
set_identity();
- matrix[0][0] = p_scale.x;
- matrix[1][1] = p_scale.y;
- matrix[2][2] = p_scale.z;
+ columns[0][0] = p_scale.x;
+ columns[1][1] = p_scale.y;
+ columns[2][2] = p_scale.z;
}
void Projection::scale_translate_to_fit(const AABB &p_aabb) {
Vector3 min = p_aabb.position;
Vector3 max = p_aabb.position + p_aabb.size;
- matrix[0][0] = 2 / (max.x - min.x);
- matrix[1][0] = 0;
- matrix[2][0] = 0;
- matrix[3][0] = -(max.x + min.x) / (max.x - min.x);
+ columns[0][0] = 2 / (max.x - min.x);
+ columns[1][0] = 0;
+ columns[2][0] = 0;
+ columns[3][0] = -(max.x + min.x) / (max.x - min.x);
- matrix[0][1] = 0;
- matrix[1][1] = 2 / (max.y - min.y);
- matrix[2][1] = 0;
- matrix[3][1] = -(max.y + min.y) / (max.y - min.y);
+ columns[0][1] = 0;
+ columns[1][1] = 2 / (max.y - min.y);
+ columns[2][1] = 0;
+ columns[3][1] = -(max.y + min.y) / (max.y - min.y);
- matrix[0][2] = 0;
- matrix[1][2] = 0;
- matrix[2][2] = 2 / (max.z - min.z);
- matrix[3][2] = -(max.z + min.z) / (max.z - min.z);
+ columns[0][2] = 0;
+ columns[1][2] = 0;
+ columns[2][2] = 2 / (max.z - min.z);
+ columns[3][2] = -(max.z + min.z) / (max.z - min.z);
- matrix[0][3] = 0;
- matrix[1][3] = 0;
- matrix[2][3] = 0;
- matrix[3][3] = 1;
+ columns[0][3] = 0;
+ columns[1][3] = 0;
+ columns[2][3] = 0;
+ columns[3][3] = 1;
}
void Projection::add_jitter_offset(const Vector2 &p_offset) {
- matrix[3][0] += p_offset.x;
- matrix[3][1] += p_offset.y;
+ columns[3][0] += p_offset.x;
+ columns[3][1] += p_offset.y;
}
Projection::operator Transform3D() const {
Transform3D tr;
- const real_t *m = &matrix[0][0];
+ const real_t *m = &columns[0][0];
tr.basis.rows[0][0] = m[0];
tr.basis.rows[1][0] = m[1];
@@ -899,15 +899,17 @@ Projection::operator Transform3D() const {
return tr;
}
+
Projection::Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w) {
- matrix[0] = p_x;
- matrix[1] = p_y;
- matrix[2] = p_z;
- matrix[3] = p_w;
+ columns[0] = p_x;
+ columns[1] = p_y;
+ columns[2] = p_z;
+ columns[3] = p_w;
}
+
Projection::Projection(const Transform3D &p_transform) {
const Transform3D &tr = p_transform;
- real_t *m = &matrix[0][0];
+ real_t *m = &columns[0][0];
m[0] = tr.basis.rows[0][0];
m[1] = tr.basis.rows[1][0];
diff --git a/core/math/projection.h b/core/math/projection.h
index f149d307b3..1bf5d8b2ed 100644
--- a/core/math/projection.h
+++ b/core/math/projection.h
@@ -52,16 +52,16 @@ struct Projection {
PLANE_BOTTOM
};
- Vector4 matrix[4];
+ Vector4 columns[4];
_FORCE_INLINE_ const Vector4 &operator[](const int p_axis) const {
DEV_ASSERT((unsigned int)p_axis < 4);
- return matrix[p_axis];
+ return columns[p_axis];
}
_FORCE_INLINE_ Vector4 &operator[](const int p_axis) {
DEV_ASSERT((unsigned int)p_axis < 4);
- return matrix[p_axis];
+ return columns[p_axis];
}
float determinant() const;
@@ -135,7 +135,7 @@ struct Projection {
bool operator==(const Projection &p_cam) const {
for (uint32_t i = 0; i < 4; i++) {
for (uint32_t j = 0; j < 4; j++) {
- if (matrix[i][j] != p_cam.matrix[i][j]) {
+ if (columns[i][j] != p_cam.columns[i][j]) {
return false;
}
}
@@ -157,10 +157,10 @@ struct Projection {
Vector3 Projection::xform(const Vector3 &p_vec3) const {
Vector3 ret;
- ret.x = matrix[0][0] * p_vec3.x + matrix[1][0] * p_vec3.y + matrix[2][0] * p_vec3.z + matrix[3][0];
- ret.y = matrix[0][1] * p_vec3.x + matrix[1][1] * p_vec3.y + matrix[2][1] * p_vec3.z + matrix[3][1];
- ret.z = matrix[0][2] * p_vec3.x + matrix[1][2] * p_vec3.y + matrix[2][2] * p_vec3.z + matrix[3][2];
- real_t w = matrix[0][3] * p_vec3.x + matrix[1][3] * p_vec3.y + matrix[2][3] * p_vec3.z + matrix[3][3];
+ ret.x = columns[0][0] * p_vec3.x + columns[1][0] * p_vec3.y + columns[2][0] * p_vec3.z + columns[3][0];
+ ret.y = columns[0][1] * p_vec3.x + columns[1][1] * p_vec3.y + columns[2][1] * p_vec3.z + columns[3][1];
+ ret.z = columns[0][2] * p_vec3.x + columns[1][2] * p_vec3.y + columns[2][2] * p_vec3.z + columns[3][2];
+ real_t w = columns[0][3] * p_vec3.x + columns[1][3] * p_vec3.y + columns[2][3] * p_vec3.z + columns[3][3];
return ret / w;
}
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index f24ffeb1a9..a6e91bf2ac 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -1835,11 +1835,13 @@ String Variant::stringify(int recursion_count) const {
case DICTIONARY: {
const Dictionary &d = *reinterpret_cast<const Dictionary *>(_data._mem);
if (recursion_count > MAX_RECURSION) {
- ERR_PRINT("Max recursion reached");
- return "{...}";
+ ERR_PRINT("Maximum dictionary recursion reached!");
+ return "{ ... }";
}
- String str("{");
+ // Add leading and trailing space to Dictionary printing. This distinguishes it
+ // from array printing on fonts that have similar-looking {} and [] characters.
+ String str("{ ");
List<Variant> keys;
d.get_key_list(&keys);
@@ -1858,9 +1860,9 @@ String Variant::stringify(int recursion_count) const {
if (i > 0) {
str += ", ";
}
- str += pairs[i].key + ":" + pairs[i].value;
+ str += pairs[i].key + ": " + pairs[i].value;
}
- str += "}";
+ str += " }";
return str;
} break;
@@ -1894,7 +1896,7 @@ String Variant::stringify(int recursion_count) const {
case ARRAY: {
Array arr = operator Array();
if (recursion_count > MAX_RECURSION) {
- ERR_PRINT("Max recursion reached");
+ ERR_PRINT("Maximum array recursion reached!");
return "[...]";
}
@@ -3121,22 +3123,22 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
case PROJECTION: {
uint32_t h = HASH_MURMUR3_SEED;
const Projection &t = *_data._projection;
- h = hash_murmur3_one_real(t.matrix[0].x, h);
- h = hash_murmur3_one_real(t.matrix[0].y, h);
- h = hash_murmur3_one_real(t.matrix[0].z, h);
- h = hash_murmur3_one_real(t.matrix[0].w, h);
- h = hash_murmur3_one_real(t.matrix[1].x, h);
- h = hash_murmur3_one_real(t.matrix[1].y, h);
- h = hash_murmur3_one_real(t.matrix[1].z, h);
- h = hash_murmur3_one_real(t.matrix[1].w, h);
- h = hash_murmur3_one_real(t.matrix[2].x, h);
- h = hash_murmur3_one_real(t.matrix[2].y, h);
- h = hash_murmur3_one_real(t.matrix[2].z, h);
- h = hash_murmur3_one_real(t.matrix[2].w, h);
- h = hash_murmur3_one_real(t.matrix[3].x, h);
- h = hash_murmur3_one_real(t.matrix[3].y, h);
- h = hash_murmur3_one_real(t.matrix[3].z, h);
- h = hash_murmur3_one_real(t.matrix[3].w, h);
+ h = hash_murmur3_one_real(t.columns[0].x, h);
+ h = hash_murmur3_one_real(t.columns[0].y, h);
+ h = hash_murmur3_one_real(t.columns[0].z, h);
+ h = hash_murmur3_one_real(t.columns[0].w, h);
+ h = hash_murmur3_one_real(t.columns[1].x, h);
+ h = hash_murmur3_one_real(t.columns[1].y, h);
+ h = hash_murmur3_one_real(t.columns[1].z, h);
+ h = hash_murmur3_one_real(t.columns[1].w, h);
+ h = hash_murmur3_one_real(t.columns[2].x, h);
+ h = hash_murmur3_one_real(t.columns[2].y, h);
+ h = hash_murmur3_one_real(t.columns[2].z, h);
+ h = hash_murmur3_one_real(t.columns[2].w, h);
+ h = hash_murmur3_one_real(t.columns[3].x, h);
+ h = hash_murmur3_one_real(t.columns[3].y, h);
+ h = hash_murmur3_one_real(t.columns[3].z, h);
+ h = hash_murmur3_one_real(t.columns[3].w, h);
return hash_fmix32(h);
} break;
// misc types
@@ -3507,7 +3509,7 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const
const Projection *r = p_variant._data._projection;
for (int i = 0; i < 4; i++) {
- if (!(hash_compare_vector4(l->matrix[i], r->matrix[i]))) {
+ if (!(hash_compare_vector4(l->columns[i], r->columns[i]))) {
return false;
}
}
diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp
index 8151ff2102..d2e4d752a4 100644
--- a/core/variant/variant_parser.cpp
+++ b/core/variant/variant_parser.cpp
@@ -1651,7 +1651,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
if (i != 0 || j != 0) {
s += ", ";
}
- s += rtos_fix(t.matrix[i][j]);
+ s += rtos_fix(t.columns[i][j]);
}
}
diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp
index ff67b187ef..188103ee5e 100644
--- a/core/variant/variant_setget.cpp
+++ b/core/variant/variant_setget.cpp
@@ -826,7 +826,7 @@ INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Color, double, float, 4)
INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Transform2D, Vector2, .columns, 3)
INDEXED_SETGET_STRUCT_BULTIN_FUNC(Basis, Vector3, set_column, get_column, 3)
-INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Projection, Vector4, .matrix, 4)
+INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Projection, Vector4, .columns, 4)
INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedByteArray, int64_t, uint8_t)
INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedInt32Array, int64_t, int32_t)
diff --git a/core/variant/variant_setget.h b/core/variant/variant_setget.h
index 570277dc7a..d151a85a6e 100644
--- a/core/variant/variant_setget.h
+++ b/core/variant/variant_setget.h
@@ -325,10 +325,10 @@ SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, z, set_column, get_column, 2)
SETGET_STRUCT(Transform3D, Basis, basis)
SETGET_STRUCT(Transform3D, Vector3, origin)
-SETGET_STRUCT_CUSTOM(Projection, Vector4, x, matrix[0])
-SETGET_STRUCT_CUSTOM(Projection, Vector4, y, matrix[1])
-SETGET_STRUCT_CUSTOM(Projection, Vector4, z, matrix[2])
-SETGET_STRUCT_CUSTOM(Projection, Vector4, w, matrix[3])
+SETGET_STRUCT_CUSTOM(Projection, Vector4, x, columns[0])
+SETGET_STRUCT_CUSTOM(Projection, Vector4, y, columns[1])
+SETGET_STRUCT_CUSTOM(Projection, Vector4, z, columns[2])
+SETGET_STRUCT_CUSTOM(Projection, Vector4, w, columns[3])
SETGET_NUMBER_STRUCT(Color, double, r)
SETGET_NUMBER_STRUCT(Color, double, g)
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 5bb10d162f..6f455f35c1 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -2260,10 +2260,10 @@
Enum value which doesn't correspond to any mouse button. This is used to initialize [enum MouseButton] properties with a generic state.
</constant>
<constant name="MOUSE_BUTTON_LEFT" value="1" enum="MouseButton">
- Left mouse button.
+ Primary mouse button, usually the left button.
</constant>
<constant name="MOUSE_BUTTON_RIGHT" value="2" enum="MouseButton">
- Right mouse button.
+ Secondary mouse button, usually the right button.
</constant>
<constant name="MOUSE_BUTTON_MIDDLE" value="3" enum="MouseButton">
Middle mouse button.
@@ -2287,10 +2287,10 @@
Extra mouse button 2 (only present on some mice).
</constant>
<constant name="MOUSE_BUTTON_MASK_LEFT" value="1" enum="MouseButton">
- Left mouse button mask.
+ Primary mouse button mask, usually for the left button.
</constant>
<constant name="MOUSE_BUTTON_MASK_RIGHT" value="2" enum="MouseButton">
- Right mouse button mask.
+ Secondary mouse button mask, usually for the right button.
</constant>
<constant name="MOUSE_BUTTON_MASK_MIDDLE" value="4" enum="MouseButton">
Middle mouse button mask.
diff --git a/doc/classes/AtlasTexture.xml b/doc/classes/AtlasTexture.xml
index 4794c8ef14..809d983a9d 100644
--- a/doc/classes/AtlasTexture.xml
+++ b/doc/classes/AtlasTexture.xml
@@ -6,13 +6,13 @@
<description>
[Texture2D] resource that draws only part of its [member atlas] texture, as defined by the [member region]. An additional [member margin] can also be set, which is useful for small adjustments.
Multiple [AtlasTexture] resources can be cropped from the same [member atlas]. Packing many smaller textures into a singular large texture helps to optimize video memory costs and render calls.
- [b]Note:[/b] [AtlasTexture] cannot be used in an [AnimatedTexture], and does not work properly if used inside of other [AtlasTexture] resources.
+ [b]Note:[/b] [AtlasTexture] cannot be used in an [AnimatedTexture], and may not tile properly in nodes such as [TextureRect], when inside other [AtlasTexture] resources.
</description>
<tutorials>
</tutorials>
<members>
<member name="atlas" type="Texture2D" setter="set_atlas" getter="get_atlas">
- The texture that contains the atlas. Can be any type inheriting from [Texture2D]. Nesting [AtlasTexture] resources is not supported.
+ The texture that contains the atlas. Can be any type inheriting from [Texture2D], including another [AtlasTexture].
</member>
<member name="filter_clip" type="bool" setter="set_filter_clip" getter="has_filter_clip" default="false">
If [code]true[/code], the area outside of the [member region] is clipped to avoid bleeding of the surrounding texture pixels.
diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml
index a1d24f778d..671ecb6af1 100644
--- a/doc/classes/Camera2D.xml
+++ b/doc/classes/Camera2D.xml
@@ -150,6 +150,13 @@
<member name="process_callback" type="int" setter="set_process_callback" getter="get_process_callback" enum="Camera2D.Camera2DProcessCallback" default="1">
The camera's process callback. See [enum Camera2DProcessCallback].
</member>
+ <member name="rotation_smoothing_enabled" type="bool" setter="set_rotation_smoothing_enabled" getter="is_rotation_smoothing_enabled" default="false">
+ If [code]true[/code], the camera's view smoothly rotates, via asymptotic smoothing, to align with its target rotation at [member rotation_smoothing_speed].
+ [b]Note:[/b] This property has no effect if [member ignore_rotation] is [code]true[/code].
+ </member>
+ <member name="rotation_smoothing_speed" type="float" setter="set_rotation_smoothing_speed" getter="get_rotation_smoothing_speed" default="5.0">
+ The angular, asymptotic speed of the camera's rotation smoothing effect when [member rotation_smoothing_enabled] is [code]true[/code].
+ </member>
<member name="smoothing_enabled" type="bool" setter="set_enable_follow_smoothing" getter="is_follow_smoothing_enabled" default="false">
If [code]true[/code], the camera smoothly moves towards the target at [member smoothing_speed].
</member>
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index bf449ade77..c66a93ce37 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -7,10 +7,10 @@
Base class for all UI-related nodes. [Control] features a bounding rectangle that defines its extents, an anchor position relative to its parent control or the current viewport, and offsets relative to the anchor. The offsets update automatically when the node, any of its parents, or the screen size change.
For more information on Godot's UI system, anchors, offsets, and containers, see the related tutorials in the manual. To build flexible UIs, you'll need a mix of UI elements that inherit from [Control] and [Container] nodes.
[b]User Interface nodes and input[/b]
- Godot sends input events to the scene's root node first, by calling [method Node._input]. [method Node._input] forwards the event down the node tree to the nodes under the mouse cursor, or on keyboard focus. To do so, it calls [code]MainLoop._input_event[/code].
+ Godot sends input events to the scene's root node first, by calling [method Node._input]. [method Node._input] forwards the event down the node tree to the nodes under the mouse cursor, or in focus. To do so, it calls [code]MainLoop._input_event[/code].
[b]FIXME:[/b] No longer valid after DisplayServer split and Input refactoring.
Call [method accept_event] so no other node receives the event. Once you accept an input, it becomes handled so [method Node._unhandled_input] will not process it.
- Only one [Control] node can be in keyboard focus. Only the node in focus will receive keyboard events. To get the focus, call [method grab_focus]. [Control] nodes lose focus when another node grabs it, or if you hide the node in focus.
+ Only one [Control] node can be in focus. Only the node in focus will receive events. To get the focus, call [method grab_focus]. [Control] nodes lose focus when another node grabs it, or if you hide the node in focus.
Sets [member mouse_filter] to [constant MOUSE_FILTER_IGNORE] to tell a [Control] node to ignore mouse or touch events. You'll need it if you place an icon on top of a button.
[Theme] resources change the Control's appearance. If you change the [Theme] on a [Control] node, it affects all of its children. To override some of the theme's parameters, call one of the [code]add_theme_*_override[/code] methods, like [method add_theme_font_override]. You can override the theme with the inspector.
[b]Note:[/b] Theme items are [i]not[/i] [Object] properties. This means you can't access their values using [method Object.get] and [method Object.set]. Instead, use the [code]get_theme_*[/code] and [code]add_theme_*_override[/code] methods provided by this class.
@@ -680,7 +680,7 @@
<method name="release_focus">
<return type="void" />
<description>
- Give up the focus. No other control will be able to receive keyboard input.
+ Give up the focus. No other control will be able to receive input.
</description>
</method>
<method name="remove_theme_color_override">
@@ -976,26 +976,26 @@
The minimum size of the node's bounding rectangle. If you set it to a value greater than (0, 0), the node's bounding rectangle will always have at least this size, even if its content is smaller. If it's set to (0, 0), the node sizes automatically to fit its content, be it a texture or child nodes.
</member>
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" enum="Control.FocusMode" default="0">
- The focus access mode for the control (None, Click or All). Only one Control can be focused at the same time, and it will receive keyboard signals.
+ The focus access mode for the control (None, Click or All). Only one Control can be focused at the same time, and it will receive keyboard, gamepad, and mouse signals.
</member>
<member name="focus_neighbor_bottom" type="NodePath" setter="set_focus_neighbor" getter="get_focus_neighbor" default="NodePath(&quot;&quot;)">
- Tells Godot which node it should give keyboard focus to if the user presses the down arrow on the keyboard or down on a gamepad by default. You can change the key by editing the [code]ui_down[/code] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the bottom of this one.
+ Tells Godot which node it should give focus to if the user presses the down arrow on the keyboard or down on a gamepad by default. You can change the key by editing the [code]ui_down[/code] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the bottom of this one.
</member>
<member name="focus_neighbor_left" type="NodePath" setter="set_focus_neighbor" getter="get_focus_neighbor" default="NodePath(&quot;&quot;)">
- Tells Godot which node it should give keyboard focus to if the user presses the left arrow on the keyboard or left on a gamepad by default. You can change the key by editing the [code]ui_left[/code] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the left of this one.
+ Tells Godot which node it should give focus to if the user presses the left arrow on the keyboard or left on a gamepad by default. You can change the key by editing the [code]ui_left[/code] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the left of this one.
</member>
<member name="focus_neighbor_right" type="NodePath" setter="set_focus_neighbor" getter="get_focus_neighbor" default="NodePath(&quot;&quot;)">
- Tells Godot which node it should give keyboard focus to if the user presses the right arrow on the keyboard or right on a gamepad by default. You can change the key by editing the [code]ui_right[/code] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the bottom of this one.
+ Tells Godot which node it should give focus to if the user presses the right arrow on the keyboard or right on a gamepad by default. You can change the key by editing the [code]ui_right[/code] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the bottom of this one.
</member>
<member name="focus_neighbor_top" type="NodePath" setter="set_focus_neighbor" getter="get_focus_neighbor" default="NodePath(&quot;&quot;)">
- Tells Godot which node it should give keyboard focus to if the user presses the top arrow on the keyboard or top on a gamepad by default. You can change the key by editing the [code]ui_top[/code] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the bottom of this one.
+ Tells Godot which node it should give focus to if the user presses the top arrow on the keyboard or top on a gamepad by default. You can change the key by editing the [code]ui_top[/code] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the bottom of this one.
</member>
<member name="focus_next" type="NodePath" setter="set_focus_next" getter="get_focus_next" default="NodePath(&quot;&quot;)">
- Tells Godot which node it should give keyboard focus to if the user presses [kbd]Tab[/kbd] on a keyboard by default. You can change the key by editing the [code]ui_focus_next[/code] input action.
+ Tells Godot which node it should give focus to if the user presses [kbd]Tab[/kbd] on a keyboard by default. You can change the key by editing the [code]ui_focus_next[/code] input action.
If this property is not set, Godot will select a "best guess" based on surrounding nodes in the scene tree.
</member>
<member name="focus_previous" type="NodePath" setter="set_focus_previous" getter="get_focus_previous" default="NodePath(&quot;&quot;)">
- Tells Godot which node it should give keyboard focus to if the user presses [kbd]Shift + Tab[/kbd] on a keyboard by default. You can change the key by editing the [code]ui_focus_prev[/code] input action.
+ Tells Godot which node it should give focus to if the user presses [kbd]Shift + Tab[/kbd] on a keyboard by default. You can change the key by editing the [code]ui_focus_prev[/code] input action.
If this property is not set, Godot will select a "best guess" based on surrounding nodes in the scene tree.
</member>
<member name="global_position" type="Vector2" setter="_set_global_position" getter="get_global_position">
@@ -1098,12 +1098,12 @@
<signals>
<signal name="focus_entered">
<description>
- Emitted when the node gains keyboard focus.
+ Emitted when the node gains focus.
</description>
</signal>
<signal name="focus_exited">
<description>
- Emitted when the node loses keyboard focus.
+ Emitted when the node loses focus.
</description>
</signal>
<signal name="gui_input">
@@ -1159,7 +1159,7 @@
The node can only grab focus on mouse clicks. Use with [member focus_mode].
</constant>
<constant name="FOCUS_ALL" value="2" enum="FocusMode">
- The node can grab focus on mouse click or using the arrows and the Tab keys on the keyboard. Use with [member focus_mode].
+ The node can grab focus on mouse click, using the arrows and the Tab keys on the keyboard, or using the D-pad buttons on a gamepad. Use with [member focus_mode].
</constant>
<constant name="NOTIFICATION_RESIZED" value="40">
Sent when the node changes size. Use [member size] to get the new size.
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index 6d3f3a7362..0dbaa9c86f 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -1244,7 +1244,7 @@
<param index="1" name="window_id" type="int" default="0" />
<description>
Sets window mode for the given window to [param mode]. See [enum WindowMode] for possible values and how each mode behaves.
- [b]Note:[/b] Setting the window to fullscreen forcibly sets the borderless flag to [code]true[/code], so make sure to set it back to [code]false[/code] when not wanted.
+ [b]Note:[/b] Setting the window to full screen forcibly sets the borderless flag to [code]true[/code], so make sure to set it back to [code]false[/code] when not wanted.
</description>
</method>
<method name="window_set_mouse_passthrough">
@@ -1324,7 +1324,8 @@
<param index="0" name="window_id" type="int" />
<param index="1" name="parent_window_id" type="int" />
<description>
- Sets window transient parent. Transient window is will be destroyed with its transient parent and displayed on top of non-exclusive full-screen parent window. Transient windows can't enter full-screen mode.
+ Sets window transient parent. Transient window is will be destroyed with its transient parent and will return focus to their parent when closed. The transient window is displayed on top of a non-exclusive full-screen parent window. Transient windows can't enter full-screen mode.
+ Note that behavior might be different depending on the platform.
</description>
</method>
<method name="window_set_vsync_mode">
@@ -1495,60 +1496,78 @@
<constant name="CURSOR_MAX" value="17" enum="CursorShape">
</constant>
<constant name="WINDOW_MODE_WINDOWED" value="0" enum="WindowMode">
+ Windowed mode, i.e. [Window] doesn't occupy the whole screen (unless set to the size of the screen).
</constant>
<constant name="WINDOW_MODE_MINIMIZED" value="1" enum="WindowMode">
+ Minimized window mode, i.e. [Window] is not visible and available on window manager's window list. Normally happens when the minimize button is pressed.
</constant>
<constant name="WINDOW_MODE_MAXIMIZED" value="2" enum="WindowMode">
+ Maximized window mode, i.e. [Window] will occupy whole screen area except task bar and still display its borders. Normally happens when the minimize button is pressed.
</constant>
<constant name="WINDOW_MODE_FULLSCREEN" value="3" enum="WindowMode">
- Fullscreen window mode. Note that this is not [i]exclusive[/i] fullscreen. On Windows and Linux, a borderless window is used to emulate fullscreen. On macOS, a new desktop is used to display the running project.
- Regardless of the platform, enabling fullscreen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling fullscreen mode.
+ Full screen window mode. Note that this is not [i]exclusive[/i] full screen. On Windows and Linux, a borderless window is used to emulate full screen. On macOS, a new desktop is used to display the running project.
+ Regardless of the platform, enabling full screen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling full screen mode.
</constant>
<constant name="WINDOW_MODE_EXCLUSIVE_FULLSCREEN" value="4" enum="WindowMode">
- Exclusive fullscreen window mode. This mode is implemented on Windows only. On other platforms, it is equivalent to [constant WINDOW_MODE_FULLSCREEN].
- Only one window in exclusive fullscreen mode can be visible on a given screen at a time. If multiple windows are in exclusive fullscreen mode for the same screen, the last one being set to this mode takes precedence.
- Regardless of the platform, enabling fullscreen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling fullscreen mode.
+ Exclusive full screen window mode. This mode is implemented on Windows only. On other platforms, it is equivalent to [constant WINDOW_MODE_FULLSCREEN].
+ Only one window in exclusive full screen mode can be visible on a given screen at a time. If multiple windows are in exclusive full screen mode for the same screen, the last one being set to this mode takes precedence.
+ Regardless of the platform, enabling full screen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling full screen mode.
</constant>
<constant name="WINDOW_FLAG_RESIZE_DISABLED" value="0" enum="WindowFlags">
- Window can't be resizing by dragging its resize grip. It's still possible to resize the window using [method window_set_size]. This flag is ignored for full screen windows.
+ The window can't be resizing by dragging its resize grip. It's still possible to resize the window using [method window_set_size]. This flag is ignored for full screen windows.
</constant>
<constant name="WINDOW_FLAG_BORDERLESS" value="1" enum="WindowFlags">
- Window do not have native title bar and other decorations. This flag is ignored for full-screen windows.
+ The window do not have native title bar and other decorations. This flag is ignored for full-screen windows.
</constant>
<constant name="WINDOW_FLAG_ALWAYS_ON_TOP" value="2" enum="WindowFlags">
- Window is floating above other regular windows. This flag is ignored for full-screen windows.
+ The window is floating on top of all other windows. This flag is ignored for full-screen windows.
</constant>
<constant name="WINDOW_FLAG_TRANSPARENT" value="3" enum="WindowFlags">
- Window background can be transparent.
+ The window background can be transparent.
[b]Note:[/b] This flag has no effect if [member ProjectSettings.display/window/per_pixel_transparency/allowed] is set to [code]false[/code].
+ [b]Note:[/b] Transparency support is implemented on Linux, macOS and Windows, but availability might vary depending on GPU driver, display manager, and compositor capabilities.
</constant>
<constant name="WINDOW_FLAG_NO_FOCUS" value="4" enum="WindowFlags">
- Window can't be focused. No-focus window will ignore all input, except mouse clicks.
+ The window can't be focused. No-focus window will ignore all input, except mouse clicks.
</constant>
<constant name="WINDOW_FLAG_POPUP" value="5" enum="WindowFlags">
- Window is part of menu or [OptionButton] dropdown. This flag can't be changed when window is visible. An active popup window will exclusively receive all input, without stealing focus from its parent. Popup windows are automatically closed when uses click outside it, or when an application is switched. Popup window must have [constant WINDOW_FLAG_TRANSPARENT] set.
+ Window is part of menu or [OptionButton] dropdown. This flag can't be changed when the window is visible. An active popup window will exclusively receive all input, without stealing focus from its parent. Popup windows are automatically closed when uses click outside it, or when an application is switched. Popup window must have [code]transient parent[/code] set (see [method window_set_transient]).
</constant>
<constant name="WINDOW_FLAG_EXTEND_TO_TITLE" value="6" enum="WindowFlags">
Window content is expanded to the full size of the window. Unlike borderless window, the frame is left intact and can be used to resize the window, title bar is transparent, but have minimize/maximize/close buttons.
+ Use [method window_set_window_buttons_offset] to adjust minimize/maximize/close buttons offset.
+ Use [method window_get_safe_title_margins] to determine area under the title bar that is not covered by decorations.
[b]Note:[/b] This flag is implemented on macOS.
</constant>
<constant name="WINDOW_FLAG_MAX" value="7" enum="WindowFlags">
+ Max value of the [enum WindowFlags].
</constant>
<constant name="WINDOW_EVENT_MOUSE_ENTER" value="0" enum="WindowEvent">
+ Sent when the mouse pointer enters the window, see [method window_set_window_event_callback].
</constant>
<constant name="WINDOW_EVENT_MOUSE_EXIT" value="1" enum="WindowEvent">
+ Sent when the mouse pointer exits the window, see [method window_set_window_event_callback].
</constant>
<constant name="WINDOW_EVENT_FOCUS_IN" value="2" enum="WindowEvent">
+ Sent when the window grabs focus, see [method window_set_window_event_callback].
</constant>
<constant name="WINDOW_EVENT_FOCUS_OUT" value="3" enum="WindowEvent">
+ Sent when the window loses focus, see [method window_set_window_event_callback].
</constant>
<constant name="WINDOW_EVENT_CLOSE_REQUEST" value="4" enum="WindowEvent">
+ Sent when the user has attempted to close the window (e.g. close button is pressed), see [method window_set_window_event_callback].
</constant>
<constant name="WINDOW_EVENT_GO_BACK_REQUEST" value="5" enum="WindowEvent">
+ Sent when the device "Back" button is pressed, see [method window_set_window_event_callback].
+ [b]Note:[/b] This event is implemented on Android.
</constant>
<constant name="WINDOW_EVENT_DPI_CHANGE" value="6" enum="WindowEvent">
+ Sent when the window is moved to the display with different DPI, or display DPI is changed, see [method window_set_window_event_callback].
+ [b]Note:[/b] This flag is implemented on macOS.
</constant>
<constant name="WINDOW_EVENT_TITLEBAR_CHANGE" value="7" enum="WindowEvent">
+ Sent when the window title bar decoration is changed (e.g. [constant WINDOW_FLAG_EXTEND_TO_TITLE] is set or window entered/exited full screen mode), see [method window_set_window_event_callback].
+ [b]Note:[/b] This flag is implemented on macOS.
</constant>
<constant name="VSYNC_DISABLED" value="0" enum="VSyncMode">
No vertical synchronization, which means the engine will display frames as fast as possible (tearing may be visible).
diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml
index b138a55ea3..510f14ec54 100644
--- a/doc/classes/Image.xml
+++ b/doc/classes/Image.xml
@@ -197,7 +197,6 @@
<param index="0" name="renormalize" type="bool" default="false" />
<description>
Generates mipmaps for the image. Mipmaps are precalculated lower-resolution copies of the image that are automatically used if the image needs to be scaled down when rendered. They help improve image quality and performance when rendering. This method returns an error if the image is compressed, in a custom format, or if the image's width/height is [code]0[/code].
- [b]Note:[/b] Mipmap generation is done on the CPU, is single-threaded and is [i]always[/i] done on the main thread. This means generating mipmaps will result in noticeable stuttering during gameplay, even if [method generate_mipmaps] is called from a [Thread].
</description>
</method>
<method name="get_data" qualifiers="const">
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index bc6ac8012f..15b3d4958c 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -4,7 +4,7 @@
Operating System functions.
</brief_description>
<description>
- Operating System functions. OS wraps the most common functionality to communicate with the host operating system, such as the clipboard, video driver, date and time, timers, environment variables, execution of binaries, command line, etc.
+ Operating System functions. OS wraps the most common functionality to communicate with the host operating system, such as the clipboard, video driver, delays, environment variables, execution of binaries, command line, etc.
</description>
<tutorials>
<link title="OS Test Demo">https://godotengine.org/asset-library/asset/677</link>
diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml
index c585b54ee1..a688fb36b3 100644
--- a/doc/classes/Window.xml
+++ b/doc/classes/Window.xml
@@ -355,7 +355,7 @@
</member>
<member name="mode" type="int" setter="set_mode" getter="get_mode" enum="Window.Mode" default="0">
Set's the window's current mode.
- [b]Note:[/b] Fullscreen mode is not exclusive fullscreen on Windows and Linux.
+ [b]Note:[/b] Fullscreen mode is not exclusive full screen on Windows and Linux.
</member>
<member name="popup_window" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the [Window] will be considered a popup. Popups are sub-windows that don't show as separate windows in system's window manager's window list and will send close request when anything is clicked outside of them (unless [member exclusive] is enabled).
@@ -377,12 +377,13 @@
The window's title. If the [Window] is non-embedded, title styles set in [Theme] will have no effect.
</member>
<member name="transient" type="bool" setter="set_transient" getter="is_transient" default="false">
- If [code]true[/code], the [Window] is transient, i.e. it's considered a child of another [Window]. Transient windows can't be in fullscreen mode and will return focus to their parent when closed.
+ If [code]true[/code], the [Window] is transient, i.e. it's considered a child of another [Window]. Transient window is will be destroyed with its transient parent and will return focus to their parent when closed. The transient window is displayed on top of a non-exclusive full-screen parent window. Transient windows can't enter full-screen mode.
Note that behavior might be different depending on the platform.
</member>
<member name="transparent" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the [Window]'s background can be transparent. This is best used with embedded windows.
- [b]Note:[/b] This flag has no effect if [member ProjectSettings.display/window/per_pixel_transparency/allowed] is set to [code]false[/code].
+ [b]Note:[/b] For native windows, this flag has no effect if [member ProjectSettings.display/window/per_pixel_transparency/allowed] is set to [code]false[/code].
+ [b]Note:[/b] Transparency support is implemented on Linux, macOS and Windows, but availability might vary depending on GPU driver, display manager, and compositor capabilities.
</member>
<member name="unfocusable" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the [Window] can't be focused nor interacted with. It can still be visible.
@@ -457,7 +458,7 @@
</signal>
<signal name="titlebar_changed">
<description>
- Emitted when window title bar decorations are changed, e.g., macOS window enter/exit full screen mode, or extend-to-title flag is changed.
+ Emitted when window title bar decorations are changed, e.g. macOS window enter/exit full screen mode, or extend-to-title flag is changed.
</description>
</signal>
<signal name="visibility_changed">
@@ -484,43 +485,45 @@
[b]Note:[/b] As an optimization, this notification won't be sent from changes that occur while this node is outside of the scene tree. Instead, all of the theme item updates can be applied at once when the node enters the scene tree.
</constant>
<constant name="MODE_WINDOWED" value="0" enum="Mode">
- Windowed mode, i.e. [Window] doesn't occupy whole screen (unless set to the size of the screen).
+ Windowed mode, i.e. [Window] doesn't occupy the whole screen (unless set to the size of the screen).
</constant>
<constant name="MODE_MINIMIZED" value="1" enum="Mode">
- Minimized window mode, i.e. [Window] is not visible and available on window manager's window list. Normally happens when the minimize button is presesd.
+ Minimized window mode, i.e. [Window] is not visible and available on window manager's window list. Normally happens when the minimize button is pressed.
</constant>
<constant name="MODE_MAXIMIZED" value="2" enum="Mode">
- Maximized window mode, i.e. [Window] will occupy whole screen area except task bar and still display its borders. Normally happens when the minimize button is presesd.
+ Maximized window mode, i.e. [Window] will occupy whole screen area except task bar and still display its borders. Normally happens when the minimize button is pressed.
</constant>
<constant name="MODE_FULLSCREEN" value="3" enum="Mode">
- Fullscreen window mode. Note that this is not [i]exclusive[/i] fullscreen. On Windows and Linux, a borderless window is used to emulate fullscreen. On macOS, a new desktop is used to display the running project.
- Regardless of the platform, enabling fullscreen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling fullscreen mode.
+ Full screen window mode. Note that this is not [i]exclusive[/i] full screen. On Windows and Linux, a borderless window is used to emulate full screen. On macOS, a new desktop is used to display the running project.
+ Regardless of the platform, enabling full screen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling full screen mode.
</constant>
<constant name="MODE_EXCLUSIVE_FULLSCREEN" value="4" enum="Mode">
- Exclusive fullscreen window mode. This mode is implemented on Windows only. On other platforms, it is equivalent to [constant MODE_FULLSCREEN].
- Only one window in exclusive fullscreen mode can be visible on a given screen at a time. If multiple windows are in exclusive fullscreen mode for the same screen, the last one being set to this mode takes precedence.
- Regardless of the platform, enabling fullscreen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling fullscreen mode.
+ Exclusive full screen window mode. This mode is implemented on Windows only. On other platforms, it is equivalent to [constant MODE_FULLSCREEN].
+ Only one window in exclusive full screen mode can be visible on a given screen at a time. If multiple windows are in exclusive full screen mode for the same screen, the last one being set to this mode takes precedence.
+ Regardless of the platform, enabling full screen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling full screen mode.
</constant>
<constant name="FLAG_RESIZE_DISABLED" value="0" enum="Flags">
- The window's ability to be resized. Set with [member unresizable].
+ The window can't be resizing by dragging its resize grip. It's still possible to resize the window using [member size]. This flag is ignored for full screen windows. Set with [member unresizable].
</constant>
<constant name="FLAG_BORDERLESS" value="1" enum="Flags">
- Borderless window. Set with [member borderless].
+ The window do not have native title bar and other decorations. This flag is ignored for full-screen windows. Set with [member borderless].
</constant>
<constant name="FLAG_ALWAYS_ON_TOP" value="2" enum="Flags">
- Flag for making the window always on top of all other windows. Set with [member always_on_top].
+ The window is floating on top of all other windows. This flag is ignored for full-screen windows. Set with [member always_on_top].
</constant>
<constant name="FLAG_TRANSPARENT" value="3" enum="Flags">
- Flag for per-pixel transparency. Set with [member transparent].
+ The window background can be transparent.
+ [b]Note:[/b] This flag has no effect if [member ProjectSettings.display/window/per_pixel_transparency/allowed] is set to [code]false[/code]. Set with [member transparent].
</constant>
<constant name="FLAG_NO_FOCUS" value="4" enum="Flags">
- The window's ability to gain focus. Set with [member unfocusable].
+ The window can't be focused. No-focus window will ignore all input, except mouse clicks. Set with [member unfocusable].
</constant>
<constant name="FLAG_POPUP" value="5" enum="Flags">
- Whether the window is popup or a regular window. Set with [member popup_window].
+ Window is part of menu or [OptionButton] dropdown. This flag can't be changed when the window is visible. An active popup window will exclusively receive all input, without stealing focus from its parent. Popup windows are automatically closed when uses click outside it, or when an application is switched. Popup window must have [code]transient parent[/code] set (see [member transient]).
</constant>
<constant name="FLAG_EXTEND_TO_TITLE" value="6" enum="Flags">
- Window contents is expanded to the full size of the window, window title bar is transparent.
+ Window content is expanded to the full size of the window. Unlike borderless window, the frame is left intact and can be used to resize the window, title bar is transparent, but have minimize/maximize/close buttons. Set with [member extend_to_title].
+ [b]Note:[/b] This flag is implemented on macOS.
</constant>
<constant name="FLAG_MAX" value="7" enum="Flags">
Max value of the [enum Flags].
diff --git a/doc/classes/World2D.xml b/doc/classes/World2D.xml
index b0cf126d7b..4a13389708 100644
--- a/doc/classes/World2D.xml
+++ b/doc/classes/World2D.xml
@@ -14,7 +14,7 @@
The [RID] of this world's canvas resource. Used by the [RenderingServer] for 2D drawing.
</member>
<member name="direct_space_state" type="PhysicsDirectSpaceState2D" setter="" getter="get_direct_space_state">
- Direct access to the world's physics 2D space state. Used for querying current and potential collisions. When using multi-threaded physics, access is limited to [code]_physics_process(delta)[/code] in the main thread.
+ Direct access to the world's physics 2D space state. Used for querying current and potential collisions. When using multi-threaded physics, access is limited to [method Node._physics_process] in the main thread.
</member>
<member name="navigation_map" type="RID" setter="" getter="get_navigation_map">
The [RID] of this world's navigation map. Used by the [NavigationServer2D].
diff --git a/doc/classes/World3D.xml b/doc/classes/World3D.xml
index f3c7136075..5e58bb0360 100644
--- a/doc/classes/World3D.xml
+++ b/doc/classes/World3D.xml
@@ -14,7 +14,7 @@
The default [CameraAttributes] resource to use if none set on the [Camera3D].
</member>
<member name="direct_space_state" type="PhysicsDirectSpaceState3D" setter="" getter="get_direct_space_state">
- Direct access to the world's physics 3D space state. Used for querying current and potential collisions.
+ Direct access to the world's physics 3D space state. Used for querying current and potential collisions. When using multi-threaded physics, access is limited to [method Node._physics_process] in the main thread.
</member>
<member name="environment" type="Environment" setter="set_environment" getter="get_environment">
The World3D's [Environment].
diff --git a/doc/classes/XRInterfaceExtension.xml b/doc/classes/XRInterfaceExtension.xml
index 06ef18b534..5958999037 100644
--- a/doc/classes/XRInterfaceExtension.xml
+++ b/doc/classes/XRInterfaceExtension.xml
@@ -39,6 +39,18 @@
Returns the capabilities of this interface.
</description>
</method>
+ <method name="_get_color_texture" qualifiers="virtual">
+ <return type="RID" />
+ <description>
+ Return color texture into which to render (if applicable).
+ </description>
+ </method>
+ <method name="_get_depth_texture" qualifiers="virtual">
+ <return type="RID" />
+ <description>
+ Return depth texture into which to render (if applicable).
+ </description>
+ </method>
<method name="_get_name" qualifiers="virtual const">
<return type="StringName" />
<description>
@@ -100,6 +112,12 @@
Returns a [Transform3D] for a given view.
</description>
</method>
+ <method name="_get_velocity_texture" qualifiers="virtual">
+ <return type="RID" />
+ <description>
+ Return velocity texture into which to render (if applicable).
+ </description>
+ </method>
<method name="_get_view_count" qualifiers="virtual">
<return type="int" />
<description>
@@ -213,6 +231,16 @@
Blits our render results to screen optionally applying lens distortion. This can only be called while processing [code]_commit_views[/code].
</description>
</method>
+ <method name="get_color_texture">
+ <return type="RID" />
+ <description>
+ </description>
+ </method>
+ <method name="get_depth_texture">
+ <return type="RID" />
+ <description>
+ </description>
+ </method>
<method name="get_render_target_texture">
<return type="RID" />
<param index="0" name="render_target" type="RID" />
@@ -220,5 +248,10 @@
Returns a valid [RID] for a texture to which we should render the current frame if supported by the interface.
</description>
</method>
+ <method name="get_velocity_texture">
+ <return type="RID" />
+ <description>
+ </description>
+ </method>
</methods>
</class>
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 3575837794..3ac923d33c 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -280,11 +280,7 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display
GLES3::RenderTarget *rt = texture_storage->get_render_target(p_render_target);
ERR_FAIL_COND(!rt);
- if (rt->external.fbo != 0) {
- glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->external.fbo);
- } else {
- glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->fbo);
- }
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
// Flip content upside down to correct for coordinates.
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 82d054ac59..4c71edc24c 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -753,7 +753,7 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection,
GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_bind_shader(shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::ORIENTATION, sky_transform, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
- GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, camera.matrix[2][0], camera.matrix[0][0], camera.matrix[2][1], camera.matrix[1][1], shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
+ GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, camera.columns[2][0], camera.columns[0][0], camera.columns[2][1], camera.columns[1][1], shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
@@ -854,7 +854,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p
GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);
GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);
- GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, cm.matrix[2][0], cm.matrix[0][0], cm.matrix[2][1], cm.matrix[1][1], shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);
+ GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, cm.columns[2][0], cm.columns[0][0], cm.columns[2][1], cm.columns[1][1], shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);
GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);
glBindVertexArray(sky_globals.screen_triangle_array);
diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp
index bbbad50b14..8e6009c943 100644
--- a/drivers/gles3/storage/material_storage.cpp
+++ b/drivers/gles3/storage/material_storage.cpp
@@ -714,7 +714,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
Projection v = value;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- gui[i * 4 + j] = v.matrix[i][j];
+ gui[i * 4 + j] = v.columns[i][j];
}
}
}
diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h
index 65c46631ed..6504c7748c 100644
--- a/drivers/gles3/storage/material_storage.h
+++ b/drivers/gles3/storage/material_storage.h
@@ -494,7 +494,7 @@ public:
static _FORCE_INLINE_ void store_camera(const Projection &p_mtx, float *p_array) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- p_array[i * 4 + j] = p_mtx.matrix[i][j];
+ p_array[i * 4 + j] = p_mtx.columns[i][j];
}
}
}
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index 8ea10539ec..5950997f9b 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -1343,24 +1343,6 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
rt->fbo = 0;
rt->color = 0;
}
- /*
- if (rt->external.fbo != 0) {
- // free this
- glDeleteFramebuffers(1, &rt->external.fbo);
-
- // clean up our texture
- Texture *t = get_texture(rt->external.texture);
- t->alloc_height = 0;
- t->alloc_width = 0;
- t->width = 0;
- t->height = 0;
- t->active = false;
- texture_free(rt->external.texture);
- memdelete(t);
-
- rt->external.fbo = 0;
- }
- */
Texture *tex = get_texture(rt->texture);
tex->alloc_height = 0;
@@ -1412,6 +1394,13 @@ void TextureStorage::render_target_set_position(RID p_render_target, int p_x, in
rt->position = Point2i(p_x, p_y);
}
+Point2i TextureStorage::render_target_get_position(RID p_render_target) const {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND_V(!rt, Point2i());
+
+ return rt->position;
+};
+
void TextureStorage::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@@ -1428,9 +1417,9 @@ void TextureStorage::render_target_set_size(RID p_render_target, int p_width, in
}
// TODO: convert to Size2i internally
-Size2i TextureStorage::render_target_get_size(RID p_render_target) {
+Size2i TextureStorage::render_target_get_size(RID p_render_target) const {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
- ERR_FAIL_COND_V(!rt, Size2());
+ ERR_FAIL_COND_V(!rt, Size2i());
return rt->size;
}
@@ -1439,105 +1428,7 @@ RID TextureStorage::render_target_get_texture(RID p_render_target) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
- if (rt->external.fbo == 0) {
- return rt->texture;
- } else {
- return rt->external.texture;
- }
-}
-
-void TextureStorage::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {
- RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
- ERR_FAIL_COND(!rt);
-
- if (p_texture_id == 0) {
- if (rt->external.fbo != 0) {
- // free this
- glDeleteFramebuffers(1, &rt->external.fbo);
-
- // and this
- if (rt->external.depth != 0) {
- glDeleteRenderbuffers(1, &rt->external.depth);
- }
-
- // clean up our texture
- Texture *t = get_texture(rt->external.texture);
- t->alloc_height = 0;
- t->alloc_width = 0;
- t->width = 0;
- t->height = 0;
- t->active = false;
- texture_free(rt->external.texture);
- //memdelete(t);
-
- rt->external.fbo = 0;
- rt->external.color = 0;
- rt->external.depth = 0;
- }
- } else {
- Texture *t;
-
- if (rt->external.fbo == 0) {
- // create our fbo
- glGenFramebuffers(1, &rt->external.fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, rt->external.fbo);
-
- // allocate a texture
- t = memnew(Texture);
-
- t->type = Texture::TYPE_2D;
- t->width = 0;
- t->height = 0;
- t->alloc_height = 0;
- t->alloc_width = 0;
- t->format = Image::FORMAT_RGBA8;
- t->target = GL_TEXTURE_2D;
- t->gl_format_cache = 0;
- t->gl_internal_format_cache = 0;
- t->gl_type_cache = 0;
- t->total_data_size = 0;
- t->mipmaps = 1;
- t->active = true;
- t->tex_id = 0;
- t->render_target = rt;
- t->is_render_target = true;
-
- //rt->external.texture = make_rid(t);
-
- } else {
- // bind our frame buffer
- glBindFramebuffer(GL_FRAMEBUFFER, rt->external.fbo);
-
- // find our texture
- t = get_texture(rt->external.texture);
- }
-
- // set our texture
- t->tex_id = p_texture_id;
- rt->external.color = p_texture_id;
-
- // size shouldn't be different
- t->width = rt->size.x;
- t->height = rt->size.y;
- t->alloc_height = rt->size.x;
- t->alloc_width = rt->size.y;
-
- // Switch our texture on our frame buffer
- {
- // set our texture as the destination for our framebuffer
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture_id, 0);
- }
-
- // check status and unbind
- GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
-
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- WARN_PRINT("framebuffer fail, status: " + get_framebuffer_error(status));
- }
-
- ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
- }
+ return rt->texture;
}
void TextureStorage::render_target_set_transparent(RID p_render_target, bool p_transparent) {
@@ -1550,6 +1441,13 @@ void TextureStorage::render_target_set_transparent(RID p_render_target, bool p_t
_update_render_target(rt);
}
+bool TextureStorage::render_target_get_transparent(RID p_render_target) const {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND_V(!rt, false);
+
+ return rt->is_transparent;
+}
+
void TextureStorage::render_target_set_direct_to_screen(RID p_render_target, bool p_direct_to_screen) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@@ -1564,7 +1462,14 @@ void TextureStorage::render_target_set_direct_to_screen(RID p_render_target, boo
_update_render_target(rt);
}
-bool TextureStorage::render_target_was_used(RID p_render_target) {
+bool TextureStorage::render_target_get_direct_to_screen(RID p_render_target) const {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND_V(!rt, false);
+
+ return rt->direct_to_screen;
+}
+
+bool TextureStorage::render_target_was_used(RID p_render_target) const {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, false);
@@ -1591,6 +1496,13 @@ void TextureStorage::render_target_set_msaa(RID p_render_target, RS::ViewportMSA
_update_render_target(rt);
}
+RS::ViewportMSAA TextureStorage::render_target_get_msaa(RID p_render_target) const {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND_V(!rt, RS::VIEWPORT_MSAA_DISABLED);
+
+ return rt->msaa;
+}
+
void TextureStorage::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h
index 16bf406845..0d4cd9c7e3 100644
--- a/drivers/gles3/storage/texture_storage.h
+++ b/drivers/gles3/storage/texture_storage.h
@@ -327,16 +327,6 @@ private:
};
struct RenderTarget {
- struct External {
- GLuint fbo = 0;
- GLuint color = 0;
- GLuint depth = 0;
- RID texture;
-
- External() {
- }
- } external;
-
Point2i position = Point2i(0, 0);
Size2i size = Size2i(0, 0);
int mipmap_count = 1;
@@ -524,17 +514,19 @@ public:
virtual RID render_target_create() override;
virtual void render_target_free(RID p_rid) override;
+
virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) override;
+ virtual Point2i render_target_get_position(RID p_render_target) const override;
virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override;
- Size2i render_target_get_size(RID p_render_target);
- virtual RID render_target_get_texture(RID p_render_target) override;
- virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override;
-
+ virtual Size2i render_target_get_size(RID p_render_target) const override;
virtual void render_target_set_transparent(RID p_render_target, bool p_is_transparent) override;
+ virtual bool render_target_get_transparent(RID p_render_target) const override;
virtual void render_target_set_direct_to_screen(RID p_render_target, bool p_direct_to_screen) override;
- virtual bool render_target_was_used(RID p_render_target) override;
+ virtual bool render_target_get_direct_to_screen(RID p_render_target) const override;
+ virtual bool render_target_was_used(RID p_render_target) const override;
void render_target_clear_used(RID p_render_target);
virtual void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) override;
+ virtual RS::ViewportMSAA render_target_get_msaa(RID p_render_target) const override;
// new
void render_target_set_as_unused(RID p_render_target) override {
@@ -554,8 +546,20 @@ public:
void render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps);
void render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color);
void render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region);
- virtual void render_target_set_vrs_mode(RID p_render_target, RS::ViewportVRSMode p_mode) override{};
- virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) override{};
+
+ virtual void render_target_set_vrs_mode(RID p_render_target, RS::ViewportVRSMode p_mode) override {}
+ virtual RS::ViewportVRSMode render_target_get_vrs_mode(RID p_render_target) const override { return RS::VIEWPORT_VRS_DISABLED; }
+ virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) override {}
+ virtual RID render_target_get_vrs_texture(RID p_render_target) const override { return RID(); }
+
+ virtual void render_target_set_override_color(RID p_render_target, RID p_texture) override {}
+ virtual RID render_target_get_override_color(RID p_render_target) const override { return RID(); }
+ virtual void render_target_set_override_depth(RID p_render_target, RID p_texture) override {}
+ virtual RID render_target_get_override_depth(RID p_render_target) const override { return RID(); }
+ virtual void render_target_set_override_velocity(RID p_render_target, RID p_texture) override {}
+ virtual RID render_target_get_override_velocity(RID p_render_target) const override { return RID(); }
+
+ virtual RID render_target_get_texture(RID p_render_target) override;
void bind_framebuffer(GLuint framebuffer) {
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp
index b6348c5952..4d48dd5ac5 100644
--- a/editor/action_map_editor.cpp
+++ b/editor/action_map_editor.cpp
@@ -35,6 +35,106 @@
#include "editor/editor_scale.h"
#include "scene/gui/separator.h"
+bool EventListenerLineEdit::_is_event_allowed(const Ref<InputEvent> &p_event) const {
+ const Ref<InputEventMouseButton> mb = p_event;
+ const Ref<InputEventKey> k = p_event;
+ const Ref<InputEventJoypadButton> jb = p_event;
+ const Ref<InputEventJoypadMotion> jm = p_event;
+
+ return (mb.is_valid() && (allowed_input_types & INPUT_MOUSE_BUTTON)) ||
+ (k.is_valid() && (allowed_input_types & INPUT_KEY)) ||
+ (jb.is_valid() && (allowed_input_types & INPUT_JOY_BUTTON)) ||
+ (jm.is_valid() && (allowed_input_types & INPUT_JOY_MOTION));
+}
+
+void EventListenerLineEdit::gui_input(const Ref<InputEvent> &p_event) {
+ const Ref<InputEventMouseMotion> mm = p_event;
+ if (mm.is_valid()) {
+ LineEdit::gui_input(p_event);
+ return;
+ }
+
+ // Allow mouse button click on the clear button without being treated as an event.
+ const Ref<InputEventMouseButton> b = p_event;
+ if (b.is_valid() && _is_over_clear_button(b->get_position())) {
+ LineEdit::gui_input(p_event);
+ return;
+ }
+
+ // First event will be an event which is used to focus this control - i.e. a mouse click, or a tab press.
+ // Ignore the first one so that clicking into the LineEdit does not override the current event.
+ // Ignore is reset to true when the control is unfocused.
+ if (ignore) {
+ ignore = false;
+ return;
+ }
+
+ accept_event();
+ if (!p_event->is_pressed() || p_event->is_echo() || p_event->is_match(event) || !_is_event_allowed(p_event)) {
+ return;
+ }
+
+ event = p_event;
+ set_text(event->as_text());
+ emit_signal("event_changed", event);
+}
+
+void EventListenerLineEdit::_on_text_changed(const String &p_text) {
+ if (p_text.is_empty()) {
+ clear_event();
+ }
+}
+
+void EventListenerLineEdit::_on_focus() {
+ set_placeholder(TTR("Listening for input..."));
+}
+
+void EventListenerLineEdit::_on_unfocus() {
+ ignore = true;
+ set_placeholder(TTR("Filter by event..."));
+}
+
+Ref<InputEvent> EventListenerLineEdit::get_event() const {
+ return event;
+}
+
+void EventListenerLineEdit::clear_event() {
+ if (event.is_valid()) {
+ event = Ref<InputEvent>();
+ set_text("");
+ emit_signal("event_changed", event);
+ }
+}
+
+void EventListenerLineEdit::set_allowed_input_types(int input_types) {
+ allowed_input_types = input_types;
+}
+
+int EventListenerLineEdit::get_allowed_input_types() const {
+ return allowed_input_types;
+}
+
+void EventListenerLineEdit::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ connect("text_changed", callable_mp(this, &EventListenerLineEdit::_on_text_changed));
+ connect("focus_entered", callable_mp(this, &EventListenerLineEdit::_on_focus));
+ connect("focus_exited", callable_mp(this, &EventListenerLineEdit::_on_unfocus));
+ set_right_icon(get_theme_icon(SNAME("Keyboard"), SNAME("EditorIcons")));
+ set_clear_button_enabled(true);
+ } break;
+ }
+}
+
+void EventListenerLineEdit::_bind_methods() {
+ ADD_SIGNAL(MethodInfo("event_changed", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
+}
+
+EventListenerLineEdit::EventListenerLineEdit() {
+ set_caret_blink_enabled(false);
+ set_placeholder(TTR("Filter by event..."));
+}
+
/////////////////////////////////////////
// Maps to 2*axis if value is neg, or 2*axis+1 if value is pos.
@@ -98,6 +198,13 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event, b
if (p_event.is_valid()) {
event = p_event;
+ // If the event is changed to something which is not the same as the listener,
+ // clear out the event from the listener text box to avoid confusion.
+ const Ref<InputEvent> listener_event = event_listener->get_event();
+ if (listener_event.is_valid() && !listener_event->is_match(p_event)) {
+ event_listener->clear_event();
+ }
+
// Update Label
event_as_text->set_text(get_event_text(event, true));
@@ -175,31 +282,8 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event, b
} else {
// Event is not valid, reset dialog
event = p_event;
- Vector<String> strings;
-
- // Reset message, promp for input according to which input types are allowed.
- String text = TTR("Perform an Input (%s).");
-
- if (allowed_input_types & INPUT_KEY) {
- strings.append(TTR("Key"));
- }
-
- if (allowed_input_types & INPUT_JOY_BUTTON) {
- strings.append(TTR("Joypad Button"));
- }
- if (allowed_input_types & INPUT_JOY_MOTION) {
- strings.append(TTR("Joypad Axis"));
- }
- if (allowed_input_types & INPUT_MOUSE_BUTTON) {
- strings.append(TTR("Mouse Button in area below"));
- }
- if (strings.size() == 0) {
- text = TTR("Input Event dialog has been misconfigured: No input types are allowed.");
- event_as_text->set_text(text);
- } else {
- String insert_text = String(", ").join(strings);
- event_as_text->set_text(vformat(text, insert_text));
- }
+ event_listener->clear_event();
+ event_as_text->set_text(TTR("No Event Configured"));
additional_options_container->hide();
input_list_tree->deselect_all();
@@ -207,54 +291,19 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event, b
}
}
-void InputEventConfigurationDialog::_tab_selected(int p_tab) {
- Callable signal_method = callable_mp(this, &InputEventConfigurationDialog::_listen_window_input);
- if (p_tab == 0) {
- // Start Listening.
- if (!is_connected("window_input", signal_method)) {
- connect("window_input", signal_method);
- }
- } else {
- // Stop Listening.
- if (is_connected("window_input", signal_method)) {
- disconnect("window_input", signal_method);
- }
- input_list_tree->call_deferred(SNAME("ensure_cursor_is_visible"));
- if (input_list_tree->get_selected() == nullptr) {
- // If nothing selected, scroll to top.
- input_list_tree->scroll_to_item(input_list_tree->get_root());
- }
- }
-}
-
-void InputEventConfigurationDialog::_listen_window_input(const Ref<InputEvent> &p_event) {
- // Ignore if echo or not pressed
- if (p_event->is_echo() || !p_event->is_pressed()) {
- return;
- }
-
- // Ignore mouse motion
- Ref<InputEventMouseMotion> mm = p_event;
- if (mm.is_valid()) {
+void InputEventConfigurationDialog::_on_listen_input_changed(const Ref<InputEvent> &p_event) {
+ // Ignore if invalid, echo or not pressed
+ if (p_event.is_null() || p_event->is_echo() || !p_event->is_pressed()) {
return;
}
- // Ignore mouse button if not in the detection rect
- Ref<InputEventMouseButton> mb = p_event;
- if (mb.is_valid()) {
- Rect2 r = mouse_detection_rect->get_rect();
- if (!r.has_point(mouse_detection_rect->get_local_mouse_position() + r.get_position())) {
- return;
- }
- }
-
// Create an editable reference
Ref<InputEvent> received_event = p_event;
-
// Check what the type is and if it is allowed.
Ref<InputEventKey> k = received_event;
Ref<InputEventJoypadButton> joyb = received_event;
Ref<InputEventJoypadMotion> joym = received_event;
+ Ref<InputEventMouseButton> mb = received_event;
int type = 0;
if (k.is_valid()) {
@@ -301,7 +350,14 @@ void InputEventConfigurationDialog::_listen_window_input(const Ref<InputEvent> &
received_event->set_device(_get_current_device());
_set_event(received_event);
- set_input_as_handled();
+}
+
+void InputEventConfigurationDialog::_on_listen_focus_changed() {
+ if (event_listener->has_focus()) {
+ set_close_on_escape(false);
+ } else {
+ set_close_on_escape(true);
+ }
}
void InputEventConfigurationDialog::_search_term_updated(const String &) {
@@ -478,10 +534,10 @@ void InputEventConfigurationDialog::_input_list_item_selected() {
return;
}
- InputEventConfigurationDialog::InputType input_type = (InputEventConfigurationDialog::InputType)(int)selected->get_parent()->get_meta("__type");
+ InputType input_type = (InputType)(int)selected->get_parent()->get_meta("__type");
switch (input_type) {
- case InputEventConfigurationDialog::INPUT_KEY: {
+ case INPUT_KEY: {
Key keycode = (Key)(int)selected->get_meta("__keycode");
Ref<InputEventKey> k;
k.instantiate();
@@ -506,7 +562,7 @@ void InputEventConfigurationDialog::_input_list_item_selected() {
_set_event(k, false);
} break;
- case InputEventConfigurationDialog::INPUT_MOUSE_BUTTON: {
+ case INPUT_MOUSE_BUTTON: {
MouseButton idx = (MouseButton)(int)selected->get_meta("__index");
Ref<InputEventMouseButton> mb;
mb.instantiate();
@@ -526,7 +582,7 @@ void InputEventConfigurationDialog::_input_list_item_selected() {
_set_event(mb, false);
} break;
- case InputEventConfigurationDialog::INPUT_JOY_BUTTON: {
+ case INPUT_JOY_BUTTON: {
JoyButton idx = (JoyButton)(int)selected->get_meta("__index");
Ref<InputEventJoypadButton> jb = InputEventJoypadButton::create_reference(idx);
@@ -535,7 +591,7 @@ void InputEventConfigurationDialog::_input_list_item_selected() {
_set_event(jb, false);
} break;
- case InputEventConfigurationDialog::INPUT_JOY_MOTION: {
+ case INPUT_JOY_MOTION: {
JoyAxis axis = (JoyAxis)(int)selected->get_meta("__axis");
int value = selected->get_meta("__value");
@@ -611,10 +667,6 @@ void InputEventConfigurationDialog::popup_and_configure(const Ref<InputEvent> &p
physical_key_checkbox->set_pressed(true);
autoremap_command_or_control_checkbox->set_pressed(false);
- _set_current_device(0);
-
- // Switch to "Listen" tab
- tab_container->set_current_tab(0);
// Select "All Devices" by default.
device_id_option->select(0);
@@ -632,7 +684,7 @@ void InputEventConfigurationDialog::set_allowed_input_types(int p_type_masks) {
}
InputEventConfigurationDialog::InputEventConfigurationDialog() {
- allowed_input_types = INPUT_KEY | INPUT_MOUSE_BUTTON | INPUT_JOY_BUTTON | INPUT_JOY_MOTION | INPUT_MOUSE_BUTTON;
+ allowed_input_types = INPUT_KEY | INPUT_MOUSE_BUTTON | INPUT_JOY_BUTTON | INPUT_JOY_MOTION;
set_title(TTR("Event Configuration"));
set_min_size(Size2i(550 * EDSCALE, 0)); // Min width
@@ -640,31 +692,28 @@ InputEventConfigurationDialog::InputEventConfigurationDialog() {
VBoxContainer *main_vbox = memnew(VBoxContainer);
add_child(main_vbox);
- tab_container = memnew(TabContainer);
- tab_container->set_use_hidden_tabs_for_min_size(true);
- tab_container->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- tab_container->set_theme_type_variation("TabContainerOdd");
- tab_container->connect("tab_selected", callable_mp(this, &InputEventConfigurationDialog::_tab_selected));
- main_vbox->add_child(tab_container);
-
- // Listen to input tab
- VBoxContainer *vb = memnew(VBoxContainer);
- vb->set_name(TTR("Listen for Input"));
event_as_text = memnew(Label);
+ event_as_text->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART);
event_as_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
- vb->add_child(event_as_text);
- // Mouse button detection rect (Mouse button event outside this rect will be ignored)
- mouse_detection_rect = memnew(Panel);
- mouse_detection_rect->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- vb->add_child(mouse_detection_rect);
- tab_container->add_child(vb);
+ event_as_text->add_theme_font_override("font", get_theme_font(SNAME("bold"), SNAME("EditorFonts")));
+ event_as_text->add_theme_font_size_override("font_size", 18 * EDSCALE);
+ main_vbox->add_child(event_as_text);
- // List of all input options to manually select from.
+ event_listener = memnew(EventListenerLineEdit);
+ event_listener->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ event_listener->set_stretch_ratio(0.75);
+ event_listener->connect("event_changed", callable_mp(this, &InputEventConfigurationDialog::_on_listen_input_changed));
+ event_listener->connect("focus_entered", callable_mp(this, &InputEventConfigurationDialog::_on_listen_focus_changed));
+ event_listener->connect("focus_exited", callable_mp(this, &InputEventConfigurationDialog::_on_listen_focus_changed));
+ main_vbox->add_child(event_listener);
+ main_vbox->add_child(memnew(HSeparator));
+
+ // List of all input options to manually select from.
VBoxContainer *manual_vbox = memnew(VBoxContainer);
manual_vbox->set_name(TTR("Manual Selection"));
manual_vbox->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- tab_container->add_child(manual_vbox);
+ main_vbox->add_child(manual_vbox);
input_list_search = memnew(LineEdit);
input_list_search->set_h_size_flags(Control::SIZE_EXPAND_FILL);
@@ -747,9 +796,6 @@ InputEventConfigurationDialog::InputEventConfigurationDialog() {
additional_options_container->add_child(physical_key_checkbox);
main_vbox->add_child(additional_options_container);
-
- // Default to first tab
- tab_container->set_current_tab(0);
}
/////////////////////////////////////////
@@ -944,6 +990,12 @@ void ActionMapEditor::_search_term_updated(const String &) {
update_action_list();
}
+void ActionMapEditor::_search_by_event(const Ref<InputEvent> &p_event) {
+ if (p_event.is_null() || (p_event->is_pressed() && !p_event->is_echo())) {
+ update_action_list();
+ }
+}
+
Variant ActionMapEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
TreeItem *selected = action_tree->get_selected();
if (!selected) {
@@ -1084,6 +1136,22 @@ InputEventConfigurationDialog *ActionMapEditor::get_configuration_dialog() {
return event_config_dialog;
}
+bool ActionMapEditor::_should_display_action(const String &p_name, const Array &p_events) const {
+ const Ref<InputEvent> search_ev = action_list_search_by_event->get_event();
+ bool event_match = true;
+ if (search_ev.is_valid()) {
+ event_match = false;
+ for (int i = 0; i < p_events.size(); ++i) {
+ const Ref<InputEvent> ev = p_events[i];
+ if (ev.is_valid() && ev->is_match(search_ev, true)) {
+ event_match = true;
+ }
+ }
+ }
+
+ return event_match && action_list_search->get_text().is_subsequence_ofn(p_name);
+}
+
void ActionMapEditor::update_action_list(const Vector<ActionInfo> &p_action_infos) {
if (!p_action_infos.is_empty()) {
actions_cache = p_action_infos;
@@ -1101,8 +1169,8 @@ void ActionMapEditor::update_action_list(const Vector<ActionInfo> &p_action_info
uneditable_count++;
}
- String search_term = action_list_search->get_text();
- if (!search_term.is_empty() && action_info.name.findn(search_term) == -1) {
+ const Array events = action_info.action["events"];
+ if (!_should_display_action(action_info.name, events)) {
continue;
}
@@ -1110,7 +1178,6 @@ void ActionMapEditor::update_action_list(const Vector<ActionInfo> &p_action_info
continue;
}
- const Array events = action_info.action["events"];
const Variant deadzone = action_info.action["deadzone"];
// Update Tree...
@@ -1206,16 +1273,22 @@ ActionMapEditor::ActionMapEditor() {
action_list_search = memnew(LineEdit);
action_list_search->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- action_list_search->set_placeholder(TTR("Filter Actions"));
+ action_list_search->set_placeholder(TTR("Filter by name..."));
action_list_search->set_clear_button_enabled(true);
action_list_search->connect("text_changed", callable_mp(this, &ActionMapEditor::_search_term_updated));
top_hbox->add_child(action_list_search);
- show_builtin_actions_checkbutton = memnew(CheckButton);
- show_builtin_actions_checkbutton->set_pressed(false);
- show_builtin_actions_checkbutton->set_text(TTR("Show Built-in Actions"));
- show_builtin_actions_checkbutton->connect("toggled", callable_mp(this, &ActionMapEditor::set_show_builtin_actions));
- top_hbox->add_child(show_builtin_actions_checkbutton);
+ action_list_search_by_event = memnew(EventListenerLineEdit);
+ action_list_search_by_event->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ action_list_search_by_event->set_stretch_ratio(0.75);
+ action_list_search_by_event->connect("event_changed", callable_mp(this, &ActionMapEditor::_search_by_event));
+ top_hbox->add_child(action_list_search_by_event);
+
+ Button *clear_all_search = memnew(Button);
+ clear_all_search->set_text(TTR("Clear All"));
+ clear_all_search->connect("pressed", callable_mp(action_list_search_by_event, &EventListenerLineEdit::clear_event));
+ clear_all_search->connect("pressed", callable_mp(action_list_search, &LineEdit::clear));
+ top_hbox->add_child(clear_all_search);
// Adding Action line edit + button
add_hbox = memnew(HBoxContainer);
@@ -1236,6 +1309,12 @@ ActionMapEditor::ActionMapEditor() {
// Disable the button and set its tooltip.
_add_edit_text_changed(add_edit->get_text());
+ show_builtin_actions_checkbutton = memnew(CheckButton);
+ show_builtin_actions_checkbutton->set_pressed(false);
+ show_builtin_actions_checkbutton->set_text(TTR("Show Built-in Actions"));
+ show_builtin_actions_checkbutton->connect("toggled", callable_mp(this, &ActionMapEditor::set_show_builtin_actions));
+ add_hbox->add_child(show_builtin_actions_checkbutton);
+
main_vbox->add_child(add_hbox);
// Action Editor Tree
diff --git a/editor/action_map_editor.h b/editor/action_map_editor.h
index 36d21fe258..f576a2b565 100644
--- a/editor/action_map_editor.h
+++ b/editor/action_map_editor.h
@@ -40,19 +40,48 @@
#include "scene/gui/tab_container.h"
#include "scene/gui/tree.h"
-// Confirmation Dialog used when configuring an input event.
-// Separate from ActionMapEditor for code cleanliness and separation of responsibilities.
-class InputEventConfigurationDialog : public ConfirmationDialog {
- GDCLASS(InputEventConfigurationDialog, ConfirmationDialog);
+enum InputType {
+ INPUT_KEY = 1,
+ INPUT_MOUSE_BUTTON = 2,
+ INPUT_JOY_BUTTON = 4,
+ INPUT_JOY_MOTION = 8
+};
+
+class EventListenerLineEdit : public LineEdit {
+ GDCLASS(EventListenerLineEdit, LineEdit)
+
+ int allowed_input_types = INPUT_KEY | INPUT_MOUSE_BUTTON | INPUT_JOY_BUTTON | INPUT_JOY_MOTION;
+ bool ignore = true;
+ bool share_keycodes = false;
+ Ref<InputEvent> event;
+
+ bool _is_event_allowed(const Ref<InputEvent> &p_event) const;
+
+ void gui_input(const Ref<InputEvent> &p_event) override;
+ void _on_text_changed(const String &p_text);
+
+ void _on_focus();
+ void _on_unfocus();
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
public:
- enum InputType {
- INPUT_KEY = 1,
- INPUT_MOUSE_BUTTON = 2,
- INPUT_JOY_BUTTON = 4,
- INPUT_JOY_MOTION = 8
- };
+ Ref<InputEvent> get_event() const;
+ void clear_event();
+
+ void set_allowed_input_types(int input_types);
+ int get_allowed_input_types() const;
+
+public:
+ EventListenerLineEdit();
+};
+// Confirmation Dialog used when configuring an input event.
+// Separate from ActionMapEditor for code cleanliness and separation of responsibilities.
+class InputEventConfigurationDialog : public ConfirmationDialog {
+ GDCLASS(InputEventConfigurationDialog, ConfirmationDialog)
private:
struct IconCache {
Ref<Texture2D> keyboard;
@@ -63,11 +92,9 @@ private:
Ref<InputEvent> event = Ref<InputEvent>();
- TabContainer *tab_container = nullptr;
-
// Listening for input
+ EventListenerLineEdit *event_listener = nullptr;
Label *event_as_text = nullptr;
- Panel *mouse_detection_rect = nullptr;
// List of All Key/Mouse/Joypad input options.
int allowed_input_types;
@@ -104,9 +131,8 @@ private:
CheckBox *physical_key_checkbox = nullptr;
void _set_event(const Ref<InputEvent> &p_event, bool p_update_input_list_selection = true);
-
- void _tab_selected(int p_tab);
- void _listen_window_input(const Ref<InputEvent> &p_event);
+ void _on_listen_input_changed(const Ref<InputEvent> &p_event);
+ void _on_listen_focus_changed();
void _search_term_updated(const String &p_term);
void _update_input_list();
@@ -174,6 +200,7 @@ private:
bool show_builtin_actions = false;
CheckButton *show_builtin_actions_checkbutton = nullptr;
LineEdit *action_list_search = nullptr;
+ EventListenerLineEdit *action_list_search_by_event = nullptr;
HBoxContainer *add_hbox = nullptr;
LineEdit *add_edit = nullptr;
@@ -191,6 +218,8 @@ private:
void _tree_button_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button);
void _tree_item_activated();
void _search_term_updated(const String &p_search_term);
+ void _search_by_event(const Ref<InputEvent> &p_event);
+ bool _should_display_action(const String &p_name, const Array &p_events) const;
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 11a6912aa5..25556482bc 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -1526,19 +1526,7 @@ void CodeTextEditor::clear_executing_line() {
Variant CodeTextEditor::get_edit_state() {
Dictionary state;
-
- state["scroll_position"] = text_editor->get_v_scroll();
- state["h_scroll_position"] = text_editor->get_h_scroll();
- state["column"] = text_editor->get_caret_column();
- state["row"] = text_editor->get_caret_line();
-
- state["selection"] = get_text_editor()->has_selection();
- if (get_text_editor()->has_selection()) {
- state["selection_from_line"] = text_editor->get_selection_from_line();
- state["selection_from_column"] = text_editor->get_selection_from_column();
- state["selection_to_line"] = text_editor->get_selection_to_line();
- state["selection_to_column"] = text_editor->get_selection_to_column();
- }
+ state.merge(get_navigation_state());
state["folded_lines"] = text_editor->get_folded_lines();
state["breakpoints"] = text_editor->get_breakpointed_lines();
@@ -1559,8 +1547,10 @@ void CodeTextEditor::set_edit_state(const Variant &p_state) {
text_editor->set_v_scroll(state["scroll_position"]);
text_editor->set_h_scroll(state["h_scroll_position"]);
- if (state.has("selection")) {
+ if (state.get("selection", false)) {
text_editor->select(state["selection_from_line"], state["selection_from_column"], state["selection_to_line"], state["selection_to_column"]);
+ } else {
+ text_editor->deselect();
}
if (state.has("folded_lines")) {
@@ -1585,6 +1575,25 @@ void CodeTextEditor::set_edit_state(const Variant &p_state) {
}
}
+Variant CodeTextEditor::get_navigation_state() {
+ Dictionary state;
+
+ state["scroll_position"] = text_editor->get_v_scroll();
+ state["h_scroll_position"] = text_editor->get_h_scroll();
+ state["column"] = text_editor->get_caret_column();
+ state["row"] = text_editor->get_caret_line();
+
+ state["selection"] = get_text_editor()->has_selection();
+ if (get_text_editor()->has_selection()) {
+ state["selection_from_line"] = text_editor->get_selection_from_line();
+ state["selection_from_column"] = text_editor->get_selection_from_column();
+ state["selection_to_line"] = text_editor->get_selection_to_line();
+ state["selection_to_column"] = text_editor->get_selection_to_column();
+ }
+
+ return state;
+}
+
void CodeTextEditor::set_error(const String &p_error) {
error->set_text(p_error);
if (!p_error.is_empty()) {
diff --git a/editor/code_editor.h b/editor/code_editor.h
index 49679cc700..775708954d 100644
--- a/editor/code_editor.h
+++ b/editor/code_editor.h
@@ -246,6 +246,7 @@ public:
Variant get_edit_state();
void set_edit_state(const Variant &p_state);
+ Variant get_navigation_state();
void set_error_count(int p_error_count);
void set_warning_count(int p_warning_count);
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 3b99962435..00dd80c8fa 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -3393,22 +3393,22 @@ void EditorPropertyProjection::_value_changed(double val, const String &p_name)
}
Projection p;
- p.matrix[0][0] = spin[0]->get_value();
- p.matrix[0][1] = spin[1]->get_value();
- p.matrix[0][2] = spin[2]->get_value();
- p.matrix[0][3] = spin[3]->get_value();
- p.matrix[1][0] = spin[4]->get_value();
- p.matrix[1][1] = spin[5]->get_value();
- p.matrix[1][2] = spin[6]->get_value();
- p.matrix[1][3] = spin[7]->get_value();
- p.matrix[2][0] = spin[8]->get_value();
- p.matrix[2][1] = spin[9]->get_value();
- p.matrix[2][2] = spin[10]->get_value();
- p.matrix[2][3] = spin[11]->get_value();
- p.matrix[3][0] = spin[12]->get_value();
- p.matrix[3][1] = spin[13]->get_value();
- p.matrix[3][2] = spin[14]->get_value();
- p.matrix[3][3] = spin[15]->get_value();
+ p.columns[0][0] = spin[0]->get_value();
+ p.columns[0][1] = spin[1]->get_value();
+ p.columns[0][2] = spin[2]->get_value();
+ p.columns[0][3] = spin[3]->get_value();
+ p.columns[1][0] = spin[4]->get_value();
+ p.columns[1][1] = spin[5]->get_value();
+ p.columns[1][2] = spin[6]->get_value();
+ p.columns[1][3] = spin[7]->get_value();
+ p.columns[2][0] = spin[8]->get_value();
+ p.columns[2][1] = spin[9]->get_value();
+ p.columns[2][2] = spin[10]->get_value();
+ p.columns[2][3] = spin[11]->get_value();
+ p.columns[3][0] = spin[12]->get_value();
+ p.columns[3][1] = spin[13]->get_value();
+ p.columns[3][2] = spin[14]->get_value();
+ p.columns[3][3] = spin[15]->get_value();
emit_changed(get_edited_property(), p, p_name);
}
@@ -3419,22 +3419,22 @@ void EditorPropertyProjection::update_property() {
void EditorPropertyProjection::update_using_transform(Projection p_transform) {
setting = true;
- spin[0]->set_value(p_transform.matrix[0][0]);
- spin[1]->set_value(p_transform.matrix[0][1]);
- spin[2]->set_value(p_transform.matrix[0][2]);
- spin[3]->set_value(p_transform.matrix[0][3]);
- spin[4]->set_value(p_transform.matrix[1][0]);
- spin[5]->set_value(p_transform.matrix[1][1]);
- spin[6]->set_value(p_transform.matrix[1][2]);
- spin[7]->set_value(p_transform.matrix[1][3]);
- spin[8]->set_value(p_transform.matrix[2][0]);
- spin[9]->set_value(p_transform.matrix[2][1]);
- spin[10]->set_value(p_transform.matrix[2][2]);
- spin[11]->set_value(p_transform.matrix[2][3]);
- spin[12]->set_value(p_transform.matrix[3][0]);
- spin[13]->set_value(p_transform.matrix[3][1]);
- spin[14]->set_value(p_transform.matrix[3][2]);
- spin[15]->set_value(p_transform.matrix[3][3]);
+ spin[0]->set_value(p_transform.columns[0][0]);
+ spin[1]->set_value(p_transform.columns[0][1]);
+ spin[2]->set_value(p_transform.columns[0][2]);
+ spin[3]->set_value(p_transform.columns[0][3]);
+ spin[4]->set_value(p_transform.columns[1][0]);
+ spin[5]->set_value(p_transform.columns[1][1]);
+ spin[6]->set_value(p_transform.columns[1][2]);
+ spin[7]->set_value(p_transform.columns[1][3]);
+ spin[8]->set_value(p_transform.columns[2][0]);
+ spin[9]->set_value(p_transform.columns[2][1]);
+ spin[10]->set_value(p_transform.columns[2][2]);
+ spin[11]->set_value(p_transform.columns[2][3]);
+ spin[12]->set_value(p_transform.columns[3][0]);
+ spin[13]->set_value(p_transform.columns[3][1]);
+ spin[14]->set_value(p_transform.columns[3][2]);
+ spin[15]->set_value(p_transform.columns[3][3]);
setting = false;
}
diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp
index 2c09543d92..b5147bb4eb 100644
--- a/editor/editor_settings_dialog.cpp
+++ b/editor/editor_settings_dialog.cpp
@@ -106,11 +106,16 @@ void EditorSettingsDialog::popup_edit_settings() {
_focus_current_search_box();
}
-void EditorSettingsDialog::_filter_shortcuts(const String &p_filter) {
- shortcut_filter = p_filter;
+void EditorSettingsDialog::_filter_shortcuts(const String &) {
_update_shortcuts();
}
+void EditorSettingsDialog::_filter_shortcuts_by_event(const Ref<InputEvent> &p_event) {
+ if (p_event.is_null() || (p_event->is_pressed() && !p_event->is_echo())) {
+ _update_shortcuts();
+ }
+}
+
void EditorSettingsDialog::_undo_redo_callback(void *p_self, const String &p_name) {
EditorNode::get_log()->add_message(p_name, EditorLog::MSG_TYPE_EDITOR);
}
@@ -326,6 +331,22 @@ void EditorSettingsDialog::_create_shortcut_treeitem(TreeItem *p_parent, const S
}
}
+bool EditorSettingsDialog::_should_display_shortcut(const String &p_name, const Array &p_events) const {
+ const Ref<InputEvent> search_ev = shortcut_search_by_event->get_event();
+ bool event_match = true;
+ if (search_ev.is_valid()) {
+ event_match = false;
+ for (int i = 0; i < p_events.size(); ++i) {
+ const Ref<InputEvent> ev = p_events[i];
+ if (ev.is_valid() && ev->is_match(search_ev, true)) {
+ event_match = true;
+ }
+ }
+ }
+
+ return event_match && shortcut_search_box->get_text().is_subsequence_ofn(p_name);
+}
+
void EditorSettingsDialog::_update_shortcuts() {
// Before clearing the tree, take note of which categories are collapsed so that this state can be maintained when the tree is repopulated.
HashMap<String, bool> collapsed;
@@ -379,32 +400,17 @@ void EditorSettingsDialog::_update_shortcuts() {
const String &action_name = E.key;
const InputMap::Action &action = E.value;
- Array events; // Need to get the list of events into an array so it can be set as metadata on the item.
- Vector<String> event_strings;
-
// Skip non-builtin actions.
if (!InputMap::get_singleton()->get_builtins_with_feature_overrides_applied().has(action_name)) {
continue;
}
const List<Ref<InputEvent>> &all_default_events = InputMap::get_singleton()->get_builtins_with_feature_overrides_applied().find(action_name)->value;
- List<Ref<InputEventKey>> key_default_events;
- // Remove all non-key events from the defaults. Only check keys, since we are in the editor.
- for (const List<Ref<InputEvent>>::Element *I = all_default_events.front(); I; I = I->next()) {
- Ref<InputEventKey> k = I->get();
- if (k.is_valid()) {
- key_default_events.push_back(k);
- }
- }
-
- // Join the text of the events with a delimiter so they can all be displayed in one cell.
- String events_display_string = event_strings.is_empty() ? "None" : String("; ").join(event_strings);
-
- if (!shortcut_filter.is_subsequence_ofn(action_name) && (events_display_string == "None" || !shortcut_filter.is_subsequence_ofn(events_display_string))) {
+ Array action_events = _event_list_to_array_helper(action.inputs);
+ if (!_should_display_shortcut(action_name, action_events)) {
continue;
}
- Array action_events = _event_list_to_array_helper(action.inputs);
Array default_events = _event_list_to_array_helper(all_default_events);
bool same_as_defaults = Shortcut::is_event_array_equal(default_events, action_events);
bool collapse = !collapsed.has(action_name) || (collapsed.has(action_name) && collapsed[action_name]);
@@ -459,8 +465,7 @@ void EditorSettingsDialog::_update_shortcuts() {
String section_name = E.get_slice("/", 0);
TreeItem *section = sections[section_name];
- // Shortcut Item
- if (!shortcut_filter.is_subsequence_ofn(sc->get_name())) {
+ if (!_should_display_shortcut(sc->get_name(), sc->get_events())) {
continue;
}
@@ -749,12 +754,29 @@ EditorSettingsDialog::EditorSettingsDialog() {
tabs->add_child(tab_shortcuts);
tab_shortcuts->set_name(TTR("Shortcuts"));
+ HBoxContainer *top_hbox = memnew(HBoxContainer);
+ top_hbox->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ tab_shortcuts->add_child(top_hbox);
+
shortcut_search_box = memnew(LineEdit);
- shortcut_search_box->set_placeholder(TTR("Filter Shortcuts"));
+ shortcut_search_box->set_placeholder(TTR("Filter by name..."));
shortcut_search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- tab_shortcuts->add_child(shortcut_search_box);
+ top_hbox->add_child(shortcut_search_box);
shortcut_search_box->connect("text_changed", callable_mp(this, &EditorSettingsDialog::_filter_shortcuts));
+ shortcut_search_by_event = memnew(EventListenerLineEdit);
+ shortcut_search_by_event->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ shortcut_search_by_event->set_stretch_ratio(0.75);
+ shortcut_search_by_event->set_allowed_input_types(INPUT_KEY);
+ shortcut_search_by_event->connect("event_changed", callable_mp(this, &EditorSettingsDialog::_filter_shortcuts_by_event));
+ top_hbox->add_child(shortcut_search_by_event);
+
+ Button *clear_all_search = memnew(Button);
+ clear_all_search->set_text(TTR("Clear All"));
+ clear_all_search->connect("pressed", callable_mp(shortcut_search_box, &LineEdit::clear));
+ clear_all_search->connect("pressed", callable_mp(shortcut_search_by_event, &EventListenerLineEdit::clear_event));
+ top_hbox->add_child(clear_all_search);
+
shortcuts = memnew(Tree);
shortcuts->set_v_size_flags(Control::SIZE_EXPAND_FILL);
shortcuts->set_columns(2);
@@ -771,8 +793,7 @@ EditorSettingsDialog::EditorSettingsDialog() {
// Adding event dialog
shortcut_editor = memnew(InputEventConfigurationDialog);
shortcut_editor->connect("confirmed", callable_mp(this, &EditorSettingsDialog::_event_config_confirmed));
- shortcut_editor->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_KEY);
- shortcut_editor->set_close_on_escape(false);
+ shortcut_editor->set_allowed_input_types(INPUT_KEY);
add_child(shortcut_editor);
set_hide_on_ok(true);
diff --git a/editor/editor_settings_dialog.h b/editor/editor_settings_dialog.h
index 87ed6a77eb..05424a64ed 100644
--- a/editor/editor_settings_dialog.h
+++ b/editor/editor_settings_dialog.h
@@ -53,6 +53,7 @@ class EditorSettingsDialog : public AcceptDialog {
LineEdit *search_box = nullptr;
LineEdit *shortcut_search_box = nullptr;
+ EventListenerLineEdit *shortcut_search_by_event = nullptr;
SectionedInspector *inspector = nullptr;
// Shortcuts
@@ -64,7 +65,6 @@ class EditorSettingsDialog : public AcceptDialog {
};
Tree *shortcuts = nullptr;
- String shortcut_filter;
InputEventConfigurationDialog *shortcut_editor = nullptr;
@@ -103,13 +103,13 @@ class EditorSettingsDialog : public AcceptDialog {
void _focus_current_search_box();
void _filter_shortcuts(const String &p_filter);
+ void _filter_shortcuts_by_event(const Ref<InputEvent> &p_event);
+ bool _should_display_shortcut(const String &p_name, const Array &p_events) const;
void _update_shortcuts();
void _shortcut_button_pressed(Object *p_item, int p_column, int p_idx, MouseButton p_button = MouseButton::LEFT);
void _shortcut_cell_double_clicked();
- void _builtin_action_popup_index_pressed(int p_index);
-
static void _undo_redo_callback(void *p_self, const String &p_name);
Label *restart_label = nullptr;
diff --git a/editor/plugins/input_event_editor_plugin.cpp b/editor/plugins/input_event_editor_plugin.cpp
index 153eab32d2..e28c1a4777 100644
--- a/editor/plugins/input_event_editor_plugin.cpp
+++ b/editor/plugins/input_event_editor_plugin.cpp
@@ -63,13 +63,13 @@ void InputEventConfigContainer::set_event(const Ref<InputEvent> &p_event) {
Ref<InputEventJoypadMotion> jm = p_event;
if (k.is_valid()) {
- config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_KEY);
+ config_dialog->set_allowed_input_types(INPUT_KEY);
} else if (m.is_valid()) {
- config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_MOUSE_BUTTON);
+ config_dialog->set_allowed_input_types(INPUT_MOUSE_BUTTON);
} else if (jb.is_valid()) {
- config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_JOY_BUTTON);
+ config_dialog->set_allowed_input_types(INPUT_JOY_BUTTON);
} else if (jm.is_valid()) {
- config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_JOY_MOTION);
+ config_dialog->set_allowed_input_types(INPUT_JOY_MOTION);
}
input_event = p_event;
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index a3f2c2509f..67813a3635 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -566,7 +566,7 @@ void ScriptEditor::_save_history() {
Node *n = tab_container->get_current_tab_control();
if (Object::cast_to<ScriptEditorBase>(n)) {
- history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
+ history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_navigation_state();
}
if (Object::cast_to<EditorHelp>(n)) {
history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
@@ -601,7 +601,7 @@ void ScriptEditor::_go_to_tab(int p_idx) {
Node *n = tab_container->get_current_tab_control();
if (Object::cast_to<ScriptEditorBase>(n)) {
- history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
+ history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_navigation_state();
}
if (Object::cast_to<EditorHelp>(n)) {
history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
@@ -3360,7 +3360,7 @@ void ScriptEditor::_update_history_pos(int p_new_pos) {
Node *n = tab_container->get_current_tab_control();
if (Object::cast_to<ScriptEditorBase>(n)) {
- history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
+ history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_navigation_state();
}
if (Object::cast_to<EditorHelp>(n)) {
history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
@@ -3371,11 +3371,12 @@ void ScriptEditor::_update_history_pos(int p_new_pos) {
n = history[history_pos].control;
- if (Object::cast_to<ScriptEditorBase>(n)) {
- Object::cast_to<ScriptEditorBase>(n)->set_edit_state(history[history_pos].state);
- Object::cast_to<ScriptEditorBase>(n)->ensure_focus();
+ ScriptEditorBase *seb = Object::cast_to<ScriptEditorBase>(n);
+ if (seb) {
+ seb->set_edit_state(history[history_pos].state);
+ seb->ensure_focus();
- Ref<Script> script = Object::cast_to<ScriptEditorBase>(n)->get_edited_resource();
+ Ref<Script> script = seb->get_edited_resource();
if (script != nullptr) {
notify_script_changed(script);
}
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index aab713c9a3..e69b8f8f82 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -146,6 +146,7 @@ public:
virtual bool is_unsaved() = 0;
virtual Variant get_edit_state() = 0;
virtual void set_edit_state(const Variant &p_state) = 0;
+ virtual Variant get_navigation_state() = 0;
virtual void goto_line(int p_line, bool p_with_error = false) = 0;
virtual void set_executing_line(int p_line) = 0;
virtual void clear_executing_line() = 0;
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index a1d24907e5..ae2ed4ddeb 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -347,6 +347,10 @@ void ScriptTextEditor::set_edit_state(const Variant &p_state) {
}
}
+Variant ScriptTextEditor::get_navigation_state() {
+ return code_editor->get_navigation_state();
+}
+
void ScriptTextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) {
code_editor->convert_case(p_case);
}
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index 99fafb2192..fb02e5c7c4 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -215,6 +215,7 @@ public:
virtual bool is_unsaved() override;
virtual Variant get_edit_state() override;
virtual void set_edit_state(const Variant &p_state) override;
+ virtual Variant get_navigation_state() override;
virtual void ensure_focus() override;
virtual void trim_trailing_whitespace() override;
virtual void insert_final_newline() override;
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index 9846cd4a84..51e7ee101c 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -222,6 +222,10 @@ void TextEditor::set_edit_state(const Variant &p_state) {
ensure_focus();
}
+Variant TextEditor::get_navigation_state() {
+ return code_editor->get_navigation_state();
+}
+
void TextEditor::trim_trailing_whitespace() {
code_editor->trim_trailing_whitespace();
}
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
index 9ee6a39b2e..a7a640247f 100644
--- a/editor/plugins/text_editor.h
+++ b/editor/plugins/text_editor.h
@@ -117,6 +117,7 @@ public:
virtual bool is_unsaved() override;
virtual Variant get_edit_state() override;
virtual void set_edit_state(const Variant &p_state) override;
+ virtual Variant get_navigation_state() override;
virtual Vector<String> get_functions() override;
virtual PackedInt32Array get_breakpoints() override;
virtual void set_breakpoint(int p_line, bool p_enabled) override{};
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
index 45b2a5eb14..4299ae8d3e 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
@@ -2043,6 +2043,13 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_unscaled_draw() {
}
void TileSetAtlasSourceEditor::_tile_set_changed() {
+ if (tile_set->get_source_count() == 0) {
+ // No sources, so nothing to do here anymore.
+ tile_set->disconnect("changed", callable_mp(this, &TileSetAtlasSourceEditor::_tile_set_changed));
+ tile_set = Ref<TileSet>();
+ return;
+ }
+
tile_set_changed_needs_update = true;
}
diff --git a/gles3_builders.py b/gles3_builders.py
index 84f11532e0..46ab1bbc03 100644
--- a/gles3_builders.py
+++ b/gles3_builders.py
@@ -436,7 +436,7 @@ def build_gles3_header(filename: str, include: str, class_suffix: str, header_da
)
fd.write(
- """_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Projection& p_matrix,RID p_version,ShaderVariant p_variant"""
+ """_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Projection& p_matrix, RID p_version, ShaderVariant p_variant"""
+ defvariant
+ """,uint64_t p_specialization="""
+ str(defspec)
@@ -444,13 +444,13 @@ def build_gles3_header(filename: str, include: str, class_suffix: str, header_da
GLfloat matrix[16];
- for (int i=0;i<4;i++) {
- for (int j=0;j<4;j++) {
- matrix[i*4+j]=p_matrix.matrix[i][j];
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ matrix[i * 4 + j] = p_matrix.columns[i][j];
}
}
- glUniformMatrix4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,false,matrix);
+ glUniformMatrix4fv(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), 1, false, matrix);
}"""
)
diff --git a/methods.py b/methods.py
index bec1b803e9..3a2dd07964 100644
--- a/methods.py
+++ b/methods.py
@@ -777,7 +777,7 @@ def generate_vs_project(env, num_jobs):
for platform in ModuleConfigs.PLATFORMS
]
self.arg_dict["runfile"] += [
- f'bin\\godot.windows.{config}{ModuleConfigs.DEV_SUFFIX}.{plat_id}{f".{name}" if name else ""}.exe'
+ f'bin\\godot.windows.{config}{ModuleConfigs.DEV_SUFFIX}{".double" if env["float"] == "64" else ""}.{plat_id}{f".{name}" if name else ""}.exe'
for config in ModuleConfigs.CONFIGURATIONS
for plat_id in ModuleConfigs.PLATFORM_IDS
]
@@ -814,12 +814,18 @@ def generate_vs_project(env, num_jobs):
if env["dev_build"]:
common_build_postfix.append("dev_build=yes")
- if env["tests"]:
+ if env["dev_mode"]:
+ common_build_postfix.append("dev_mode=yes")
+
+ elif env["tests"]:
common_build_postfix.append("tests=yes")
if env["custom_modules"]:
common_build_postfix.append("custom_modules=%s" % env["custom_modules"])
+ if env["float"] == "64":
+ common_build_postfix.append("float=64")
+
result = " ^& ".join(common_build_prefix + [" ".join([commands] + common_build_postfix)])
return result
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp
index 46a9b33eb0..fa7e5924f9 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.cpp
+++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp
@@ -437,11 +437,11 @@ String ExtendGDScriptParser::parse_documentation(int p_line, bool p_docs_down) {
if (!p_docs_down) { // inline comment
String inline_comment = lines[p_line];
- int comment_start = inline_comment.find("#");
+ int comment_start = inline_comment.find("##");
if (comment_start != -1) {
inline_comment = inline_comment.substr(comment_start, inline_comment.length()).strip_edges();
if (inline_comment.length() > 1) {
- doc_lines.push_back(inline_comment.substr(1, inline_comment.length()));
+ doc_lines.push_back(inline_comment.substr(2, inline_comment.length()));
}
}
}
@@ -454,8 +454,8 @@ String ExtendGDScriptParser::parse_documentation(int p_line, bool p_docs_down) {
}
String line_comment = lines[i].strip_edges(true, false);
- if (line_comment.begins_with("#")) {
- line_comment = line_comment.substr(1, line_comment.length());
+ if (line_comment.begins_with("##")) {
+ line_comment = line_comment.substr(2, line_comment.length());
if (p_docs_down) {
doc_lines.push_back(line_comment);
} else {
diff --git a/modules/gdscript/tests/scripts/parser/features/dictionary.out b/modules/gdscript/tests/scripts/parser/features/dictionary.out
index 5f999f573a..e1eeb46f78 100644
--- a/modules/gdscript/tests/scripts/parser/features/dictionary.out
+++ b/modules/gdscript/tests/scripts/parser/features/dictionary.out
@@ -7,8 +7,8 @@ null
false
empty array
zero Vector2i
-{22:{4:["nesting", "arrays"]}}
-{4:["nesting", "arrays"]}
+{ 22: { 4: ["nesting", "arrays"] } }
+{ 4: ["nesting", "arrays"] }
["nesting", "arrays"]
nesting
arrays
diff --git a/modules/gdscript/tests/scripts/parser/features/dictionary_lua_style.out b/modules/gdscript/tests/scripts/parser/features/dictionary_lua_style.out
index 5143d040a9..553d40d953 100644
--- a/modules/gdscript/tests/scripts/parser/features/dictionary_lua_style.out
+++ b/modules/gdscript/tests/scripts/parser/features/dictionary_lua_style.out
@@ -1,2 +1,2 @@
GDTEST_OK
-{"a":1, "b":2, "with spaces":3, "2":4}
+{ "a": 1, "b": 2, "with spaces": 3, "2": 4 }
diff --git a/modules/gdscript/tests/scripts/parser/features/dictionary_mixed_syntax.out b/modules/gdscript/tests/scripts/parser/features/dictionary_mixed_syntax.out
index dd28609850..cf79845f53 100644
--- a/modules/gdscript/tests/scripts/parser/features/dictionary_mixed_syntax.out
+++ b/modules/gdscript/tests/scripts/parser/features/dictionary_mixed_syntax.out
@@ -1,2 +1,2 @@
GDTEST_OK
-{"hello":{"world":{"is":"beautiful"}}}
+{ "hello": { "world": { "is": "beautiful" } } }
diff --git a/modules/gdscript/tests/scripts/parser/features/nested_dictionary.out b/modules/gdscript/tests/scripts/parser/features/nested_dictionary.out
index 8b8c33202f..508f0ff217 100644
--- a/modules/gdscript/tests/scripts/parser/features/nested_dictionary.out
+++ b/modules/gdscript/tests/scripts/parser/features/nested_dictionary.out
@@ -1,5 +1,5 @@
GDTEST_OK
-{8:{"key":"value"}}
-{"key":"value"}
+{ 8: { "key": "value" } }
+{ "key": "value" }
value
value
diff --git a/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out b/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out
index 5e7ccf534a..22929bf636 100644
--- a/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out
+++ b/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out
@@ -1,6 +1,6 @@
GDTEST_OK
-{1:(2, 0)}
-{3:(4, 0)}
+{ 1: (2, 0) }
+{ 3: (4, 0) }
[[(5, 0)]]
[[(6, 0)]]
[[(7, 0)]]
diff --git a/modules/gdscript/tests/scripts/runtime/features/stringify.out b/modules/gdscript/tests/scripts/runtime/features/stringify.out
index d4468737a5..1f33de00cc 100644
--- a/modules/gdscript/tests/scripts/runtime/features/stringify.out
+++ b/modules/gdscript/tests/scripts/runtime/features/stringify.out
@@ -21,7 +21,7 @@ hello/world
RID(0)
Node::get_name
Node::[signal]property_list_changed
-{"hello":123}
+{ "hello": 123 }
["hello", 123]
[255, 0, 1]
[-1, 0, 1]
diff --git a/modules/gltf/editor/editor_scene_importer_blend.cpp b/modules/gltf/editor/editor_scene_importer_blend.cpp
index f79731dd22..dcf59bce24 100644
--- a/modules/gltf/editor/editor_scene_importer_blend.cpp
+++ b/modules/gltf/editor/editor_scene_importer_blend.cpp
@@ -77,20 +77,19 @@ Node *EditorSceneFormatImporterBlend::import_scene(const String &p_path, uint32_
} else {
parameters_arg += "export_extras=False,";
}
- if (p_options.has(SNAME("blender/meshes/skins")) && p_options[SNAME("blender/meshes/skins")]) {
+ if (p_options.has(SNAME("blender/meshes/skins"))) {
int32_t skins = p_options["blender/meshes/skins"];
if (skins == BLEND_BONE_INFLUENCES_NONE) {
- parameters_arg += "export_all_influences=False,";
+ parameters_arg += "export_skins=False,";
} else if (skins == BLEND_BONE_INFLUENCES_COMPATIBLE) {
- parameters_arg += "export_all_influences=False,";
+ parameters_arg += "export_all_influences=False,export_skins=True,";
} else if (skins == BLEND_BONE_INFLUENCES_ALL) {
- parameters_arg += "export_all_influences=True,";
+ parameters_arg += "export_all_influences=True,export_skins=True,";
}
- parameters_arg += "export_skins=True,";
} else {
parameters_arg += "export_skins=False,";
}
- if (p_options.has(SNAME("blender/materials/export_materials")) && p_options[SNAME("blender/materials/export_materials")]) {
+ if (p_options.has(SNAME("blender/materials/export_materials"))) {
int32_t exports = p_options["blender/materials/export_materials"];
if (exports == BLEND_MATERIAL_EXPORT_PLACEHOLDER) {
parameters_arg += "export_materials='PLACEHOLDER',";
@@ -115,7 +114,7 @@ Node *EditorSceneFormatImporterBlend::import_scene(const String &p_path, uint32_
} else {
parameters_arg += "export_colors=False,";
}
- if (p_options.has(SNAME("blender/nodes/visible")) && p_options[SNAME("blender/nodes/visible")]) {
+ if (p_options.has(SNAME("blender/nodes/visible"))) {
int32_t visible = p_options["blender/nodes/visible"];
if (visible == BLEND_VISIBLE_VISIBLE_ONLY) {
parameters_arg += "use_visible=True,";
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 95a44d3b7e..d29e0d69ab 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -3326,11 +3326,11 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
} break;
case Variant::PROJECTION: {
- Projection transform = p_val.operator Projection();
- if (transform == Projection()) {
+ Projection projection = p_val.operator Projection();
+ if (projection == Projection()) {
r_iarg.default_argument = "Projection.Identity";
} else {
- r_iarg.default_argument = "new Projection(new Vector4" + transform.matrix[0].operator String() + ", new Vector4" + transform.matrix[1].operator String() + ", new Vector4" + transform.matrix[2].operator String() + ", new Vector4" + transform.matrix[3].operator String() + ")";
+ r_iarg.default_argument = "new Projection(new Vector4" + projection.columns[0].operator String() + ", new Vector4" + projection.columns[1].operator String() + ", new Vector4" + projection.columns[2].operator String() + ", new Vector4" + projection.columns[3].operator String() + ")";
}
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
} break;
diff --git a/modules/openxr/SCsub b/modules/openxr/SCsub
index d4469b110b..5ac167ad98 100644
--- a/modules/openxr/SCsub
+++ b/modules/openxr/SCsub
@@ -92,6 +92,7 @@ if env["vulkan"]:
env_openxr.add_source_files(module_obj, "extensions/openxr_vulkan_extension.cpp")
env_openxr.add_source_files(module_obj, "extensions/openxr_palm_pose_extension.cpp")
+env_openxr.add_source_files(module_obj, "extensions/openxr_composition_layer_depth_extension.cpp")
env_openxr.add_source_files(module_obj, "extensions/openxr_htc_vive_tracker_extension.cpp")
env_openxr.add_source_files(module_obj, "extensions/openxr_hand_tracking_extension.cpp")
env_openxr.add_source_files(module_obj, "extensions/openxr_fb_passthrough_extension_wrapper.cpp")
diff --git a/modules/openxr/extensions/openxr_composition_layer_depth_extension.cpp b/modules/openxr/extensions/openxr_composition_layer_depth_extension.cpp
new file mode 100644
index 0000000000..0f6aaf8afb
--- /dev/null
+++ b/modules/openxr/extensions/openxr_composition_layer_depth_extension.cpp
@@ -0,0 +1,58 @@
+/*************************************************************************/
+/* openxr_composition_layer_depth_extension.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "openxr_composition_layer_depth_extension.h"
+
+OpenXRCompositionLayerDepthExtension *OpenXRCompositionLayerDepthExtension::singleton = nullptr;
+
+OpenXRCompositionLayerDepthExtension *OpenXRCompositionLayerDepthExtension::get_singleton() {
+ return singleton;
+}
+
+OpenXRCompositionLayerDepthExtension::OpenXRCompositionLayerDepthExtension(OpenXRAPI *p_openxr_api) :
+ OpenXRExtensionWrapper(p_openxr_api) {
+ singleton = this;
+
+ request_extensions[XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME] = &available;
+}
+
+OpenXRCompositionLayerDepthExtension::~OpenXRCompositionLayerDepthExtension() {
+ singleton = nullptr;
+}
+
+bool OpenXRCompositionLayerDepthExtension::is_available() {
+ return available;
+}
+
+XrCompositionLayerBaseHeader *OpenXRCompositionLayerDepthExtension::get_composition_layer() {
+ // Seems this is all done in our base layer... Just in case this changes...
+
+ return nullptr;
+}
diff --git a/modules/openxr/extensions/openxr_composition_layer_depth_extension.h b/modules/openxr/extensions/openxr_composition_layer_depth_extension.h
new file mode 100644
index 0000000000..9533783d83
--- /dev/null
+++ b/modules/openxr/extensions/openxr_composition_layer_depth_extension.h
@@ -0,0 +1,53 @@
+/*************************************************************************/
+/* openxr_composition_layer_depth_extension.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef OPENXR_COMPOSITION_LAYER_DEPTH_EXTENSION_H
+#define OPENXR_COMPOSITION_LAYER_DEPTH_EXTENSION_H
+
+#include "openxr_composition_layer_provider.h"
+#include "openxr_extension_wrapper.h"
+
+class OpenXRCompositionLayerDepthExtension : public OpenXRExtensionWrapper, public OpenXRCompositionLayerProvider {
+public:
+ static OpenXRCompositionLayerDepthExtension *get_singleton();
+
+ OpenXRCompositionLayerDepthExtension(OpenXRAPI *p_openxr_api);
+ virtual ~OpenXRCompositionLayerDepthExtension() override;
+
+ bool is_available();
+ virtual XrCompositionLayerBaseHeader *get_composition_layer() override;
+
+private:
+ static OpenXRCompositionLayerDepthExtension *singleton;
+
+ bool available = false;
+};
+
+#endif // OPENXR_COMPOSITION_LAYER_DEPTH_EXTENSION_H
diff --git a/modules/openxr/extensions/openxr_composition_layer_provider.h b/modules/openxr/extensions/openxr_composition_layer_provider.h
index ba51389f7d..a4c4cbe0c6 100644
--- a/modules/openxr/extensions/openxr_composition_layer_provider.h
+++ b/modules/openxr/extensions/openxr_composition_layer_provider.h
@@ -31,6 +31,7 @@
#ifndef OPENXR_COMPOSITION_LAYER_PROVIDER_H
#define OPENXR_COMPOSITION_LAYER_PROVIDER_H
+#include "openxr_extension_wrapper.h"
#include <openxr/openxr.h>
// Interface for OpenXR extensions that provide a composition layer.
diff --git a/modules/openxr/extensions/openxr_extension_wrapper.h b/modules/openxr/extensions/openxr_extension_wrapper.h
index 623c264e6e..c417c90d11 100644
--- a/modules/openxr/extensions/openxr_extension_wrapper.h
+++ b/modules/openxr/extensions/openxr_extension_wrapper.h
@@ -100,11 +100,12 @@ public:
class OpenXRGraphicsExtensionWrapper : public OpenXRExtensionWrapper {
public:
virtual void get_usable_swapchain_formats(Vector<int64_t> &p_usable_swap_chains) = 0;
+ virtual void get_usable_depth_formats(Vector<int64_t> &p_usable_swap_chains) = 0;
virtual String get_swapchain_format_name(int64_t p_swapchain_format) const = 0;
virtual bool get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) = 0;
virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) = 0;
virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) = 0;
- virtual bool copy_render_target_to_image(RID p_from_render_target, void *p_swapchain_graphics_data, int p_image_index) = 0;
+ virtual RID get_texture(void *p_swapchain_graphics_data, int p_image_index) = 0;
OpenXRGraphicsExtensionWrapper(OpenXRAPI *p_openxr_api) :
OpenXRExtensionWrapper(p_openxr_api){};
diff --git a/modules/openxr/extensions/openxr_vulkan_extension.cpp b/modules/openxr/extensions/openxr_vulkan_extension.cpp
index f9e771c934..ee5bda2881 100644
--- a/modules/openxr/extensions/openxr_vulkan_extension.cpp
+++ b/modules/openxr/extensions/openxr_vulkan_extension.cpp
@@ -228,6 +228,12 @@ void OpenXRVulkanExtension::get_usable_swapchain_formats(Vector<int64_t> &p_usab
p_usable_swap_chains.push_back(VK_FORMAT_B8G8R8A8_UINT);
}
+void OpenXRVulkanExtension::get_usable_depth_formats(Vector<int64_t> &p_usable_swap_chains) {
+ p_usable_swap_chains.push_back(VK_FORMAT_R32_SFLOAT);
+ p_usable_swap_chains.push_back(VK_FORMAT_D24_UNORM_S8_UINT);
+ p_usable_swap_chains.push_back(VK_FORMAT_D32_SFLOAT_S8_UINT);
+}
+
bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) {
XrSwapchainImageVulkanKHR *images = nullptr;
@@ -271,7 +277,7 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
RenderingDevice::DataFormat format = RenderingDevice::DATA_FORMAT_R8G8B8A8_SRGB;
RenderingDevice::TextureSamples samples = RenderingDevice::TEXTURE_SAMPLES_1;
- uint64_t usage_flags = RenderingDevice::TEXTURE_USAGE_SAMPLING_BIT | RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ uint64_t usage_flags = RenderingDevice::TEXTURE_USAGE_SAMPLING_BIT;
switch (p_swapchain_format) {
case VK_FORMAT_R8G8B8A8_SRGB:
@@ -283,16 +289,32 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
// will thus do an sRGB -> Linear conversion as expected.
// format = RenderingDevice::DATA_FORMAT_R8G8B8A8_SRGB;
format = RenderingDevice::DATA_FORMAT_R8G8B8A8_UNORM;
+ usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
break;
case VK_FORMAT_B8G8R8A8_SRGB:
// format = RenderingDevice::DATA_FORMAT_B8G8R8A8_SRGB;
format = RenderingDevice::DATA_FORMAT_B8G8R8A8_UNORM;
+ usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
break;
case VK_FORMAT_R8G8B8A8_UINT:
format = RenderingDevice::DATA_FORMAT_R8G8B8A8_UINT;
+ usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
break;
case VK_FORMAT_B8G8R8A8_UINT:
format = RenderingDevice::DATA_FORMAT_B8G8R8A8_UINT;
+ usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ break;
+ case VK_FORMAT_R32_SFLOAT:
+ format = RenderingDevice::DATA_FORMAT_R32_SFLOAT;
+ usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+ break;
+ case VK_FORMAT_D24_UNORM_S8_UINT:
+ format = RenderingDevice::DATA_FORMAT_D24_UNORM_S8_UINT;
+ usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+ break;
+ case VK_FORMAT_D32_SFLOAT_S8_UINT:
+ format = RenderingDevice::DATA_FORMAT_D32_SFLOAT_S8_UINT;
+ usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
break;
default:
// continue with our default value
@@ -328,8 +350,7 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
break;
}
- Vector<RID> image_rids;
- Vector<RID> framebuffers;
+ Vector<RID> texture_rids;
// create Godot texture objects for each entry in our swapchain
for (uint64_t i = 0; i < swapchain_length; i++) {
@@ -344,19 +365,10 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
1,
p_array_size);
- image_rids.push_back(image_rid);
-
- {
- Vector<RID> fb;
- fb.push_back(image_rid);
-
- RID fb_rid = rendering_device->framebuffer_create(fb, RenderingDevice::INVALID_ID, p_array_size);
- framebuffers.push_back(fb_rid);
- }
+ texture_rids.push_back(image_rid);
}
- data->image_rids = image_rids;
- data->framebuffers = framebuffers;
+ data->texture_rids = texture_rids;
memfree(images);
@@ -370,33 +382,19 @@ bool OpenXRVulkanExtension::create_projection_fov(const XrFovf p_fov, double p_z
for (int j = 0; j < 4; j++) {
for (int i = 0; i < 4; i++) {
- r_camera_matrix.matrix[j][i] = matrix.m[j * 4 + i];
+ r_camera_matrix.columns[j][i] = matrix.m[j * 4 + i];
}
}
return true;
}
-bool OpenXRVulkanExtension::copy_render_target_to_image(RID p_from_render_target, void *p_swapchain_graphics_data, int p_image_index) {
+RID OpenXRVulkanExtension::get_texture(void *p_swapchain_graphics_data, int p_image_index) {
SwapchainGraphicsData *data = (SwapchainGraphicsData *)p_swapchain_graphics_data;
- ERR_FAIL_NULL_V(data, false);
- ERR_FAIL_COND_V(p_from_render_target.is_null(), false);
+ ERR_FAIL_NULL_V(data, RID());
- RID source_image = RendererRD::TextureStorage::get_singleton()->render_target_get_rd_texture(p_from_render_target);
- ERR_FAIL_COND_V(source_image.is_null(), false);
-
- RID depth_image; // TODO implement
-
- ERR_FAIL_INDEX_V(p_image_index, data->framebuffers.size(), false);
- RID fb = data->framebuffers[p_image_index];
- ERR_FAIL_COND_V(fb.is_null(), false);
-
- // Our vulkan extension can only be used in conjunction with our vulkan renderer.
- RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
- ERR_FAIL_NULL_V(copy_effects, false);
- copy_effects->copy_to_fb_rect(source_image, fb, Rect2i(), false, false, false, false, depth_image, data->is_multiview);
-
- return true;
+ ERR_FAIL_INDEX_V(p_image_index, data->texture_rids.size(), RID());
+ return data->texture_rids[p_image_index];
}
void OpenXRVulkanExtension::cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) {
@@ -411,17 +409,11 @@ void OpenXRVulkanExtension::cleanup_swapchain_graphics_data(void **p_swapchain_g
RenderingDevice *rendering_device = rendering_server->get_rendering_device();
ERR_FAIL_NULL(rendering_device);
- for (int i = 0; i < data->image_rids.size(); i++) {
- // This should clean up our RIDs and associated texture objects but shouldn't destroy the images, they are owned by our XrSwapchain
- rendering_device->free(data->image_rids[i]);
- }
- data->image_rids.clear();
-
- for (int i = 0; i < data->framebuffers.size(); i++) {
+ for (int i = 0; i < data->texture_rids.size(); i++) {
// This should clean up our RIDs and associated texture objects but shouldn't destroy the images, they are owned by our XrSwapchain
- rendering_device->free(data->framebuffers[i]);
+ rendering_device->free(data->texture_rids[i]);
}
- data->framebuffers.clear();
+ data->texture_rids.clear();
memdelete(data);
*p_swapchain_graphics_data = nullptr;
diff --git a/modules/openxr/extensions/openxr_vulkan_extension.h b/modules/openxr/extensions/openxr_vulkan_extension.h
index d6e9917900..71abe3b166 100644
--- a/modules/openxr/extensions/openxr_vulkan_extension.h
+++ b/modules/openxr/extensions/openxr_vulkan_extension.h
@@ -69,11 +69,12 @@ public:
virtual bool create_vulkan_device(const VkDeviceCreateInfo *p_device_create_info, VkDevice *r_device) override;
virtual void get_usable_swapchain_formats(Vector<int64_t> &p_usable_swap_chains) override;
+ virtual void get_usable_depth_formats(Vector<int64_t> &p_usable_swap_chains) override;
virtual String get_swapchain_format_name(int64_t p_swapchain_format) const override;
virtual bool get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) override;
virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) override;
virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) override;
- virtual bool copy_render_target_to_image(RID p_from_render_target, void *p_swapchain_graphics_data, int p_image_index) override;
+ virtual RID get_texture(void *p_swapchain_graphics_data, int p_image_index) override;
private:
static OpenXRVulkanExtension *singleton;
@@ -81,8 +82,7 @@ private:
struct SwapchainGraphicsData {
bool is_multiview;
- Vector<RID> image_rids;
- Vector<RID> framebuffers;
+ Vector<RID> texture_rids;
};
bool check_graphics_api_support(XrVersion p_desired_version);
diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp
index 16879ac4e5..8a69072793 100644
--- a/modules/openxr/openxr_api.cpp
+++ b/modules/openxr/openxr_api.cpp
@@ -49,6 +49,7 @@
#include "extensions/openxr_vulkan_extension.h"
#endif
+#include "extensions/openxr_composition_layer_depth_extension.h"
#include "extensions/openxr_fb_passthrough_extension_wrapper.h"
#include "extensions/openxr_hand_tracking_extension.h"
#include "extensions/openxr_htc_vive_tracker_extension.h"
@@ -663,7 +664,7 @@ bool OpenXRAPI::is_swapchain_format_supported(int64_t p_swapchain_format) {
return false;
}
-bool OpenXRAPI::create_main_swapchain() {
+bool OpenXRAPI::create_swapchains() {
ERR_FAIL_NULL_V(graphics_extension, false);
ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
@@ -681,34 +682,36 @@ bool OpenXRAPI::create_main_swapchain() {
already rendering the next frame.
Finally an area we need to expand upon is that Foveated rendering is only enabled for the swap chain we create,
- as we render 3D content into internal buffers that are copied into the swapchain, we don't get any of the performance gains
- until such time as we implement VRS.
+ as we render 3D content into internal buffers that are copied into the swapchain, we do now have (basic) VRS support
*/
- // Build a vector with swapchain formats we want to use, from best fit to worst
- Vector<int64_t> usable_swapchain_formats;
- int64_t swapchain_format_to_use = 0;
+ Size2 recommended_size = get_recommended_target_size();
- graphics_extension->get_usable_swapchain_formats(usable_swapchain_formats);
+ // We start with our color swapchain...
+ {
+ // Build a vector with swapchain formats we want to use, from best fit to worst
+ Vector<int64_t> usable_swapchain_formats;
+ int64_t swapchain_format_to_use = 0;
- // now find out which one is supported
- for (int i = 0; i < usable_swapchain_formats.size() && swapchain_format_to_use == 0; i++) {
- if (is_swapchain_format_supported(usable_swapchain_formats[i])) {
- swapchain_format_to_use = usable_swapchain_formats[i];
- }
- }
+ graphics_extension->get_usable_swapchain_formats(usable_swapchain_formats);
- if (swapchain_format_to_use == 0) {
- swapchain_format_to_use = usable_swapchain_formats[0]; // just use the first one and hope for the best...
- print_line("Couldn't find usable swap chain format, using", get_swapchain_format_name(swapchain_format_to_use), "instead.");
- } else {
- print_line("Using swap chain format:", get_swapchain_format_name(swapchain_format_to_use));
- }
+ // now find out which one is supported
+ for (int i = 0; i < usable_swapchain_formats.size() && swapchain_format_to_use == 0; i++) {
+ if (is_swapchain_format_supported(usable_swapchain_formats[i])) {
+ swapchain_format_to_use = usable_swapchain_formats[i];
+ }
+ }
- Size2 recommended_size = get_recommended_target_size();
+ if (swapchain_format_to_use == 0) {
+ swapchain_format_to_use = usable_swapchain_formats[0]; // just use the first one and hope for the best...
+ print_line("Couldn't find usable color swap chain format, using", get_swapchain_format_name(swapchain_format_to_use), "instead.");
+ } else {
+ print_line("Using color swap chain format:", get_swapchain_format_name(swapchain_format_to_use));
+ }
- if (!create_swapchain(swapchain_format_to_use, recommended_size.width, recommended_size.height, view_configuration_views[0].recommendedSwapchainSampleCount, view_count, swapchain, &swapchain_graphics_data)) {
- return false;
+ if (!create_swapchain(XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT, swapchain_format_to_use, recommended_size.width, recommended_size.height, view_configuration_views[0].recommendedSwapchainSampleCount, view_count, swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain, &swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain_graphics_data)) {
+ return false;
+ }
}
views = (XrView *)memalloc(sizeof(XrView) * view_count);
@@ -717,18 +720,73 @@ bool OpenXRAPI::create_main_swapchain() {
projection_views = (XrCompositionLayerProjectionView *)memalloc(sizeof(XrCompositionLayerProjectionView) * view_count);
ERR_FAIL_NULL_V_MSG(projection_views, false, "OpenXR Couldn't allocate memory for projection views");
+ // We create our depth swapchain if:
+ // - we support our depth layer extension
+ // - we have our spacewarp extension (not yet implemented)
+ if (OpenXRCompositionLayerDepthExtension::get_singleton()->is_available()) {
+ // Build a vector with swapchain formats we want to use, from best fit to worst
+ Vector<int64_t> usable_swapchain_formats;
+ int64_t swapchain_format_to_use = 0;
+
+ graphics_extension->get_usable_depth_formats(usable_swapchain_formats);
+
+ // now find out which one is supported
+ for (int i = 0; i < usable_swapchain_formats.size() && swapchain_format_to_use == 0; i++) {
+ if (is_swapchain_format_supported(usable_swapchain_formats[i])) {
+ swapchain_format_to_use = usable_swapchain_formats[i];
+ }
+ }
+
+ if (swapchain_format_to_use == 0) {
+ swapchain_format_to_use = usable_swapchain_formats[0]; // just use the first one and hope for the best...
+ print_line("Couldn't find usable depth swap chain format, using", get_swapchain_format_name(swapchain_format_to_use), "instead.");
+ } else {
+ print_line("Using depth swap chain format:", get_swapchain_format_name(swapchain_format_to_use));
+ }
+
+ if (!create_swapchain(XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, swapchain_format_to_use, recommended_size.width, recommended_size.height, view_configuration_views[0].recommendedSwapchainSampleCount, view_count, swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain, &swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain_graphics_data)) {
+ return false;
+ }
+
+ depth_views = (XrCompositionLayerDepthInfoKHR *)memalloc(sizeof(XrCompositionLayerDepthInfoKHR) * view_count);
+ ERR_FAIL_NULL_V_MSG(depth_views, false, "OpenXR Couldn't allocate memory for depth views");
+ }
+
+ // We create our velocity swapchain if:
+ // - we have our spacewarp extension (not yet implemented)
+ {
+ // TBD
+ }
+
for (uint32_t i = 0; i < view_count; i++) {
views[i].type = XR_TYPE_VIEW;
views[i].next = nullptr;
projection_views[i].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
projection_views[i].next = nullptr;
- projection_views[i].subImage.swapchain = swapchain;
+ projection_views[i].subImage.swapchain = swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain;
projection_views[i].subImage.imageArrayIndex = i;
projection_views[i].subImage.imageRect.offset.x = 0;
projection_views[i].subImage.imageRect.offset.y = 0;
projection_views[i].subImage.imageRect.extent.width = recommended_size.width;
projection_views[i].subImage.imageRect.extent.height = recommended_size.height;
+
+ if (OpenXRCompositionLayerDepthExtension::get_singleton()->is_available() && depth_views) {
+ projection_views[i].next = &depth_views[i];
+
+ depth_views[i].type = XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR;
+ depth_views[i].next = nullptr;
+ depth_views[i].subImage.swapchain = swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain;
+ depth_views[i].subImage.imageArrayIndex = 0;
+ depth_views[i].subImage.imageRect.offset.x = 0;
+ depth_views[i].subImage.imageRect.offset.y = 0;
+ depth_views[i].subImage.imageRect.extent.width = recommended_size.width;
+ depth_views[i].subImage.imageRect.extent.height = recommended_size.height;
+ depth_views[i].minDepth = 0.0;
+ depth_views[i].maxDepth = 1.0;
+ depth_views[i].nearZ = 0.01; // Near and far Z will be set to the correct values in fill_projection_matrix
+ depth_views[i].farZ = 100.0;
+ }
};
return true;
@@ -740,7 +798,7 @@ void OpenXRAPI::destroy_session() {
}
if (graphics_extension) {
- graphics_extension->cleanup_swapchain_graphics_data(&swapchain_graphics_data);
+ graphics_extension->cleanup_swapchain_graphics_data(&swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain_graphics_data);
}
if (views != nullptr) {
@@ -753,9 +811,16 @@ void OpenXRAPI::destroy_session() {
projection_views = nullptr;
}
- if (swapchain != XR_NULL_HANDLE) {
- xrDestroySwapchain(swapchain);
- swapchain = XR_NULL_HANDLE;
+ if (depth_views != nullptr) {
+ memfree(depth_views);
+ depth_views = nullptr;
+ }
+
+ for (int i = 0; i < OPENXR_SWAPCHAIN_MAX; i++) {
+ if (swapchains[i].swapchain != XR_NULL_HANDLE) {
+ xrDestroySwapchain(swapchains[i].swapchain);
+ swapchains[i].swapchain = XR_NULL_HANDLE;
+ }
}
if (supported_swapchain_formats != nullptr) {
@@ -789,7 +854,7 @@ void OpenXRAPI::destroy_session() {
}
}
-bool OpenXRAPI::create_swapchain(int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, XrSwapchain &r_swapchain, void **r_swapchain_graphics_data) {
+bool OpenXRAPI::create_swapchain(XrSwapchainUsageFlags p_usage_flags, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, XrSwapchain &r_swapchain, void **r_swapchain_graphics_data) {
ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
ERR_FAIL_NULL_V(graphics_extension, false);
@@ -807,7 +872,7 @@ bool OpenXRAPI::create_swapchain(int64_t p_swapchain_format, uint32_t p_width, u
XR_TYPE_SWAPCHAIN_CREATE_INFO, // type
next_pointer, // next
0, // createFlags
- XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT, // usageFlags
+ p_usage_flags, // usageFlags
p_swapchain_format, // format
p_sample_count, // sampleCount
p_width, // width
@@ -871,7 +936,7 @@ bool OpenXRAPI::on_state_ready() {
// That will be very very ugly
// The other possibility is to create a separate OpenXRViewport type specifically for this goal as part of our OpenXR module
- if (!create_main_swapchain()) {
+ if (!create_swapchains()) {
return false;
}
@@ -1304,6 +1369,15 @@ bool OpenXRAPI::get_view_projection(uint32_t p_view, double p_z_near, double p_z
return false;
}
+ // if we're using depth views, make sure we update our near and far there...
+ if (depth_views != nullptr) {
+ for (uint32_t i = 0; i < view_count; i++) {
+ depth_views[i].nearZ = p_z_near;
+ depth_views[i].farZ = p_z_far;
+ }
+ }
+
+ // now update our projection
return graphics_extension->create_projection_fov(views[p_view].fov, p_z_near, p_z_far, p_camera_matrix);
}
@@ -1442,15 +1516,15 @@ bool OpenXRAPI::process() {
return true;
}
-bool OpenXRAPI::acquire_image(XrSwapchain p_swapchain, uint32_t &r_image_index) {
- ERR_FAIL_COND_V(image_acquired, true); // this was not released when it should be, error out and re-use...
+bool OpenXRAPI::acquire_image(OpenXRSwapChainInfo &p_swapchain) {
+ ERR_FAIL_COND_V(p_swapchain.image_acquired, true); // this was not released when it should be, error out and re-use...
XrResult result;
XrSwapchainImageAcquireInfo swapchain_image_acquire_info = {
XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO, // type
nullptr // next
};
- result = xrAcquireSwapchainImage(p_swapchain, &swapchain_image_acquire_info, &r_image_index);
+ result = xrAcquireSwapchainImage(p_swapchain.swapchain, &swapchain_image_acquire_info, &p_swapchain.image_index);
if (XR_FAILED(result)) {
print_line("OpenXR: failed to acquire swapchain image [", get_error_string(result), "]");
return false;
@@ -1462,7 +1536,7 @@ bool OpenXRAPI::acquire_image(XrSwapchain p_swapchain, uint32_t &r_image_index)
17000000 // timeout in nanoseconds
};
- result = xrWaitSwapchainImage(p_swapchain, &swapchain_image_wait_info);
+ result = xrWaitSwapchainImage(p_swapchain.swapchain, &swapchain_image_wait_info);
if (XR_FAILED(result)) {
print_line("OpenXR: failed to wait for swapchain image [", get_error_string(result), "]");
return false;
@@ -1471,12 +1545,12 @@ bool OpenXRAPI::acquire_image(XrSwapchain p_swapchain, uint32_t &r_image_index)
return true;
}
-bool OpenXRAPI::release_image(XrSwapchain p_swapchain) {
+bool OpenXRAPI::release_image(OpenXRSwapChainInfo &p_swapchain) {
XrSwapchainImageReleaseInfo swapchain_image_release_info = {
XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO, // type
nullptr // next
};
- XrResult result = xrReleaseSwapchainImage(swapchain, &swapchain_image_release_info);
+ XrResult result = xrReleaseSwapchainImage(p_swapchain.swapchain, &swapchain_image_release_info);
if (XR_FAILED(result)) {
print_line("OpenXR: failed to release swapchain image! [", get_error_string(result), "]");
return false;
@@ -1590,28 +1664,41 @@ bool OpenXRAPI::pre_draw_viewport(RID p_render_target) {
// TODO: at some point in time we may support multiple viewports in which case we need to handle that...
+ // Acquire our images
+ for (int i = 0; i < OPENXR_SWAPCHAIN_MAX; i++) {
+ if (!swapchains[i].image_acquired && swapchains[i].swapchain != XR_NULL_HANDLE) {
+ if (!acquire_image(swapchains[i])) {
+ return false;
+ }
+ swapchains[i].image_acquired = true;
+ }
+ }
+
return true;
}
+RID OpenXRAPI::get_color_texture() {
+ if (swapchains[OPENXR_SWAPCHAIN_COLOR].image_acquired) {
+ return graphics_extension->get_texture(swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain_graphics_data, swapchains[OPENXR_SWAPCHAIN_COLOR].image_index);
+ } else {
+ return RID();
+ }
+}
+
+RID OpenXRAPI::get_depth_texture() {
+ if (swapchains[OPENXR_SWAPCHAIN_DEPTH].image_acquired) {
+ return graphics_extension->get_texture(swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain_graphics_data, swapchains[OPENXR_SWAPCHAIN_DEPTH].image_index);
+ } else {
+ return RID();
+ }
+}
+
void OpenXRAPI::post_draw_viewport(RID p_render_target) {
if (!can_render()) {
return;
}
- // TODO: at some point in time we may support multiple viewports in which case we need to handle that...
-
- // TODO: if we can get PR 51179 to work properly we can change away from this approach and move this into get_external_texture or something
- if (!image_acquired) {
- if (!acquire_image(swapchain, image_index)) {
- return;
- }
- image_acquired = true;
-
- // print_line("OpenXR: acquired image " + itos(image_index) + ", copying...");
-
- // Copy our buffer into our swap chain (remove once PR 51179 is done)
- graphics_extension->copy_render_target_to_image(p_render_target, swapchain_graphics_data, image_index);
- }
+ // Nothing to do here at this point in time...
};
void OpenXRAPI::end_frame() {
@@ -1623,7 +1710,7 @@ void OpenXRAPI::end_frame() {
return;
}
- if (frame_state.shouldRender && view_pose_valid && !image_acquired) {
+ if (frame_state.shouldRender && view_pose_valid && !swapchains[OPENXR_SWAPCHAIN_COLOR].image_acquired) {
print_line("OpenXR: No viewport was marked with use_xr, there is no rendered output!");
}
@@ -1631,7 +1718,7 @@ void OpenXRAPI::end_frame() {
// - shouldRender set to true
// - a valid view pose for projection_views[eye].pose to submit layer
// - an image to render
- if (!frame_state.shouldRender || !view_pose_valid || !image_acquired) {
+ if (!frame_state.shouldRender || !view_pose_valid || !swapchains[OPENXR_SWAPCHAIN_COLOR].image_acquired) {
// submit 0 layers when we shouldn't render
XrFrameEndInfo frame_end_info = {
XR_TYPE_FRAME_END_INFO, // type
@@ -1652,10 +1739,12 @@ void OpenXRAPI::end_frame() {
}
// release our swapchain image if we acquired it
- if (image_acquired) {
- image_acquired = false; // whether we succeed or not, consider this released.
+ for (int i = 0; i < OPENXR_SWAPCHAIN_MAX; i++) {
+ if (swapchains[i].image_acquired) {
+ swapchains[i].image_acquired = false; // whether we succeed or not, consider this released.
- release_image(swapchain);
+ release_image(swapchains[i]);
+ }
}
for (uint32_t eye = 0; eye < view_count; eye++) {
@@ -1763,6 +1852,7 @@ OpenXRAPI::OpenXRAPI() {
// register our other extensions
register_extension_wrapper(memnew(OpenXRPalmPoseExtension(this)));
+ register_extension_wrapper(memnew(OpenXRCompositionLayerDepthExtension(this)));
register_extension_wrapper(memnew(OpenXRHTCViveTrackerExtension(this)));
register_extension_wrapper(memnew(OpenXRHandTrackingExtension(this)));
register_extension_wrapper(memnew(OpenXRFbPassthroughExtensionWrapper(this)));
diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h
index 316886239e..bd69432dcb 100644
--- a/modules/openxr/openxr_api.h
+++ b/modules/openxr/openxr_api.h
@@ -120,15 +120,28 @@ private:
OpenXRGraphicsExtensionWrapper *graphics_extension = nullptr;
XrSystemGraphicsProperties graphics_properties;
- void *swapchain_graphics_data = nullptr;
- uint32_t image_index = 0;
- bool image_acquired = false;
uint32_t view_count = 0;
XrViewConfigurationView *view_configuration_views = nullptr;
XrView *views = nullptr;
XrCompositionLayerProjectionView *projection_views = nullptr;
- XrSwapchain swapchain = XR_NULL_HANDLE;
+ XrCompositionLayerDepthInfoKHR *depth_views = nullptr; // Only used by Composition Layer Depth Extension if available
+
+ enum OpenXRSwapChainTypes {
+ OPENXR_SWAPCHAIN_COLOR,
+ OPENXR_SWAPCHAIN_DEPTH,
+ // OPENXR_SWAPCHAIN_VELOCITY,
+ OPENXR_SWAPCHAIN_MAX
+ };
+
+ struct OpenXRSwapChainInfo {
+ XrSwapchain swapchain = XR_NULL_HANDLE;
+ void *swapchain_graphics_data = nullptr;
+ uint32_t image_index = 0;
+ bool image_acquired = false;
+ };
+
+ OpenXRSwapChainInfo swapchains[OPENXR_SWAPCHAIN_MAX];
XrSpace play_space = XR_NULL_HANDLE;
XrSpace view_space = XR_NULL_HANDLE;
@@ -212,13 +225,13 @@ private:
bool setup_spaces();
bool load_supported_swapchain_formats();
bool is_swapchain_format_supported(int64_t p_swapchain_format);
- bool create_main_swapchain();
+ bool create_swapchains();
void destroy_session();
// swapchains
- bool create_swapchain(int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, XrSwapchain &r_swapchain, void **r_swapchain_graphics_data);
- bool acquire_image(XrSwapchain p_swapchain, uint32_t &r_image_index);
- bool release_image(XrSwapchain p_swapchain);
+ bool create_swapchain(XrSwapchainUsageFlags p_usage_flags, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, XrSwapchain &r_swapchain, void **r_swapchain_graphics_data);
+ bool acquire_image(OpenXRSwapChainInfo &p_swapchain);
+ bool release_image(OpenXRSwapChainInfo &p_swapchain);
// action map
struct Tracker { // Trackers represent tracked physical objects such as controllers, pucks, etc.
@@ -318,6 +331,8 @@ public:
void pre_render();
bool pre_draw_viewport(RID p_render_target);
+ RID get_color_texture();
+ RID get_depth_texture();
void post_draw_viewport(RID p_render_target);
void end_frame();
diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp
index 01e148e00f..31dc2bbf43 100644
--- a/modules/openxr/openxr_interface.cpp
+++ b/modules/openxr/openxr_interface.cpp
@@ -648,6 +648,22 @@ Projection OpenXRInterface::get_projection_for_view(uint32_t p_view, double p_as
return cm;
}
+RID OpenXRInterface::get_color_texture() {
+ if (openxr_api) {
+ return openxr_api->get_color_texture();
+ } else {
+ return RID();
+ }
+}
+
+RID OpenXRInterface::get_depth_texture() {
+ if (openxr_api) {
+ return openxr_api->get_depth_texture();
+ } else {
+ return RID();
+ }
+}
+
void OpenXRInterface::process() {
if (openxr_api) {
// do our normal process
@@ -707,6 +723,7 @@ bool OpenXRInterface::pre_draw_viewport(RID p_render_target) {
Vector<BlitToScreen> OpenXRInterface::post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) {
Vector<BlitToScreen> blit_to_screen;
+#ifndef ANDROID_ENABLED
// If separate HMD we should output one eye to screen
if (p_screen_rect != Rect2()) {
BlitToScreen blit;
@@ -732,6 +749,7 @@ Vector<BlitToScreen> OpenXRInterface::post_draw_viewport(RID p_render_target, co
blit.dst_rect = dst_rect;
blit_to_screen.push_back(blit);
}
+#endif
if (openxr_api) {
openxr_api->post_draw_viewport(p_render_target);
diff --git a/modules/openxr/openxr_interface.h b/modules/openxr/openxr_interface.h
index 3765f18637..72935b039c 100644
--- a/modules/openxr/openxr_interface.h
+++ b/modules/openxr/openxr_interface.h
@@ -126,6 +126,9 @@ public:
virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override;
virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override;
+ virtual RID get_color_texture() override;
+ virtual RID get_depth_texture() override;
+
virtual void process() override;
virtual void pre_render() override;
bool pre_draw_viewport(RID p_render_target) override;
diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp
index d0c7484aa1..6b671c1660 100644
--- a/modules/webxr/webxr_interface_js.cpp
+++ b/modules/webxr/webxr_interface_js.cpp
@@ -388,15 +388,15 @@ Projection WebXRInterfaceJS::get_projection_for_view(uint32_t p_view, double p_a
int k = 0;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- eye.matrix[i][j] = js_matrix[k++];
+ eye.columns[i][j] = js_matrix[k++];
}
}
free(js_matrix);
// Copied from godot_oculus_mobile's ovr_mobile_session.cpp
- eye.matrix[2][2] = -(p_z_far + p_z_near) / (p_z_far - p_z_near);
- eye.matrix[3][2] = -(2.0f * p_z_far * p_z_near) / (p_z_far - p_z_near);
+ eye.columns[2][2] = -(p_z_far + p_z_near) / (p_z_far - p_z_near);
+ eye.columns[3][2] = -(2.0f * p_z_far * p_z_near) / (p_z_far - p_z_near);
return eye;
}
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index dfde0d249c..86ae1f2d9c 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -363,8 +363,10 @@ def configure(env: "Environment"):
if platform.system() == "Linux":
env.Append(LIBS=["dl"])
- if platform.system().find("BSD") >= 0:
- env["execinfo"] = True
+ if not env["execinfo"] and platform.libc_ver()[0] != "glibc":
+ # The default crash handler depends on glibc, so if the host uses
+ # a different libc (BSD libc, musl), fall back to libexecinfo.
+ print("Note: Using `execinfo=yes` for the crash handler as required on platforms where glibc is missing.")
if env["execinfo"]:
env.Append(LIBS=["execinfo"])
diff --git a/platform/web/package-lock.json b/platform/web/package-lock.json
index f8c67b206f..9a7d871c64 100644
--- a/platform/web/package-lock.json
+++ b/platform/web/package-lock.json
@@ -12,8 +12,7 @@
"eslint": "^7.28.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.23.4",
- "jsdoc": "^3.6.7",
- "serve": "^13.0.2"
+ "jsdoc": "^3.6.7"
}
},
"node_modules/@babel/code-frame": {
@@ -131,25 +130,6 @@
"integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
"dev": true
},
- "node_modules/@zeit/schemas": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz",
- "integrity": "sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg==",
- "dev": true
- },
- "node_modules/accepts": {
- "version": "1.3.7",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
- "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
- "dev": true,
- "dependencies": {
- "mime-types": "~2.1.24",
- "negotiator": "0.6.2"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/acorn": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
@@ -187,15 +167,6 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
- "node_modules/ansi-align": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
- "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==",
- "dev": true,
- "dependencies": {
- "string-width": "^4.1.0"
- }
- },
"node_modules/ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
@@ -226,32 +197,6 @@
"node": ">=4"
}
},
- "node_modules/arch": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz",
- "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
- "node_modules/arg": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/arg/-/arg-2.0.0.tgz",
- "integrity": "sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==",
- "dev": true
- },
"node_modules/argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -318,28 +263,6 @@
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
"dev": true
},
- "node_modules/boxen": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz",
- "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==",
- "dev": true,
- "dependencies": {
- "ansi-align": "^3.0.0",
- "camelcase": "^6.2.0",
- "chalk": "^4.1.0",
- "cli-boxes": "^2.2.1",
- "string-width": "^4.2.2",
- "type-fest": "^0.20.2",
- "widest-line": "^3.1.0",
- "wrap-ansi": "^7.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -350,15 +273,6 @@
"concat-map": "0.0.1"
}
},
- "node_modules/bytes": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
- "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
- "dev": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
@@ -381,18 +295,6 @@
"node": ">=6"
}
},
- "node_modules/camelcase": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/catharsis": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz",
@@ -475,32 +377,6 @@
"node": ">=8"
}
},
- "node_modules/cli-boxes": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
- "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==",
- "dev": true,
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/clipboardy": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz",
- "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==",
- "dev": true,
- "dependencies": {
- "arch": "^2.1.1",
- "execa": "^1.0.0",
- "is-wsl": "^2.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -516,51 +392,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
- "node_modules/compressible": {
- "version": "2.0.18",
- "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
- "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
- "dev": true,
- "dependencies": {
- "mime-db": ">= 1.43.0 < 2"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/compression": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz",
- "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==",
- "dev": true,
- "dependencies": {
- "accepts": "~1.3.5",
- "bytes": "3.0.0",
- "compressible": "~2.0.14",
- "debug": "2.6.9",
- "on-headers": "~1.0.1",
- "safe-buffer": "5.1.2",
- "vary": "~1.1.2"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/compression/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/compression/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
- "dev": true
- },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -573,15 +404,6 @@
"integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==",
"dev": true
},
- "node_modules/content-disposition": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
- "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=",
- "dev": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -613,15 +435,6 @@
}
}
},
- "node_modules/deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
- "dev": true,
- "engines": {
- "node": ">=4.0.0"
- }
- },
"node_modules/deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
@@ -658,15 +471,6 @@
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
- "node_modules/end-of-stream": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "dev": true,
- "dependencies": {
- "once": "^1.4.0"
- }
- },
"node_modules/enquirer": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
@@ -1075,91 +879,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/execa": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
- "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
- "dev": true,
- "dependencies": {
- "cross-spawn": "^6.0.0",
- "get-stream": "^4.0.0",
- "is-stream": "^1.1.0",
- "npm-run-path": "^2.0.0",
- "p-finally": "^1.0.0",
- "signal-exit": "^3.0.0",
- "strip-eof": "^1.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/execa/node_modules/cross-spawn": {
- "version": "6.0.5",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
- "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
- "dev": true,
- "dependencies": {
- "nice-try": "^1.0.4",
- "path-key": "^2.0.1",
- "semver": "^5.5.0",
- "shebang-command": "^1.2.0",
- "which": "^1.2.9"
- },
- "engines": {
- "node": ">=4.8"
- }
- },
- "node_modules/execa/node_modules/path-key": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
- "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/execa/node_modules/semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
- "dev": true,
- "bin": {
- "semver": "bin/semver"
- }
- },
- "node_modules/execa/node_modules/shebang-command": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
- "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
- "dev": true,
- "dependencies": {
- "shebang-regex": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/execa/node_modules/shebang-regex": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
- "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/execa/node_modules/which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
- "dev": true,
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "which": "bin/which"
- }
- },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -1178,21 +897,6 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
- "node_modules/fast-url-parser": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz",
- "integrity": "sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=",
- "dev": true,
- "dependencies": {
- "punycode": "^1.3.2"
- }
- },
- "node_modules/fast-url-parser/node_modules/punycode": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
- "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
- "dev": true
- },
"node_modules/file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@@ -1268,18 +972,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/get-stream": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
- "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
- "dev": true,
- "dependencies": {
- "pump": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/glob": {
"version": "7.1.7",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
@@ -1431,12 +1123,6 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
- "node_modules/ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
- "dev": true
- },
"node_modules/is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
@@ -1503,21 +1189,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-docker": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
- "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
- "dev": true,
- "bin": {
- "is-docker": "cli.js"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -1588,15 +1259,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/is-string": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz",
@@ -1624,18 +1286,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-wsl": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
- "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
- "dev": true,
- "dependencies": {
- "is-docker": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -1883,27 +1533,6 @@
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
"dev": true
},
- "node_modules/mime-db": {
- "version": "1.51.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
- "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
- "dev": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "2.1.34",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
- "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
- "dev": true,
- "dependencies": {
- "mime-db": "1.51.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@@ -1946,21 +1575,6 @@
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
- "node_modules/negotiator": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
- "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
- "dev": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/nice-try": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
- "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
- "dev": true
- },
"node_modules/normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
@@ -1982,27 +1596,6 @@
"semver": "bin/semver"
}
},
- "node_modules/npm-run-path": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
- "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
- "dev": true,
- "dependencies": {
- "path-key": "^2.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/npm-run-path/node_modules/path-key": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
- "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/object-inspect": {
"version": "1.10.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
@@ -2070,15 +1663,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/on-headers": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
- "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
- "dev": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -2105,15 +1689,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/p-finally": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
- "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/p-limit": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
@@ -2190,12 +1765,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/path-is-inside": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
- "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
- "dev": true
- },
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -2211,12 +1780,6 @@
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
- "node_modules/path-to-regexp": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz",
- "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==",
- "dev": true
- },
"node_modules/path-type": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
@@ -2280,16 +1843,6 @@
"node": ">=0.4.0"
}
},
- "node_modules/pump": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dev": true,
- "dependencies": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
"node_modules/punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
@@ -2299,39 +1852,6 @@
"node": ">=6"
}
},
- "node_modules/range-parser": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
- "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
- "dev": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/rc": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
- "dev": true,
- "dependencies": {
- "deep-extend": "^0.6.0",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- },
- "bin": {
- "rc": "cli.js"
- }
- },
- "node_modules/rc/node_modules/strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@@ -2371,28 +1891,6 @@
"url": "https://github.com/sponsors/mysticatea"
}
},
- "node_modules/registry-auth-token": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz",
- "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==",
- "dev": true,
- "dependencies": {
- "rc": "^1.1.6",
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/registry-url": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
- "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
- "dev": true,
- "dependencies": {
- "rc": "^1.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
@@ -2448,12 +1946,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
"node_modules/semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
@@ -2469,86 +1961,6 @@
"node": ">=10"
}
},
- "node_modules/serve": {
- "version": "13.0.2",
- "resolved": "https://registry.npmjs.org/serve/-/serve-13.0.2.tgz",
- "integrity": "sha512-71R6fKvNgKrqARAag6lYJNnxDzpH7DCNrMuvPY5PLVaC2PDhJsGTj/34o4o4tPWhTuLgEXqvgnAWbATQ9zGZTQ==",
- "dev": true,
- "dependencies": {
- "@zeit/schemas": "2.6.0",
- "ajv": "6.12.6",
- "arg": "2.0.0",
- "boxen": "5.1.2",
- "chalk": "2.4.1",
- "clipboardy": "2.3.0",
- "compression": "1.7.3",
- "serve-handler": "6.1.3",
- "update-check": "1.5.2"
- },
- "bin": {
- "serve": "bin/serve.js"
- }
- },
- "node_modules/serve-handler": {
- "version": "6.1.3",
- "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.3.tgz",
- "integrity": "sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==",
- "dev": true,
- "dependencies": {
- "bytes": "3.0.0",
- "content-disposition": "0.5.2",
- "fast-url-parser": "1.1.3",
- "mime-types": "2.1.18",
- "minimatch": "3.0.4",
- "path-is-inside": "1.0.2",
- "path-to-regexp": "2.2.1",
- "range-parser": "1.2.0"
- }
- },
- "node_modules/serve-handler/node_modules/mime-db": {
- "version": "1.33.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
- "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
- "dev": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/serve-handler/node_modules/mime-types": {
- "version": "2.1.18",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
- "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
- "dev": true,
- "dependencies": {
- "mime-db": "~1.33.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/serve/node_modules/chalk": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
- "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/serve/node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
- "dev": true,
- "engines": {
- "node": ">=0.8.0"
- }
- },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -2570,12 +1982,6 @@
"node": ">=8"
}
},
- "node_modules/signal-exit": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz",
- "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==",
- "dev": true
- },
"node_modules/slice-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
@@ -2725,15 +2131,6 @@
"node": ">=4"
}
},
- "node_modules/strip-eof": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
- "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -2872,16 +2269,6 @@
"integrity": "sha512-QvjkYpiD+dJJraRA8+dGAU4i7aBbb2s0S3jA45TFOvg2VgqvdCDd/3N6CqA8gluk1W91GLoXg5enMUx560QzuA==",
"dev": true
},
- "node_modules/update-check": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.2.tgz",
- "integrity": "sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==",
- "dev": true,
- "dependencies": {
- "registry-auth-token": "3.3.2",
- "registry-url": "3.1.0"
- }
- },
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -2907,15 +2294,6 @@
"spdx-expression-parse": "^3.0.0"
}
},
- "node_modules/vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
- "dev": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -2947,18 +2325,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/widest-line": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
- "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
- "dev": true,
- "dependencies": {
- "string-width": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
@@ -2968,56 +2334,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/wrap-ansi/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/wrap-ansi/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/wrap-ansi/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@@ -3134,22 +2450,6 @@
"integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
"dev": true
},
- "@zeit/schemas": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz",
- "integrity": "sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg==",
- "dev": true
- },
- "accepts": {
- "version": "1.3.7",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
- "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
- "dev": true,
- "requires": {
- "mime-types": "~2.1.24",
- "negotiator": "0.6.2"
- }
- },
"acorn": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
@@ -3175,15 +2475,6 @@
"uri-js": "^4.2.2"
}
},
- "ansi-align": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
- "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==",
- "dev": true,
- "requires": {
- "string-width": "^4.1.0"
- }
- },
"ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
@@ -3205,18 +2496,6 @@
"color-convert": "^1.9.0"
}
},
- "arch": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz",
- "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==",
- "dev": true
- },
- "arg": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/arg/-/arg-2.0.0.tgz",
- "integrity": "sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==",
- "dev": true
- },
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -3268,22 +2547,6 @@
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
"dev": true
},
- "boxen": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz",
- "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==",
- "dev": true,
- "requires": {
- "ansi-align": "^3.0.0",
- "camelcase": "^6.2.0",
- "chalk": "^4.1.0",
- "cli-boxes": "^2.2.1",
- "string-width": "^4.2.2",
- "type-fest": "^0.20.2",
- "widest-line": "^3.1.0",
- "wrap-ansi": "^7.0.0"
- }
- },
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -3294,12 +2557,6 @@
"concat-map": "0.0.1"
}
},
- "bytes": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
- "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
- "dev": true
- },
"call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
@@ -3316,12 +2573,6 @@
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true
},
- "camelcase": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
- "dev": true
- },
"catharsis": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz",
@@ -3382,23 +2633,6 @@
}
}
},
- "cli-boxes": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
- "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==",
- "dev": true
- },
- "clipboardy": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz",
- "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==",
- "dev": true,
- "requires": {
- "arch": "^2.1.1",
- "execa": "^1.0.0",
- "is-wsl": "^2.1.1"
- }
- },
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -3414,47 +2648,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
- "compressible": {
- "version": "2.0.18",
- "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
- "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
- "dev": true,
- "requires": {
- "mime-db": ">= 1.43.0 < 2"
- }
- },
- "compression": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz",
- "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==",
- "dev": true,
- "requires": {
- "accepts": "~1.3.5",
- "bytes": "3.0.0",
- "compressible": "~2.0.14",
- "debug": "2.6.9",
- "on-headers": "~1.0.1",
- "safe-buffer": "5.1.2",
- "vary": "~1.1.2"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
- "dev": true
- }
- }
- },
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -3467,12 +2660,6 @@
"integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==",
"dev": true
},
- "content-disposition": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
- "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=",
- "dev": true
- },
"cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -3493,12 +2680,6 @@
"ms": "2.1.2"
}
},
- "deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
- "dev": true
- },
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
@@ -3529,15 +2710,6 @@
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
- "end-of-stream": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "dev": true,
- "requires": {
- "once": "^1.4.0"
- }
- },
"enquirer": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
@@ -3862,72 +3034,6 @@
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true
},
- "execa": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
- "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
- "dev": true,
- "requires": {
- "cross-spawn": "^6.0.0",
- "get-stream": "^4.0.0",
- "is-stream": "^1.1.0",
- "npm-run-path": "^2.0.0",
- "p-finally": "^1.0.0",
- "signal-exit": "^3.0.0",
- "strip-eof": "^1.0.0"
- },
- "dependencies": {
- "cross-spawn": {
- "version": "6.0.5",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
- "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
- "dev": true,
- "requires": {
- "nice-try": "^1.0.4",
- "path-key": "^2.0.1",
- "semver": "^5.5.0",
- "shebang-command": "^1.2.0",
- "which": "^1.2.9"
- }
- },
- "path-key": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
- "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
- "dev": true
- },
- "semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
- "dev": true
- },
- "shebang-command": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
- "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
- "dev": true,
- "requires": {
- "shebang-regex": "^1.0.0"
- }
- },
- "shebang-regex": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
- "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
- "dev": true
- },
- "which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
- "dev": true,
- "requires": {
- "isexe": "^2.0.0"
- }
- }
- }
- },
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -3946,23 +3052,6 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
- "fast-url-parser": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz",
- "integrity": "sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=",
- "dev": true,
- "requires": {
- "punycode": "^1.3.2"
- },
- "dependencies": {
- "punycode": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
- "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
- "dev": true
- }
- }
- },
"file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@@ -4026,15 +3115,6 @@
"has-symbols": "^1.0.1"
}
},
- "get-stream": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
- "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
- "dev": true,
- "requires": {
- "pump": "^3.0.0"
- }
- },
"glob": {
"version": "7.1.7",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
@@ -4144,12 +3224,6 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
- "ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
- "dev": true
- },
"is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
@@ -4192,12 +3266,6 @@
"integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==",
"dev": true
},
- "is-docker": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
- "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
- "dev": true
- },
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -4241,12 +3309,6 @@
"has-symbols": "^1.0.2"
}
},
- "is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
- "dev": true
- },
"is-string": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz",
@@ -4262,15 +3324,6 @@
"has-symbols": "^1.0.2"
}
},
- "is-wsl": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
- "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
- "dev": true,
- "requires": {
- "is-docker": "^2.0.0"
- }
- },
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -4480,21 +3533,6 @@
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
"dev": true
},
- "mime-db": {
- "version": "1.51.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
- "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
- "dev": true
- },
- "mime-types": {
- "version": "2.1.34",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
- "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
- "dev": true,
- "requires": {
- "mime-db": "1.51.0"
- }
- },
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@@ -4528,18 +3566,6 @@
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
- "negotiator": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
- "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
- "dev": true
- },
- "nice-try": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
- "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
- "dev": true
- },
"normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
@@ -4560,23 +3586,6 @@
}
}
},
- "npm-run-path": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
- "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
- "dev": true,
- "requires": {
- "path-key": "^2.0.0"
- },
- "dependencies": {
- "path-key": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
- "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
- "dev": true
- }
- }
- },
"object-inspect": {
"version": "1.10.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
@@ -4623,12 +3632,6 @@
"es-abstract": "^1.18.2"
}
},
- "on-headers": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
- "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
- "dev": true
- },
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -4652,12 +3655,6 @@
"word-wrap": "^1.2.3"
}
},
- "p-finally": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
- "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
- "dev": true
- },
"p-limit": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
@@ -4713,12 +3710,6 @@
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
- "path-is-inside": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
- "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
- "dev": true
- },
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -4731,12 +3722,6 @@
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
- "path-to-regexp": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz",
- "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==",
- "dev": true
- },
"path-type": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
@@ -4782,48 +3767,12 @@
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"dev": true
},
- "pump": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dev": true,
- "requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
},
- "range-parser": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
- "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
- "dev": true
- },
- "rc": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
- "dev": true,
- "requires": {
- "deep-extend": "^0.6.0",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- },
- "dependencies": {
- "strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
- "dev": true
- }
- }
- },
"read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@@ -4851,25 +3800,6 @@
"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
"dev": true
},
- "registry-auth-token": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz",
- "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==",
- "dev": true,
- "requires": {
- "rc": "^1.1.6",
- "safe-buffer": "^5.0.1"
- }
- },
- "registry-url": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
- "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
- "dev": true,
- "requires": {
- "rc": "^1.0.1"
- }
- },
"require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
@@ -4910,12 +3840,6 @@
"glob": "^7.1.3"
}
},
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
@@ -4925,75 +3849,6 @@
"lru-cache": "^6.0.0"
}
},
- "serve": {
- "version": "13.0.2",
- "resolved": "https://registry.npmjs.org/serve/-/serve-13.0.2.tgz",
- "integrity": "sha512-71R6fKvNgKrqARAag6lYJNnxDzpH7DCNrMuvPY5PLVaC2PDhJsGTj/34o4o4tPWhTuLgEXqvgnAWbATQ9zGZTQ==",
- "dev": true,
- "requires": {
- "@zeit/schemas": "2.6.0",
- "ajv": "6.12.6",
- "arg": "2.0.0",
- "boxen": "5.1.2",
- "chalk": "2.4.1",
- "clipboardy": "2.3.0",
- "compression": "1.7.3",
- "serve-handler": "6.1.3",
- "update-check": "1.5.2"
- },
- "dependencies": {
- "chalk": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
- "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- },
- "escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
- "dev": true
- }
- }
- },
- "serve-handler": {
- "version": "6.1.3",
- "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.3.tgz",
- "integrity": "sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==",
- "dev": true,
- "requires": {
- "bytes": "3.0.0",
- "content-disposition": "0.5.2",
- "fast-url-parser": "1.1.3",
- "mime-types": "2.1.18",
- "minimatch": "3.0.4",
- "path-is-inside": "1.0.2",
- "path-to-regexp": "2.2.1",
- "range-parser": "1.2.0"
- },
- "dependencies": {
- "mime-db": {
- "version": "1.33.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
- "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
- "dev": true
- },
- "mime-types": {
- "version": "2.1.18",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
- "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
- "dev": true,
- "requires": {
- "mime-db": "~1.33.0"
- }
- }
- }
- },
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -5009,12 +3864,6 @@
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
- "signal-exit": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz",
- "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==",
- "dev": true
- },
"slice-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
@@ -5136,12 +3985,6 @@
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
"dev": true
},
- "strip-eof": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
- "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
- "dev": true
- },
"strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -5254,16 +4097,6 @@
"integrity": "sha512-QvjkYpiD+dJJraRA8+dGAU4i7aBbb2s0S3jA45TFOvg2VgqvdCDd/3N6CqA8gluk1W91GLoXg5enMUx560QzuA==",
"dev": true
},
- "update-check": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.2.tgz",
- "integrity": "sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==",
- "dev": true,
- "requires": {
- "registry-auth-token": "3.3.2",
- "registry-url": "3.1.0"
- }
- },
"uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -5289,12 +4122,6 @@
"spdx-expression-parse": "^3.0.0"
}
},
- "vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
- "dev": true
- },
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -5317,58 +4144,12 @@
"is-symbol": "^1.0.3"
}
},
- "widest-line": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
- "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
- "dev": true,
- "requires": {
- "string-width": "^4.0.0"
- }
- },
"word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
"dev": true
},
- "wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- }
- }
- },
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
diff --git a/platform/web/package.json b/platform/web/package.json
index 0a8d9e4334..8d4983663b 100644
--- a/platform/web/package.json
+++ b/platform/web/package.json
@@ -14,8 +14,7 @@
"format:engine": "npm run lint:engine -- --fix",
"format:libs": "npm run lint:libs -- --fix",
"format:modules": "npm run lint:modules -- --fix",
- "format:tools": "npm run lint:tools -- --fix",
- "serve": "serve"
+ "format:tools": "npm run lint:tools -- --fix"
},
"author": "Godot Engine contributors",
"license": "MIT",
@@ -23,7 +22,6 @@
"eslint": "^7.28.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.23.4",
- "jsdoc": "^3.6.7",
- "serve": "^13.0.2"
+ "jsdoc": "^3.6.7"
}
}
diff --git a/platform/web/serve.json b/platform/web/serve.json
deleted file mode 100644
index f2ef24751f..0000000000
--- a/platform/web/serve.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "public": "../../bin",
- "headers": [{
- "source": "**/*",
- "headers": [
- {
- "key": "Cross-Origin-Embedder-Policy",
- "value": "require-corp"
- }, {
- "key": "Cross-Origin-Opener-Policy",
- "value": "same-origin"
- }, {
- "key": "Access-Control-Allow-Origin",
- "value": "*"
- }, {
- "key": "Cache-Control",
- "value": "no-store, max-age=0"
- }
- ]
- }]
-}
diff --git a/platform/web/serve.py b/platform/web/serve.py
new file mode 100755
index 0000000000..14e87e9ea1
--- /dev/null
+++ b/platform/web/serve.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+
+from http.server import HTTPServer, SimpleHTTPRequestHandler, test # type: ignore
+from pathlib import Path
+import os
+import sys
+import argparse
+import subprocess
+
+
+class CORSRequestHandler(SimpleHTTPRequestHandler):
+ def end_headers(self):
+ self.send_header("Cross-Origin-Opener-Policy", "same-origin")
+ self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
+ self.send_header("Access-Control-Allow-Origin", "*")
+ super().end_headers()
+
+
+def shell_open(url):
+ if sys.platform == "win32":
+ os.startfile(url)
+ else:
+ opener = "open" if sys.platform == "darwin" else "xdg-open"
+ subprocess.call([opener, url])
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-p", "--port", help="port to listen on", default=8060, type=int)
+ parser.add_argument(
+ "-r", "--root", help="path to serve as root (relative to `platform/web/`)", default="../../bin", type=Path
+ )
+ browser_parser = parser.add_mutually_exclusive_group(required=False)
+ browser_parser.add_argument(
+ "-n", "--no-browser", help="don't open default web browser automatically", dest="browser", action="store_false"
+ )
+ parser.set_defaults(browser=True)
+ args = parser.parse_args()
+
+ # Change to the directory where the script is located,
+ # so that the script can be run from any location.
+ os.chdir(Path(__file__).resolve().parent)
+
+ if args.root:
+ os.chdir(args.root)
+
+ if args.browser:
+ # Open the served page in the user's default browser.
+ print("Opening the served URL in the default browser (use `--no-browser` or `-n` to disable this).")
+ shell_open(f"http://127.0.0.1:{args.port}")
+
+ test(CORSRequestHandler, HTTPServer, port=args.port)
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index e120aa871b..aeaaaf3aec 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -171,9 +171,14 @@ Transform2D Camera2D::get_camera_transform() {
Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom_scale) : Point2());
- real_t angle = get_global_rotation();
if (!ignore_rotation) {
- screen_offset = screen_offset.rotated(angle);
+ if (rotation_smoothing_enabled && !Engine::get_singleton()->is_editor_hint()) {
+ real_t step = rotation_smoothing_speed * (process_callback == CAMERA2D_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time());
+ camera_angle = Math::lerp_angle(camera_angle, get_global_rotation(), step);
+ } else {
+ camera_angle = get_global_rotation();
+ }
+ screen_offset = screen_offset.rotated(camera_angle);
}
Rect2 screen_rect(-screen_offset + ret_camera_pos, screen_size * zoom_scale);
@@ -205,7 +210,7 @@ Transform2D Camera2D::get_camera_transform() {
Transform2D xform;
xform.scale_basis(zoom_scale);
if (!ignore_rotation) {
- xform.set_rotation(angle);
+ xform.set_rotation(camera_angle);
}
xform.set_origin(screen_rect.position);
@@ -366,6 +371,12 @@ Camera2D::AnchorMode Camera2D::get_anchor_mode() const {
void Camera2D::set_ignore_rotation(bool p_ignore) {
ignore_rotation = p_ignore;
Point2 old_smoothed_camera_pos = smoothed_camera_pos;
+
+ // Reset back to zero so it matches the camera rotation when ignore_rotation is enabled.
+ if (ignore_rotation) {
+ camera_angle = 0.0;
+ }
+
_update_scroll();
smoothed_camera_pos = old_smoothed_camera_pos;
}
@@ -415,6 +426,14 @@ void Camera2D::set_current(bool p_current) {
}
}
+void Camera2D::_update_process_internal_for_smoothing() {
+ bool is_not_in_scene_or_editor = !(is_inside_tree() && Engine::get_singleton()->is_editor_hint());
+ bool is_any_smoothing_valid = smoothing > 0 || rotation_smoothing_speed > 0;
+
+ bool enabled = is_any_smoothing_valid && is_not_in_scene_or_editor;
+ set_process_internal(enabled);
+}
+
bool Camera2D::is_current() const {
return current;
}
@@ -508,17 +527,31 @@ void Camera2D::align() {
void Camera2D::set_follow_smoothing(real_t p_speed) {
smoothing = p_speed;
- if (smoothing > 0 && !(is_inside_tree() && Engine::get_singleton()->is_editor_hint())) {
- set_process_internal(true);
- } else {
- set_process_internal(false);
- }
+ _update_process_internal_for_smoothing();
}
real_t Camera2D::get_follow_smoothing() const {
return smoothing;
}
+void Camera2D::set_rotation_smoothing_speed(real_t p_speed) {
+ rotation_smoothing_speed = p_speed;
+ _update_process_internal_for_smoothing();
+}
+
+real_t Camera2D::get_rotation_smoothing_speed() const {
+ return rotation_smoothing_speed;
+}
+
+void Camera2D::set_rotation_smoothing_enabled(bool p_enabled) {
+ rotation_smoothing_enabled = p_enabled;
+ notify_property_list_changed();
+}
+
+bool Camera2D::is_rotation_smoothing_enabled() const {
+ return rotation_smoothing_enabled;
+}
+
Point2 Camera2D::get_camera_screen_center() const {
return camera_screen_center;
}
@@ -659,6 +692,9 @@ void Camera2D::_validate_property(PropertyInfo &p_property) const {
if (!smoothing_enabled && p_property.name == "smoothing_speed") {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}
+ if (!rotation_smoothing_enabled && p_property.name == "rotation_smoothing_speed") {
+ p_property.usage = PROPERTY_USAGE_NO_EDITOR;
+ }
}
void Camera2D::_bind_methods() {
@@ -716,6 +752,12 @@ void Camera2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enable_follow_smoothing", "follow_smoothing"), &Camera2D::set_enable_follow_smoothing);
ClassDB::bind_method(D_METHOD("is_follow_smoothing_enabled"), &Camera2D::is_follow_smoothing_enabled);
+ ClassDB::bind_method(D_METHOD("set_rotation_smoothing_enabled", "enabled"), &Camera2D::set_rotation_smoothing_enabled);
+ ClassDB::bind_method(D_METHOD("is_rotation_smoothing_enabled"), &Camera2D::is_rotation_smoothing_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_rotation_smoothing_speed", "speed"), &Camera2D::set_rotation_smoothing_speed);
+ ClassDB::bind_method(D_METHOD("get_rotation_smoothing_speed"), &Camera2D::get_rotation_smoothing_speed);
+
ClassDB::bind_method(D_METHOD("force_update_scroll"), &Camera2D::force_update_scroll);
ClassDB::bind_method(D_METHOD("reset_smoothing"), &Camera2D::reset_smoothing);
ClassDB::bind_method(D_METHOD("align"), &Camera2D::align);
@@ -750,6 +792,10 @@ void Camera2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smoothing_enabled"), "set_enable_follow_smoothing", "is_follow_smoothing_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "smoothing_speed", PROPERTY_HINT_NONE, "suffix:px/s"), "set_follow_smoothing", "get_follow_smoothing");
+ ADD_GROUP("Rotation Smoothing", "rotation_smoothing_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotation_smoothing_enabled"), "set_rotation_smoothing_enabled", "is_rotation_smoothing_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation_smoothing_speed"), "set_rotation_smoothing_speed", "get_rotation_smoothing_speed");
+
ADD_GROUP("Drag", "drag_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_horizontal_enabled"), "set_drag_horizontal_enabled", "is_drag_horizontal_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_vertical_enabled"), "set_drag_vertical_enabled", "is_drag_vertical_enabled");
diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h
index 1ce622388c..1411175af2 100644
--- a/scene/2d/camera_2d.h
+++ b/scene/2d/camera_2d.h
@@ -67,6 +67,11 @@ protected:
bool current = false;
real_t smoothing = 5.0;
bool smoothing_enabled = false;
+
+ real_t camera_angle = 0.0;
+ real_t rotation_smoothing_speed = 5.0;
+ bool rotation_smoothing_enabled = false;
+
int limit[4];
bool limit_smoothing_enabled = false;
@@ -87,6 +92,8 @@ protected:
void _set_old_smoothing(real_t p_enable);
+ void _update_process_internal_for_smoothing();
+
bool screen_drawing_enabled = true;
bool limit_drawing_enabled = false;
bool margin_drawing_enabled = false;
@@ -139,6 +146,12 @@ public:
void set_follow_smoothing(real_t p_speed);
real_t get_follow_smoothing() const;
+ void set_rotation_smoothing_speed(real_t p_speed);
+ real_t get_rotation_smoothing_speed() const;
+
+ void set_rotation_smoothing_enabled(bool p_enabled);
+ bool is_rotation_smoothing_enabled() const;
+
void set_process_callback(Camera2DProcessCallback p_mode);
Camera2DProcessCallback get_process_callback() const;
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index a4d5205f81..861c7f273b 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -199,8 +199,6 @@ private:
float base_scale = 1.0;
} theme_cache;
- bool _is_over_clear_button(const Point2 &p_pos) const;
-
void _clear_undo_stack();
void _clear_redo();
void _create_undo_state();
@@ -240,6 +238,7 @@ private:
void _ensure_menu();
protected:
+ bool _is_over_clear_button(const Point2 &p_pos) const;
virtual void _update_theme_item_cache() override;
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 15678c9281..298d7b1ffa 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -1209,6 +1209,8 @@ Error ImageTexture3D::create(Image::Format p_format, int p_width, int p_height,
if (texture.is_valid()) {
RenderingServer::get_singleton()->texture_replace(texture, tex);
+ } else {
+ texture = tex;
}
return OK;
@@ -1489,7 +1491,15 @@ void AtlasTexture::set_atlas(const Ref<Texture2D> &p_atlas) {
if (atlas == p_atlas) {
return;
}
+ // Support recursive AtlasTextures.
+ if (Ref<AtlasTexture>(atlas).is_valid()) {
+ atlas->disconnect(CoreStringNames::get_singleton()->changed, callable_mp((Resource *)this, &AtlasTexture::emit_changed));
+ }
atlas = p_atlas;
+ if (Ref<AtlasTexture>(atlas).is_valid()) {
+ atlas->connect(CoreStringNames::get_singleton()->changed, callable_mp((Resource *)this, &AtlasTexture::emit_changed));
+ }
+
emit_changed();
}
diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h
index f5bdccca68..98acd5ad74 100644
--- a/servers/rendering/dummy/storage/texture_storage.h
+++ b/servers/rendering/dummy/storage/texture_storage.h
@@ -157,14 +157,17 @@ public:
virtual RID render_target_create() override { return RID(); }
virtual void render_target_free(RID p_rid) override {}
virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) override {}
+ virtual Point2i render_target_get_position(RID p_render_target) const override { return Point2i(); }
virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override {}
- virtual RID render_target_get_texture(RID p_render_target) override { return RID(); }
- virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override {}
+ virtual Size2i render_target_get_size(RID p_render_target) const override { return Size2i(); }
virtual void render_target_set_transparent(RID p_render_target, bool p_is_transparent) override {}
+ virtual bool render_target_get_transparent(RID p_render_target) const override { return false; }
virtual void render_target_set_direct_to_screen(RID p_render_target, bool p_direct_to_screen) override {}
- virtual bool render_target_was_used(RID p_render_target) override { return false; }
+ virtual bool render_target_get_direct_to_screen(RID p_render_target) const override { return false; }
+ virtual bool render_target_was_used(RID p_render_target) const override { return false; }
virtual void render_target_set_as_unused(RID p_render_target) override {}
virtual void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) override {}
+ virtual RS::ViewportMSAA render_target_get_msaa(RID p_render_target) const override { return RS::VIEWPORT_MSAA_DISABLED; }
virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) override {}
virtual bool render_target_is_clear_requested(RID p_render_target) override { return false; }
@@ -176,8 +179,19 @@ public:
virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const override { return Rect2i(); }
virtual void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override {}
- virtual void render_target_set_vrs_mode(RID p_render_target, RS::ViewportVRSMode p_mode) override{};
- virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) override{};
+ virtual void render_target_set_vrs_mode(RID p_render_target, RS::ViewportVRSMode p_mode) override {}
+ virtual RS::ViewportVRSMode render_target_get_vrs_mode(RID p_render_target) const override { return RS::VIEWPORT_VRS_DISABLED; }
+ virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) override {}
+ virtual RID render_target_get_vrs_texture(RID p_render_target) const override { return RID(); }
+
+ virtual void render_target_set_override_color(RID p_render_target, RID p_texture) override {}
+ virtual RID render_target_get_override_color(RID p_render_target) const override { return RID(); }
+ virtual void render_target_set_override_depth(RID p_render_target, RID p_texture) override {}
+ virtual RID render_target_get_override_depth(RID p_render_target) const override { return RID(); }
+ virtual void render_target_set_override_velocity(RID p_render_target, RID p_texture) override {}
+ virtual RID render_target_get_override_velocity(RID p_render_target) const override { return RID(); }
+
+ virtual RID render_target_get_texture(RID p_render_target) override { return RID(); }
};
} // namespace RendererDummy
diff --git a/servers/rendering/renderer_rd/effects/ss_effects.cpp b/servers/rendering/renderer_rd/effects/ss_effects.cpp
index 1cbc52dec3..4bc6cd6143 100644
--- a/servers/rendering/renderer_rd/effects/ss_effects.cpp
+++ b/servers/rendering/renderer_rd/effects/ss_effects.cpp
@@ -43,7 +43,7 @@ SSEffects *SSEffects::singleton = nullptr;
static _FORCE_INLINE_ void store_camera(const Projection &p_mtx, float *p_array) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- p_array[i * 4 + j] = p_mtx.matrix[i][j];
+ p_array[i * 4 + j] = p_mtx.columns[i][j];
}
}
}
@@ -488,8 +488,8 @@ void SSEffects::downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_
ss_effects.downsample_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, use_full_mips ? 6 : 2), 2);
}
- float depth_linearize_mul = -p_projection.matrix[3][2];
- float depth_linearize_add = p_projection.matrix[2][2];
+ float depth_linearize_mul = -p_projection.columns[3][2];
+ float depth_linearize_add = p_projection.columns[2][2];
if (depth_linearize_mul * depth_linearize_add < 0) {
depth_linearize_add = -depth_linearize_add;
}
@@ -713,8 +713,8 @@ void SSEffects::screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers
ssil.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssil_buffers.buffer_width;
ssil.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssil_buffers.buffer_height;
- float tan_half_fov_x = 1.0 / p_projection.matrix[0][0];
- float tan_half_fov_y = 1.0 / p_projection.matrix[1][1];
+ float tan_half_fov_x = 1.0 / p_projection.columns[0][0];
+ float tan_half_fov_y = 1.0 / p_projection.columns[1][1];
ssil.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0;
ssil.gather_push_constant.NDC_to_view_mul[1] = tan_half_fov_y * -2.0;
ssil.gather_push_constant.NDC_to_view_add[0] = tan_half_fov_x * -1.0;
@@ -1164,8 +1164,8 @@ void SSEffects::generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_bu
ssao.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssao_buffers.buffer_width;
ssao.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssao_buffers.buffer_height;
- float tan_half_fov_x = 1.0 / p_projection.matrix[0][0];
- float tan_half_fov_y = 1.0 / p_projection.matrix[1][1];
+ float tan_half_fov_x = 1.0 / p_projection.columns[0][0];
+ float tan_half_fov_y = 1.0 / p_projection.columns[1][1];
ssao.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0;
ssao.gather_push_constant.NDC_to_view_mul[1] = tan_half_fov_y * -2.0;
ssao.gather_push_constant.NDC_to_view_add[0] = tan_half_fov_x * -1.0;
@@ -1611,10 +1611,10 @@ void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const R
push_constant.num_steps = p_max_steps;
push_constant.depth_tolerance = p_tolerance;
push_constant.use_half_res = true;
- push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_projections[v].matrix[0][0]);
- push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_projections[v].matrix[1][1]);
- push_constant.proj_info[2] = (1.0f - p_projections[v].matrix[0][2]) / p_projections[v].matrix[0][0];
- push_constant.proj_info[3] = (1.0f + p_projections[v].matrix[1][2]) / p_projections[v].matrix[1][1];
+ push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_projections[v].columns[0][0]);
+ push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_projections[v].columns[1][1]);
+ push_constant.proj_info[2] = (1.0f - p_projections[v].columns[0][2]) / p_projections[v].columns[0][0];
+ push_constant.proj_info[3] = (1.0f + p_projections[v].columns[1][2]) / p_projections[v].columns[1][1];
ScreenSpaceReflectionMode mode = (ssr_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) ? SCREEN_SPACE_REFLECTION_ROUGH : SCREEN_SPACE_REFLECTION_NORMAL;
RID shader = ssr.shader.version_get_shader(ssr.shader_version, mode);
@@ -1659,10 +1659,10 @@ void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const R
push_constant.view_index = v;
push_constant.orthogonal = p_projections[v].is_orthogonal();
push_constant.edge_tolerance = Math::sin(Math::deg_to_rad(15.0));
- push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_projections[v].matrix[0][0]);
- push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_projections[v].matrix[1][1]);
- push_constant.proj_info[2] = (1.0f - p_projections[v].matrix[0][2]) / p_projections[v].matrix[0][0];
- push_constant.proj_info[3] = (1.0f + p_projections[v].matrix[1][2]) / p_projections[v].matrix[1][1];
+ push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_projections[v].columns[0][0]);
+ push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_projections[v].columns[1][1]);
+ push_constant.proj_info[2] = (1.0f - p_projections[v].columns[0][2]) / p_projections[v].columns[0][0];
+ push_constant.proj_info[3] = (1.0f + p_projections[v].columns[1][2]) / p_projections[v].columns[1][1];
push_constant.vertical = 0;
if (ssr_roughness_quality == RS::ENV_SSR_ROUGHNESS_QUALITY_LOW) {
push_constant.steps = p_max_steps / 3;
diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp
index 0853460861..9b6be0b422 100644
--- a/servers/rendering/renderer_rd/environment/gi.cpp
+++ b/servers/rendering/renderer_rd/environment/gi.cpp
@@ -1634,7 +1634,7 @@ void GI::SDFGI::debug_draw(uint32_t p_view_count, const Projection *p_projection
Projection inv_projection = p_projections[v].inverse();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) {
- push_constant.inv_projection[j][i] = inv_projection.matrix[i][j];
+ push_constant.inv_projection[j][i] = inv_projection.columns[i][j];
}
}
@@ -1644,8 +1644,8 @@ void GI::SDFGI::debug_draw(uint32_t p_view_count, const Projection *p_projection
RD::get_singleton()->compute_list_end();
}
- Size2 rtsize = texture_storage->render_target_get_size(p_render_target);
- copy_effects->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2(Vector2(), rtsize), true, false, false, false, RID(), p_view_count > 1);
+ Size2i rtsize = texture_storage->render_target_get_size(p_render_target);
+ copy_effects->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2i(Point2i(), rtsize), true, false, false, false, RID(), p_view_count > 1);
}
void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) {
@@ -3285,7 +3285,7 @@ void GI::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, c
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- push_constant.projection[i * 4 + j] = cam_transform.matrix[i][j];
+ push_constant.projection[i * 4 + j] = cam_transform.columns[i][j];
}
}
@@ -3820,10 +3820,10 @@ void GI::process_gi(Ref<RenderSceneBuffersRD> p_render_buffers, const RID *p_nor
push_constant.z_far = p_projections[0].get_z_far();
// these are only used if we have 1 view, else we use the projections in our scene data
- push_constant.proj_info[0] = -2.0f / (internal_size.x * p_projections[0].matrix[0][0]);
- push_constant.proj_info[1] = -2.0f / (internal_size.y * p_projections[0].matrix[1][1]);
- push_constant.proj_info[2] = (1.0f - p_projections[0].matrix[0][2]) / p_projections[0].matrix[0][0];
- push_constant.proj_info[3] = (1.0f + p_projections[0].matrix[1][2]) / p_projections[0].matrix[1][1];
+ push_constant.proj_info[0] = -2.0f / (internal_size.x * p_projections[0].columns[0][0]);
+ push_constant.proj_info[1] = -2.0f / (internal_size.y * p_projections[0].columns[1][1]);
+ push_constant.proj_info[2] = (1.0f - p_projections[0].columns[0][2]) / p_projections[0].columns[0][0];
+ push_constant.proj_info[3] = (1.0f + p_projections[0].columns[1][2]) / p_projections[0].columns[1][1];
bool use_sdfgi = p_render_buffers->has_custom_data(RB_SCOPE_SDFGI);
bool use_voxel_gi_instances = push_constant.max_voxel_gi_instances > 0;
diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp
index 21a15ed475..84130f9504 100644
--- a/servers/rendering/renderer_rd/environment/sky.cpp
+++ b/servers/rendering/renderer_rd/environment/sky.cpp
@@ -300,10 +300,10 @@ void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineC
for (uint32_t v = 0; v < p_view_count; v++) {
// We only need key components of our projection matrix
- sky_push_constant.projections[v][0] = p_projections[v].matrix[2][0];
- sky_push_constant.projections[v][1] = p_projections[v].matrix[0][0];
- sky_push_constant.projections[v][2] = p_projections[v].matrix[2][1];
- sky_push_constant.projections[v][3] = p_projections[v].matrix[1][1];
+ sky_push_constant.projections[v][0] = p_projections[v].columns[2][0];
+ sky_push_constant.projections[v][1] = p_projections[v].columns[0][0];
+ sky_push_constant.projections[v][2] = p_projections[v].columns[2][1];
+ sky_push_constant.projections[v][3] = p_projections[v].columns[1][1];
}
sky_push_constant.position[0] = p_position.x;
sky_push_constant.position[1] = p_position.y;
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index c1a7818921..cf08949d99 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -2095,17 +2095,17 @@ void RenderForwardClustered::_render_buffers_debug_draw(Ref<RenderSceneBuffersRD
RID render_target = p_render_buffers->get_render_target();
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SSAO && rb_data->ss_effects_data.ssao.ao_final.is_valid()) {
- Size2 rtsize = texture_storage->render_target_get_size(render_target);
+ Size2i rtsize = texture_storage->render_target_get_size(render_target);
copy_effects->copy_to_fb_rect(rb_data->ss_effects_data.ssao.ao_final, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, true);
}
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SSIL && rb_data->ss_effects_data.ssil.ssil_final.is_valid()) {
- Size2 rtsize = texture_storage->render_target_get_size(render_target);
+ Size2i rtsize = texture_storage->render_target_get_size(render_target);
copy_effects->copy_to_fb_rect(rb_data->ss_effects_data.ssil.ssil_final, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, false);
}
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && p_render_buffers->has_texture(RB_SCOPE_GI, RB_TEX_AMBIENT)) {
- Size2 rtsize = texture_storage->render_target_get_size(render_target);
+ Size2i rtsize = texture_storage->render_target_get_size(render_target);
RID ambient_texture = p_render_buffers->get_texture(RB_SCOPE_GI, RB_TEX_AMBIENT);
RID reflection_texture = p_render_buffers->get_texture(RB_SCOPE_GI, RB_TEX_REFLECTION);
copy_effects->copy_to_fb_rect(ambient_texture, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, false, false, true, reflection_texture, p_render_buffers->get_view_count() > 1);
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index bbb53f7b97..3de6f05e84 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -1627,7 +1627,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index,
ShadowRenderPushConstant push_constant;
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
- push_constant.projection[y * 4 + x] = projection.matrix[y][x];
+ push_constant.projection[y * 4 + x] = projection.columns[y][x];
}
}
static const Vector2 directions[4] = { Vector2(1, 0), Vector2(0, 1), Vector2(-1, 0), Vector2(0, -1) };
@@ -1702,7 +1702,7 @@ void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_sh
ShadowRenderPushConstant push_constant;
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
- push_constant.projection[y * 4 + x] = projection.matrix[y][x];
+ push_constant.projection[y * 4 + x] = projection.columns[y][x];
}
}
@@ -1770,7 +1770,7 @@ void RendererCanvasRenderRD::render_sdf(RID p_render_target, LightOccluderInstan
ShadowRenderPushConstant push_constant;
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
- push_constant.projection[y * 4 + x] = projection.matrix[y][x];
+ push_constant.projection[y * 4 + x] = projection.columns[y][x];
}
}
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
index a50742f91a..dd3f62e509 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
@@ -44,13 +44,9 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID
}
for (int i = 0; i < p_amount; i++) {
- RID texture = texture_storage->render_target_get_texture(p_render_targets[i].render_target);
- ERR_CONTINUE(texture.is_null());
- RID rd_texture = texture_storage->texture_get_rd_texture(texture);
+ RID rd_texture = texture_storage->render_target_get_rd_texture(p_render_targets[i].render_target);
ERR_CONTINUE(rd_texture.is_null());
- // TODO if keep_3d_linear was set when rendering to this render target we need to add a linear->sRGB conversion in.
-
if (!render_target_descriptors.has(rd_texture) || !RD::get_singleton()->uniform_set_is_valid(render_target_descriptors[rd_texture])) {
Vector<RD::Uniform> uniforms;
RD::Uniform u;
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index acc964b3f3..6157d7d840 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -828,7 +828,7 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(Ref<RenderSceneBuffersRD>
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS) {
if (RendererRD::LightStorage::get_singleton()->directional_shadow_get_texture().is_valid()) {
RID shadow_atlas_texture = RendererRD::LightStorage::get_singleton()->directional_shadow_get_texture();
- Size2 rtsize = texture_storage->render_target_get_size(render_target);
+ Size2i rtsize = texture_storage->render_target_get_size(render_target);
copy_effects->copy_to_fb_rect(shadow_atlas_texture, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2i(Vector2(), rtsize / 2), false, true);
}
@@ -838,7 +838,7 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(Ref<RenderSceneBuffersRD>
RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture();
if (decal_atlas.is_valid()) {
- Size2 rtsize = texture_storage->render_target_get_size(render_target);
+ Size2i rtsize = texture_storage->render_target_get_size(render_target);
copy_effects->copy_to_fb_rect(decal_atlas, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2i(Vector2(), rtsize / 2), false, false, true);
}
@@ -846,7 +846,7 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(Ref<RenderSceneBuffersRD>
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE) {
if (p_render_buffers->luminance.current.is_valid()) {
- Size2 rtsize = texture_storage->render_target_get_size(render_target);
+ Size2i rtsize = texture_storage->render_target_get_size(render_target);
copy_effects->copy_to_fb_rect(p_render_buffers->luminance.current, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize / 8), false, true);
}
@@ -859,13 +859,13 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(Ref<RenderSceneBuffersRD>
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_OCCLUDERS) {
if (p_occlusion_buffer.is_valid()) {
- Size2 rtsize = texture_storage->render_target_get_size(render_target);
+ Size2i rtsize = texture_storage->render_target_get_size(render_target);
copy_effects->copy_to_fb_rect(texture_storage->texture_get_rd_texture(p_occlusion_buffer), texture_storage->render_target_get_rd_framebuffer(render_target), Rect2i(Vector2(), rtsize), true, false);
}
}
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS && _render_buffers_get_velocity_texture(p_render_buffers).is_valid()) {
- Size2 rtsize = texture_storage->render_target_get_size(render_target);
+ Size2i rtsize = texture_storage->render_target_get_size(render_target);
copy_effects->copy_to_fb_rect(_render_buffers_get_velocity_texture(p_render_buffers), texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, false);
}
}
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
index 36f1bc0316..626738d971 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
@@ -720,7 +720,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
Projection v = value;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- gui[i * 4 + j] = v.matrix[i][j];
+ gui[i * 4 + j] = v.columns[i][j];
}
}
}
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h
index d496eed17a..330eac777f 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h
@@ -302,7 +302,7 @@ public:
static _FORCE_INLINE_ void store_camera(const Projection &p_mtx, float *p_array) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- p_array[i * 4 + j] = p_mtx.matrix[i][j];
+ p_array[i * 4 + j] = p_mtx.columns[i][j];
}
}
}
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp
index 1b2237b505..0c2092f03e 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp
@@ -178,7 +178,7 @@ void RenderSceneBuffersRD::configure(RID p_render_target, const Size2i p_interna
// Create our depth buffer
{
- // TODO If we have depth buffer supplied externally, pick this up
+ // TODO Lazy create this in case we've got an external depth buffer
RD::DataFormat format;
uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
@@ -490,6 +490,28 @@ Ref<RenderBufferCustomDataRD> RenderSceneBuffersRD::get_custom_data(const String
return ret;
}
+// Depth texture
+
+RID RenderSceneBuffersRD::get_depth_texture() {
+ RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+ RID depth = texture_storage->render_target_get_override_depth(render_target);
+ if (depth.is_valid()) {
+ return depth;
+ } else {
+ return get_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH);
+ }
+}
+
+RID RenderSceneBuffersRD::get_depth_texture(const uint32_t p_layer) {
+ RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+ RID depth_slice = texture_storage->render_target_get_override_depth_slice(render_target, p_layer);
+ if (depth_slice.is_valid()) {
+ return depth_slice;
+ } else {
+ return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_DEPTH, p_layer, 0);
+ }
+}
+
// Velocity texture.
void RenderSceneBuffersRD::ensure_velocity() {
@@ -516,6 +538,20 @@ void RenderSceneBuffersRD::ensure_velocity() {
}
}
+bool RenderSceneBuffersRD::has_velocity_buffer(bool p_has_msaa) {
+ if (p_has_msaa) {
+ return has_texture(RB_SCOPE_BUFFERS, RB_TEX_VELOCITY_MSAA);
+ } else {
+ RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+ RID velocity = texture_storage->render_target_get_override_velocity(render_target);
+ if (velocity.is_valid()) {
+ return true;
+ } else {
+ return has_texture(RB_SCOPE_BUFFERS, RB_TEX_VELOCITY);
+ }
+ }
+}
+
RID RenderSceneBuffersRD::get_velocity_buffer(bool p_get_msaa) {
if (p_get_msaa) {
if (!has_texture(RB_SCOPE_BUFFERS, RB_TEX_VELOCITY_MSAA)) {
@@ -524,10 +560,28 @@ RID RenderSceneBuffersRD::get_velocity_buffer(bool p_get_msaa) {
return get_texture(RB_SCOPE_BUFFERS, RB_TEX_VELOCITY_MSAA);
}
} else {
- if (!has_texture(RB_SCOPE_BUFFERS, RB_TEX_VELOCITY)) {
+ RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+ RID velocity = texture_storage->render_target_get_override_velocity(render_target);
+ if (velocity.is_valid()) {
+ return velocity;
+ } else if (!has_texture(RB_SCOPE_BUFFERS, RB_TEX_VELOCITY)) {
return RID();
} else {
return get_texture(RB_SCOPE_BUFFERS, RB_TEX_VELOCITY);
}
}
}
+
+RID RenderSceneBuffersRD::get_velocity_buffer(bool p_get_msaa, uint32_t p_layer) {
+ if (p_get_msaa) {
+ return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_VELOCITY_MSAA, p_layer, 0);
+ } else {
+ RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+ RID velocity_slice = texture_storage->render_target_get_override_velocity_slice(render_target, p_layer);
+ if (velocity_slice.is_valid()) {
+ return velocity_slice;
+ } else {
+ return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_VELOCITY, p_layer, 0);
+ }
+ }
+}
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h
index 169ee2e2b1..6907f69b93 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h
@@ -189,12 +189,8 @@ public:
return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_COLOR, p_layer, 0);
}
- _FORCE_INLINE_ RID get_depth_texture() const {
- return get_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH);
- }
- _FORCE_INLINE_ RID get_depth_texture(const uint32_t p_layer) {
- return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_DEPTH, p_layer, 0);
- }
+ RID get_depth_texture();
+ RID get_depth_texture(const uint32_t p_layer);
// back buffer (color)
RID get_back_buffer_texture() const { return has_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0) ? get_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0) : RID(); } // We (re)use our blur texture here.
@@ -202,9 +198,9 @@ public:
// Velocity, currently only used by TAA (Clustered) but we'll be using this in other places soon too.
void ensure_velocity();
- bool has_velocity_buffer(bool p_has_msaa) { return has_texture(RB_SCOPE_BUFFERS, p_has_msaa ? RB_TEX_VELOCITY_MSAA : RB_TEX_VELOCITY); }
+ bool has_velocity_buffer(bool p_has_msaa);
RID get_velocity_buffer(bool p_get_msaa);
- RID get_velocity_buffer(bool p_get_msaa, uint32_t p_layer) { return get_texture_slice(RB_SCOPE_BUFFERS, p_get_msaa ? RB_TEX_VELOCITY_MSAA : RB_TEX_VELOCITY, p_layer, 0); }
+ RID get_velocity_buffer(bool p_get_msaa, uint32_t p_layer);
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Everything after this needs to be re-evaluated, this is all old implementation
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index 14e41a0d6b..b3a7e05ff5 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -30,6 +30,7 @@
#include "texture_storage.h"
#include "../effects/copy_effects.h"
+#include "../framebuffer_cache_rd.h"
#include "material_storage.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
@@ -2359,10 +2360,26 @@ void TextureStorage::update_decal_buffer(const PagedArray<RID> &p_decals, const
/* RENDER TARGET API */
+RID TextureStorage::RenderTarget::get_framebuffer() {
+ // Note that if we're using an overridden color buffer, we're likely cycling through a texture chain.
+ // this is where our framebuffer cache comes in clutch..
+
+ if (msaa != RS::VIEWPORT_MSAA_DISABLED) {
+ return FramebufferCacheRD::get_singleton()->get_cache_multiview(view_count, color_multisample, overridden.color.is_valid() ? overridden.color : color);
+ } else {
+ return FramebufferCacheRD::get_singleton()->get_cache_multiview(view_count, overridden.color.is_valid() ? overridden.color : color);
+ }
+}
+
void TextureStorage::_clear_render_target(RenderTarget *rt) {
- //free in reverse dependency order
- if (rt->framebuffer.is_valid()) {
- RD::get_singleton()->free(rt->framebuffer);
+ // clear overrides, we assume these are freed by the object that created them
+ rt->overridden.color = RID();
+ rt->overridden.depth = RID();
+ rt->overridden.velocity = RID();
+ rt->overridden.cached_slices.clear(); // these are automatically freed when their parent textures are freed so just clear
+
+ // free in reverse dependency order
+ if (rt->framebuffer_uniform_set.is_valid()) {
rt->framebuffer_uniform_set = RID(); //chain deleted
}
@@ -2384,7 +2401,6 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
_render_target_clear_sdf(rt);
- rt->framebuffer = RID();
rt->color = RID();
rt->color_multisample = RID();
}
@@ -2432,11 +2448,10 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
}
}
+ // TODO see if we can lazy create this once we actually use it as we may not need to create this if we have an overridden color buffer...
rt->color = RD::get_singleton()->texture_create(rd_color_attachment_format, rd_view);
ERR_FAIL_COND(rt->color.is_null());
- Vector<RID> fb_textures;
-
if (rt->msaa != RS::VIEWPORT_MSAA_DISABLED) {
// Use the texture format of the color attachment for the multisample color attachment.
RD::TextureFormat rd_color_multisample_format = rd_color_attachment_format;
@@ -2450,15 +2465,8 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
RD::TextureView rd_view_multisample;
rd_color_multisample_format.is_resolve_buffer = false;
rt->color_multisample = RD::get_singleton()->texture_create(rd_color_multisample_format, rd_view_multisample);
- fb_textures.push_back(rt->color_multisample);
ERR_FAIL_COND(rt->color_multisample.is_null());
}
- fb_textures.push_back(rt->color);
- rt->framebuffer = RD::get_singleton()->framebuffer_create(fb_textures, RenderingDevice::INVALID_ID, rt->view_count);
- if (rt->framebuffer.is_null()) {
- _clear_render_target(rt);
- ERR_FAIL_COND(rt->framebuffer.is_null());
- }
{ //update texture
@@ -2568,6 +2576,11 @@ void TextureStorage::render_target_set_position(RID p_render_target, int p_x, in
//unused for this render target
}
+Point2i TextureStorage::render_target_get_position(RID p_render_target) const {
+ //unused for this render target
+ return Point2i();
+}
+
void TextureStorage::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@@ -2579,6 +2592,13 @@ void TextureStorage::render_target_set_size(RID p_render_target, int p_width, in
}
}
+Size2i TextureStorage::render_target_get_size(RID p_render_target) const {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND_V(!rt, Size2i());
+
+ return rt->size;
+}
+
RID TextureStorage::render_target_get_texture(RID p_render_target) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
@@ -2586,7 +2606,84 @@ RID TextureStorage::render_target_get_texture(RID p_render_target) {
return rt->texture;
}
-void TextureStorage::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {
+void TextureStorage::render_target_set_override_color(RID p_render_target, RID p_texture) {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND(!rt);
+
+ rt->overridden.color = p_texture;
+}
+
+RID TextureStorage::render_target_get_override_color(RID p_render_target) const {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND_V(!rt, RID());
+
+ return rt->overridden.color;
+}
+
+void TextureStorage::render_target_set_override_depth(RID p_render_target, RID p_texture) {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND(!rt);
+
+ rt->overridden.depth = p_texture;
+}
+
+RID TextureStorage::render_target_get_override_depth(RID p_render_target) const {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND_V(!rt, RID());
+
+ return rt->overridden.depth;
+}
+
+RID TextureStorage::render_target_get_override_depth_slice(RID p_render_target, const uint32_t p_layer) const {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND_V(!rt, RID());
+
+ if (rt->overridden.depth.is_null()) {
+ return RID();
+ } else if (rt->view_count == 1) {
+ return rt->overridden.depth;
+ } else {
+ RenderTarget::RTOverridden::SliceKey key(rt->overridden.depth, p_layer);
+
+ if (!rt->overridden.cached_slices.has(key)) {
+ rt->overridden.cached_slices[key] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->overridden.depth, p_layer, 0);
+ }
+
+ return rt->overridden.cached_slices[key];
+ }
+}
+
+void TextureStorage::render_target_set_override_velocity(RID p_render_target, RID p_texture) {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND(!rt);
+
+ rt->overridden.velocity = p_texture;
+}
+
+RID TextureStorage::render_target_get_override_velocity(RID p_render_target) const {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND_V(!rt, RID());
+
+ return rt->overridden.velocity;
+}
+
+RID TextureStorage::render_target_get_override_velocity_slice(RID p_render_target, const uint32_t p_layer) const {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND_V(!rt, RID());
+
+ if (rt->overridden.velocity.is_null()) {
+ return RID();
+ } else if (rt->view_count == 1) {
+ return rt->overridden.velocity;
+ } else {
+ RenderTarget::RTOverridden::SliceKey key(rt->overridden.velocity, p_layer);
+
+ if (!rt->overridden.cached_slices.has(key)) {
+ rt->overridden.cached_slices[key] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->overridden.velocity, p_layer, 0);
+ }
+
+ return rt->overridden.cached_slices[key];
+ }
}
void TextureStorage::render_target_set_transparent(RID p_render_target, bool p_is_transparent) {
@@ -2596,10 +2693,21 @@ void TextureStorage::render_target_set_transparent(RID p_render_target, bool p_i
_update_render_target(rt);
}
+bool TextureStorage::render_target_get_transparent(RID p_render_target) const {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND_V(!rt, false);
+
+ return rt->is_transparent;
+}
+
void TextureStorage::render_target_set_direct_to_screen(RID p_render_target, bool p_value) {
}
-bool TextureStorage::render_target_was_used(RID p_render_target) {
+bool TextureStorage::render_target_get_direct_to_screen(RID p_render_target) const {
+ return false;
+}
+
+bool TextureStorage::render_target_was_used(RID p_render_target) const {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, false);
return rt->was_used;
@@ -2622,25 +2730,29 @@ void TextureStorage::render_target_set_msaa(RID p_render_target, RS::ViewportMSA
_update_render_target(rt);
}
-Size2 TextureStorage::render_target_get_size(RID p_render_target) {
+RS::ViewportMSAA TextureStorage::render_target_get_msaa(RID p_render_target) const {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
- ERR_FAIL_COND_V(!rt, Size2());
+ ERR_FAIL_COND_V(!rt, RS::VIEWPORT_MSAA_DISABLED);
- return rt->size;
+ return rt->msaa;
}
RID TextureStorage::render_target_get_rd_framebuffer(RID p_render_target) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
- return rt->framebuffer;
+ return rt->get_framebuffer();
}
RID TextureStorage::render_target_get_rd_texture(RID p_render_target) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
- return rt->color;
+ if (rt->overridden.color.is_valid()) {
+ return rt->overridden.color;
+ } else {
+ return rt->color;
+ }
}
RID TextureStorage::render_target_get_rd_texture_slice(RID p_render_target, uint32_t p_layer) {
@@ -2711,7 +2823,7 @@ void TextureStorage::render_target_do_clear_request(RID p_render_target) {
}
Vector<Color> clear_colors;
clear_colors.push_back(rt->clear_color);
- RD::get_singleton()->draw_list_begin(rt->framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, clear_colors);
+ RD::get_singleton()->draw_list_begin(rt->get_framebuffer(), RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, clear_colors);
RD::get_singleton()->draw_list_end();
rt->clear_requested = false;
}
@@ -3140,18 +3252,18 @@ void TextureStorage::render_target_set_vrs_mode(RID p_render_target, RS::Viewpor
rt->vrs_mode = p_mode;
}
-void TextureStorage::render_target_set_vrs_texture(RID p_render_target, RID p_texture) {
+RS::ViewportVRSMode TextureStorage::render_target_get_vrs_mode(RID p_render_target) const {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
- ERR_FAIL_COND(!rt);
+ ERR_FAIL_COND_V(!rt, RS::VIEWPORT_VRS_DISABLED);
- rt->vrs_texture = p_texture;
+ return rt->vrs_mode;
}
-RS::ViewportVRSMode TextureStorage::render_target_get_vrs_mode(RID p_render_target) const {
+void TextureStorage::render_target_set_vrs_texture(RID p_render_target, RID p_texture) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
- ERR_FAIL_COND_V(!rt, RS::VIEWPORT_VRS_DISABLED);
+ ERR_FAIL_COND(!rt);
- return rt->vrs_mode;
+ rt->vrs_texture = p_texture;
}
RID TextureStorage::render_target_get_vrs_texture(RID p_render_target) const {
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
index 327a21a1fc..00b4e50737 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
@@ -301,7 +301,6 @@ private:
struct RenderTarget {
Size2i size;
uint32_t view_count;
- RID framebuffer;
RID color;
Vector<RID> color_slices;
RID color_multisample; // Needed when MSAA is enabled.
@@ -339,6 +338,43 @@ private:
RS::ViewportVRSMode vrs_mode = RS::VIEWPORT_VRS_DISABLED;
RID vrs_texture;
+ // overridden textures
+ struct RTOverridden {
+ RID color;
+ RID depth;
+ RID velocity;
+
+ // In a multiview scenario, which is the most likely where we
+ // override our destination textures, we need to obtain slices
+ // for each layer of these textures.
+ // These are likely changing every frame as we loop through
+ // texture chains hence we add a cache to manage these slices.
+ // For this we define a key using the RID of the texture and
+ // the layer for which we create a slice.
+ struct SliceKey {
+ RID rid;
+ uint32_t layer = 0;
+
+ bool operator==(const SliceKey &p_val) const {
+ return (rid == p_val.rid) && (layer == p_val.layer);
+ }
+
+ static uint32_t hash(const SliceKey &p_val) {
+ uint32_t h = hash_one_uint64(p_val.rid.get_id());
+ h = hash_murmur3_one_32(p_val.layer, h);
+ return hash_fmix32(h);
+ }
+
+ SliceKey() {}
+ SliceKey(RID p_rid, uint32_t p_layer) {
+ rid = p_rid;
+ layer = p_layer;
+ }
+ };
+
+ mutable HashMap<SliceKey, RID, SliceKey> cached_slices;
+ } overridden;
+
//texture generated for this owner (nor RD).
RID texture;
bool was_used;
@@ -346,6 +382,8 @@ private:
//clear request
bool clear_requested;
Color clear_color;
+
+ RID get_framebuffer();
};
mutable RID_Owner<RenderTarget> render_target_owner;
@@ -644,14 +682,17 @@ public:
virtual void render_target_free(RID p_rid) override;
virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) override;
+ virtual Point2i render_target_get_position(RID p_render_target) const override;
virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override;
- virtual RID render_target_get_texture(RID p_render_target) override;
- virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override;
+ virtual Size2i render_target_get_size(RID p_render_target) const override;
virtual void render_target_set_transparent(RID p_render_target, bool p_is_transparent) override;
+ virtual bool render_target_get_transparent(RID p_render_target) const override;
virtual void render_target_set_direct_to_screen(RID p_render_target, bool p_direct_to_screen) override;
- virtual bool render_target_was_used(RID p_render_target) override;
+ virtual bool render_target_get_direct_to_screen(RID p_render_target) const override;
+ virtual bool render_target_was_used(RID p_render_target) const override;
virtual void render_target_set_as_unused(RID p_render_target) override;
virtual void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) override;
+ virtual RS::ViewportMSAA render_target_get_msaa(RID p_render_target) const override;
void render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps);
void render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color);
@@ -673,12 +714,21 @@ public:
bool render_target_is_sdf_enabled(RID p_render_target) const;
virtual void render_target_set_vrs_mode(RID p_render_target, RS::ViewportVRSMode p_mode) override;
+ virtual RS::ViewportVRSMode render_target_get_vrs_mode(RID p_render_target) const override;
virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) override;
+ virtual RID render_target_get_vrs_texture(RID p_render_target) const override;
- RS::ViewportVRSMode render_target_get_vrs_mode(RID p_render_target) const;
- RID render_target_get_vrs_texture(RID p_render_target) const;
+ virtual void render_target_set_override_color(RID p_render_target, RID p_texture) override;
+ virtual RID render_target_get_override_color(RID p_render_target) const override;
+ virtual void render_target_set_override_depth(RID p_render_target, RID p_texture) override;
+ virtual RID render_target_get_override_depth(RID p_render_target) const override;
+ RID render_target_get_override_depth_slice(RID p_render_target, const uint32_t p_layer) const;
+ virtual void render_target_set_override_velocity(RID p_render_target, RID p_texture) override;
+ virtual RID render_target_get_override_velocity(RID p_render_target) const override;
+ RID render_target_get_override_velocity_slice(RID p_render_target, const uint32_t p_layer) const;
+
+ virtual RID render_target_get_texture(RID p_render_target) override;
- Size2 render_target_get_size(RID p_render_target);
RID render_target_get_rd_framebuffer(RID p_render_target);
RID render_target_get_rd_texture(RID p_render_target);
RID render_target_get_rd_texture_slice(RID p_render_target, uint32_t p_layer);
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index 1db018b647..4f7683493b 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -664,9 +664,9 @@ void RendererViewport::draw_viewports() {
RSG::texture_storage->render_target_set_as_unused(vp->render_target);
if (vp->use_xr && xr_interface.is_valid()) {
- // check for an external texture destination (disabled for now, not yet supported)
- // RSG::texture_storage->render_target_set_external_texture(vp->render_target, xr_interface->get_external_texture_for_eye(leftOrMono));
- RSG::texture_storage->render_target_set_external_texture(vp->render_target, 0);
+ RSG::texture_storage->render_target_set_override_color(vp->render_target, xr_interface->get_color_texture());
+ RSG::texture_storage->render_target_set_override_depth(vp->render_target, xr_interface->get_depth_texture());
+ RSG::texture_storage->render_target_set_override_velocity(vp->render_target, xr_interface->get_velocity_texture());
// render...
RSG::scene->set_debug_draw_mode(vp->debug_draw);
@@ -695,7 +695,9 @@ void RendererViewport::draw_viewports() {
}
}
} else {
- RSG::texture_storage->render_target_set_external_texture(vp->render_target, 0);
+ RSG::texture_storage->render_target_set_override_color(vp->render_target, RID()); // TODO if fullscreen output, we can set this to our texture chain
+ RSG::texture_storage->render_target_set_override_depth(vp->render_target, RID());
+ RSG::texture_storage->render_target_set_override_velocity(vp->render_target, RID());
RSG::scene->set_debug_draw_mode(vp->debug_draw);
diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h
index 5024a76c09..635f44786c 100644
--- a/servers/rendering/storage/texture_storage.h
+++ b/servers/rendering/storage/texture_storage.h
@@ -131,15 +131,18 @@ public:
virtual RID render_target_create() = 0;
virtual void render_target_free(RID p_rid) = 0;
- virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) = 0;
- virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) = 0;
- virtual RID render_target_get_texture(RID p_render_target) = 0;
- virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) = 0;
+ virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) = 0; // Q change input to const Point2i &p_position ?
+ virtual Point2i render_target_get_position(RID p_render_target) const = 0;
+ virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) = 0; // Q change input to const Size2i &p_size ?
+ virtual Size2i render_target_get_size(RID p_render_target) const = 0;
virtual void render_target_set_transparent(RID p_render_target, bool p_is_transparent) = 0;
+ virtual bool render_target_get_transparent(RID p_render_target) const = 0;
virtual void render_target_set_direct_to_screen(RID p_render_target, bool p_direct_to_screen) = 0;
- virtual bool render_target_was_used(RID p_render_target) = 0;
+ virtual bool render_target_get_direct_to_screen(RID p_render_target) const = 0;
+ virtual bool render_target_was_used(RID p_render_target) const = 0;
virtual void render_target_set_as_unused(RID p_render_target) = 0;
virtual void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) = 0;
+ virtual RS::ViewportMSAA render_target_get_msaa(RID p_render_target) const = 0;
virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) = 0;
virtual bool render_target_is_clear_requested(RID p_render_target) = 0;
@@ -152,7 +155,20 @@ public:
virtual void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) = 0;
virtual void render_target_set_vrs_mode(RID p_render_target, RS::ViewportVRSMode p_mode) = 0;
+ virtual RS::ViewportVRSMode render_target_get_vrs_mode(RID p_render_target) const = 0;
virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) = 0;
+ virtual RID render_target_get_vrs_texture(RID p_render_target) const = 0;
+
+ // override color, depth and velocity buffers (depth and velocity only for 3D)
+ virtual void render_target_set_override_color(RID p_render_target, RID p_texture) = 0;
+ virtual RID render_target_get_override_color(RID p_render_target) const = 0;
+ virtual void render_target_set_override_depth(RID p_render_target, RID p_texture) = 0;
+ virtual RID render_target_get_override_depth(RID p_render_target) const = 0;
+ virtual void render_target_set_override_velocity(RID p_render_target, RID p_texture) = 0;
+ virtual RID render_target_get_override_velocity(RID p_render_target) const = 0;
+
+ // get textures
+ virtual RID render_target_get_texture(RID p_render_target) = 0;
};
#endif // TEXTURE_STORAGE_H
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 57378708ba..750121719f 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -701,6 +701,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
}
uint32_t RenderingServer::mesh_surface_get_format_offset(uint32_t p_format, int p_vertex_len, int p_array_index) const {
+ ERR_FAIL_INDEX_V(p_array_index, ARRAY_MAX, 0);
p_format &= ~ARRAY_FORMAT_INDEX;
uint32_t offsets[ARRAY_MAX];
uint32_t vstr;
diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp
index 430a5bfd16..430e2042d9 100644
--- a/servers/xr/xr_interface.cpp
+++ b/servers/xr/xr_interface.cpp
@@ -241,6 +241,19 @@ RID XRInterface::get_vrs_texture() {
}
/** these are optional, so we want dummies **/
+
+RID XRInterface::get_color_texture() {
+ return RID();
+}
+
+RID XRInterface::get_depth_texture() {
+ return RID();
+}
+
+RID XRInterface::get_velocity_texture() {
+ return RID();
+}
+
PackedStringArray XRInterface::get_suggested_tracker_names() const {
PackedStringArray arr;
diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h
index 17ff5f8add..86d328d41c 100644
--- a/servers/xr/xr_interface.h
+++ b/servers/xr/xr_interface.h
@@ -121,8 +121,9 @@ public:
virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) = 0; /* get each views transform */
virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) = 0; /* get each view projection matrix */
virtual RID get_vrs_texture(); /* obtain VRS texture */
-
- // note, external color/depth/vrs texture support will be added here soon.
+ virtual RID get_color_texture(); /* obtain color output texture (if applicable) */
+ virtual RID get_depth_texture(); /* obtain depth output texture (if applicable, used for reprojection) */
+ virtual RID get_velocity_texture(); /* obtain velocity output texture (if applicable, used for spacewarp) */
virtual void process() = 0;
virtual void pre_render(){};
diff --git a/servers/xr/xr_interface_extension.cpp b/servers/xr/xr_interface_extension.cpp
index 7024a25528..0d4a53d287 100644
--- a/servers/xr/xr_interface_extension.cpp
+++ b/servers/xr/xr_interface_extension.cpp
@@ -74,6 +74,15 @@ void XRInterfaceExtension::_bind_methods() {
GDVIRTUAL_BIND(_set_anchor_detection_is_enabled, "enabled");
GDVIRTUAL_BIND(_get_camera_feed_id);
+ // override output methods
+ GDVIRTUAL_BIND(_get_color_texture);
+ GDVIRTUAL_BIND(_get_depth_texture);
+ GDVIRTUAL_BIND(_get_velocity_texture);
+
+ ClassDB::bind_method(D_METHOD("get_color_texture"), &XRInterfaceExtension::get_color_texture);
+ ClassDB::bind_method(D_METHOD("get_depth_texture"), &XRInterfaceExtension::get_depth_texture);
+ ClassDB::bind_method(D_METHOD("get_velocity_texture"), &XRInterfaceExtension::get_velocity_texture);
+
// helper methods
ClassDB::bind_method(D_METHOD("add_blit", "render_target", "src_rect", "dst_rect", "use_layer", "layer", "apply_lens_distortion", "eye_center", "k1", "k2", "upscale", "aspect_ratio"), &XRInterfaceExtension::add_blit);
ClassDB::bind_method(D_METHOD("get_render_target_texture", "render_target"), &XRInterfaceExtension::get_render_target_texture);
@@ -264,7 +273,7 @@ Projection XRInterfaceExtension::get_projection_for_view(uint32_t p_view, double
if (GDVIRTUAL_CALL(_get_projection_for_view, p_view, p_aspect, p_z_near, p_z_far, arr)) {
ERR_FAIL_COND_V_MSG(arr.size() != 16, Projection(), "Projection matrix must contain 16 floats");
- real_t *m = (real_t *)cm.matrix;
+ real_t *m = (real_t *)cm.columns;
for (int i = 0; i < 16; i++) {
m[i] = arr[i];
}
@@ -283,6 +292,33 @@ RID XRInterfaceExtension::get_vrs_texture() {
}
}
+RID XRInterfaceExtension::get_color_texture() {
+ RID texture;
+ if (GDVIRTUAL_CALL(_get_color_texture, texture)) {
+ return texture;
+ } else {
+ return RID();
+ }
+}
+
+RID XRInterfaceExtension::get_depth_texture() {
+ RID texture;
+ if (GDVIRTUAL_CALL(_get_depth_texture, texture)) {
+ return texture;
+ } else {
+ return RID();
+ }
+}
+
+RID XRInterfaceExtension::get_velocity_texture() {
+ RID texture;
+ if (GDVIRTUAL_CALL(_get_velocity_texture, texture)) {
+ return texture;
+ } else {
+ return RID();
+ }
+}
+
void XRInterfaceExtension::add_blit(RID p_render_target, Rect2 p_src_rect, Rect2i p_dst_rect, bool p_use_layer, uint32_t p_layer, bool p_apply_lens_distortion, Vector2 p_eye_center, double p_k1, double p_k2, double p_upscale, double p_aspect_ratio) {
BlitToScreen blit;
diff --git a/servers/xr/xr_interface_extension.h b/servers/xr/xr_interface_extension.h
index 65b474425e..2235b57cb3 100644
--- a/servers/xr/xr_interface_extension.h
+++ b/servers/xr/xr_interface_extension.h
@@ -102,6 +102,9 @@ public:
virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override;
virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override;
virtual RID get_vrs_texture() override;
+ virtual RID get_color_texture() override;
+ virtual RID get_depth_texture() override;
+ virtual RID get_velocity_texture() override;
GDVIRTUAL0R(Size2, _get_render_target_size);
GDVIRTUAL0R(uint32_t, _get_view_count);
@@ -109,6 +112,9 @@ public:
GDVIRTUAL2R(Transform3D, _get_transform_for_view, uint32_t, const Transform3D &);
GDVIRTUAL4R(PackedFloat64Array, _get_projection_for_view, uint32_t, double, double, double);
GDVIRTUAL0R(RID, _get_vrs_texture);
+ GDVIRTUAL0R(RID, _get_color_texture);
+ GDVIRTUAL0R(RID, _get_depth_texture);
+ GDVIRTUAL0R(RID, _get_velocity_texture);
void add_blit(RID p_render_target, Rect2 p_src_rect, Rect2i p_dst_rect, bool p_use_layer = false, uint32_t p_layer = 0, bool p_apply_lens_distortion = false, Vector2 p_eye_center = Vector2(), double p_k1 = 0.0, double p_k2 = 0.0, double p_upscale = 1.0, double p_aspect_ratio = 1.0);