mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-12-24 04:46:48 +01:00
Backported from Godot4: Implemented SkeletonEditorGizmo.
-TokageItLab, lyuma
f2e9867e9f
- It still has some issues, as this one works differently than the 3.x version, they will be fixed later.
This commit is contained in:
parent
d662b2f3c9
commit
92600420ba
@ -203,6 +203,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">
|
||||
</return>
|
||||
@ -296,6 +303,14 @@
|
||||
<description>
|
||||
</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" />
|
||||
@ -401,7 +416,18 @@
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<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>
|
||||
@ -412,6 +438,10 @@
|
||||
<description>
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="show_rest_only_changed">
|
||||
<description>
|
||||
</description>
|
||||
</signal>
|
||||
</signals>
|
||||
<constants>
|
||||
<constant name="NOTIFICATION_UPDATE_SKELETON" value="50">
|
||||
|
@ -237,6 +237,15 @@
|
||||
Sets whether the node notifies about its global and local transformation changes. [Spatial] 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="SpatialGizmo" />
|
||||
<argument index="1" name="id" type="int" />
|
||||
<argument index="2" name="transform" type="Transform" />
|
||||
<description>
|
||||
Set subgizmo selection for this node in the editor.
|
||||
</description>
|
||||
</method>
|
||||
<method name="show">
|
||||
<return type="void" />
|
||||
<description>
|
||||
|
@ -6403,3 +6403,31 @@ bool AnimationTrackEditor::has_transform_key(Spatial *p_node, const String &p_su
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AnimationTrackEditor::has_transform_track(Spatial *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) {
|
||||
//TODO
|
||||
//if (animation->track_get_type(track_id) == Animation::TYPE_TRANSFORM) {
|
||||
// return true;
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -30,15 +30,13 @@
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/range.h"
|
||||
#include "scene/gui/control.h"
|
||||
#include "core/reference.h"
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/control.h"
|
||||
#include "scene/gui/range.h"
|
||||
|
||||
#include "scene/gui/slider.h"
|
||||
|
||||
#include "scene/resources/texture.h"
|
||||
#include "scene/resources/animation.h"
|
||||
#include "core/dictionary.h"
|
||||
#include "core/list.h"
|
||||
#include "core/map.h"
|
||||
@ -49,6 +47,8 @@
|
||||
#include "core/ustring.h"
|
||||
#include "core/variant.h"
|
||||
#include "core/vector.h"
|
||||
#include "scene/resources/animation.h"
|
||||
#include "scene/resources/texture.h"
|
||||
|
||||
class AnimationTrackEdit;
|
||||
class Button;
|
||||
@ -582,10 +582,12 @@ public:
|
||||
void goto_next_step(bool p_from_mouse_event);
|
||||
|
||||
MenuButton *get_edit_menu();
|
||||
|
||||
AnimationTrackEditor();
|
||||
~AnimationTrackEditor();
|
||||
|
||||
bool has_transform_key(Spatial *p_node, const String &p_sub);
|
||||
bool has_transform_track(Spatial *p_node, const String &p_sub);
|
||||
};
|
||||
|
||||
#endif // ANIMATION_TRACK_EDITOR_H
|
||||
|
@ -6901,6 +6901,33 @@ void SpatialEditor::_request_gizmo(Object *p_obj) {
|
||||
}
|
||||
}
|
||||
|
||||
void SpatialEditor::_set_subgizmo_selection(Object *p_obj, Ref<SpatialGizmo> p_gizmo, int p_id, Transform p_transform) {
|
||||
if (p_id == -1) {
|
||||
_clear_subgizmo_selection(p_obj);
|
||||
return;
|
||||
}
|
||||
|
||||
Spatial *sp = nullptr;
|
||||
if (p_obj) {
|
||||
sp = Object::cast_to<Spatial>(p_obj);
|
||||
} else {
|
||||
sp = selected;
|
||||
}
|
||||
|
||||
if (!sp) {
|
||||
return;
|
||||
}
|
||||
|
||||
SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
|
||||
if (se) {
|
||||
se->subgizmos.clear();
|
||||
se->subgizmos.insert(p_id, p_transform);
|
||||
se->gizmo = p_gizmo;
|
||||
sp->update_gizmos();
|
||||
update_transform_gizmo();
|
||||
}
|
||||
}
|
||||
|
||||
void SpatialEditor::_clear_subgizmo_selection(Object *p_obj) {
|
||||
Spatial *sp = nullptr;
|
||||
if (p_obj) {
|
||||
@ -7022,6 +7049,7 @@ void SpatialEditor::_bind_methods() {
|
||||
ClassDB::bind_method("_xform_dialog_action", &SpatialEditor::_xform_dialog_action);
|
||||
ClassDB::bind_method("_get_editor_data", &SpatialEditor::_get_editor_data);
|
||||
ClassDB::bind_method("_request_gizmo", &SpatialEditor::_request_gizmo);
|
||||
ClassDB::bind_method("_set_subgizmo_selection", &SpatialEditor::_set_subgizmo_selection);
|
||||
ClassDB::bind_method("_clear_subgizmo_selection", &SpatialEditor::_clear_subgizmo_selection);
|
||||
ClassDB::bind_method("_toggle_maximize_view", &SpatialEditor::_toggle_maximize_view);
|
||||
ClassDB::bind_method("_refresh_menu_icons", &SpatialEditor::_refresh_menu_icons);
|
||||
@ -7513,6 +7541,14 @@ void SpatialEditorPlugin::set_state(const Dictionary &p_state) {
|
||||
spatial_editor->set_state(p_state);
|
||||
}
|
||||
|
||||
bool SpatialEditor::is_gizmo_visible() const {
|
||||
if (selected) {
|
||||
return gizmo.visible && selected->is_transform_gizmo_visible();
|
||||
}
|
||||
return gizmo.visible;
|
||||
}
|
||||
|
||||
|
||||
void SpatialEditor::snap_cursor_to_plane(const Plane &p_plane) {
|
||||
//cursor.pos=p_plane.project(cursor.pos);
|
||||
}
|
||||
|
@ -727,6 +727,7 @@ private:
|
||||
Spatial *selected;
|
||||
|
||||
void _request_gizmo(Object *p_obj);
|
||||
void _set_subgizmo_selection(Object *p_obj, Ref<SpatialGizmo> p_gizmo, int p_id, Transform p_transform = Transform());
|
||||
void _clear_subgizmo_selection(Object *p_obj = nullptr);
|
||||
|
||||
static SpatialEditor *singleton;
|
||||
@ -758,7 +759,7 @@ public:
|
||||
float get_fov() const { return settings_fov->get_value(); }
|
||||
|
||||
Transform 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[SpatialEditor::TOOL_OPT_LOCAL_COORDS]->is_pressed(); }
|
||||
|
@ -1166,7 +1166,7 @@ void EditorSpatialGizmoPlugin::_bind_methods() {
|
||||
MethodInfo cs = MethodInfo("commit_subgizmos", GIZMO_REF, PropertyInfo(Variant::POOL_INT_ARRAY, "ids"), PropertyInfo(Variant::ARRAY, "restore"), PropertyInfo(Variant::BOOL, "cancel"));
|
||||
cs.default_arguments.push_back(false);
|
||||
BIND_VMETHOD(cs);
|
||||
|
||||
|
||||
#undef GIZMO_REF
|
||||
}
|
||||
|
||||
@ -1270,13 +1270,13 @@ Transform EditorSpatialGizmoPlugin::get_subgizmo_transform(const EditorSpatialGi
|
||||
return Transform();
|
||||
}
|
||||
|
||||
void EditorSpatialGizmoPlugin::set_subgizmo_transform(const EditorSpatialGizmo *p_gizmo, int p_id, Transform p_transform) const {
|
||||
void EditorSpatialGizmoPlugin::set_subgizmo_transform(const EditorSpatialGizmo *p_gizmo, int p_id, Transform p_transform) {
|
||||
if (get_script_instance() && get_script_instance()->has_method("set_subgizmo_transform")) {
|
||||
get_script_instance()->call("set_subgizmo_transform", p_id, p_transform);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorSpatialGizmoPlugin::commit_subgizmos(const EditorSpatialGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform> &p_restore, bool p_cancel) const {
|
||||
void EditorSpatialGizmoPlugin::commit_subgizmos(const EditorSpatialGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform> &p_restore, bool p_cancel) {
|
||||
if (get_script_instance() && get_script_instance()->has_method("commit_subgizmos")) {
|
||||
Array ids;
|
||||
for (int i = 0; i < p_ids.size(); i++) {
|
||||
|
@ -186,8 +186,8 @@ public:
|
||||
virtual int subgizmos_intersect_ray(const EditorSpatialGizmo *p_gizmo, Camera *p_camera, const Vector2 &p_point) const;
|
||||
virtual Vector<int> subgizmos_intersect_frustum(const EditorSpatialGizmo *p_gizmo, const Camera *p_camera, const Vector<Plane> &p_frustum) const;
|
||||
virtual Transform get_subgizmo_transform(const EditorSpatialGizmo *p_gizmo, int p_id) const;
|
||||
virtual void set_subgizmo_transform(const EditorSpatialGizmo *p_gizmo, int p_id, Transform p_transform) const;
|
||||
virtual void commit_subgizmos(const EditorSpatialGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform> &p_restore, bool p_cancel = false) const;
|
||||
virtual void set_subgizmo_transform(const EditorSpatialGizmo *p_gizmo, int p_id, Transform p_transform);
|
||||
virtual void commit_subgizmos(const EditorSpatialGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform> &p_restore, bool p_cancel = false);
|
||||
|
||||
|
||||
Ref<EditorSpatialGizmo> get_gizmo(Spatial *p_spatial);
|
||||
|
@ -4,5 +4,4 @@ env.add_source_files(env.modules_sources,"register_types.cpp")
|
||||
|
||||
if env["tools"]:
|
||||
env.add_source_files(env.modules_sources, "skeleton_editor_plugin.cpp")
|
||||
env.add_source_files(env.modules_sources, "spatial_editor_gizmos.cpp")
|
||||
|
||||
|
@ -24,7 +24,6 @@ SOFTWARE.
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
#include "skeleton_editor_plugin.h"
|
||||
#include "spatial_editor_gizmos.h"
|
||||
#endif
|
||||
|
||||
void register_skeleton_editor_types() {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -38,6 +38,7 @@
|
||||
#include "scene/3d/camera.h"
|
||||
#include "scene/3d/mesh_instance.h"
|
||||
#include "scene/3d/skeleton.h"
|
||||
#include "scene/resources/immediate_mesh.h"
|
||||
|
||||
class EditorInspectorPluginSkeleton;
|
||||
class Joint;
|
||||
@ -93,6 +94,8 @@ class BoneTransformEditor : public VBoxContainer {
|
||||
void _value_changed_transform(const String &p_path, const Variant &p_value, const String &p_name = "", bool changing = false);
|
||||
// Changes the transform to the given transform and updates the UI accordingly.
|
||||
void _change_transform(Transform p_new_transform);
|
||||
// Update it is truely keyable then.
|
||||
void _update_key_button(const bool p_keyable);
|
||||
// Creates a Transform using the EditorPropertyVector3 properties.
|
||||
Transform compute_transform_from_vector3s() const;
|
||||
|
||||
@ -116,6 +119,10 @@ public:
|
||||
// Transform can be keyed, whether or not to show the button
|
||||
void set_keyable(const bool p_keyable);
|
||||
|
||||
// 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);
|
||||
|
||||
@ -126,45 +133,32 @@ public:
|
||||
void _checkbox_toggled(const bool p_toggled);
|
||||
};
|
||||
|
||||
class ModuleSkeletonEditor : public VBoxContainer {
|
||||
GDCLASS(ModuleSkeletonEditor, VBoxContainer);
|
||||
class SkeletonEditor : public VBoxContainer {
|
||||
GDCLASS(SkeletonEditor, VBoxContainer);
|
||||
|
||||
friend class SkeletonEditorPlugin;
|
||||
|
||||
enum Menu {
|
||||
MENU_OPTION_INIT_POSE,
|
||||
MENU_OPTION_INSERT_KEYS,
|
||||
MENU_OPTION_INSERT_KEYS_EXISTED,
|
||||
MENU_OPTION_POSE_TO_REST,
|
||||
MENU_OPTION_CREATE_PHYSICAL_SKELETON,
|
||||
MENU_OPTION_ADD_BONE,
|
||||
MENU_OPTION_REMOVE_BONE,
|
||||
MENU_OPTION_RENAME_BONE
|
||||
enum SkeletonOption {
|
||||
SKELETON_OPTION_INIT_POSE,
|
||||
SKELETON_OPTION_INSERT_KEYS,
|
||||
SKELETON_OPTION_INSERT_KEYS_EXISTED,
|
||||
SKELETON_OPTION_CREATE_PHYSICAL_SKELETON,
|
||||
SKELETON_OPTION_ADD_BONE,
|
||||
SKELETON_OPTION_REMOVE_BONE,
|
||||
SKELETON_OPTION_RENAME_BONE
|
||||
};
|
||||
|
||||
enum ToolMode {
|
||||
TOOL_MODE_BONE_SELECT,
|
||||
TOOL_MODE_BONE_MOVE,
|
||||
TOOL_MODE_BONE_ROTATE,
|
||||
TOOL_MODE_BONE_SCALE,
|
||||
TOOL_MODE_BONE_NONE,
|
||||
TOOL_MODE_BONE_MAX
|
||||
};
|
||||
|
||||
enum MenuToolOption {
|
||||
MENU_TOOL_BONE_SELECT,
|
||||
MENU_TOOL_BONE_MOVE,
|
||||
MENU_TOOL_BONE_ROTATE,
|
||||
MENU_TOOL_BONE_SCALE,
|
||||
MENU_TOOL_BONE_NONE,
|
||||
MENU_TOOL_BONE_MAX
|
||||
enum RestOption {
|
||||
REST_OPTION_POSE_TO_REST
|
||||
};
|
||||
|
||||
struct BoneInfo {
|
||||
PhysicalBone *physical_bone;
|
||||
Transform relative_rest; // Relative to skeleton node
|
||||
BoneInfo() :
|
||||
physical_bone(NULL) {}
|
||||
|
||||
BoneInfo() {
|
||||
physical_bone = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
EditorNode *editor;
|
||||
@ -177,24 +171,24 @@ class ModuleSkeletonEditor : public VBoxContainer {
|
||||
BoneTransformEditor *pose_editor;
|
||||
BoneTransformEditor *custom_pose_editor;
|
||||
|
||||
VSeparator *separators[2];
|
||||
MenuButton *options;
|
||||
ToolButton *tool_button[TOOL_MODE_BONE_MAX];
|
||||
ToolButton *rest_mode_button;
|
||||
VSeparator *separator;
|
||||
MenuButton *skeleton_options;
|
||||
MenuButton *rest_options;
|
||||
Button *edit_mode_button;
|
||||
|
||||
ToolMode tool_mode = TOOL_MODE_BONE_NONE;
|
||||
bool rest_mode = false;
|
||||
bool edit_mode;
|
||||
|
||||
EditorFileDialog *file_dialog;
|
||||
|
||||
UndoRedo *undo_redo;
|
||||
|
||||
bool keyable;
|
||||
|
||||
void _on_click_option(int p_option);
|
||||
static SkeletonEditor *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);
|
||||
void _menu_tool_item_pressed(int p_option);
|
||||
void rest_mode_toggled(const bool pressed);
|
||||
TreeItem *_find(TreeItem *p_node, const NodePath &p_path);
|
||||
void edit_mode_toggled(const bool pressed);
|
||||
|
||||
EditorFileDialog *file_export_lib;
|
||||
|
||||
@ -206,6 +200,7 @@ class ModuleSkeletonEditor : public VBoxContainer {
|
||||
void init_pose();
|
||||
void insert_keys(bool p_all_bones);
|
||||
void pose_to_rest();
|
||||
|
||||
void create_physical_skeleton();
|
||||
PhysicalBone *create_physical_bone(int bone_id, int bone_child_id, const Vector<BoneInfo> &bones_infos);
|
||||
|
||||
@ -213,22 +208,34 @@ class ModuleSkeletonEditor : 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);
|
||||
|
||||
MeshInstance *handles_mesh_instance;
|
||||
Ref<ImmediateMesh> handles_mesh;
|
||||
Ref<ShaderMaterial> handle_material;
|
||||
Ref<Shader> handle_shader;
|
||||
MeshInstance *pointsm;
|
||||
Ref<ArrayMesh> am;
|
||||
|
||||
Transform 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();
|
||||
|
||||
SpatialEditorViewport::EditData _edit;
|
||||
void _compute_edit(int p_index, const Point2 &p_point);
|
||||
bool _gizmo_select(int p_index, const Vector2 &p_screenpos, bool p_highlight_only = false);
|
||||
void _joint_tree_selection_changed();
|
||||
void _joint_tree_rmb_select(const Vector2 &p_pos);
|
||||
void _update_properties();
|
||||
|
||||
Transform original_local;
|
||||
Transform original_global;
|
||||
Transform original_to_local;
|
||||
void _subgizmo_selection_change();
|
||||
|
||||
void _update_spatial_transform_gizmo();
|
||||
int selected_bone;
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
@ -236,23 +243,23 @@ protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event);
|
||||
void move_skeleton_bone(NodePath p_skeleton_path, int32_t p_selected_boneidx, int32_t p_target_boneidx);
|
||||
static SkeletonEditor *get_singleton() { return singleton; }
|
||||
|
||||
// Transform can be keyed, whether or not to show the button
|
||||
void set_keyable(const bool p_keyable);
|
||||
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);
|
||||
|
||||
Skeleton *get_skeleton() const { return skeleton; };
|
||||
|
||||
void set_rest_mode_toggled(const bool pressed);
|
||||
bool is_edit_mode() const { return edit_mode; }
|
||||
|
||||
void _joint_tree_selection_changed();
|
||||
void _joint_tree_rmb_select(const Vector2 &p_pos);
|
||||
void update_bone_original();
|
||||
Transform get_bone_original() { return bone_original; };
|
||||
|
||||
void _update_properties();
|
||||
|
||||
ModuleSkeletonEditor(EditorInspectorPluginSkeleton *e_plugin, EditorNode *p_editor, Skeleton *skeleton);
|
||||
~ModuleSkeletonEditor();
|
||||
SkeletonEditor(EditorInspectorPluginSkeleton *e_plugin, EditorNode *p_editor, Skeleton *skeleton);
|
||||
~SkeletonEditor();
|
||||
|
||||
void add_bone();
|
||||
void remove_bone();
|
||||
@ -277,20 +284,15 @@ class EditorInspectorPluginSkeleton : public EditorInspectorPlugin {
|
||||
|
||||
friend class SkeletonEditorPlugin;
|
||||
|
||||
ModuleSkeletonEditor *skel_editor;
|
||||
SkeletonEditor *skel_editor;
|
||||
EditorNode *editor;
|
||||
UndoRedo *undo_redo;
|
||||
|
||||
void set_rest_mode_toggled(const bool p_pressed);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event) { return skel_editor->forward_spatial_gui_input(p_camera, p_event); }
|
||||
virtual bool can_handle(Object *p_object);
|
||||
virtual void parse_begin(Object *p_object);
|
||||
UndoRedo *get_undo_redo() { return undo_redo; }
|
||||
};
|
||||
|
||||
class SkeletonEditorPlugin : public EditorPlugin {
|
||||
@ -300,12 +302,8 @@ class SkeletonEditorPlugin : public EditorPlugin {
|
||||
EditorNode *editor;
|
||||
|
||||
public:
|
||||
virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event) {
|
||||
if (SpatialEditor::get_singleton()->get_tool_mode() != SpatialEditor::TOOL_MODE_EXTERNAL) {
|
||||
return EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||
}
|
||||
return skeleton_plugin->forward_spatial_gui_input(p_camera, p_event);
|
||||
}
|
||||
virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event);
|
||||
|
||||
bool has_main_screen() const { return false; }
|
||||
virtual bool handles(Object *p_object) const;
|
||||
|
||||
@ -317,4 +315,26 @@ protected:
|
||||
void _notification(int p_what);
|
||||
};
|
||||
|
||||
class SkeletonGizmoPlugin : public EditorSpatialGizmoPlugin {
|
||||
GDCLASS(SkeletonGizmoPlugin, EditorSpatialGizmoPlugin);
|
||||
|
||||
Ref<SpatialMaterial> unselected_mat;
|
||||
Ref<ShaderMaterial> selected_mat;
|
||||
Ref<Shader> selected_sh;
|
||||
|
||||
public:
|
||||
bool has_gizmo(Spatial *p_spatial);
|
||||
String get_gizmo_name() const;
|
||||
int get_priority() const;
|
||||
|
||||
int subgizmos_intersect_ray(const EditorSpatialGizmo *p_gizmo, Camera *p_camera, const Vector2 &p_point) const;
|
||||
Transform get_subgizmo_transform(const EditorSpatialGizmo *p_gizmo, int p_id) const;
|
||||
void set_subgizmo_transform(const EditorSpatialGizmo *p_gizmo, int p_id, Transform p_transform);
|
||||
void commit_subgizmos(const EditorSpatialGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform> &p_restore, bool p_cancel);
|
||||
|
||||
void redraw(EditorSpatialGizmo *p_gizmo);
|
||||
|
||||
SkeletonGizmoPlugin();
|
||||
};
|
||||
|
||||
#endif // SKELETON_EDITOR_PLUGIN_H
|
||||
|
@ -1,18 +0,0 @@
|
||||
In case it's needed later
|
||||
|
||||
+ void Skeleton::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
for (int i = 0; i < bones.size(); i++) {
|
||||
String prep = "bones/" + itos(i) + "/";
|
||||
-p_list->push_back(PropertyInfo(Variant::STRING, prep + "name"));
|
||||
-p_list->push_back(PropertyInfo(Variant::INT, prep + "parent", PROPERTY_HINT_RANGE, "-1," + itos(bones.size() - 1) + ",1"));
|
||||
-p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "rest"));
|
||||
-p_list->push_back(PropertyInfo(Variant::BOOL, prep + "enabled"));
|
||||
+p_list->push_back(PropertyInfo(Variant::STRING, prep + "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
|
||||
+p_list->push_back(PropertyInfo(Variant::INT, prep + "parent", PROPERTY_HINT_RANGE, "-1," + itos(bones.size() - 1) + ",1", PROPERTY_USAGE_NOEDITOR));
|
||||
+p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "rest", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
|
||||
+p_list->push_back(PropertyInfo(Variant::BOOL, prep + "enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
|
||||
p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "pose", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
|
||||
-p_list->push_back(PropertyInfo(Variant::ARRAY, prep + "bound_children"));
|
||||
+p_list->push_back(PropertyInfo(Variant::ARRAY, prep + "bound_children", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
|
||||
}
|
||||
}
|
@ -1,269 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* spatial_editor_gizmos.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "spatial_editor_gizmos.h"
|
||||
|
||||
#include "editor/editor_settings.h"
|
||||
#include "scene/3d/skeleton.h"
|
||||
#include "scene/resources/skin.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
|
||||
SkeletonSpatialGizmoPlugin::SkeletonSpatialGizmoPlugin() {
|
||||
skeleton_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/skeleton", Color(1, 0.8, 0.4));
|
||||
selected_bone_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/selected_bone", Color(1, 0, 0));
|
||||
bone_axis_length = EDITOR_DEF("editors/3d_gizmos/gizmo_settings/bone_axis_length", (float)0.015);
|
||||
create_material("skeleton_material", skeleton_color);
|
||||
selected_mat = Ref<ShaderMaterial>(memnew(ShaderMaterial));
|
||||
selected_sh = Ref<Shader>(memnew(Shader));
|
||||
selected_sh->set_code(" \
|
||||
shader_type spatial; \
|
||||
render_mode unshaded; \
|
||||
uniform vec4 albedo : hint_color = vec4(1,1,1,1); \
|
||||
uniform sampler2D texture_albedo : hint_albedo; \
|
||||
uniform float point_size : hint_range(0,128) = 32; \
|
||||
void vertex() { \
|
||||
if (!OUTPUT_IS_SRGB) { \
|
||||
COLOR.rgb = mix( pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb* (1.0 / 12.92), lessThan(COLOR.rgb,vec3(0.04045)) ); \
|
||||
} \
|
||||
VERTEX = VERTEX; \
|
||||
POSITION=PROJECTION_MATRIX*INV_CAMERA_MATRIX*WORLD_MATRIX*vec4(VERTEX.xyz,1.0); \
|
||||
POSITION.z = mix(POSITION.z, -POSITION.w, 0.998); \
|
||||
} \
|
||||
void fragment() { \
|
||||
vec2 base_uv = UV; \
|
||||
vec4 albedo_tex = texture(texture_albedo,base_uv); \
|
||||
albedo_tex *= COLOR; \
|
||||
if (albedo.a * albedo_tex.a < 0.5) { discard; } \
|
||||
ALBEDO = albedo.rgb * albedo_tex.rgb; \
|
||||
} \
|
||||
");
|
||||
selected_mat->set_shader(selected_sh);
|
||||
}
|
||||
|
||||
bool SkeletonSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
|
||||
return Object::cast_to<Skeleton>(p_spatial) != NULL;
|
||||
}
|
||||
|
||||
String SkeletonSpatialGizmoPlugin::get_gizmo_name() const {
|
||||
return "Skeleton";
|
||||
}
|
||||
|
||||
int SkeletonSpatialGizmoPlugin::get_priority() const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void SkeletonSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
|
||||
Skeleton *skel = Object::cast_to<Skeleton>(p_gizmo->get_spatial_node());
|
||||
|
||||
skel->force_update_all_bone_transforms();
|
||||
|
||||
p_gizmo->clear();
|
||||
|
||||
Ref<Material> material;
|
||||
if (p_gizmo->is_selected()) {
|
||||
material = selected_mat;
|
||||
} else {
|
||||
material = get_material("skeleton_material", p_gizmo);
|
||||
}
|
||||
|
||||
Ref<SurfaceTool> surface_tool(memnew(SurfaceTool));
|
||||
|
||||
surface_tool->begin(Mesh::PRIMITIVE_LINES);
|
||||
surface_tool->set_material(material);
|
||||
Vector<Transform> grests;
|
||||
grests.resize(skel->get_bone_count());
|
||||
|
||||
Vector<int> bones;
|
||||
Vector<float> weights;
|
||||
bones.resize(4);
|
||||
weights.resize(4);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
bones.write[i] = 0;
|
||||
weights.write[i] = 0;
|
||||
}
|
||||
|
||||
weights.write[0] = 1;
|
||||
|
||||
Color bone_color;
|
||||
AABB aabb;
|
||||
|
||||
//LocalVector<int> bones_to_process = skel->get_parentless_bones();
|
||||
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();
|
||||
|
||||
// You have children but no parent, then you must be a root/parentless bone.
|
||||
if (child_bones_size >= 0 && skel->get_bone_parent(current_bone_idx) <= 0) {
|
||||
grests.write[current_bone_idx] = skel->global_pose_to_local_pose(current_bone_idx, skel->get_bone_global_pose(current_bone_idx));
|
||||
}
|
||||
|
||||
for (int i = 0; i < child_bones_size; i++) {
|
||||
int child_bone_idx = child_bones_vector[i];
|
||||
|
||||
int parent = skel->get_bone_parent(child_bone_idx);
|
||||
if (parent == skel->get_selected_bone()) {
|
||||
bone_color = selected_bone_color;
|
||||
} else {
|
||||
bone_color = skeleton_color;
|
||||
}
|
||||
|
||||
grests.write[child_bone_idx] = skel->global_pose_to_local_pose(child_bone_idx, skel->get_bone_global_pose(child_bone_idx));
|
||||
Vector3 v0 = grests[current_bone_idx].origin;
|
||||
Vector3 v1 = grests[child_bone_idx].origin;
|
||||
Vector3 d = skel->get_bone_rest(child_bone_idx).origin.normalized();
|
||||
real_t dist = skel->get_bone_rest(child_bone_idx).origin.length();
|
||||
|
||||
// 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 pointidx = 0;
|
||||
//Color axis_color[3];
|
||||
//axis_color[0] = Color(1, 0, 0);
|
||||
//axis_color[1] = Color(0, 1, 0);
|
||||
//axis_color[2] = Color(0, 0, 1);
|
||||
for (int j = 0; j < 3; j++) {
|
||||
/*
|
||||
if (p_gizmo->is_selected()) {
|
||||
bones.write[0] = current_bone_idx;
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(axis_color[j]);
|
||||
surface_tool->add_vertex(v1);
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(axis_color[j]);
|
||||
surface_tool->add_vertex(v1 + (grests[current_bone_idx].basis.inverse())[j].normalized() * bone_axis_length);
|
||||
} else {
|
||||
bones.write[0] = current_bone_idx;
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(axis_color[j]);
|
||||
surface_tool->add_vertex(v1 - (grests[current_bone_idx].basis.inverse())[j].normalized() * bone_axis_length * 0.5);
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(axis_color[j]);
|
||||
surface_tool->add_vertex(v1 + (grests[current_bone_idx].basis.inverse())[j].normalized() * bone_axis_length * 0.5);
|
||||
}*/
|
||||
|
||||
bones.write[0] = current_bone_idx;
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(bone_color);
|
||||
surface_tool->add_vertex(v0 - grests[current_bone_idx].basis[j].normalized() * dist * 0.05);
|
||||
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(bone_color);
|
||||
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.write[0] = current_bone_idx;
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(bone_color);
|
||||
surface_tool->add_vertex(v0);
|
||||
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(bone_color);
|
||||
surface_tool->add_vertex(point);
|
||||
|
||||
bones.write[0] = current_bone_idx;
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(bone_color);
|
||||
surface_tool->add_vertex(point);
|
||||
|
||||
bones.write[0] = child_bone_idx;
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(bone_color);
|
||||
surface_tool->add_vertex(v1);
|
||||
points[pointidx++] = point;
|
||||
}
|
||||
}
|
||||
|
||||
SWAP(points[1], points[2]);
|
||||
for (int j = 0; j < 4; j++) {
|
||||
bones.write[0] = current_bone_idx;
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(bone_color);
|
||||
surface_tool->add_vertex(points[j]);
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(bone_color);
|
||||
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>(), Transform(), skel->register_skin(Ref<Skin>()));
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
#ifndef MODULE_SPATIAL_EDITOR_GIZMOS_H
|
||||
#define MODULE_SPATIAL_EDITOR_GIZMOS_H
|
||||
/*************************************************************************/
|
||||
/* spatial_editor_gizmos.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "editor/spatial_editor_gizmos.h"
|
||||
#include "scene/3d/camera.h"
|
||||
#include "core/local_vector.h"
|
||||
|
||||
class Camera;
|
||||
|
||||
class SkeletonSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
|
||||
GDCLASS(SkeletonSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
|
||||
Color skeleton_color = Color(1, 0.8, 0.4);
|
||||
Color selected_bone_color = Color(1, 0, 0);
|
||||
float bone_axis_length = 0.015;
|
||||
Ref<ShaderMaterial> selected_mat;
|
||||
Ref<Shader> selected_sh;
|
||||
|
||||
public:
|
||||
bool has_gizmo(Spatial *p_spatial);
|
||||
String get_gizmo_name() const;
|
||||
int get_priority() const;
|
||||
void redraw(EditorSpatialGizmo *p_gizmo);
|
||||
|
||||
SkeletonSpatialGizmoPlugin();
|
||||
};
|
||||
|
||||
#endif // SPATIAL_EDITOR_GIZMOS_H
|
@ -658,6 +658,7 @@ void Skeleton::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();
|
||||
}
|
||||
|
||||
@ -667,6 +668,16 @@ bool Skeleton::is_bone_enabled(int p_bone) const {
|
||||
return bones[p_bone].enabled;
|
||||
}
|
||||
|
||||
void Skeleton::set_show_rest_only(bool p_enabled) {
|
||||
show_rest_only = p_enabled;
|
||||
emit_signal(SceneStringNames::get_singleton()->show_rest_only_changed);
|
||||
_make_dirty();
|
||||
}
|
||||
|
||||
bool Skeleton::is_show_rest_only() const {
|
||||
return show_rest_only;
|
||||
}
|
||||
|
||||
void Skeleton::clear_bones() {
|
||||
bones.clear();
|
||||
process_order_dirty = true;
|
||||
@ -1065,6 +1076,12 @@ Ref<SkinReference> Skeleton::register_skin(const Ref<Skin> &p_skin) {
|
||||
return skin_ref;
|
||||
}
|
||||
|
||||
void Skeleton::force_update_all_dirty_bones() {
|
||||
if (dirty) {
|
||||
const_cast<Skeleton *>(this)->notification(NOTIFICATION_UPDATE_SKELETON);
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::force_update_all_bone_transforms() {
|
||||
_update_process_order();
|
||||
|
||||
@ -1086,9 +1103,10 @@ void Skeleton::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) {
|
||||
b.update_pose_cache();
|
||||
Transform pose = b.pose_cache;
|
||||
if (b.custom_pose_enable) {
|
||||
@ -1112,7 +1130,7 @@ void Skeleton::force_update_bone_children_transforms(int p_bone_idx) {
|
||||
}
|
||||
|
||||
} else {
|
||||
if (b.enabled) {
|
||||
if (bone_enabled) {
|
||||
b.update_pose_cache();
|
||||
Transform pose = b.pose_cache;
|
||||
if (b.custom_pose_enable) {
|
||||
@ -1303,6 +1321,9 @@ void Skeleton::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_bone_pose_rotation", "bone_idx"), &Skeleton::get_bone_pose_rotation);
|
||||
ClassDB::bind_method(D_METHOD("get_bone_pose_scale", "bone_idx"), &Skeleton::get_bone_pose_scale);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_bone_enabled", "bone_idx"), &Skeleton::is_bone_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_bone_enabled", "bone_idx", "enabled"), &Skeleton::set_bone_enabled, true);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("clear_bones_global_pose_override"), &Skeleton::clear_bones_global_pose_override);
|
||||
ClassDB::bind_method(D_METHOD("set_bone_global_pose_override", "bone_idx", "pose", "amount", "persistent"), &Skeleton::set_bone_global_pose_override, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("get_bone_global_pose_override", "bone_idx"), &Skeleton::get_bone_global_pose_override);
|
||||
@ -1326,6 +1347,10 @@ void Skeleton::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("local_pose_to_global_pose", "bone_idx", "local_pose"), &Skeleton::local_pose_to_global_pose);
|
||||
ClassDB::bind_method(D_METHOD("global_pose_z_forward_to_bone_forward", "bone_idx", "basis"), &Skeleton::global_pose_z_forward_to_bone_forward);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_show_rest_only"), &Skeleton::set_show_rest_only);
|
||||
ClassDB::bind_method(D_METHOD("is_show_rest_only"), &Skeleton::is_show_rest_only);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_rest_only"), "set_show_rest_only", "is_show_rest_only");
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_animate_physical_bones"), &Skeleton::get_animate_physical_bones);
|
||||
@ -1351,6 +1376,8 @@ void Skeleton::_bind_methods() {
|
||||
|
||||
ADD_SIGNAL(MethodInfo("bone_pose_changed", PropertyInfo(Variant::INT, "bone_idx")));
|
||||
ADD_SIGNAL(MethodInfo("bones_updated"));
|
||||
ADD_SIGNAL(MethodInfo("bone_enabled_changed", PropertyInfo(Variant::INT, "bone_idx")));
|
||||
ADD_SIGNAL(MethodInfo("show_rest_only_changed"));
|
||||
|
||||
BIND_CONSTANT(NOTIFICATION_UPDATE_SKELETON);
|
||||
|
||||
@ -1362,6 +1389,7 @@ Skeleton::Skeleton() {
|
||||
dirty = false;
|
||||
version = 1;
|
||||
process_order_dirty = true;
|
||||
show_rest_only = false;
|
||||
}
|
||||
|
||||
Skeleton::~Skeleton() {
|
||||
|
@ -158,6 +158,8 @@ private:
|
||||
void _make_dirty();
|
||||
bool dirty;
|
||||
|
||||
bool show_rest_only;
|
||||
|
||||
uint64_t version;
|
||||
|
||||
void _update_process_order();
|
||||
@ -220,6 +222,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
|
||||
@ -250,6 +255,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);
|
||||
|
||||
|
@ -552,6 +552,20 @@ void Spatial::update_gizmos() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void Spatial::set_subgizmo_selection(Ref<SpatialGizmo> p_gizmo, int p_id, Transform 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 Spatial::clear_subgizmo_selection() {
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (!is_inside_world()) {
|
||||
@ -940,6 +954,7 @@ void Spatial::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("add_gizmo", "gizmo"), &Spatial::add_gizmo);
|
||||
ClassDB::bind_method(D_METHOD("get_gizmos"), &Spatial::get_gizmos_bind);
|
||||
ClassDB::bind_method(D_METHOD("clear_gizmos"), &Spatial::clear_gizmos);
|
||||
ClassDB::bind_method(D_METHOD("set_subgizmo_selection", "gizmo", "id", "transform"), &Spatial::set_subgizmo_selection);
|
||||
ClassDB::bind_method(D_METHOD("clear_subgizmo_selection"), &Spatial::clear_subgizmo_selection);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_visible", "visible"), &Spatial::set_visible);
|
||||
@ -1020,6 +1035,7 @@ Spatial::Spatial() :
|
||||
#ifdef TOOLS_ENABLED
|
||||
data.gizmos_disabled = false;
|
||||
data.gizmos_dirty = false;
|
||||
data.transform_gizmo_visible = true;
|
||||
#endif
|
||||
data.notify_local_transform = false;
|
||||
data.notify_transform = false;
|
||||
|
@ -110,6 +110,7 @@ class Spatial : public Node {
|
||||
Vector<Ref<SpatialGizmo>> gizmos;
|
||||
bool gizmos_disabled : 1;
|
||||
bool gizmos_dirty : 1;
|
||||
bool transform_gizmo_visible : 1;
|
||||
#endif
|
||||
|
||||
} data;
|
||||
@ -180,6 +181,8 @@ public:
|
||||
#ifdef TOOLS_ENABLED
|
||||
virtual Transform get_global_gizmo_transform() const;
|
||||
virtual Transform 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; };
|
||||
virtual AABB get_fallback_gizmo_aabb() const;
|
||||
#endif
|
||||
|
||||
@ -191,6 +194,7 @@ public:
|
||||
|
||||
void set_disable_gizmos(bool p_enabled);
|
||||
void update_gizmos();
|
||||
void set_subgizmo_selection(Ref<SpatialGizmo> p_gizmo, int p_id, Transform p_transform = Transform());
|
||||
void clear_subgizmo_selection();
|
||||
Vector<Ref<SpatialGizmo>> get_gizmos() const;
|
||||
Vector<Variant> get_gizmos_bind() const;
|
||||
|
@ -68,6 +68,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");
|
||||
@ -142,6 +144,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;
|
||||
@ -160,6 +162,7 @@ public:
|
||||
|
||||
StringName _spatial_editor_group;
|
||||
StringName _request_gizmo;
|
||||
StringName _set_subgizmo_selection;
|
||||
StringName _clear_subgizmo_selection;
|
||||
|
||||
StringName offset;
|
||||
|
Loading…
Reference in New Issue
Block a user