diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2019-09-01 17:21:22 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2019-09-03 19:35:36 +0300 |
commit | e91ea20ebee800600ec073f9738b448778372453 (patch) | |
tree | 5ba45f03fc6fa53b45ae085cd561afb60dea0a26 /source/blender/blenkernel | |
parent | b3b59e3b5657ad95ecca4b8c47c3b20c7e55da35 (diff) |
Drivers: support decomposing rotation into swing followed by twist.
In order to correctly drive corrective shape keys from a freely
rotating organic joint it is very often found necessary to
decompose the rotation into separate bending and twisting
motions. This type of decomposition cannot be reproduced by
any Euler order or a single quaternion.
Instead this is done by using a helper bone with a Damped Track
constraint aimed at the tail of the control to pick up the bending,
and its helper child with Copy Transforms to separate the twist.
Requiring two additional bones to drive a shape key or a correction
bone seems inconvenient, so this implements the necessary math as new
options in the recently introduced Rotation Mode dropdown of the
Transform Channel driver variable type. The data is also accessible
as a Transformation constraint input.
The output is in the form of Quaternion-derived 'pseudo-angles',
which for `Swing and Y Twist` would represent the following:
* W: true bend angle, independent of bend direction.
* Y: true twist angle.
* X, Z: pseudo-angles representing the proportion of bending around X/Z.
Reviewers: brecht
Differential Revision: https://developer.blender.org/D5651
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/intern/fcurve.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index c4da2d2efc9..b596eeb9e35 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1798,6 +1798,25 @@ void BKE_driver_target_matrix_to_rot_channels( quaternion_to_angles(quat, channel); } } + else if (rotation_mode >= DTAR_ROTMODE_SWING_TWIST_X && + rotation_mode <= DTAR_ROTMODE_SWING_TWIST_Z) { + int axis = rotation_mode - DTAR_ROTMODE_SWING_TWIST_X; + float raw_quat[4], twist; + + mat4_to_quat(raw_quat, mat); + + if (channel == axis + 1) { + /* If only the twist angle is needed, skip computing swing. */ + twist = quat_split_swing_and_twist(raw_quat, axis, NULL, NULL); + } + else { + twist = quat_split_swing_and_twist(raw_quat, axis, quat, NULL); + + quaternion_to_angles(quat, channel); + } + + quat[axis + 1] = twist; + } else { BLI_assert(false); } |