mirror of
https://github.com/godotengine/godot
synced 2024-09-05 17:09:44 +00:00
Implemented SkeletonEditorGizmo
Co-authored-by: Lyuma <xn.lyuma@gmail.com>
This commit is contained in:
parent
ce0268a0c1
commit
f2e9867e9f
|
@ -96,7 +96,7 @@
|
|||
</description>
|
||||
</method>
|
||||
<method name="_forward_3d_gui_input" qualifiers="virtual">
|
||||
<return type="bool" />
|
||||
<return type="int" />
|
||||
<argument index="0" name="viewport_camera" type="Camera3D" />
|
||||
<argument index="1" name="event" type="InputEvent" />
|
||||
<description>
|
||||
|
@ -105,13 +105,13 @@
|
|||
[gdscript]
|
||||
# Prevents the InputEvent to reach other Editor classes.
|
||||
func _forward_3d_gui_input(camera, event):
|
||||
return true
|
||||
return EditorPlugin.AFTER_GUI_INPUT_STOP
|
||||
[/gdscript]
|
||||
[csharp]
|
||||
// Prevents the InputEvent to reach other Editor classes.
|
||||
public override bool _Forward3dGuiInput(Camera3D camera, InputEvent @event)
|
||||
{
|
||||
return true;
|
||||
return EditorPlugin.AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
[/csharp]
|
||||
[/codeblocks]
|
||||
|
@ -185,12 +185,12 @@
|
|||
Called when there is a root node in the current edited scene, [method _handles] is implemented and an [InputEvent] happens in the 2D viewport. Intercepts the [InputEvent], if [code]return true[/code] [EditorPlugin] consumes the [code]event[/code], otherwise forwards [code]event[/code] to other Editor classes. Example:
|
||||
[codeblocks]
|
||||
[gdscript]
|
||||
# Prevents the InputEvent to reach other Editor classes
|
||||
# Prevents the InputEvent to reach other Editor classes.
|
||||
func _forward_canvas_gui_input(event):
|
||||
return true
|
||||
[/gdscript]
|
||||
[csharp]
|
||||
// Prevents the InputEvent to reach other Editor classes
|
||||
// Prevents the InputEvent to reach other Editor classes.
|
||||
public override bool ForwardCanvasGuiInput(InputEvent @event)
|
||||
{
|
||||
return true;
|
||||
|
@ -202,13 +202,18 @@
|
|||
[gdscript]
|
||||
# Consumes InputEventMouseMotion and forwards other InputEvent types.
|
||||
func _forward_canvas_gui_input(event):
|
||||
return event is InputEventMouseMotion
|
||||
if (event is InputEventMouseMotion):
|
||||
return true
|
||||
return false
|
||||
[/gdscript]
|
||||
[csharp]
|
||||
// Consumes InputEventMouseMotion and forwards other InputEvent types.
|
||||
public override bool ForwardCanvasGuiInput(InputEvent @event)
|
||||
{
|
||||
return @event is InputEventMouseMotion;
|
||||
if (@event is InputEventMouseMotion) {
|
||||
return true;
|
||||
}
|
||||
return false
|
||||
}
|
||||
[/csharp]
|
||||
[/codeblocks]
|
||||
|
|
|
@ -212,6 +212,15 @@
|
|||
Sets whether the node notifies about its global and local transformation changes. [Node3D] will not propagate this by default, unless it is in the editor context and it has a valid gizmo.
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_subgizmo_selection">
|
||||
<return type="void" />
|
||||
<argument index="0" name="gizmo" type="Node3DGizmo" />
|
||||
<argument index="1" name="id" type="int" />
|
||||
<argument index="2" name="transform" type="Transform3D" />
|
||||
<description>
|
||||
Set subgizmo selection for this node in the editor.
|
||||
</description>
|
||||
</method>
|
||||
<method name="show">
|
||||
<return type="void" />
|
||||
<description>
|
||||
|
|
|
@ -189,6 +189,13 @@
|
|||
This is helper function to make using [method Transform3D.looking_at] easier with bone poses.
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_bone_enabled" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<argument index="0" name="bone_idx" type="int" />
|
||||
<description>
|
||||
Returns whether the bone pose for the bone at [code]bone_idx[/code] is enabled.
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_bone_rest_disabled" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<argument index="0" name="bone_idx" type="int" />
|
||||
|
@ -282,6 +289,14 @@
|
|||
Disables the rest pose for the bone at [code]bone_idx[/code] if [code]true[/code], enables the bone rest if [code]false[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_bone_enabled">
|
||||
<return type="void" />
|
||||
<argument index="0" name="bone_idx" type="int" />
|
||||
<argument index="1" name="enabled" type="bool" default="true" />
|
||||
<description>
|
||||
Disables the pose for the bone at [code]bone_idx[/code] if [code]false[/code], enables the bone pose if [code]true[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_bone_global_pose_override">
|
||||
<return type="void" />
|
||||
<argument index="0" name="bone_idx" type="int" />
|
||||
|
@ -365,8 +380,15 @@
|
|||
<members>
|
||||
<member name="animate_physical_bones" type="bool" setter="set_animate_physical_bones" getter="get_animate_physical_bones" default="true">
|
||||
</member>
|
||||
<member name="show_rest_only" type="bool" setter="set_show_rest_only" getter="is_show_rest_only" default="false">
|
||||
</member>
|
||||
</members>
|
||||
<signals>
|
||||
<signal name="bone_enabled_changed">
|
||||
<argument index="0" name="bone_idx" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="bone_pose_changed">
|
||||
<argument index="0" name="bone_idx" type="int" />
|
||||
<description>
|
||||
|
@ -377,6 +399,10 @@
|
|||
<description>
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="show_rest_only_changed">
|
||||
<description>
|
||||
</description>
|
||||
</signal>
|
||||
</signals>
|
||||
<constants>
|
||||
<constant name="NOTIFICATION_UPDATE_SKELETON" value="50">
|
||||
|
|
|
@ -3359,7 +3359,7 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
|
|||
insert_data.push_back(p_id);
|
||||
|
||||
bool reset_allowed = true;
|
||||
AnimationPlayer *player = AnimationPlayerEditor::singleton->get_player();
|
||||
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
|
||||
if (player->has_animation("RESET") && player->get_animation("RESET") == animation) {
|
||||
// Avoid messing with the reset animation itself
|
||||
reset_allowed = false;
|
||||
|
@ -3528,6 +3528,31 @@ void AnimationTrackEditor::insert_transform_key(Node3D *p_node, const String &p_
|
|||
_query_insert(id);
|
||||
}
|
||||
|
||||
bool AnimationTrackEditor::has_transform_track(Node3D *p_node, const String &p_sub) {
|
||||
if (!keying) {
|
||||
return false;
|
||||
}
|
||||
if (!animation.is_valid()) {
|
||||
return false;
|
||||
}
|
||||
if (!root) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//let's build a node path
|
||||
String path = root->get_path_to(p_node);
|
||||
if (p_sub != "") {
|
||||
path += ":" + p_sub;
|
||||
}
|
||||
int track_id = animation->find_track(path);
|
||||
if (track_id >= 0) {
|
||||
if (animation->track_get_type(track_id) == Animation::TYPE_TRANSFORM3D) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AnimationTrackEditor::_insert_animation_key(NodePath p_path, const Variant &p_value) {
|
||||
String path = p_path;
|
||||
|
||||
|
@ -3571,7 +3596,7 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
|
|||
String path = root->get_path_to(node);
|
||||
|
||||
if (Object::cast_to<AnimationPlayer>(node) && p_property == "current_animation") {
|
||||
if (node == AnimationPlayerEditor::singleton->get_player()) {
|
||||
if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
|
||||
EditorNode::get_singleton()->show_warning(TTR("AnimationPlayer can't animate itself, only other players."));
|
||||
return;
|
||||
}
|
||||
|
@ -3672,7 +3697,7 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
|
|||
String path = root->get_path_to(node);
|
||||
|
||||
if (Object::cast_to<AnimationPlayer>(node) && p_property == "current_animation") {
|
||||
if (node == AnimationPlayerEditor::singleton->get_player()) {
|
||||
if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
|
||||
EditorNode::get_singleton()->show_warning(TTR("AnimationPlayer can't animate itself, only other players."));
|
||||
return;
|
||||
}
|
||||
|
@ -3752,7 +3777,7 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
|
|||
}
|
||||
|
||||
Ref<Animation> AnimationTrackEditor::_create_and_get_reset_animation() {
|
||||
AnimationPlayer *player = AnimationPlayerEditor::singleton->get_player();
|
||||
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
|
||||
if (player->has_animation("RESET")) {
|
||||
return player->get_animation("RESET");
|
||||
} else {
|
||||
|
@ -3760,9 +3785,9 @@ Ref<Animation> AnimationTrackEditor::_create_and_get_reset_animation() {
|
|||
reset_anim.instantiate();
|
||||
reset_anim->set_length(ANIM_MIN_LENGTH);
|
||||
undo_redo->add_do_method(player, "add_animation", "RESET", reset_anim);
|
||||
undo_redo->add_do_method(AnimationPlayerEditor::singleton, "_animation_player_changed", player);
|
||||
undo_redo->add_do_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player);
|
||||
undo_redo->add_undo_method(player, "remove_animation", "RESET");
|
||||
undo_redo->add_undo_method(AnimationPlayerEditor::singleton, "_animation_player_changed", player);
|
||||
undo_redo->add_undo_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player);
|
||||
return reset_anim;
|
||||
}
|
||||
}
|
||||
|
@ -4446,7 +4471,7 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (node == AnimationPlayerEditor::singleton->get_player()) {
|
||||
if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
|
||||
EditorNode::get_singleton()->show_warning(TTR("AnimationPlayer can't animate itself, only other players."));
|
||||
return;
|
||||
}
|
||||
|
@ -5173,7 +5198,7 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) {
|
|||
}
|
||||
|
||||
void AnimationTrackEditor::_edit_menu_about_to_popup() {
|
||||
AnimationPlayer *player = AnimationPlayerEditor::singleton->get_player();
|
||||
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
|
||||
edit->get_popup()->set_item_disabled(edit->get_popup()->get_item_index(EDIT_APPLY_RESET), !player->can_apply_reset());
|
||||
}
|
||||
|
||||
|
@ -5517,7 +5542,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
|
|||
goto_prev_step(false);
|
||||
} break;
|
||||
case EDIT_APPLY_RESET: {
|
||||
AnimationPlayerEditor::singleton->get_player()->apply_reset(true);
|
||||
AnimationPlayerEditor::get_singleton()->get_player()->apply_reset(true);
|
||||
|
||||
} break;
|
||||
case EDIT_OPTIMIZE_ANIMATION: {
|
||||
|
@ -5537,9 +5562,9 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
|
|||
case EDIT_CLEAN_UP_ANIMATION_CONFIRM: {
|
||||
if (cleanup_all->is_pressed()) {
|
||||
List<StringName> names;
|
||||
AnimationPlayerEditor::singleton->get_player()->get_animation_list(&names);
|
||||
AnimationPlayerEditor::get_singleton()->get_player()->get_animation_list(&names);
|
||||
for (const StringName &E : names) {
|
||||
_cleanup_animation(AnimationPlayerEditor::singleton->get_player()->get_animation(E));
|
||||
_cleanup_animation(AnimationPlayerEditor::get_singleton()->get_player()->get_animation(E));
|
||||
}
|
||||
} else {
|
||||
_cleanup_animation(animation);
|
||||
|
|
|
@ -531,6 +531,7 @@ public:
|
|||
void insert_node_value_key(Node *p_node, const String &p_property, const Variant &p_value, bool p_only_if_exists = false);
|
||||
void insert_value_key(const String &p_property, const Variant &p_value, bool p_advance);
|
||||
void insert_transform_key(Node3D *p_node, const String &p_sub, const Transform3D &p_xform);
|
||||
bool has_transform_track(Node3D *p_node, const String &p_sub);
|
||||
|
||||
void show_select_node_warning(bool p_show);
|
||||
|
||||
|
|
|
@ -6930,7 +6930,7 @@ EditorNode::EditorNode() {
|
|||
add_child(editor_interface);
|
||||
|
||||
//more visually meaningful to have this later
|
||||
raise_bottom_panel_item(AnimationPlayerEditor::singleton);
|
||||
raise_bottom_panel_item(AnimationPlayerEditor::get_singleton());
|
||||
|
||||
add_editor_plugin(VersionControlEditorPlugin::get_singleton());
|
||||
add_editor_plugin(memnew(ShaderEditorPlugin(this)));
|
||||
|
@ -7204,20 +7204,24 @@ bool EditorPluginList::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|||
return discard;
|
||||
}
|
||||
|
||||
bool EditorPluginList::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled) {
|
||||
bool discard = false;
|
||||
EditorPlugin::AfterGUIInput EditorPluginList::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled) {
|
||||
EditorPlugin::AfterGUIInput after = EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
|
||||
for (int i = 0; i < plugins_list.size(); i++) {
|
||||
if ((!serve_when_force_input_enabled) && plugins_list[i]->is_input_event_forwarding_always_enabled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (plugins_list[i]->forward_spatial_gui_input(p_camera, p_event)) {
|
||||
discard = true;
|
||||
EditorPlugin::AfterGUIInput current_after = plugins_list[i]->forward_spatial_gui_input(p_camera, p_event);
|
||||
if (current_after == EditorPlugin::AFTER_GUI_INPUT_STOP) {
|
||||
after = EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
if (after != EditorPlugin::AFTER_GUI_INPUT_STOP && current_after == EditorPlugin::AFTER_GUI_INPUT_DESELECT) {
|
||||
after = EditorPlugin::AFTER_GUI_INPUT_DESELECT;
|
||||
}
|
||||
}
|
||||
|
||||
return discard;
|
||||
return after;
|
||||
}
|
||||
|
||||
void EditorPluginList::forward_canvas_draw_over_viewport(Control *p_overlay) {
|
||||
|
|
|
@ -942,7 +942,7 @@ public:
|
|||
bool forward_gui_input(const Ref<InputEvent> &p_event);
|
||||
void forward_canvas_draw_over_viewport(Control *p_overlay);
|
||||
void forward_canvas_force_draw_over_viewport(Control *p_overlay);
|
||||
bool forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled);
|
||||
EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled);
|
||||
void forward_spatial_draw_over_viewport(Control *p_overlay);
|
||||
void forward_spatial_force_draw_over_viewport(Control *p_overlay);
|
||||
void add_plugin(EditorPlugin *p_plugin);
|
||||
|
|
|
@ -593,14 +593,14 @@ int EditorPlugin::update_overlays() const {
|
|||
}
|
||||
}
|
||||
|
||||
bool EditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
|
||||
bool success;
|
||||
EditorPlugin::AfterGUIInput EditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
|
||||
int success;
|
||||
|
||||
if (GDVIRTUAL_CALL(_forward_3d_gui_input, p_camera, p_event, success)) {
|
||||
return success;
|
||||
return static_cast<EditorPlugin::AfterGUIInput>(success);
|
||||
}
|
||||
|
||||
return false;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
}
|
||||
|
||||
void EditorPlugin::forward_spatial_draw_over_viewport(Control *p_overlay) {
|
||||
|
|
|
@ -151,7 +151,7 @@ protected:
|
|||
GDVIRTUAL1R(bool, _forward_canvas_gui_input, Ref<InputEvent>)
|
||||
GDVIRTUAL1(_forward_canvas_draw_over_viewport, Control *)
|
||||
GDVIRTUAL1(_forward_canvas_force_draw_over_viewport, Control *)
|
||||
GDVIRTUAL2R(bool, _forward_3d_gui_input, Camera3D *, Ref<InputEvent>)
|
||||
GDVIRTUAL2R(int, _forward_3d_gui_input, Camera3D *, Ref<InputEvent>)
|
||||
GDVIRTUAL1(_forward_3d_draw_over_viewport, Control *)
|
||||
GDVIRTUAL1(_forward_3d_force_draw_over_viewport, Control *)
|
||||
GDVIRTUAL0RC(String, _get_plugin_name)
|
||||
|
@ -200,6 +200,12 @@ public:
|
|||
DOCK_SLOT_MAX
|
||||
};
|
||||
|
||||
enum AfterGUIInput {
|
||||
AFTER_GUI_INPUT_PASS,
|
||||
AFTER_GUI_INPUT_STOP,
|
||||
AFTER_GUI_INPUT_DESELECT
|
||||
};
|
||||
|
||||
//TODO: send a resource for editing to the editor node?
|
||||
|
||||
void add_control_to_container(CustomControlContainer p_location, Control *p_control);
|
||||
|
@ -228,7 +234,7 @@ public:
|
|||
virtual void forward_canvas_draw_over_viewport(Control *p_overlay);
|
||||
virtual void forward_canvas_force_draw_over_viewport(Control *p_overlay);
|
||||
|
||||
virtual bool forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event);
|
||||
virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event);
|
||||
virtual void forward_spatial_draw_over_viewport(Control *p_overlay);
|
||||
virtual void forward_spatial_force_draw_over_viewport(Control *p_overlay);
|
||||
|
||||
|
|
|
@ -213,6 +213,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
|
|||
exceptions.insert("EditorPivot");
|
||||
exceptions.insert("EditorHandle");
|
||||
exceptions.insert("Editor3DHandle");
|
||||
exceptions.insert("EditorBoneHandle");
|
||||
exceptions.insert("Godot");
|
||||
exceptions.insert("Sky");
|
||||
exceptions.insert("EditorControlAnchor");
|
||||
|
|
1
editor/icons/EditorBoneHandle.svg
Normal file
1
editor/icons/EditorBoneHandle.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><circle cx="4" cy="4" fill="#fff" r="4"/><circle cx="4" cy="4" fill="#000" r="2.5"/></svg>
|
After Width: | Height: | Size: 170 B |
1
editor/icons/ToolBoneSelect.svg
Normal file
1
editor/icons/ToolBoneSelect.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg enable-background="new 0 0 16 16" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" fill-opacity=".9961"><path d="m16 11.46-6.142-2.527-1.572-.647.647 1.572 2.527 6.142.913-2.72 1.815 1.817.91-.909-1.818-1.815z"/><path d="m7.784 11.008-.886-2.152c-.23-.56-.102-1.203.327-1.631.287-.287.67-.439 1.061-.439.192 0 .386.037.57.113l2.151.885.17-.17c.977.645 2.271.516 3.1-.311.964-.963.964-2.524 0-3.488-.377-.377-.867-.622-1.396-.697-.074-.529-.318-1.019-.695-1.397-.455-.453-1.067-.711-1.707-.721-.667-.01-1.309.25-1.782.72-.828.829-.96 2.126-.314 3.105l-3.558 3.561c-.978-.646-2.274-.515-3.103.312-.963.962-.963 2.524 0 3.487.378.377.868.621 1.396.695.075.529.319 1.02.696 1.396.963.964 2.525.964 3.488 0 .828-.828.96-2.125.314-3.104z"/></g></svg>
|
After Width: | Height: | Size: 797 B |
|
@ -383,7 +383,7 @@ void InspectorDock::_menu_expandall() {
|
|||
}
|
||||
|
||||
void InspectorDock::_property_keyed(const String &p_keyed, const Variant &p_value, bool p_advance) {
|
||||
AnimationPlayerEditor::singleton->get_track_editor()->insert_value_key(p_keyed, p_value, p_advance);
|
||||
AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_value_key(p_keyed, p_value, p_advance);
|
||||
}
|
||||
|
||||
void InspectorDock::_transform_keyed(Object *sp, const String &p_sub, const Transform3D &p_key) {
|
||||
|
@ -391,7 +391,7 @@ void InspectorDock::_transform_keyed(Object *sp, const String &p_sub, const Tran
|
|||
if (!s) {
|
||||
return;
|
||||
}
|
||||
AnimationPlayerEditor::singleton->get_track_editor()->insert_transform_key(s, p_sub, p_key);
|
||||
AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_transform_key(s, p_sub, p_key);
|
||||
}
|
||||
|
||||
void InspectorDock::_warning_pressed() {
|
||||
|
@ -545,7 +545,7 @@ void InspectorDock::go_back() {
|
|||
void InspectorDock::update_keying() {
|
||||
bool valid = false;
|
||||
|
||||
if (AnimationPlayerEditor::singleton->get_track_editor()->has_keying()) {
|
||||
if (AnimationPlayerEditor::get_singleton()->get_track_editor()->has_keying()) {
|
||||
EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history();
|
||||
if (editor_history->get_path_size() >= 1) {
|
||||
Object *obj = ObjectDB::get_instance(editor_history->get_path_object(0));
|
||||
|
|
|
@ -298,7 +298,7 @@ void AnimationPlayerEditor::_animation_selected(int p_which) {
|
|||
|
||||
autoplay->set_pressed(current == player->get_autoplay());
|
||||
|
||||
AnimationPlayerEditor::singleton->get_track_editor()->update_keying();
|
||||
AnimationPlayerEditor::get_singleton()->get_track_editor()->update_keying();
|
||||
EditorNode::get_singleton()->update_keying();
|
||||
_animation_key_editor_seek(timeline_position, false);
|
||||
}
|
||||
|
@ -826,7 +826,7 @@ void AnimationPlayerEditor::_update_player() {
|
|||
pin->set_disabled(player == nullptr);
|
||||
|
||||
if (!player) {
|
||||
AnimationPlayerEditor::singleton->get_track_editor()->update_keying();
|
||||
AnimationPlayerEditor::get_singleton()->get_track_editor()->update_keying();
|
||||
EditorNode::get_singleton()->update_keying();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -128,6 +128,7 @@ class AnimationPlayerEditor : public VBoxContainer {
|
|||
bool updating_blends;
|
||||
|
||||
AnimationTrackEditor *track_editor;
|
||||
static AnimationPlayerEditor *singleton;
|
||||
|
||||
// Onion skinning.
|
||||
struct {
|
||||
|
@ -226,7 +227,8 @@ protected:
|
|||
|
||||
public:
|
||||
AnimationPlayer *get_player() const;
|
||||
static AnimationPlayerEditor *singleton;
|
||||
|
||||
static AnimationPlayerEditor *get_singleton() { return singleton; }
|
||||
|
||||
bool is_pinned() const { return pin->is_pressed(); }
|
||||
void unpin() { pin->set_pressed(false); }
|
||||
|
|
|
@ -513,7 +513,7 @@ Object *CanvasItemEditor::_get_editor_data(Object *p_what) {
|
|||
}
|
||||
|
||||
void CanvasItemEditor::_keying_changed() {
|
||||
if (AnimationPlayerEditor::singleton->get_track_editor()->is_visible_in_tree()) {
|
||||
if (AnimationPlayerEditor::get_singleton()->get_track_editor()->is_visible_in_tree()) {
|
||||
animation_hb->show();
|
||||
} else {
|
||||
animation_hb->hide();
|
||||
|
@ -3816,7 +3816,7 @@ void CanvasItemEditor::_notification(int p_what) {
|
|||
select_sb->set_default_margin(Side(i), 4);
|
||||
}
|
||||
|
||||
AnimationPlayerEditor::singleton->get_track_editor()->connect("visibility_changed", callable_mp(this, &CanvasItemEditor::_keying_changed));
|
||||
AnimationPlayerEditor::get_singleton()->get_track_editor()->connect("visibility_changed", callable_mp(this, &CanvasItemEditor::_keying_changed));
|
||||
_keying_changed();
|
||||
|
||||
} else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
|
||||
|
@ -4277,13 +4277,13 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation,
|
|||
Node2D *n2d = Object::cast_to<Node2D>(canvas_item);
|
||||
|
||||
if (key_pos && p_location) {
|
||||
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(n2d, "position", n2d->get_position(), p_on_existing);
|
||||
AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_node_value_key(n2d, "position", n2d->get_position(), p_on_existing);
|
||||
}
|
||||
if (key_rot && p_rotation) {
|
||||
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(n2d, "rotation", n2d->get_rotation(), p_on_existing);
|
||||
AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_node_value_key(n2d, "rotation", n2d->get_rotation(), p_on_existing);
|
||||
}
|
||||
if (key_scale && p_scale) {
|
||||
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(n2d, "scale", n2d->get_scale(), p_on_existing);
|
||||
AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_node_value_key(n2d, "scale", n2d->get_scale(), p_on_existing);
|
||||
}
|
||||
|
||||
if (n2d->has_meta("_edit_bone_") && n2d->get_parent_item()) {
|
||||
|
@ -4309,13 +4309,13 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation,
|
|||
if (has_chain && ik_chain.size()) {
|
||||
for (Node2D *&F : ik_chain) {
|
||||
if (key_pos) {
|
||||
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(F, "position", F->get_position(), p_on_existing);
|
||||
AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_node_value_key(F, "position", F->get_position(), p_on_existing);
|
||||
}
|
||||
if (key_rot) {
|
||||
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(F, "rotation", F->get_rotation(), p_on_existing);
|
||||
AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_node_value_key(F, "rotation", F->get_rotation(), p_on_existing);
|
||||
}
|
||||
if (key_scale) {
|
||||
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(F, "scale", F->get_scale(), p_on_existing);
|
||||
AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_node_value_key(F, "scale", F->get_scale(), p_on_existing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4325,13 +4325,13 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation,
|
|||
Control *ctrl = Object::cast_to<Control>(canvas_item);
|
||||
|
||||
if (key_pos) {
|
||||
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(ctrl, "rect_position", ctrl->get_position(), p_on_existing);
|
||||
AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_node_value_key(ctrl, "rect_position", ctrl->get_position(), p_on_existing);
|
||||
}
|
||||
if (key_rot) {
|
||||
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(ctrl, "rect_rotation", ctrl->get_rotation(), p_on_existing);
|
||||
AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_node_value_key(ctrl, "rect_rotation", ctrl->get_rotation(), p_on_existing);
|
||||
}
|
||||
if (key_scale) {
|
||||
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(ctrl, "rect_size", ctrl->get_size(), p_on_existing);
|
||||
AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_node_value_key(ctrl, "rect_size", ctrl->get_size(), p_on_existing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4771,7 +4771,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
|
|||
}
|
||||
/*
|
||||
if (key_scale)
|
||||
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(ctrl,"rect/size",ctrl->get_size());
|
||||
AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_node_value_key(ctrl,"rect/size",ctrl->get_size());
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,9 +103,9 @@ void CollisionPolygon3DEditor::_wip_close() {
|
|||
undo_redo->commit_action();
|
||||
}
|
||||
|
||||
bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
|
||||
EditorPlugin::AfterGUIInput CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
|
||||
if (!node) {
|
||||
return false;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
}
|
||||
|
||||
Transform3D gt = node->get_global_transform();
|
||||
|
@ -124,7 +124,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
|
|||
Vector3 spoint;
|
||||
|
||||
if (!p.intersects_ray(ray_from, ray_dir, &spoint)) {
|
||||
return false;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
}
|
||||
|
||||
spoint = gi.xform(spoint);
|
||||
|
@ -151,19 +151,19 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
|
|||
snap_ignore = false;
|
||||
_polygon_draw();
|
||||
edited_point = 1;
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
} else {
|
||||
if (wip.size() > 1 && p_camera->unproject_position(gt.xform(Vector3(wip[0].x, wip[0].y, depth))).distance_to(gpoint) < grab_threshold) {
|
||||
//wip closed
|
||||
_wip_close();
|
||||
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
} else {
|
||||
wip.push_back(cpoint);
|
||||
edited_point = wip.size();
|
||||
snap_ignore = false;
|
||||
_polygon_draw();
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
}
|
||||
} else if (mb->get_button_index() == MOUSE_BUTTON_RIGHT && mb->is_pressed() && wip_active) {
|
||||
|
@ -184,7 +184,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
|
|||
undo_redo->add_do_method(this, "_polygon_draw");
|
||||
undo_redo->add_undo_method(this, "_polygon_draw");
|
||||
undo_redo->commit_action();
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
|
||||
//search edges
|
||||
|
@ -219,7 +219,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
|
|||
_polygon_draw();
|
||||
snap_ignore = true;
|
||||
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
} else {
|
||||
//look for points to move
|
||||
|
@ -244,7 +244,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
|
|||
edited_point_pos = poly[closest_idx];
|
||||
_polygon_draw();
|
||||
snap_ignore = false;
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -253,7 +253,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
|
|||
if (edited_point != -1) {
|
||||
//apply
|
||||
|
||||
ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
|
||||
ERR_FAIL_INDEX_V(edited_point, poly.size(), EditorPlugin::AFTER_GUI_INPUT_PASS);
|
||||
poly.write[edited_point] = edited_point_pos;
|
||||
undo_redo->create_action(TTR("Edit Poly"));
|
||||
undo_redo->add_do_method(node, "set_polygon", poly);
|
||||
|
@ -263,7 +263,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
|
|||
undo_redo->commit_action();
|
||||
|
||||
edited_point = -1;
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -290,7 +290,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
|
|||
undo_redo->add_do_method(this, "_polygon_draw");
|
||||
undo_redo->add_undo_method(this, "_polygon_draw");
|
||||
undo_redo->commit_action();
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,7 +310,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
|
|||
Vector3 spoint;
|
||||
|
||||
if (!p.intersects_ray(ray_from, ray_dir, &spoint)) {
|
||||
return false;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
}
|
||||
|
||||
spoint = gi.xform(spoint);
|
||||
|
@ -332,7 +332,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
|
|||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
}
|
||||
|
||||
float CollisionPolygon3DEditor::_get_depth() {
|
||||
|
|
|
@ -88,7 +88,7 @@ protected:
|
|||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
virtual bool forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event);
|
||||
virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event);
|
||||
void edit(Node *p_collision_polygon);
|
||||
CollisionPolygon3DEditor(EditorNode *p_editor);
|
||||
~CollisionPolygon3DEditor();
|
||||
|
@ -101,7 +101,7 @@ class Polygon3DEditorPlugin : public EditorPlugin {
|
|||
EditorNode *editor;
|
||||
|
||||
public:
|
||||
virtual bool forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return collision_polygon_editor->forward_spatial_gui_input(p_camera, p_event); }
|
||||
virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return collision_polygon_editor->forward_spatial_gui_input(p_camera, p_event); }
|
||||
|
||||
virtual String get_name() const override { return "Polygon3DEditor"; }
|
||||
bool has_main_screen() const override { return false; }
|
||||
|
|
|
@ -2070,169 +2070,6 @@ void Position3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
|
|||
p_gizmo->add_collision_segments(cursor_points);
|
||||
}
|
||||
|
||||
/////
|
||||
|
||||
Skeleton3DGizmoPlugin::Skeleton3DGizmoPlugin() {
|
||||
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/skeleton", Color(1, 0.8, 0.4));
|
||||
create_material("skeleton_material", gizmo_color);
|
||||
}
|
||||
|
||||
bool Skeleton3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
|
||||
return Object::cast_to<Skeleton3D>(p_spatial) != nullptr;
|
||||
}
|
||||
|
||||
String Skeleton3DGizmoPlugin::get_gizmo_name() const {
|
||||
return "Skeleton3D";
|
||||
}
|
||||
|
||||
int Skeleton3DGizmoPlugin::get_priority() const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
|
||||
Skeleton3D *skel = Object::cast_to<Skeleton3D>(p_gizmo->get_spatial_node());
|
||||
|
||||
p_gizmo->clear();
|
||||
|
||||
Ref<Material> material = get_material("skeleton_material", p_gizmo);
|
||||
|
||||
Ref<SurfaceTool> surface_tool(memnew(SurfaceTool));
|
||||
|
||||
surface_tool->begin(Mesh::PRIMITIVE_LINES);
|
||||
surface_tool->set_material(material);
|
||||
LocalVector<Transform3D> grests;
|
||||
grests.resize(skel->get_bone_count());
|
||||
|
||||
LocalVector<int> bones;
|
||||
LocalVector<float> weights;
|
||||
bones.resize(4);
|
||||
weights.resize(4);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
bones[i] = 0;
|
||||
weights[i] = 0;
|
||||
}
|
||||
|
||||
weights[0] = 1;
|
||||
|
||||
AABB aabb;
|
||||
|
||||
Color bonecolor = Color(1.0, 0.4, 0.4, 0.3);
|
||||
Color rootcolor = Color(0.4, 1.0, 0.4, 0.1);
|
||||
|
||||
LocalVector<int> bones_to_process;
|
||||
bones_to_process = skel->get_parentless_bones();
|
||||
|
||||
while (bones_to_process.size() > 0) {
|
||||
int current_bone_idx = bones_to_process[0];
|
||||
bones_to_process.erase(current_bone_idx);
|
||||
|
||||
LocalVector<int> child_bones_vector;
|
||||
child_bones_vector = skel->get_bone_children(current_bone_idx);
|
||||
int child_bones_size = child_bones_vector.size();
|
||||
|
||||
if (skel->get_bone_parent(current_bone_idx) < 0) {
|
||||
grests[current_bone_idx] = skel->get_bone_rest(current_bone_idx);
|
||||
}
|
||||
|
||||
for (int i = 0; i < child_bones_size; i++) {
|
||||
int child_bone_idx = child_bones_vector[i];
|
||||
|
||||
grests[child_bone_idx] = grests[current_bone_idx] * skel->get_bone_rest(child_bone_idx);
|
||||
Vector3 v0 = grests[current_bone_idx].origin;
|
||||
Vector3 v1 = grests[child_bone_idx].origin;
|
||||
Vector3 d = (v1 - v0).normalized();
|
||||
real_t dist = v0.distance_to(v1);
|
||||
|
||||
// Find closest axis.
|
||||
int closest = -1;
|
||||
real_t closest_d = 0.0;
|
||||
for (int j = 0; j < 3; j++) {
|
||||
real_t dp = Math::abs(grests[current_bone_idx].basis[j].normalized().dot(d));
|
||||
if (j == 0 || dp > closest_d) {
|
||||
closest = j;
|
||||
}
|
||||
}
|
||||
|
||||
// Find closest other.
|
||||
Vector3 first;
|
||||
Vector3 points[4];
|
||||
int point_idx = 0;
|
||||
for (int j = 0; j < 3; j++) {
|
||||
bones[0] = current_bone_idx;
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(rootcolor);
|
||||
surface_tool->add_vertex(v0 - grests[current_bone_idx].basis[j].normalized() * dist * 0.05);
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(rootcolor);
|
||||
surface_tool->add_vertex(v0 + grests[current_bone_idx].basis[j].normalized() * dist * 0.05);
|
||||
|
||||
if (j == closest) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector3 axis;
|
||||
if (first == Vector3()) {
|
||||
axis = d.cross(d.cross(grests[current_bone_idx].basis[j])).normalized();
|
||||
first = axis;
|
||||
} else {
|
||||
axis = d.cross(first).normalized();
|
||||
}
|
||||
|
||||
for (int k = 0; k < 2; k++) {
|
||||
if (k == 1) {
|
||||
axis = -axis;
|
||||
}
|
||||
Vector3 point = v0 + d * dist * 0.2;
|
||||
point += axis * dist * 0.1;
|
||||
|
||||
bones[0] = current_bone_idx;
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(bonecolor);
|
||||
surface_tool->add_vertex(v0);
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(bonecolor);
|
||||
surface_tool->add_vertex(point);
|
||||
|
||||
bones[0] = current_bone_idx;
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(bonecolor);
|
||||
surface_tool->add_vertex(point);
|
||||
bones[0] = child_bone_idx;
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(bonecolor);
|
||||
surface_tool->add_vertex(v1);
|
||||
points[point_idx++] = point;
|
||||
}
|
||||
}
|
||||
SWAP(points[1], points[2]);
|
||||
for (int j = 0; j < 4; j++) {
|
||||
bones[0] = current_bone_idx;
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(bonecolor);
|
||||
surface_tool->add_vertex(points[j]);
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(bonecolor);
|
||||
surface_tool->add_vertex(points[(j + 1) % 4]);
|
||||
}
|
||||
|
||||
// Add the bone's children to the list of bones to be processed.
|
||||
bones_to_process.push_back(child_bones_vector[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Ref<ArrayMesh> m = surface_tool->commit();
|
||||
p_gizmo->add_mesh(m, Ref<Material>(), Transform3D(), skel->register_skin(Ref<Skin>()));
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
PhysicalBone3DGizmoPlugin::PhysicalBone3DGizmoPlugin() {
|
||||
|
|
|
@ -332,18 +332,6 @@ public:
|
|||
Position3DGizmoPlugin();
|
||||
};
|
||||
|
||||
class Skeleton3DGizmoPlugin : public EditorNode3DGizmoPlugin {
|
||||
GDCLASS(Skeleton3DGizmoPlugin, EditorNode3DGizmoPlugin);
|
||||
|
||||
public:
|
||||
bool has_gizmo(Node3D *p_spatial) override;
|
||||
String get_gizmo_name() const override;
|
||||
int get_priority() const override;
|
||||
void redraw(EditorNode3DGizmo *p_gizmo) override;
|
||||
|
||||
Skeleton3DGizmoPlugin();
|
||||
};
|
||||
|
||||
class PhysicalBone3DGizmoPlugin : public EditorNode3DGizmoPlugin {
|
||||
GDCLASS(PhysicalBone3DGizmoPlugin, EditorNode3DGizmoPlugin);
|
||||
|
||||
|
|
|
@ -1291,24 +1291,31 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
|
|||
return; //do NONE
|
||||
}
|
||||
|
||||
EditorPlugin::AfterGUIInput after = EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
{
|
||||
EditorNode *en = editor;
|
||||
EditorPluginList *force_input_forwarding_list = en->get_editor_plugins_force_input_forwarding();
|
||||
if (!force_input_forwarding_list->is_empty()) {
|
||||
bool discard = force_input_forwarding_list->forward_spatial_gui_input(camera, p_event, true);
|
||||
if (discard) {
|
||||
EditorPlugin::AfterGUIInput discard = force_input_forwarding_list->forward_spatial_gui_input(camera, p_event, true);
|
||||
if (discard == EditorPlugin::AFTER_GUI_INPUT_STOP) {
|
||||
return;
|
||||
}
|
||||
if (discard == EditorPlugin::AFTER_GUI_INPUT_DESELECT) {
|
||||
after = EditorPlugin::AFTER_GUI_INPUT_DESELECT;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
EditorNode *en = editor;
|
||||
EditorPluginList *over_plugin_list = en->get_editor_plugins_over();
|
||||
if (!over_plugin_list->is_empty()) {
|
||||
bool discard = over_plugin_list->forward_spatial_gui_input(camera, p_event, false);
|
||||
if (discard) {
|
||||
EditorPlugin::AfterGUIInput discard = over_plugin_list->forward_spatial_gui_input(camera, p_event, false);
|
||||
if (discard == EditorPlugin::AFTER_GUI_INPUT_STOP) {
|
||||
return;
|
||||
}
|
||||
if (discard == EditorPlugin::AFTER_GUI_INPUT_DESELECT) {
|
||||
after = EditorPlugin::AFTER_GUI_INPUT_DESELECT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1573,17 +1580,19 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
|
|||
break;
|
||||
}
|
||||
|
||||
clicked = _select_ray(b->get_position());
|
||||
if (after != EditorPlugin::AFTER_GUI_INPUT_DESELECT) {
|
||||
clicked = _select_ray(b->get_position());
|
||||
|
||||
//clicking is always deferred to either move or release
|
||||
//clicking is always deferred to either move or release
|
||||
|
||||
clicked_wants_append = b->is_shift_pressed();
|
||||
clicked_wants_append = b->is_shift_pressed();
|
||||
|
||||
if (clicked.is_null()) {
|
||||
//default to regionselect
|
||||
cursor.region_select = true;
|
||||
cursor.region_begin = b->get_position();
|
||||
cursor.region_end = b->get_position();
|
||||
if (clicked.is_null()) {
|
||||
//default to regionselect
|
||||
cursor.region_select = true;
|
||||
cursor.region_begin = b->get_position();
|
||||
cursor.region_end = b->get_position();
|
||||
}
|
||||
}
|
||||
|
||||
surface->update();
|
||||
|
@ -1594,14 +1603,16 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (clicked.is_valid()) {
|
||||
_select_clicked(false);
|
||||
}
|
||||
if (after != EditorPlugin::AFTER_GUI_INPUT_DESELECT) {
|
||||
if (clicked.is_valid()) {
|
||||
_select_clicked(false);
|
||||
}
|
||||
|
||||
if (cursor.region_select) {
|
||||
_select_region();
|
||||
cursor.region_select = false;
|
||||
surface->update();
|
||||
if (cursor.region_select) {
|
||||
_select_region();
|
||||
cursor.region_select = false;
|
||||
surface->update();
|
||||
}
|
||||
}
|
||||
|
||||
if (_edit.mode != TRANSFORM_NONE) {
|
||||
|
@ -2237,7 +2248,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!AnimationPlayerEditor::singleton->get_track_editor()->has_keying()) {
|
||||
if (!AnimationPlayerEditor::get_singleton()->get_track_editor()->has_keying()) {
|
||||
set_message(TTR("Keying is disabled (no key inserted)."));
|
||||
return;
|
||||
}
|
||||
|
@ -6736,6 +6747,33 @@ void Node3DEditor::_request_gizmo(Object *p_obj) {
|
|||
}
|
||||
}
|
||||
|
||||
void Node3DEditor::_set_subgizmo_selection(Object *p_obj, Ref<Node3DGizmo> p_gizmo, int p_id, Transform3D p_transform) {
|
||||
if (p_id == -1) {
|
||||
_clear_subgizmo_selection(p_obj);
|
||||
return;
|
||||
}
|
||||
|
||||
Node3D *sp = nullptr;
|
||||
if (p_obj) {
|
||||
sp = Object::cast_to<Node3D>(p_obj);
|
||||
} else {
|
||||
sp = selected;
|
||||
}
|
||||
|
||||
if (!sp) {
|
||||
return;
|
||||
}
|
||||
|
||||
Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
|
||||
if (se) {
|
||||
se->subgizmos.clear();
|
||||
se->subgizmos.insert(p_id, p_transform);
|
||||
se->gizmo = p_gizmo;
|
||||
sp->update_gizmos();
|
||||
update_transform_gizmo();
|
||||
}
|
||||
}
|
||||
|
||||
void Node3DEditor::_clear_subgizmo_selection(Object *p_obj) {
|
||||
Node3D *sp = nullptr;
|
||||
if (p_obj) {
|
||||
|
@ -6861,7 +6899,6 @@ void Node3DEditor::_register_all_gizmos() {
|
|||
add_gizmo_plugin(Ref<OccluderInstance3DGizmoPlugin>(memnew(OccluderInstance3DGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<SoftDynamicBody3DGizmoPlugin>(memnew(SoftDynamicBody3DGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<Sprite3DGizmoPlugin>(memnew(Sprite3DGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<Skeleton3DGizmoPlugin>(memnew(Skeleton3DGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<Position3DGizmoPlugin>(memnew(Position3DGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<RayCast3DGizmoPlugin>(memnew(RayCast3DGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<SpringArm3DGizmoPlugin>(memnew(SpringArm3DGizmoPlugin)));
|
||||
|
@ -6886,6 +6923,7 @@ void Node3DEditor::_register_all_gizmos() {
|
|||
void Node3DEditor::_bind_methods() {
|
||||
ClassDB::bind_method("_get_editor_data", &Node3DEditor::_get_editor_data);
|
||||
ClassDB::bind_method("_request_gizmo", &Node3DEditor::_request_gizmo);
|
||||
ClassDB::bind_method("_set_subgizmo_selection", &Node3DEditor::_set_subgizmo_selection);
|
||||
ClassDB::bind_method("_clear_subgizmo_selection", &Node3DEditor::_clear_subgizmo_selection);
|
||||
ClassDB::bind_method("_refresh_menu_icons", &Node3DEditor::_refresh_menu_icons);
|
||||
|
||||
|
@ -7712,6 +7750,13 @@ Vector3 Node3DEditor::snap_point(Vector3 p_target, Vector3 p_start) const {
|
|||
return p_target;
|
||||
}
|
||||
|
||||
bool Node3DEditor::is_gizmo_visible() const {
|
||||
if (selected) {
|
||||
return gizmo.visible && selected->is_transform_gizmo_visible();
|
||||
}
|
||||
return gizmo.visible;
|
||||
}
|
||||
|
||||
double Node3DEditor::get_translate_snap() const {
|
||||
double snap_value;
|
||||
if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
|
||||
|
|
|
@ -663,6 +663,7 @@ private:
|
|||
Node3D *selected;
|
||||
|
||||
void _request_gizmo(Object *p_obj);
|
||||
void _set_subgizmo_selection(Object *p_obj, Ref<Node3DGizmo> p_gizmo, int p_id, Transform3D p_transform = Transform3D());
|
||||
void _clear_subgizmo_selection(Object *p_obj = nullptr);
|
||||
|
||||
static Node3DEditor *singleton;
|
||||
|
@ -756,7 +757,7 @@ public:
|
|||
float get_fov() const { return settings_fov->get_value(); }
|
||||
|
||||
Transform3D get_gizmo_transform() const { return gizmo.transform; }
|
||||
bool is_gizmo_visible() const { return gizmo.visible; }
|
||||
bool is_gizmo_visible() const;
|
||||
|
||||
ToolMode get_tool_mode() const { return tool_mode; }
|
||||
bool are_local_coords_enabled() const { return tool_option_button[Node3DEditor::TOOL_OPT_LOCAL_COORDS]->is_pressed(); }
|
||||
|
|
|
@ -294,13 +294,13 @@ Path3DGizmo::Path3DGizmo(Path3D *p_path) {
|
|||
orig_out_length = 0;
|
||||
}
|
||||
|
||||
bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
|
||||
EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
|
||||
if (!path) {
|
||||
return false;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
}
|
||||
Ref<Curve3D> c = path->get_curve();
|
||||
if (c.is_null()) {
|
||||
return false;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
}
|
||||
Transform3D gt = path->get_global_transform();
|
||||
Transform3D it = gt.affine_inverse();
|
||||
|
@ -329,14 +329,14 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref
|
|||
const Vector3 *r = v3a.ptr();
|
||||
|
||||
if (p_camera->unproject_position(gt.xform(c->get_point_position(0))).distance_to(mbpos) < click_dist) {
|
||||
return false; //nope, existing
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS; //nope, existing
|
||||
}
|
||||
|
||||
for (int i = 0; i < c->get_point_count() - 1; i++) {
|
||||
//find the offset and point index of the place to break up
|
||||
int j = idx;
|
||||
if (p_camera->unproject_position(gt.xform(c->get_point_position(i + 1))).distance_to(mbpos) < click_dist) {
|
||||
return false; //nope, existing
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS; //nope, existing
|
||||
}
|
||||
|
||||
while (j < rc && c->get_point_position(i + 1) != r[j]) {
|
||||
|
@ -386,7 +386,7 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref
|
|||
ur->add_do_method(c.ptr(), "add_point", closest_seg_point, Vector3(), Vector3(), closest_seg + 1);
|
||||
ur->add_undo_method(c.ptr(), "remove_point", closest_seg + 1);
|
||||
ur->commit_action();
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
|
||||
} else {
|
||||
Vector3 org;
|
||||
|
@ -405,7 +405,7 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref
|
|||
ur->add_do_method(c.ptr(), "add_point", it.xform(inters), Vector3(), Vector3(), -1);
|
||||
ur->add_undo_method(c.ptr(), "remove_point", c->get_point_count());
|
||||
ur->commit_action();
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
|
||||
//add new at pos
|
||||
|
@ -425,27 +425,27 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref
|
|||
ur->add_do_method(c.ptr(), "remove_point", i);
|
||||
ur->add_undo_method(c.ptr(), "add_point", c->get_point_position(i), c->get_point_in(i), c->get_point_out(i), i);
|
||||
ur->commit_action();
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
} else if (dist_to_p_out < click_dist) {
|
||||
UndoRedo *ur = editor->get_undo_redo();
|
||||
ur->create_action(TTR("Remove Out-Control Point"));
|
||||
ur->add_do_method(c.ptr(), "set_point_out", i, Vector3());
|
||||
ur->add_undo_method(c.ptr(), "set_point_out", i, c->get_point_out(i));
|
||||
ur->commit_action();
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
} else if (dist_to_p_in < click_dist) {
|
||||
UndoRedo *ur = editor->get_undo_redo();
|
||||
ur->create_action(TTR("Remove In-Control Point"));
|
||||
ur->add_do_method(c.ptr(), "set_point_in", i, Vector3());
|
||||
ur->add_undo_method(c.ptr(), "set_point_in", i, c->get_point_in(i));
|
||||
ur->commit_action();
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
}
|
||||
|
||||
void Path3DEditorPlugin::edit(Object *p_object) {
|
||||
|
|
|
@ -100,7 +100,7 @@ public:
|
|||
Path3D *get_edited_path() { return path; }
|
||||
|
||||
static Path3DEditorPlugin *singleton;
|
||||
virtual bool forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override;
|
||||
virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override;
|
||||
|
||||
virtual String get_name() const override { return "Path3D"; }
|
||||
bool has_main_screen() const override { return false; }
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -33,7 +33,12 @@
|
|||
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_plugin.h"
|
||||
#include "editor/editor_properties.h"
|
||||
#include "node_3d_editor_plugin.h"
|
||||
#include "scene/3d/camera_3d.h"
|
||||
#include "scene/3d/mesh_instance_3d.h"
|
||||
#include "scene/3d/skeleton_3d.h"
|
||||
#include "scene/resources/immediate_mesh.h"
|
||||
|
||||
class EditorInspectorPluginSkeleton;
|
||||
class Joint;
|
||||
|
@ -41,8 +46,6 @@ class PhysicalBone3D;
|
|||
class Skeleton3DEditorPlugin;
|
||||
class Button;
|
||||
class CheckBox;
|
||||
class EditorPropertyTransform3D;
|
||||
class EditorPropertyVector3;
|
||||
|
||||
class BoneTransformEditor : public VBoxContainer {
|
||||
GDCLASS(BoneTransformEditor, VBoxContainer);
|
||||
|
@ -81,6 +84,8 @@ class BoneTransformEditor : public VBoxContainer {
|
|||
void _value_changed_transform(const String p_property_name, const Transform3D p_transform, const StringName p_edited_property_name, const bool p_boolean);
|
||||
// Changes the transform to the given transform and updates the UI accordingly.
|
||||
void _change_transform(Transform3D p_new_transform);
|
||||
// Update it is truely keyable then.
|
||||
void _update_key_button(const bool p_keyable);
|
||||
// Creates a Transform using the EditorPropertyVector3 properties.
|
||||
Transform3D compute_transform_from_vector3s() const;
|
||||
|
||||
|
@ -92,7 +97,7 @@ protected:
|
|||
public:
|
||||
BoneTransformEditor(Skeleton3D *p_skeleton);
|
||||
|
||||
// Which transform target to modify
|
||||
// Which transform target to modify.
|
||||
void set_target(const String &p_prop);
|
||||
void set_label(const String &p_label) { label = p_label; }
|
||||
|
||||
|
@ -100,20 +105,21 @@ public:
|
|||
void _update_custom_pose_properties();
|
||||
void _update_transform_properties(Transform3D p_transform);
|
||||
|
||||
// Can/cannot modify the spinner values for the Transform
|
||||
void set_read_only(const bool p_read_only);
|
||||
|
||||
// Transform can be keyed, whether or not to show the button
|
||||
// Transform can be keyed, whether or not to show the button.
|
||||
void set_keyable(const bool p_keyable);
|
||||
|
||||
// Bone can be toggled enabled or disabled, whether or not to show the checkbox
|
||||
// When rest mode, pose and custom_pose editor are diasbled.
|
||||
void set_properties_read_only(const bool p_readonly);
|
||||
void set_transform_read_only(const bool p_readonly);
|
||||
|
||||
// Bone can be toggled enabled or disabled, whether or not to show the checkbox.
|
||||
void set_toggle_enabled(const bool p_enabled);
|
||||
|
||||
// Key Transform Button pressed
|
||||
// Key Transform Button pressed.
|
||||
void _key_button_pressed();
|
||||
|
||||
// Bone Enabled Checkbox toggled
|
||||
void _checkbox_toggled(const bool p_toggled);
|
||||
// Bone Enabled Checkbox toggled.
|
||||
void _checkbox_pressed();
|
||||
};
|
||||
|
||||
class Skeleton3DEditor : public VBoxContainer {
|
||||
|
@ -121,13 +127,20 @@ class Skeleton3DEditor : public VBoxContainer {
|
|||
|
||||
friend class Skeleton3DEditorPlugin;
|
||||
|
||||
enum Menu {
|
||||
MENU_OPTION_CREATE_PHYSICAL_SKELETON
|
||||
enum SkeletonOption {
|
||||
SKELETON_OPTION_INIT_POSE,
|
||||
SKELETON_OPTION_INSERT_KEYS,
|
||||
SKELETON_OPTION_INSERT_KEYS_EXISTED,
|
||||
SKELETON_OPTION_CREATE_PHYSICAL_SKELETON
|
||||
};
|
||||
|
||||
enum RestOption {
|
||||
REST_OPTION_POSE_TO_REST
|
||||
};
|
||||
|
||||
struct BoneInfo {
|
||||
PhysicalBone3D *physical_bone = nullptr;
|
||||
Transform3D relative_rest; // Relative to skeleton node
|
||||
Transform3D relative_rest; // Relative to skeleton node.
|
||||
};
|
||||
|
||||
EditorNode *editor;
|
||||
|
@ -140,13 +153,24 @@ class Skeleton3DEditor : public VBoxContainer {
|
|||
BoneTransformEditor *pose_editor = nullptr;
|
||||
BoneTransformEditor *custom_pose_editor = nullptr;
|
||||
|
||||
MenuButton *options = nullptr;
|
||||
VSeparator *separator;
|
||||
MenuButton *skeleton_options = nullptr;
|
||||
MenuButton *rest_options = nullptr;
|
||||
Button *edit_mode_button;
|
||||
|
||||
bool edit_mode = false;
|
||||
|
||||
EditorFileDialog *file_dialog = nullptr;
|
||||
|
||||
UndoRedo *undo_redo = nullptr;
|
||||
bool keyable;
|
||||
|
||||
void _on_click_option(int p_option);
|
||||
static Skeleton3DEditor *singleton;
|
||||
|
||||
void _on_click_skeleton_option(int p_skeleton_option);
|
||||
void _on_click_rest_option(int p_rest_option);
|
||||
void _file_selected(const String &p_file);
|
||||
TreeItem *_find(TreeItem *p_node, const NodePath &p_path);
|
||||
void edit_mode_toggled(const bool pressed);
|
||||
|
||||
EditorFileDialog *file_export_lib = nullptr;
|
||||
|
||||
|
@ -155,6 +179,10 @@ class Skeleton3DEditor : public VBoxContainer {
|
|||
|
||||
void create_editors();
|
||||
|
||||
void init_pose();
|
||||
void insert_keys(bool p_all_bones);
|
||||
void pose_to_rest();
|
||||
|
||||
void create_physical_skeleton();
|
||||
PhysicalBone3D *create_physical_bone(int bone_id, int bone_child_id, const Vector<BoneInfo> &bones_infos);
|
||||
|
||||
|
@ -162,20 +190,56 @@ class Skeleton3DEditor : public VBoxContainer {
|
|||
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
|
||||
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
|
||||
|
||||
void set_keyable(const bool p_keyable);
|
||||
void set_rest_options_enabled(const bool p_rest_options_enabled);
|
||||
|
||||
// Handle.
|
||||
MeshInstance3D *handles_mesh_instance;
|
||||
Ref<ImmediateMesh> handles_mesh;
|
||||
Ref<ShaderMaterial> handle_material;
|
||||
Ref<Shader> handle_shader;
|
||||
|
||||
Transform3D bone_original;
|
||||
|
||||
void _update_pose_enabled(int p_bone = -1);
|
||||
void _update_show_rest_only();
|
||||
|
||||
void _update_gizmo_transform();
|
||||
void _update_gizmo_visible();
|
||||
|
||||
void _hide_handles();
|
||||
|
||||
void _draw_gizmo();
|
||||
void _draw_handles();
|
||||
|
||||
void _joint_tree_selection_changed();
|
||||
void _joint_tree_rmb_select(const Vector2 &p_pos);
|
||||
void _update_properties();
|
||||
|
||||
void _subgizmo_selection_change();
|
||||
|
||||
int selected_bone = -1;
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
void _node_removed(Node *p_node);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
static Skeleton3DEditor *get_singleton() { return singleton; }
|
||||
|
||||
void select_bone(int p_idx);
|
||||
|
||||
int get_selected_bone() const;
|
||||
|
||||
void move_skeleton_bone(NodePath p_skeleton_path, int32_t p_selected_boneidx, int32_t p_target_boneidx);
|
||||
|
||||
Skeleton3D *get_skeleton() const { return skeleton; };
|
||||
|
||||
void _joint_tree_selection_changed();
|
||||
void _joint_tree_rmb_select(const Vector2 &p_pos);
|
||||
bool is_edit_mode() const { return edit_mode; }
|
||||
|
||||
void _update_properties();
|
||||
void update_bone_original();
|
||||
Transform3D get_bone_original() { return bone_original; };
|
||||
|
||||
Skeleton3DEditor(EditorInspectorPluginSkeleton *e_plugin, EditorNode *p_editor, Skeleton3D *skeleton);
|
||||
~Skeleton3DEditor();
|
||||
|
@ -186,6 +250,7 @@ class EditorInspectorPluginSkeleton : public EditorInspectorPlugin {
|
|||
|
||||
friend class Skeleton3DEditorPlugin;
|
||||
|
||||
Skeleton3DEditor *skel_editor;
|
||||
EditorNode *editor;
|
||||
|
||||
public:
|
||||
|
@ -196,12 +261,40 @@ public:
|
|||
class Skeleton3DEditorPlugin : public EditorPlugin {
|
||||
GDCLASS(Skeleton3DEditorPlugin, EditorPlugin);
|
||||
|
||||
EditorInspectorPluginSkeleton *skeleton_plugin;
|
||||
EditorNode *editor;
|
||||
|
||||
public:
|
||||
Skeleton3DEditorPlugin(EditorNode *p_node);
|
||||
virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override;
|
||||
|
||||
bool has_main_screen() const override { return false; }
|
||||
virtual bool handles(Object *p_object) const override;
|
||||
|
||||
virtual String get_name() const override { return "Skeleton3D"; }
|
||||
|
||||
Skeleton3DEditorPlugin(EditorNode *p_node);
|
||||
};
|
||||
|
||||
class Skeleton3DGizmoPlugin : public EditorNode3DGizmoPlugin {
|
||||
GDCLASS(Skeleton3DGizmoPlugin, EditorNode3DGizmoPlugin);
|
||||
|
||||
Ref<StandardMaterial3D> unselected_mat;
|
||||
Ref<ShaderMaterial> selected_mat;
|
||||
Ref<Shader> selected_sh;
|
||||
|
||||
public:
|
||||
bool has_gizmo(Node3D *p_spatial) override;
|
||||
String get_gizmo_name() const override;
|
||||
int get_priority() const override;
|
||||
|
||||
int subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const override;
|
||||
Transform3D get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
|
||||
void set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) override;
|
||||
void commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel) override;
|
||||
|
||||
void redraw(EditorNode3DGizmo *p_gizmo) override;
|
||||
|
||||
Skeleton3DGizmoPlugin();
|
||||
};
|
||||
|
||||
#endif // SKELETON_3D_EDITOR_PLUGIN_H
|
||||
|
|
|
@ -1833,8 +1833,8 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
|
|||
|
||||
editor_data->get_undo_redo().add_do_method(this, "_set_owners", edited_scene, owners);
|
||||
|
||||
if (AnimationPlayerEditor::singleton->get_track_editor()->get_root() == node) {
|
||||
editor_data->get_undo_redo().add_do_method(AnimationPlayerEditor::singleton->get_track_editor(), "set_root", node);
|
||||
if (AnimationPlayerEditor::get_singleton()->get_track_editor()->get_root() == node) {
|
||||
editor_data->get_undo_redo().add_do_method(AnimationPlayerEditor::get_singleton()->get_track_editor(), "set_root", node);
|
||||
}
|
||||
|
||||
editor_data->get_undo_redo().add_undo_method(new_parent, "remove_child", node);
|
||||
|
@ -1859,8 +1859,8 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
|
|||
editor_data->get_undo_redo().add_undo_method(node->get_parent(), "add_child", node);
|
||||
editor_data->get_undo_redo().add_undo_method(node->get_parent(), "move_child", node, child_pos);
|
||||
editor_data->get_undo_redo().add_undo_method(this, "_set_owners", edited_scene, owners);
|
||||
if (AnimationPlayerEditor::singleton->get_track_editor()->get_root() == node) {
|
||||
editor_data->get_undo_redo().add_undo_method(AnimationPlayerEditor::singleton->get_track_editor(), "set_root", node);
|
||||
if (AnimationPlayerEditor::get_singleton()->get_track_editor()->get_root() == node) {
|
||||
editor_data->get_undo_redo().add_undo_method(AnimationPlayerEditor::get_singleton()->get_track_editor(), "set_root", node);
|
||||
}
|
||||
|
||||
if (p_keep_global_xform) {
|
||||
|
@ -2071,8 +2071,8 @@ void SceneTreeDock::_delete_confirm(bool p_cut) {
|
|||
editor_data->get_undo_redo().add_do_method(n->get_parent(), "remove_child", n);
|
||||
editor_data->get_undo_redo().add_undo_method(n->get_parent(), "add_child", n);
|
||||
editor_data->get_undo_redo().add_undo_method(n->get_parent(), "move_child", n, n->get_index());
|
||||
if (AnimationPlayerEditor::singleton->get_track_editor()->get_root() == n) {
|
||||
editor_data->get_undo_redo().add_undo_method(AnimationPlayerEditor::singleton->get_track_editor(), "set_root", n);
|
||||
if (AnimationPlayerEditor::get_singleton()->get_track_editor()->get_root() == n) {
|
||||
editor_data->get_undo_redo().add_undo_method(AnimationPlayerEditor::get_singleton()->get_track_editor(), "set_root", n);
|
||||
}
|
||||
editor_data->get_undo_redo().add_undo_method(this, "_set_owners", edited_scene, owners);
|
||||
editor_data->get_undo_redo().add_undo_reference(n);
|
||||
|
|
|
@ -102,7 +102,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
|
|||
undo_redo->commit_action();
|
||||
} else if (p_id == BUTTON_PIN) {
|
||||
if (n->is_class("AnimationPlayer")) {
|
||||
AnimationPlayerEditor::singleton->unpin();
|
||||
AnimationPlayerEditor::get_singleton()->unpin();
|
||||
_update_tree();
|
||||
}
|
||||
|
||||
|
@ -386,7 +386,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll
|
|||
|
||||
_update_visibility_color(p_node, item);
|
||||
} else if (p_node->is_class("AnimationPlayer")) {
|
||||
bool is_pinned = AnimationPlayerEditor::singleton->get_player() == p_node && AnimationPlayerEditor::singleton->is_pinned();
|
||||
bool is_pinned = AnimationPlayerEditor::get_singleton()->get_player() == p_node && AnimationPlayerEditor::get_singleton()->is_pinned();
|
||||
|
||||
if (is_pinned) {
|
||||
item->add_button(0, get_theme_icon(SNAME("Pin"), SNAME("EditorIcons")), BUTTON_PIN, false, TTR("AnimationPlayer is pinned.\nClick to unpin."));
|
||||
|
|
|
@ -603,9 +603,9 @@ void GridMapEditor::_do_paste() {
|
|||
_clear_clipboard_data();
|
||||
}
|
||||
|
||||
bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
|
||||
EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
|
||||
if (!node) {
|
||||
return false;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
}
|
||||
|
||||
Ref<InputEventMouseButton> mb = p_event;
|
||||
|
@ -616,12 +616,12 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
|
|||
floor->set_value(floor->get_value() + mb->get_factor());
|
||||
}
|
||||
|
||||
return true; // Eaten.
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP; // Eaten.
|
||||
} else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && (mb->is_command_pressed() || mb->is_shift_pressed())) {
|
||||
if (mb->is_pressed()) {
|
||||
floor->set_value(floor->get_value() - mb->get_factor());
|
||||
}
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
|
||||
if (mb->is_pressed()) {
|
||||
|
@ -648,19 +648,22 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
|
|||
_clear_clipboard_data();
|
||||
input_action = INPUT_NONE;
|
||||
_update_paste_indicator();
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
} else if (selection.active) {
|
||||
_set_selection(false);
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
} else {
|
||||
input_action = INPUT_ERASE;
|
||||
set_items.clear();
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
}
|
||||
|
||||
return do_input_action(p_camera, Point2(mb->get_position().x, mb->get_position().y), true);
|
||||
if (do_input_action(p_camera, Point2(mb->get_position().x, mb->get_position().y), true)) {
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
} else {
|
||||
if ((mb->get_button_index() == MOUSE_BUTTON_RIGHT && input_action == INPUT_ERASE) || (mb->get_button_index() == MOUSE_BUTTON_LEFT && input_action == INPUT_PAINT)) {
|
||||
if (set_items.size()) {
|
||||
|
@ -677,7 +680,11 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
|
|||
}
|
||||
set_items.clear();
|
||||
input_action = INPUT_NONE;
|
||||
return set_items.size() > 0;
|
||||
|
||||
if (set_items.size() > 0) {
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
}
|
||||
|
||||
if (mb->get_button_index() == MOUSE_BUTTON_LEFT && input_action == INPUT_SELECT) {
|
||||
|
@ -690,11 +697,11 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
|
|||
if (mb->get_button_index() == MOUSE_BUTTON_LEFT && input_action != INPUT_NONE) {
|
||||
set_items.clear();
|
||||
input_action = INPUT_NONE;
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
if (mb->get_button_index() == MOUSE_BUTTON_RIGHT && (input_action == INPUT_ERASE || input_action == INPUT_PASTE)) {
|
||||
input_action = INPUT_NONE;
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -702,7 +709,10 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
|
|||
Ref<InputEventMouseMotion> mm = p_event;
|
||||
|
||||
if (mm.is_valid()) {
|
||||
return do_input_action(p_camera, mm->get_position(), false);
|
||||
if (do_input_action(p_camera, mm->get_position(), false)) {
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
}
|
||||
|
||||
Ref<InputEventKey> k = p_event;
|
||||
|
@ -714,16 +724,16 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
|
|||
_clear_clipboard_data();
|
||||
input_action = INPUT_NONE;
|
||||
_update_paste_indicator();
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
} else if (selection.active) {
|
||||
_set_selection(false);
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
} else {
|
||||
selected_palette = -1;
|
||||
mesh_library_palette->deselect_all();
|
||||
update_palette();
|
||||
_update_cursor_instance();
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -731,12 +741,12 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
|
|||
if (k->get_keycode() == options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_PREV_LEVEL))) {
|
||||
selection.click[edit_axis]--;
|
||||
_validate_selection();
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
if (k->get_keycode() == options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_NEXT_LEVEL))) {
|
||||
selection.click[edit_axis]++;
|
||||
_validate_selection();
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -755,12 +765,12 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
|
|||
if (step) {
|
||||
floor->set_value(floor->get_value() + step);
|
||||
}
|
||||
return true;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
}
|
||||
accumulated_floor_delta = 0.0;
|
||||
|
||||
return false;
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
}
|
||||
|
||||
struct _CGMEItemSort {
|
||||
|
|
|
@ -232,7 +232,7 @@ protected:
|
|||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
bool forward_spatial_input_event(Camera3D *p_camera, const Ref<InputEvent> &p_event);
|
||||
EditorPlugin::AfterGUIInput forward_spatial_input_event(Camera3D *p_camera, const Ref<InputEvent> &p_event);
|
||||
|
||||
void edit(GridMap *p_gridmap);
|
||||
GridMapEditor() {}
|
||||
|
@ -250,7 +250,7 @@ protected:
|
|||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
virtual bool forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return grid_map_editor->forward_spatial_input_event(p_camera, p_event); }
|
||||
virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return grid_map_editor->forward_spatial_input_event(p_camera, p_event); }
|
||||
virtual String get_name() const override { return "GridMap"; }
|
||||
bool has_main_screen() const override { return false; }
|
||||
virtual void edit(Object *p_object) override;
|
||||
|
|
|
@ -376,6 +376,18 @@ void Node3D::update_gizmos() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void Node3D::set_subgizmo_selection(Ref<Node3DGizmo> p_gizmo, int p_id, Transform3D p_transform) {
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (!is_inside_world()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Engine::get_singleton()->is_editor_hint() && get_tree()->is_node_being_edited(this)) {
|
||||
get_tree()->call_group_flags(0, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_set_subgizmo_selection, this, p_gizmo, p_id, p_transform);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Node3D::clear_subgizmo_selection() {
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (!is_inside_world()) {
|
||||
|
@ -792,6 +804,7 @@ void Node3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("add_gizmo", "gizmo"), &Node3D::add_gizmo);
|
||||
ClassDB::bind_method(D_METHOD("get_gizmos"), &Node3D::get_gizmos_bind);
|
||||
ClassDB::bind_method(D_METHOD("clear_gizmos"), &Node3D::clear_gizmos);
|
||||
ClassDB::bind_method(D_METHOD("set_subgizmo_selection", "gizmo", "id", "transform"), &Node3D::set_subgizmo_selection);
|
||||
ClassDB::bind_method(D_METHOD("clear_subgizmo_selection"), &Node3D::clear_subgizmo_selection);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_visible", "visible"), &Node3D::set_visible);
|
||||
|
|
|
@ -92,6 +92,7 @@ class Node3D : public Node {
|
|||
Vector<Ref<Node3DGizmo>> gizmos;
|
||||
bool gizmos_disabled = false;
|
||||
bool gizmos_dirty = false;
|
||||
bool transform_gizmo_visible = true;
|
||||
#endif
|
||||
|
||||
} data;
|
||||
|
@ -145,6 +146,8 @@ public:
|
|||
#ifdef TOOLS_ENABLED
|
||||
virtual Transform3D get_global_gizmo_transform() const;
|
||||
virtual Transform3D get_local_gizmo_transform() const;
|
||||
virtual void set_transform_gizmo_visible(bool p_enabled) { data.transform_gizmo_visible = p_enabled; };
|
||||
virtual bool is_transform_gizmo_visible() const { return data.transform_gizmo_visible; };
|
||||
#endif
|
||||
|
||||
void set_as_top_level(bool p_enabled);
|
||||
|
@ -155,6 +158,7 @@ public:
|
|||
|
||||
void set_disable_gizmos(bool p_enabled);
|
||||
void update_gizmos();
|
||||
void set_subgizmo_selection(Ref<Node3DGizmo> p_gizmo, int p_id, Transform3D p_transform = Transform3D());
|
||||
void clear_subgizmo_selection();
|
||||
Vector<Ref<Node3DGizmo>> get_gizmos() const;
|
||||
Array get_gizmos_bind() const;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "core/object/message_queue.h"
|
||||
#include "core/variant/type_info.h"
|
||||
#include "editor/plugins/skeleton_3d_editor_plugin.h"
|
||||
#include "scene/3d/physics_body_3d.h"
|
||||
#include "scene/resources/skeleton_modification_3d.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
|
@ -178,7 +179,7 @@ void Skeleton3D::_update_process_order() {
|
|||
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (bonesptr[i].parent >= len) {
|
||||
//validate this just in case
|
||||
// Validate this just in case.
|
||||
ERR_PRINT("Bone " + itos(i) + " has invalid parent: " + itos(bonesptr[i].parent));
|
||||
bonesptr[i].parent = -1;
|
||||
}
|
||||
|
@ -186,9 +187,9 @@ void Skeleton3D::_update_process_order() {
|
|||
if (bonesptr[i].parent != -1) {
|
||||
int parent_bone_idx = bonesptr[i].parent;
|
||||
|
||||
// Check to see if this node is already added to the parent:
|
||||
// Check to see if this node is already added to the parent.
|
||||
if (bonesptr[parent_bone_idx].child_bones.find(i) < 0) {
|
||||
// Add the child node
|
||||
// Add the child node.
|
||||
bonesptr[parent_bone_idx].child_bones.push_back(i);
|
||||
} else {
|
||||
ERR_PRINT("Skeleton3D parenthood graph is cyclic");
|
||||
|
@ -210,10 +211,10 @@ void Skeleton3D::_notification(int p_what) {
|
|||
int len = bones.size();
|
||||
dirty = false;
|
||||
|
||||
// Update bone transforms
|
||||
// Update bone transforms.
|
||||
force_update_all_bone_transforms();
|
||||
|
||||
//update skins
|
||||
// Update skins.
|
||||
for (Set<SkinReference *>::Element *E = skin_bindings.front(); E; E = E->next()) {
|
||||
const Skin *skin = E->get()->skin.operator->();
|
||||
RID skeleton = E->get()->skeleton;
|
||||
|
@ -231,7 +232,7 @@ void Skeleton3D::_notification(int p_what) {
|
|||
StringName bind_name = skin->get_bind_name(i);
|
||||
|
||||
if (bind_name != StringName()) {
|
||||
//bind name used, use this
|
||||
// Bind name used, use this.
|
||||
bool found = false;
|
||||
for (int j = 0; j < len; j++) {
|
||||
if (bonesptr[j].name == bind_name) {
|
||||
|
@ -453,7 +454,8 @@ int Skeleton3D::get_bone_axis_forward_enum(int p_bone) {
|
|||
return bones[p_bone].rest_bone_forward_axis;
|
||||
}
|
||||
|
||||
// skeleton creation api
|
||||
// Skeleton creation api
|
||||
|
||||
void Skeleton3D::add_bone(const String &p_name) {
|
||||
ERR_FAIL_COND(p_name == "" || p_name.find(":") != -1 || p_name.find("/") != -1);
|
||||
|
||||
|
@ -626,6 +628,7 @@ void Skeleton3D::set_bone_enabled(int p_bone, bool p_enabled) {
|
|||
ERR_FAIL_INDEX(p_bone, bone_size);
|
||||
|
||||
bones.write[p_bone].enabled = p_enabled;
|
||||
emit_signal(SceneStringNames::get_singleton()->bone_enabled_changed, p_bone);
|
||||
_make_dirty();
|
||||
}
|
||||
|
||||
|
@ -635,6 +638,16 @@ bool Skeleton3D::is_bone_enabled(int p_bone) const {
|
|||
return bones[p_bone].enabled;
|
||||
}
|
||||
|
||||
void Skeleton3D::set_show_rest_only(bool p_enabled) {
|
||||
show_rest_only = p_enabled;
|
||||
emit_signal(SceneStringNames::get_singleton()->show_rest_only_changed);
|
||||
_make_dirty();
|
||||
}
|
||||
|
||||
bool Skeleton3D::is_show_rest_only() const {
|
||||
return show_rest_only;
|
||||
}
|
||||
|
||||
void Skeleton3D::clear_bones() {
|
||||
bones.clear();
|
||||
process_order_dirty = true;
|
||||
|
@ -642,7 +655,7 @@ void Skeleton3D::clear_bones() {
|
|||
_make_dirty();
|
||||
}
|
||||
|
||||
// posing api
|
||||
// Posing api
|
||||
|
||||
void Skeleton3D::set_bone_pose(int p_bone, const Transform3D &p_pose) {
|
||||
const int bone_size = bones.size();
|
||||
|
@ -697,7 +710,7 @@ void Skeleton3D::localize_rests() {
|
|||
set_bone_rest(current_bone_idx, bones[bones[current_bone_idx].parent].rest.affine_inverse() * bones[current_bone_idx].rest);
|
||||
}
|
||||
|
||||
// Add the bone's children to the list of bones to be processed
|
||||
// Add the bone's children to the list of bones to be processed.
|
||||
int child_bone_size = bones[current_bone_idx].child_bones.size();
|
||||
for (int i = 0; i < child_bone_size; i++) {
|
||||
bones_to_process.push_back(bones[current_bone_idx].child_bones[i]);
|
||||
|
@ -831,7 +844,7 @@ void Skeleton3D::physical_bones_start_simulation_on(const TypedArray<StringName>
|
|||
|
||||
Vector<int> sim_bones;
|
||||
if (p_bones.size() <= 0) {
|
||||
sim_bones.push_back(0); // if no bones is specified, activate ragdoll on full body
|
||||
sim_bones.push_back(0); // If no bones is specified, activate ragdoll on full body.
|
||||
} else {
|
||||
sim_bones.resize(p_bones.size());
|
||||
int c = 0;
|
||||
|
@ -884,19 +897,19 @@ Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) {
|
|||
Ref<Skin> skin = p_skin;
|
||||
|
||||
if (skin.is_null()) {
|
||||
//need to create one from existing code, this is for compatibility only
|
||||
//when skeletons did not support skins. It is also used by gizmo
|
||||
//to display the skeleton.
|
||||
// Need to create one from existing code, this is for compatibility only
|
||||
// when skeletons did not support skins. It is also used by gizmo
|
||||
// to display the skeleton.
|
||||
|
||||
skin.instantiate();
|
||||
skin->set_bind_count(bones.size());
|
||||
_update_process_order(); //just in case
|
||||
_update_process_order(); // Just in case.
|
||||
|
||||
// pose changed, rebuild cache of inverses
|
||||
// Pose changed, rebuild cache of inverses.
|
||||
const Bone *bonesptr = bones.ptr();
|
||||
int len = bones.size();
|
||||
|
||||
// calculate global rests and invert them
|
||||
// Calculate global rests and invert them.
|
||||
LocalVector<int> bones_to_process;
|
||||
bones_to_process = get_parentless_bones();
|
||||
while (bones_to_process.size() > 0) {
|
||||
|
@ -919,7 +932,7 @@ Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) {
|
|||
}
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
//the inverse is what is actually required
|
||||
// The inverse is what is actually required.
|
||||
skin->set_bind_bone(i, i);
|
||||
skin->set_bind_pose(i, skin->get_bind_pose(i).affine_inverse());
|
||||
}
|
||||
|
@ -940,11 +953,17 @@ Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) {
|
|||
|
||||
skin->connect("changed", Callable(skin_ref.operator->(), "_skin_changed"));
|
||||
|
||||
_make_dirty(); //skin needs to be updated, so update skeleton
|
||||
_make_dirty(); // Skin needs to be updated, so update skeleton.
|
||||
|
||||
return skin_ref;
|
||||
}
|
||||
|
||||
void Skeleton3D::force_update_all_dirty_bones() {
|
||||
if (dirty) {
|
||||
const_cast<Skeleton3D *>(this)->notification(NOTIFICATION_UPDATE_SKELETON);
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton3D::force_update_all_bone_transforms() {
|
||||
_update_process_order();
|
||||
|
||||
|
@ -966,9 +985,10 @@ void Skeleton3D::force_update_bone_children_transforms(int p_bone_idx) {
|
|||
bones_to_process.erase(current_bone_idx);
|
||||
|
||||
Bone &b = bonesptr[current_bone_idx];
|
||||
bool bone_enabled = b.enabled && !show_rest_only;
|
||||
|
||||
if (b.disable_rest) {
|
||||
if (b.enabled) {
|
||||
if (bone_enabled) {
|
||||
Transform3D pose = b.pose;
|
||||
if (b.custom_pose_enable) {
|
||||
pose = b.custom_pose * pose;
|
||||
|
@ -991,7 +1011,7 @@ void Skeleton3D::force_update_bone_children_transforms(int p_bone_idx) {
|
|||
}
|
||||
|
||||
} else {
|
||||
if (b.enabled) {
|
||||
if (bone_enabled) {
|
||||
Transform3D pose = b.pose;
|
||||
if (b.custom_pose_enable) {
|
||||
pose = b.custom_pose * pose;
|
||||
|
@ -1035,7 +1055,7 @@ void Skeleton3D::force_update_bone_children_transforms(int p_bone_idx) {
|
|||
b.global_pose_override_amount = 0.0;
|
||||
}
|
||||
|
||||
// Add the bone's children to the list of bones to be processed
|
||||
// Add the bone's children to the list of bones to be processed.
|
||||
int child_bone_size = b.child_bones.size();
|
||||
for (int i = 0; i < child_bone_size; i++) {
|
||||
bones_to_process.push_back(b.child_bones[i]);
|
||||
|
@ -1045,7 +1065,7 @@ void Skeleton3D::force_update_bone_children_transforms(int p_bone_idx) {
|
|||
}
|
||||
}
|
||||
|
||||
// helper functions
|
||||
// Helper functions
|
||||
|
||||
Transform3D Skeleton3D::global_pose_to_world_transform(Transform3D p_global_pose) {
|
||||
return get_global_transform() * p_global_pose;
|
||||
|
@ -1175,6 +1195,9 @@ void Skeleton3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_bone_pose", "bone_idx"), &Skeleton3D::get_bone_pose);
|
||||
ClassDB::bind_method(D_METHOD("set_bone_pose", "bone_idx", "pose"), &Skeleton3D::set_bone_pose);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_bone_enabled", "bone_idx"), &Skeleton3D::is_bone_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_bone_enabled", "bone_idx", "enabled"), &Skeleton3D::set_bone_enabled, DEFVAL(true));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("clear_bones_global_pose_override"), &Skeleton3D::clear_bones_global_pose_override);
|
||||
ClassDB::bind_method(D_METHOD("set_bone_global_pose_override", "bone_idx", "pose", "amount", "persistent"), &Skeleton3D::set_bone_global_pose_override, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("get_bone_global_pose_override", "bone_idx"), &Skeleton3D::get_bone_global_pose_override);
|
||||
|
@ -1198,6 +1221,9 @@ void Skeleton3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("local_pose_to_global_pose", "bone_idx", "local_pose"), &Skeleton3D::local_pose_to_global_pose);
|
||||
ClassDB::bind_method(D_METHOD("global_pose_z_forward_to_bone_forward", "bone_idx", "basis"), &Skeleton3D::global_pose_z_forward_to_bone_forward);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_show_rest_only"), &Skeleton3D::set_show_rest_only);
|
||||
ClassDB::bind_method(D_METHOD("is_show_rest_only"), &Skeleton3D::is_show_rest_only);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_animate_physical_bones"), &Skeleton3D::set_animate_physical_bones);
|
||||
ClassDB::bind_method(D_METHOD("get_animate_physical_bones"), &Skeleton3D::get_animate_physical_bones);
|
||||
|
||||
|
@ -1212,6 +1238,7 @@ void Skeleton3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("execute_modifications", "delta", "execution_mode"), &Skeleton3D::execute_modifications);
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_rest_only"), "set_show_rest_only", "is_show_rest_only");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "animate_physical_bones"), "set_animate_physical_bones", "get_animate_physical_bones");
|
||||
#endif // _3D_DISABLED
|
||||
|
||||
|
@ -1220,6 +1247,8 @@ void Skeleton3D::_bind_methods() {
|
|||
#endif // TOOLS_ENABLED
|
||||
|
||||
ADD_SIGNAL(MethodInfo("bone_pose_changed", PropertyInfo(Variant::INT, "bone_idx")));
|
||||
ADD_SIGNAL(MethodInfo("bone_enabled_changed", PropertyInfo(Variant::INT, "bone_idx")));
|
||||
ADD_SIGNAL(MethodInfo("show_rest_only_changed"));
|
||||
|
||||
BIND_CONSTANT(NOTIFICATION_UPDATE_SKELETON);
|
||||
}
|
||||
|
@ -1228,7 +1257,7 @@ Skeleton3D::Skeleton3D() {
|
|||
}
|
||||
|
||||
Skeleton3D::~Skeleton3D() {
|
||||
//some skins may remain bound
|
||||
// Some skins may remain bound.
|
||||
for (Set<SkinReference *>::Element *E = skin_bindings.front(); E; E = E->next()) {
|
||||
E->get()->skeleton_node = nullptr;
|
||||
}
|
||||
|
|
|
@ -137,6 +137,8 @@ private:
|
|||
void _make_dirty();
|
||||
bool dirty = false;
|
||||
|
||||
bool show_rest_only = false;
|
||||
|
||||
uint64_t version = 1;
|
||||
|
||||
void _update_process_order();
|
||||
|
@ -197,6 +199,9 @@ public:
|
|||
|
||||
void set_bone_enabled(int p_bone, bool p_enabled);
|
||||
bool is_bone_enabled(int p_bone) const;
|
||||
|
||||
void set_show_rest_only(bool p_enabled);
|
||||
bool is_show_rest_only() const;
|
||||
void clear_bones();
|
||||
|
||||
// posing api
|
||||
|
@ -219,6 +224,7 @@ public:
|
|||
|
||||
Ref<SkinReference> register_skin(const Ref<Skin> &p_skin);
|
||||
|
||||
void force_update_all_dirty_bones();
|
||||
void force_update_all_bone_transforms();
|
||||
void force_update_bone_children_transforms(int bone_idx);
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ SceneStringNames::SceneStringNames() {
|
|||
|
||||
pose_updated = StaticCString::create("pose_updated");
|
||||
bone_pose_changed = StaticCString::create("bone_pose_changed");
|
||||
bone_enabled_changed = StaticCString::create("bone_enabled_changed");
|
||||
show_rest_only_changed = StaticCString::create("show_rest_only_changed");
|
||||
|
||||
mouse_entered = StaticCString::create("mouse_entered");
|
||||
mouse_exited = StaticCString::create("mouse_exited");
|
||||
|
@ -134,6 +136,7 @@ SceneStringNames::SceneStringNames() {
|
|||
|
||||
_spatial_editor_group = StaticCString::create("_spatial_editor_group");
|
||||
_request_gizmo = StaticCString::create("_request_gizmo");
|
||||
_set_subgizmo_selection = StaticCString::create("_set_subgizmo_selection");
|
||||
_clear_subgizmo_selection = StaticCString::create("_clear_subgizmo_selection");
|
||||
|
||||
offset = StaticCString::create("offset");
|
||||
|
|
|
@ -99,6 +99,8 @@ public:
|
|||
|
||||
StringName pose_updated;
|
||||
StringName bone_pose_changed;
|
||||
StringName bone_enabled_changed;
|
||||
StringName show_rest_only_changed;
|
||||
|
||||
StringName body_shape_entered;
|
||||
StringName body_entered;
|
||||
|
@ -154,6 +156,7 @@ public:
|
|||
|
||||
StringName _spatial_editor_group;
|
||||
StringName _request_gizmo;
|
||||
StringName _set_subgizmo_selection;
|
||||
StringName _clear_subgizmo_selection;
|
||||
|
||||
StringName offset;
|
||||
|
|
Loading…
Reference in a new issue