summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/config/project_settings.cpp4
-rw-r--r--core/templates/list.h4
-rw-r--r--doc/classes/PhysicsServer2D.xml4
-rw-r--r--editor/editor_node.cpp3
-rw-r--r--editor/editor_properties_array_dict.cpp351
-rw-r--r--editor/editor_properties_array_dict.h34
-rw-r--r--editor/icons/TripleBar.svg1
-rw-r--r--editor/plugin_config_dialog.cpp1
-rw-r--r--editor/plugins/sub_viewport_preview_editor_plugin.cpp49
-rw-r--r--editor/plugins/sub_viewport_preview_editor_plugin.h56
-rw-r--r--editor/plugins/texture_editor_plugin.cpp141
-rw-r--r--editor/plugins/texture_editor_plugin.h18
-rw-r--r--editor/rename_dialog.cpp8
-rw-r--r--modules/fbx/data/fbx_material.cpp4
-rw-r--r--modules/fbx/data/import_state.h1
-rw-r--r--modules/fbx/editor_scene_importer_fbx.h1
-rw-r--r--modules/gdscript/editor/gdscript_translation_parser_plugin.h1
-rw-r--r--modules/gdscript/language_server/gdscript_language_protocol.h12
-rw-r--r--modules/gltf/editor_scene_importer_gltf.cpp22
-rw-r--r--modules/gltf/editor_scene_importer_gltf.h21
-rw-r--r--modules/gltf/gltf_document.cpp41
-rw-r--r--modules/gltf/gltf_document.h8
-rw-r--r--modules/gltf/gltf_state.h6
-rw-r--r--modules/mbedtls/tests/test_crypto_mbedtls.cpp2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs73
-rw-r--r--modules/navigation/navigation_mesh_generator.cpp2
-rw-r--r--modules/text_server_adv/dynamic_font_adv.h1
-rw-r--r--modules/text_server_fb/dynamic_font_fb.h1
-rw-r--r--modules/webrtc/webrtc_data_channel_gdnative.cpp1
-rw-r--r--modules/websocket/editor_debugger_server_websocket.h9
-rw-r--r--modules/websocket/remote_debugger_peer_websocket.h6
-rw-r--r--platform/javascript/os_javascript.cpp2
-rw-r--r--platform/uwp/export/export.cpp1
-rw-r--r--scene/2d/physics_body_2d.cpp99
-rw-r--r--scene/2d/physics_body_2d.h3
-rw-r--r--servers/physics_2d/physics_server_2d_sw.cpp4
-rw-r--r--servers/physics_2d/physics_server_2d_sw.h2
-rw-r--r--servers/physics_2d/physics_server_2d_wrap_mt.h4
-rw-r--r--servers/physics_2d/space_2d_sw.cpp11
-rw-r--r--servers/physics_2d/space_2d_sw.h2
-rw-r--r--servers/physics_server_2d.cpp10
-rw-r--r--servers/physics_server_2d.h4
42 files changed, 559 insertions, 469 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index ac4e0db5b7..84860b648d 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -30,7 +30,7 @@
#include "project_settings.h"
-#include "core/core_bind.h"
+#include "core/core_bind.h" // For Compression enum.
#include "core/core_string_names.h"
#include "core/input/input_map.h"
#include "core/io/dir_access.h"
@@ -42,8 +42,6 @@
#include "core/os/os.h"
#include "core/variant/variant_parser.h"
-#include <zlib.h>
-
ProjectSettings *ProjectSettings::singleton = nullptr;
ProjectSettings *ProjectSettings::get_singleton() {
diff --git a/core/templates/list.h b/core/templates/list.h
index 6047b89670..c2e17a2f6f 100644
--- a/core/templates/list.h
+++ b/core/templates/list.h
@@ -176,8 +176,8 @@ public:
return *this;
}
- _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; }
- _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; }
+ _FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return E == b.E; }
+ _FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return E != b.E; }
_FORCE_INLINE_ ConstIterator(const Element *p_E) { E = p_E; }
_FORCE_INLINE_ ConstIterator() {}
diff --git a/doc/classes/PhysicsServer2D.xml b/doc/classes/PhysicsServer2D.xml
index 67b27b174f..b492ddaa25 100644
--- a/doc/classes/PhysicsServer2D.xml
+++ b/doc/classes/PhysicsServer2D.xml
@@ -820,6 +820,10 @@
</argument>
<argument index="5" name="result" type="PhysicsTestMotionResult2D" default="null">
</argument>
+ <argument index="6" name="exclude_raycast_shapes" type="bool" default="true">
+ </argument>
+ <argument index="7" name="exclude" type="Array" default="[]">
+ </argument>
<description>
Returns [code]true[/code] if a collision would result from moving in the given direction from a given point in space. Margin increases the size of the shapes involved in the collision detection. [PhysicsTestMotionResult2D] can be passed to return additional information in.
</description>
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 4d52414748..f09a6f678a 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -31,7 +31,6 @@
#include "editor_node.h"
#include "core/config/project_settings.h"
-#include "core/core_bind.h"
#include "core/extension/native_extension_manager.h"
#include "core/input/input.h"
#include "core/io/config_file.h"
@@ -168,6 +167,7 @@
#include "editor/plugins/sprite_2d_editor_plugin.h"
#include "editor/plugins/sprite_frames_editor_plugin.h"
#include "editor/plugins/style_box_editor_plugin.h"
+#include "editor/plugins/sub_viewport_preview_editor_plugin.h"
#include "editor/plugins/text_editor.h"
#include "editor/plugins/texture_3d_editor_plugin.h"
#include "editor/plugins/texture_editor_plugin.h"
@@ -6841,6 +6841,7 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(MaterialEditorPlugin(this)));
add_editor_plugin(memnew(GPUParticlesCollisionSDFEditorPlugin(this)));
add_editor_plugin(memnew(InputEventEditorPlugin(this)));
+ add_editor_plugin(memnew(SubViewportPreviewEditorPlugin(this)));
for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) {
add_editor_plugin(EditorPlugins::create(i, this));
diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp
index 3216728be1..8b67b67571 100644
--- a/editor/editor_properties_array_dict.cpp
+++ b/editor/editor_properties_array_dict.cpp
@@ -30,16 +30,18 @@
#include "editor_properties_array_dict.h"
+#include "core/input/input.h"
#include "core/io/marshalls.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor_properties.h"
bool EditorPropertyArrayObject::_set(const StringName &p_name, const Variant &p_value) {
- String pn = p_name;
+ String name = p_name;
- if (pn.begins_with("indices")) {
- int idx = pn.get_slicec('/', 1).to_int();
- array.set(idx, p_value);
+ if (name.begins_with("indices")) {
+ int index = name.get_slicec('/', 1).to_int();
+ array.set(index, p_value);
return true;
}
@@ -47,12 +49,12 @@ bool EditorPropertyArrayObject::_set(const StringName &p_name, const Variant &p_
}
bool EditorPropertyArrayObject::_get(const StringName &p_name, Variant &r_ret) const {
- String pn = p_name;
+ String name = p_name;
- if (pn.begins_with("indices")) {
- int idx = pn.get_slicec('/', 1).to_int();
+ if (name.begins_with("indices")) {
+ int index = name.get_slicec('/', 1).to_int();
bool valid;
- r_ret = array.get(idx, &valid);
+ r_ret = array.get(index, &valid);
if (r_ret.get_type() == Variant::OBJECT && Object::cast_to<EncodedObjectAsID>(r_ret)) {
r_ret = Object::cast_to<EncodedObjectAsID>(r_ret)->get_object_id();
}
@@ -77,21 +79,21 @@ EditorPropertyArrayObject::EditorPropertyArrayObject() {
///////////////////
bool EditorPropertyDictionaryObject::_set(const StringName &p_name, const Variant &p_value) {
- String pn = p_name;
+ String name = p_name;
- if (pn == "new_item_key") {
+ if (name == "new_item_key") {
new_item_key = p_value;
return true;
}
- if (pn == "new_item_value") {
+ if (name == "new_item_value") {
new_item_value = p_value;
return true;
}
- if (pn.begins_with("indices")) {
- int idx = pn.get_slicec('/', 1).to_int();
- Variant key = dict.get_key_at_index(idx);
+ if (name.begins_with("indices")) {
+ int index = name.get_slicec('/', 1).to_int();
+ Variant key = dict.get_key_at_index(index);
dict[key] = p_value;
return true;
}
@@ -100,21 +102,21 @@ bool EditorPropertyDictionaryObject::_set(const StringName &p_name, const Varian
}
bool EditorPropertyDictionaryObject::_get(const StringName &p_name, Variant &r_ret) const {
- String pn = p_name;
+ String name = p_name;
- if (pn == "new_item_key") {
+ if (name == "new_item_key") {
r_ret = new_item_key;
return true;
}
- if (pn == "new_item_value") {
+ if (name == "new_item_value") {
r_ret = new_item_value;
return true;
}
- if (pn.begins_with("indices")) {
- int idx = pn.get_slicec('/', 1).to_int();
- Variant key = dict.get_key_at_index(idx);
+ if (name.begins_with("indices")) {
+ int index = name.get_slicec('/', 1).to_int();
+ Variant key = dict.get_key_at_index(index);
r_ret = dict[key];
if (r_ret.get_type() == Variant::OBJECT && Object::cast_to<EncodedObjectAsID>(r_ret)) {
r_ret = Object::cast_to<EncodedObjectAsID>(r_ret)->get_object_id();
@@ -157,13 +159,13 @@ EditorPropertyDictionaryObject::EditorPropertyDictionaryObject() {
void EditorPropertyArray::_property_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing) {
if (p_property.begins_with("indices")) {
- int idx = p_property.get_slice("/", 1).to_int();
+ int index = p_property.get_slice("/", 1).to_int();
Variant array = object->get_array();
- array.set(idx, p_value);
+ array.set(index, p_value);
emit_changed(get_edited_property(), array, "", true);
if (array.get_type() == Variant::ARRAY) {
- array = array.call("duplicate"); //dupe, so undo/redo works better
+ array = array.call("duplicate"); // Duplicate, so undo/redo works better.
}
object->set_array(array);
}
@@ -171,7 +173,7 @@ void EditorPropertyArray::_property_changed(const String &p_property, Variant p_
void EditorPropertyArray::_change_type(Object *p_button, int p_index) {
Button *button = Object::cast_to<Button>(p_button);
- changing_type_idx = p_index;
+ changing_type_index = p_index;
Rect2 rect = button->get_screen_rect();
change_type->set_as_minsize();
change_type->set_position(rect.position + rect.size - Vector2(change_type->get_contents_minimum_size().x, 0));
@@ -180,7 +182,7 @@ void EditorPropertyArray::_change_type(Object *p_button, int p_index) {
void EditorPropertyArray::_change_type_menu(int p_index) {
if (p_index == Variant::VARIANT_MAX) {
- _remove_pressed(changing_type_idx);
+ _remove_pressed(changing_type_index);
return;
}
@@ -188,12 +190,12 @@ void EditorPropertyArray::_change_type_menu(int p_index) {
Callable::CallError ce;
Variant::construct(Variant::Type(p_index), value, nullptr, 0, ce);
Variant array = object->get_array();
- array.set(changing_type_idx, value);
+ array.set(changing_type_index, value);
emit_changed(get_edited_property(), array, "", true);
if (array.get_type() == Variant::ARRAY) {
- array = array.call("duplicate"); //dupe, so undo/redo works better
+ array = array.call("duplicate"); // Duplicate, so undo/redo works better.
}
object->set_array(array);
@@ -213,7 +215,7 @@ void EditorPropertyArray::update_property() {
arrtype = "Array";
} break;
- // arrays
+ // Arrays.
case Variant::PACKED_BYTE_ARRAY: {
arrtype = "PackedByteArray";
} break;
@@ -256,7 +258,12 @@ void EditorPropertyArray::update_property() {
return;
}
- edit->set_text(arrtype + " (size " + itos(array.call("size")) + ")");
+ int size = array.call("size");
+ int pages = MAX(0, size - 1) / page_length + 1;
+ page_index = MIN(page_index, pages - 1);
+ int offset = page_index * page_length;
+
+ edit->set_text(arrtype + " (size " + itos(size) + ")");
bool unfolded = get_edited_object()->editor_is_section_unfolded(get_edited_property());
if (edit->is_pressed() != unfolded) {
@@ -270,50 +277,50 @@ void EditorPropertyArray::update_property() {
vbox = memnew(VBoxContainer);
add_child(vbox);
set_bottom_editor(vbox);
- HBoxContainer *hbc = memnew(HBoxContainer);
- vbox->add_child(hbc);
+
+ HBoxContainer *hbox = memnew(HBoxContainer);
+ vbox->add_child(hbox);
+
Label *label = memnew(Label(TTR("Size: ")));
label->set_h_size_flags(SIZE_EXPAND_FILL);
- hbc->add_child(label);
- length = memnew(EditorSpinSlider);
- length->set_step(1);
- length->set_max(1000000);
- length->set_h_size_flags(SIZE_EXPAND_FILL);
- hbc->add_child(length);
- length->connect("value_changed", callable_mp(this, &EditorPropertyArray::_length_changed));
-
- page_hb = memnew(HBoxContainer);
- vbox->add_child(page_hb);
- label = memnew(Label(TTR("Page: ")));
- label->set_h_size_flags(SIZE_EXPAND_FILL);
- page_hb->add_child(label);
- page = memnew(EditorSpinSlider);
- page->set_step(1);
- page_hb->add_child(page);
- page->set_h_size_flags(SIZE_EXPAND_FILL);
- page->connect("value_changed", callable_mp(this, &EditorPropertyArray::_page_changed));
- } else {
- //bye bye children of the box
- while (vbox->get_child_count() > 2) {
- vbox->get_child(2)->queue_delete(); // button still needed after pressed is called
- vbox->remove_child(vbox->get_child(2));
- }
- }
+ hbox->add_child(label);
- int len = array.call("size");
+ size_slider = memnew(EditorSpinSlider);
+ size_slider->set_step(1);
+ size_slider->set_max(1000000);
+ size_slider->set_h_size_flags(SIZE_EXPAND_FILL);
+ size_slider->connect("value_changed", callable_mp(this, &EditorPropertyArray::_length_changed));
+ hbox->add_child(size_slider);
- length->set_value(len);
+ page_hbox = memnew(HBoxContainer);
+ vbox->add_child(page_hbox);
- int pages = MAX(0, len - 1) / page_len + 1;
+ label = memnew(Label(TTR("Page: ")));
+ label->set_h_size_flags(SIZE_EXPAND_FILL);
+ page_hbox->add_child(label);
- page->set_max(pages);
- page_idx = MIN(page_idx, pages - 1);
- page->set_value(page_idx);
- page_hb->set_visible(pages > 1);
+ page_slider = memnew(EditorSpinSlider);
+ page_slider->set_step(1);
+ page_slider->set_h_size_flags(SIZE_EXPAND_FILL);
+ page_slider->connect("value_changed", callable_mp(this, &EditorPropertyArray::_page_changed));
+ page_hbox->add_child(page_slider);
+ } else {
+ // Bye bye children of the box.
+ for (int i = vbox->get_child_count() - 1; i >= 2; i--) {
+ Node *child = vbox->get_child(i);
+ if (child == reorder_selected_element_hbox) {
+ continue; // Don't remove the property that the user is moving.
+ }
- int offset = page_idx * page_len;
+ child->queue_delete(); // Button still needed after pressed is called.
+ vbox->remove_child(child);
+ }
+ }
- int amount = MIN(len - offset, page_len);
+ size_slider->set_value(size);
+ page_slider->set_max(pages);
+ page_slider->set_value(page_index);
+ page_hbox->set_visible(pages > 1);
if (array.get_type() == Variant::ARRAY) {
array = array.call("duplicate");
@@ -321,7 +328,31 @@ void EditorPropertyArray::update_property() {
object->set_array(array);
+ int amount = MIN(size - offset, page_length);
for (int i = 0; i < amount; i++) {
+ bool reorder_is_from_current_page = reorder_from_index / page_length == page_index;
+ if (reorder_is_from_current_page && i == reorder_from_index % page_length) {
+ // Don't duplicate the property that the user is moving.
+ continue;
+ }
+ if (!reorder_is_from_current_page && i == reorder_to_index % page_length) {
+ // Don't create the property the moving property will take the place of,
+ // e.g. (if page_length == 20) don't create element 20 if dragging an item from
+ // the first page to the second page because element 20 would become element 19.
+ continue;
+ }
+
+ HBoxContainer *hbox = memnew(HBoxContainer);
+ vbox->add_child(hbox);
+
+ Button *reorder_button = memnew(Button);
+ reorder_button->set_icon(get_theme_icon("TripleBar", "EditorIcons"));
+ reorder_button->set_default_cursor_shape(Control::CURSOR_MOVE);
+ reorder_button->connect("gui_input", callable_mp(this, &EditorPropertyArray::_reorder_button_gui_input));
+ reorder_button->connect("button_down", callable_mp(this, &EditorPropertyArray::_reorder_button_down), varray(i + offset));
+ reorder_button->connect("button_up", callable_mp(this, &EditorPropertyArray::_reorder_button_up));
+ hbox->add_child(reorder_button);
+
String prop_name = "indices/" + itos(i + offset);
EditorProperty *prop = nullptr;
@@ -346,29 +377,29 @@ void EditorPropertyArray::update_property() {
prop->connect("property_changed", callable_mp(this, &EditorPropertyArray::_property_changed));
prop->connect("object_id_selected", callable_mp(this, &EditorPropertyArray::_object_id_selected));
prop->set_h_size_flags(SIZE_EXPAND_FILL);
-
- HBoxContainer *hb = memnew(HBoxContainer);
-
- vbox->add_child(hb);
- hb->add_child(prop);
+ hbox->add_child(prop);
bool is_untyped_array = array.get_type() == Variant::ARRAY && subtype == Variant::NIL;
if (is_untyped_array) {
Button *edit = memnew(Button);
edit->set_icon(get_theme_icon("Edit", "EditorIcons"));
- hb->add_child(edit);
+ hbox->add_child(edit);
edit->connect("pressed", callable_mp(this, &EditorPropertyArray::_change_type), varray(edit, i + offset));
} else {
Button *remove = memnew(Button);
remove->set_icon(get_theme_icon("Remove", "EditorIcons"));
remove->connect("pressed", callable_mp(this, &EditorPropertyArray::_remove_pressed), varray(i + offset));
- hb->add_child(remove);
+ hbox->add_child(remove);
}
prop->update_property();
}
+ if (reorder_to_index % page_length > 0) {
+ vbox->move_child(vbox->get_child(2), reorder_to_index % page_length + 2);
+ }
+
updating = false;
} else {
@@ -384,12 +415,7 @@ void EditorPropertyArray::_remove_pressed(int p_index) {
Variant array = object->get_array();
array.call("remove", p_index);
- if (array.get_type() == Variant::ARRAY) {
- array = array.call("duplicate");
- }
-
emit_changed(get_edited_property(), array, "", false);
- object->set_array(array);
update_property();
}
@@ -414,14 +440,14 @@ bool EditorPropertyArray::_is_drop_valid(const Dictionary &p_drag_data) const {
for (int j = 0; j < allowed_type.get_slice_count(","); j++) {
String at = allowed_type.get_slice(",", j).strip_edges();
- // Fail if one of the files is not of allowed type
+ // Fail if one of the files is not of allowed type.
if (!ClassDB::is_parent_class(ftype, at)) {
return false;
}
}
}
- // If no files fail, drop is valid
+ // If no files fail, drop is valid.
return true;
}
@@ -442,13 +468,13 @@ void EditorPropertyArray::drop_data_fw(const Point2 &p_point, const Variant &p_d
Variant array = object->get_array();
- // Handle the case where array is not initialised yet
+ // Handle the case where array is not initialised yet.
if (!array.is_array()) {
Callable::CallError ce;
Variant::construct(array_type, array, nullptr, 0, ce);
}
- // Loop the file array and add to existing array
+ // Loop the file array and add to existing array.
for (int i = 0; i < files.size(); i++) {
String file = files[i];
@@ -504,7 +530,7 @@ void EditorPropertyArray::_page_changed(double p_page) {
if (updating) {
return;
}
- page_idx = p_page;
+ page_index = p_page;
update_property();
}
@@ -530,10 +556,10 @@ void EditorPropertyArray::_length_changed(double p_page) {
}
}
}
- array = array.call("duplicate"); //dupe, so undo/redo works better
+ array = array.call("duplicate"); // Duplicate, so undo/redo works better.
} else {
int size = array.call("size");
- // Pool*Array don't initialize their elements, have to do it manually
+ // Pool*Array don't initialize their elements, have to do it manually.
for (int i = previous_size; i < size; i++) {
Callable::CallError ce;
Variant r;
@@ -551,7 +577,7 @@ void EditorPropertyArray::setup(Variant::Type p_array_type, const String &p_hint
array_type = p_array_type;
// The format of p_hint_string is:
- // subType/subTypeHint:nextSubtype ... etc
+ // subType/subTypeHint:nextSubtype ... etc.
if (array_type == Variant::ARRAY && !p_hint_string.is_empty()) {
int hint_subtype_separator = p_hint_string.find(":");
if (hint_subtype_separator >= 0) {
@@ -568,6 +594,73 @@ void EditorPropertyArray::setup(Variant::Type p_array_type, const String &p_hint
}
}
+void EditorPropertyArray::_reorder_button_gui_input(const Ref<InputEvent> &p_event) {
+ if (reorder_from_index < 0) {
+ return;
+ }
+
+ Ref<InputEventMouseMotion> mm = p_event;
+ if (mm.is_valid()) {
+ Variant array = object->get_array();
+ int size = array.call("size");
+
+ if ((reorder_to_index == 0 && mm->get_relative().y < 0.0f) || (reorder_to_index == size - 1 && mm->get_relative().y > 0.0f)) {
+ return;
+ }
+
+ reorder_mouse_y_delta += mm->get_relative().y;
+ float required_y_distance = 20.0f * EDSCALE;
+ if (ABS(reorder_mouse_y_delta) > required_y_distance) {
+ int direction = reorder_mouse_y_delta > 0.0f ? 1 : -1;
+ reorder_mouse_y_delta -= required_y_distance * direction;
+
+ reorder_to_index += direction;
+ if ((direction < 0 && reorder_to_index % page_length == page_length - 1) || (direction > 0 && reorder_to_index % page_length == 0)) {
+ // Automatically move to the next/previous page.
+ page_slider->set_value(page_index + direction);
+ }
+ vbox->move_child(reorder_selected_element_hbox, reorder_to_index % page_length + 2);
+ // Ensure the moving element is visible.
+ EditorNode::get_singleton()->get_inspector()->ensure_control_visible(reorder_selected_element_hbox);
+ }
+ }
+}
+
+void EditorPropertyArray::_reorder_button_down(int p_index) {
+ reorder_from_index = p_index;
+ reorder_to_index = p_index;
+ reorder_selected_element_hbox = Object::cast_to<HBoxContainer>(vbox->get_child(p_index % page_length + 2));
+ reorder_selected_button = Object::cast_to<Button>(reorder_selected_element_hbox->get_child(0));
+ // Ideally it'd to be able to show the mouse but I had issues with
+ // Control's `mouse_exit()`/`mouse_entered()` signals not getting called.
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
+}
+
+void EditorPropertyArray::_reorder_button_up() {
+ if (reorder_from_index != reorder_to_index) {
+ // Move the element.
+ Variant array = object->get_array();
+
+ Variant value_to_move = array.get(reorder_from_index);
+ array.call("remove", reorder_from_index);
+ array.call("insert", reorder_to_index, value_to_move);
+
+ emit_changed(get_edited_property(), array, "", false);
+ object->set_array(array);
+ update_property();
+ }
+
+ reorder_from_index = -1;
+ reorder_to_index = -1;
+ reorder_mouse_y_delta = 0.0f;
+
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+ reorder_selected_button->warp_mouse(reorder_selected_button->get_size() / 2.0f);
+
+ reorder_selected_element_hbox = nullptr;
+ reorder_selected_button = nullptr;
+}
+
void EditorPropertyArray::_bind_methods() {
ClassDB::bind_method(D_METHOD("_can_drop_data_fw"), &EditorPropertyArray::can_drop_data_fw);
ClassDB::bind_method(D_METHOD("_drop_data_fw"), &EditorPropertyArray::drop_data_fw);
@@ -575,7 +668,7 @@ void EditorPropertyArray::_bind_methods() {
EditorPropertyArray::EditorPropertyArray() {
object.instantiate();
- page_len = int(EDITOR_GET("interface/inspector/max_array_dictionary_items_per_page"));
+ page_length = int(EDITOR_GET("interface/inspector/max_array_dictionary_items_per_page"));
edit = memnew(Button);
edit->set_h_size_flags(SIZE_EXPAND_FILL);
edit->set_clip_text(true);
@@ -586,8 +679,8 @@ EditorPropertyArray::EditorPropertyArray() {
add_child(edit);
add_focusable(edit);
vbox = nullptr;
- page = nullptr;
- length = nullptr;
+ page_slider = nullptr;
+ size_slider = nullptr;
updating = false;
change_type = memnew(PopupMenu);
add_child(change_type);
@@ -599,7 +692,7 @@ EditorPropertyArray::EditorPropertyArray() {
}
change_type->add_separator();
change_type->add_item(TTR("Remove Item"), Variant::VARIANT_MAX);
- changing_type_idx = -1;
+ changing_type_index = -1;
subtype = Variant::NIL;
subtype_hint = PROPERTY_HINT_NONE;
@@ -616,14 +709,14 @@ void EditorPropertyDictionary::_property_changed(const String &p_property, Varia
} else if (p_property == "new_item_value") {
object->set_new_item_value(p_value);
} else if (p_property.begins_with("indices")) {
- int idx = p_property.get_slice("/", 1).to_int();
+ int index = p_property.get_slice("/", 1).to_int();
Dictionary dict = object->get_dict();
- Variant key = dict.get_key_at_index(idx);
+ Variant key = dict.get_key_at_index(index);
dict[key] = p_value;
emit_changed(get_edited_property(), dict, "", true);
- dict = dict.duplicate(); //dupe, so undo/redo works better
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better\.
object->set_dict(dict);
}
}
@@ -635,7 +728,7 @@ void EditorPropertyDictionary::_change_type(Object *p_button, int p_index) {
change_type->set_as_minsize();
change_type->set_position(rect.position + rect.size - Vector2(change_type->get_contents_minimum_size().x, 0));
change_type->popup();
- changing_type_idx = p_index;
+ changing_type_index = p_index;
}
void EditorPropertyDictionary::_add_key_value() {
@@ -652,17 +745,17 @@ void EditorPropertyDictionary::_add_key_value() {
emit_changed(get_edited_property(), dict, "", false);
- dict = dict.duplicate(); //dupe, so undo/redo works better
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better.
object->set_dict(dict);
update_property();
}
void EditorPropertyDictionary::_change_type_menu(int p_index) {
- if (changing_type_idx < 0) {
+ if (changing_type_index < 0) {
Variant value;
Callable::CallError ce;
Variant::construct(Variant::Type(p_index), value, nullptr, 0, ce);
- if (changing_type_idx == -1) {
+ if (changing_type_index == -1) {
object->set_new_item_key(value);
} else {
object->set_new_item_value(value);
@@ -677,16 +770,16 @@ void EditorPropertyDictionary::_change_type_menu(int p_index) {
Variant value;
Callable::CallError ce;
Variant::construct(Variant::Type(p_index), value, nullptr, 0, ce);
- Variant key = dict.get_key_at_index(changing_type_idx);
+ Variant key = dict.get_key_at_index(changing_type_index);
dict[key] = value;
} else {
- Variant key = dict.get_key_at_index(changing_type_idx);
+ Variant key = dict.get_key_at_index(changing_type_index);
dict.erase(key);
}
emit_changed(get_edited_property(), dict, "", false);
- dict = dict.duplicate(); //dupe, so undo/redo works better
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better\.
object->set_dict(dict);
update_property();
}
@@ -695,7 +788,7 @@ void EditorPropertyDictionary::update_property() {
Variant updated_val = get_edited_object()->get(get_edited_property());
if (updated_val.get_type() == Variant::NIL) {
- edit->set_text("Dictionary (Nil)"); //This provides symmetry with the array property.
+ edit->set_text("Dictionary (Nil)"); // This provides symmetry with the array property.
edit->set_pressed(false);
if (vbox) {
set_bottom_editor(nullptr);
@@ -722,16 +815,16 @@ void EditorPropertyDictionary::update_property() {
add_child(vbox);
set_bottom_editor(vbox);
- page_hb = memnew(HBoxContainer);
- vbox->add_child(page_hb);
+ page_hbox = memnew(HBoxContainer);
+ vbox->add_child(page_hbox);
Label *label = memnew(Label(TTR("Page: ")));
label->set_h_size_flags(SIZE_EXPAND_FILL);
- page_hb->add_child(label);
- page = memnew(EditorSpinSlider);
- page->set_step(1);
- page_hb->add_child(page);
- page->set_h_size_flags(SIZE_EXPAND_FILL);
- page->connect("value_changed", callable_mp(this, &EditorPropertyDictionary::_page_changed));
+ page_hbox->add_child(label);
+ page_slider = memnew(EditorSpinSlider);
+ page_slider->set_step(1);
+ page_hbox->add_child(page_slider);
+ page_slider->set_h_size_flags(SIZE_EXPAND_FILL);
+ page_slider->connect("value_changed", callable_mp(this, &EditorPropertyDictionary::_page_changed));
} else {
// Queue children for deletion, deleting immediately might cause errors.
for (int i = 1; i < vbox->get_child_count(); i++) {
@@ -739,18 +832,18 @@ void EditorPropertyDictionary::update_property() {
}
}
- int len = dict.size();
+ int size = dict.size();
- int pages = MAX(0, len - 1) / page_len + 1;
+ int pages = MAX(0, size - 1) / page_length + 1;
- page->set_max(pages);
- page_idx = MIN(page_idx, pages - 1);
- page->set_value(page_idx);
- page_hb->set_visible(pages > 1);
+ page_slider->set_max(pages);
+ page_index = MIN(page_index, pages - 1);
+ page_slider->set_value(page_index);
+ page_hbox->set_visible(pages > 1);
- int offset = page_idx * page_len;
+ int offset = page_index * page_length;
- int amount = MIN(len - offset, page_len);
+ int amount = MIN(size - offset, page_length);
dict = dict.duplicate();
@@ -782,7 +875,7 @@ void EditorPropertyDictionary::update_property() {
} break;
- // atomic types
+ // Atomic types.
case Variant::BOOL: {
prop = memnew(EditorPropertyCheck);
@@ -803,7 +896,7 @@ void EditorPropertyDictionary::update_property() {
} break;
- // math types
+ // Math types.
case Variant::VECTOR2: {
EditorPropertyVector2 *editor = memnew(EditorPropertyVector2);
editor->setup(-100000, 100000, 0.001, true);
@@ -877,7 +970,7 @@ void EditorPropertyDictionary::update_property() {
} break;
- // misc types
+ // Miscellaneous types.
case Variant::COLOR: {
prop = memnew(EditorPropertyColor);
@@ -919,7 +1012,7 @@ void EditorPropertyDictionary::update_property() {
prop = editor;
} break;
- // arrays
+ // Arrays.
case Variant::PACKED_BYTE_ARRAY: {
EditorPropertyArray *editor = memnew(EditorPropertyArray);
editor->setup(Variant::PACKED_BYTE_ARRAY);
@@ -1003,17 +1096,17 @@ void EditorPropertyDictionary::update_property() {
prop->connect("property_changed", callable_mp(this, &EditorPropertyDictionary::_property_changed));
prop->connect("object_id_selected", callable_mp(this, &EditorPropertyDictionary::_object_id_selected));
- HBoxContainer *hb = memnew(HBoxContainer);
+ HBoxContainer *hbox = memnew(HBoxContainer);
if (add_vbox) {
- add_vbox->add_child(hb);
+ add_vbox->add_child(hbox);
} else {
- vbox->add_child(hb);
+ vbox->add_child(hbox);
}
- hb->add_child(prop);
+ hbox->add_child(prop);
prop->set_h_size_flags(SIZE_EXPAND_FILL);
Button *edit = memnew(Button);
edit->set_icon(get_theme_icon("Edit", "EditorIcons"));
- hb->add_child(edit);
+ hbox->add_child(edit);
edit->connect("pressed", callable_mp(this, &EditorPropertyDictionary::_change_type), varray(edit, change_index));
prop->update_property();
@@ -1060,7 +1153,7 @@ void EditorPropertyDictionary::_page_changed(double p_page) {
if (updating) {
return;
}
- page_idx = p_page;
+ page_index = p_page;
update_property();
}
@@ -1069,7 +1162,7 @@ void EditorPropertyDictionary::_bind_methods() {
EditorPropertyDictionary::EditorPropertyDictionary() {
object.instantiate();
- page_len = int(EDITOR_GET("interface/inspector/max_array_dictionary_items_per_page"));
+ page_length = int(EDITOR_GET("interface/inspector/max_array_dictionary_items_per_page"));
edit = memnew(Button);
edit->set_h_size_flags(SIZE_EXPAND_FILL);
edit->set_clip_text(true);
@@ -1078,7 +1171,7 @@ EditorPropertyDictionary::EditorPropertyDictionary() {
add_child(edit);
add_focusable(edit);
vbox = nullptr;
- page = nullptr;
+ page_slider = nullptr;
updating = false;
change_type = memnew(PopupMenu);
add_child(change_type);
@@ -1090,5 +1183,5 @@ EditorPropertyDictionary::EditorPropertyDictionary() {
}
change_type->add_separator();
change_type->add_item(TTR("Remove Item"), Variant::VARIANT_MAX);
- changing_type_idx = -1;
+ changing_type_index = -1;
}
diff --git a/editor/editor_properties_array_dict.h b/editor/editor_properties_array_dict.h
index aa2d8744b1..7547d57346 100644
--- a/editor/editor_properties_array_dict.h
+++ b/editor/editor_properties_array_dict.h
@@ -84,19 +84,25 @@ class EditorPropertyArray : public EditorProperty {
bool dropping;
Ref<EditorPropertyArrayObject> object;
- int page_len = 20;
- int page_idx = 0;
- int changing_type_idx;
+ int page_length = 20;
+ int page_index = 0;
+ int changing_type_index;
Button *edit;
VBoxContainer *vbox;
- EditorSpinSlider *length;
- EditorSpinSlider *page;
- HBoxContainer *page_hb;
+ EditorSpinSlider *size_slider;
+ EditorSpinSlider *page_slider;
+ HBoxContainer *page_hbox;
Variant::Type array_type;
Variant::Type subtype;
PropertyHint subtype_hint;
String subtype_hint_string;
+ int reorder_from_index = -1;
+ int reorder_to_index = -1;
+ float reorder_mouse_y_delta = 0.0f;
+ HBoxContainer *reorder_selected_element_hbox = nullptr;
+ Button *reorder_selected_button = nullptr;
+
void _page_changed(double p_page);
void _length_changed(double p_page);
void _edit_pressed();
@@ -112,6 +118,10 @@ class EditorPropertyArray : public EditorProperty {
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
+ void _reorder_button_gui_input(const Ref<InputEvent> &p_event);
+ void _reorder_button_down(int p_index);
+ void _reorder_button_up();
+
protected:
static void _bind_methods();
void _notification(int p_what);
@@ -129,14 +139,14 @@ class EditorPropertyDictionary : public EditorProperty {
bool updating;
Ref<EditorPropertyDictionaryObject> object;
- int page_len = 20;
- int page_idx = 0;
- int changing_type_idx;
+ int page_length = 20;
+ int page_index = 0;
+ int changing_type_index;
Button *edit;
VBoxContainer *vbox;
- EditorSpinSlider *length;
- EditorSpinSlider *page;
- HBoxContainer *page_hb;
+ EditorSpinSlider *size_slider;
+ EditorSpinSlider *page_slider;
+ HBoxContainer *page_hbox;
void _page_changed(double p_page);
void _edit_pressed();
diff --git a/editor/icons/TripleBar.svg b/editor/icons/TripleBar.svg
new file mode 100644
index 0000000000..2b521e6c15
--- /dev/null
+++ b/editor/icons/TripleBar.svg
@@ -0,0 +1 @@
+<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m1.9375 4h12.062zm0 4h12.062zm0 4h12.062z" fill="none" stroke="#e0e0e0" stroke-opacity=".99608" stroke-width=".92823"/></svg>
diff --git a/editor/plugin_config_dialog.cpp b/editor/plugin_config_dialog.cpp
index f55d77d782..cbcc3c9880 100644
--- a/editor/plugin_config_dialog.cpp
+++ b/editor/plugin_config_dialog.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "plugin_config_dialog.h"
+
#include "core/io/config_file.h"
#include "core/io/dir_access.h"
#include "editor/editor_node.h"
diff --git a/editor/plugins/sub_viewport_preview_editor_plugin.cpp b/editor/plugins/sub_viewport_preview_editor_plugin.cpp
new file mode 100644
index 0000000000..5fd173cae3
--- /dev/null
+++ b/editor/plugins/sub_viewport_preview_editor_plugin.cpp
@@ -0,0 +1,49 @@
+/*************************************************************************/
+/* sub_viewport_preview_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 "sub_viewport_preview_editor_plugin.h"
+
+bool EditorInspectorPluginSubViewportPreview::can_handle(Object *p_object) {
+ return Object::cast_to<SubViewport>(p_object) != nullptr;
+}
+
+void EditorInspectorPluginSubViewportPreview::parse_begin(Object *p_object) {
+ SubViewport *sub_viewport = Object::cast_to<SubViewport>(p_object);
+
+ TexturePreview *sub_viewport_preview = memnew(TexturePreview(sub_viewport->get_texture(), false));
+ sub_viewport->connect("size_changed", callable_mp((CanvasItem *)sub_viewport_preview->get_texture_display(), &CanvasItem::update));
+ add_custom_control(sub_viewport_preview);
+}
+
+SubViewportPreviewEditorPlugin::SubViewportPreviewEditorPlugin(EditorNode *p_node) {
+ Ref<EditorInspectorPluginSubViewportPreview> plugin;
+ plugin.instantiate();
+ add_inspector_plugin(plugin);
+}
diff --git a/editor/plugins/sub_viewport_preview_editor_plugin.h b/editor/plugins/sub_viewport_preview_editor_plugin.h
new file mode 100644
index 0000000000..03b8b678d1
--- /dev/null
+++ b/editor/plugins/sub_viewport_preview_editor_plugin.h
@@ -0,0 +1,56 @@
+/*************************************************************************/
+/* sub_viewport_preview_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 SUB_VIEWPORT_PREVIEW_EDITOR_PLUGIN_H
+#define SUB_VIEWPORT_PREVIEW_EDITOR_PLUGIN_H
+
+#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
+#include "editor/plugins/texture_editor_plugin.h"
+#include "scene/main/viewport.h"
+
+class EditorInspectorPluginSubViewportPreview : public EditorInspectorPluginTexture {
+ GDCLASS(EditorInspectorPluginSubViewportPreview, EditorInspectorPluginTexture);
+
+public:
+ virtual bool can_handle(Object *p_object) override;
+ virtual void parse_begin(Object *p_object) override;
+};
+
+class SubViewportPreviewEditorPlugin : public EditorPlugin {
+ GDCLASS(SubViewportPreviewEditorPlugin, EditorPlugin);
+
+public:
+ virtual String get_name() const override { return "SubViewportPreview"; }
+
+ SubViewportPreviewEditorPlugin(EditorNode *p_node);
+};
+
+#endif // SUB_VIEWPORT_PREVIEW_EDITOR_PLUGIN_H
diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp
index 10b942d9ee..6ee652098d 100644
--- a/editor/plugins/texture_editor_plugin.cpp
+++ b/editor/plugins/texture_editor_plugin.cpp
@@ -30,132 +30,69 @@
#include "texture_editor_plugin.h"
-#include "core/config/project_settings.h"
-#include "core/io/resource_loader.h"
-#include "editor/editor_settings.h"
+#include "editor/editor_scale.h"
-void TextureEditor::_gui_input(Ref<InputEvent> p_event) {
+TextureRect *TexturePreview::get_texture_display() {
+ return texture_display;
}
-void TextureEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_READY) {
- //get_scene()->connect("node_removed",this,"_node_removed");
- }
-
- if (p_what == NOTIFICATION_DRAW) {
- Ref<Texture2D> checkerboard = get_theme_icon("Checkerboard", "EditorIcons");
- Size2 size = get_size();
-
- draw_texture_rect(checkerboard, Rect2(Point2(), size), true);
-
- int tex_width = texture->get_width() * size.height / texture->get_height();
- int tex_height = size.height;
-
- if (tex_width > size.width) {
- tex_width = size.width;
- tex_height = texture->get_height() * tex_width / texture->get_width();
- }
-
- // Prevent the texture from being unpreviewable after the rescale, so that we can still see something
- if (tex_height <= 0) {
- tex_height = 1;
- }
- if (tex_width <= 0) {
- tex_width = 1;
- }
+TexturePreview::TexturePreview(Ref<Texture2D> p_texture, bool p_show_metadata) {
+ Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
- int ofs_x = (size.width - tex_width) / 2;
- int ofs_y = (size.height - tex_height) / 2;
-
- if (Object::cast_to<CurveTexture>(*texture)) {
- // In the case of CurveTextures we know they are 1 in height, so fill the preview to see the gradient
- ofs_y = 0;
- tex_height = size.height;
- } else if (Object::cast_to<GradientTexture>(*texture)) {
- ofs_y = size.height / 4.0;
- tex_height = size.height / 2.0;
- }
+ TextureRect *checkerboard = memnew(TextureRect);
+ checkerboard->set_texture(theme->get_icon("Checkerboard", "EditorIcons"));
+ checkerboard->set_stretch_mode(TextureRect::STRETCH_TILE);
+ checkerboard->set_texture_repeat(CanvasItem::TEXTURE_REPEAT_ENABLED);
+ checkerboard->set_custom_minimum_size(Size2(0.0, 256.0) * EDSCALE);
+ add_child(checkerboard);
- draw_texture_rect(texture, Rect2(ofs_x, ofs_y, tex_width, tex_height));
+ texture_display = memnew(TextureRect);
+ texture_display->set_texture(p_texture);
+ texture_display->set_anchors_preset(TextureRect::PRESET_WIDE);
+ texture_display->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
+ texture_display->set_expand(true);
+ add_child(texture_display);
- Ref<Font> font = get_theme_font("font", "Label");
- int font_size = get_theme_font_size("font_size", "Label");
+ if (p_show_metadata) {
+ Label *metadata_label = memnew(Label);
String format;
- if (Object::cast_to<ImageTexture>(*texture)) {
- format = Image::get_format_name(Object::cast_to<ImageTexture>(*texture)->get_format());
- } else if (Object::cast_to<StreamTexture2D>(*texture)) {
- format = Image::get_format_name(Object::cast_to<StreamTexture2D>(*texture)->get_format());
+ if (Object::cast_to<ImageTexture>(*p_texture)) {
+ format = Image::get_format_name(Object::cast_to<ImageTexture>(*p_texture)->get_format());
+ } else if (Object::cast_to<StreamTexture2D>(*p_texture)) {
+ format = Image::get_format_name(Object::cast_to<StreamTexture2D>(*p_texture)->get_format());
} else {
- format = texture->get_class();
+ format = p_texture->get_class();
}
- String text = itos(texture->get_width()) + "x" + itos(texture->get_height()) + " " + format;
- Size2 rect = font->get_string_size(text, font_size);
+ metadata_label->set_text(itos(p_texture->get_width()) + "x" + itos(p_texture->get_height()) + " " + format);
- Vector2 draw_from = size - rect + Size2(-2, font->get_ascent(font_size) - 2);
- if (draw_from.x < 0) {
- draw_from.x = 0;
- }
+ metadata_label->add_theme_font_size_override("font_size", 16 * EDSCALE);
+ metadata_label->add_theme_color_override("font_outline_color", Color::named("black"));
+ metadata_label->add_theme_constant_override("outline_size", 2 * EDSCALE);
+ Ref<Font> metadata_label_font = theme->get_font("expression", "EditorFonts");
+ metadata_label->add_theme_font_override("font", metadata_label_font);
- draw_string(font, draw_from + Vector2(2, 2), text, HALIGN_LEFT, size.width, font_size, Color(0, 0, 0, 0.5));
- draw_string(font, draw_from - Vector2(2, 2), text, HALIGN_LEFT, size.width, font_size, Color(0, 0, 0, 0.5));
- draw_string(font, draw_from, text, HALIGN_LEFT, size.width, font_size, Color(1, 1, 1, 1));
- }
-}
+ // it's okay that these colors are static since the grid color is static too
+ metadata_label->add_theme_color_override("font_color", Color::named("white"));
+ metadata_label->add_theme_color_override("font_color_shadow", Color::named("black"));
-void TextureEditor::_texture_changed() {
- if (!is_visible()) {
- return;
- }
- update();
-}
+ metadata_label->add_theme_constant_override("shadow_as_outline", 1);
+ metadata_label->set_h_size_flags(Control::SIZE_SHRINK_END);
+ metadata_label->set_v_size_flags(Control::SIZE_SHRINK_END);
-void TextureEditor::edit(Ref<Texture2D> p_texture) {
- if (!texture.is_null()) {
- texture->disconnect("changed", callable_mp(this, &TextureEditor::_texture_changed));
+ add_child(metadata_label);
}
-
- texture = p_texture;
-
- if (!texture.is_null()) {
- texture->connect("changed", callable_mp(this, &TextureEditor::_texture_changed));
- update();
- } else {
- hide();
- }
-}
-
-void TextureEditor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &TextureEditor::_gui_input);
}
-TextureEditor::TextureEditor() {
- set_texture_repeat(TextureRepeat::TEXTURE_REPEAT_ENABLED);
- set_custom_minimum_size(Size2(1, 150));
-}
-
-TextureEditor::~TextureEditor() {
- if (!texture.is_null()) {
- texture->disconnect("changed", callable_mp(this, &TextureEditor::_texture_changed));
- }
-}
-
-//
bool EditorInspectorPluginTexture::can_handle(Object *p_object) {
return Object::cast_to<ImageTexture>(p_object) != nullptr || Object::cast_to<AtlasTexture>(p_object) != nullptr || Object::cast_to<StreamTexture2D>(p_object) != nullptr || Object::cast_to<AnimatedTexture>(p_object) != nullptr;
}
void EditorInspectorPluginTexture::parse_begin(Object *p_object) {
- Texture2D *texture = Object::cast_to<Texture2D>(p_object);
- if (!texture) {
- return;
- }
- Ref<Texture2D> m(texture);
+ Ref<Texture> texture(Object::cast_to<Texture>(p_object));
- TextureEditor *editor = memnew(TextureEditor);
- editor->edit(m);
- add_custom_control(editor);
+ add_custom_control(memnew(TexturePreview(texture, true)));
}
TextureEditorPlugin::TextureEditorPlugin(EditorNode *p_node) {
diff --git a/editor/plugins/texture_editor_plugin.h b/editor/plugins/texture_editor_plugin.h
index ebe8882194..165090be93 100644
--- a/editor/plugins/texture_editor_plugin.h
+++ b/editor/plugins/texture_editor_plugin.h
@@ -35,21 +35,15 @@
#include "editor/editor_plugin.h"
#include "scene/resources/texture.h"
-class TextureEditor : public Control {
- GDCLASS(TextureEditor, Control);
+class TexturePreview : public MarginContainer {
+ GDCLASS(TexturePreview, MarginContainer);
- Ref<Texture2D> texture;
-
-protected:
- void _notification(int p_what);
- void _gui_input(Ref<InputEvent> p_event);
- void _texture_changed();
- static void _bind_methods();
+private:
+ TextureRect *texture_display;
public:
- void edit(Ref<Texture2D> p_texture);
- TextureEditor();
- ~TextureEditor();
+ TextureRect *get_texture_display();
+ TexturePreview(Ref<Texture2D> p_texture, bool p_show_metadata);
};
class EditorInspectorPluginTexture : public EditorInspectorPlugin {
diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp
index 0f15d4b119..87fbbbcfb8 100644
--- a/editor/rename_dialog.cpp
+++ b/editor/rename_dialog.cpp
@@ -35,12 +35,18 @@
#include "editor_scale.h"
#include "editor_settings.h"
#include "editor_themes.h"
-#include "modules/regex/regex.h"
#include "plugins/script_editor_plugin.h"
#include "scene/gui/control.h"
#include "scene/gui/label.h"
#include "scene/gui/tab_container.h"
+#include "modules/modules_enabled.gen.h"
+#ifdef MODULE_REGEX_ENABLED
+#include "modules/regex/regex.h"
+#else
+#error "Can't build editor rename dialog without RegEx module."
+#endif
+
RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_undo_redo) {
scene_tree_editor = p_scene_tree_editor;
undo_redo = p_undo_redo;
diff --git a/modules/fbx/data/fbx_material.cpp b/modules/fbx/data/fbx_material.cpp
index cf5d70fa5b..fb6c67f7b9 100644
--- a/modules/fbx/data/fbx_material.cpp
+++ b/modules/fbx/data/fbx_material.cpp
@@ -29,6 +29,10 @@
/*************************************************************************/
#include "fbx_material.h"
+
+// FIXME: Shouldn't depend on core_bind.h! Use DirAccessRef like the rest of
+// the engine instead of _Directory.
+#include "core/core_bind.h"
#include "scene/resources/material.h"
#include "scene/resources/texture.h"
#include "tools/validation_tools.h"
diff --git a/modules/fbx/data/import_state.h b/modules/fbx/data/import_state.h
index 83bc43faff..9ba60eaacf 100644
--- a/modules/fbx/data/import_state.h
+++ b/modules/fbx/data/import_state.h
@@ -37,7 +37,6 @@
#include "pivot_transform.h"
-#include "core/core_bind.h"
#include "core/io/resource_importer.h"
#include "core/templates/vector.h"
#include "editor/import/resource_importer_scene.h"
diff --git a/modules/fbx/editor_scene_importer_fbx.h b/modules/fbx/editor_scene_importer_fbx.h
index 4bb2c9d21b..4a3b78480b 100644
--- a/modules/fbx/editor_scene_importer_fbx.h
+++ b/modules/fbx/editor_scene_importer_fbx.h
@@ -36,7 +36,6 @@
#include "data/import_state.h"
#include "tools/import_utils.h"
-#include "core/core_bind.h"
#include "core/io/resource_importer.h"
#include "core/string/ustring.h"
#include "core/templates/local_vector.h"
diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.h b/modules/gdscript/editor/gdscript_translation_parser_plugin.h
index fcf438422a..caa80fc24c 100644
--- a/modules/gdscript/editor/gdscript_translation_parser_plugin.h
+++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.h
@@ -34,7 +34,6 @@
#include "core/templates/set.h"
#include "editor/editor_translation_parser.h"
#include "modules/gdscript/gdscript_parser.h"
-#include "modules/regex/regex.h"
class GDScriptEditorTranslationParserPlugin : public EditorTranslationParserPlugin {
GDCLASS(GDScriptEditorTranslationParserPlugin, EditorTranslationParserPlugin);
diff --git a/modules/gdscript/language_server/gdscript_language_protocol.h b/modules/gdscript/language_server/gdscript_language_protocol.h
index 969c38eab6..5a2dd55c46 100644
--- a/modules/gdscript/language_server/gdscript_language_protocol.h
+++ b/modules/gdscript/language_server/gdscript_language_protocol.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GDSCRIPT_PROTOCAL_SERVER_H
-#define GDSCRIPT_PROTOCAL_SERVER_H
+#ifndef GDSCRIPT_LANGUAGE_PROTOCOL_H
+#define GDSCRIPT_LANGUAGE_PROTOCOL_H
#include "core/io/stream_peer.h"
#include "core/io/stream_peer_tcp.h"
@@ -37,7 +37,13 @@
#include "gdscript_text_document.h"
#include "gdscript_workspace.h"
#include "lsp.hpp"
+
+#include "modules/modules_enabled.gen.h"
+#ifdef MODULE_JSONRPC_ENABLED
#include "modules/jsonrpc/jsonrpc.h"
+#else
+#error "Can't build GDScript LSP without JSONRPC module."
+#endif
#define LSP_MAX_BUFFER_SIZE 4194304
#define LSP_MAX_CLIENTS 8
@@ -108,4 +114,4 @@ public:
GDScriptLanguageProtocol();
};
-#endif
+#endif // GDSCRIPT_LANGUAGE_PROTOCOL_H
diff --git a/modules/gltf/editor_scene_importer_gltf.cpp b/modules/gltf/editor_scene_importer_gltf.cpp
index cef5278f03..eca1c85bf3 100644
--- a/modules/gltf/editor_scene_importer_gltf.cpp
+++ b/modules/gltf/editor_scene_importer_gltf.cpp
@@ -28,22 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "core/crypto/crypto_core.h"
-#include "core/io/file_access.h"
-#include "core/math/disjoint_set.h"
-#include "core/math/math_defs.h"
-#include "core/os/os.h"
-#include "editor/import/resource_importer_scene.h"
-#include "modules/gltf/gltf_state.h"
-#include "modules/regex/regex.h"
-#include "scene/3d/bone_attachment_3d.h"
-#include "scene/3d/camera_3d.h"
-#include "scene/3d/mesh_instance_3d.h"
-#include "scene/animation/animation_player.h"
-#include "scene/resources/packed_scene.h"
-#include "scene/resources/surface_tool.h"
+#include "editor_scene_importer_gltf.h"
+
+#include "gltf_document.h"
+#include "gltf_state.h"
-#include "modules/gltf/editor_scene_importer_gltf.h"
+#include "scene/3d/node_3d.h"
+#include "scene/animation/animation_player.h"
+#include "scene/resources/animation.h"
uint32_t EditorSceneImporterGLTF::get_import_flags() const {
return ImportFlags::IMPORT_SCENE | ImportFlags::IMPORT_ANIMATION;
diff --git a/modules/gltf/editor_scene_importer_gltf.h b/modules/gltf/editor_scene_importer_gltf.h
index 566d5cfd34..7bc5f594ed 100644
--- a/modules/gltf/editor_scene_importer_gltf.h
+++ b/modules/gltf/editor_scene_importer_gltf.h
@@ -31,28 +31,13 @@
#ifndef EDITOR_SCENE_IMPORTER_GLTF_H
#define EDITOR_SCENE_IMPORTER_GLTF_H
-#include "core/config/project_settings.h"
-#include "core/object/object.h"
-#include "core/templates/vector.h"
+#include "gltf_state.h"
+
#include "editor/import/resource_importer_scene.h"
-#include "modules/csg/csg_shape.h"
-#include "modules/gridmap/grid_map.h"
-#include "scene/3d/mesh_instance_3d.h"
-#include "scene/3d/multimesh_instance_3d.h"
-#include "scene/3d/node_3d.h"
-#include "scene/3d/skeleton_3d.h"
-#include "scene/animation/animation_player.h"
-#include "scene/gui/check_box.h"
#include "scene/main/node.h"
#include "scene/resources/packed_scene.h"
-#include "scene/resources/surface_tool.h"
-
-#include "gltf_document.h"
-#include "gltf_state.h"
-class AnimationPlayer;
-class BoneAttachment;
-class EditorSceneImporterMeshNode3D;
+class Animation;
#ifdef TOOLS_ENABLED
class EditorSceneImporterGLTF : public EditorSceneImporter {
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 660c2ab305..71a9b3667f 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -29,9 +29,7 @@
/*************************************************************************/
#include "gltf_document.h"
-#include "core/error/error_list.h"
-#include "core/error/error_macros.h"
-#include "core/variant/variant.h"
+
#include "gltf_accessor.h"
#include "gltf_animation.h"
#include "gltf_camera.h"
@@ -44,35 +42,33 @@
#include "gltf_state.h"
#include "gltf_texture.h"
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "core/core_bind.h"
#include "core/crypto/crypto_core.h"
+#include "core/io/dir_access.h"
#include "core/io/file_access.h"
#include "core/io/json.h"
#include "core/math/disjoint_set.h"
#include "core/variant/typed_array.h"
+#include "core/variant/variant.h"
#include "core/version.h"
#include "core/version_hash.gen.h"
#include "drivers/png/png_driver_common.h"
#include "editor/import/resource_importer_scene.h"
+#include "scene/2d/node_2d.h"
+#include "scene/3d/camera_3d.h"
+#include "scene/3d/multimesh_instance_3d.h"
+#include "scene/animation/animation_player.h"
+#include "scene/resources/surface_tool.h"
+
+#include "modules/modules_enabled.gen.h"
#ifdef MODULE_CSG_ENABLED
#include "modules/csg/csg_shape.h"
#endif // MODULE_CSG_ENABLED
#ifdef MODULE_GRIDMAP_ENABLED
#include "modules/gridmap/grid_map.h"
#endif // MODULE_GRIDMAP_ENABLED
-#include "scene/2d/node_2d.h"
-#include "scene/3d/bone_attachment_3d.h"
-#include "scene/3d/camera_3d.h"
-#include "scene/3d/mesh_instance_3d.h"
-#include "scene/3d/multimesh_instance_3d.h"
-#include "scene/3d/node_3d.h"
-#include "scene/3d/skeleton_3d.h"
-#include "scene/animation/animation_player.h"
-#include "scene/main/node.h"
-#include "scene/resources/surface_tool.h"
+
+#include <stdio.h>
+#include <stdlib.h>
#include <limits>
Error GLTFDocument::serialize(Ref<GLTFState> state, Node *p_root, const String &p_path) {
@@ -2873,16 +2869,13 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> state, const String &p_path
name = itos(i);
}
name = _gen_unique_name(state, name);
- name = name.pad_zeros(3);
- Ref<_Directory> dir;
- dir.instantiate();
+ name = name.pad_zeros(3) + ".png";
String texture_dir = "textures";
String new_texture_dir = p_path.get_base_dir() + "/" + texture_dir;
- dir->open(p_path.get_base_dir());
- if (!dir->dir_exists(new_texture_dir)) {
- dir->make_dir(new_texture_dir);
+ DirAccessRef da = DirAccess::open(p_path.get_base_dir());
+ if (!da->dir_exists(new_texture_dir)) {
+ da->make_dir(new_texture_dir);
}
- name = name + ".png";
image->save_png(new_texture_dir.plus_file(name));
d["uri"] = texture_dir.plus_file(name);
}
diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h
index 514373c4f0..3e8ea19045 100644
--- a/modules/gltf/gltf_document.h
+++ b/modules/gltf/gltf_document.h
@@ -31,11 +31,9 @@
#ifndef GLTF_DOCUMENT_H
#define GLTF_DOCUMENT_H
-#include "editor/import/resource_importer_scene.h"
-#include "editor/import/scene_importer_mesh_node_3d.h"
#include "gltf_animation.h"
-#include "modules/modules_enabled.gen.h"
-#include "scene/2d/node_2d.h"
+
+#include "editor/import/scene_importer_mesh_node_3d.h"
#include "scene/3d/bone_attachment_3d.h"
#include "scene/3d/light_3d.h"
#include "scene/3d/mesh_instance_3d.h"
@@ -45,6 +43,8 @@
#include "scene/resources/material.h"
#include "scene/resources/texture.h"
+#include "modules/modules_enabled.gen.h"
+
class GLTFState;
class GLTFSkin;
class GLTFNode;
diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h
index ba6bf8a533..d8209523c5 100644
--- a/modules/gltf/gltf_state.h
+++ b/modules/gltf/gltf_state.h
@@ -31,9 +31,6 @@
#ifndef GLTF_STATE_H
#define GLTF_STATE_H
-#include "core/io/resource.h"
-#include "core/templates/vector.h"
-#include "editor_scene_importer_gltf.h"
#include "gltf_accessor.h"
#include "gltf_animation.h"
#include "gltf_buffer_view.h"
@@ -45,6 +42,9 @@
#include "gltf_skeleton.h"
#include "gltf_skin.h"
#include "gltf_texture.h"
+
+#include "core/io/resource.h"
+#include "core/templates/vector.h"
#include "scene/animation/animation_player.h"
#include "scene/resources/texture.h"
diff --git a/modules/mbedtls/tests/test_crypto_mbedtls.cpp b/modules/mbedtls/tests/test_crypto_mbedtls.cpp
index 4217497082..8762838883 100644
--- a/modules/mbedtls/tests/test_crypto_mbedtls.cpp
+++ b/modules/mbedtls/tests/test_crypto_mbedtls.cpp
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "modules/mbedtls/tests/test_crypto_mbedtls.h"
+#include "test_crypto_mbedtls.h"
#include "modules/mbedtls/crypto_mbedtls.h"
#include "tests/test_macros.h"
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index c71c44d79d..1faa6eeac0 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -26,8 +26,6 @@ namespace GodotTools
private PopupMenu menuPopup;
private AcceptDialog errorDialog;
- private AcceptDialog aboutDialog;
- private CheckBox aboutDialogCheckBox;
private Button bottomPanelBtn;
private Button toolBarBuildButton;
@@ -130,13 +128,6 @@ namespace GodotTools
toolBarBuildButton.Show();
}
- private void _ShowAboutDialog()
- {
- bool showOnStart = (bool)editorSettings.GetSetting("mono/editor/show_info_on_start");
- aboutDialogCheckBox.Pressed = showOnStart;
- aboutDialog.PopupCentered();
- }
-
private void _MenuOptionPressed(int id)
{
switch ((MenuOptions)id)
@@ -144,9 +135,6 @@ namespace GodotTools
case MenuOptions.CreateSln:
CreateProjectSolution();
break;
- case MenuOptions.AboutCSharp:
- _ShowAboutDialog();
- break;
case MenuOptions.SetupGodotNugetFallbackFolder:
{
try
@@ -183,21 +171,11 @@ namespace GodotTools
base._Ready();
MSBuildPanel.BuildOutputView.BuildStateChanged += BuildStateChanged;
-
- bool showInfoDialog = (bool)editorSettings.GetSetting("mono/editor/show_info_on_start");
- if (showInfoDialog)
- {
- aboutDialog.Exclusive = true;
- _ShowAboutDialog();
- // Once shown a first time, it can be seen again via the Mono menu - it doesn't have to be exclusive from that time on.
- aboutDialog.Exclusive = false;
- }
}
private enum MenuOptions
{
CreateSln,
- AboutCSharp,
SetupGodotNugetFallbackFolder,
}
@@ -439,57 +417,6 @@ namespace GodotTools
AddToolSubmenuItem("C#", menuPopup);
- // TODO: Remove or edit this info dialog once Mono support is no longer in alpha
- {
- menuPopup.AddItem("About C# support".TTR(), (int)MenuOptions.AboutCSharp);
- menuPopup.AddItem("Setup Godot NuGet Offline Packages".TTR(), (int)MenuOptions.SetupGodotNugetFallbackFolder);
- aboutDialog = new AcceptDialog();
- editorBaseControl.AddChild(aboutDialog);
- aboutDialog.Title = "Important: C# support is not feature-complete";
-
- // We don't use DialogText as the default AcceptDialog Label doesn't play well with the TextureRect and CheckBox
- // we'll add. Instead we add containers and a new autowrapped Label inside.
-
- // Main VBoxContainer (icon + label on top, checkbox at bottom)
- var aboutVBox = new VBoxContainer();
- aboutDialog.AddChild(aboutVBox);
-
- // HBoxContainer for icon + label
- var aboutHBox = new HBoxContainer();
- aboutVBox.AddChild(aboutHBox);
-
- var aboutIcon = new TextureRect();
- aboutIcon.Texture = aboutIcon.GetThemeIcon("NodeWarning", "EditorIcons");
- aboutHBox.AddChild(aboutIcon);
-
- var aboutLabel = new Label();
- aboutHBox.AddChild(aboutLabel);
- aboutLabel.RectMinSize = new Vector2(600, 150) * EditorScale;
- aboutLabel.SizeFlagsVertical = (int)Control.SizeFlags.ExpandFill;
- aboutLabel.Autowrap = true;
- aboutLabel.Text =
- "C# support in Godot Engine is in late alpha stage and, while already usable, " +
- "it is not meant for use in production.\n\n" +
- "Projects can be exported to Linux, macOS, Windows, Android, iOS and HTML5, but not yet to UWP. " +
- "Bugs and usability issues will be addressed gradually over future releases, " +
- "potentially including compatibility breaking changes as new features are implemented for a better overall C# experience.\n\n" +
- "If you experience issues with this Mono build, please report them on Godot's issue tracker with details about your system, MSBuild version, IDE, etc.:\n\n" +
- " https://github.com/godotengine/godot/issues\n\n" +
- "Your critical feedback at this stage will play a great role in shaping the C# support in future releases, so thank you!";
-
- EditorDef("mono/editor/show_info_on_start", true);
-
- // CheckBox in main container
- aboutDialogCheckBox = new CheckBox {Text = "Show this warning when starting the editor"};
- aboutDialogCheckBox.Toggled += enabled =>
- {
- bool showOnStart = (bool)editorSettings.GetSetting("mono/editor/show_info_on_start");
- if (showOnStart != enabled)
- editorSettings.SetSetting("mono/editor/show_info_on_start", enabled);
- };
- aboutVBox.AddChild(aboutDialogCheckBox);
- }
-
toolBarBuildButton = new Button
{
Text = "Build",
diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp
index 0d8330c1da..7aeb9e1858 100644
--- a/modules/navigation/navigation_mesh_generator.cpp
+++ b/modules/navigation/navigation_mesh_generator.cpp
@@ -47,12 +47,12 @@
#include "scene/resources/sphere_shape_3d.h"
#include "scene/resources/world_margin_shape_3d.h"
-#include "modules/modules_enabled.gen.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#endif
+#include "modules/modules_enabled.gen.h"
#ifdef MODULE_CSG_ENABLED
#include "modules/csg/csg_shape.h"
#endif
diff --git a/modules/text_server_adv/dynamic_font_adv.h b/modules/text_server_adv/dynamic_font_adv.h
index 1292966f0c..b3f97bb029 100644
--- a/modules/text_server_adv/dynamic_font_adv.h
+++ b/modules/text_server_adv/dynamic_font_adv.h
@@ -34,7 +34,6 @@
#include "font_adv.h"
#include "modules/modules_enabled.gen.h"
-
#ifdef MODULE_FREETYPE_ENABLED
#include <ft2build.h>
diff --git a/modules/text_server_fb/dynamic_font_fb.h b/modules/text_server_fb/dynamic_font_fb.h
index b34c8cbed5..82e59fa607 100644
--- a/modules/text_server_fb/dynamic_font_fb.h
+++ b/modules/text_server_fb/dynamic_font_fb.h
@@ -34,7 +34,6 @@
#include "font_fb.h"
#include "modules/modules_enabled.gen.h"
-
#ifdef MODULE_FREETYPE_ENABLED
#include <ft2build.h>
diff --git a/modules/webrtc/webrtc_data_channel_gdnative.cpp b/modules/webrtc/webrtc_data_channel_gdnative.cpp
index d4cf464c7c..f3009dde2f 100644
--- a/modules/webrtc/webrtc_data_channel_gdnative.cpp
+++ b/modules/webrtc/webrtc_data_channel_gdnative.cpp
@@ -31,6 +31,7 @@
#ifdef WEBRTC_GDNATIVE_ENABLED
#include "webrtc_data_channel_gdnative.h"
+
#include "core/io/resource_loader.h"
#include "modules/gdnative/nativescript/nativescript.h"
diff --git a/modules/websocket/editor_debugger_server_websocket.h b/modules/websocket/editor_debugger_server_websocket.h
index 2f73b98c3d..d9543bb647 100644
--- a/modules/websocket/editor_debugger_server_websocket.h
+++ b/modules/websocket/editor_debugger_server_websocket.h
@@ -28,12 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SCRIPT_EDITOR_DEBUGGER_WEBSOCKET_H
-#define SCRIPT_EDITOR_DEBUGGER_WEBSOCKET_H
-
-#include "modules/websocket/websocket_server.h"
+#ifndef EDITOR_DEBUGGER_SERVER_WEBSOCKET_H
+#define EDITOR_DEBUGGER_SERVER_WEBSOCKET_H
#include "editor/debugger/editor_debugger_server.h"
+#include "modules/websocket/websocket_server.h"
class EditorDebuggerServerWebSocket : public EditorDebuggerServer {
GDCLASS(EditorDebuggerServerWebSocket, EditorDebuggerServer);
@@ -59,4 +58,4 @@ public:
~EditorDebuggerServerWebSocket();
};
-#endif // SCRIPT_EDITOR_DEBUGGER_WEBSOCKET_H
+#endif // EDITOR_DEBUGGER_SERVER_WEBSOCKET_H
diff --git a/modules/websocket/remote_debugger_peer_websocket.h b/modules/websocket/remote_debugger_peer_websocket.h
index 03c60fb480..590d925dcc 100644
--- a/modules/websocket/remote_debugger_peer_websocket.h
+++ b/modules/websocket/remote_debugger_peer_websocket.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SCRIPT_DEBUGGER_WEBSOCKET_H
-#define SCRIPT_DEBUGGER_WEBSOCKET_H
+#ifndef REMOTE_DEBUGGER_PEER_WEBSOCKET_H
+#define REMOTE_DEBUGGER_PEER_WEBSOCKET_H
#ifdef JAVASCRIPT_ENABLED
#include "modules/websocket/emws_client.h"
@@ -62,4 +62,4 @@ public:
RemoteDebuggerPeerWebSocket(Ref<WebSocketPeer> p_peer = Ref<WebSocketPeer>());
};
-#endif // SCRIPT_DEBUGGER_WEBSOCKET_H
+#endif // REMOTE_DEBUGGER_PEER_WEBSOCKET_H
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 0b1650076c..92b8b70508 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -35,9 +35,9 @@
#include "drivers/unix/dir_access_unix.h"
#include "drivers/unix/file_access_unix.h"
#include "main/main.h"
-#include "modules/modules_enabled.gen.h"
#include "platform/javascript/display_server_javascript.h"
+#include "modules/modules_enabled.gen.h"
#ifdef MODULE_WEBSOCKET_ENABLED
#include "modules/websocket/remote_debugger_peer_websocket.h"
#endif
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index 1075ae38ce..98925fd7fa 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -31,7 +31,6 @@
#include "export.h"
#include "core/config/project_settings.h"
-#include "core/core_bind.h"
#include "core/crypto/crypto_core.h"
#include "core/io/dir_access.h"
#include "core/io/file_access.h"
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 80aa99bf5e..b68f0312fc 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -76,12 +76,12 @@ Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_motion, bool p_i
return Ref<KinematicCollision2D>();
}
-bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only, bool p_cancel_sliding) {
+bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only, bool p_cancel_sliding, const Set<RID> &p_exclude) {
if (is_only_update_transform_changes_enabled()) {
ERR_PRINT("Move functions do not work together with 'sync to physics' option. Please read the documentation.");
}
Transform2D gt = get_global_transform();
- bool colliding = PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, p_margin, &r_result, p_exclude_raycast_shapes);
+ bool colliding = PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, p_margin, &r_result, p_exclude_raycast_shapes, p_exclude);
// Restore direction of motion to be along original motion,
// in order to avoid sliding due to recovery,
@@ -960,11 +960,14 @@ void RigidBody2D::_reload_physics_characteristics() {
void CharacterBody2D::move_and_slide() {
Vector2 body_velocity_normal = linear_velocity.normalized();
-
bool was_on_floor = on_floor;
+ // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky
+ float delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
+
Vector2 current_floor_velocity = floor_velocity;
- if (on_floor && on_floor_body.is_valid()) {
+
+ if ((on_floor || on_wall) && on_floor_body.is_valid()) {
//this approach makes sure there is less delay between the actual body velocity and the one we saved
PhysicsDirectBodyState2D *bs = PhysicsServer2D::get_singleton()->body_get_direct_state(on_floor_body);
if (bs) {
@@ -972,20 +975,30 @@ void CharacterBody2D::move_and_slide() {
}
}
- // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky
- Vector2 motion = (current_floor_velocity + linear_velocity) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time());
-
+ motion_results.clear();
on_floor = false;
- on_floor_body = RID();
on_ceiling = false;
on_wall = false;
- motion_results.clear();
floor_normal = Vector2();
floor_velocity = Vector2();
+ if (current_floor_velocity != Vector2()) {
+ PhysicsServer2D::MotionResult floor_result;
+ Set<RID> exclude;
+ exclude.insert(on_floor_body);
+ if (move_and_collide(current_floor_velocity * delta, infinite_inertia, floor_result, true, false, false, false, exclude)) {
+ motion_results.push_back(floor_result);
+ _set_collision_direction(floor_result);
+ }
+ }
+
+ on_floor_body = RID();
+ Vector2 motion = linear_velocity * delta;
+
// No sliding on first attempt to keep floor motion stable when possible,
// when stop on slope is enabled.
bool sliding_enabled = !stop_on_slope;
+
for (int iteration = 0; iteration < max_slides; ++iteration) {
PhysicsServer2D::MotionResult result;
bool found_collision = false;
@@ -1009,35 +1022,19 @@ void CharacterBody2D::move_and_slide() {
found_collision = true;
motion_results.push_back(result);
-
- if (up_direction == Vector2()) {
- //all is a wall
- on_wall = true;
- } else {
- if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
-
- on_floor = true;
- floor_normal = result.collision_normal;
- on_floor_body = result.collider;
- floor_velocity = result.collider_velocity;
-
- if (stop_on_slope) {
- if ((body_velocity_normal + up_direction).length() < 0.01) {
- Transform2D gt = get_global_transform();
- if (result.motion.length() > margin) {
- gt.elements[2] -= result.motion.slide(up_direction);
- } else {
- gt.elements[2] -= result.motion;
- }
- set_global_transform(gt);
- linear_velocity = Vector2();
- return;
- }
+ _set_collision_direction(result);
+
+ if (on_floor && stop_on_slope) {
+ if ((body_velocity_normal + up_direction).length() < 0.01) {
+ Transform2D gt = get_global_transform();
+ if (result.motion.length() > margin) {
+ gt.elements[2] -= result.motion.slide(up_direction);
+ } else {
+ gt.elements[2] -= result.motion;
}
- } else if (Math::acos(result.collision_normal.dot(-up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
- on_ceiling = true;
- } else {
- on_wall = true;
+ set_global_transform(gt);
+ linear_velocity = Vector2();
+ return;
}
}
@@ -1057,6 +1054,11 @@ void CharacterBody2D::move_and_slide() {
}
}
+ if (!on_floor && !on_wall) {
+ // Add last platform velocity when just left a moving platform.
+ linear_velocity += current_floor_velocity;
+ }
+
if (!was_on_floor || snap == Vector2()) {
return;
}
@@ -1093,6 +1095,29 @@ void CharacterBody2D::move_and_slide() {
}
}
+void CharacterBody2D::_set_collision_direction(const PhysicsServer2D::MotionResult &p_result) {
+ on_floor = false;
+ on_ceiling = false;
+ on_wall = false;
+ if (up_direction == Vector2()) {
+ //all is a wall
+ on_wall = true;
+ } else {
+ if (Math::acos(p_result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
+ on_floor = true;
+ floor_normal = p_result.collision_normal;
+ on_floor_body = p_result.collider;
+ floor_velocity = p_result.collider_velocity;
+ } else if (Math::acos(p_result.collision_normal.dot(-up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
+ on_ceiling = true;
+ } else {
+ on_wall = true;
+ on_floor_body = p_result.collider;
+ floor_velocity = p_result.collider_velocity;
+ }
+ }
+}
+
bool CharacterBody2D::separate_raycast_shapes(PhysicsServer2D::MotionResult &r_result) {
PhysicsServer2D::SeparationResult sep_res[8]; //max 8 rays
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 5a5417eaf3..52e432f005 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -50,7 +50,7 @@ protected:
Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false, real_t p_margin = 0.08);
public:
- bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes = true, bool p_test_only = false, bool p_cancel_sliding = true);
+ bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes = true, bool p_test_only = false, bool p_cancel_sliding = true, const Set<RID> &p_exclude = Set<RID>());
bool test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, const Ref<KinematicCollision2D> &r_collision = Ref<KinematicCollision2D>(), real_t p_margin = 0.08);
TypedArray<PhysicsBody2D> get_collision_exceptions();
@@ -308,6 +308,7 @@ private:
const Vector2 &get_up_direction() const;
void set_up_direction(const Vector2 &p_up_direction);
+ void _set_collision_direction(const PhysicsServer2D::MotionResult &p_result);
protected:
void _notification(int p_what);
diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp
index 155dda4394..467c664302 100644
--- a/servers/physics_2d/physics_server_2d_sw.cpp
+++ b/servers/physics_2d/physics_server_2d_sw.cpp
@@ -946,7 +946,7 @@ void PhysicsServer2DSW::body_set_pickable(RID p_body, bool p_pickable) {
body->set_pickable(p_pickable);
}
-bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, MotionResult *r_result, bool p_exclude_raycast_shapes) {
+bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, MotionResult *r_result, bool p_exclude_raycast_shapes, const Set<RID> &p_exclude) {
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
ERR_FAIL_COND_V(!body->get_space(), false);
@@ -954,7 +954,7 @@ bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from,
_update_shapes();
- return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes);
+ return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes, p_exclude);
}
int PhysicsServer2DSW::body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin) {
diff --git a/servers/physics_2d/physics_server_2d_sw.h b/servers/physics_2d/physics_server_2d_sw.h
index 5002bf5fc8..f40b5a7c42 100644
--- a/servers/physics_2d/physics_server_2d_sw.h
+++ b/servers/physics_2d/physics_server_2d_sw.h
@@ -247,7 +247,7 @@ public:
virtual void body_set_pickable(RID p_body, bool p_pickable) override;
- virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override;
+ virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true, const Set<RID> &p_exclude = Set<RID>()) override;
virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.08) override;
// this function only works on physics process, errors and returns null otherwise
diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.h b/servers/physics_2d/physics_server_2d_wrap_mt.h
index a8f7ff3393..fb7235c031 100644
--- a/servers/physics_2d/physics_server_2d_wrap_mt.h
+++ b/servers/physics_2d/physics_server_2d_wrap_mt.h
@@ -253,9 +253,9 @@ public:
FUNC2(body_set_pickable, RID, bool);
- bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override {
+ bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true, const Set<RID> &p_exclude = Set<RID>()) override {
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
- return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes);
+ return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes, p_exclude);
}
int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.08) override {
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index cbde7144b7..82da5774db 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -709,7 +709,7 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
return rays_found;
}
-bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer2D::MotionResult *r_result, bool p_exclude_raycast_shapes) {
+bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer2D::MotionResult *r_result, bool p_exclude_raycast_shapes, const Set<RID> &p_exclude) {
//give me back regular physics engine logic
//this is madness
//and most people using this function will think
@@ -801,6 +801,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j);
for (int i = 0; i < amount; i++) {
const CollisionObject2DSW *col_obj = intersection_query_results[i];
+ if (p_exclude.has(col_obj->get_self())) {
+ continue;
+ }
int shape_idx = intersection_query_subindex_results[i];
if (CollisionObject2DSW::TYPE_BODY == col_obj->get_type()) {
@@ -930,6 +933,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
for (int i = 0; i < amount; i++) {
const CollisionObject2DSW *col_obj = intersection_query_results[i];
+ if (p_exclude.has(col_obj->get_self())) {
+ continue;
+ }
int col_shape_idx = intersection_query_subindex_results[i];
Shape2DSW *against_shape = col_obj->get_shape(col_shape_idx);
@@ -1086,6 +1092,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
for (int i = 0; i < amount; i++) {
const CollisionObject2DSW *col_obj = intersection_query_results[i];
+ if (p_exclude.has(col_obj->get_self())) {
+ continue;
+ }
int shape_idx = intersection_query_subindex_results[i];
if (CollisionObject2DSW::TYPE_BODY == col_obj->get_type()) {
diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h
index 4d737d622f..f7224e4661 100644
--- a/servers/physics_2d/space_2d_sw.h
+++ b/servers/physics_2d/space_2d_sw.h
@@ -183,7 +183,7 @@ public:
int get_collision_pairs() const { return collision_pairs; }
- bool test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer2D::MotionResult *r_result, bool p_exclude_raycast_shapes = true);
+ bool test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer2D::MotionResult *r_result, bool p_exclude_raycast_shapes = true, const Set<RID> &p_exclude = Set<RID>());
int test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, PhysicsServer2D::SeparationResult *r_results, int p_result_max, real_t p_margin);
void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); }
diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp
index ec0ff57a5e..e8272f377e 100644
--- a/servers/physics_server_2d.cpp
+++ b/servers/physics_server_2d.cpp
@@ -498,12 +498,16 @@ void PhysicsTestMotionResult2D::_bind_methods() {
///////////////////////////////////////
-bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) {
+bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, const Ref<PhysicsTestMotionResult2D> &p_result, bool p_exclude_raycast_shapes, const Vector<RID> &p_exclude) {
MotionResult *r = nullptr;
if (p_result.is_valid()) {
r = p_result->get_result_ptr();
}
- return body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r);
+ Set<RID> exclude;
+ for (int i = 0; i < p_exclude.size(); i++) {
+ exclude.insert(p_exclude[i]);
+ }
+ return body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r, p_exclude_raycast_shapes, exclude);
}
void PhysicsServer2D::_bind_methods() {
@@ -630,7 +634,7 @@ void PhysicsServer2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_set_force_integration_callback", "body", "callable", "userdata"), &PhysicsServer2D::body_set_force_integration_callback, DEFVAL(Variant()));
- ClassDB::bind_method(D_METHOD("body_test_motion", "body", "from", "motion", "infinite_inertia", "margin", "result"), &PhysicsServer2D::_body_test_motion, DEFVAL(0.08), DEFVAL(Variant()));
+ ClassDB::bind_method(D_METHOD("body_test_motion", "body", "from", "motion", "infinite_inertia", "margin", "result", "exclude_raycast_shapes", "exclude"), &PhysicsServer2D::_body_test_motion, DEFVAL(0.08), DEFVAL(Variant()), DEFVAL(true), DEFVAL(Array()));
ClassDB::bind_method(D_METHOD("body_get_direct_state", "body"), &PhysicsServer2D::body_get_direct_state);
diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h
index e2bff2975e..8542b54838 100644
--- a/servers/physics_server_2d.h
+++ b/servers/physics_server_2d.h
@@ -208,7 +208,7 @@ class PhysicsServer2D : public Object {
static PhysicsServer2D *singleton;
- virtual bool _body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>());
+ virtual bool _body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>(), bool p_exclude_raycast_shapes = true, const Vector<RID> &p_exclude = Vector<RID>());
protected:
static void _bind_methods();
@@ -481,7 +481,7 @@ public:
Variant collider_metadata;
};
- virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0;
+ virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true, const Set<RID> &p_exclude = Set<RID>()) = 0;
struct SeparationResult {
real_t collision_depth;