Fix Skeleton3D edit mode usability issues
This commit is contained in:
@@ -1518,15 +1518,32 @@ EditorPlugin::AfterGUIInput Skeleton3DEditorPlugin::forward_3d_gui_input(Camera3
|
||||
Node3DEditor *ne = Node3DEditor::get_singleton();
|
||||
if (se && se->is_edit_mode()) {
|
||||
const Ref<InputEventMouseButton> mb = p_event;
|
||||
if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) {
|
||||
Skeleton3D *skeleton = se->get_skeleton();
|
||||
if (skeleton) {
|
||||
int closest_idx = Skeleton3DGizmoPlugin::skeleton_intersect_ray(skeleton, p_camera, mb->get_position());
|
||||
if (closest_idx >= 0) {
|
||||
se->select_bone(closest_idx);
|
||||
se->update_bone_original();
|
||||
|
||||
Vector<Ref<Node3DGizmo>> gizmos = skeleton->get_gizmos();
|
||||
for (Ref<EditorNode3DGizmo> seg : gizmos) {
|
||||
if (seg.is_valid()) {
|
||||
Transform3D bone_xform = seg->get_subgizmo_transform(closest_idx);
|
||||
ne->call("_set_subgizmo_selection", skeleton, seg, closest_idx, bone_xform);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT) {
|
||||
if (ne->get_tool_mode() != Node3DEditor::TOOL_MODE_SELECT) {
|
||||
if (!ne->is_gizmo_visible()) {
|
||||
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
||||
}
|
||||
}
|
||||
if (mb->is_pressed()) {
|
||||
se->update_bone_original();
|
||||
}
|
||||
}
|
||||
return EditorPlugin::AFTER_GUI_INPUT_CUSTOM;
|
||||
}
|
||||
@@ -1629,19 +1646,27 @@ int Skeleton3DGizmoPlugin::subgizmos_intersect_ray(const EditorNode3DGizmo *p_gi
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (Node3DEditor::get_singleton()->get_tool_mode() != Node3DEditor::TOOL_MODE_SELECT) {
|
||||
return -1;
|
||||
int closest_idx = skeleton_intersect_ray(skeleton, p_camera, p_point);
|
||||
|
||||
if (closest_idx >= 0) {
|
||||
se->select_bone(closest_idx);
|
||||
se->update_bone_original();
|
||||
return closest_idx;
|
||||
}
|
||||
|
||||
// Select bone.
|
||||
real_t grab_threshold = 4 * EDSCALE;
|
||||
se->select_bone(-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Skeleton3DGizmoPlugin::skeleton_intersect_ray(const Skeleton3D *p_skeleton, Camera3D *p_camera, const Vector2 &p_point) {
|
||||
real_t grab_threshold = 8 * EDSCALE;
|
||||
Vector3 ray_from = p_camera->get_global_transform().origin;
|
||||
Transform3D gt = skeleton->get_global_transform();
|
||||
Transform3D gt = p_skeleton->get_global_transform();
|
||||
int closest_idx = -1;
|
||||
real_t closest_dist = 1e10;
|
||||
const int bone_count = skeleton->get_bone_count();
|
||||
const int bone_count = p_skeleton->get_bone_count();
|
||||
for (int i = 0; i < bone_count; i++) {
|
||||
Vector3 joint_pos_3d = gt.xform(skeleton->get_bone_global_pose(i).origin);
|
||||
Vector3 joint_pos_3d = gt.xform(p_skeleton->get_bone_global_pose(i).origin);
|
||||
Vector2 joint_pos_2d = p_camera->unproject_position(joint_pos_3d);
|
||||
real_t dist_3d = ray_from.distance_to(joint_pos_3d);
|
||||
real_t dist_2d = p_point.distance_to(joint_pos_2d);
|
||||
@@ -1650,14 +1675,7 @@ int Skeleton3DGizmoPlugin::subgizmos_intersect_ray(const EditorNode3DGizmo *p_gi
|
||||
closest_idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (closest_idx >= 0) {
|
||||
se->select_bone(closest_idx);
|
||||
return closest_idx;
|
||||
}
|
||||
|
||||
se->select_bone(-1);
|
||||
return -1;
|
||||
return closest_idx;
|
||||
}
|
||||
|
||||
Transform3D Skeleton3DGizmoPlugin::get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const {
|
||||
@@ -1705,25 +1723,35 @@ void Skeleton3DGizmoPlugin::commit_subgizmos(const EditorNode3DGizmo *p_gizmo, c
|
||||
|
||||
EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
|
||||
ur->create_action(TTR("Set Bone Transform"));
|
||||
if (ne->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || ne->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE) {
|
||||
for (int i = 0; i < p_ids.size(); i++) {
|
||||
ur->add_do_method(skeleton, "set_bone_pose_position", p_ids[i], skeleton->get_bone_pose_position(p_ids[i]));
|
||||
ur->add_undo_method(skeleton, "set_bone_pose_position", p_ids[i], se->get_bone_original_position());
|
||||
|
||||
if (p_cancel) {
|
||||
for (int id : p_ids) {
|
||||
ur->add_do_method(skeleton, "set_bone_pose_position", id, se->get_bone_original_position());
|
||||
ur->add_do_method(skeleton, "set_bone_pose_rotation", id, se->get_bone_original_rotation());
|
||||
ur->add_do_method(skeleton, "set_bone_pose_scale", id, se->get_bone_original_scale());
|
||||
ur->add_undo_method(skeleton, "set_bone_pose_position", id, skeleton->get_bone_pose_position(id));
|
||||
ur->add_undo_method(skeleton, "set_bone_pose_rotation", id, skeleton->get_bone_pose_rotation(id));
|
||||
ur->add_undo_method(skeleton, "set_bone_pose_scale", id, skeleton->get_bone_pose_scale(id));
|
||||
}
|
||||
}
|
||||
if (ne->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || ne->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) {
|
||||
for (int i = 0; i < p_ids.size(); i++) {
|
||||
ur->add_do_method(skeleton, "set_bone_pose_rotation", p_ids[i], skeleton->get_bone_pose_rotation(p_ids[i]));
|
||||
ur->add_undo_method(skeleton, "set_bone_pose_rotation", p_ids[i], se->get_bone_original_rotation());
|
||||
} else {
|
||||
Node3DEditor::ToolMode tool_mode = ne->get_tool_mode();
|
||||
if (tool_mode == Node3DEditor::TOOL_MODE_SELECT || tool_mode == Node3DEditor::TOOL_MODE_MOVE || tool_mode == Node3DEditor::TOOL_MODE_TRANSFORM) {
|
||||
for (int id : p_ids) {
|
||||
ur->add_do_method(skeleton, "set_bone_pose_position", id, skeleton->get_bone_pose_position(id));
|
||||
ur->add_undo_method(skeleton, "set_bone_pose_position", id, se->get_bone_original_position());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ne->get_tool_mode() == Node3DEditor::TOOL_MODE_SCALE) {
|
||||
for (int i = 0; i < p_ids.size(); i++) {
|
||||
// If the axis is swapped by scaling, the rotation can be changed.
|
||||
ur->add_do_method(skeleton, "set_bone_pose_rotation", p_ids[i], skeleton->get_bone_pose_rotation(p_ids[i]));
|
||||
ur->add_undo_method(skeleton, "set_bone_pose_rotation", p_ids[i], se->get_bone_original_rotation());
|
||||
ur->add_do_method(skeleton, "set_bone_pose_scale", p_ids[i], skeleton->get_bone_pose_scale(p_ids[i]));
|
||||
ur->add_undo_method(skeleton, "set_bone_pose_scale", p_ids[i], se->get_bone_original_scale());
|
||||
if (tool_mode == Node3DEditor::TOOL_MODE_SELECT || tool_mode == Node3DEditor::TOOL_MODE_ROTATE || tool_mode == Node3DEditor::TOOL_MODE_TRANSFORM) {
|
||||
for (int id : p_ids) {
|
||||
ur->add_do_method(skeleton, "set_bone_pose_rotation", id, skeleton->get_bone_pose_rotation(id));
|
||||
ur->add_undo_method(skeleton, "set_bone_pose_rotation", id, se->get_bone_original_rotation());
|
||||
}
|
||||
}
|
||||
if (tool_mode == Node3DEditor::TOOL_MODE_SCALE || tool_mode == Node3DEditor::TOOL_MODE_TRANSFORM) {
|
||||
for (int id : p_ids) {
|
||||
ur->add_do_method(skeleton, "set_bone_pose_scale", id, skeleton->get_bone_pose_scale(id));
|
||||
ur->add_undo_method(skeleton, "set_bone_pose_scale", id, se->get_bone_original_scale());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -292,15 +292,16 @@ class Skeleton3DGizmoPlugin : public EditorNode3DGizmoPlugin {
|
||||
|
||||
public:
|
||||
static Ref<ArrayMesh> get_bones_mesh(Skeleton3D *p_skeleton, int p_selected, bool p_is_selected);
|
||||
static int skeleton_intersect_ray(const Skeleton3D *p_skeleton, Camera3D *p_camera, const Vector2 &p_point);
|
||||
|
||||
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;
|
||||
virtual int subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const override;
|
||||
virtual Transform3D get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
|
||||
virtual void set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) override;
|
||||
virtual 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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user