Path: blob/master/editor/scene/3d/skeleton_3d_editor_plugin.h
21635 views
/**************************************************************************/1/* skeleton_3d_editor_plugin.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "editor/gui/editor_file_dialog.h"33#include "editor/inspector/add_metadata_dialog.h"34#include "editor/inspector/editor_properties.h"35#include "editor/plugins/editor_plugin.h"36#include "editor/scene/3d/node_3d_editor_plugin.h"37#include "scene/3d/camera_3d.h"38#include "scene/3d/mesh_instance_3d.h"39#include "scene/3d/skeleton_3d.h"40#include "scene/resources/immediate_mesh.h"4142class EditorInspectorPluginSkeleton;43class EditorPropertyVector3;44class Joint;45class PhysicalBone3D;46class Skeleton3DEditorPlugin;47class Button;48class Tree;49class TreeItem;50class VSeparator;5152class BonePropertiesEditor : public VBoxContainer {53GDCLASS(BonePropertiesEditor, VBoxContainer);5455EditorInspectorSection *section = nullptr;5657EditorPropertyCheck *enabled_checkbox = nullptr;58EditorPropertyVector3 *position_property = nullptr;59EditorPropertyQuaternion *rotation_property = nullptr;60EditorPropertyVector3 *scale_property = nullptr;6162EditorInspectorSection *rest_section = nullptr;63EditorPropertyTransform3D *rest_matrix = nullptr;6465EditorInspectorSection *meta_section = nullptr;66AddMetadataDialog *add_meta_dialog = nullptr;6768Rect2 background_rects[5];6970Skeleton3D *skeleton = nullptr;71// String property;7273bool toggle_enabled = false;74bool updating = false;7576String label;7778void create_editors();7980void _value_changed(const String &p_property, const Variant &p_value, const String &p_name, bool p_changing);8182void _property_keyed(const String &p_path, bool p_advance);8384void _meta_changed(const String &p_property, const Variant &p_value, const String &p_name, bool p_changing);85void _meta_deleted(const String &p_property);86void _show_add_meta_dialog();87void _add_meta_confirm();8889HashMap<StringName, EditorProperty *> meta_editors;9091protected:92void _notification(int p_what);9394public:95BonePropertiesEditor(Skeleton3D *p_skeleton);9697// Which transform target to modify.98void set_target(const String &p_prop);99void set_label(const String &p_label) { label = p_label; }100void set_keyable(const bool p_keyable);101void set_skeleton(Skeleton3D *p_skeleton);102103void _update_properties();104};105106class Skeleton3DEditor : public VBoxContainer {107GDCLASS(Skeleton3DEditor, VBoxContainer);108109static void _bind_methods();110111friend class Skeleton3DEditorPlugin;112113enum SkeletonOption {114SKELETON_OPTION_RESET_ALL_POSES,115SKELETON_OPTION_RESET_SELECTED_POSES,116SKELETON_OPTION_ALL_POSES_TO_RESTS,117SKELETON_OPTION_SELECTED_POSES_TO_RESTS,118SKELETON_OPTION_CREATE_PHYSICAL_SKELETON,119SKELETON_OPTION_EXPORT_SKELETON_PROFILE,120};121122struct BoneInfo {123PhysicalBone3D *physical_bone = nullptr;124Transform3D relative_rest; // Relative to skeleton node.125};126127EditorInspectorPluginSkeleton *editor_plugin = nullptr;128129Skeleton3D *skeleton = nullptr;130131enum {132JOINT_BUTTON_REVERT = 0,133};134135Tree *joint_tree = nullptr;136BonePropertiesEditor *rest_editor = nullptr;137BonePropertiesEditor *pose_editor = nullptr;138139HBoxContainer *topmenu_bar = nullptr;140MenuButton *skeleton_options = nullptr;141Button *edit_mode_button = nullptr;142143bool edit_mode = false;144145HBoxContainer *animation_hb = nullptr;146Button *key_loc_button = nullptr;147Button *key_rot_button = nullptr;148Button *key_scale_button = nullptr;149Button *key_insert_button = nullptr;150Button *key_insert_new_button = nullptr;151Button *key_mod_insert_button = nullptr;152Button *key_mod_insert_new_button = nullptr;153154// To maintain the status while running editor.155void _loc_toggled(bool p_toggled_on);156void _rot_toggled(bool p_toggled_on);157void _scl_toggled(bool p_toggled_on);158159EditorInspectorSection *bones_section = nullptr;160161EditorFileDialog *file_dialog = nullptr;162163bool keyable = false;164165static Skeleton3DEditor *singleton;166167void _on_click_skeleton_option(int p_skeleton_option);168void _file_selected(const String &p_file);169TreeItem *_find(TreeItem *p_node, const NodePath &p_path);170void edit_mode_toggled(const bool pressed);171172EditorFileDialog *file_export_lib = nullptr;173174void update_joint_tree();175void update_all();176177void create_editors();178179void reset_pose(const bool p_all_bones);180void pose_to_rest(const bool p_all_bones);181182void _insert_keys(const bool p_all_bones);183void insert_keys(const bool p_all_bones, const bool p_enable_modifier);184185void create_physical_skeleton();186PhysicalBone3D *create_physical_bone(int bone_id, int bone_child_id, const Vector<BoneInfo> &bones_infos);187188void export_skeleton_profile();189190Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);191bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;192void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);193194void set_keyable(const bool p_keyable);195void set_bone_options_enabled(const bool p_bone_options_enabled);196197// Handle.198MeshInstance3D *handles_mesh_instance = nullptr;199Ref<ImmediateMesh> handles_mesh;200Ref<ShaderMaterial> handle_material;201Ref<Shader> handle_shader;202203Vector3 bone_original_position;204Quaternion bone_original_rotation;205Vector3 bone_original_scale;206207void _update_gizmo_visible();208void _bone_enabled_changed(const int p_bone_id);209210void _hide_handles();211212void _draw_gizmo();213void _draw_handles();214215void _joint_tree_selection_changed();216void _joint_tree_rmb_select(const Vector2 &p_pos, MouseButton p_button);217void _joint_tree_button_clicked(Object *p_item, int p_column, int p_id, MouseButton p_button);218void _update_properties();219220void _subgizmo_selection_change();221void _disconnect_from_skeleton();222223int selected_bone = -1;224225protected:226void _notification(int p_what);227void _node_removed(Node *p_node);228229public:230static Skeleton3DEditor *get_singleton() { return singleton; }231232void select_bone(int p_idx);233234int get_selected_bone() const;235236void move_skeleton_bone(NodePath p_skeleton_path, int32_t p_selected_boneidx, int32_t p_target_boneidx);237238Skeleton3D *get_skeleton() const { return skeleton; }239240bool is_edit_mode() const { return edit_mode; }241242void update_bone_original();243Vector3 get_bone_original_position() const { return bone_original_position; }244Quaternion get_bone_original_rotation() const { return bone_original_rotation; }245Vector3 get_bone_original_scale() const { return bone_original_scale; }246247Skeleton3DEditor(EditorInspectorPluginSkeleton *e_plugin, Skeleton3D *skeleton);248~Skeleton3DEditor();249};250251class EditorInspectorPluginSkeleton : public EditorInspectorPlugin {252GDCLASS(EditorInspectorPluginSkeleton, EditorInspectorPlugin);253254friend class Skeleton3DEditorPlugin;255256Skeleton3DEditor *skel_editor = nullptr;257258public:259bool loc_pressed = false;260bool rot_pressed = true;261bool scl_pressed = false;262263virtual bool can_handle(Object *p_object) override;264virtual void parse_begin(Object *p_object) override;265};266267class Skeleton3DEditorPlugin : public EditorPlugin {268GDCLASS(Skeleton3DEditorPlugin, EditorPlugin);269270EditorInspectorPluginSkeleton *skeleton_plugin = nullptr;271272public:273virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override;274275bool has_main_screen() const override { return false; }276virtual bool handles(Object *p_object) const override;277278virtual String get_plugin_name() const override { return "Skeleton3D"; }279280Skeleton3DEditorPlugin();281};282283class Skeleton3DGizmoPlugin : public EditorNode3DGizmoPlugin {284GDCLASS(Skeleton3DGizmoPlugin, EditorNode3DGizmoPlugin);285286struct SelectionMaterials {287Ref<StandardMaterial3D> unselected_mat;288Ref<ShaderMaterial> selected_mat;289};290static SelectionMaterials selection_materials;291292public:293static Ref<ArrayMesh> get_bones_mesh(Skeleton3D *p_skeleton, int p_selected, bool p_is_selected);294static int skeleton_intersect_ray(const Skeleton3D *p_skeleton, Camera3D *p_camera, const Vector2 &p_point);295296bool has_gizmo(Node3D *p_spatial) override;297String get_gizmo_name() const override;298int get_priority() const override;299300virtual int subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const override;301virtual Transform3D get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const override;302virtual void set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) override;303virtual void commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel) override;304305void redraw(EditorNode3DGizmo *p_gizmo) override;306307Skeleton3DGizmoPlugin();308~Skeleton3DGizmoPlugin();309};310311312