summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/os/os.h1
-rw-r--r--core/script_debugger_remote.cpp1
-rw-r--r--core/undo_redo.cpp12
-rw-r--r--core/undo_redo.h3
-rw-r--r--drivers/dummy/rasterizer_dummy.h1
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp16
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp13
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp26
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.h7
-rw-r--r--drivers/gles2/shaders/scene.glsl13
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp12
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp30
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp14
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h6
-rw-r--r--drivers/gles3/shaders/scene.glsl11
-rw-r--r--editor/animation_track_editor.cpp30
-rw-r--r--editor/animation_track_editor.h9
-rw-r--r--editor/animation_track_editor_plugins.cpp6
-rw-r--r--editor/editor_node.cpp1
-rw-r--r--editor/filesystem_dock.cpp2
-rw-r--r--editor/import/editor_import_collada.cpp2
-rw-r--r--editor/import/editor_scene_importer_gltf.cpp1
-rw-r--r--modules/gdscript/gdscript_function.cpp13
-rw-r--r--modules/gdscript/gdscript_parser.cpp17
-rw-r--r--platform/windows/os_windows.cpp26
-rw-r--r--platform/windows/os_windows.h3
-rw-r--r--scene/3d/physics_body.cpp12
-rw-r--r--scene/3d/physics_body.h4
-rw-r--r--scene/3d/skeleton.cpp46
-rw-r--r--scene/3d/skeleton.h4
-rw-r--r--scene/gui/container.cpp13
-rw-r--r--scene/gui/container.h2
-rw-r--r--scene/resources/packed_scene.cpp4
-rw-r--r--servers/visual/rasterizer.h1
-rw-r--r--servers/visual/visual_server_raster.cpp1
-rw-r--r--servers/visual/visual_server_raster.h1
-rw-r--r--servers/visual/visual_server_wrap_mt.h1
-rw-r--r--servers/visual_server.h1
38 files changed, 228 insertions, 138 deletions
diff --git a/core/os/os.h b/core/os/os.h
index d6541034fd..30cfb32b89 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -518,6 +518,7 @@ public:
bool is_restart_on_exit_set() const;
List<String> get_restart_on_exit_arguments() const;
+ virtual void process_and_drop_events() { }
OS();
virtual ~OS();
};
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index 3ed25f118d..e7ff7a3aef 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -311,6 +311,7 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue)
} else {
OS::get_singleton()->delay_usec(10000);
+ OS::get_singleton()->process_and_drop_events();
}
}
diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp
index 00894b41d8..9a10e0585d 100644
--- a/core/undo_redo.cpp
+++ b/core/undo_redo.cpp
@@ -239,6 +239,10 @@ void UndoRedo::_pop_history_tail() {
}
}
+bool UndoRedo::is_commiting_action() const {
+ return commiting > 0;
+}
+
void UndoRedo::commit_action() {
ERR_FAIL_COND(action_level <= 0);
@@ -321,10 +325,13 @@ bool UndoRedo::redo() {
if ((current_action + 1) >= actions.size())
return false; //nothing to redo
+
+ commiting++;
current_action++;
_process_operation_list(actions.write[current_action].do_ops.front());
version++;
+ commiting--;
return true;
}
@@ -334,10 +341,11 @@ bool UndoRedo::undo() {
ERR_FAIL_COND_V(action_level > 0, false);
if (current_action < 0)
return false; //nothing to redo
+ commiting++;
_process_operation_list(actions.write[current_action].undo_ops.front());
current_action--;
version--;
-
+ commiting--;
return true;
}
@@ -386,6 +394,7 @@ void UndoRedo::set_property_notify_callback(PropertyNotifyCallback p_property_ca
UndoRedo::UndoRedo() {
+ commiting = 0;
version = 1;
action_level = 0;
current_action = -1;
@@ -484,6 +493,7 @@ void UndoRedo::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_action", "name", "merge_mode"), &UndoRedo::create_action, DEFVAL(MERGE_DISABLE));
ClassDB::bind_method(D_METHOD("commit_action"), &UndoRedo::commit_action);
+ ClassDB::bind_method(D_METHOD("is_commiting_action"), &UndoRedo::is_commiting_action);
//ClassDB::bind_method(D_METHOD("add_do_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_do_method);
//ClassDB::bind_method(D_METHOD("add_undo_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_undo_method);
diff --git a/core/undo_redo.h b/core/undo_redo.h
index 4ee64dbfcf..b626149ce6 100644
--- a/core/undo_redo.h
+++ b/core/undo_redo.h
@@ -94,6 +94,8 @@ private:
MethodNotifyCallback method_callback;
PropertyNotifyCallback property_callback;
+ int commiting;
+
protected:
static void _bind_methods();
@@ -107,6 +109,7 @@ public:
void add_do_reference(Object *p_object);
void add_undo_reference(Object *p_object);
+ bool is_commiting_action() const;
void commit_action();
bool redo();
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h
index 214da82819..ddf4d1d85c 100644
--- a/drivers/dummy/rasterizer_dummy.h
+++ b/drivers/dummy/rasterizer_dummy.h
@@ -461,6 +461,7 @@ public:
RID skeleton_create() { return RID(); }
void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) {}
void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) {}
+ void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform) {}
int skeleton_get_bone_count(RID p_skeleton) const { return 0; }
void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) {}
Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const { return Transform(); }
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index bf0da5feb1..3671679b49 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -202,12 +202,12 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(con
} else {
- texture = texture->get_ptr();
-
if (texture->redraw_if_visible) {
VisualServerRaster::redraw_request();
}
+ texture = texture->get_ptr();
+
if (texture->render_target) {
texture->render_target->used_in_frame = true;
}
@@ -244,12 +244,12 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(con
} else {
- normal_map = normal_map->get_ptr();
-
if (normal_map->redraw_if_visible) { //check before proxy, because this is usually used with proxies
VisualServerRaster::redraw_request();
}
+ normal_map = normal_map->get_ptr();
+
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
state.current_normal = p_normal_map;
@@ -1412,6 +1412,10 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
continue;
}
+ if (t->redraw_if_visible) {
+ VisualServerRaster::redraw_request();
+ }
+
t = t->get_ptr();
#ifdef TOOLS_ENABLED
@@ -1422,10 +1426,6 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
if (t->render_target)
t->render_target->used_in_frame = true;
- if (t->redraw_if_visible) {
- VisualServerRaster::redraw_request();
- }
-
glBindTexture(t->target, t->tex_id);
}
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index e0eec74700..5e006b7527 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -1312,12 +1312,12 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
continue;
}
- t = t->get_ptr();
-
if (t->redraw_if_visible) { //must check before proxy because this is often used with proxies
VisualServerRaster::redraw_request();
}
+ t = t->get_ptr();
+
#ifdef TOOLS_ENABLED
if (t->detect_3d) {
t->detect_3d(t->detect_3d_ud);
@@ -1671,11 +1671,10 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) {
if (c.texture.is_valid() && storage->texture_owner.owns(c.texture)) {
RasterizerStorageGLES2::Texture *t = storage->texture_owner.get(c.texture);
- t = t->get_ptr();
-
if (t->redraw_if_visible) {
VisualServerRaster::redraw_request();
}
+ t = t->get_ptr();
#ifdef TOOLS_ENABLED
if (t->detect_3d) {
@@ -2487,6 +2486,12 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
state.scene_shader.set_uniform(SceneShaderGLES2::WORLD_TRANSFORM, e->instance->transform);
+ if (skeleton) {
+ state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_IN_WORLD_COORDS, skeleton->use_world_transform);
+ state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TRANSFORM, skeleton->world_transform);
+ state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TRANSFORM_INVERSE, skeleton->world_transform_inverse);
+ }
+
if (use_lightmap_capture) { //this is per instance, must be set always if present
glUniform4fv(state.scene_shader.get_uniform_location(SceneShaderGLES2::LIGHTMAP_CAPTURES), 12, (const GLfloat *)e->instance->lightmap_capture_data.ptr());
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHTMAP_CAPTURE_SKY, false);
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index d5965bba4f..11ab8438df 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -429,7 +429,6 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
if (!image.is_null()) {
image = image->duplicate();
- print_line("decompressing...");
image->decompress();
ERR_FAIL_COND_V(image->is_compressed(), image);
switch (image->get_format()) {
@@ -2380,7 +2379,7 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
surface->total_data_size += surface->array_byte_size + surface->index_array_byte_size;
for (int i = 0; i < surface->skeleton_bone_used.size(); i++) {
- surface->skeleton_bone_used.write[i] = surface->skeleton_bone_aabb[i].size.x < 0 || surface->skeleton_bone_aabb[i].size.y < 0 || surface->skeleton_bone_aabb[i].size.z < 0;
+ surface->skeleton_bone_used.write[i] = !(surface->skeleton_bone_aabb[i].size.x < 0 || surface->skeleton_bone_aabb[i].size.y < 0 || surface->skeleton_bone_aabb[i].size.z < 0);
}
for (int i = 0; i < VS::ARRAY_MAX; i++) {
@@ -2688,7 +2687,7 @@ AABB RasterizerStorageGLES2::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
mtx.basis[0].x = texture[base_ofs + 0];
mtx.basis[0].y = texture[base_ofs + 1];
mtx.origin.x = texture[base_ofs + 3];
- base_ofs += 256 * 4;
+ base_ofs += 4;
mtx.basis[1].x = texture[base_ofs + 0];
mtx.basis[1].y = texture[base_ofs + 1];
mtx.origin.y = texture[base_ofs + 3];
@@ -2716,12 +2715,12 @@ AABB RasterizerStorageGLES2::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
mtx.basis[0].y = texture[base_ofs + 1];
mtx.basis[0].z = texture[base_ofs + 2];
mtx.origin.x = texture[base_ofs + 3];
- base_ofs += 256 * 4;
+ base_ofs += 4;
mtx.basis[1].x = texture[base_ofs + 0];
mtx.basis[1].y = texture[base_ofs + 1];
mtx.basis[1].z = texture[base_ofs + 2];
mtx.origin.y = texture[base_ofs + 3];
- base_ofs += 256 * 4;
+ base_ofs += 4;
mtx.basis[2].x = texture[base_ofs + 0];
mtx.basis[2].y = texture[base_ofs + 1];
mtx.basis[2].z = texture[base_ofs + 2];
@@ -3599,6 +3598,23 @@ void RasterizerStorageGLES2::skeleton_set_base_transform_2d(RID p_skeleton, cons
skeleton->base_transform_2d = p_base_transform;
}
+void RasterizerStorageGLES2::skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform) {
+
+ Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
+
+ ERR_FAIL_COND(skeleton->use_2d);
+
+ skeleton->world_transform = p_world_transform;
+ skeleton->use_world_transform = p_enable;
+ if (p_enable) {
+ skeleton->world_transform_inverse = skeleton->world_transform.affine_inverse();
+ }
+
+ if (!skeleton->update_list.in_list()) {
+ skeleton_update_list.add(&skeleton->update_list);
+ }
+}
+
void RasterizerStorageGLES2::_update_skeleton_transform_buffer(const PoolVector<float> &p_data, size_t p_size) {
glBindBuffer(GL_ARRAY_BUFFER, resources.skeleton_transform_buffer);
diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h
index e6c23716a5..8f5565c96f 100644
--- a/drivers/gles2/rasterizer_storage_gles2.h
+++ b/drivers/gles2/rasterizer_storage_gles2.h
@@ -864,12 +864,16 @@ public:
Set<RasterizerScene::InstanceBase *> instances;
Transform2D base_transform_2d;
+ Transform world_transform;
+ Transform world_transform_inverse;
+ bool use_world_transform;
Skeleton() :
use_2d(false),
size(0),
tex_id(0),
- update_list(this) {
+ update_list(this),
+ use_world_transform(false) {
}
};
@@ -887,6 +891,7 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform);
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const;
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform);
+ virtual void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform);
void _update_skeleton_transform_buffer(const PoolVector<float> &p_data, size_t p_size);
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index 371ea8498a..e3c6966e21 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -59,6 +59,10 @@ uniform ivec2 skeleton_texture_size;
#endif
+uniform highp mat4 skeleton_transform;
+uniform highp mat4 skeleton_transform_inverse;
+uniform bool skeleton_in_world_coords;
+
#endif
#ifdef USE_INSTANCING
@@ -404,7 +408,14 @@ void main() {
#endif
- world_matrix = bone_transform * world_matrix;
+ if (skeleton_in_world_coords) {
+ bone_transform = skeleton_transform * (bone_transform * skeleton_transform_inverse);
+ world_matrix = bone_transform * world_matrix;
+ } else {
+ world_matrix = world_matrix * bone_transform;
+ }
+
+
#endif
#ifdef USE_INSTANCING
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 227445ae5b..4f4608dca0 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -222,12 +222,12 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con
} else {
- texture = texture->get_ptr();
-
if (texture->redraw_if_visible) { //check before proxy, because this is usually used with proxies
VisualServerRaster::redraw_request();
}
+ texture = texture->get_ptr();
+
if (texture->render_target)
texture->render_target->used_in_frame = true;
@@ -263,12 +263,12 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con
} else {
- normal_map = normal_map->get_ptr();
-
if (normal_map->redraw_if_visible) { //check before proxy, because this is usually used with proxies
VisualServerRaster::redraw_request();
}
+ normal_map = normal_map->get_ptr();
+
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
state.current_normal = p_normal_map;
@@ -1402,12 +1402,12 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
continue;
}
- t = t->get_ptr();
-
if (t->redraw_if_visible) { //check before proxy, because this is usually used with proxies
VisualServerRaster::redraw_request();
}
+ t = t->get_ptr();
+
if (storage->config.srgb_decode_supported && t->using_srgb) {
//no srgb in 2D
glTexParameteri(t->target, _TEXTURE_SRGB_DECODE_EXT, _SKIP_DECODE_EXT);
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index e645e39f3f..0c7d8c53d4 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1199,12 +1199,12 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m
if (t) {
- t = t->get_ptr(); //resolve for proxies
-
if (t->redraw_if_visible) { //must check before proxy because this is often used with proxies
VisualServerRaster::redraw_request();
}
+ t = t->get_ptr(); //resolve for proxies
+
#ifdef TOOLS_ENABLED
if (t->detect_3d) {
t->detect_3d(t->detect_3d_ud);
@@ -1629,11 +1629,10 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
RasterizerStorageGLES3::Texture *t = storage->texture_owner.get(c.texture);
- t = t->get_ptr(); //resolve for proxies
-
if (t->redraw_if_visible) {
VisualServerRaster::redraw_request();
}
+ t = t->get_ptr(); //resolve for proxies
#ifdef TOOLS_ENABLED
if (t->detect_3d) {
@@ -2044,7 +2043,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
int current_blend_mode = -1;
int prev_shading = -1;
- RID prev_skeleton;
+ RasterizerStorageGLES3::Skeleton *prev_skeleton = NULL;
state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS, true); //by default unshaded (easier to set)
@@ -2058,7 +2057,10 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
RenderList::Element *e = p_elements[i];
RasterizerStorageGLES3::Material *material = e->material;
- RID skeleton = e->instance->skeleton;
+ RasterizerStorageGLES3::Skeleton *skeleton = NULL;
+ if (e->instance->skeleton.is_valid()) {
+ skeleton = storage->skeleton_owner.getornull(e->instance->skeleton);
+ }
bool rebind = first;
@@ -2205,15 +2207,14 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
}
if (prev_skeleton != skeleton) {
- if (prev_skeleton.is_valid() != skeleton.is_valid()) {
- state.scene_shader.set_conditional(SceneShaderGLES3::USE_SKELETON, skeleton.is_valid());
+ if ((prev_skeleton == NULL) != (skeleton == NULL)) {
+ state.scene_shader.set_conditional(SceneShaderGLES3::USE_SKELETON, skeleton != NULL);
rebind = true;
}
- if (skeleton.is_valid()) {
- RasterizerStorageGLES3::Skeleton *sk = storage->skeleton_owner.getornull(skeleton);
+ if (skeleton) {
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
- glBindTexture(GL_TEXTURE_2D, sk->texture);
+ glBindTexture(GL_TEXTURE_2D, skeleton->texture);
}
}
@@ -2240,6 +2241,11 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
_set_cull(e->sort_key & RenderList::SORT_KEY_MIRROR_FLAG, e->sort_key & RenderList::SORT_KEY_CULL_DISABLED_FLAG, p_reverse_cull);
+ if (skeleton) {
+ state.scene_shader.set_uniform(SceneShaderGLES3::SKELETON_TRANSFORM, skeleton->world_transform);
+ state.scene_shader.set_uniform(SceneShaderGLES3::SKELETON_IN_WORLD_COORDS, skeleton->use_world_transform);
+ }
+
state.scene_shader.set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, e->instance->transform);
_render_geometry(e);
@@ -4250,7 +4256,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
} else {
- use_mrt = env && (state.used_sss || env->ssao_enabled || env->ssr_enabled); //only enable MRT rendering if any of these is enabled
+ use_mrt = env && (state.used_sss || env->ssao_enabled || env->ssr_enabled || env->dof_blur_far_enabled || env->dof_blur_near_enabled); //only enable MRT rendering if any of these is enabled
//effects disabled and transparency also prevent using MRTs
use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT];
use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS];
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index fdfa4a72e4..e38f9f922c 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -5135,6 +5135,20 @@ void RasterizerStorageGLES3::skeleton_set_base_transform_2d(RID p_skeleton, cons
skeleton->base_transform_2d = p_base_transform;
}
+void RasterizerStorageGLES3::skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform) {
+
+ Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
+
+ ERR_FAIL_COND(skeleton->use_2d);
+
+ skeleton->world_transform = p_world_transform;
+ skeleton->use_world_transform = p_enable;
+
+ if (!skeleton->update_list.in_list()) {
+ skeleton_update_list.add(&skeleton->update_list);
+ }
+}
+
void RasterizerStorageGLES3::update_dirty_skeletons() {
glActiveTexture(GL_TEXTURE0);
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index d1e02e25d6..2994bfb074 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -890,12 +890,15 @@ public:
SelfList<Skeleton> update_list;
Set<RasterizerScene::InstanceBase *> instances; //instances using skeleton
Transform2D base_transform_2d;
+ bool use_world_transform;
+ Transform world_transform;
Skeleton() :
use_2d(false),
size(0),
texture(0),
- update_list(this) {
+ update_list(this),
+ use_world_transform(false) {
}
};
@@ -913,6 +916,7 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform);
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const;
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform);
+ virtual void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform);
/* Light API */
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 3b06b08dec..630e1c2089 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -302,6 +302,8 @@ out highp float dp_clip;
#ifdef USE_SKELETON
uniform highp sampler2D skeleton_texture; // texunit:-1
+uniform highp mat4 skeleton_transform;
+uniform bool skeleton_in_world_coords;
#endif
out highp vec4 position_interp;
@@ -430,7 +432,14 @@ void main() {
vec4(0.0, 0.0, 0.0, 1.0)) *
bone_weights.w;
- world_matrix = transpose(m) * world_matrix;
+ if (skeleton_in_world_coords) {
+ highp mat4 bone_matrix = skeleton_transform * (transpose(m) * inverse(skeleton_transform));
+ world_matrix = bone_matrix * world_matrix;
+
+ } else {
+
+ world_matrix = world_matrix * transpose(m);
+ }
}
#endif
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 6b45ca2cae..6b863a162c 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -692,12 +692,10 @@ void AnimationTimelineEdit::_anim_length_changed(double p_new_len) {
p_new_len = MAX(0.001, p_new_len);
editing = true;
- *block_animation_update_ptr = true;
undo_redo->create_action(TTR("Change Animation Length"));
undo_redo->add_do_method(animation.ptr(), "set_length", p_new_len);
undo_redo->add_undo_method(animation.ptr(), "set_length", animation->get_length());
undo_redo->commit_action();
- *block_animation_update_ptr = false;
editing = false;
update();
@@ -706,12 +704,10 @@ void AnimationTimelineEdit::_anim_length_changed(double p_new_len) {
void AnimationTimelineEdit::_anim_loop_pressed() {
- *block_animation_update_ptr = true;
undo_redo->create_action(TTR("Change Animation Loop"));
undo_redo->add_do_method(animation.ptr(), "set_loop", loop->is_pressed());
undo_redo->add_undo_method(animation.ptr(), "set_loop", animation->has_loop());
undo_redo->commit_action();
- *block_animation_update_ptr = false;
}
int AnimationTimelineEdit::get_buttons_width() const {
@@ -936,10 +932,6 @@ Size2 AnimationTimelineEdit::get_minimum_size() const {
return ms;
}
-void AnimationTimelineEdit::set_block_animation_update_ptr(bool *p_block_ptr) {
- block_animation_update_ptr = p_block_ptr;
-}
-
void AnimationTimelineEdit::set_undo_redo(UndoRedo *p_undo_redo) {
undo_redo = p_undo_redo;
}
@@ -1080,7 +1072,6 @@ void AnimationTimelineEdit::_bind_methods() {
AnimationTimelineEdit::AnimationTimelineEdit() {
- block_animation_update_ptr = NULL;
editing = false;
name_limit = 150;
zoom = NULL;
@@ -1884,12 +1875,10 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
Point2 pos = mb->get_position();
if (check_rect.has_point(pos)) {
- *block_animation_update_ptr = true;
undo_redo->create_action(TTR("Toggle Track Enabled"));
undo_redo->add_do_method(animation.ptr(), "track_set_enabled", track, !animation->track_is_enabled(track));
undo_redo->add_undo_method(animation.ptr(), "track_set_enabled", track, animation->track_is_enabled(track));
undo_redo->commit_action();
- *block_animation_update_ptr = false;
update();
accept_event();
}
@@ -2186,12 +2175,10 @@ void AnimationTrackEdit::_menu_selected(int p_index) {
case MENU_CALL_MODE_CAPTURE: {
Animation::UpdateMode update_mode = Animation::UpdateMode(p_index);
- *block_animation_update_ptr = true;
undo_redo->create_action(TTR("Change Animation Update Mode"));
undo_redo->add_do_method(animation.ptr(), "value_track_set_update_mode", track, update_mode);
undo_redo->add_undo_method(animation.ptr(), "value_track_set_update_mode", track, animation->value_track_get_update_mode(track));
undo_redo->commit_action();
- *block_animation_update_ptr = false;
update();
} break;
@@ -2200,24 +2187,20 @@ void AnimationTrackEdit::_menu_selected(int p_index) {
case MENU_INTERPOLATION_CUBIC: {
Animation::InterpolationType interp_mode = Animation::InterpolationType(p_index - MENU_INTERPOLATION_NEAREST);
- *block_animation_update_ptr = true;
undo_redo->create_action(TTR("Change Animation Interpolation Mode"));
undo_redo->add_do_method(animation.ptr(), "track_set_interpolation_type", track, interp_mode);
undo_redo->add_undo_method(animation.ptr(), "track_set_interpolation_type", track, animation->track_get_interpolation_type(track));
undo_redo->commit_action();
- *block_animation_update_ptr = false;
update();
} break;
case MENU_LOOP_WRAP:
case MENU_LOOP_CLAMP: {
bool loop_wrap = p_index == MENU_LOOP_WRAP;
- *block_animation_update_ptr = true;
undo_redo->create_action(TTR("Change Animation Loop Mode"));
undo_redo->add_do_method(animation.ptr(), "track_set_interpolation_loop_wrap", track, loop_wrap);
undo_redo->add_undo_method(animation.ptr(), "track_set_interpolation_loop_wrap", track, animation->track_get_interpolation_loop_wrap(track));
undo_redo->commit_action();
- *block_animation_update_ptr = false;
update();
} break;
@@ -2235,10 +2218,6 @@ void AnimationTrackEdit::_menu_selected(int p_index) {
}
}
-void AnimationTrackEdit::set_block_animation_update_ptr(bool *p_block_ptr) {
- block_animation_update_ptr = p_block_ptr;
-}
-
void AnimationTrackEdit::cancel_drop() {
if (dropping_at != 0) {
dropping_at = 0;
@@ -2301,7 +2280,6 @@ AnimationTrackEdit::AnimationTrackEdit() {
root = NULL;
path = NULL;
menu = NULL;
- block_animation_update_ptr = NULL;
clicking_on_name = false;
dropping_at = 0;
@@ -3384,7 +3362,6 @@ void AnimationTrackEditor::_update_tracks() {
track_edit->set_undo_redo(undo_redo);
track_edit->set_timeline(timeline);
- track_edit->set_block_animation_update_ptr(&block_animation_update);
track_edit->set_root(root);
track_edit->set_animation_and_track(animation, i);
track_edit->set_play_position(timeline->get_play_position());
@@ -3425,7 +3402,7 @@ void AnimationTrackEditor::_animation_changed() {
timeline->update();
timeline->update_values();
- if (block_animation_update) {
+ if (undo_redo->is_commiting_action()) {
for (int i = 0; i < track_edits.size(); i++) {
track_edits[i]->update();
}
@@ -4075,9 +4052,7 @@ void AnimationTrackEditor::_move_selection_commit() {
undo_redo->add_undo_method(this, "_select_at_anim", animation, E->key().track, oldpos);
}
- block_animation_update = true; //animation will change and this is triggered from a signal, so block updates
undo_redo->commit_action();
- block_animation_update = false;
moving_selection = false;
for (int i = 0; i < track_edits.size(); i++) {
@@ -4778,7 +4753,6 @@ void AnimationTrackEditor::_bind_methods() {
AnimationTrackEditor::AnimationTrackEditor() {
root = NULL;
- block_animation_update = false;
undo_redo = EditorNode::get_singleton()->get_undo_redo();
@@ -4796,7 +4770,6 @@ AnimationTrackEditor::AnimationTrackEditor() {
timeline_vbox->add_constant_override("separation", 0);
timeline = memnew(AnimationTimelineEdit);
- timeline->set_block_animation_update_ptr(&block_animation_update);
timeline->set_undo_redo(undo_redo);
timeline_vbox->add_child(timeline);
timeline->connect("timeline_changed", this, "_timeline_changed");
@@ -4815,7 +4788,6 @@ AnimationTrackEditor::AnimationTrackEditor() {
bezier_edit = memnew(AnimationBezierTrackEdit);
timeline_vbox->add_child(bezier_edit);
- bezier_edit->set_block_animation_update_ptr(&block_animation_update);
bezier_edit->set_undo_redo(undo_redo);
bezier_edit->set_editor(this);
bezier_edit->set_timeline(timeline);
diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h
index 47058839ba..4ad8b6fd68 100644
--- a/editor/animation_track_editor.h
+++ b/editor/animation_track_editor.h
@@ -76,7 +76,6 @@ class AnimationTimelineEdit : public Range {
Rect2 hsize_rect;
bool editing;
- bool *block_animation_update_ptr; //used to block all tracks re-gen (speed up)
bool panning_timeline;
float panning_timeline_from;
@@ -104,7 +103,6 @@ public:
void set_zoom(Range *p_zoom);
Range *get_zoom() const { return zoom; }
void set_undo_redo(UndoRedo *p_undo_redo);
- void set_block_animation_update_ptr(bool *p_block_ptr);
void set_play_position(float p_pos);
float get_play_position() const;
@@ -170,8 +168,6 @@ class AnimationTrackEdit : public Control {
void _menu_selected(int p_index);
- bool *block_animation_update_ptr; //used to block all tracks re-gen (speed up)
-
void _path_entered(const String &p_text);
void _play_position_draw();
mutable int dropping_at;
@@ -216,7 +212,6 @@ public:
AnimationTimelineEdit *get_timeline() const { return timeline; }
AnimationTrackEditor *get_editor() const { return editor; }
UndoRedo *get_undo_redo() const { return undo_redo; }
- bool *get_block_animation_update_ptr() { return block_animation_update_ptr; }
void set_animation_and_track(const Ref<Animation> &p_animation, int p_track);
virtual Size2 get_minimum_size() const;
@@ -226,8 +221,6 @@ public:
void set_editor(AnimationTrackEditor *p_editor);
void set_root(Node *p_root);
- void set_block_animation_update_ptr(bool *p_block_ptr);
-
void set_play_position(float p_pos);
void update_play_position();
void cancel_drop();
@@ -313,8 +306,6 @@ class AnimationTrackEditor : public VBoxContainer {
Vector<AnimationTrackEdit *> track_edits;
Vector<AnimationTrackEditGroup *> groups;
- bool block_animation_update;
-
int _get_track_selected();
void _animation_changed();
void _update_tracks();
diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp
index 399d561e28..baf417fed7 100644
--- a/editor/animation_track_editor_plugins.cpp
+++ b/editor/animation_track_editor_plugins.cpp
@@ -1004,12 +1004,10 @@ void AnimationTrackEditTypeAudio::drop_data(const Point2 &p_point, const Variant
ofs += 0.001;
}
- *get_block_animation_update_ptr() = true;
get_undo_redo()->create_action(TTR("Add Audio Track Clip"));
get_undo_redo()->add_do_method(get_animation().ptr(), "audio_track_insert_key", get_track(), ofs, stream);
get_undo_redo()->add_undo_method(get_animation().ptr(), "track_remove_key_at_position", get_track(), ofs);
get_undo_redo()->commit_action();
- *get_block_animation_update_ptr() = false;
update();
return;
@@ -1098,21 +1096,17 @@ void AnimationTrackEditTypeAudio::_gui_input(const Ref<InputEvent> &p_event) {
float ofs_local = -len_resizing_rel / get_timeline()->get_zoom_scale();
if (len_resizing_start) {
float prev_ofs = get_animation()->audio_track_get_key_start_offset(get_track(), len_resizing_index);
- *get_block_animation_update_ptr() = true;
get_undo_redo()->create_action(TTR("Change Audio Track Clip Start Offset"));
get_undo_redo()->add_do_method(get_animation().ptr(), "audio_track_set_key_start_offset", get_track(), len_resizing_index, prev_ofs + ofs_local);
get_undo_redo()->add_undo_method(get_animation().ptr(), "audio_track_set_key_start_offset", get_track(), len_resizing_index, prev_ofs);
get_undo_redo()->commit_action();
- *get_block_animation_update_ptr() = false;
} else {
float prev_ofs = get_animation()->audio_track_get_key_end_offset(get_track(), len_resizing_index);
- *get_block_animation_update_ptr() = true;
get_undo_redo()->create_action(TTR("Change Audio Track Clip End Offset"));
get_undo_redo()->add_do_method(get_animation().ptr(), "audio_track_set_key_end_offset", get_track(), len_resizing_index, prev_ofs + ofs_local);
get_undo_redo()->add_undo_method(get_animation().ptr(), "audio_track_set_key_end_offset", get_track(), len_resizing_index, prev_ofs);
get_undo_redo()->commit_action();
- *get_block_animation_update_ptr() = false;
}
len_resizing = false;
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index b36afaef88..07dfcaa917 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -5659,7 +5659,6 @@ EditorNode::EditorNode() {
filesystem_dock = memnew(FileSystemDock(this));
filesystem_dock->connect("open", this, "open_request");
- filesystem_dock->set_file_list_display_mode(FileSystemDock::FILE_LIST_DISPLAY_LIST);
filesystem_dock->connect("instance", this, "_instance_request");
filesystem_dock->connect("display_mode_changed", this, "_save_docks");
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 9bd6063a71..66deb42c11 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -302,6 +302,8 @@ void FileSystemDock::_notification(int p_what) {
always_show_folders = bool(EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders"));
+ set_file_list_display_mode(FileSystemDock::FILE_LIST_DISPLAY_LIST);
+
_update_display_mode();
if (EditorFileSystem::get_singleton()->is_scanning()) {
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index 652f1ebac9..44eaf3d9ef 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -176,7 +176,7 @@ Error ColladaImport::_create_scene_skeletons(Collada::Node *p_node) {
Skeleton *sk = memnew(Skeleton);
int bone = 0;
-
+ sk->set_use_bones_in_world_transform(true); // This improves compatibility in Collada
for (int i = 0; i < p_node->children.size(); i++) {
_populate_skeleton(sk, p_node->children[i], bone, -1);
diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp
index 3909d437e5..7032146229 100644
--- a/editor/import/editor_scene_importer_gltf.cpp
+++ b/editor/import/editor_scene_importer_gltf.cpp
@@ -2121,6 +2121,7 @@ Spatial *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, int p_bake_f
Vector<Skeleton *> skeletons;
for (int i = 0; i < state.skins.size(); i++) {
Skeleton *s = memnew(Skeleton);
+ s->set_use_bones_in_world_transform(false); //GLTF does not need this since meshes are always local
String name = state.skins[i].name;
if (name == "") {
name = _gen_unique_name(state, "Skeleton");
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index 98871ddec3..cff9ba55b8 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -329,10 +329,15 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
if (!argument_types[i].is_type(*p_args[i], true)) {
- r_err.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_err.argument = i;
- r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT;
- return Variant();
+ if (argument_types[i].is_type(Variant(), true)) {
+ memnew_placement(&stack[i], Variant);
+ continue;
+ } else {
+ r_err.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_err.argument = i;
+ r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT;
+ return Variant();
+ }
}
if (argument_types[i].kind == GDScriptDataType::BUILTIN) {
Variant arg = Variant::construct(argument_types[i].builtin_type, &p_args[i], 1, r_err);
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 36b6a0dec6..aff39f0b07 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -2086,7 +2086,7 @@ GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) {
return NULL;
}
pattern->pt_type = GDScriptParser::PatternNode::PT_BIND;
- pattern->bind = tokenizer->get_token_identifier();
+ pattern->bind = tokenizer->get_token_literal();
// Check if variable name is already used
BlockNode *bl = current_block;
while (bl) {
@@ -7853,13 +7853,16 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
return;
}
- if (!lh_type.has_type && check_types) {
- if (op->arguments[0]->type == Node::TYPE_OPERATOR) {
- _mark_line_as_unsafe(op->line);
+ if (check_types) {
+ if (!lh_type.has_type) {
+ if (op->arguments[0]->type == Node::TYPE_OPERATOR) {
+ _mark_line_as_unsafe(op->line);
+ }
+ }
+ if (lh_type.is_constant) {
+ _set_error("Cannot assign a new value to a constant.", op->line);
+ return;
}
- } else if (lh_type.is_constant) {
- _set_error("Cannot assign a new value to a constant.", op->line);
- return;
}
DataType rh_type;
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 61aeb3ec93..bace65e772 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -298,6 +298,16 @@ void OS_Windows::_drag_event(float p_x, float p_y, int idx) {
LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
+ if (drop_events) {
+
+ if (user_proc) {
+
+ return CallWindowProcW(user_proc, hWnd, uMsg, wParam, lParam);
+ } else {
+ return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+ }
+ };
+
switch (uMsg) // Check For Windows Messages
{
case WM_SETFOCUS: {
@@ -2230,7 +2240,9 @@ void OS_Windows::process_events() {
MSG msg;
- joypad->process_joypads();
+ if (!drop_events) {
+ joypad->process_joypads();
+ }
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
@@ -2238,7 +2250,9 @@ void OS_Windows::process_events() {
DispatchMessageW(&msg);
}
- process_key_events();
+ if (!drop_events) {
+ process_key_events();
+ }
}
void OS_Windows::set_cursor_shape(CursorShape p_shape) {
@@ -2987,6 +3001,13 @@ bool OS_Windows::is_disable_crash_handler() const {
return crash_handler.is_disabled();
}
+void OS_Windows::process_and_drop_events() {
+
+ drop_events = true;
+ process_events();
+ drop_events = false;
+}
+
Error OS_Windows::move_to_trash(const String &p_path) {
SHFILEOPSTRUCTW sf;
WCHAR *from = new WCHAR[p_path.length() + 2];
@@ -3015,6 +3036,7 @@ Error OS_Windows::move_to_trash(const String &p_path) {
OS_Windows::OS_Windows(HINSTANCE _hInstance) {
+ drop_events = false;
key_event_pos = 0;
layered_window = false;
hBitmap = NULL;
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 6c257016ec..2d03532c69 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -127,6 +127,7 @@ class OS_Windows : public OS {
bool window_has_focus;
uint32_t last_button_state;
bool use_raw_input;
+ bool drop_events;
HCURSOR cursors[CURSOR_MAX] = { NULL };
CursorShape cursor_shape;
@@ -330,6 +331,8 @@ public:
virtual Error move_to_trash(const String &p_path);
+ virtual void process_and_drop_events();
+
OS_Windows(HINSTANCE _hInstance);
~OS_Windows();
};
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index ab1eed0859..05214ed669 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -1104,10 +1104,10 @@ void RigidBody::_reload_physics_characteristics() {
//////////////////////////////////////////////////////
//////////////////////////
-Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_test_only) {
+Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only) {
Collision col;
- if (move_and_collide(p_motion, p_infinite_inertia, col, p_test_only)) {
+ if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_test_only)) {
if (motion_cache.is_null()) {
motion_cache.instance();
motion_cache->owner = this;
@@ -1121,11 +1121,11 @@ Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_inf
return Ref<KinematicCollision>();
}
-bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_test_only) {
+bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) {
Transform gt = get_global_transform();
PhysicsServer::MotionResult result;
- bool colliding = PhysicsServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, &result);
+ bool colliding = PhysicsServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, &result, p_exclude_raycast_shapes);
if (colliding) {
r_collision.collider_metadata = result.collider_metadata;
@@ -1280,7 +1280,7 @@ Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity
Collision col;
Transform gt = get_global_transform();
- if (move_and_collide(p_snap, p_infinite_inertia, col, true)) {
+ if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) {
bool apply = true;
if (p_floor_direction != Vector3()) {
@@ -1415,7 +1415,7 @@ Ref<KinematicCollision> KinematicBody::_get_slide_collision(int p_bounce) {
void KinematicBody::_bind_methods() {
- ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "test_only"), &KinematicBody::_move, DEFVAL(true), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false));
ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index 5570d0c86b..589af98062 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -310,14 +310,14 @@ private:
_FORCE_INLINE_ bool _ignores_mode(PhysicsServer::BodyMode) const;
- Ref<KinematicCollision> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_test_only = false);
+ Ref<KinematicCollision> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false);
Ref<KinematicCollision> _get_slide_collision(int p_bounce);
protected:
static void _bind_methods();
public:
- bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collisionz, bool p_test_only = false);
+ bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collisionz, bool p_exclude_raycast_shapes = true, bool p_test_only = false);
bool test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia);
bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision);
diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp
index ceea50f74a..b7279e4d4f 100644
--- a/scene/3d/skeleton.cpp
+++ b/scene/3d/skeleton.cpp
@@ -198,11 +198,7 @@ void Skeleton::_notification(int p_what) {
case NOTIFICATION_ENTER_WORLD: {
- if (dirty) {
-
- dirty = false;
- _make_dirty(); // property make it dirty
- }
+ VS::get_singleton()->skeleton_set_world_transform(skeleton, use_bones_in_world_transform, get_global_transform());
} break;
case NOTIFICATION_EXIT_WORLD: {
@@ -210,21 +206,7 @@ void Skeleton::_notification(int p_what) {
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
- if (dirty)
- break; //will be eventually updated
-
- //if moved, just update transforms
- VisualServer *vs = VisualServer::get_singleton();
- const Bone *bonesptr = bones.ptr();
- int len = bones.size();
- Transform global_transform = get_global_transform();
- Transform global_transform_inverse = global_transform.affine_inverse();
-
- for (int i = 0; i < len; i++) {
-
- const Bone &b = bonesptr[i];
- vs->skeleton_bone_set_transform(skeleton, i, global_transform * (b.transform_final * global_transform_inverse));
- }
+ VS::get_singleton()->skeleton_set_world_transform(skeleton, use_bones_in_world_transform, get_global_transform());
} break;
case NOTIFICATION_UPDATE_SKELETON: {
@@ -257,9 +239,6 @@ void Skeleton::_notification(int p_what) {
rest_global_inverse_dirty = false;
}
- Transform global_transform = get_global_transform();
- Transform global_transform_inverse = global_transform.affine_inverse();
-
for (int i = 0; i < len; i++) {
Bone &b = bonesptr[order[i]];
@@ -320,7 +299,7 @@ void Skeleton::_notification(int p_what) {
}
b.transform_final = b.pose_global * b.rest_global_inverse;
- vs->skeleton_bone_set_transform(skeleton, order[i], global_transform * (b.transform_final * global_transform_inverse));
+ vs->skeleton_bone_set_transform(skeleton, order[i], b.transform_final);
for (List<uint32_t>::Element *E = b.nodes_bound.front(); E; E = E->next()) {
@@ -594,10 +573,6 @@ void Skeleton::_make_dirty() {
if (dirty)
return;
- if (!is_inside_tree()) {
- dirty = true;
- return;
- }
MessageQueue::get_singleton()->push_notification(this, NOTIFICATION_UPDATE_SKELETON);
dirty = true;
}
@@ -771,6 +746,16 @@ void Skeleton::physical_bones_remove_collision_exception(RID p_exception) {
#endif // _3D_DISABLED
+void Skeleton::set_use_bones_in_world_transform(bool p_enable) {
+ use_bones_in_world_transform = p_enable;
+ if (is_inside_tree()) {
+ VS::get_singleton()->skeleton_set_world_transform(skeleton, use_bones_in_world_transform, get_global_transform());
+ }
+}
+bool Skeleton::is_using_bones_in_world_transform() const {
+ return use_bones_in_world_transform;
+}
+
void Skeleton::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_bone", "name"), &Skeleton::add_bone);
@@ -807,6 +792,9 @@ void Skeleton::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_bone_transform", "bone_idx"), &Skeleton::get_bone_transform);
+ ClassDB::bind_method(D_METHOD("set_use_bones_in_world_transform", "enable"), &Skeleton::set_use_bones_in_world_transform);
+ ClassDB::bind_method(D_METHOD("is_using_bones_in_world_transform"), &Skeleton::is_using_bones_in_world_transform);
+
#ifndef _3D_DISABLED
ClassDB::bind_method(D_METHOD("physical_bones_stop_simulation"), &Skeleton::physical_bones_stop_simulation);
@@ -818,6 +806,7 @@ void Skeleton::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bone_ignore_animation", "bone", "ignore"), &Skeleton::set_bone_ignore_animation);
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bones_in_world_transform"), "set_use_bones_in_world_transform", "is_using_bones_in_world_transform");
BIND_CONSTANT(NOTIFICATION_UPDATE_SKELETON);
}
@@ -828,6 +817,7 @@ Skeleton::Skeleton() {
process_order_dirty = true;
skeleton = VisualServer::get_singleton()->skeleton_create();
set_notify_transform(true);
+ use_bones_in_world_transform = false;
}
Skeleton::~Skeleton() {
diff --git a/scene/3d/skeleton.h b/scene/3d/skeleton.h
index 0f463c9ea7..5f43b3c6c3 100644
--- a/scene/3d/skeleton.h
+++ b/scene/3d/skeleton.h
@@ -100,6 +100,7 @@ class Skeleton : public Spatial {
void _make_dirty();
bool dirty;
+ bool use_bones_in_world_transform;
// bind helpers
Array _get_bound_child_nodes_to_bone(int p_bone) const {
@@ -179,6 +180,9 @@ public:
void localize_rests(); // used for loaders and tools
int get_process_order(int p_idx);
+ void set_use_bones_in_world_transform(bool p_enable);
+ bool is_using_bones_in_world_transform() const;
+
#ifndef _3D_DISABLED
// Physical bone API
diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp
index 2579321773..7f1ca58d58 100644
--- a/scene/gui/container.cpp
+++ b/scene/gui/container.cpp
@@ -169,6 +169,19 @@ void Container::_notification(int p_what) {
}
}
+String Container::get_configuration_warning() const {
+
+ String warning = Control::get_configuration_warning();
+
+ if (get_class() == "Container" && get_script().is_null()) {
+ if (warning != String()) {
+ warning += "\n";
+ }
+ warning += TTR("Container by itself serves no purpose unless a script configures it's children placement behavior.\nIf you dont't intend to add a script, then please use a plain 'Control' node instead.");
+ }
+ return warning;
+}
+
void Container::_bind_methods() {
ClassDB::bind_method(D_METHOD("_sort_children"), &Container::_sort_children);
diff --git a/scene/gui/container.h b/scene/gui/container.h
index 0b014137f4..80d3f6ee5d 100644
--- a/scene/gui/container.h
+++ b/scene/gui/container.h
@@ -57,6 +57,8 @@ public:
void fit_child_in_rect(Control *p_child, const Rect2 &p_rect);
+ virtual String get_configuration_warning() const;
+
Container();
};
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 99440ff202..626ed9f5b4 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -177,8 +177,8 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
node = Object::cast_to<Node>(obj);
} else {
- print_line("Class is disabled for: " + itos(n.type));
- print_line("name: " + String(snames[n.type]));
+ //print_line("Class is disabled for: " + itos(n.type));
+ //print_line("name: " + String(snames[n.type]));
}
if (node) {
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 8502ef5bf7..dd54698471 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -355,6 +355,7 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) = 0;
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0;
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0;
+ virtual void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform) = 0;
/* Light API */
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 6622433b17..a9ca920178 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -123,7 +123,6 @@ void VisualServerRaster::draw(bool p_swap_buffers, double frame_step) {
frame_drawn_callbacks.pop_front();
}
-
VS::get_singleton()->emit_signal("frame_post_draw");
}
void VisualServerRaster::sync() {
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 89a759b963..a1204c7573 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -296,6 +296,7 @@ public:
BIND3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &)
BIND2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int)
BIND2(skeleton_set_base_transform_2d, RID, const Transform2D &)
+ BIND3(skeleton_set_world_transform, RID, bool, const Transform &)
/* Light API */
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index a6f0bd9d16..c6da6799a5 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -232,6 +232,7 @@ public:
FUNC3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &)
FUNC2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int)
FUNC2(skeleton_set_base_transform_2d, RID, const Transform2D &)
+ FUNC3(skeleton_set_world_transform, RID, bool, const Transform &)
/* Light API */
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 96a5d19efd..63ddc3328a 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -393,6 +393,7 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) = 0;
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0;
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0;
+ virtual void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_base_transform) = 0;
/* Light API */