Animation: Add in Parent space alignment option to the Transform Orientation gizmo

Animation: Adds a new "Parent Space" Orientation option for the Transformation Gizmo.

---
For child targets (objects, bones, etc) being able to transform in parent space is a desired feature (especially when it comes to rigging / animation).

For objects:
* with a parent, the gizmo orients to it's parents orientation
* without a parent, the gizmo orients to Global space

For Armatures:
* Child bone shows parent's space regardless if "Local Location" is set for parent bone
* For root bone **without** "Local Location" set, use the armature objects space.
* For root bone **with** "Local Location" set, use local bone space.

---

No new transformation orientation code needs to be written, we can achieve the desired results be using the existing `transform_orientations_create_from_axis`, `ED_getTransformOrientationMatrix`, and `unit_m3` methods. To do this, we check to see if the bone has a parent, if so, we use the bones pose matrix (`pose_mat`). This is done similarly for objects using the parent's object matrix (`object_to_world`).

Pull Request: https://projects.blender.org/blender/blender/pulls/104724
This commit is contained in:
Nate Rupsis
2023-04-20 17:40:19 +02:00
committed by Nate Rupsis
parent 0e23aef6b6
commit 5c4b0c98d3
3 changed files with 50 additions and 1 deletions

View File

@@ -580,6 +580,33 @@ void ED_transform_calc_orientation_from_type(const bContext *C, float r_mat[3][3
scene, view_layer, v3d, rv3d, ob, obedit, orient_index, pivot_point, r_mat);
}
static void handle_armature_parent_orientation(Object *ob, float r_mat[3][3])
{
bPoseChannel *active_pchan = BKE_pose_channel_active(ob, false);
/* Check if target bone is a child. */
if (active_pchan->parent) {
/* For child, show parent local regardless if "local location" is set for parent bone. */
transform_orientations_create_from_axis(r_mat, UNPACK3(active_pchan->parent->pose_mat));
return;
}
/* For root, use local transform of armature object. */
transform_orientations_create_from_axis(r_mat, UNPACK3(ob->object_to_world));
}
static void handle_object_parent_orientation(Object *ob, float r_mat[3][3])
{
/* If object has parent, then orient to parent. */
if (ob->parent) {
transform_orientations_create_from_axis(r_mat, UNPACK3(ob->parent->object_to_world));
}
else {
/* If object doesn't have parent, then orient to world. */
unit_m3(r_mat);
}
}
short ED_transform_calc_orientation_from_type_ex(const Scene *scene,
ViewLayer *view_layer,
const View3D *v3d,
@@ -609,6 +636,20 @@ short ED_transform_calc_orientation_from_type_ex(const Scene *scene,
/* If not gimbal, fall through to normal. */
ATTR_FALLTHROUGH;
}
case V3D_ORIENT_PARENT: {
if (ob) {
if (ob->mode & OB_MODE_POSE) {
handle_armature_parent_orientation(ob, r_mat);
break;
}
else {
handle_object_parent_orientation(ob, r_mat);
break;
}
}
/* No break; we define 'parent' as 'normal' otherwise. */
ATTR_FALLTHROUGH;
}
case V3D_ORIENT_NORMAL: {
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
ED_getTransformOrientationMatrix(scene, view_layer, v3d, ob, obedit, pivot_point, r_mat);
@@ -621,7 +662,7 @@ short ED_transform_calc_orientation_from_type_ex(const Scene *scene,
if (ob) {
if (ob->mode & OB_MODE_POSE) {
/* Each bone moves on its own local axis, but to avoid confusion,
* use the active pones axis for display #33575, this works as expected on a single
* use the active bone's axis for display #33575, this works as expected on a single
* bone and users who select many bones will understand what's going on and what local
* means when they start transforming. */
ED_getTransformOrientationMatrix(scene, view_layer, v3d, ob, obedit, pivot_point, r_mat);
@@ -741,6 +782,8 @@ const char *transform_orientations_spacename_get(TransInfo *t, const short orien
return TIP_("view");
case V3D_ORIENT_CURSOR:
return TIP_("cursor");
case V3D_ORIENT_PARENT:
return TIP_("parent");
case V3D_ORIENT_CUSTOM_MATRIX:
return TIP_("custom");
case V3D_ORIENT_CUSTOM:

View File

@@ -630,6 +630,7 @@ enum {
V3D_ORIENT_VIEW = 3,
V3D_ORIENT_GIMBAL = 4,
V3D_ORIENT_CURSOR = 5,
V3D_ORIENT_PARENT = 6,
V3D_ORIENT_CUSTOM = 1024,
/** Runtime only, never saved to DNA. */
V3D_ORIENT_CUSTOM_MATRIX = (V3D_ORIENT_CUSTOM - 1),

View File

@@ -628,6 +628,11 @@ const EnumPropertyItem rna_enum_transform_orientation_items[] = {
ICON_ORIENTATION_CURSOR,
"Cursor",
"Align the transformation axes to the 3D cursor"},
{V3D_ORIENT_PARENT,
"PARENT",
ICON_BLANK1,
"Parent",
"Align the transformation axes to the object's parent space"},
// {V3D_ORIENT_CUSTOM, "CUSTOM", 0, "Custom", "Use a custom transform orientation"},
{0, NULL, 0, NULL, NULL},
};