diff options
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 */ |