diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/animation_track_editor.cpp | 48 | ||||
-rw-r--r-- | editor/icons/KeyBlendShape.svg | 44 | ||||
-rw-r--r-- | editor/icons/KeyTrackBlendShape.svg | 45 | ||||
-rw-r--r-- | editor/import/editor_import_collada.cpp | 4 | ||||
-rw-r--r-- | editor/import/resource_importer_scene.cpp | 145 | ||||
-rw-r--r-- | editor/import/resource_importer_scene.h | 1 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.cpp | 20 |
7 files changed, 244 insertions, 63 deletions
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 2ee7f0ffa5..7f118532c9 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -198,6 +198,7 @@ public: } } break; + case Animation::TYPE_BLEND_SHAPE: case Animation::TYPE_VALUE: { if (name == "value") { Variant value = p_value; @@ -438,6 +439,7 @@ public: return true; } } break; + case Animation::TYPE_BLEND_SHAPE: case Animation::TYPE_VALUE: { if (name == "value") { r_ret = animation->track_get_key_value(track, key); @@ -551,6 +553,9 @@ public: case Animation::TYPE_SCALE_3D: { p_list->push_back(PropertyInfo(Variant::VECTOR3, "scale")); } break; + case Animation::TYPE_BLEND_SHAPE: { + p_list->push_back(PropertyInfo(Variant::FLOAT, "value")); + } break; case Animation::TYPE_VALUE: { Variant v = animation->track_get_key_value(track, key); @@ -828,6 +833,7 @@ public: undo_redo->add_undo_method(animation.ptr(), "track_set_key_value", track, key, old); update_obj = true; } break; + case Animation::TYPE_BLEND_SHAPE: case Animation::TYPE_VALUE: { if (name == "value") { Variant value = p_value; @@ -1054,6 +1060,7 @@ public: } } break; + case Animation::TYPE_BLEND_SHAPE: case Animation::TYPE_VALUE: { if (name == "value") { r_ret = animation->track_get_key_value(track, key); @@ -1206,6 +1213,9 @@ public: case Animation::TYPE_SCALE_3D: { p_list->push_back(PropertyInfo(Variant::VECTOR3, "scale")); } break; + case Animation::TYPE_BLEND_SHAPE: { + p_list->push_back(PropertyInfo(Variant::FLOAT, "value")); + } break; case Animation::TYPE_VALUE: { if (same_key_type) { Variant v = animation->track_get_key_value(first_track, first_key); @@ -1404,6 +1414,7 @@ void AnimationTimelineEdit::_notification(int p_what) { add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyXPosition"), SNAME("EditorIcons")), TTR("3D Position Track")); add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyXRotation"), SNAME("EditorIcons")), TTR("3D Rotation Track")); add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyXScale"), SNAME("EditorIcons")), TTR("3D Scale Track")); + add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyBlendShape"), SNAME("EditorIcons")), TTR("Blend Shape Track")); add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyCall"), SNAME("EditorIcons")), TTR("Call Method Track")); add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyBezier"), SNAME("EditorIcons")), TTR("Bezier Curve Track")); add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyAudio"), SNAME("EditorIcons")), TTR("Audio Playback Track")); @@ -1872,11 +1883,12 @@ void AnimationTrackEdit::_notification(int p_what) { Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); Color color = get_theme_color(SNAME("font_color"), SNAME("Label")); - Ref<Texture2D> type_icons[8] = { + Ref<Texture2D> type_icons[9] = { get_theme_icon(SNAME("KeyValue"), SNAME("EditorIcons")), get_theme_icon(SNAME("KeyTrackPosition"), SNAME("EditorIcons")), get_theme_icon(SNAME("KeyTrackRotation"), SNAME("EditorIcons")), get_theme_icon(SNAME("KeyTrackScale"), SNAME("EditorIcons")), + get_theme_icon(SNAME("KeyTrackBlendShape"), SNAME("EditorIcons")), get_theme_icon(SNAME("KeyCall"), SNAME("EditorIcons")), get_theme_icon(SNAME("KeyBezier"), SNAME("EditorIcons")), get_theme_icon(SNAME("KeyAudio"), SNAME("EditorIcons")), @@ -2067,7 +2079,7 @@ void AnimationTrackEdit::_notification(int p_what) { interp_mode_rect.position.y = int(get_size().height - icon->get_height()) / 2; interp_mode_rect.size = icon->get_size(); - if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D) { + if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_BLEND_SHAPE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D) { draw_texture(icon, interp_mode_rect.position); } // Make it easier to click. @@ -2077,7 +2089,7 @@ void AnimationTrackEdit::_notification(int p_what) { ofs += icon->get_width() + hsep; interp_mode_rect.size.x += hsep; - if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D) { + if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_BLEND_SHAPE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D) { draw_texture(down_icon, Vector2(ofs, int(get_size().height - down_icon->get_height()) / 2)); interp_mode_rect.size.x += down_icon->get_width(); } else { @@ -2100,7 +2112,7 @@ void AnimationTrackEdit::_notification(int p_what) { loop_mode_rect.position.y = int(get_size().height - icon->get_height()) / 2; loop_mode_rect.size = icon->get_size(); - if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D) { + if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_BLEND_SHAPE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D) { draw_texture(icon, loop_mode_rect.position); } @@ -2110,7 +2122,7 @@ void AnimationTrackEdit::_notification(int p_what) { ofs += icon->get_width() + hsep; loop_mode_rect.size.x += hsep; - if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D) { + if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_BLEND_SHAPE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D) { draw_texture(down_icon, Vector2(ofs, int(get_size().height - down_icon->get_height()) / 2)); loop_mode_rect.size.x += down_icon->get_width(); } else { @@ -2330,11 +2342,12 @@ void AnimationTrackEdit::set_animation_and_track(const Ref<Animation> &p_animati track = p_track; update(); - Ref<Texture2D> type_icons[8] = { + Ref<Texture2D> type_icons[9] = { get_theme_icon(SNAME("KeyValue"), SNAME("EditorIcons")), get_theme_icon(SNAME("KeyXPosition"), SNAME("EditorIcons")), get_theme_icon(SNAME("KeyXRotation"), SNAME("EditorIcons")), get_theme_icon(SNAME("KeyXScale"), SNAME("EditorIcons")), + get_theme_icon(SNAME("KeyBlendShape"), SNAME("EditorIcons")), get_theme_icon(SNAME("KeyCall"), SNAME("EditorIcons")), get_theme_icon(SNAME("KeyBezier"), SNAME("EditorIcons")), get_theme_icon(SNAME("KeyAudio"), SNAME("EditorIcons")), @@ -2516,6 +2529,10 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const { Vector3 t = animation->track_get_key_value(track, key_idx); text += "Scale: " + String(t) + "\n"; } break; + case Animation::TYPE_BLEND_SHAPE: { + float t = animation->track_get_key_value(track, key_idx); + text += "Blend Shape: " + itos(t) + "\n"; + } break; case Animation::TYPE_VALUE: { const Variant &v = animation->track_get_key_value(track, key_idx); text += "Type: " + Variant::get_type_name(v.get_type()) + "\n"; @@ -3369,6 +3386,8 @@ static bool track_type_is_resettable(Animation::TrackType p_type) { switch (p_type) { case Animation::TYPE_VALUE: [[fallthrough]]; + case Animation::TYPE_BLEND_SHAPE: + [[fallthrough]]; case Animation::TYPE_BEZIER: [[fallthrough]]; case Animation::TYPE_POSITION_3D: @@ -4049,6 +4068,7 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD case Animation::TYPE_POSITION_3D: case Animation::TYPE_ROTATION_3D: case Animation::TYPE_SCALE_3D: + case Animation::TYPE_BLEND_SHAPE: case Animation::TYPE_VALUE: { value = p_id.value; @@ -4468,6 +4488,11 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) { ERR_FAIL_COND(!node); NodePath path_to = root->get_path_to(node); + if (adding_track_type == Animation::TYPE_BLEND_SHAPE && !node->is_class("MeshInstance3D")) { + EditorNode::get_singleton()->show_warning(TTR("Blend Shape tracks only apply to MeshInstance3D nodes.")); + return; + } + if ((adding_track_type == Animation::TYPE_POSITION_3D || adding_track_type == Animation::TYPE_ROTATION_3D || adding_track_type == Animation::TYPE_SCALE_3D) && !node->is_class("Node3D")) { EditorNode::get_singleton()->show_warning(TTR("Position/Rotation/Scale 3D tracks only apply to 3D-based nodes.")); return; @@ -4479,6 +4504,13 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) { prop_selector->set_type_filter(Vector<Variant::Type>()); prop_selector->select_property_from_instance(node); } break; + case Animation::TYPE_BLEND_SHAPE: { + adding_track_path = path_to; + Vector<Variant::Type> filter; + filter.push_back(Variant::FLOAT); + prop_selector->set_type_filter(filter); + prop_selector->select_property_from_instance(node); + } break; case Animation::TYPE_POSITION_3D: case Animation::TYPE_ROTATION_3D: case Animation::TYPE_SCALE_3D: @@ -4710,6 +4742,7 @@ void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) { undo_redo->commit_action(); } break; + case Animation::TYPE_BLEND_SHAPE: case Animation::TYPE_VALUE: { NodePath bp; Variant value; @@ -5388,6 +5421,9 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { case Animation::TYPE_SCALE_3D: text += " (Scale)"; break; + case Animation::TYPE_BLEND_SHAPE: + text += " (BlendShape)"; + break; case Animation::TYPE_METHOD: text += " (Methods)"; break; diff --git a/editor/icons/KeyBlendShape.svg b/editor/icons/KeyBlendShape.svg new file mode 100644 index 0000000000..42f7341942 --- /dev/null +++ b/editor/icons/KeyBlendShape.svg @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + height="10" + viewBox="0 0 10 10" + width="10" + version="1.1" + id="svg80" + sodipodi:docname="KeyBlendShape.svg" + inkscape:version="1.1 (1:1.1+202106031931+af4d65493e)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <defs + id="defs84" /> + <sodipodi:namedview + id="namedview82" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + showgrid="false" + inkscape:zoom="84.4" + inkscape:cx="2.6599526" + inkscape:cy="5.0059242" + inkscape:window-width="1848" + inkscape:window-height="1016" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="svg80" /> + <rect + fill="#3cf34e" + height="6.1027" + ry=".76286" + transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" + width="6.1027" + x="-740.13947" + y="741.10779" + id="rect78" + style="fill:#5ad5c4;fill-opacity:1" /> +</svg> diff --git a/editor/icons/KeyTrackBlendShape.svg b/editor/icons/KeyTrackBlendShape.svg new file mode 100644 index 0000000000..e82f0d6a6f --- /dev/null +++ b/editor/icons/KeyTrackBlendShape.svg @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + height="10" + viewBox="0 0 10 10" + width="10" + version="1.1" + id="svg12" + sodipodi:docname="KeyTrackBlendShape.svg" + inkscape:version="1.1 (1:1.1+202106031931+af4d65493e)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <defs + id="defs16" /> + <sodipodi:namedview + id="namedview14" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + showgrid="false" + inkscape:zoom="29.839906" + inkscape:cx="-3.5690461" + inkscape:cy="9.0985541" + inkscape:window-width="1848" + inkscape:window-height="1016" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="svg12" /> + <ellipse + style="fill:none;fill-opacity:0.401212;stroke:none;stroke-width:4.7811;stroke-linejoin:round" + id="path921" + cx="-0.88986981" + cy="6.0959954" + rx="1.2495773" + ry="1.0867468" /> + <path + id="path1910" + style="color:#000000;fill:#5ad5c4;stroke-linejoin:round;-inkscape-stroke:none" + d="m 4.5230825,1.1341567 c -2.1310744,0.017055 -3.86718737,1.7635044 -3.86718737,3.8984375 0,1.8778511 1.34348597,3.4523891 3.11718737,3.8164061 L 3.95277,7.5794693 C 2.7929991,7.3095662 1.9351921,6.2780435 1.9351921,5.0325942 c 0,-1.4262775 1.123493,-2.5732858 2.5390622,-2.6152344 v 0.017578 h 0.2011719 l 0.1796875,-1.28125 H 4.5230825 v -0.011719 c 0,-0.00263 -2.64e-5,-0.00518 0,-0.00781 z m 1.6816406,0.019531 -0.1796875,1.28125 h 1.3085937 c 0.078866,0 0.1230469,0.044181 0.1230469,0.1230469 v 4.9882815 c 0,0.07887 -0.044181,0.121093 -0.1230469,0.121094 H 5.2887075 L 5.10902,8.9486103 h 2.2246093 c 0.7663818,0 1.4042969,-0.635962 1.4042969,-1.402344 V 2.5579848 c 0,-0.7663818 -0.637915,-1.4042969 -1.4042969,-1.4042969 z" /> +</svg> diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index 52be03a1b1..ac8adedf2f 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -1710,7 +1710,7 @@ void ColladaImport::create_animation(int p_clip, bool p_import_value_tracks) { NodeMap &nm = node_map[at.target]; String path = scene->get_path_to(nm.node); - animation->add_track(Animation::TYPE_VALUE); + animation->add_track(Animation::TYPE_BLEND_SHAPE); int track = animation->get_track_count() - 1; path = path + ":" + at.param; @@ -1732,7 +1732,7 @@ void ColladaImport::create_animation(int p_clip, bool p_import_value_tracks) { WARN_PRINT("Collada: Unexpected amount of value keys: " + itos(data.size())); } - animation->track_insert_key(track, time, value); + animation->blend_shape_track_insert_key(track, time, value); } tracks_found = true; diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index c393d7f5fc..319e5ee25f 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -1036,6 +1036,10 @@ void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_ } else if (default_anim->track_get_type(j) == Animation::TYPE_VALUE) { Variant var = default_anim->value_track_interpolate(j, from); new_anim->track_insert_key(dtrack, 0, var); + } else if (default_anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) { + float interp; + default_anim->blend_shape_track_interpolate(j, from, &interp); + new_anim->blend_shape_track_insert_key(dtrack, 0, interp); } } } @@ -1055,6 +1059,10 @@ void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_ } else if (default_anim->track_get_type(j) == Animation::TYPE_VALUE) { Variant var = default_anim->track_get_key_value(j, k); new_anim->track_insert_key(dtrack, kt - from, var); + } else if (default_anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) { + float interp; + default_anim->blend_shape_track_get_key(j, k, &interp); + new_anim->blend_shape_track_insert_key(dtrack, kt - from, interp); } } @@ -1074,6 +1082,10 @@ void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_ } else if (default_anim->track_get_type(j) == Animation::TYPE_VALUE) { Variant var = default_anim->value_track_interpolate(j, to); new_anim->track_insert_key(dtrack, to - from, var); + } else if (default_anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) { + float interp; + default_anim->blend_shape_track_interpolate(j, to, &interp); + new_anim->blend_shape_track_insert_key(dtrack, to - from, interp); } } } @@ -1105,6 +1117,12 @@ void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_ new_anim->track_insert_key(dtrack, 0, var); Variant to_var = default_anim->value_track_interpolate(j, to); new_anim->track_insert_key(dtrack, to - from, to_var); + } else if (default_anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) { + float interp; + default_anim->blend_shape_track_interpolate(j, from, &interp); + new_anim->blend_shape_track_insert_key(dtrack, 0, interp); + default_anim->blend_shape_track_interpolate(j, to, &interp); + new_anim->blend_shape_track_insert_key(dtrack, to - from, interp); } } } @@ -1652,7 +1670,7 @@ void ResourceImporterScene::_optimize_track_usage(AnimationPlayer *p_player, Ani ERR_FAIL_COND(parent == nullptr); OrderedHashMap<NodePath, uint32_t> used_tracks[TRACK_CHANNEL_MAX]; bool tracks_to_add = false; - static const Animation::TrackType track_types[TRACK_CHANNEL_MAX] = { Animation::TYPE_POSITION_3D, Animation::TYPE_ROTATION_3D, Animation::TYPE_SCALE_3D }; + static const Animation::TrackType track_types[TRACK_CHANNEL_MAX] = { Animation::TYPE_POSITION_3D, Animation::TYPE_ROTATION_3D, Animation::TYPE_SCALE_3D, Animation::TYPE_BLEND_SHAPE }; for (const StringName &I : anims) { Ref<Animation> anim = p_player->get_animation(I); for (int i = 0; i < anim->get_track_count(); i++) { @@ -1710,67 +1728,84 @@ void ResourceImporterScene::_optimize_track_usage(AnimationPlayer *p_player, Ani NodePath path = J.key(); Node *n = parent->get_node(path); - Skeleton3D *skel = Object::cast_to<Skeleton3D>(n); - Node3D *n3d = Object::cast_to<Node3D>(n); - Vector3 loc; - Quaternion rot; - Vector3 scale; - if (skel && path.get_subname_count() > 0) { - StringName bone = path.get_subname(0); - int bone_idx = skel->find_bone(bone); - if (bone_idx == -1) { - continue; + + if (j == TRACK_CHANNEL_BLEND_SHAPE) { + MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(n); + if (mi && path.get_subname_count() > 0) { + StringName bs = path.get_subname(0); + bool valid; + float value = mi->get(bs, &valid); + if (valid) { + int track_idx = anim->add_track(track_types[j]); + anim->track_set_path(track_idx, path); + anim->track_set_imported(track_idx, true); + anim->blend_shape_track_insert_key(track_idx, 0, value); + } } - skel->get_bone_pose(bone_idx); - loc = skel->get_bone_pose_position(bone_idx); - rot = skel->get_bone_pose_rotation(bone_idx); - scale = skel->get_bone_pose_scale(bone_idx); - } else if (n3d) { - loc = n3d->get_position(); - rot = n3d->get_transform().basis.get_rotation_quaternion(); - scale = n3d->get_scale(); + } else { - continue; - } + Skeleton3D *skel = Object::cast_to<Skeleton3D>(n); + Node3D *n3d = Object::cast_to<Node3D>(n); + Vector3 loc; + Quaternion rot; + Vector3 scale; + if (skel && path.get_subname_count() > 0) { + StringName bone = path.get_subname(0); + int bone_idx = skel->find_bone(bone); + if (bone_idx == -1) { + continue; + } + skel->get_bone_pose(bone_idx); + loc = skel->get_bone_pose_position(bone_idx); + rot = skel->get_bone_pose_rotation(bone_idx); + scale = skel->get_bone_pose_scale(bone_idx); + } else if (n3d) { + loc = n3d->get_position(); + rot = n3d->get_transform().basis.get_rotation_quaternion(); + scale = n3d->get_scale(); + } else { + continue; + } - // Ensure insertion keeps tracks together and ordered by type (loc/rot/scale) - int insert_at_pos = -1; - for (int k = 0; k < anim->get_track_count(); k++) { - NodePath tpath = anim->track_get_path(k); - - if (path == tpath) { - Animation::TrackType ttype = anim->track_get_type(k); - if (insert_at_pos == -1) { - // First insert, determine whether replacing or kicking back - if (track_types[j] < ttype) { - insert_at_pos = k; - break; // No point in continuing. - } else { + // Ensure insertion keeps tracks together and ordered by type (loc/rot/scale) + int insert_at_pos = -1; + for (int k = 0; k < anim->get_track_count(); k++) { + NodePath tpath = anim->track_get_path(k); + + if (path == tpath) { + Animation::TrackType ttype = anim->track_get_type(k); + if (insert_at_pos == -1) { + // First insert, determine whether replacing or kicking back + if (track_types[j] < ttype) { + insert_at_pos = k; + break; // No point in continuing. + } else { + insert_at_pos = k + 1; + } + } else if (ttype < track_types[j]) { + // Kick back. insert_at_pos = k + 1; } - } else if (ttype < track_types[j]) { - // Kick back. - insert_at_pos = k + 1; + } else if (insert_at_pos >= 0) { + break; } - } else if (insert_at_pos >= 0) { - break; } - } - int track_idx = anim->add_track(track_types[j], insert_at_pos); - - anim->track_set_path(track_idx, path); - anim->track_set_imported(track_idx, true); - switch (j) { - case TRACK_CHANNEL_POSITION: { - anim->position_track_insert_key(track_idx, 0, loc); - } break; - case TRACK_CHANNEL_ROTATION: { - anim->rotation_track_insert_key(track_idx, 0, rot); - } break; - case TRACK_CHANNEL_SCALE: { - anim->scale_track_insert_key(track_idx, 0, scale); - } break; - default: { + int track_idx = anim->add_track(track_types[j], insert_at_pos); + + anim->track_set_path(track_idx, path); + anim->track_set_imported(track_idx, true); + switch (j) { + case TRACK_CHANNEL_POSITION: { + anim->position_track_insert_key(track_idx, 0, loc); + } break; + case TRACK_CHANNEL_ROTATION: { + anim->rotation_track_insert_key(track_idx, 0, rot); + } break; + case TRACK_CHANNEL_SCALE: { + anim->scale_track_insert_key(track_idx, 0, scale); + } break; + default: { + } } } } diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index fab602b8ff..e1e7046be5 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -207,6 +207,7 @@ class ResourceImporterScene : public ResourceImporter { TRACK_CHANNEL_POSITION, TRACK_CHANNEL_ROTATION, TRACK_CHANNEL_SCALE, + TRACK_CHANNEL_BLEND_SHAPE, TRACK_CHANNEL_MAX }; diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index cc94449f78..32a8bbf406 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2226,6 +2226,21 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (ED_IS_SHORTCUT("spatial_editor/right_view", p_event)) { _menu_option(VIEW_RIGHT); } + if (ED_IS_SHORTCUT("spatial_editor/orbit_view_down", p_event)) { + cursor.x_rot -= Math_PI / 12.0; + } + if (ED_IS_SHORTCUT("spatial_editor/orbit_view_up", p_event)) { + cursor.x_rot += Math_PI / 12.0; + } + if (ED_IS_SHORTCUT("spatial_editor/orbit_view_right", p_event)) { + cursor.y_rot -= Math_PI / 12.0; + } + if (ED_IS_SHORTCUT("spatial_editor/orbit_view_left", p_event)) { + cursor.y_rot += Math_PI / 12.0; + } + if (ED_IS_SHORTCUT("spatial_editor/orbit_view_180", p_event)) { + cursor.y_rot += Math_PI; + } if (ED_IS_SHORTCUT("spatial_editor/focus_origin", p_event)) { _menu_option(VIEW_CENTER_TO_ORIGIN); } @@ -7306,6 +7321,11 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) { ED_SHORTCUT("spatial_editor/front_view", TTR("Front View"), KEY_KP_1); ED_SHORTCUT("spatial_editor/left_view", TTR("Left View"), KEY_MASK_ALT + KEY_KP_3); ED_SHORTCUT("spatial_editor/right_view", TTR("Right View"), KEY_KP_3); + ED_SHORTCUT("spatial_editor/orbit_view_down", TTR("Orbit View Down"), KEY_KP_2); + ED_SHORTCUT("spatial_editor/orbit_view_left", TTR("Orbit View Left"), KEY_KP_4); + ED_SHORTCUT("spatial_editor/orbit_view_right", TTR("Orbit View Right"), KEY_KP_6); + ED_SHORTCUT("spatial_editor/orbit_view_up", TTR("Orbit View Up"), KEY_KP_8); + ED_SHORTCUT("spatial_editor/orbit_view_180", TTR("Orbit View 180"), KEY_KP_9); ED_SHORTCUT("spatial_editor/switch_perspective_orthogonal", TTR("Switch Perspective/Orthogonal View"), KEY_KP_5); ED_SHORTCUT("spatial_editor/insert_anim_key", TTR("Insert Animation Key"), KEY_K); ED_SHORTCUT("spatial_editor/focus_origin", TTR("Focus Origin"), KEY_O); |