summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/math/basis.cpp4
-rw-r--r--core/math/transform_2d.cpp12
-rw-r--r--core/math/transform_2d.h1
-rw-r--r--core/object.cpp15
-rw-r--r--core/object.h1
-rw-r--r--core/script_language.cpp2
-rw-r--r--core/script_language.h3
-rw-r--r--doc/classes/TileMap.xml4
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp28
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.h1
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp29
-rw-r--r--drivers/gles2/shaders/scene.glsl10
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp2
-rw-r--r--editor/editor_audio_buses.cpp2
-rw-r--r--editor/plugin_config_dialog.cpp10
-rw-r--r--editor/plugins/particles_2d_editor_plugin.cpp1
-rw-r--r--modules/gdnative/include/videodecoder/godot_videodecoder.h4
-rw-r--r--modules/gdnative/videodecoder/register_types.cpp4
-rw-r--r--modules/gdnative/videodecoder/register_types.h4
-rw-r--r--modules/gdnative/videodecoder/video_stream_gdnative.cpp4
-rw-r--r--modules/gdnative/videodecoder/video_stream_gdnative.h4
-rw-r--r--modules/mono/csharp_script.cpp21
-rw-r--r--modules/mono/csharp_script.h5
-rw-r--r--modules/mono/editor/bindings_generator.cpp2
-rw-r--r--modules/mono/glue/Managed/Files/Transform2D.cs62
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.cpp43
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp15
-rw-r--r--scene/2d/node_2d.cpp2
-rw-r--r--scene/animation/animation_node_state_machine.cpp3
29 files changed, 232 insertions, 66 deletions
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index 8e4eacd9a6..7f60b7962c 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -258,7 +258,7 @@ Vector3 Basis::get_scale_abs() const {
}
Vector3 Basis::get_scale_local() const {
- real_t det_sign = determinant() > 0 ? 1 : -1;
+ real_t det_sign = SGN(determinant());
return det_sign * Vector3(elements[0].length(), elements[1].length(), elements[2].length());
}
@@ -284,7 +284,7 @@ Vector3 Basis::get_scale() const {
// matrix elements.
//
// The rotation part of this decomposition is returned by get_rotation* functions.
- real_t det_sign = determinant() > 0 ? 1 : -1;
+ real_t det_sign = SGN(determinant());
return det_sign * Vector3(
Vector3(elements[0][0], elements[1][0], elements[2][0]).length(),
Vector3(elements[0][1], elements[1][1], elements[2][1]).length(),
diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp
index 295e60babb..7d00158f3d 100644
--- a/core/math/transform_2d.cpp
+++ b/core/math/transform_2d.cpp
@@ -80,13 +80,14 @@ real_t Transform2D::get_rotation() const {
}
void Transform2D::set_rotation(real_t p_rot) {
-
+ Size2 scale = get_scale();
real_t cr = Math::cos(p_rot);
real_t sr = Math::sin(p_rot);
elements[0][0] = cr;
elements[0][1] = sr;
elements[1][0] = -sr;
elements[1][1] = cr;
+ set_scale(scale);
}
Transform2D::Transform2D(real_t p_rot, const Vector2 &p_pos) {
@@ -101,10 +102,17 @@ Transform2D::Transform2D(real_t p_rot, const Vector2 &p_pos) {
}
Size2 Transform2D::get_scale() const {
- real_t det_sign = basis_determinant() > 0 ? 1 : -1;
+ real_t det_sign = SGN(basis_determinant());
return Size2(elements[0].length(), det_sign * elements[1].length());
}
+void Transform2D::set_scale(Size2 &p_scale) {
+ elements[0].normalize();
+ elements[1].normalize();
+ elements[0] *= p_scale.x;
+ elements[1] *= p_scale.y;
+}
+
void Transform2D::scale(const Size2 &p_scale) {
scale_basis(p_scale);
elements[2] *= p_scale;
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index 507e6a16eb..b9e7a36fb3 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -81,6 +81,7 @@ struct Transform2D {
real_t basis_determinant() const;
Size2 get_scale() const;
+ void set_scale(Size2 &p_scale);
_FORCE_INLINE_ const Vector2 &get_origin() const { return elements[2]; }
_FORCE_INLINE_ void set_origin(const Vector2 &p_origin) { elements[2] = p_origin; }
diff --git a/core/object.cpp b/core/object.cpp
index 05e661baab..b30ae1f512 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -1929,6 +1929,13 @@ bool Object::has_script_instance_binding(int p_script_language_index) {
return _script_instance_bindings[p_script_language_index] != NULL;
}
+void Object::set_script_instance_binding(int p_script_language_index, void *p_data) {
+#ifdef DEBUG_ENABLED
+ CRASH_COND(_script_instance_bindings[p_script_language_index] != NULL);
+#endif
+ _script_instance_bindings[p_script_language_index] = p_data;
+}
+
Object::Object() {
_class_ptr = NULL;
@@ -1992,9 +1999,11 @@ Object::~Object() {
_instance_ID = 0;
_predelete_ok = 2;
- for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) {
- if (_script_instance_bindings[i]) {
- ScriptServer::get_language(i)->free_instance_binding_data(_script_instance_bindings[i]);
+ if (!ScriptServer::are_languages_finished()) {
+ for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) {
+ if (_script_instance_bindings[i]) {
+ ScriptServer::get_language(i)->free_instance_binding_data(_script_instance_bindings[i]);
+ }
}
}
}
diff --git a/core/object.h b/core/object.h
index 5bfef8a439..9a5217e3de 100644
--- a/core/object.h
+++ b/core/object.h
@@ -730,6 +730,7 @@ public:
//used by script languages to store binding data
void *get_script_instance_binding(int p_script_language_index);
bool has_script_instance_binding(int p_script_language_index);
+ void set_script_instance_binding(int p_script_language_index, void *p_data);
void clear_internal_resource_paths();
diff --git a/core/script_language.cpp b/core/script_language.cpp
index 632fa3b336..2746c015d6 100644
--- a/core/script_language.cpp
+++ b/core/script_language.cpp
@@ -37,6 +37,7 @@ int ScriptServer::_language_count = 0;
bool ScriptServer::scripting_enabled = true;
bool ScriptServer::reload_scripts_on_save = false;
+bool ScriptServer::languages_finished = false;
ScriptEditRequestFunction ScriptServer::edit_request_func = NULL;
void Script::_notification(int p_what) {
@@ -130,6 +131,7 @@ void ScriptServer::finish_languages() {
_languages[i]->finish();
}
global_classes_clear();
+ languages_finished = true;
}
void ScriptServer::set_reload_scripts_on_save(bool p_enable) {
diff --git a/core/script_language.h b/core/script_language.h
index b0f12dc291..2d35097692 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -54,6 +54,7 @@ class ScriptServer {
static int _language_count;
static bool scripting_enabled;
static bool reload_scripts_on_save;
+ static bool languages_finished;
struct GlobalScriptClass {
StringName language;
@@ -91,6 +92,8 @@ public:
static void init_languages();
static void finish_languages();
+
+ static bool are_languages_finished() { return languages_finished; }
};
class ScriptInstance;
diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml
index 4849d768f5..fe3b2118a3 100644
--- a/doc/classes/TileMap.xml
+++ b/doc/classes/TileMap.xml
@@ -34,7 +34,7 @@
<argument index="1" name="y" type="int">
</argument>
<description>
- Returns the tile index of the given cell.
+ Returns the tile index of the given cell. If no tile exists in the cell, returns [constant INVALID_CELL].
</description>
</method>
<method name="get_cell_autotile_coord" qualifiers="const">
@@ -53,7 +53,7 @@
<argument index="0" name="position" type="Vector2">
</argument>
<description>
- Returns the tile index of the cell given by a Vector2.
+ Returns the tile index of the cell given by a Vector2. If no tile exists in the cell, returns [constant INVALID_CELL].
</description>
</method>
<method name="get_collision_layer_bit" qualifiers="const">
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index 64e4dbdab4..a7345978e1 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -576,8 +576,15 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
} else {
+ static const Vector2 uvs[4] = {
+ Vector2(0.0, 0.0),
+ Vector2(0.0, 1.0),
+ Vector2(1.0, 1.0),
+ Vector2(1.0, 0.0),
+ };
+
state.canvas_shader.set_uniform(CanvasShaderGLES2::COLOR_TEXPIXEL_SIZE, Vector2());
- _draw_gui_primitive(4, points, NULL, NULL);
+ _draw_gui_primitive(4, points, NULL, uvs);
}
} else {
@@ -1165,7 +1172,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
}
}
-void RasterizerCanvasGLES2::_copy_texscreen(const Rect2 &p_rect) {
+void RasterizerCanvasGLES2::_copy_screen(const Rect2 &p_rect) {
if (storage->frame.current_rt->copy_screen_effect.color == 0) {
ERR_EXPLAIN("Can't use screen texture copying in a render target configured without copy buffers");
@@ -1174,8 +1181,6 @@ void RasterizerCanvasGLES2::_copy_texscreen(const Rect2 &p_rect) {
glDisable(GL_BLEND);
- state.canvas_texscreen_used = true;
-
Vector2 wh(storage->frame.current_rt->width, storage->frame.current_rt->height);
Color copy_section(p_rect.position.x / wh.x, p_rect.position.y / wh.y, p_rect.size.x / wh.x, p_rect.size.y / wh.y);
@@ -1188,9 +1193,6 @@ void RasterizerCanvasGLES2::_copy_texscreen(const Rect2 &p_rect) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color);
- glClearColor(1, 0, 1, 1);
- glClear(GL_COLOR_BUFFER_BIT);
-
storage->shaders.copy.bind();
storage->shaders.copy.set_uniform(CopyShaderGLES2::COPY_SECTION, copy_section);
@@ -1218,14 +1220,20 @@ void RasterizerCanvasGLES2::_copy_texscreen(const Rect2 &p_rect) {
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_COPY_SECTION, false);
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); //back to front
+ glEnable(GL_BLEND);
+}
+
+void RasterizerCanvasGLES2::_copy_texscreen(const Rect2 &p_rect) {
+
+ state.canvas_texscreen_used = true;
+
+ _copy_screen(p_rect);
// back to canvas, force rebind
state.using_texture_rect = false;
state.canvas_shader.bind();
_bind_canvas_texture(state.current_tex, state.current_normal);
_set_uniforms();
-
- glEnable(GL_BLEND);
}
void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform) {
@@ -1878,6 +1886,8 @@ void RasterizerCanvasGLES2::draw_window_margins(int *black_margin, RID *black_im
draw_generic_textured_rect(Rect2(0, window_h - black_margin[MARGIN_BOTTOM], window_w, black_margin[MARGIN_BOTTOM]), Rect2(0, 0, 1, 1));
}
+
+ canvas_end();
}
void RasterizerCanvasGLES2::initialize() {
diff --git a/drivers/gles2/rasterizer_canvas_gles2.h b/drivers/gles2/rasterizer_canvas_gles2.h
index 221427198a..0d069ebabc 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.h
+++ b/drivers/gles2/rasterizer_canvas_gles2.h
@@ -118,6 +118,7 @@ public:
_FORCE_INLINE_ void _draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
_FORCE_INLINE_ void _canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip, RasterizerStorageGLES2::Material *p_material);
+ void _copy_screen(const Rect2 &p_rect);
_FORCE_INLINE_ void _copy_texscreen(const Rect2 &p_rect);
virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform);
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index cc9084dceb..2c6168241e 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -1178,6 +1178,11 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
state.scene_shader.set_custom_shader(p_material->shader->custom_code_id);
+ if (p_material->shader->spatial.uses_screen_texture && storage->frame.current_rt) {
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->copy_screen_effect.color);
+ }
+
bool shader_rebind = state.scene_shader.bind();
if (p_material->shader->spatial.no_depth_test) {
@@ -1200,9 +1205,6 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
} break;
}
- // TODO whyyyyy????
- p_reverse_cull = true;
-
switch (p_material->shader->spatial.cull_mode) {
case RasterizerStorageGLES2::Shader::Spatial::CULL_MODE_DISABLED: {
glDisable(GL_CULL_FACE);
@@ -2557,11 +2559,19 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C
void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
+ Transform cam_transform = p_cam_transform;
+
GLuint current_fb = 0;
Environment *env = NULL;
int viewport_width, viewport_height;
bool probe_interior = false;
+ bool reverse_cull = false;
+
+ if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) {
+ cam_transform.basis.set_axis(1, -cam_transform.basis.get_axis(1));
+ reverse_cull = true;
+ }
if (p_reflection_probe.is_valid()) {
ReflectionProbeInstance *probe = reflection_probe_instance_owner.getornull(p_reflection_probe);
@@ -2588,6 +2598,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
viewport_height = storage->frame.current_rt->height;
}
+ state.used_screen_texture = false;
state.viewport_size.x = viewport_width;
state.viewport_size.y = viewport_height;
state.screen_pixel_size.x = 1.0 / viewport_width;
@@ -2711,7 +2722,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
if (env && env->bg_mode == VS::ENV_BG_SKY && (!storage->frame.current_rt || !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT])) {
if (sky && sky->panorama.is_valid()) {
- _draw_sky(sky, p_cam_projection, p_cam_transform, false, env->sky_custom_fov, env->bg_energy, env->sky_orientation);
+ _draw_sky(sky, p_cam_projection, cam_transform, false, env->sky_custom_fov, env->bg_energy, env->sky_orientation);
}
}
@@ -2721,8 +2732,12 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
// render opaque things first
render_list.sort_by_key(false);
- _render_render_list(render_list.elements, render_list.element_count, p_cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, false, false, false);
+ _render_render_list(render_list.elements, render_list.element_count, cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, reverse_cull, false, false);
+ if (storage->frame.current_rt && state.used_screen_texture) {
+ //copy screen texture
+ storage->canvas->_copy_screen(Rect2());
+ }
// alpha pass
glBlendEquation(GL_FUNC_ADD);
@@ -2730,7 +2745,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
render_list.sort_by_depth(true);
- _render_render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, false, true, false);
+ _render_render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, reverse_cull, true, false);
glDisable(GL_DEPTH_TEST);
@@ -3228,6 +3243,8 @@ void RasterizerSceneGLES2::initialize() {
}
shadow_filter_mode = SHADOW_FILTER_NEAREST;
+
+ glFrontFace(GL_CW);
}
void RasterizerSceneGLES2::iteration() {
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index 6c3d3baccd..242329d4a7 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -2049,7 +2049,13 @@ FRAGMENT_SHADER_CODE
#if defined(USE_VERTEX_LIGHTING)
+#if defined(BASE_PASS)
gl_FragColor.rgb = mix(gl_FragColor.rgb, fog_interp.rgb, fog_interp.a);
+#else
+ gl_FragColor.rgb *= (1.0 - fog_interp.a);
+#endif // BASE_PASS
+
+
#else //pixel based fog
float fog_amount = 0.0;
@@ -2083,7 +2089,11 @@ FRAGMENT_SHADER_CODE
}
#endif
+#if defined(BASE_PASS)
gl_FragColor.rgb = mix(gl_FragColor.rgb, fog_color, fog_amount);
+#else
+ gl_FragColor.rgb *= (1.0 - fog_amount);
+#endif // BASE_PASS
#endif //use vertex lit
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index b8f0965af8..29b4b0c6c4 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -1704,6 +1704,8 @@ void RasterizerCanvasGLES3::canvas_debug_viewport_shadows(Light *p_lights_with_s
light = light->shadows_next_ptr;
}
+
+ canvas_end();
}
void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache) {
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index 6593eb8f03..f5cbc3861a 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -1165,7 +1165,7 @@ EditorAudioBuses::EditorAudioBuses() {
add = memnew(Button);
top_hb->add_child(add);
add->set_text(TTR("Add Bus"));
- add->set_tooltip(TTR("Create a new Bus Layout."));
+ add->set_tooltip(TTR("Add a new Audio Bus to this layout."));
add->connect("pressed", this, "_add_bus");
diff --git a/editor/plugin_config_dialog.cpp b/editor/plugin_config_dialog.cpp
index 88672bdf34..12bf544357 100644
--- a/editor/plugin_config_dialog.cpp
+++ b/editor/plugin_config_dialog.cpp
@@ -120,6 +120,10 @@ void PluginConfigDialog::_notification(int p_what) {
connect("confirmed", this, "_on_confirmed");
get_cancel()->connect("pressed", this, "_on_cancelled");
} break;
+
+ case NOTIFICATION_POST_POPUP: {
+ name_edit->grab_focus();
+ } break;
}
}
@@ -215,11 +219,15 @@ PluginConfigDialog::PluginConfigDialog() {
grid->add_child(script_option_lb);
script_option_edit = memnew(OptionButton);
+ int default_lang = 0;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
ScriptLanguage *lang = ScriptServer::get_language(i);
script_option_edit->add_item(lang->get_name());
+ if (lang == GDScriptLanguage::get_singleton()) {
+ default_lang = i;
+ }
}
- script_option_edit->select(0);
+ script_option_edit->select(default_lang);
grid->add_child(script_option_edit);
Label *script_lb = memnew(Label);
diff --git a/editor/plugins/particles_2d_editor_plugin.cpp b/editor/plugins/particles_2d_editor_plugin.cpp
index a944674cbd..bb7d50a9c1 100644
--- a/editor/plugins/particles_2d_editor_plugin.cpp
+++ b/editor/plugins/particles_2d_editor_plugin.cpp
@@ -91,6 +91,7 @@ void Particles2DEditorPlugin::_menu_callback(int p_idx) {
cpu_particles->set_transform(particles->get_transform());
cpu_particles->set_visible(particles->is_visible());
cpu_particles->set_pause_mode(particles->get_pause_mode());
+ cpu_particles->set_z_index(particles->get_z_index());
EditorNode::get_singleton()->get_scene_tree_dock()->replace_node(particles, cpu_particles, false);
diff --git a/modules/gdnative/include/videodecoder/godot_videodecoder.h b/modules/gdnative/include/videodecoder/godot_videodecoder.h
index 360fc0f5f5..1b08be30f0 100644
--- a/modules/gdnative/include/videodecoder/godot_videodecoder.h
+++ b/modules/gdnative/include/videodecoder/godot_videodecoder.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 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 */
diff --git a/modules/gdnative/videodecoder/register_types.cpp b/modules/gdnative/videodecoder/register_types.cpp
index ea78cb1970..0a0b2f64d5 100644
--- a/modules/gdnative/videodecoder/register_types.cpp
+++ b/modules/gdnative/videodecoder/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 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 */
diff --git a/modules/gdnative/videodecoder/register_types.h b/modules/gdnative/videodecoder/register_types.h
index dd1943fc47..f082343d8c 100644
--- a/modules/gdnative/videodecoder/register_types.h
+++ b/modules/gdnative/videodecoder/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 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 */
diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp
index a1590cef43..8c2a84f60b 100644
--- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp
+++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 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 */
diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.h b/modules/gdnative/videodecoder/video_stream_gdnative.h
index f9dec46b72..aafd02f33d 100644
--- a/modules/gdnative/videodecoder/video_stream_gdnative.h
+++ b/modules/gdnative/videodecoder/video_stream_gdnative.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 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 */
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 5da1344595..9c127b837d 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -1113,19 +1113,23 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b
void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
+ SCOPED_MUTEX_LOCK(language_bind_mutex);
+
+ Map<Object *, CSharpScriptBinding>::Element *match = script_bindings.find(p_object);
+ if (match)
+ return (void *)match;
+
CSharpScriptBinding script_binding;
if (!setup_csharp_script_binding(script_binding, p_object))
return NULL;
- void *data;
+ return (void *)insert_script_binding(p_object, script_binding);
+}
- {
- SCOPED_MUTEX_LOCK(language_bind_mutex);
- data = (void *)script_bindings.insert(p_object, script_binding);
- }
+Map<Object *, CSharpScriptBinding>::Element *CSharpLanguage::insert_script_binding(Object *p_object, const CSharpScriptBinding &p_script_binding) {
- return data;
+ return script_bindings.insert(p_object, p_script_binding);
}
void CSharpLanguage::free_instance_binding_data(void *p_data) {
@@ -2279,17 +2283,18 @@ void CSharpScript::_bind_methods() {
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &CSharpScript::_new, MethodInfo(Variant::OBJECT, "new"));
}
-Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class) {
+Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native) {
// This method should not fail
CRASH_COND(!p_class);
+ // TODO: Cache the 'CSharpScript' associated with this 'p_class' instead of allocating a new one every time
Ref<CSharpScript> script = memnew(CSharpScript);
script->name = p_class->get_name();
script->script_class = p_class;
- script->native = GDMonoUtils::get_class_native_base(script->script_class);
+ script->native = p_native;
CRASH_COND(script->native == NULL);
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index db9d6a73a2..8b1a4b5f7e 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -135,7 +135,7 @@ class CSharpScript : public Script {
// Do not use unless you know what you are doing
friend void GDMonoInternals::tie_managed_to_unmanaged(MonoObject *, Object *);
- static Ref<CSharpScript> create_for_managed_type(GDMonoClass *p_class);
+ static Ref<CSharpScript> create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native);
protected:
static void _bind_methods();
@@ -312,6 +312,8 @@ class CSharpLanguage : public ScriptLanguage {
public:
StringNameCache string_names;
+ Mutex *get_language_bind_mutex() { return language_bind_mutex; }
+
_FORCE_INLINE_ int get_language_index() { return lang_idx; }
void set_language_index(int p_idx);
@@ -406,6 +408,7 @@ public:
virtual void refcount_incremented_instance_binding(Object *p_object);
virtual bool refcount_decremented_instance_binding(Object *p_object);
+ Map<Object *, CSharpScriptBinding>::Element *insert_script_binding(Object *p_object, const CSharpScriptBinding &p_script_binding);
bool setup_csharp_script_binding(CSharpScriptBinding &r_script_binding, Object *p_object);
#ifdef DEBUG_ENABLED
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 0b6a6a327c..77e9b1f1f4 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -849,6 +849,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
}
}
+ // TODO: BINDINGS_NATIVE_NAME_FIELD should be StringName, once we support it in C#
+
if (itype.is_singleton) {
// Add the type name and the singleton pointer as static fields
diff --git a/modules/mono/glue/Managed/Files/Transform2D.cs b/modules/mono/glue/Managed/Files/Transform2D.cs
index f89c99cff2..df7ba3402d 100644
--- a/modules/mono/glue/Managed/Files/Transform2D.cs
+++ b/modules/mono/glue/Managed/Files/Transform2D.cs
@@ -17,12 +17,40 @@ namespace Godot
public real_t Rotation
{
- get { return Mathf.Atan2(y.x, origin.y); }
+ get
+ {
+ real_t det = BasisDeterminant();
+ Transform2D t = Orthonormalized();
+ if (det < 0)
+ {
+ t.ScaleBasis(new Vector2(1, -1));
+ }
+ return Mathf.Atan2(t.x.y, t.x.x);
+ }
+ set
+ {
+ Vector2 scale = Scale;
+ x.x = y.y = Mathf.Cos(value);
+ x.y = y.x = Mathf.Sin(value);
+ y.x *= -1;
+ Scale = scale;
+ }
}
public Vector2 Scale
{
- get { return new Vector2(x.Length(), y.Length()); }
+ get
+ {
+ real_t detSign = Mathf.Sign(BasisDeterminant());
+ return new Vector2(x.Length(), detSign * y.Length());
+ }
+ set
+ {
+ x = x.Normalized();
+ y = y.Normalized();
+ x *= value.x;
+ y *= value.y;
+ }
}
public Vector2 this[int index]
@@ -95,7 +123,7 @@ namespace Godot
{
var inv = this;
- real_t det = this[0, 0] * this[1, 1] - this[1, 0] * this[0, 1];
+ real_t det = BasisDeterminant();
if (det == 0)
{
@@ -107,20 +135,25 @@ namespace Godot
);
}
- real_t idet = 1.0f / det;
+ real_t detInv = 1.0f / det;
real_t temp = this[0, 0];
this[0, 0] = this[1, 1];
this[1, 1] = temp;
- this[0] *= new Vector2(idet, -idet);
- this[1] *= new Vector2(-idet, idet);
+ this[0] *= new Vector2(detInv, -detInv);
+ this[1] *= new Vector2(-detInv, detInv);
this[2] = BasisXform(-this[2]);
return inv;
}
+ private real_t BasisDeterminant()
+ {
+ return x.x * y.y - x.y * y.x;
+ }
+
public Vector2 BasisXform(Vector2 v)
{
return new Vector2(Tdotx(v), Tdoty(v));
@@ -220,6 +253,14 @@ namespace Godot
return copy;
}
+ private void ScaleBasis(Vector2 scale)
+ {
+ x.x *= scale.x;
+ x.y *= scale.y;
+ y.x *= scale.x;
+ y.y *= scale.y;
+ }
+
private real_t Tdotx(Vector2 with)
{
return this[0, 0] * with[0] + this[1, 0] * with[1];
@@ -274,12 +315,9 @@ namespace Godot
public Transform2D(real_t rot, Vector2 pos)
{
- real_t cr = Mathf.Cos(rot);
- real_t sr = Mathf.Sin(rot);
- x.x = cr;
- x.y = -sr;
- y.x = sr;
- y.y = cr;
+ x.x = y.y = Mathf.Cos(rot);
+ x.y = y.x = Mathf.Sin(rot);
+ y.x *= -1;
origin = pos;
}
diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp
index 0daa394e63..14ec24466b 100644
--- a/modules/mono/mono_gd/gd_mono_internals.cpp
+++ b/modules/mono/mono_gd/gd_mono_internals.cpp
@@ -34,6 +34,8 @@
#include "../mono_gc_handle.h"
#include "../utils/macros.h"
#include "../utils/thread_local.h"
+#include "gd_mono_class.h"
+#include "gd_mono_marshal.h"
#include "gd_mono_utils.h"
#include <mono/metadata/exception.h>
@@ -55,10 +57,49 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
CRASH_COND(!klass);
+ GDMonoClass *native = GDMonoUtils::get_class_native_base(klass);
+
+ CRASH_COND(native == NULL);
+
+ if (native == klass) {
+ // If it's just a wrapper Godot class and not a custom inheriting class, then attach a
+ // script binding instead. One of the advantages of this is that if a script is attached
+ // later and it's not a C# script, then the managed object won't have to be disposed.
+ // Another reason for doing this is that this instance could outlive CSharpLanguage, which would
+ // be problematic when using a script. See: https://github.com/godotengine/godot/issues/25621
+
+ CSharpScriptBinding script_binding;
+
+ script_binding.inited = true;
+ script_binding.type_name = NATIVE_GDMONOCLASS_NAME(klass);
+ script_binding.wrapper_class = klass;
+ script_binding.gchandle = MonoGCHandle::create_strong(managed);
+
+ Reference *ref = Object::cast_to<Reference>(unmanaged);
+ if (ref) {
+ // Unsafe refcount increment. The managed instance also counts as a reference.
+ // This way if the unmanaged world has no references to our owner
+ // but the managed instance is alive, the refcount will be 1 instead of 0.
+ // See: godot_icall_Reference_Dtor(MonoObject *p_obj, Object *p_ptr)
+
+ ref->reference();
+ }
+
+ // The object was just created, no script instance binding should have been attached
+ CRASH_COND(unmanaged->has_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index()));
+
+ void *data = (void *)CSharpLanguage::get_singleton()->insert_script_binding(unmanaged, script_binding);
+
+ // Should be thread safe because the object was just created and nothing else should be referencing it
+ unmanaged->set_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index(), data);
+
+ return;
+ }
+
Ref<MonoGCHandle> gchandle = ref ? MonoGCHandle::create_weak(managed) :
MonoGCHandle::create_strong(managed);
- Ref<CSharpScript> script = CSharpScript::create_for_managed_type(klass);
+ Ref<CSharpScript> script = CSharpScript::create_for_managed_type(klass, native);
CRASH_COND(script.is_null());
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index ac6ccac3a7..3b97339fea 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -39,6 +39,7 @@
#include "../csharp_script.h"
#include "../utils/macros.h"
+#include "../utils/mutex_utils.h"
#include "gd_mono.h"
#include "gd_mono_class.h"
#include "gd_mono_marshal.h"
@@ -281,17 +282,19 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) {
void *data = unmanaged->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
- if (!data)
- return NULL;
+ ERR_FAIL_NULL_V(data, NULL);
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->value();
if (!script_binding.inited) {
- // Already had a binding that needs to be setup
- CSharpLanguage::get_singleton()->setup_csharp_script_binding(script_binding, unmanaged);
+ SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->get_language_bind_mutex());
+
+ if (!script_binding.inited) { // Other thread may have set it up
+ // Already had a binding that needs to be setup
+ CSharpLanguage::get_singleton()->setup_csharp_script_binding(script_binding, unmanaged);
- if (!script_binding.inited)
- return NULL;
+ ERR_FAIL_COND_V(!script_binding.inited, NULL);
+ }
}
Ref<MonoGCHandle> &gchandle = script_binding.gchandle;
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index 9a94092840..f4430d93f6 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -376,7 +376,7 @@ void Node2D::look_at(const Vector2 &p_pos) {
float Node2D::get_angle_to(const Vector2 &p_pos) const {
- return (get_global_transform().affine_inverse().xform(p_pos)).angle();
+ return (to_local(p_pos) * get_scale()).angle();
}
Point2 Node2D::to_local(Point2 p_global) const {
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index 08cc655cdd..5df3da93e1 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -421,7 +421,8 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *sm,
if (sm->transitions[i].from == current && auto_advance) {
- if (sm->transitions[i].transition->get_priority() < priority_best) {
+ if (sm->transitions[i].transition->get_priority() <= priority_best) {
+ priority_best = sm->transitions[i].transition->get_priority();
auto_advance_to = i;
}
}