summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md19
-rw-r--r--SConstruct1
-rw-r--r--core/variant/variant_call.cpp1
-rw-r--r--doc/classes/Area3D.xml2
-rw-r--r--doc/classes/EditorResourcePicker.xml3
-rw-r--r--doc/classes/PhysicsServer2D.xml6
-rw-r--r--doc/classes/PhysicsServer3D.xml6
-rw-r--r--doc/classes/String.xml14
-rw-r--r--editor/editor_properties.cpp4
-rw-r--r--editor/editor_properties.h2
-rw-r--r--editor/editor_resource_picker.cpp6
-rw-r--r--editor/import/resource_importer_texture.cpp3
-rw-r--r--editor/plugins/theme_editor_plugin.cpp2
-rw-r--r--editor/plugins/theme_editor_plugin.h2
-rw-r--r--modules/bullet/area_bullet.cpp17
-rw-r--r--modules/bullet/area_bullet.h5
-rw-r--r--modules/bullet/bullet_physics_server.cpp8
-rw-r--r--modules/bullet/bullet_physics_server.h4
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp9
-rw-r--r--modules/gdscript/gdscript_tokenizer.h1
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out2
-rw-r--r--modules/gltf/doc_classes/GLTFMesh.xml2
-rw-r--r--modules/gltf/gltf_document.cpp37
-rw-r--r--modules/gltf/gltf_mesh.cpp11
-rw-r--r--modules/gltf/gltf_mesh.h3
-rw-r--r--platform/osx/SCsub2
-rw-r--r--platform/osx/context_gl_osx.mm161
-rw-r--r--platform/osx/detect.py7
-rw-r--r--platform/osx/display_server_osx.h13
-rw-r--r--platform/osx/display_server_osx.mm122
-rw-r--r--platform/osx/gl_manager_osx.h (renamed from platform/osx/context_gl_osx.h)74
-rw-r--r--platform/osx/gl_manager_osx.mm233
-rw-r--r--scene/2d/area_2d.cpp12
-rw-r--r--scene/3d/area_3d.cpp11
-rw-r--r--scene/3d/fog_volume.cpp1
-rw-r--r--scene/resources/mesh_data_tool.cpp2
-rw-r--r--servers/physics_2d/godot_area_2d.cpp132
-rw-r--r--servers/physics_2d/godot_area_2d.h14
-rw-r--r--servers/physics_2d/godot_physics_server_2d.cpp8
-rw-r--r--servers/physics_2d/godot_physics_server_2d.h4
-rw-r--r--servers/physics_3d/godot_area_3d.cpp130
-rw-r--r--servers/physics_3d/godot_area_3d.h15
-rw-r--r--servers/physics_3d/godot_physics_server_3d.cpp8
-rw-r--r--servers/physics_3d/godot_physics_server_3d.h4
-rw-r--r--servers/physics_server_2d.cpp4
-rw-r--r--servers/physics_server_2d.h4
-rw-r--r--servers/physics_server_2d_wrap_mt.h4
-rw-r--r--servers/physics_server_3d.cpp4
-rw-r--r--servers/physics_server_3d.h4
-rw-r--r--servers/physics_server_3d_wrap_mt.h4
50 files changed, 668 insertions, 479 deletions
diff --git a/README.md b/README.md
index 8ddddf0e63..a7e67f8946 100644
--- a/README.md
+++ b/README.md
@@ -10,8 +10,8 @@
**[Godot Engine](https://godotengine.org) is a feature-packed, cross-platform
game engine to create 2D and 3D games from a unified interface.** It provides a
-comprehensive set of common tools, so that users can focus on making games
-without having to reinvent the wheel. Games can be exported in one click to a
+comprehensive set of [common tools](https://godotengine.org/features), so that users can focus on making games
+without having to reinvent the wheel. Games can be exported with one click to a
number of platforms, including the major desktop platforms (Linux, macOS,
Windows), mobile platforms (Android, iOS), as well as Web-based platforms
(HTML5) and
@@ -19,18 +19,19 @@ Windows), mobile platforms (Android, iOS), as well as Web-based platforms
## Free, open source and community-driven
-Godot is completely free and open source under the very permissive MIT license.
+Godot is completely free and open source under the very permissive [MIT license](https://godotengine.org/license).
No strings attached, no royalties, nothing. The users' games are theirs, down
to the last line of engine code. Godot's development is fully independent and
community-driven, empowering users to help shape their engine to match their
expectations. It is supported by the [Software Freedom Conservancy](https://sfconservancy.org/)
not-for-profit.
-Before being open sourced in February 2014, Godot had been developed by Juan
-Linietsky and Ariel Manzur (both still maintaining the project) for several
+Before being open sourced in [February 2014](https://github.com/godotengine/godot/commit/0b806ee0fc9097fa7bda7ac0109191c9c5e0a1ac),
+Godot had been developed by [Juan Linietsky](https://github.com/reduz) and
+[Ariel Manzur](https://github.com/punto-) (both still maintaining the project) for several
years as an in-house engine, used to publish several work-for-hire titles.
-![Screenshot of a 3D scene in Godot Engine](https://raw.githubusercontent.com/godotengine/godot-design/master/screenshots/editor_tps_demo_1920x1080.jpg)
+![Screenshot of a 3D scene in the Godot Engine editor](https://raw.githubusercontent.com/godotengine/godot-design/master/screenshots/editor_tps_demo_1920x1080.jpg)
## Getting the engine
@@ -49,7 +50,7 @@ for compilation instructions for every supported platform.
Godot is not only an engine but an ever-growing community of users and engine
developers. The main community channels are listed [on the homepage](https://godotengine.org/community).
-To get in touch with the engine developers, the best way is to join the
+The best way to get in touch with the core engine developers is to join the
[Godot Contributors Chat](https://chat.godotengine.org).
To get started contributing to the project, see the [contributing guide](CONTRIBUTING.md).
@@ -62,8 +63,8 @@ It is maintained by the Godot community in its own [GitHub repository](https://g
The [class reference](https://docs.godotengine.org/en/latest/classes/)
is also accessible from the Godot editor.
-The official demos are maintained in their own [GitHub repository](https://github.com/godotengine/godot-demo-projects)
-as well.
+We also maintain official demos in their own [GitHub repository](https://github.com/godotengine/godot-demo-projects)
+as well as a list of [awesome Godot community resources](https://github.com/godotengine/awesome-godot).
There are also a number of other
[learning resources](https://docs.godotengine.org/en/latest/community/tutorials.html)
diff --git a/SConstruct b/SConstruct
index 78e3d28337..fea0e0ab28 100644
--- a/SConstruct
+++ b/SConstruct
@@ -132,6 +132,7 @@ opts.Add(BoolVariable("deprecated", "Enable deprecated features", True))
opts.Add(BoolVariable("minizip", "Enable ZIP archive support using minizip", True))
opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False))
opts.Add(BoolVariable("vulkan", "Enable the vulkan video driver", True))
+opts.Add(BoolVariable("opengl3", "Enable the OpenGL/GLES3 video driver", True))
opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "")
opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursively for each specified path.", True))
opts.Add(BoolVariable("use_volk", "Use the volk library to load the Vulkan loader dynamically", True))
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index ec3a6a5ca8..2b1d330942 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1366,6 +1366,7 @@ static void _register_variant_builtin_methods() {
bind_method(String, naturalnocasecmp_to, sarray("to"), varray());
bind_method(String, length, sarray(), varray());
bind_method(String, substr, sarray("from", "len"), varray(-1));
+ bind_method(String, get_slice, sarray("delimiter", "slice"), varray());
bind_methodv(String, find, static_cast<int (String::*)(const String &, int) const>(&String::find), sarray("what", "from"), varray(0));
bind_method(String, count, sarray("what", "from", "to"), varray(0, 0));
bind_method(String, countn, sarray("what", "from", "to"), varray(0, 0));
diff --git a/doc/classes/Area3D.xml b/doc/classes/Area3D.xml
index 14225c52a4..571fd8cad3 100644
--- a/doc/classes/Area3D.xml
+++ b/doc/classes/Area3D.xml
@@ -138,7 +138,7 @@
<argument index="2" name="area_shape_index" type="int" />
<argument index="3" name="local_shape_index" type="int" />
<description>
- Emitted when one of another Area3D's [Shape3D]s enters one of this Area3D's [Shape3D]s. Requires [member monitoring] to be set to [code]true[/code].
+ Emitted when one of another Area3D's [Shape3D]s exits one of this Area3D's [Shape3D]s. Requires [member monitoring] to be set to [code]true[/code].
[code]area_rid[/code] the [RID] of the other Area3D's [CollisionObject3D] used by the [PhysicsServer3D].
[code]area[/code] the other Area3D.
[code]area_shape_index[/code] the index of the [Shape3D] of the other Area3D used by the [PhysicsServer3D]. Get the [CollisionShape3D] node with [code]area.shape_owner_get_owner(area_shape_index)[/code].
diff --git a/doc/classes/EditorResourcePicker.xml b/doc/classes/EditorResourcePicker.xml
index 9c490cbb3e..b26b6f9527 100644
--- a/doc/classes/EditorResourcePicker.xml
+++ b/doc/classes/EditorResourcePicker.xml
@@ -62,8 +62,9 @@
</signal>
<signal name="resource_selected">
<argument index="0" name="resource" type="Resource" />
+ <argument index="1" name="edit" type="bool" />
<description>
- Emitted when the resource value was set and user clicked to edit it.
+ Emitted when the resource value was set and user clicked to edit it. When [code]edit[/code] is [code]true[/code], the signal was caused by the context menu "Edit" option.
</description>
</signal>
</signals>
diff --git a/doc/classes/PhysicsServer2D.xml b/doc/classes/PhysicsServer2D.xml
index 24a20b5613..e44bf71e8d 100644
--- a/doc/classes/PhysicsServer2D.xml
+++ b/doc/classes/PhysicsServer2D.xml
@@ -123,8 +123,7 @@
<method name="area_set_area_monitor_callback">
<return type="void" />
<argument index="0" name="area" type="RID" />
- <argument index="1" name="receiver" type="Object" />
- <argument index="2" name="method" type="StringName" />
+ <argument index="1" name="callback" type="Callable" />
<description>
</description>
</method>
@@ -147,8 +146,7 @@
<method name="area_set_monitor_callback">
<return type="void" />
<argument index="0" name="area" type="RID" />
- <argument index="1" name="receiver" type="Object" />
- <argument index="2" name="method" type="StringName" />
+ <argument index="1" name="callback" type="Callable" />
<description>
Sets the function to call when any body/area enters or exits the area. This callback will be called for any object interacting with the area, and takes five parameters:
1: [constant AREA_BODY_ADDED] or [constant AREA_BODY_REMOVED], depending on whether the object entered or exited the area.
diff --git a/doc/classes/PhysicsServer3D.xml b/doc/classes/PhysicsServer3D.xml
index 034bd55519..0c34cf8092 100644
--- a/doc/classes/PhysicsServer3D.xml
+++ b/doc/classes/PhysicsServer3D.xml
@@ -110,8 +110,7 @@
<method name="area_set_area_monitor_callback">
<return type="void" />
<argument index="0" name="area" type="RID" />
- <argument index="1" name="receiver" type="Object" />
- <argument index="2" name="method" type="StringName" />
+ <argument index="1" name="callback" type="Callable" />
<description>
</description>
</method>
@@ -134,8 +133,7 @@
<method name="area_set_monitor_callback">
<return type="void" />
<argument index="0" name="area" type="RID" />
- <argument index="1" name="receiver" type="Object" />
- <argument index="2" name="method" type="StringName" />
+ <argument index="1" name="callback" type="Callable" />
<description>
Sets the function to call when any body/area enters or exits the area. This callback will be called for any object interacting with the area, and takes five parameters:
1: [constant AREA_BODY_ADDED] or [constant AREA_BODY_REMOVED], depending on whether the object entered or exited the area.
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index 1190d90190..a58bfd5c15 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -202,6 +202,19 @@
If the string is a valid file path, returns the filename.
</description>
</method>
+ <method name="get_slice" qualifiers="const">
+ <return type="String" />
+ <argument index="0" name="delimiter" type="String" />
+ <argument index="1" name="slice" type="int" />
+ <description>
+ Splits a string using a [code]delimiter[/code] and returns a substring at index [code]slice[/code]. Returns an empty string if the index doesn't exist.
+ This is a more performant alternative to [method split] for cases when you need only one element from the array at a fixed index.
+ Example:
+ [codeblock]
+ print("i/am/example/string".get_slice("/", 2)) # Prints 'example'.
+ [/codeblock]
+ </description>
+ </method>
<method name="hash" qualifiers="const">
<return type="int" />
<description>
@@ -602,6 +615,7 @@
<description>
Splits the string by a [code]delimiter[/code] string and returns an array of the substrings. The [code]delimiter[/code] can be of any length.
If [code]maxsplit[/code] is specified, it defines the number of splits to do from the left up to [code]maxsplit[/code]. The default value of [code]0[/code] means that all items are split.
+ If you need only one element from the array at a specific index, [method get_slice] is a more performant option.
Example:
[codeblocks]
[gdscript]
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index e679222567..fbf80fef2e 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -2821,8 +2821,8 @@ void EditorPropertyResource::_set_read_only(bool p_read_only) {
resource_picker->set_editable(!p_read_only);
};
-void EditorPropertyResource::_resource_selected(const RES &p_resource) {
- if (use_sub_inspector) {
+void EditorPropertyResource::_resource_selected(const RES &p_resource, bool p_edit) {
+ if (!p_edit && use_sub_inspector) {
bool unfold = !get_edited_object()->editor_is_section_unfolded(get_edited_property());
get_edited_object()->editor_set_section_unfold(get_edited_property(), unfold);
update_property();
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index 9a687f1a72..6b07efb068 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -657,7 +657,7 @@ class EditorPropertyResource : public EditorProperty {
bool updating_theme = false;
bool opened_editor = false;
- void _resource_selected(const RES &p_resource);
+ void _resource_selected(const RES &p_resource, bool p_edit);
void _resource_changed(const RES &p_resource);
void _viewport_selected(const NodePath &p_path);
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp
index 9dbf69a779..a2d11c4b1f 100644
--- a/editor/editor_resource_picker.cpp
+++ b/editor/editor_resource_picker.cpp
@@ -106,7 +106,7 @@ void EditorResourcePicker::_resource_selected() {
return;
}
- emit_signal(SNAME("resource_selected"), edited_resource);
+ emit_signal(SNAME("resource_selected"), edited_resource, false);
}
void EditorResourcePicker::_file_selected(const String &p_path) {
@@ -266,7 +266,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
case OBJ_MENU_EDIT: {
if (edited_resource.is_valid()) {
- emit_signal(SNAME("resource_selected"), edited_resource);
+ emit_signal(SNAME("resource_selected"), edited_resource, true);
}
} break;
@@ -690,7 +690,7 @@ void EditorResourcePicker::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "toggle_mode"), "set_toggle_mode", "is_toggle_mode");
- ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
+ ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), PropertyInfo(Variant::BOOL, "edit")));
ADD_SIGNAL(MethodInfo("resource_changed", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
}
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index 96a53b3257..e4553c625b 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -218,7 +218,8 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,
void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image> &p_image, CompressMode p_compress_mode, Image::UsedChannels p_channels, Image::CompressMode p_compress_format, float p_lossy_quality) {
switch (p_compress_mode) {
case COMPRESS_LOSSLESS: {
- bool lossless_force_png = ProjectSettings::get_singleton()->get("rendering/textures/lossless_compression/force_png");
+ bool lossless_force_png = ProjectSettings::get_singleton()->get("rendering/textures/lossless_compression/force_png") ||
+ !Image::_webp_mem_loader_func; // WebP module disabled.
bool use_webp = !lossless_force_png && p_image->get_width() <= 16383 && p_image->get_height() <= 16383; // WebP has a size limit
f->store_32(use_webp ? StreamTexture2D::DATA_FORMAT_WEBP : StreamTexture2D::DATA_FORMAT_PNG);
f->store_16(p_image->get_width());
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index 127219546d..b1ef85b4f4 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -2848,7 +2848,7 @@ void ThemeTypeEditor::_font_size_item_changed(float p_value, String p_item_name)
edited_theme->set_font_size(p_item_name, edited_type, int(p_value));
}
-void ThemeTypeEditor::_edit_resource_item(RES p_resource) {
+void ThemeTypeEditor::_edit_resource_item(RES p_resource, bool p_edit) {
EditorNode::get_singleton()->edit_resource(p_resource);
}
diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h
index b6becbb1c7..f5ad577aff 100644
--- a/editor/plugins/theme_editor_plugin.h
+++ b/editor/plugins/theme_editor_plugin.h
@@ -362,7 +362,7 @@ class ThemeTypeEditor : public MarginContainer {
void _color_item_changed(Color p_value, String p_item_name);
void _constant_item_changed(float p_value, String p_item_name);
void _font_size_item_changed(float p_value, String p_item_name);
- void _edit_resource_item(RES p_resource);
+ void _edit_resource_item(RES p_resource, bool p_edit);
void _font_item_changed(Ref<Font> p_value, String p_item_name);
void _icon_item_changed(Ref<Texture2D> p_value, String p_item_name);
void _stylebox_item_changed(Ref<StyleBox> p_value, String p_item_name);
diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp
index c3bd84c329..b5a7da0c38 100644
--- a/modules/bullet/area_bullet.cpp
+++ b/modules/bullet/area_bullet.cpp
@@ -94,10 +94,9 @@ void AreaBullet::dispatch_callbacks() {
void AreaBullet::call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3D::AreaBodyStatus p_status) {
InOutEventCallback &event = eventsCallbacks[static_cast<int>(p_otherObject->getType())];
- Object *areaGodoObject = ObjectDB::get_instance(event.event_callback_id);
- if (!areaGodoObject) {
- event.event_callback_id = ObjectID();
+ if (!event.event_callback.is_valid()) {
+ event.event_callback = Callable();
return;
}
@@ -108,7 +107,8 @@ void AreaBullet::call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3
call_event_res[4] = 0; // self_shape ID
Callable::CallError outResp;
- areaGodoObject->call(event.event_callback_method, (const Variant **)call_event_res_ptr, 5, outResp);
+ Variant ret;
+ event.event_callback.call((const Variant **)call_event_res, 5, ret, outResp);
}
void AreaBullet::scratch() {
@@ -267,13 +267,12 @@ Variant AreaBullet::get_param(PhysicsServer3D::AreaParameter p_param) const {
}
}
-void AreaBullet::set_event_callback(Type p_callbackObjectType, ObjectID p_id, const StringName &p_method) {
+void AreaBullet::set_event_callback(Type p_callbackObjectType, const Callable &p_callback) {
InOutEventCallback &ev = eventsCallbacks[static_cast<int>(p_callbackObjectType)];
- ev.event_callback_id = p_id;
- ev.event_callback_method = p_method;
+ ev.event_callback = p_callback;
/// Set if monitoring
- if (eventsCallbacks[0].event_callback_id.is_valid() || eventsCallbacks[1].event_callback_id.is_valid()) {
+ if (!eventsCallbacks[0].event_callback.is_null() || !eventsCallbacks[1].event_callback.is_null()) {
set_godot_object_flags(get_godot_object_flags() | GOF_IS_MONITORING_AREA);
} else {
set_godot_object_flags(get_godot_object_flags() & (~GOF_IS_MONITORING_AREA));
@@ -281,7 +280,7 @@ void AreaBullet::set_event_callback(Type p_callbackObjectType, ObjectID p_id, co
}
bool AreaBullet::has_event_callback(Type p_callbackObjectType) {
- return eventsCallbacks[static_cast<int>(p_callbackObjectType)].event_callback_id.is_valid();
+ return !eventsCallbacks[static_cast<int>(p_callbackObjectType)].event_callback.is_null();
}
void AreaBullet::on_enter_area(AreaBullet *p_area) {
diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h
index c8b516c951..d96c550082 100644
--- a/modules/bullet/area_bullet.h
+++ b/modules/bullet/area_bullet.h
@@ -47,8 +47,7 @@ class AreaBullet : public RigidCollisionObjectBullet {
public:
struct InOutEventCallback {
- ObjectID event_callback_id;
- StringName event_callback_method;
+ Callable event_callback;
InOutEventCallback() {}
};
@@ -162,7 +161,7 @@ public:
void set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value);
Variant get_param(PhysicsServer3D::AreaParameter p_param) const;
- void set_event_callback(Type p_callbackObjectType, ObjectID p_id, const StringName &p_method);
+ void set_event_callback(Type p_callbackObjectType, const Callable &p_callback);
bool has_event_callback(Type p_callbackObjectType);
virtual void on_enter_area(AreaBullet *p_area);
diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp
index bb2db49c87..610d2145cd 100644
--- a/modules/bullet/bullet_physics_server.cpp
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -413,18 +413,18 @@ void BulletPhysicsServer3D::area_set_monitorable(RID p_area, bool p_monitorable)
area->set_monitorable(p_monitorable);
}
-void BulletPhysicsServer3D::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
+void BulletPhysicsServer3D::area_set_monitor_callback(RID p_area, const Callable &p_callback) {
AreaBullet *area = area_owner.get_or_null(p_area);
ERR_FAIL_COND(!area);
- area->set_event_callback(CollisionObjectBullet::TYPE_RIGID_BODY, p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method);
+ area->set_event_callback(CollisionObjectBullet::TYPE_RIGID_BODY, p_callback.is_valid() ? p_callback : Callable());
}
-void BulletPhysicsServer3D::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
+void BulletPhysicsServer3D::area_set_area_monitor_callback(RID p_area, const Callable &p_callback) {
AreaBullet *area = area_owner.get_or_null(p_area);
ERR_FAIL_COND(!area);
- area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method);
+ area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_callback.is_valid() ? p_callback : Callable());
}
void BulletPhysicsServer3D::area_set_ray_pickable(RID p_area, bool p_enable) {
diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h
index 7c146de0c3..94635b5bfc 100644
--- a/modules/bullet/bullet_physics_server.h
+++ b/modules/bullet/bullet_physics_server.h
@@ -160,8 +160,8 @@ public:
virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override;
virtual void area_set_monitorable(RID p_area, bool p_monitorable) override;
- virtual void area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) override;
- virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) override;
+ virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) override;
+ virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) override;
virtual void area_set_ray_pickable(RID p_area, bool p_enable) override;
/* RIGID BODY API */
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index d4a098811a..cd247d1d26 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -1064,7 +1064,8 @@ void GDScriptTokenizer::check_indent() {
// First time indenting, choose character now.
indent_char = current_indent_char;
} else if (current_indent_char != indent_char) {
- Token error = make_error(vformat("Used \"%s\" for indentation instead \"%s\" as used before in the file.", String(&current_indent_char, 1).c_escape(), String(&indent_char, 1).c_escape()));
+ Token error = make_error(vformat("Used %s character for indentation instead of %s as used before in the file.",
+ _get_indent_char_name(current_indent_char), _get_indent_char_name(indent_char)));
error.start_line = line;
error.start_column = 1;
error.leftmost_column = 1;
@@ -1114,6 +1115,12 @@ void GDScriptTokenizer::check_indent() {
}
}
+String GDScriptTokenizer::_get_indent_char_name(char32_t ch) {
+ ERR_FAIL_COND_V(ch != ' ' && ch != '\t', String(&ch, 1).c_escape());
+
+ return ch == ' ' ? "space" : "tab";
+}
+
void GDScriptTokenizer::_skip_whitespace() {
if (pending_indents != 0) {
// Still have some indent/dedent tokens to give.
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index 84b82c07f0..b4ee11fd9a 100644
--- a/modules/gdscript/gdscript_tokenizer.h
+++ b/modules/gdscript/gdscript_tokenizer.h
@@ -233,6 +233,7 @@ private:
bool has_error() const { return !error_stack.is_empty(); }
Token pop_error();
char32_t _advance();
+ String _get_indent_char_name(char32_t ch);
void _skip_whitespace();
void check_indent();
diff --git a/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out b/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out
index 6390de9788..31bed2dbc7 100644
--- a/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out
+++ b/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out
@@ -1,2 +1,2 @@
GDTEST_PARSER_ERROR
-Used "\t" for indentation instead " " as used before in the file.
+Used tab character for indentation instead of space as used before in the file.
diff --git a/modules/gltf/doc_classes/GLTFMesh.xml b/modules/gltf/doc_classes/GLTFMesh.xml
index 1e7199d229..58853217e2 100644
--- a/modules/gltf/doc_classes/GLTFMesh.xml
+++ b/modules/gltf/doc_classes/GLTFMesh.xml
@@ -9,6 +9,8 @@
<members>
<member name="blend_weights" type="PackedFloat32Array" setter="set_blend_weights" getter="get_blend_weights" default="PackedFloat32Array()">
</member>
+ <member name="instance_materials" type="Array" setter="set_instance_materials" getter="get_instance_materials" default="[]">
+ </member>
<member name="mesh" type="ImporterMesh" setter="set_mesh" getter="get_mesh">
</member>
</members>
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 333fc4637d..a5e56640ed 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -795,6 +795,9 @@ Error GLTFDocument::_encode_buffer_views(Ref<GLTFState> state) {
buffers.push_back(d);
}
print_verbose("glTF: Total buffer views: " + itos(state->buffer_views.size()));
+ if (!buffers.size()) {
+ return OK;
+ }
state->json["bufferViews"] = buffers;
return OK;
}
@@ -884,6 +887,9 @@ Error GLTFDocument::_encode_accessors(Ref<GLTFState> state) {
accessors.push_back(d);
}
+ if (!accessors.size()) {
+ return OK;
+ }
state->json["accessors"] = accessors;
ERR_FAIL_COND_V(!state->json.has("accessors"), ERR_FILE_CORRUPT);
print_verbose("glTF: Total accessors: " + itos(state->accessors.size()));
@@ -2112,6 +2118,7 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) {
if (import_mesh.is_null()) {
continue;
}
+ Array instance_materials = state->meshes.write[gltf_mesh_i]->get_instance_materials();
Array primitives;
Dictionary gltf_mesh;
Array target_names;
@@ -2431,7 +2438,14 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) {
}
}
- Ref<BaseMaterial3D> mat = import_mesh->get_surface_material(surface_i);
+ Variant v;
+ if (surface_i < instance_materials.size()) {
+ v = instance_materials.get(surface_i);
+ }
+ Ref<BaseMaterial3D> mat = v;
+ if (!mat.is_valid()) {
+ mat = import_mesh->get_surface_material(surface_i);
+ }
if (mat.is_valid()) {
Map<Ref<BaseMaterial3D>, GLTFMaterialIndex>::Element *material_cache_i = state->material_cache.find(mat);
if (material_cache_i && material_cache_i->get() != -1) {
@@ -2475,6 +2489,9 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) {
meshes.push_back(gltf_mesh);
}
+ if (!meshes.size()) {
+ return OK;
+ }
state->json["meshes"] = meshes;
print_verbose("glTF: Total meshes: " + itos(meshes.size()));
@@ -3454,6 +3471,9 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
}
materials.push_back(d);
}
+ if (!materials.size()) {
+ return OK;
+ }
state->json["materials"] = materials;
print_verbose("Total materials: " + itos(state->materials.size()));
@@ -4837,6 +4857,9 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) {
}
}
+ if (!animations.size()) {
+ return OK;
+ }
state->json["animations"] = animations;
print_verbose("glTF: Total animations '" + itos(state->animations.size()) + "'.");
@@ -5057,6 +5080,18 @@ GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref<GLTFState> state, MeshInst
}
Ref<GLTFMesh> gltf_mesh;
gltf_mesh.instantiate();
+ Array instance_materials;
+ for (int32_t surface_i = 0; surface_i < current_mesh->get_surface_count(); surface_i++) {
+ Ref<Material> mat = current_mesh->get_surface_material(surface_i);
+ if (p_mesh_instance->get_surface_override_material(surface_i).is_valid()) {
+ mat = p_mesh_instance->get_surface_override_material(surface_i);
+ }
+ if (p_mesh_instance->get_material_override().is_valid()) {
+ mat = p_mesh_instance->get_material_override();
+ }
+ instance_materials.append(mat);
+ }
+ gltf_mesh->set_instance_materials(instance_materials);
gltf_mesh->set_mesh(current_mesh);
gltf_mesh->set_blend_weights(blend_weights);
GLTFMeshIndex mesh_i = state->meshes.size();
diff --git a/modules/gltf/gltf_mesh.cpp b/modules/gltf/gltf_mesh.cpp
index 747820521a..7134345b30 100644
--- a/modules/gltf/gltf_mesh.cpp
+++ b/modules/gltf/gltf_mesh.cpp
@@ -36,9 +36,12 @@ void GLTFMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &GLTFMesh::set_mesh);
ClassDB::bind_method(D_METHOD("get_blend_weights"), &GLTFMesh::get_blend_weights);
ClassDB::bind_method(D_METHOD("set_blend_weights", "blend_weights"), &GLTFMesh::set_blend_weights);
+ ClassDB::bind_method(D_METHOD("get_instance_materials"), &GLTFMesh::get_instance_materials);
+ ClassDB::bind_method(D_METHOD("set_instance_materials", "instance_materials"), &GLTFMesh::set_instance_materials);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh"), "set_mesh", "get_mesh");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT32_ARRAY, "blend_weights"), "set_blend_weights", "get_blend_weights"); // Vector<float>
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "instance_materials"), "set_instance_materials", "get_instance_materials");
}
Ref<ImporterMesh> GLTFMesh::get_mesh() {
@@ -49,6 +52,14 @@ void GLTFMesh::set_mesh(Ref<ImporterMesh> p_mesh) {
mesh = p_mesh;
}
+Array GLTFMesh::get_instance_materials() {
+ return instance_materials;
+}
+
+void GLTFMesh::set_instance_materials(Array p_instance_materials) {
+ instance_materials = p_instance_materials;
+}
+
Vector<float> GLTFMesh::get_blend_weights() {
return blend_weights;
}
diff --git a/modules/gltf/gltf_mesh.h b/modules/gltf/gltf_mesh.h
index 3aba0ede32..cc2be93c09 100644
--- a/modules/gltf/gltf_mesh.h
+++ b/modules/gltf/gltf_mesh.h
@@ -43,6 +43,7 @@ class GLTFMesh : public Resource {
private:
Ref<ImporterMesh> mesh;
Vector<float> blend_weights;
+ Array instance_materials;
protected:
static void _bind_methods();
@@ -52,5 +53,7 @@ public:
void set_mesh(Ref<ImporterMesh> p_mesh);
Vector<float> get_blend_weights();
void set_blend_weights(Vector<float> p_blend_weights);
+ Array get_instance_materials();
+ void set_instance_materials(Array p_instance_materials);
};
#endif // GLTF_MESH_H
diff --git a/platform/osx/SCsub b/platform/osx/SCsub
index 46c13d8550..8ba106d1c2 100644
--- a/platform/osx/SCsub
+++ b/platform/osx/SCsub
@@ -13,7 +13,7 @@ files = [
"dir_access_osx.mm",
"joypad_osx.cpp",
"vulkan_context_osx.mm",
- "context_gl_osx.mm",
+ "gl_manager_osx.mm",
]
prog = env.add_program("#bin/godot", files)
diff --git a/platform/osx/context_gl_osx.mm b/platform/osx/context_gl_osx.mm
deleted file mode 100644
index eab9d8dc0c..0000000000
--- a/platform/osx/context_gl_osx.mm
+++ /dev/null
@@ -1,161 +0,0 @@
-/*************************************************************************/
-/* context_gl_osx.mm */
-/*************************************************************************/
-/* 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 "context_gl_osx.h"
-
-#if defined(GLES3_ENABLED) || defined(GLES_ENABLED)
-
-void ContextGL_OSX::release_current() {
- [NSOpenGLContext clearCurrentContext];
-}
-
-void ContextGL_OSX::make_current() {
- [context makeCurrentContext];
-}
-
-void ContextGL_OSX::update() {
- [context update];
-}
-
-void ContextGL_OSX::set_opacity(GLint p_opacity) {
- [context setValues:&p_opacity forParameter:NSOpenGLCPSurfaceOpacity];
-}
-
-int ContextGL_OSX::get_window_width() {
- return OS::get_singleton()->get_video_mode().width;
-}
-
-int ContextGL_OSX::get_window_height() {
- return OS::get_singleton()->get_video_mode().height;
-}
-
-void ContextGL_OSX::swap_buffers() {
- [context flushBuffer];
-}
-
-void ContextGL_OSX::set_use_vsync(bool p_use) {
- CGLContextObj ctx = CGLGetCurrentContext();
- if (ctx) {
- GLint swapInterval = p_use ? 1 : 0;
- CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval);
- use_vsync = p_use;
- }
-}
-
-bool ContextGL_OSX::is_using_vsync() const {
- return use_vsync;
-}
-
-Error ContextGL_OSX::initialize() {
- framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
- ERR_FAIL_COND_V(!framework, ERR_CANT_CREATE);
-
- unsigned int attributeCount = 0;
-
- // OS X needs non-zero color size, so set reasonable values
- int colorBits = 32;
-
- // Fail if a robustness strategy was requested
-
-#define ADD_ATTR(x) \
- { attributes[attributeCount++] = x; }
-#define ADD_ATTR2(x, y) \
- { \
- ADD_ATTR(x); \
- ADD_ATTR(y); \
- }
-
- // Arbitrary array size here
- NSOpenGLPixelFormatAttribute attributes[40];
-
- ADD_ATTR(NSOpenGLPFADoubleBuffer);
- ADD_ATTR(NSOpenGLPFAClosestPolicy);
-
- if (!gles3_context) {
- ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy);
- } else {
- //we now need OpenGL 3 or better, maybe even change this to 3_3Core ?
- ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
- }
-
- ADD_ATTR2(NSOpenGLPFAColorSize, colorBits);
-
- /*
- if (fbconfig->alphaBits > 0)
- ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
-*/
-
- ADD_ATTR2(NSOpenGLPFADepthSize, 24);
-
- ADD_ATTR2(NSOpenGLPFAStencilSize, 8);
-
- /*
- if (fbconfig->stereo)
- ADD_ATTR(NSOpenGLPFAStereo);
-*/
-
- /*
- if (fbconfig->samples > 0) {
- ADD_ATTR2(NSOpenGLPFASampleBuffers, 1);
- ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples);
- }
-*/
-
- // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
- // framebuffer, so there's no need (and no way) to request it
-
- ADD_ATTR(0);
-
-#undef ADD_ATTR
-#undef ADD_ATTR2
-
- pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
- ERR_FAIL_COND_V(pixelFormat == nil, ERR_CANT_CREATE);
-
- context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
-
- ERR_FAIL_COND_V(context == nil, ERR_CANT_CREATE);
-
- [context setView:window_view];
-
- [context makeCurrentContext];
-
- return OK;
-}
-
-ContextGL_OSX::ContextGL_OSX(id p_view, bool p_gles3_context) {
- gles3_context = p_gles3_context;
- window_view = p_view;
- use_vsync = false;
-}
-
-ContextGL_OSX::~ContextGL_OSX() {}
-
-#endif
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index d9b55631cd..6bd79c7d4f 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -183,10 +183,13 @@ def configure(env):
)
env.Append(LIBS=["pthread", "z"])
+ if env["opengl3"]:
+ env.Append(CPPDEFINES=["GLES_ENABLED", "GLES3_ENABLED"])
+ env.Append(CCFLAGS=["-Wno-deprecated-declarations"]) # Disable deprecation warnings
+ env.Append(LINKFLAGS=["-framework", "OpenGL"])
+
if env["vulkan"]:
env.Append(CPPDEFINES=["VULKAN_ENABLED"])
env.Append(LINKFLAGS=["-framework", "Metal", "-framework", "QuartzCore", "-framework", "IOSurface"])
if not env["use_volk"]:
env.Append(LINKFLAGS=["-L$VULKAN_SDK_PATH/MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/", "-lMoltenVK"])
-
- # env.Append(CPPDEFINES=['GLES_ENABLED', 'GLES3_ENABLED'])
diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h
index 96baeb4dec..c45b470078 100644
--- a/platform/osx/display_server_osx.h
+++ b/platform/osx/display_server_osx.h
@@ -37,8 +37,7 @@
#include "servers/display_server.h"
#if defined(GLES3_ENABLED)
-#include "context_gl_osx.h"
-//TODO - reimplement OpenGLES
+#include "gl_manager_osx.h"
#endif
#if defined(VULKAN_ENABLED)
@@ -65,11 +64,11 @@ public:
void _menu_callback(id p_sender);
#if defined(GLES3_ENABLED)
- ContextGL_OSX *context_gles2;
+ GLManager_OSX *gl_manager = nullptr;
#endif
#if defined(VULKAN_ENABLED)
- VulkanContextOSX *context_vulkan;
- RenderingDeviceVulkan *rendering_device_vulkan;
+ VulkanContextOSX *context_vulkan = nullptr;
+ RenderingDeviceVulkan *rendering_device_vulkan = nullptr;
#endif
const NSMenu *_get_menu_root(const String &p_menu_root) const;
@@ -109,9 +108,6 @@ public:
Vector<Vector2> mpath;
-#if defined(GLES3_ENABLED)
- ContextGL_OSX *context_gles2 = nullptr;
-#endif
Point2i mouse_pos;
Size2i min_size;
@@ -287,6 +283,7 @@ public:
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
+ virtual void gl_window_make_current(DisplayServer::WindowID p_window_id) override;
virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index d89e64cd7d..a862f14efb 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -46,7 +46,7 @@
#include <IOKit/hid/IOHIDLib.h>
#if defined(GLES3_ENABLED)
-//TODO - reimplement OpenGLES
+#include "drivers/gles3/rasterizer_gles3.h"
#import <AppKit/NSOpenGLView.h>
#endif
@@ -167,8 +167,8 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
#if defined(GLES3_ENABLED)
- if (DS_OSX->rendering_driver == "opengl_es") {
- //TODO - reimplement OpenGLES
+ if (DS_OSX->rendering_driver == "opengl3") {
+ DS_OSX->gl_manager->window_destroy(window_id);
}
#endif
#ifdef VULKAN_ENABLED
@@ -272,8 +272,8 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
#if defined(GLES3_ENABLED)
- if (DS_OSX->rendering_driver == "opengl_es") {
- //TODO - reimplement OpenGLES
+ if (DS_OSX->rendering_driver == "opengl3") {
+ DS_OSX->gl_manager->window_resize(window_id, wd.size.width, wd.size.height);
}
#endif
#if defined(VULKAN_ENABLED)
@@ -377,7 +377,12 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
/* GodotContentView */
/*************************************************************************/
+#if defined(GLES3_ENABLED)
+@interface GodotContentView : NSOpenGLView <NSTextInputClient> {
+#else
@interface GodotContentView : NSView <NSTextInputClient> {
+#endif
+
DisplayServerOSX::WindowID window_id;
NSTrackingArea *trackingArea;
NSMutableAttributedString *markedText;
@@ -405,12 +410,6 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
- (CALayer *)makeBackingLayer {
-#if defined(GLES3_ENABLED)
- if (DS_OSX->rendering_driver == "opengl_es") {
- CALayer *layer = [[NSOpenGLLayer class] layer];
- return layer;
- }
-#endif
#if defined(VULKAN_ENABLED)
if (DS_OSX->rendering_driver == "vulkan") {
CALayer *layer = [[CAMetalLayer class] layer];
@@ -422,9 +421,8 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
- (void)updateLayer {
#if defined(GLES3_ENABLED)
- if (DS_OSX->rendering_driver == "opengl_es") {
- [super updateLayer];
- //TODO - reimplement OpenGLES
+ if (DS_OSX->rendering_driver == "opengl3") {
+ DS_OSX->gl_manager->window_update(window_id);
}
#endif
#if defined(VULKAN_ENABLED)
@@ -2587,7 +2585,7 @@ void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled
}
#endif
#if defined(GLES3_ENABLED)
- if (rendering_driver == "opengl_es") {
+ if (rendering_driver == "opengl3") {
//TODO - reimplement OpenGLES
}
#endif
@@ -2606,14 +2604,14 @@ void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled
}
#endif
#if defined(GLES3_ENABLED)
- if (rendering_driver == "opengl_es") {
+ if (rendering_driver == "opengl3") {
//TODO - reimplement OpenGLES
}
#endif
wd.layered_window = false;
}
#if defined(GLES3_ENABLED)
- if (rendering_driver == "opengl_es") {
+ if (rendering_driver == "opengl3") {
//TODO - reimplement OpenGLES
}
#endif
@@ -3455,18 +3453,31 @@ void DisplayServerOSX::set_icon(const Ref<Image> &p_icon) {
void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
_THREAD_SAFE_METHOD_
+#if defined(GLES3_ENABLED)
+ if (rendering_driver == "opengl3") {
+ gl_manager->swap_buffers();
+ }
+#endif
#if defined(VULKAN_ENABLED)
- context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+ if (rendering_driver == "vulkan") {
+ context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+ }
#endif
}
DisplayServer::VSyncMode DisplayServerOSX::window_get_vsync_mode(WindowID p_window) const {
_THREAD_SAFE_METHOD_
+#if defined(GLES3_ENABLED)
+ if (rendering_driver == "opengl3") {
+ return (gl_manager->is_using_vsync() ? DisplayServer::VSyncMode::VSYNC_ENABLED : DisplayServer::VSyncMode::VSYNC_DISABLED);
+ }
+#endif
#if defined(VULKAN_ENABLED)
- return context_vulkan->get_vsync_mode(p_window);
-#else
- return DisplayServer::VSYNC_ENABLED;
+ if (rendering_driver == "vulkan") {
+ return context_vulkan->get_vsync_mode(p_window);
+ }
#endif
+ return DisplayServer::VSYNC_ENABLED;
}
Vector<String> DisplayServerOSX::get_rendering_drivers_func() {
@@ -3476,12 +3487,18 @@ Vector<String> DisplayServerOSX::get_rendering_drivers_func() {
drivers.push_back("vulkan");
#endif
#if defined(GLES3_ENABLED)
- drivers.push_back("opengl_es");
+ drivers.push_back("opengl3");
#endif
return drivers;
}
+void DisplayServerOSX::gl_window_make_current(DisplayServer::WindowID p_window_id) {
+#if defined(GLES3_ENABLED)
+ gl_manager->window_make_current(p_window_id);
+#endif
+}
+
Point2i DisplayServerOSX::ime_get_selection() const {
return im_selection;
}
@@ -3522,7 +3539,7 @@ ObjectID DisplayServerOSX::window_get_attached_instance_id(WindowID p_window) co
DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
DisplayServer *ds = memnew(DisplayServerOSX(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) {
- OS::get_singleton()->alert("Your video card driver does not support any of the supported Metal versions.", "Unable to initialize Video driver");
+ OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan or OpenGL versions.", "Unable to initialize Video driver");
}
return ds;
}
@@ -3580,8 +3597,11 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, V
}
#endif
#if defined(GLES3_ENABLED)
- if (rendering_driver == "opengl_es") {
- //TODO - reimplement OpenGLES
+ if (rendering_driver == "opengl3") {
+ if (gl_manager) {
+ Error err = gl_manager->window_create(window_id_counter, wd.window_view, p_rect.size.width, p_rect.size.height);
+ ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create an OpenGL context");
+ }
}
#endif
id = window_id_counter++;
@@ -3601,8 +3621,8 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, V
}
#if defined(GLES3_ENABLED)
- if (rendering_driver == "opengl_es") {
- //TODO - reimplement OpenGLES
+ if (rendering_driver == "opengl3") {
+ gl_manager->window_resize(id, wd.size.width, wd.size.height);
}
#endif
#if defined(VULKAN_ENABLED)
@@ -3654,15 +3674,15 @@ void DisplayServerOSX::_dispatch_input_event(const Ref<InputEvent> &p_event) {
}
void DisplayServerOSX::release_rendering_thread() {
- //TODO - reimplement OpenGLES
}
void DisplayServerOSX::make_rendering_thread() {
- //TODO - reimplement OpenGLES
}
void DisplayServerOSX::swap_buffers() {
- //TODO - reimplement OpenGLES
+#if defined(GLES3_ENABLED)
+ gl_manager->swap_buffers();
+#endif
}
void DisplayServerOSX::console_set_visible(bool p_enabled) {
@@ -3753,14 +3773,17 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
//TODO - do Vulkan and OpenGL support checks, driver selection and fallback
rendering_driver = p_rendering_driver;
-#ifndef _MSC_VER
-#warning Forcing vulkan rendering driver because OpenGL not implemented yet
-#endif
- rendering_driver = "vulkan";
-
#if defined(GLES3_ENABLED)
- if (rendering_driver == "opengl_es") {
- //TODO - reimplement OpenGLES
+ if (rendering_driver == "opengl3") {
+ GLManager_OSX::ContextType opengl_api_type = GLManager_OSX::GLES_3_0_COMPATIBLE;
+ gl_manager = memnew(GLManager_OSX(opengl_api_type));
+ if (gl_manager->initialize() != OK) {
+ memdelete(gl_manager);
+ gl_manager = nullptr;
+ r_error = ERR_UNAVAILABLE;
+ ERR_FAIL_MSG("Could not initialize OpenGL");
+ return;
+ }
}
#endif
#if defined(VULKAN_ENABLED)
@@ -3788,8 +3811,8 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
show_window(MAIN_WINDOW_ID);
#if defined(GLES3_ENABLED)
- if (rendering_driver == "opengl_es") {
- //TODO - reimplement OpenGLES
+ if (rendering_driver == "opengl3") {
+ RasterizerGLES3::make_current();
}
#endif
#if defined(VULKAN_ENABLED)
@@ -3821,20 +3844,21 @@ DisplayServerOSX::~DisplayServerOSX() {
//destroy drivers
#if defined(GLES3_ENABLED)
- if (rendering_driver == "opengl_es") {
- //TODO - reimplement OpenGLES
+ if (gl_manager) {
+ memdelete(gl_manager);
+ gl_manager = nullptr;
}
#endif
#if defined(VULKAN_ENABLED)
- if (rendering_driver == "vulkan") {
- if (rendering_device_vulkan) {
- rendering_device_vulkan->finalize();
- memdelete(rendering_device_vulkan);
- }
+ if (rendering_device_vulkan) {
+ rendering_device_vulkan->finalize();
+ memdelete(rendering_device_vulkan);
+ rendering_device_vulkan = nullptr;
+ }
- if (context_vulkan) {
- memdelete(context_vulkan);
- }
+ if (context_vulkan) {
+ memdelete(context_vulkan);
+ context_vulkan = nullptr;
}
#endif
diff --git a/platform/osx/context_gl_osx.h b/platform/osx/gl_manager_osx.h
index 77bae3247d..f86bc805c1 100644
--- a/platform/osx/context_gl_osx.h
+++ b/platform/osx/gl_manager_osx.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* context_gl_osx.h */
+/* gl_manager_osx.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,47 +28,79 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef CONTEXT_GL_OSX_H
-#define CONTEXT_GL_OSX_H
+#ifndef GL_MANAGER_OSX_H
+#define GL_MANAGER_OSX_H
-#if defined(GLES3_ENABLED) || defined(GLES_ENABLED)
+#if defined(OSX_ENABLED) && defined(GLES3_ENABLED)
#include "core/error/error_list.h"
#include "core/os/os.h"
+#include "core/templates/local_vector.h"
+#include "servers/display_server.h"
#include <AppKit/AppKit.h>
#include <ApplicationServices/ApplicationServices.h>
#include <CoreVideo/CoreVideo.h>
-class ContextGL_OSX {
- bool gles3_context;
- bool use_vsync;
+class GLManager_OSX {
+public:
+ enum ContextType {
+ GLES_3_0_COMPATIBLE,
+ };
+
+private:
+ struct GLWindow {
+ GLWindow() { in_use = false; }
+ bool in_use;
+
+ DisplayServer::WindowID window_id;
+ int width;
+ int height;
+
+ id window_view;
+ NSOpenGLContext *context;
+ };
+
+ LocalVector<GLWindow> _windows;
+
+ NSOpenGLContext *_shared_context = nullptr;
+ GLWindow *_current_window;
+
+ Error _create_context(GLWindow &win);
+ void _internal_set_current_window(GLWindow *p_win);
- void *framework;
- id window_view;
- NSOpenGLPixelFormat *pixelFormat;
- NSOpenGLContext *context;
+ GLWindow &get_window(unsigned int id) { return _windows[id]; }
+ const GLWindow &get_window(unsigned int id) const { return _windows[id]; }
+
+ bool use_vsync;
+ ContextType context_type;
public:
- void release_current();
+ Error window_create(DisplayServer::WindowID p_window_id, id p_view, int p_width, int p_height);
+ void window_destroy(DisplayServer::WindowID p_window_id);
+ void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height);
+
+ // get directly from the cached GLWindow
+ int window_get_width(DisplayServer::WindowID p_window_id = 0);
+ int window_get_height(DisplayServer::WindowID p_window_id = 0);
+ void release_current();
void make_current();
- void update();
+ void swap_buffers();
- void set_opacity(GLint p_opacity);
+ void window_make_current(DisplayServer::WindowID p_window_id);
- int get_window_width();
- int get_window_height();
- void swap_buffers();
+ void window_update(DisplayServer::WindowID p_window_id);
Error initialize();
void set_use_vsync(bool p_use);
bool is_using_vsync() const;
- ContextGL_OSX(id p_view, bool p_gles3_context);
- ~ContextGL_OSX();
+ GLManager_OSX(ContextType p_context_type);
+ ~GLManager_OSX();
};
-#endif
-#endif
+#endif // defined(OSX_ENABLED) && defined(GLES3_ENABLED)
+
+#endif // GL_MANAGER_OSX_H
diff --git a/platform/osx/gl_manager_osx.mm b/platform/osx/gl_manager_osx.mm
new file mode 100644
index 0000000000..cce58530ee
--- /dev/null
+++ b/platform/osx/gl_manager_osx.mm
@@ -0,0 +1,233 @@
+/*************************************************************************/
+/* gl_manager_osx.mm */
+/*************************************************************************/
+/* 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 "gl_manager_osx.h"
+
+#ifdef OSX_ENABLED
+#ifdef GLES3_ENABLED
+
+#include <stdio.h>
+#include <stdlib.h>
+
+Error GLManager_OSX::_create_context(GLWindow &win) {
+ NSOpenGLPixelFormatAttribute attributes[] = {
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFAClosestPolicy,
+ NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
+ NSOpenGLPFAColorSize, 32,
+ NSOpenGLPFADepthSize, 24,
+ NSOpenGLPFAStencilSize, 8,
+ 0
+ };
+
+ NSOpenGLPixelFormat *pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
+ ERR_FAIL_COND_V(pixel_format == nil, ERR_CANT_CREATE);
+
+ win.context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:_shared_context];
+ ERR_FAIL_COND_V(win.context == nil, ERR_CANT_CREATE);
+ if (_shared_context == nullptr) {
+ _shared_context = win.context;
+ }
+
+ [win.context setView:win.window_view];
+ [win.context makeCurrentContext];
+
+ return OK;
+}
+
+Error GLManager_OSX::window_create(DisplayServer::WindowID p_window_id, id p_view, int p_width, int p_height) {
+ if (p_window_id >= (int)_windows.size()) {
+ _windows.resize(p_window_id + 1);
+ }
+
+ GLWindow &win = _windows[p_window_id];
+ win.in_use = true;
+ win.window_id = p_window_id;
+ win.width = p_width;
+ win.height = p_height;
+ win.window_view = p_view;
+
+ if (_create_context(win) != OK) {
+ _windows.remove(_windows.size() - 1);
+ return FAILED;
+ }
+
+ window_make_current(_windows.size() - 1);
+
+ return OK;
+}
+
+void GLManager_OSX::_internal_set_current_window(GLWindow *p_win) {
+ _current_window = p_win;
+}
+
+void GLManager_OSX::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {
+ if (p_window_id == -1) {
+ return;
+ }
+
+ GLWindow &win = _windows[p_window_id];
+ if (!win.in_use) {
+ return;
+ }
+
+ win.width = p_width;
+ win.height = p_height;
+
+ GLint dim[2];
+ dim[0] = p_width;
+ dim[1] = p_height;
+ CGLSetParameter((CGLContextObj)[win.context CGLContextObj], kCGLCPSurfaceBackingSize, &dim[0]);
+ CGLEnable((CGLContextObj)[win.context CGLContextObj], kCGLCESurfaceBackingSize);
+ if (OS::get_singleton()->is_hidpi_allowed()) {
+ [win.window_view setWantsBestResolutionOpenGLSurface:YES];
+ } else {
+ [win.window_view setWantsBestResolutionOpenGLSurface:NO];
+ }
+
+ [win.context update];
+}
+
+int GLManager_OSX::window_get_width(DisplayServer::WindowID p_window_id) {
+ return get_window(p_window_id).width;
+}
+
+int GLManager_OSX::window_get_height(DisplayServer::WindowID p_window_id) {
+ return get_window(p_window_id).height;
+}
+
+void GLManager_OSX::window_destroy(DisplayServer::WindowID p_window_id) {
+ GLWindow &win = get_window(p_window_id);
+ win.in_use = false;
+
+ if (_current_window == &win) {
+ _current_window = nullptr;
+ }
+}
+
+void GLManager_OSX::release_current() {
+ if (!_current_window) {
+ return;
+ }
+
+ [NSOpenGLContext clearCurrentContext];
+}
+
+void GLManager_OSX::window_make_current(DisplayServer::WindowID p_window_id) {
+ if (p_window_id == -1) {
+ return;
+ }
+
+ GLWindow &win = _windows[p_window_id];
+ if (!win.in_use) {
+ return;
+ }
+
+ if (&win == _current_window) {
+ return;
+ }
+
+ [win.context makeCurrentContext];
+
+ _internal_set_current_window(&win);
+}
+
+void GLManager_OSX::make_current() {
+ if (!_current_window) {
+ return;
+ }
+ if (!_current_window->in_use) {
+ WARN_PRINT("current window not in use!");
+ return;
+ }
+ [_current_window->context makeCurrentContext];
+}
+
+void GLManager_OSX::swap_buffers() {
+ // NO NEED TO CALL SWAP BUFFERS for each window...
+ // see https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glXSwapBuffers.xml
+
+ if (!_current_window) {
+ return;
+ }
+ if (!_current_window->in_use) {
+ WARN_PRINT("current window not in use!");
+ return;
+ }
+ [_current_window->context flushBuffer];
+}
+
+void GLManager_OSX::window_update(DisplayServer::WindowID p_window_id) {
+ if (p_window_id == -1) {
+ return;
+ }
+
+ GLWindow &win = _windows[p_window_id];
+ if (!win.in_use) {
+ return;
+ }
+
+ if (&win == _current_window) {
+ return;
+ }
+
+ [win.context update];
+}
+
+Error GLManager_OSX::initialize() {
+ return OK;
+}
+
+void GLManager_OSX::set_use_vsync(bool p_use) {
+ use_vsync = p_use;
+ CGLContextObj ctx = CGLGetCurrentContext();
+ if (ctx) {
+ GLint swapInterval = p_use ? 1 : 0;
+ CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval);
+ use_vsync = p_use;
+ }
+}
+
+bool GLManager_OSX::is_using_vsync() const {
+ return use_vsync;
+}
+
+GLManager_OSX::GLManager_OSX(ContextType p_context_type) {
+ context_type = p_context_type;
+ use_vsync = false;
+ _current_window = nullptr;
+}
+
+GLManager_OSX::~GLManager_OSX() {
+ release_current();
+}
+
+#endif // GLES3_ENABLED
+#endif // OSX
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index fff9c47d4d..75a1723e04 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -369,12 +369,11 @@ void Area2D::set_monitoring(bool p_enable) {
monitoring = p_enable;
if (monitoring) {
- PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_body_inout);
- PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_area_inout);
-
+ PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), callable_mp(this, &Area2D::_body_inout));
+ PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), callable_mp(this, &Area2D::_area_inout));
} else {
- PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), nullptr, StringName());
- PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), nullptr, StringName());
+ PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), Callable());
+ PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), Callable());
_clear_monitoring();
}
}
@@ -530,9 +529,6 @@ void Area2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_audio_bus_override", "enable"), &Area2D::set_audio_bus_override);
ClassDB::bind_method(D_METHOD("is_overriding_audio_bus"), &Area2D::is_overriding_audio_bus);
- ClassDB::bind_method(D_METHOD("_body_inout"), &Area2D::_body_inout);
- ClassDB::bind_method(D_METHOD("_area_inout"), &Area2D::_area_inout);
-
ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D")));
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp
index 9179983220..e459c42e8c 100644
--- a/scene/3d/area_3d.cpp
+++ b/scene/3d/area_3d.cpp
@@ -334,11 +334,11 @@ void Area3D::set_monitoring(bool p_enable) {
monitoring = p_enable;
if (monitoring) {
- PhysicsServer3D::get_singleton()->area_set_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_body_inout);
- PhysicsServer3D::get_singleton()->area_set_area_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_area_inout);
+ PhysicsServer3D::get_singleton()->area_set_monitor_callback(get_rid(), callable_mp(this, &Area3D::_body_inout));
+ PhysicsServer3D::get_singleton()->area_set_area_monitor_callback(get_rid(), callable_mp(this, &Area3D::_area_inout));
} else {
- PhysicsServer3D::get_singleton()->area_set_monitor_callback(get_rid(), nullptr, StringName());
- PhysicsServer3D::get_singleton()->area_set_area_monitor_callback(get_rid(), nullptr, StringName());
+ PhysicsServer3D::get_singleton()->area_set_monitor_callback(get_rid(), Callable());
+ PhysicsServer3D::get_singleton()->area_set_area_monitor_callback(get_rid(), Callable());
_clear_monitoring();
}
}
@@ -630,9 +630,6 @@ void Area3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("overlaps_body", "body"), &Area3D::overlaps_body);
ClassDB::bind_method(D_METHOD("overlaps_area", "area"), &Area3D::overlaps_area);
- ClassDB::bind_method(D_METHOD("_body_inout"), &Area3D::_body_inout);
- ClassDB::bind_method(D_METHOD("_area_inout"), &Area3D::_area_inout);
-
ClassDB::bind_method(D_METHOD("set_audio_bus_override", "enable"), &Area3D::set_audio_bus_override);
ClassDB::bind_method(D_METHOD("is_overriding_audio_bus"), &Area3D::is_overriding_audio_bus);
diff --git a/scene/3d/fog_volume.cpp b/scene/3d/fog_volume.cpp
index cc4fbbb41b..694defd7dc 100644
--- a/scene/3d/fog_volume.cpp
+++ b/scene/3d/fog_volume.cpp
@@ -50,6 +50,7 @@ void FogVolume::_validate_property(PropertyInfo &property) const {
property.usage = PROPERTY_USAGE_NONE;
return;
}
+ VisualInstance3D::_validate_property(property);
}
void FogVolume::set_extents(const Vector3 &p_extents) {
diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp
index 04b2437ae8..9ecd8ec2f3 100644
--- a/scene/resources/mesh_data_tool.cpp
+++ b/scene/resources/mesh_data_tool.cpp
@@ -421,6 +421,7 @@ Vector<int> MeshDataTool::get_vertex_bones(int p_idx) const {
void MeshDataTool::set_vertex_bones(int p_idx, const Vector<int> &p_bones) {
ERR_FAIL_INDEX(p_idx, vertices.size());
+ ERR_FAIL_COND(p_bones.size() != 4);
vertices.write[p_idx].bones = p_bones;
format |= Mesh::ARRAY_FORMAT_BONES;
}
@@ -432,6 +433,7 @@ Vector<float> MeshDataTool::get_vertex_weights(int p_idx) const {
void MeshDataTool::set_vertex_weights(int p_idx, const Vector<float> &p_weights) {
ERR_FAIL_INDEX(p_idx, vertices.size());
+ ERR_FAIL_COND(p_weights.size() != 4);
vertices.write[p_idx].weights = p_weights;
format |= Mesh::ARRAY_FORMAT_WEIGHTS;
}
diff --git a/servers/physics_2d/godot_area_2d.cpp b/servers/physics_2d/godot_area_2d.cpp
index 7cb202dd1f..6983e28841 100644
--- a/servers/physics_2d/godot_area_2d.cpp
+++ b/servers/physics_2d/godot_area_2d.cpp
@@ -77,16 +77,17 @@ void GodotArea2D::set_space(GodotSpace2D *p_space) {
_set_space(p_space);
}
-void GodotArea2D::set_monitor_callback(ObjectID p_id, const StringName &p_method) {
- if (p_id == monitor_callback_id) {
- monitor_callback_method = p_method;
+void GodotArea2D::set_monitor_callback(const Callable &p_callback) {
+ ObjectID id = p_callback.get_object_id();
+
+ if (id == monitor_callback.get_object_id()) {
+ monitor_callback = p_callback;
return;
}
_unregister_shapes();
- monitor_callback_id = p_id;
- monitor_callback_method = p_method;
+ monitor_callback = p_callback;
monitored_bodies.clear();
monitored_areas.clear();
@@ -98,16 +99,17 @@ void GodotArea2D::set_monitor_callback(ObjectID p_id, const StringName &p_method
}
}
-void GodotArea2D::set_area_monitor_callback(ObjectID p_id, const StringName &p_method) {
- if (p_id == area_monitor_callback_id) {
- area_monitor_callback_method = p_method;
+void GodotArea2D::set_area_monitor_callback(const Callable &p_callback) {
+ ObjectID id = p_callback.get_object_id();
+
+ if (id == area_monitor_callback.get_object_id()) {
+ area_monitor_callback = p_callback;
return;
}
_unregister_shapes();
- area_monitor_callback_id = p_id;
- area_monitor_callback_method = p_method;
+ area_monitor_callback = p_callback;
monitored_bodies.clear();
monitored_areas.clear();
@@ -199,77 +201,75 @@ void GodotArea2D::set_monitorable(bool p_monitorable) {
}
void GodotArea2D::call_queries() {
- if (monitor_callback_id.is_valid() && !monitored_bodies.is_empty()) {
- Variant res[5];
- Variant *resptr[5];
- for (int i = 0; i < 5; i++) {
- resptr[i] = &res[i];
- }
+ if (!monitor_callback.is_null() && !monitored_bodies.is_empty()) {
+ if (monitor_callback.is_valid()) {
+ Variant res[5];
+ Variant *resptr[5];
+ for (int i = 0; i < 5; i++) {
+ resptr[i] = &res[i];
+ }
- Object *obj = ObjectDB::get_instance(monitor_callback_id);
- if (!obj) {
- monitored_bodies.clear();
- monitor_callback_id = ObjectID();
- return;
- }
+ for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E;) {
+ if (E->get().state == 0) { // Nothing happened
+ Map<BodyKey, BodyState>::Element *next = E->next();
+ monitored_bodies.erase(E);
+ E = next;
+ continue;
+ }
+
+ res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED;
+ res[1] = E->key().rid;
+ res[2] = E->key().instance_id;
+ res[3] = E->key().body_shape;
+ res[4] = E->key().area_shape;
- for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E;) {
- if (E->get().state == 0) { // Nothing happened
Map<BodyKey, BodyState>::Element *next = E->next();
monitored_bodies.erase(E);
E = next;
- continue;
- }
-
- res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED;
- res[1] = E->key().rid;
- res[2] = E->key().instance_id;
- res[3] = E->key().body_shape;
- res[4] = E->key().area_shape;
- Map<BodyKey, BodyState>::Element *next = E->next();
- monitored_bodies.erase(E);
- E = next;
-
- Callable::CallError ce;
- obj->call(monitor_callback_method, (const Variant **)resptr, 5, ce);
+ Callable::CallError ce;
+ Variant ret;
+ monitor_callback.call((const Variant **)resptr, 5, ret, ce);
+ }
+ } else {
+ monitored_bodies.clear();
+ monitor_callback = Callable();
}
}
- if (area_monitor_callback_id.is_valid() && !monitored_areas.is_empty()) {
- Variant res[5];
- Variant *resptr[5];
- for (int i = 0; i < 5; i++) {
- resptr[i] = &res[i];
- }
+ if (!area_monitor_callback.is_null() && !monitored_areas.is_empty()) {
+ if (area_monitor_callback.is_valid()) {
+ Variant res[5];
+ Variant *resptr[5];
+ for (int i = 0; i < 5; i++) {
+ resptr[i] = &res[i];
+ }
- Object *obj = ObjectDB::get_instance(area_monitor_callback_id);
- if (!obj) {
- monitored_areas.clear();
- area_monitor_callback_id = ObjectID();
- return;
- }
+ for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E;) {
+ if (E->get().state == 0) { // Nothing happened
+ Map<BodyKey, BodyState>::Element *next = E->next();
+ monitored_areas.erase(E);
+ E = next;
+ continue;
+ }
+
+ res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED;
+ res[1] = E->key().rid;
+ res[2] = E->key().instance_id;
+ res[3] = E->key().body_shape;
+ res[4] = E->key().area_shape;
- for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E;) {
- if (E->get().state == 0) { // Nothing happened
Map<BodyKey, BodyState>::Element *next = E->next();
monitored_areas.erase(E);
E = next;
- continue;
- }
-
- res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED;
- res[1] = E->key().rid;
- res[2] = E->key().instance_id;
- res[3] = E->key().body_shape;
- res[4] = E->key().area_shape;
-
- Map<BodyKey, BodyState>::Element *next = E->next();
- monitored_areas.erase(E);
- E = next;
- Callable::CallError ce;
- obj->call(area_monitor_callback_method, (const Variant **)resptr, 5, ce);
+ Callable::CallError ce;
+ Variant ret;
+ area_monitor_callback.call((const Variant **)resptr, 5, ret, ce);
+ }
+ } else {
+ monitored_areas.clear();
+ area_monitor_callback = Callable();
}
}
}
diff --git a/servers/physics_2d/godot_area_2d.h b/servers/physics_2d/godot_area_2d.h
index daa03d39e3..13b3ce1bf2 100644
--- a/servers/physics_2d/godot_area_2d.h
+++ b/servers/physics_2d/godot_area_2d.h
@@ -52,11 +52,9 @@ class GodotArea2D : public GodotCollisionObject2D {
int priority = 0;
bool monitorable = false;
- ObjectID monitor_callback_id;
- StringName monitor_callback_method;
+ Callable monitor_callback;
- ObjectID area_monitor_callback_id;
- StringName area_monitor_callback_method;
+ Callable area_monitor_callback;
SelfList<GodotArea2D> monitor_query_list;
SelfList<GodotArea2D> moved_list;
@@ -99,11 +97,11 @@ class GodotArea2D : public GodotCollisionObject2D {
void _queue_monitor_update();
public:
- void set_monitor_callback(ObjectID p_id, const StringName &p_method);
- _FORCE_INLINE_ bool has_monitor_callback() const { return monitor_callback_id.is_valid(); }
+ void set_monitor_callback(const Callable &p_callback);
+ _FORCE_INLINE_ bool has_monitor_callback() const { return !monitor_callback.is_null(); }
- void set_area_monitor_callback(ObjectID p_id, const StringName &p_method);
- _FORCE_INLINE_ bool has_area_monitor_callback() const { return area_monitor_callback_id.is_valid(); }
+ void set_area_monitor_callback(const Callable &p_callback);
+ _FORCE_INLINE_ bool has_area_monitor_callback() const { return !area_monitor_callback.is_null(); }
_FORCE_INLINE_ void add_body_to_query(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape);
_FORCE_INLINE_ void remove_body_from_query(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape);
diff --git a/servers/physics_2d/godot_physics_server_2d.cpp b/servers/physics_2d/godot_physics_server_2d.cpp
index c86f87fc03..cf66b80076 100644
--- a/servers/physics_2d/godot_physics_server_2d.cpp
+++ b/servers/physics_2d/godot_physics_server_2d.cpp
@@ -513,18 +513,18 @@ void GodotPhysicsServer2D::area_set_collision_layer(RID p_area, uint32_t p_layer
area->set_collision_layer(p_layer);
}
-void GodotPhysicsServer2D::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
+void GodotPhysicsServer2D::area_set_monitor_callback(RID p_area, const Callable &p_callback) {
GodotArea2D *area = area_owner.get_or_null(p_area);
ERR_FAIL_COND(!area);
- area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method);
+ area->set_monitor_callback(p_callback.is_valid() ? p_callback : Callable());
}
-void GodotPhysicsServer2D::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
+void GodotPhysicsServer2D::area_set_area_monitor_callback(RID p_area, const Callable &p_callback) {
GodotArea2D *area = area_owner.get_or_null(p_area);
ERR_FAIL_COND(!area);
- area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method);
+ area->set_area_monitor_callback(p_callback.is_valid() ? p_callback : Callable());
}
/* BODY API */
diff --git a/servers/physics_2d/godot_physics_server_2d.h b/servers/physics_2d/godot_physics_server_2d.h
index a8a1e71d13..b03d78a1de 100644
--- a/servers/physics_2d/godot_physics_server_2d.h
+++ b/servers/physics_2d/godot_physics_server_2d.h
@@ -158,8 +158,8 @@ public:
virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override;
virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override;
- virtual void area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) override;
- virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) override;
+ virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) override;
+ virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) override;
virtual void area_set_pickable(RID p_area, bool p_pickable) override;
diff --git a/servers/physics_3d/godot_area_3d.cpp b/servers/physics_3d/godot_area_3d.cpp
index e115e17061..973fc50968 100644
--- a/servers/physics_3d/godot_area_3d.cpp
+++ b/servers/physics_3d/godot_area_3d.cpp
@@ -86,16 +86,16 @@ void GodotArea3D::set_space(GodotSpace3D *p_space) {
_set_space(p_space);
}
-void GodotArea3D::set_monitor_callback(ObjectID p_id, const StringName &p_method) {
- if (p_id == monitor_callback_id) {
- monitor_callback_method = p_method;
+void GodotArea3D::set_monitor_callback(const Callable &p_callback) {
+ ObjectID id = p_callback.get_object_id();
+ if (id == monitor_callback.get_object_id()) {
+ monitor_callback = p_callback;
return;
}
_unregister_shapes();
- monitor_callback_id = p_id;
- monitor_callback_method = p_method;
+ monitor_callback = p_callback;
monitored_bodies.clear();
monitored_areas.clear();
@@ -107,16 +107,16 @@ void GodotArea3D::set_monitor_callback(ObjectID p_id, const StringName &p_method
}
}
-void GodotArea3D::set_area_monitor_callback(ObjectID p_id, const StringName &p_method) {
- if (p_id == area_monitor_callback_id) {
- area_monitor_callback_method = p_method;
+void GodotArea3D::set_area_monitor_callback(const Callable &p_callback) {
+ ObjectID id = p_callback.get_object_id();
+ if (id == area_monitor_callback.get_object_id()) {
+ area_monitor_callback = p_callback;
return;
}
_unregister_shapes();
- area_monitor_callback_id = p_id;
- area_monitor_callback_method = p_method;
+ area_monitor_callback = p_callback;
monitored_bodies.clear();
monitored_areas.clear();
@@ -230,77 +230,75 @@ void GodotArea3D::set_monitorable(bool p_monitorable) {
}
void GodotArea3D::call_queries() {
- if (monitor_callback_id.is_valid() && !monitored_bodies.is_empty()) {
- Variant res[5];
- Variant *resptr[5];
- for (int i = 0; i < 5; i++) {
- resptr[i] = &res[i];
- }
+ if (!monitor_callback.is_null() && !monitored_bodies.is_empty()) {
+ if (monitor_callback.is_valid()) {
+ Variant res[5];
+ Variant *resptr[5];
+ for (int i = 0; i < 5; i++) {
+ resptr[i] = &res[i];
+ }
- Object *obj = ObjectDB::get_instance(monitor_callback_id);
- if (!obj) {
- monitored_bodies.clear();
- monitor_callback_id = ObjectID();
- return;
- }
+ for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E;) {
+ if (E->get().state == 0) { // Nothing happened
+ Map<BodyKey, BodyState>::Element *next = E->next();
+ monitored_bodies.erase(E);
+ E = next;
+ continue;
+ }
+
+ res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED;
+ res[1] = E->key().rid;
+ res[2] = E->key().instance_id;
+ res[3] = E->key().body_shape;
+ res[4] = E->key().area_shape;
- for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E;) {
- if (E->get().state == 0) { // Nothing happened
Map<BodyKey, BodyState>::Element *next = E->next();
monitored_bodies.erase(E);
E = next;
- continue;
- }
- res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED;
- res[1] = E->key().rid;
- res[2] = E->key().instance_id;
- res[3] = E->key().body_shape;
- res[4] = E->key().area_shape;
-
- Map<BodyKey, BodyState>::Element *next = E->next();
- monitored_bodies.erase(E);
- E = next;
-
- Callable::CallError ce;
- obj->call(monitor_callback_method, (const Variant **)resptr, 5, ce);
+ Callable::CallError ce;
+ Variant ret;
+ monitor_callback.call((const Variant **)resptr, 5, ret, ce);
+ }
+ } else {
+ monitored_bodies.clear();
+ monitor_callback = Callable();
}
}
- if (area_monitor_callback_id.is_valid() && !monitored_areas.is_empty()) {
- Variant res[5];
- Variant *resptr[5];
- for (int i = 0; i < 5; i++) {
- resptr[i] = &res[i];
- }
+ if (!area_monitor_callback.is_null() && !monitored_areas.is_empty()) {
+ if (area_monitor_callback.is_valid()) {
+ Variant res[5];
+ Variant *resptr[5];
+ for (int i = 0; i < 5; i++) {
+ resptr[i] = &res[i];
+ }
- Object *obj = ObjectDB::get_instance(area_monitor_callback_id);
- if (!obj) {
- monitored_areas.clear();
- area_monitor_callback_id = ObjectID();
- return;
- }
+ for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E;) {
+ if (E->get().state == 0) { // Nothing happened
+ Map<BodyKey, BodyState>::Element *next = E->next();
+ monitored_areas.erase(E);
+ E = next;
+ continue;
+ }
+
+ res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED;
+ res[1] = E->key().rid;
+ res[2] = E->key().instance_id;
+ res[3] = E->key().body_shape;
+ res[4] = E->key().area_shape;
- for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E;) {
- if (E->get().state == 0) { // Nothing happened
Map<BodyKey, BodyState>::Element *next = E->next();
monitored_areas.erase(E);
E = next;
- continue;
- }
- res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED;
- res[1] = E->key().rid;
- res[2] = E->key().instance_id;
- res[3] = E->key().body_shape;
- res[4] = E->key().area_shape;
-
- Map<BodyKey, BodyState>::Element *next = E->next();
- monitored_areas.erase(E);
- E = next;
-
- Callable::CallError ce;
- obj->call(area_monitor_callback_method, (const Variant **)resptr, 5, ce);
+ Callable::CallError ce;
+ Variant ret;
+ area_monitor_callback.call((const Variant **)resptr, 5, ret, ce);
+ }
+ } else {
+ monitored_areas.clear();
+ area_monitor_callback = Callable();
}
}
}
diff --git a/servers/physics_3d/godot_area_3d.h b/servers/physics_3d/godot_area_3d.h
index e8caa9221b..b02fa1d5b9 100644
--- a/servers/physics_3d/godot_area_3d.h
+++ b/servers/physics_3d/godot_area_3d.h
@@ -57,11 +57,8 @@ class GodotArea3D : public GodotCollisionObject3D {
int priority = 0;
bool monitorable = false;
- ObjectID monitor_callback_id;
- StringName monitor_callback_method;
-
- ObjectID area_monitor_callback_id;
- StringName area_monitor_callback_method;
+ Callable monitor_callback;
+ Callable area_monitor_callback;
SelfList<GodotArea3D> monitor_query_list;
SelfList<GodotArea3D> moved_list;
@@ -106,11 +103,11 @@ class GodotArea3D : public GodotCollisionObject3D {
void _queue_monitor_update();
public:
- void set_monitor_callback(ObjectID p_id, const StringName &p_method);
- _FORCE_INLINE_ bool has_monitor_callback() const { return monitor_callback_id.is_valid(); }
+ void set_monitor_callback(const Callable &p_callback);
+ _FORCE_INLINE_ bool has_monitor_callback() const { return !monitor_callback.is_null(); }
- void set_area_monitor_callback(ObjectID p_id, const StringName &p_method);
- _FORCE_INLINE_ bool has_area_monitor_callback() const { return area_monitor_callback_id.is_valid(); }
+ void set_area_monitor_callback(const Callable &p_callback);
+ _FORCE_INLINE_ bool has_area_monitor_callback() const { return !area_monitor_callback.is_null(); }
_FORCE_INLINE_ void add_body_to_query(GodotBody3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape);
_FORCE_INLINE_ void remove_body_from_query(GodotBody3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape);
diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp
index 79a2e0b0ea..73654939ca 100644
--- a/servers/physics_3d/godot_physics_server_3d.cpp
+++ b/servers/physics_3d/godot_physics_server_3d.cpp
@@ -416,11 +416,11 @@ void GodotPhysicsServer3D::area_set_monitorable(RID p_area, bool p_monitorable)
area->set_monitorable(p_monitorable);
}
-void GodotPhysicsServer3D::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
+void GodotPhysicsServer3D::area_set_monitor_callback(RID p_area, const Callable &p_callback) {
GodotArea3D *area = area_owner.get_or_null(p_area);
ERR_FAIL_COND(!area);
- area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method);
+ area->set_monitor_callback(p_callback.is_valid() ? p_callback : Callable());
}
void GodotPhysicsServer3D::area_set_ray_pickable(RID p_area, bool p_enable) {
@@ -430,11 +430,11 @@ void GodotPhysicsServer3D::area_set_ray_pickable(RID p_area, bool p_enable) {
area->set_ray_pickable(p_enable);
}
-void GodotPhysicsServer3D::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
+void GodotPhysicsServer3D::area_set_area_monitor_callback(RID p_area, const Callable &p_callback) {
GodotArea3D *area = area_owner.get_or_null(p_area);
ERR_FAIL_COND(!area);
- area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method);
+ area->set_area_monitor_callback(p_callback.is_valid() ? p_callback : Callable());
}
/* BODY API */
diff --git a/servers/physics_3d/godot_physics_server_3d.h b/servers/physics_3d/godot_physics_server_3d.h
index 3ed9e320dc..4ddd10a4e0 100644
--- a/servers/physics_3d/godot_physics_server_3d.h
+++ b/servers/physics_3d/godot_physics_server_3d.h
@@ -157,8 +157,8 @@ public:
virtual void area_set_monitorable(RID p_area, bool p_monitorable) override;
- virtual void area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) override;
- virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) override;
+ virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) override;
+ virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) override;
/* BODY API */
diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp
index 300f9c7d8b..abe173b078 100644
--- a/servers/physics_server_2d.cpp
+++ b/servers/physics_server_2d.cpp
@@ -616,8 +616,8 @@ void PhysicsServer2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("area_attach_canvas_instance_id", "area", "id"), &PhysicsServer2D::area_attach_canvas_instance_id);
ClassDB::bind_method(D_METHOD("area_get_canvas_instance_id", "area"), &PhysicsServer2D::area_get_canvas_instance_id);
- ClassDB::bind_method(D_METHOD("area_set_monitor_callback", "area", "receiver", "method"), &PhysicsServer2D::area_set_monitor_callback);
- ClassDB::bind_method(D_METHOD("area_set_area_monitor_callback", "area", "receiver", "method"), &PhysicsServer2D::area_set_area_monitor_callback);
+ ClassDB::bind_method(D_METHOD("area_set_monitor_callback", "area", "callback"), &PhysicsServer2D::area_set_monitor_callback);
+ ClassDB::bind_method(D_METHOD("area_set_area_monitor_callback", "area", "callback"), &PhysicsServer2D::area_set_area_monitor_callback);
ClassDB::bind_method(D_METHOD("area_set_monitorable", "area", "monitorable"), &PhysicsServer2D::area_set_monitorable);
ClassDB::bind_method(D_METHOD("body_create"), &PhysicsServer2D::body_create);
diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h
index 584da56c66..e6acebd5dd 100644
--- a/servers/physics_server_2d.h
+++ b/servers/physics_server_2d.h
@@ -335,8 +335,8 @@ public:
virtual void area_set_monitorable(RID p_area, bool p_monitorable) = 0;
virtual void area_set_pickable(RID p_area, bool p_pickable) = 0;
- virtual void area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) = 0;
- virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) = 0;
+ virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) = 0;
+ virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) = 0;
/* BODY API */
diff --git a/servers/physics_server_2d_wrap_mt.h b/servers/physics_server_2d_wrap_mt.h
index 4a2f07ab1e..b133fa41aa 100644
--- a/servers/physics_server_2d_wrap_mt.h
+++ b/servers/physics_server_2d_wrap_mt.h
@@ -165,8 +165,8 @@ public:
FUNC2(area_set_monitorable, RID, bool);
FUNC2(area_set_pickable, RID, bool);
- FUNC3(area_set_monitor_callback, RID, Object *, const StringName &);
- FUNC3(area_set_area_monitor_callback, RID, Object *, const StringName &);
+ FUNC2(area_set_monitor_callback, RID, const Callable &);
+ FUNC2(area_set_area_monitor_callback, RID, const Callable &);
/* BODY API */
diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp
index c68cd7696b..8f66a207aa 100644
--- a/servers/physics_server_3d.cpp
+++ b/servers/physics_server_3d.cpp
@@ -612,8 +612,8 @@ void PhysicsServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("area_attach_object_instance_id", "area", "id"), &PhysicsServer3D::area_attach_object_instance_id);
ClassDB::bind_method(D_METHOD("area_get_object_instance_id", "area"), &PhysicsServer3D::area_get_object_instance_id);
- ClassDB::bind_method(D_METHOD("area_set_monitor_callback", "area", "receiver", "method"), &PhysicsServer3D::area_set_monitor_callback);
- ClassDB::bind_method(D_METHOD("area_set_area_monitor_callback", "area", "receiver", "method"), &PhysicsServer3D::area_set_area_monitor_callback);
+ ClassDB::bind_method(D_METHOD("area_set_monitor_callback", "area", "callback"), &PhysicsServer3D::area_set_monitor_callback);
+ ClassDB::bind_method(D_METHOD("area_set_area_monitor_callback", "area", "callback"), &PhysicsServer3D::area_set_area_monitor_callback);
ClassDB::bind_method(D_METHOD("area_set_monitorable", "area", "monitorable"), &PhysicsServer3D::area_set_monitorable);
ClassDB::bind_method(D_METHOD("area_set_ray_pickable", "area", "enable"), &PhysicsServer3D::area_set_ray_pickable);
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index 79369bd459..6e9f8c7704 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -348,8 +348,8 @@ public:
virtual void area_set_monitorable(RID p_area, bool p_monitorable) = 0;
- virtual void area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) = 0;
- virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) = 0;
+ virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) = 0;
+ virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) = 0;
virtual void area_set_ray_pickable(RID p_area, bool p_enable) = 0;
diff --git a/servers/physics_server_3d_wrap_mt.h b/servers/physics_server_3d_wrap_mt.h
index 4c88ef2642..df3dc279fe 100644
--- a/servers/physics_server_3d_wrap_mt.h
+++ b/servers/physics_server_3d_wrap_mt.h
@@ -166,8 +166,8 @@ public:
FUNC2(area_set_monitorable, RID, bool);
FUNC2(area_set_ray_pickable, RID, bool);
- FUNC3(area_set_monitor_callback, RID, Object *, const StringName &);
- FUNC3(area_set_area_monitor_callback, RID, Object *, const StringName &);
+ FUNC2(area_set_monitor_callback, RID, const Callable &);
+ FUNC2(area_set_area_monitor_callback, RID, const Callable &);
/* BODY API */