Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gavrilov <angavrilov@gmail.com>2019-09-01 13:19:11 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2019-09-01 14:13:23 +0300
commit18d4ad5a59d32922f9d70b0412da0c830baceb17 (patch)
treec6e630362f87e533b5482ae7fd096ce49d0eeab6 /source/blender/blenkernel/intern/fcurve.c
parentae43b1d51b4a0384c2197a6aca5cd2810c9283ff (diff)
Copy Rotation & Transform: add Euler order override options.
For reasons similar to drivers, it should be possible to set an explicit Euler rotation order in constraints that use Euler angles. The Transform constraint in a way approaches drivers in its use, in that it effectively alters channels using values of other channels after applying a fixed form mathematical expression. For this reason, instead of just specifying the euler order for its inputs, it uses the same enum as driver variables. However Quaternion components are converted to a weighted pseudo-angle representation as the rest of the constraint UI expects angles.
Diffstat (limited to 'source/blender/blenkernel/intern/fcurve.c')
-rw-r--r--source/blender/blenkernel/intern/fcurve.c68
1 files changed, 50 insertions, 18 deletions
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index ef53c926daa..c4da2d2efc9 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1732,35 +1732,21 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
* - only an option for "transform space", if quality is really bad with a)
*/
float quat[4];
- float *const eul = quat + 1;
int channel;
if (dtar->transChan == DTAR_TRANSCHAN_ROTW) {
channel = 0;
- quat[0] = 0.0f;
}
else {
channel = 1 + dtar->transChan - DTAR_TRANSCHAN_ROTX;
BLI_assert(channel < 4);
}
- if (dtar->rotation_mode == DTAR_ROTMODE_AUTO) {
- mat4_to_eulO(eul, rot_order, mat);
+ BKE_driver_target_matrix_to_rot_channels(
+ mat, rot_order, dtar->rotation_mode, channel, false, quat);
- if (use_eulers) {
- compatible_eul(eul, oldEul);
- }
- }
- else if (dtar->rotation_mode >= DTAR_ROTMODE_EULER_MIN &&
- dtar->rotation_mode <= DTAR_ROTMODE_EULER_MAX) {
- mat4_to_eulO(eul, dtar->rotation_mode, mat);
- }
- else if (dtar->rotation_mode == DTAR_ROTMODE_QUATERNION) {
- mat4_to_quat(quat, mat);
- }
- else {
- BLI_assert(false);
- zero_v3(eul);
+ if (use_eulers && dtar->rotation_mode == DTAR_ROTMODE_AUTO) {
+ compatible_eul(quat + 1, oldEul);
}
return quat[channel];
@@ -1771,6 +1757,52 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
}
}
+/* Convert a quaternion to pseudo-angles representing the weighted amount of rotation. */
+static void quaternion_to_angles(float quat[4], int channel)
+{
+ if (channel < 0) {
+ quat[0] = 2.0f * saacosf(quat[0]);
+
+ for (int i = 1; i < 4; i++) {
+ quat[i] = 2.0f * saasinf(quat[i]);
+ }
+ }
+ else if (channel == 0) {
+ quat[0] = 2.0f * saacosf(quat[0]);
+ }
+ else {
+ quat[channel] = 2.0f * saasinf(quat[channel]);
+ }
+}
+
+/* Compute channel values for a rotational Transform Channel driver variable. */
+void BKE_driver_target_matrix_to_rot_channels(
+ float mat[4][4], int auto_order, int rotation_mode, int channel, bool angles, float r_buf[4])
+{
+ float *const quat = r_buf;
+ float *const eul = r_buf + 1;
+
+ zero_v4(r_buf);
+
+ if (rotation_mode == DTAR_ROTMODE_AUTO) {
+ mat4_to_eulO(eul, auto_order, mat);
+ }
+ else if (rotation_mode >= DTAR_ROTMODE_EULER_MIN && rotation_mode <= DTAR_ROTMODE_EULER_MAX) {
+ mat4_to_eulO(eul, rotation_mode, mat);
+ }
+ else if (rotation_mode == DTAR_ROTMODE_QUATERNION) {
+ mat4_to_quat(quat, mat);
+
+ /* For Transformation constraint convenience, convert to pseudo-angles. */
+ if (angles) {
+ quaternion_to_angles(quat, channel);
+ }
+ }
+ else {
+ BLI_assert(false);
+ }
+}
+
/* ......... */
/* Table of Driver Variable Type Info Data */