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:
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 */