summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/ustring.cpp6
-rw-r--r--drivers/dummy/rasterizer_dummy.h2
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp20
-rw-r--r--drivers/gles2/rasterizer_gles2.h3
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp1
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.h1
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp22
-rw-r--r--drivers/gles3/rasterizer_gles3.h3
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp1
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h1
-rw-r--r--editor/editor_properties.cpp49
-rw-r--r--editor/editor_properties.h19
-rw-r--r--editor/plugins/script_editor_plugin.cpp14
-rw-r--r--main/main.cpp9
-rw-r--r--modules/bullet/bullet_physics_server.cpp28
-rw-r--r--modules/bullet/bullet_physics_server.h5
-rw-r--r--modules/bullet/rigid_body_bullet.cpp4
-rw-r--r--modules/bullet/rigid_body_bullet.h1
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp5
-rw-r--r--modules/mono/csharp_script.cpp59
-rw-r--r--modules/mono/editor/bindings_generator.cpp2
-rw-r--r--modules/mono/glue/cs_files/NodeExtensions.cs10
-rw-r--r--modules/mono/mono_gd/gd_mono_class.cpp6
-rw-r--r--modules/mono/mono_gd/gd_mono_class.h2
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp18
-rw-r--r--modules/visual_script/visual_script_editor.cpp14
-rw-r--r--modules/visual_script/visual_script_editor.h3
-rw-r--r--modules/visual_script/visual_script_property_selector.cpp8
-rw-r--r--platform/osx/detect.py2
-rw-r--r--scene/2d/physics_body_2d.cpp20
-rw-r--r--scene/2d/physics_body_2d.h4
-rw-r--r--scene/3d/physics_body.cpp22
-rw-r--r--scene/3d/physics_body.h5
-rw-r--r--scene/resources/texture.cpp2
-rw-r--r--servers/physics/body_sw.h5
-rw-r--r--servers/physics/physics_server_sw.cpp34
-rw-r--r--servers/physics/physics_server_sw.h5
-rw-r--r--servers/physics_2d/body_2d_sw.h25
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp33
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h4
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.h4
-rw-r--r--servers/physics_2d_server.cpp11
-rw-r--r--servers/physics_2d_server.h11
-rw-r--r--servers/physics_server.cpp6
-rw-r--r--servers/physics_server.h6
-rw-r--r--servers/visual/rasterizer.h2
-rw-r--r--servers/visual/shader_language.cpp9
-rw-r--r--servers/visual/visual_server_raster.cpp4
-rw-r--r--servers/visual/visual_server_raster.h2
-rw-r--r--servers/visual/visual_server_wrap_mt.cpp10
-rw-r--r--servers/visual/visual_server_wrap_mt.h4
-rw-r--r--servers/visual_server.cpp4
-rw-r--r--servers/visual_server.h2
53 files changed, 438 insertions, 114 deletions
diff --git a/core/ustring.cpp b/core/ustring.cpp
index f552cb13ac..5f3858cb17 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -2768,7 +2768,7 @@ String String::format(const Variant &values, String placeholder) const {
val = val.substr(1, val.length() - 2);
}
- new_string = new_string.replacen(placeholder.replace("_", key), val);
+ new_string = new_string.replace(placeholder.replace("_", key), val);
} else {
ERR_PRINT(String("STRING.format Inner Array size != 2 ").ascii().get_data());
}
@@ -2781,7 +2781,7 @@ String String::format(const Variant &values, String placeholder) const {
val = val.substr(1, val.length() - 2);
}
- new_string = new_string.replacen(placeholder.replace("_", i_as_str), val);
+ new_string = new_string.replace(placeholder.replace("_", i_as_str), val);
}
}
} else if (values.get_type() == Variant::DICTIONARY) {
@@ -2801,7 +2801,7 @@ String String::format(const Variant &values, String placeholder) const {
val = val.substr(1, val.length() - 2);
}
- new_string = new_string.replacen(placeholder.replace("_", key), val);
+ new_string = new_string.replace(placeholder.replace("_", key), val);
}
} else {
ERR_PRINT(String("Invalid type: use Array or Dictionary.").ascii().get_data());
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h
index bab89f649a..cca13e500a 100644
--- a/drivers/dummy/rasterizer_dummy.h
+++ b/drivers/dummy/rasterizer_dummy.h
@@ -777,7 +777,7 @@ public:
void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale) {}
void initialize() {}
- void begin_frame() {}
+ void begin_frame(double frame_step) {}
void set_current_render_target(RID p_render_target) {}
void restore_render_target() {}
void clear_render_target(const Color &p_color) {}
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 4a23689009..5de1d5f1dc 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -227,21 +227,14 @@ void RasterizerGLES2::initialize() {
scene->initialize();
}
-void RasterizerGLES2::begin_frame() {
- uint64_t tick = OS::get_singleton()->get_ticks_usec();
+void RasterizerGLES2::begin_frame(double frame_step) {
+ time_total += frame_step;
- double delta = double(tick - prev_ticks) / 1000000.0;
- delta *= Engine::get_singleton()->get_time_scale();
-
- time_total += delta;
-
- if (delta == 0) {
+ if (frame_step == 0) {
//to avoid hiccups
- delta = 0.001;
+ frame_step = 0.001;
}
- prev_ticks = tick;
-
// double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs");
// if (time_total > time_roll_over)
// time_total = 0; //roll over every day (should be customz
@@ -251,9 +244,7 @@ void RasterizerGLES2::begin_frame() {
storage->frame.time[2] = Math::fmod(time_total, 900);
storage->frame.time[3] = Math::fmod(time_total, 60);
storage->frame.count++;
- storage->frame.delta = delta;
-
- storage->frame.prev_tick = tick;
+ storage->frame.delta = frame_step;
storage->update_dirty_resources();
@@ -431,7 +422,6 @@ RasterizerGLES2::RasterizerGLES2() {
scene->storage = storage;
storage->scene = scene;
- prev_ticks = 0;
time_total = 0;
}
diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h
index 8d57275449..f727af39dd 100644
--- a/drivers/gles2/rasterizer_gles2.h
+++ b/drivers/gles2/rasterizer_gles2.h
@@ -43,7 +43,6 @@ class RasterizerGLES2 : public Rasterizer {
RasterizerCanvasGLES2 *canvas;
RasterizerSceneGLES2 *scene;
- uint64_t prev_ticks;
double time_total;
public:
@@ -54,7 +53,7 @@ public:
virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale);
virtual void initialize();
- virtual void begin_frame();
+ virtual void begin_frame(double frame_step);
virtual void set_current_render_target(RID p_render_target);
virtual void restore_render_target();
virtual void clear_render_target(const Color &p_color);
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index 0dc506d991..fc80436efb 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -2008,7 +2008,6 @@ void RasterizerStorageGLES2::initialize() {
config.shrink_textures_x2 = false;
frame.count = 0;
- frame.prev_tick = 0;
frame.delta = 0;
frame.current_rt = NULL;
frame.clear_request = false;
diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h
index 30e13a9f65..c2e1144128 100644
--- a/drivers/gles2/rasterizer_storage_gles2.h
+++ b/drivers/gles2/rasterizer_storage_gles2.h
@@ -824,7 +824,6 @@ public:
int canvas_draw_commands;
float time[4];
float delta;
- uint64_t prev_tick;
uint64_t count;
} frame;
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index f1fa26c0b9..97c4a98aab 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -192,22 +192,15 @@ void RasterizerGLES3::initialize() {
scene->initialize();
}
-void RasterizerGLES3::begin_frame() {
+void RasterizerGLES3::begin_frame(double frame_step) {
- uint64_t tick = OS::get_singleton()->get_ticks_usec();
+ time_total += frame_step;
- double delta = double(tick - prev_ticks) / 1000000.0;
- delta *= Engine::get_singleton()->get_time_scale();
-
- time_total += delta;
-
- if (delta == 0) {
+ if (frame_step == 0) {
//to avoid hiccups
- delta = 0.001;
+ frame_step = 0.001;
}
- prev_ticks = tick;
-
double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs");
if (time_total > time_roll_over)
time_total = 0; //roll over every day (should be customz
@@ -217,9 +210,7 @@ void RasterizerGLES3::begin_frame() {
storage->frame.time[2] = Math::fmod(time_total, 900);
storage->frame.time[3] = Math::fmod(time_total, 60);
storage->frame.count++;
- storage->frame.delta = delta;
-
- storage->frame.prev_tick = tick;
+ storage->frame.delta = frame_step;
storage->update_dirty_resources();
@@ -281,7 +272,7 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c
if (p_image.is_null() || p_image->empty())
return;
- begin_frame();
+ begin_frame(0.0);
int window_w = OS::get_singleton()->get_video_mode(0).width;
int window_h = OS::get_singleton()->get_video_mode(0).height;
@@ -430,7 +421,6 @@ RasterizerGLES3::RasterizerGLES3() {
scene->storage = storage;
storage->scene = scene;
- prev_ticks = 0;
time_total = 0;
}
diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h
index 5213101778..f4449ac0f9 100644
--- a/drivers/gles3/rasterizer_gles3.h
+++ b/drivers/gles3/rasterizer_gles3.h
@@ -44,7 +44,6 @@ class RasterizerGLES3 : public Rasterizer {
RasterizerCanvasGLES3 *canvas;
RasterizerSceneGLES3 *scene;
- uint64_t prev_ticks;
double time_total;
public:
@@ -55,7 +54,7 @@ public:
virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale);
virtual void initialize();
- virtual void begin_frame();
+ virtual void begin_frame(double frame_step);
virtual void set_current_render_target(RID p_render_target);
virtual void restore_render_target();
virtual void clear_render_target(const Color &p_color);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 9e389a353e..6361ddc846 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -7489,7 +7489,6 @@ void RasterizerStorageGLES3::initialize() {
#endif
frame.count = 0;
- frame.prev_tick = 0;
frame.delta = 0;
frame.current_rt = NULL;
config.keep_original_textures = false;
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 1db577f23c..d9c770d1b7 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -1427,7 +1427,6 @@ public:
int canvas_draw_commands;
float time[4];
float delta;
- uint64_t prev_tick;
uint64_t count;
} frame;
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 0b49b5a801..4ff1fb2984 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -258,6 +258,51 @@ EditorPropertyPath::EditorPropertyPath() {
global = false;
}
+///////////////////// CLASS NAME /////////////////////////
+
+void EditorPropertyClassName::setup(const String &p_base_type, const String &p_selected_type) {
+
+ base_type = p_base_type;
+ dialog->set_base_type(base_type);
+ selected_type = p_selected_type;
+ property->set_text(selected_type);
+}
+
+void EditorPropertyClassName::update_property() {
+
+ String s = get_edited_object()->get(get_edited_property());
+ property->set_text(s);
+ selected_type = s;
+}
+
+void EditorPropertyClassName::_property_selected() {
+ dialog->popup_create(true);
+}
+
+void EditorPropertyClassName::_dialog_created() {
+ selected_type = dialog->get_selected_type();
+ emit_signal("property_changed", get_edited_property(), selected_type);
+ update_property();
+}
+
+void EditorPropertyClassName::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_dialog_created"), &EditorPropertyClassName::_dialog_created);
+ ClassDB::bind_method(D_METHOD("_property_selected"), &EditorPropertyClassName::_property_selected);
+}
+
+EditorPropertyClassName::EditorPropertyClassName() {
+ property = memnew(Button);
+ property->set_clip_text(true);
+ add_child(property);
+ add_focusable(property);
+ property->set_text(selected_type);
+ property->connect("pressed", this, "_property_selected");
+ dialog = memnew(CreateDialog);
+ dialog->set_base_type(base_type);
+ dialog->connect("create", this, "_dialog_created");
+ add_child(dialog);
+}
+
///////////////////// MEMBER /////////////////////////
void EditorPropertyMember::_property_selected(const String &p_selected) {
@@ -2607,6 +2652,10 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
} else if (p_hint == PROPERTY_HINT_MULTILINE_TEXT) {
EditorPropertyMultilineText *editor = memnew(EditorPropertyMultilineText);
add_property_editor(p_path, editor);
+ } else if (p_hint == PROPERTY_HINT_TYPE_STRING) {
+ EditorPropertyClassName *editor = memnew(EditorPropertyClassName);
+ editor->setup("Object", p_hint_text);
+ add_property_editor(p_path, editor);
} else if (p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_FILE || p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE) {
Vector<String> extensions = p_hint_text.split(",");
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index 0afb1bf955..ccd73d2539 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -119,6 +119,25 @@ public:
EditorPropertyPath();
};
+class EditorPropertyClassName : public EditorProperty {
+ GDCLASS(EditorPropertyClassName, EditorProperty)
+private:
+ CreateDialog *dialog;
+ Button *property;
+ String selected_type;
+ String base_type;
+ void _property_selected();
+ void _dialog_created();
+
+protected:
+ static void _bind_methods();
+
+public:
+ void setup(const String &p_base_type, const String &p_selected_type);
+ virtual void update_property();
+ EditorPropertyClassName();
+};
+
class EditorPropertyMember : public EditorProperty {
GDCLASS(EditorPropertyMember, EditorProperty)
public:
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index a1dc746702..94d1b96b91 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -2407,14 +2407,14 @@ void ScriptEditor::_make_script_list_context_menu() {
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/copy_path"), FILE_COPY_PATH);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/show_in_file_system"), SHOW_IN_FILE_SYSTEM);
- }
- Ref<Script> scr = se->get_edited_resource();
- if (scr != NULL) {
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/reload_script_soft"), FILE_TOOL_RELOAD_SOFT);
- if (!scr.is_null() && scr->is_tool()) {
- context_menu->add_separator();
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/run_file"), FILE_RUN);
+ Ref<Script> scr = se->get_edited_resource();
+ if (scr != NULL) {
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/reload_script_soft"), FILE_TOOL_RELOAD_SOFT);
+ if (!scr.is_null() && scr->is_tool()) {
+ context_menu->add_separator();
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/run_file"), FILE_RUN);
+ }
}
} else {
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_file"), FILE_CLOSE);
diff --git a/main/main.cpp b/main/main.cpp
index 56dd5f73e7..5beeb95a11 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1734,8 +1734,11 @@ bool Main::iteration() {
int physics_fps = Engine::get_singleton()->get_iterations_per_second();
float frame_slice = 1.0 / physics_fps;
+ float time_scale = Engine::get_singleton()->get_time_scale();
+
MainFrameTime advance = main_timer_sync.advance(frame_slice, physics_fps);
double step = advance.idle_step;
+ double scaled_step = step * time_scale;
Engine::get_singleton()->_frame_step = step;
@@ -1757,8 +1760,6 @@ bool Main::iteration() {
advance.physics_steps = max_physics_steps;
}
- float time_scale = Engine::get_singleton()->get_time_scale();
-
bool exit = false;
Engine::get_singleton()->_in_physics = true;
@@ -1805,11 +1806,11 @@ bool Main::iteration() {
if ((!force_redraw_requested) && OS::get_singleton()->is_in_low_processor_usage_mode()) {
if (VisualServer::get_singleton()->has_changed()) {
- VisualServer::get_singleton()->draw(); // flush visual commands
+ VisualServer::get_singleton()->draw(true, scaled_step); // flush visual commands
Engine::get_singleton()->frames_drawn++;
}
} else {
- VisualServer::get_singleton()->draw(); // flush visual commands
+ VisualServer::get_singleton()->draw(true, scaled_step); // flush visual commands
Engine::get_singleton()->frames_drawn++;
force_redraw_requested = false;
}
diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp
index 2390c71b0a..9263a9ba6d 100644
--- a/modules/bullet/bullet_physics_server.cpp
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -721,6 +721,34 @@ Vector3 BulletPhysicsServer::body_get_applied_torque(RID p_body) const {
return body->get_applied_torque();
}
+void BulletPhysicsServer::body_add_central_force(RID p_body, const Vector3 &p_force) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->apply_central_force(p_force);
+}
+
+void BulletPhysicsServer::body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_pos) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->apply_force(p_force, p_pos);
+}
+
+void BulletPhysicsServer::body_add_torque(RID p_body, const Vector3 &p_torque) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->apply_torque(p_torque);
+}
+
+void BulletPhysicsServer::body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->apply_central_impulse(p_impulse);
+}
+
void BulletPhysicsServer::body_apply_impulse(RID p_body, const Vector3 &p_pos, const Vector3 &p_impulse) {
RigidBodyBullet *body = rigid_body_owner.get(p_body);
ERR_FAIL_COND(!body);
diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h
index 2165845529..2c5b7e51cf 100644
--- a/modules/bullet/bullet_physics_server.h
+++ b/modules/bullet/bullet_physics_server.h
@@ -228,6 +228,11 @@ public:
virtual void body_set_applied_torque(RID p_body, const Vector3 &p_torque);
virtual Vector3 body_get_applied_torque(RID p_body) const;
+ virtual void body_add_central_force(RID p_body, const Vector3 &p_force);
+ virtual void body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_pos);
+ virtual void body_add_torque(RID p_body, const Vector3 &p_torque);
+
+ virtual void body_apply_central_impulse(RID p_body, const Vector3 &p_impulse);
virtual void body_apply_impulse(RID p_body, const Vector3 &p_pos, const Vector3 &p_impulse);
virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse);
virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity);
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index 19fad283af..18f8f5f677 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -126,6 +126,10 @@ void BulletPhysicsDirectBodyState::add_torque(const Vector3 &p_torque) {
body->apply_torque(p_torque);
}
+void BulletPhysicsDirectBodyState::apply_central_impulse(const Vector3 &p_j) {
+ body->apply_central_impulse(p_j);
+}
+
void BulletPhysicsDirectBodyState::apply_impulse(const Vector3 &p_pos, const Vector3 &p_j) {
body->apply_impulse(p_pos, p_j);
}
diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h
index 911e93bfef..7dbb5cf870 100644
--- a/modules/bullet/rigid_body_bullet.h
+++ b/modules/bullet/rigid_body_bullet.h
@@ -113,6 +113,7 @@ public:
virtual void add_central_force(const Vector3 &p_force);
virtual void add_force(const Vector3 &p_force, const Vector3 &p_pos);
virtual void add_torque(const Vector3 &p_torque);
+ virtual void apply_central_impulse(const Vector3 &p_impulse);
virtual void apply_impulse(const Vector3 &p_pos, const Vector3 &p_j);
virtual void apply_torque_impulse(const Vector3 &p_j);
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index 5e093109d5..eb52bede24 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -149,7 +149,10 @@ Ref<Script> NativeScript::get_base_script() const {
if (!script_data)
return Ref<Script>();
- Ref<NativeScript> ns = Ref<NativeScript>(NSL->create_script());
+ NativeScript *script = (NativeScript *)NSL->create_script();
+ Ref<NativeScript> ns = Ref<NativeScript>(script);
+ ERR_FAIL_COND_V(!ns.is_valid(), Ref<Script>());
+
ns->set_class_name(script_data->base);
ns->set_library(get_library());
return ns;
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 996e73a4bb..8471083f49 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -638,33 +638,41 @@ void CSharpLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft
#ifdef TOOLS_ENABLED
void CSharpLanguage::reload_assemblies_if_needed(bool p_soft_reload) {
- if (gdmono->is_runtime_initialized()) {
+ if (!gdmono->is_runtime_initialized())
+ return;
- GDMonoAssembly *proj_assembly = gdmono->get_project_assembly();
+ GDMonoAssembly *proj_assembly = gdmono->get_project_assembly();
- String name = ProjectSettings::get_singleton()->get("application/config/name");
- if (name.empty()) {
- name = "UnnamedProject";
- }
+ String name = ProjectSettings::get_singleton()->get("application/config/name");
+ if (name.empty()) {
+ name = "UnnamedProject";
+ }
- if (proj_assembly) {
- String proj_asm_path = proj_assembly->get_path();
+ name += ".dll";
- if (!FileAccess::exists(proj_assembly->get_path())) {
- // Maybe it wasn't loaded from the default path, so check this as well
- proj_asm_path = GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(name);
- if (!FileAccess::exists(proj_asm_path))
- return; // No assembly to load
- }
+ if (proj_assembly) {
+ String proj_asm_path = proj_assembly->get_path();
- if (FileAccess::get_modified_time(proj_asm_path) <= proj_assembly->get_modified_time())
- return; // Already up to date
- } else {
- if (!FileAccess::exists(GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(name)))
+ if (!FileAccess::exists(proj_assembly->get_path())) {
+ // Maybe it wasn't loaded from the default path, so check this as well
+ proj_asm_path = GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(name);
+ if (!FileAccess::exists(proj_asm_path))
return; // No assembly to load
}
+
+ if (FileAccess::get_modified_time(proj_asm_path) <= proj_assembly->get_modified_time())
+ return; // Already up to date
+ } else {
+ if (!FileAccess::exists(GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(name)))
+ return; // No assembly to load
}
+ if (!gdmono->get_core_api_assembly() && gdmono->metadata_is_api_assembly_invalidated(APIAssembly::API_CORE))
+ return; // The core API assembly to load is invalidated
+
+ if (!gdmono->get_editor_api_assembly() && gdmono->metadata_is_api_assembly_invalidated(APIAssembly::API_EDITOR))
+ return; // The editor API assembly to load is invalidated
+
#ifndef NO_THREADS
lock->lock();
#endif
@@ -1963,8 +1971,6 @@ Variant CSharpScript::_new(const Variant **p_args, int p_argcount, Variant::Call
ScriptInstance *CSharpScript::instance_create(Object *p_this) {
- ERR_FAIL_COND_V(!valid, NULL);
-
if (!tool && !ScriptServer::is_scripting_enabled()) {
#ifdef TOOLS_ENABLED
PlaceHolderScriptInstance *si = memnew(PlaceHolderScriptInstance(CSharpLanguage::get_singleton(), Ref<Script>(this), p_this));
@@ -1981,13 +1987,15 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) {
// The project assembly is not loaded
ERR_EXPLAIN("Cannot instance script because the project assembly is not loaded. Script: " + get_path());
ERR_FAIL_V(NULL);
+ } else {
+ // The project assembly is loaded, but the class could not found
+ ERR_EXPLAIN("Cannot instance script because the class '" + name + "' could not be found. Script: " + get_path());
+ ERR_FAIL_V(NULL);
}
-
- // The project assembly is loaded, but the class could not found
- ERR_EXPLAIN("Cannot instance script because the class '" + name + "' could not be found. Script: " + get_path());
- ERR_FAIL_V(NULL);
}
+ ERR_FAIL_COND_V(!valid, NULL);
+
if (native) {
String native_name = native->get_name();
if (!ClassDB::is_parent_class(p_this->get_class_name(), native_name)) {
@@ -2040,6 +2048,9 @@ void CSharpScript::set_source_code(const String &p_code) {
bool CSharpScript::has_method(const StringName &p_method) const {
+ if (!script_class)
+ return false;
+
return script_class->has_fetched_method_unknown_params(p_method);
}
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 307a7d3e94..6819c0abe8 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -729,7 +729,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output.push_back(INDENT1 "public ");
bool is_abstract = itype.is_object_type && !ClassDB::can_instance(itype.name) && ClassDB::is_class_enabled(itype.name); // can_instance returns true if there's a constructor and the class is not 'disabled'
- output.push_back(itype.is_singleton ? "static class " : (is_abstract ? "abstract class " : "class "));
+ output.push_back(itype.is_singleton ? "static partial class " : (is_abstract ? "abstract partial class " : "partial class "));
output.push_back(itype.proxy_name);
if (itype.is_singleton) {
diff --git a/modules/mono/glue/cs_files/NodeExtensions.cs b/modules/mono/glue/cs_files/NodeExtensions.cs
new file mode 100644
index 0000000000..a099b0e400
--- /dev/null
+++ b/modules/mono/glue/cs_files/NodeExtensions.cs
@@ -0,0 +1,10 @@
+namespace Godot
+{
+ public partial class Node
+ {
+ public T GetNode<T>(NodePath path) where T : Godot.Node
+ {
+ return (T)GetNode(path);
+ }
+ }
+}
diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp
index e2597a7d42..53d6b7074c 100644
--- a/modules/mono/mono_gd/gd_mono_class.cpp
+++ b/modules/mono/mono_gd/gd_mono_class.cpp
@@ -322,6 +322,12 @@ GDMonoMethod *GDMonoClass::get_method_with_desc(const String &p_description, boo
return get_method(method);
}
+void *GDMonoClass::get_method_thunk(const StringName &p_name, int p_params_count) {
+
+ GDMonoMethod *method = get_method(p_name, p_params_count);
+ return method ? method->get_thunk() : NULL;
+}
+
GDMonoField *GDMonoClass::get_field(const StringName &p_name) {
Map<StringName, GDMonoField *>::Element *result = fields.find(p_name);
diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h
index f81ab84cd0..f4e386549a 100644
--- a/modules/mono/mono_gd/gd_mono_class.h
+++ b/modules/mono/mono_gd/gd_mono_class.h
@@ -133,6 +133,8 @@ public:
GDMonoMethod *get_method(MonoMethod *p_raw_method, const StringName &p_name, int p_params_count);
GDMonoMethod *get_method_with_desc(const String &p_description, bool p_include_namespace);
+ void *get_method_thunk(const StringName &p_name, int p_params_count = 0);
+
GDMonoField *get_field(const StringName &p_name);
const Vector<GDMonoField *> &get_all_fields();
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 7cd922138f..21efd4064a 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -176,7 +176,7 @@ void update_corlib_cache() {
#ifdef DEBUG_ENABLED
CACHE_CLASS_AND_CHECK(System_Diagnostics_StackTrace, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Diagnostics", "StackTrace"));
- CACHE_METHOD_THUNK_AND_CHECK(System_Diagnostics_StackTrace, GetFrames, (StackTrace_GetFrames)CACHED_CLASS(System_Diagnostics_StackTrace)->get_method("GetFrames")->get_thunk());
+ CACHE_METHOD_THUNK_AND_CHECK(System_Diagnostics_StackTrace, GetFrames, (StackTrace_GetFrames)CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_thunk("GetFrames"));
CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(bool)", true));
CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_Exception_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(System.Exception,bool)", true));
#endif
@@ -234,16 +234,16 @@ void update_godot_api_cache() {
CACHE_FIELD_AND_CHECK(NodePath, ptr, CACHED_CLASS(NodePath)->get_field(BINDINGS_PTR_FIELD));
CACHE_FIELD_AND_CHECK(RID, ptr, CACHED_CLASS(RID)->get_field(BINDINGS_PTR_FIELD));
- CACHE_METHOD_THUNK_AND_CHECK(Array, GetPtr, (Array_GetPtr)GODOT_API_CLASS(Array)->get_method("GetPtr", 0)->get_thunk());
- CACHE_METHOD_THUNK_AND_CHECK(Dictionary, GetPtr, (Dictionary_GetPtr)GODOT_API_CLASS(Dictionary)->get_method("GetPtr", 0)->get_thunk());
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, IsArrayGenericType, (IsArrayGenericType)GODOT_API_CLASS(MarshalUtils)->get_method("IsArrayGenericType", 1)->get_thunk());
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, IsDictionaryGenericType, (IsDictionaryGenericType)GODOT_API_CLASS(MarshalUtils)->get_method("IsDictionaryGenericType", 1)->get_thunk());
- CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, SignalCallback, (SignalAwaiter_SignalCallback)GODOT_API_CLASS(SignalAwaiter)->get_method("SignalCallback", 1)->get_thunk());
- CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, FailureCallback, (SignalAwaiter_FailureCallback)GODOT_API_CLASS(SignalAwaiter)->get_method("FailureCallback", 0)->get_thunk());
- CACHE_METHOD_THUNK_AND_CHECK(GodotTaskScheduler, Activate, (GodotTaskScheduler_Activate)GODOT_API_CLASS(GodotTaskScheduler)->get_method("Activate", 0)->get_thunk());
+ CACHE_METHOD_THUNK_AND_CHECK(Array, GetPtr, (Array_GetPtr)GODOT_API_CLASS(Array)->get_method_thunk("GetPtr", 0));
+ CACHE_METHOD_THUNK_AND_CHECK(Dictionary, GetPtr, (Dictionary_GetPtr)GODOT_API_CLASS(Dictionary)->get_method_thunk("GetPtr", 0));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, IsArrayGenericType, (IsArrayGenericType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("IsArrayGenericType", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, IsDictionaryGenericType, (IsDictionaryGenericType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("IsDictionaryGenericType", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, SignalCallback, (SignalAwaiter_SignalCallback)GODOT_API_CLASS(SignalAwaiter)->get_method_thunk("SignalCallback", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, FailureCallback, (SignalAwaiter_FailureCallback)GODOT_API_CLASS(SignalAwaiter)->get_method_thunk("FailureCallback", 0));
+ CACHE_METHOD_THUNK_AND_CHECK(GodotTaskScheduler, Activate, (GodotTaskScheduler_Activate)GODOT_API_CLASS(GodotTaskScheduler)->get_method_thunk("Activate", 0));
#ifdef DEBUG_ENABLED
- CACHE_METHOD_THUNK_AND_CHECK(DebuggingUtils, GetStackFrameInfo, (DebugUtils_StackFrameInfo)GODOT_API_CLASS(DebuggingUtils)->get_method("GetStackFrameInfo", 4)->get_thunk());
+ CACHE_METHOD_THUNK_AND_CHECK(DebuggingUtils, GetStackFrameInfo, (DebugUtils_StackFrameInfo)GODOT_API_CLASS(DebuggingUtils)->get_method_thunk("GetStackFrameInfo", 4));
#endif
// TODO Move to CSharpLanguage::init()
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index ad6d32b567..d29104ed45 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -1327,12 +1327,10 @@ void VisualScriptEditor::_input(const Ref<InputEvent> &p_event) {
if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
revert_on_drag = String(); //so we can still drag functions
}
+}
- Ref<InputEventKey> k = p_event;
- if (k.is_valid() && k->get_scancode() == KEY_A && k->get_shift() && k->is_pressed()) {
- new_connect_node_select->select_from_visual_script(String(""));
- accept_event();
- }
+void VisualScriptEditor::_generic_search() {
+ new_connect_node_select->select_from_visual_script(String(""));
}
void VisualScriptEditor::_members_gui_input(const Ref<InputEvent> &p_event) {
@@ -3148,9 +3146,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
} break;
case EDIT_FIND_NODE_TYPE: {
- //popup disappearing grabs focus to owner, so use call deferred
- node_filter->call_deferred("grab_focus");
- node_filter->call_deferred("select_all");
+ _generic_search();
} break;
case EDIT_COPY_NODES:
case EDIT_CUT_NODES: {
@@ -3487,6 +3483,8 @@ void VisualScriptEditor::_bind_methods() {
ClassDB::bind_method("_member_option", &VisualScriptEditor::_member_option);
ClassDB::bind_method("_update_available_nodes", &VisualScriptEditor::_update_available_nodes);
+
+ ClassDB::bind_method("_generic_search", &VisualScriptEditor::_generic_search);
}
VisualScriptEditor::VisualScriptEditor() {
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index 0283f7b162..e0f8a0aaa7 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -212,6 +212,9 @@ class VisualScriptEditor : public ScriptEditorBase {
String revert_on_drag;
void _input(const Ref<InputEvent> &p_event);
+
+ void _generic_search();
+
void _members_gui_input(const Ref<InputEvent> &p_event);
void _on_nodes_delete();
void _on_nodes_duplicate();
diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp
index 994ea1f791..123d697081 100644
--- a/modules/visual_script/visual_script_property_selector.cpp
+++ b/modules/visual_script/visual_script_property_selector.cpp
@@ -222,6 +222,10 @@ void VisualScriptPropertySelector::_update_search() {
item->set_selectable(0, true);
}
}
+
+ if (category && category->get_children() == NULL) {
+ memdelete(category); //old category was unused
+ }
}
if (seq_connect == true && visual_script_generic == false) {
@@ -348,6 +352,10 @@ void VisualScriptPropertySelector::_update_search() {
found = true;
}
+ if (category && category->get_children() == NULL) {
+ memdelete(category); //old category was unused
+ }
+
get_ok()->set_disabled(root->get_children() == NULL);
}
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index af96659239..8a0883eca3 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -116,7 +116,7 @@ def configure(env):
env.Append(CPPPATH=['#platform/osx'])
env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DAPPLE_STYLE_KEYS', '-DCOREAUDIO_ENABLED', '-DCOREMIDI_ENABLED'])
- env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMidi', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback'])
+ env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMIDI', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback'])
env.Append(LIBS=['pthread'])
env.Append(CPPFLAGS=['-mmacosx-version-min=10.9'])
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index d5a61b0b6b..7505aa4a94 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -800,11 +800,19 @@ int RigidBody2D::get_max_contacts_reported() const {
return max_contacts_reported;
}
+void RigidBody2D::apply_central_impulse(const Vector2 &p_impulse) {
+ Physics2DServer::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse);
+}
+
void RigidBody2D::apply_impulse(const Vector2 &p_offset, const Vector2 &p_impulse) {
Physics2DServer::get_singleton()->body_apply_impulse(get_rid(), p_offset, p_impulse);
}
+void RigidBody2D::apply_torque_impulse(float p_torque) {
+ Physics2DServer::get_singleton()->body_apply_torque_impulse(get_rid(), p_torque);
+}
+
void RigidBody2D::set_applied_force(const Vector2 &p_force) {
Physics2DServer::get_singleton()->body_set_applied_force(get_rid(), p_force);
@@ -825,11 +833,19 @@ float RigidBody2D::get_applied_torque() const {
return Physics2DServer::get_singleton()->body_get_applied_torque(get_rid());
};
+void RigidBody2D::add_central_force(const Vector2 &p_force) {
+ Physics2DServer::get_singleton()->body_add_central_force(get_rid(), p_force);
+}
+
void RigidBody2D::add_force(const Vector2 &p_offset, const Vector2 &p_force) {
Physics2DServer::get_singleton()->body_add_force(get_rid(), p_offset, p_force);
}
+void RigidBody2D::add_torque(const float p_torque) {
+ Physics2DServer::get_singleton()->body_add_torque(get_rid(), p_torque);
+}
+
void RigidBody2D::set_continuous_collision_detection_mode(CCDMode p_mode) {
ccd_mode = p_mode;
@@ -986,7 +1002,9 @@ void RigidBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_continuous_collision_detection_mode"), &RigidBody2D::get_continuous_collision_detection_mode);
ClassDB::bind_method(D_METHOD("set_axis_velocity", "axis_velocity"), &RigidBody2D::set_axis_velocity);
+ ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &RigidBody2D::apply_central_impulse);
ClassDB::bind_method(D_METHOD("apply_impulse", "offset", "impulse"), &RigidBody2D::apply_impulse);
+ ClassDB::bind_method(D_METHOD("apply_torque_impulse", "torque"), &RigidBody2D::apply_torque_impulse);
ClassDB::bind_method(D_METHOD("set_applied_force", "force"), &RigidBody2D::set_applied_force);
ClassDB::bind_method(D_METHOD("get_applied_force"), &RigidBody2D::get_applied_force);
@@ -994,7 +1012,9 @@ void RigidBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_applied_torque", "torque"), &RigidBody2D::set_applied_torque);
ClassDB::bind_method(D_METHOD("get_applied_torque"), &RigidBody2D::get_applied_torque);
+ ClassDB::bind_method(D_METHOD("add_central_force", "force"), &RigidBody2D::add_central_force);
ClassDB::bind_method(D_METHOD("add_force", "offset", "force"), &RigidBody2D::add_force);
+ ClassDB::bind_method(D_METHOD("add_torque", "torque"), &RigidBody2D::add_torque);
ClassDB::bind_method(D_METHOD("set_sleeping", "sleeping"), &RigidBody2D::set_sleeping);
ClassDB::bind_method(D_METHOD("is_sleeping"), &RigidBody2D::is_sleeping);
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index bd100f6228..0a2ce0918b 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -256,7 +256,9 @@ public:
void set_continuous_collision_detection_mode(CCDMode p_mode);
CCDMode get_continuous_collision_detection_mode() const;
+ void apply_central_impulse(const Vector2 &p_impulse);
void apply_impulse(const Vector2 &p_offset, const Vector2 &p_impulse);
+ void apply_torque_impulse(float p_torque);
void set_applied_force(const Vector2 &p_force);
Vector2 get_applied_force() const;
@@ -264,7 +266,9 @@ public:
void set_applied_torque(const float p_torque);
float get_applied_torque() const;
+ void add_central_force(const Vector2 &p_force);
void add_force(const Vector2 &p_offset, const Vector2 &p_force);
+ void add_torque(float p_torque);
Array get_colliding_bodies() const; //function for script
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index 7529a0e524..c1b867d114 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -795,6 +795,22 @@ int RigidBody::get_max_contacts_reported() const {
return max_contacts_reported;
}
+void RigidBody::add_central_force(const Vector3 &p_force) {
+ PhysicsServer::get_singleton()->body_add_central_force(get_rid(), p_force);
+}
+
+void RigidBody::add_force(const Vector3 &p_force, const Vector3 &p_pos) {
+ PhysicsServer::get_singleton()->body_add_force(get_rid(), p_force, p_pos);
+}
+
+void RigidBody::add_torque(const Vector3 &p_torque) {
+ PhysicsServer::get_singleton()->body_add_torque(get_rid(), p_torque);
+}
+
+void RigidBody::apply_central_impulse(const Vector3 &p_impulse) {
+ PhysicsServer::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse);
+}
+
void RigidBody::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse) {
PhysicsServer::get_singleton()->body_apply_impulse(get_rid(), p_pos, p_impulse);
@@ -947,6 +963,12 @@ void RigidBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_using_continuous_collision_detection"), &RigidBody::is_using_continuous_collision_detection);
ClassDB::bind_method(D_METHOD("set_axis_velocity", "axis_velocity"), &RigidBody::set_axis_velocity);
+
+ ClassDB::bind_method(D_METHOD("add_central_force", "force"), &RigidBody::add_central_force);
+ ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &RigidBody::add_force);
+ ClassDB::bind_method(D_METHOD("add_torque", "torque"), &RigidBody::add_torque);
+
+ ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &RigidBody::apply_central_impulse);
ClassDB::bind_method(D_METHOD("apply_impulse", "position", "impulse"), &RigidBody::apply_impulse);
ClassDB::bind_method(D_METHOD("apply_torque_impulse", "impulse"), &RigidBody::apply_torque_impulse);
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index 44d6502be1..4143989671 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -254,6 +254,11 @@ public:
Array get_colliding_bodies() const;
+ void add_central_force(const Vector3 &p_force);
+ void add_force(const Vector3 &p_force, const Vector3 &p_pos);
+ void add_torque(const Vector3 &p_torque);
+
+ void apply_central_impulse(const Vector3 &p_impulse);
void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse);
void apply_torque_impulse(const Vector3 &p_impulse);
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 2baad555c0..5fb9f79a1e 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -235,6 +235,8 @@ Error ImageTexture::load(const String &p_path) {
void ImageTexture::set_data(const Ref<Image> &p_image) {
+ ERR_FAIL_COND(p_image.is_null());
+
VisualServer::get_singleton()->texture_set_data(texture, p_image);
_change_notify();
diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h
index 25eb20f5d8..2f77196f58 100644
--- a/servers/physics/body_sw.h
+++ b/servers/physics/body_sw.h
@@ -219,6 +219,10 @@ public:
_FORCE_INLINE_ const Vector3 &get_biased_linear_velocity() const { return biased_linear_velocity; }
_FORCE_INLINE_ const Vector3 &get_biased_angular_velocity() const { return biased_angular_velocity; }
+ _FORCE_INLINE_ void apply_central_impulse(const Vector3 &p_j) {
+ linear_velocity += p_j * _inv_mass;
+ }
+
_FORCE_INLINE_ void apply_impulse(const Vector3 &p_pos, const Vector3 &p_j) {
linear_velocity += p_j * _inv_mass;
@@ -421,6 +425,7 @@ public:
virtual void add_central_force(const Vector3 &p_force) { body->add_central_force(p_force); }
virtual void add_force(const Vector3 &p_force, const Vector3 &p_pos) { body->add_force(p_force, p_pos); }
virtual void add_torque(const Vector3 &p_torque) { body->add_torque(p_torque); }
+ virtual void apply_central_impulse(const Vector3 &p_j) { body->apply_central_impulse(p_j); }
virtual void apply_impulse(const Vector3 &p_pos, const Vector3 &p_j) { body->apply_impulse(p_pos, p_j); }
virtual void apply_torque_impulse(const Vector3 &p_j) { body->apply_torque_impulse(p_j); }
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index f1e0cbef29..a06942cb2a 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -777,6 +777,40 @@ Vector3 PhysicsServerSW::body_get_applied_torque(RID p_body) const {
return body->get_applied_torque();
};
+void PhysicsServerSW::body_add_central_force(RID p_body, const Vector3 &p_force) {
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->add_central_force(p_force);
+ body->wakeup();
+}
+
+void PhysicsServerSW::body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_pos) {
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->add_force(p_force, p_pos);
+ body->wakeup();
+};
+
+void PhysicsServerSW::body_add_torque(RID p_body, const Vector3 &p_torque) {
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->add_torque(p_torque);
+ body->wakeup();
+};
+
+void PhysicsServerSW::body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) {
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ _update_shapes();
+
+ body->apply_central_impulse(p_impulse);
+ body->wakeup();
+}
+
void PhysicsServerSW::body_apply_impulse(RID p_body, const Vector3 &p_pos, const Vector3 &p_impulse) {
BodySW *body = body_owner.get(p_body);
diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h
index 7e9700d026..57037fb325 100644
--- a/servers/physics/physics_server_sw.h
+++ b/servers/physics/physics_server_sw.h
@@ -204,6 +204,11 @@ public:
virtual void body_set_applied_torque(RID p_body, const Vector3 &p_torque);
virtual Vector3 body_get_applied_torque(RID p_body) const;
+ virtual void body_add_central_force(RID p_body, const Vector3 &p_force);
+ virtual void body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_pos);
+ virtual void body_add_torque(RID p_body, const Vector3 &p_torque);
+
+ virtual void body_apply_central_impulse(RID p_body, const Vector3 &p_impulse);
virtual void body_apply_impulse(RID p_body, const Vector3 &p_pos, const Vector3 &p_impulse);
virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse);
virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity);
diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h
index 301bd6b299..7fe805b1f9 100644
--- a/servers/physics_2d/body_2d_sw.h
+++ b/servers/physics_2d/body_2d_sw.h
@@ -201,12 +201,20 @@ public:
_FORCE_INLINE_ void set_biased_angular_velocity(real_t p_velocity) { biased_angular_velocity = p_velocity; }
_FORCE_INLINE_ real_t get_biased_angular_velocity() const { return biased_angular_velocity; }
+ _FORCE_INLINE_ void apply_central_impulse(const Vector2 &p_impulse) {
+ linear_velocity += p_impulse * _inv_mass;
+ }
+
_FORCE_INLINE_ void apply_impulse(const Vector2 &p_offset, const Vector2 &p_impulse) {
linear_velocity += p_impulse * _inv_mass;
angular_velocity += _inv_inertia * p_offset.cross(p_impulse);
}
+ _FORCE_INLINE_ void apply_torque_impulse(real_t p_torque) {
+ angular_velocity += _inv_inertia * p_torque;
+ }
+
_FORCE_INLINE_ void apply_bias_impulse(const Vector2 &p_pos, const Vector2 &p_j) {
biased_linear_velocity += p_j * _inv_mass;
@@ -237,12 +245,20 @@ public:
void set_applied_torque(real_t p_torque) { applied_torque = p_torque; }
real_t get_applied_torque() const { return applied_torque; }
- _FORCE_INLINE_ void add_force(const Vector2 &p_force, const Vector2 &p_offset) {
+ _FORCE_INLINE_ void add_central_force(const Vector2 &p_force) {
+ applied_force += p_force;
+ }
+
+ _FORCE_INLINE_ void add_force(const Vector2 &p_offset, const Vector2 &p_force) {
applied_force += p_force;
applied_torque += p_offset.cross(p_force);
}
+ _FORCE_INLINE_ void add_torque(real_t p_torque) {
+ applied_torque += p_torque;
+ }
+
_FORCE_INLINE_ void set_continuous_collision_detection_mode(Physics2DServer::CCDMode p_mode) { continuous_cd_mode = p_mode; }
_FORCE_INLINE_ Physics2DServer::CCDMode get_continuous_collision_detection_mode() const { return continuous_cd_mode; }
@@ -357,6 +373,13 @@ public:
virtual void set_transform(const Transform2D &p_transform) { body->set_state(Physics2DServer::BODY_STATE_TRANSFORM, p_transform); }
virtual Transform2D get_transform() const { return body->get_transform(); }
+ virtual void add_central_force(const Vector2 &p_force) { body->add_central_force(p_force); }
+ virtual void add_force(const Vector2 &p_offset, const Vector2 &p_force) { body->add_force(p_offset, p_force); }
+ virtual void add_torque(real_t p_torque) { body->add_torque(p_torque); }
+ virtual void apply_central_impulse(const Vector2 &p_impulse) { body->apply_central_impulse(p_impulse); }
+ virtual void apply_impulse(const Vector2 &p_offset, const Vector2 &p_force) { body->apply_impulse(p_offset, p_force); }
+ virtual void apply_torque_impulse(real_t p_torque) { body->apply_torque_impulse(p_torque); }
+
virtual void set_sleep_state(bool p_enable) { body->set_active(!p_enable); }
virtual bool is_sleeping() const { return !body->is_active(); }
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index cfcef8cb04..ba87969eea 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -854,6 +854,21 @@ real_t Physics2DServerSW::body_get_applied_torque(RID p_body) const {
return body->get_applied_torque();
};
+void Physics2DServerSW::body_apply_central_impulse(RID p_body, const Vector2 &p_impulse) {
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->apply_central_impulse(p_impulse);
+ body->wakeup();
+}
+
+void Physics2DServerSW::body_apply_torque_impulse(RID p_body, real_t p_torque) {
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->apply_torque_impulse(p_torque);
+}
+
void Physics2DServerSW::body_apply_impulse(RID p_body, const Vector2 &p_pos, const Vector2 &p_impulse) {
Body2DSW *body = body_owner.get(p_body);
@@ -863,12 +878,28 @@ void Physics2DServerSW::body_apply_impulse(RID p_body, const Vector2 &p_pos, con
body->wakeup();
};
+void Physics2DServerSW::body_add_central_force(RID p_body, const Vector2 &p_force) {
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->add_central_force(p_force);
+ body->wakeup();
+};
+
void Physics2DServerSW::body_add_force(RID p_body, const Vector2 &p_offset, const Vector2 &p_force) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
- body->add_force(p_force, p_offset);
+ body->add_force(p_offset, p_force);
+ body->wakeup();
+};
+
+void Physics2DServerSW::body_add_torque(RID p_body, real_t p_torque) {
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->add_torque(p_torque);
body->wakeup();
};
diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h
index bf00746063..0b8d3f2a31 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -213,8 +213,12 @@ public:
virtual void body_set_applied_torque(RID p_body, real_t p_torque);
virtual real_t body_get_applied_torque(RID p_body) const;
+ virtual void body_add_central_force(RID p_body, const Vector2 &p_force);
virtual void body_add_force(RID p_body, const Vector2 &p_offset, const Vector2 &p_force);
+ virtual void body_add_torque(RID p_body, real_t p_torque);
+ virtual void body_apply_central_impulse(RID p_body, const Vector2 &p_impulse);
+ virtual void body_apply_torque_impulse(RID p_body, real_t p_torque);
virtual void body_apply_impulse(RID p_body, const Vector2 &p_pos, const Vector2 &p_impulse);
virtual void body_set_axis_velocity(RID p_body, const Vector2 &p_axis_velocity);
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h
index a85cd5ef8d..b9b0f80805 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.h
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.h
@@ -223,7 +223,11 @@ public:
FUNC2(body_set_applied_torque, RID, real_t);
FUNC1RC(real_t, body_get_applied_torque, RID);
+ FUNC2(body_add_central_force, RID, const Vector2 &);
FUNC3(body_add_force, RID, const Vector2 &, const Vector2 &);
+ FUNC2(body_add_torque, RID, real_t);
+ FUNC2(body_apply_central_impulse, RID, const Vector2 &);
+ FUNC2(body_apply_torque_impulse, RID, real_t);
FUNC3(body_apply_impulse, RID, const Vector2 &, const Vector2 &);
FUNC2(body_set_axis_velocity, RID, const Vector2 &);
diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp
index cb7669ec24..d6f3068e16 100644
--- a/servers/physics_2d_server.cpp
+++ b/servers/physics_2d_server.cpp
@@ -91,6 +91,13 @@ void Physics2DDirectBodyState::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_transform", "transform"), &Physics2DDirectBodyState::set_transform);
ClassDB::bind_method(D_METHOD("get_transform"), &Physics2DDirectBodyState::get_transform);
+ ClassDB::bind_method(D_METHOD("add_central_force", "force"), &Physics2DDirectBodyState::add_central_force);
+ ClassDB::bind_method(D_METHOD("add_force", "offset", "force"), &Physics2DDirectBodyState::add_force);
+ ClassDB::bind_method(D_METHOD("add_torque", "torque"), &Physics2DDirectBodyState::add_torque);
+ ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &Physics2DDirectBodyState::apply_central_impulse);
+ ClassDB::bind_method(D_METHOD("apply_torque_impulse", "impulse"), &Physics2DDirectBodyState::apply_torque_impulse);
+ ClassDB::bind_method(D_METHOD("apply_impulse", "offset", "impulse"), &Physics2DDirectBodyState::apply_impulse);
+
ClassDB::bind_method(D_METHOD("set_sleep_state", "enabled"), &Physics2DDirectBodyState::set_sleep_state);
ClassDB::bind_method(D_METHOD("is_sleeping"), &Physics2DDirectBodyState::is_sleeping);
@@ -585,8 +592,12 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_set_state", "body", "state", "value"), &Physics2DServer::body_set_state);
ClassDB::bind_method(D_METHOD("body_get_state", "body", "state"), &Physics2DServer::body_get_state);
+ ClassDB::bind_method(D_METHOD("body_apply_central_impulse", "body", "impulse"), &Physics2DServer::body_apply_central_impulse);
+ ClassDB::bind_method(D_METHOD("body_apply_torque_impulse", "body", "impulse"), &Physics2DServer::body_apply_torque_impulse);
ClassDB::bind_method(D_METHOD("body_apply_impulse", "body", "position", "impulse"), &Physics2DServer::body_apply_impulse);
+ ClassDB::bind_method(D_METHOD("body_add_central_force", "force"), &Physics2DServer::body_add_central_force);
ClassDB::bind_method(D_METHOD("body_add_force", "body", "offset", "force"), &Physics2DServer::body_add_force);
+ ClassDB::bind_method(D_METHOD("body_add_torque", "body", "torque"), &Physics2DServer::body_add_torque);
ClassDB::bind_method(D_METHOD("body_set_axis_velocity", "body", "axis_velocity"), &Physics2DServer::body_set_axis_velocity);
ClassDB::bind_method(D_METHOD("body_add_collision_exception", "body", "excepted_body"), &Physics2DServer::body_add_collision_exception);
diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h
index 89c649af49..796eec1e8e 100644
--- a/servers/physics_2d_server.h
+++ b/servers/physics_2d_server.h
@@ -61,6 +61,13 @@ public:
virtual void set_transform(const Transform2D &p_transform) = 0;
virtual Transform2D get_transform() const = 0;
+ virtual void add_central_force(const Vector2 &p_force) = 0;
+ virtual void add_force(const Vector2 &p_offset, const Vector2 &p_force) = 0;
+ virtual void add_torque(real_t p_torque) = 0;
+ virtual void apply_central_impulse(const Vector2 &p_impulse) = 0;
+ virtual void apply_torque_impulse(real_t p_torque) = 0;
+ virtual void apply_impulse(const Vector2 &p_offset, const Vector2 &p_impulse) = 0;
+
virtual void set_sleep_state(bool p_enable) = 0;
virtual bool is_sleeping() const = 0;
@@ -448,8 +455,12 @@ public:
virtual void body_set_applied_torque(RID p_body, float p_torque) = 0;
virtual float body_get_applied_torque(RID p_body) const = 0;
+ virtual void body_add_central_force(RID p_body, const Vector2 &p_force) = 0;
virtual void body_add_force(RID p_body, const Vector2 &p_offset, const Vector2 &p_force) = 0;
+ virtual void body_add_torque(RID p_body, float p_torque) = 0;
+ virtual void body_apply_central_impulse(RID p_body, const Vector2 &p_impulse) = 0;
+ virtual void body_apply_torque_impulse(RID p_body, float p_torque) = 0;
virtual void body_apply_impulse(RID p_body, const Vector2 &p_offset, const Vector2 &p_impulse) = 0;
virtual void body_set_axis_velocity(RID p_body, const Vector2 &p_axis_velocity) = 0;
diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp
index b4bd4cb35f..7dd3437360 100644
--- a/servers/physics_server.cpp
+++ b/servers/physics_server.cpp
@@ -95,6 +95,7 @@ void PhysicsDirectBodyState::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_central_force", "force"), &PhysicsDirectBodyState::add_central_force);
ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &PhysicsDirectBodyState::add_force);
ClassDB::bind_method(D_METHOD("add_torque", "torque"), &PhysicsDirectBodyState::add_torque);
+ ClassDB::bind_method(D_METHOD("apply_central_impulse", "j"), &PhysicsDirectBodyState::apply_central_impulse);
ClassDB::bind_method(D_METHOD("apply_impulse", "position", "j"), &PhysicsDirectBodyState::apply_impulse);
ClassDB::bind_method(D_METHOD("apply_torque_impulse", "j"), &PhysicsDirectBodyState::apply_torque_impulse);
@@ -495,6 +496,11 @@ void PhysicsServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_set_state", "body", "state", "value"), &PhysicsServer::body_set_state);
ClassDB::bind_method(D_METHOD("body_get_state", "body", "state"), &PhysicsServer::body_get_state);
+ ClassDB::bind_method(D_METHOD("body_add_central_force", "body", "force"), &PhysicsServer::body_add_central_force);
+ ClassDB::bind_method(D_METHOD("body_add_force", "body", "force", "position"), &PhysicsServer::body_add_force);
+ ClassDB::bind_method(D_METHOD("body_add_torque", "body", "torque"), &PhysicsServer::body_add_torque);
+
+ ClassDB::bind_method(D_METHOD("body_apply_central_impulse", "body", "impulse"), &PhysicsServer::body_apply_central_impulse);
ClassDB::bind_method(D_METHOD("body_apply_impulse", "body", "position", "impulse"), &PhysicsServer::body_apply_impulse);
ClassDB::bind_method(D_METHOD("body_apply_torque_impulse", "body", "impulse"), &PhysicsServer::body_apply_torque_impulse);
ClassDB::bind_method(D_METHOD("body_set_axis_velocity", "body", "axis_velocity"), &PhysicsServer::body_set_axis_velocity);
diff --git a/servers/physics_server.h b/servers/physics_server.h
index 497d23c555..217656e2a9 100644
--- a/servers/physics_server.h
+++ b/servers/physics_server.h
@@ -66,6 +66,7 @@ public:
virtual void add_central_force(const Vector3 &p_force) = 0;
virtual void add_force(const Vector3 &p_force, const Vector3 &p_pos) = 0;
virtual void add_torque(const Vector3 &p_torque) = 0;
+ virtual void apply_central_impulse(const Vector3 &p_j) = 0;
virtual void apply_impulse(const Vector3 &p_pos, const Vector3 &p_j) = 0;
virtual void apply_torque_impulse(const Vector3 &p_j) = 0;
@@ -434,6 +435,11 @@ public:
virtual void body_set_applied_torque(RID p_body, const Vector3 &p_torque) = 0;
virtual Vector3 body_get_applied_torque(RID p_body) const = 0;
+ virtual void body_add_central_force(RID p_body, const Vector3 &p_force) = 0;
+ virtual void body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_pos) = 0;
+ virtual void body_add_torque(RID p_body, const Vector3 &p_torque) = 0;
+
+ virtual void body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) = 0;
virtual void body_apply_impulse(RID p_body, const Vector3 &p_pos, const Vector3 &p_impulse) = 0;
virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) = 0;
virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) = 0;
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index a8f4377ce7..5ce4f2b62d 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -1078,7 +1078,7 @@ public:
virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale) = 0;
virtual void initialize() = 0;
- virtual void begin_frame() = 0;
+ virtual void begin_frame(double frame_step) = 0;
virtual void set_current_render_target(RID p_render_target) = 0;
virtual void restore_render_target() = 0;
virtual void clear_render_target(const Color &p_color) = 0;
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index fd1eb77143..146f0235a6 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -1376,6 +1376,15 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "bvec4", TYPE_BVEC4, { TYPE_UVEC4, TYPE_VOID } },
{ "bvec4", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID } },
+ //conversion between matrixes
+
+ { "mat2", TYPE_MAT2, { TYPE_MAT3, TYPE_VOID } },
+ { "mat2", TYPE_MAT2, { TYPE_MAT4, TYPE_VOID } },
+ { "mat3", TYPE_MAT3, { TYPE_MAT2, TYPE_VOID } },
+ { "mat3", TYPE_MAT3, { TYPE_MAT4, TYPE_VOID } },
+ { "mat4", TYPE_MAT4, { TYPE_MAT2, TYPE_VOID } },
+ { "mat4", TYPE_MAT4, { TYPE_MAT3, TYPE_VOID } },
+
//builtins - trigonometry
{ "radians", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 5f207b1d3f..6bf3670e5a 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -93,14 +93,14 @@ void VisualServerRaster::request_frame_drawn_callback(Object *p_where, const Str
frame_drawn_callbacks.push_back(fdc);
}
-void VisualServerRaster::draw(bool p_swap_buffers) {
+void VisualServerRaster::draw(bool p_swap_buffers, double frame_step) {
//needs to be done before changes is reset to 0, to not force the editor to redraw
VS::get_singleton()->emit_signal("frame_pre_draw");
changes = 0;
- VSG::rasterizer->begin_frame();
+ VSG::rasterizer->begin_frame(frame_step);
VSG::scene->update_dirty_instances(); //update scene stuff
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index ec0d02ed2a..d58be21858 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -660,7 +660,7 @@ public:
virtual void request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata);
- virtual void draw(bool p_swap_buffers);
+ virtual void draw(bool p_swap_buffers, double frame_step);
virtual void sync();
virtual bool has_changed() const;
virtual void init();
diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp
index 094e2794ed..93f3792bdc 100644
--- a/servers/visual/visual_server_wrap_mt.cpp
+++ b/servers/visual/visual_server_wrap_mt.cpp
@@ -37,11 +37,11 @@ void VisualServerWrapMT::thread_exit() {
exit = true;
}
-void VisualServerWrapMT::thread_draw() {
+void VisualServerWrapMT::thread_draw(bool p_swap_buffers, double frame_step) {
if (!atomic_decrement(&draw_pending)) {
- visual_server->draw();
+ visual_server->draw(p_swap_buffers, frame_step);
}
}
@@ -91,15 +91,15 @@ void VisualServerWrapMT::sync() {
}
}
-void VisualServerWrapMT::draw(bool p_swap_buffers) {
+void VisualServerWrapMT::draw(bool p_swap_buffers, double frame_step) {
if (create_thread) {
atomic_increment(&draw_pending);
- command_queue.push(this, &VisualServerWrapMT::thread_draw);
+ command_queue.push(this, &VisualServerWrapMT::thread_draw, p_swap_buffers, frame_step);
} else {
- visual_server->draw(p_swap_buffers);
+ visual_server->draw(p_swap_buffers, frame_step);
}
}
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 48f0ec46f3..c6af960d9f 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -55,7 +55,7 @@ class VisualServerWrapMT : public VisualServer {
bool create_thread;
uint64_t draw_pending;
- void thread_draw();
+ void thread_draw(bool p_swap_buffers, double frame_step);
void thread_flush();
void thread_exit();
@@ -578,7 +578,7 @@ public:
virtual void init();
virtual void finish();
- virtual void draw(bool p_swap_buffers);
+ virtual void draw(bool p_swap_buffers, double frame_step);
virtual void sync();
FUNC0RC(bool, has_changed)
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 1f3319dc04..95b181ff47 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1648,13 +1648,13 @@ Array VisualServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_surfa
void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("force_sync"), &VisualServer::sync);
- ClassDB::bind_method(D_METHOD("force_draw", "swap_buffers"), &VisualServer::draw, DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("force_draw", "swap_buffers", "frame_step"), &VisualServer::draw, DEFVAL(true), DEFVAL(0.0));
// "draw" and "sync" are deprecated duplicates of "force_draw" and "force_sync"
// FIXME: Add deprecation messages using GH-4397 once available, and retire
// once the warnings have been enabled for a full release cycle
ClassDB::bind_method(D_METHOD("sync"), &VisualServer::sync);
- ClassDB::bind_method(D_METHOD("draw", "swap_buffers"), &VisualServer::draw, DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("draw", "swap_buffers", "frame_step"), &VisualServer::draw, DEFVAL(true), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("texture_create"), &VisualServer::texture_create);
ClassDB::bind_method(D_METHOD("texture_create_from_image", "image", "flags"), &VisualServer::texture_create_from_image, DEFVAL(TEXTURE_FLAGS_DEFAULT));
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 367642b7d4..8a4a4e2d36 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -955,7 +955,7 @@ public:
/* EVENT QUEUING */
- virtual void draw(bool p_swap_buffers = true) = 0;
+ virtual void draw(bool p_swap_buffers = true, double frame_step = 0.0) = 0;
virtual void sync() = 0;
virtual bool has_changed() const = 0;
virtual void init() = 0;