Fix T89291: Objects with rotation deltas don't rotate in correct axes

Quaternion correction was not implemented and Euler values were being
incorrectly combined.
This commit is contained in:
Germano Cavalcante 2021-06-21 14:24:23 -03:00
parent 41af27c582
commit b665ad8621
Notes: blender-bot 2023-02-14 06:42:53 +01:00
Referenced by issue #89291, Objects with rotation deltas don't rotate in correct axes
3 changed files with 58 additions and 7 deletions

View File

@ -164,6 +164,9 @@ void compatible_eul(float eul[3], const float old[3]);
void rotate_eul(float eul[3], const char axis, const float angle);
void add_eul_euleul(float r_eul[3], float a[3], float b[3], const short order);
void sub_eul_euleul(float r_eul[3], float a[3], float b[3], const short order);
/************************** Arbitrary Order Eulers ***************************/
/* warning: must match the eRotationModes in DNA_action_types.h

View File

@ -1924,6 +1924,31 @@ void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], const short order
gmat[R->axis[2]][R->axis[2]] = 1;
}
void add_eul_euleul(float r_eul[3], float a[3], float b[3], const short order)
{
float quat[4], quat_b[4];
eulO_to_quat(quat, a, order);
eulO_to_quat(quat_b, b, order);
mul_qt_qtqt(quat, quat_b, quat);
quat_to_eulO(r_eul, order, quat);
}
void sub_eul_euleul(float r_eul[3], float a[3], float b[3], const short order)
{
float quat[4], quat_b[4];
eulO_to_quat(quat, a, order);
eulO_to_quat(quat_b, b, order);
invert_qt_normalized(quat_b);
mul_qt_qtqt(quat, quat_b, quat);
quat_to_eulO(r_eul, order, quat);
}
/******************************* Dual Quaternions ****************************/
/**

View File

@ -734,9 +734,25 @@ void ElementRotation_ex(TransInfo *t,
/* can be called for texture space translate for example, then opt out */
if (td->ext->quat) {
mul_m3_series(fmat, td->smtx, mat, td->mtx);
if (!is_zero_v3(td->ext->dquat)) {
/* Correct for delta quat */
float tmp_mat[3][3];
quat_to_mat3(tmp_mat, td->ext->dquat);
mul_m3_m3m3(fmat, fmat, tmp_mat);
}
mat3_to_quat(quat, fmat); /* Actual transform */
if (!is_zero_v4(td->ext->dquat)) {
/* Correct back for delta quat. */
float idquat[4];
invert_qt_qt_normalized(idquat, td->ext->dquat);
mul_qt_qtqt(quat, idquat, quat);
}
mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
/* this function works on end result */
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
}
@ -761,21 +777,28 @@ void ElementRotation_ex(TransInfo *t,
td->ext->irotAngle);
}
else {
/* Calculate the total rotation in eulers. */
float obmat[3][3];
mul_m3_m3m3(totmat, mat, td->mtx);
mul_m3_m3m3(smat, td->smtx, totmat);
/* Calculate the total rotation in eulers. */
add_v3_v3v3(eul, td->ext->irot, td->ext->drot); /* correct for delta rot */
eulO_to_mat3(obmat, eul, td->ext->rotOrder);
/* mat = transform, obmat = object rotation */
mul_m3_m3m3(fmat, smat, obmat);
if (!is_zero_v3(td->ext->drot)) {
/* Correct for delta rot */
add_eul_euleul(eul, td->ext->irot, td->ext->drot, td->ext->rotOrder);
}
else {
copy_v3_v3(eul, td->ext->irot);
}
eulO_to_mat3(obmat, eul, td->ext->rotOrder);
mul_m3_m3m3(fmat, smat, obmat);
mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
/* correct back for delta rot */
sub_v3_v3v3(eul, eul, td->ext->drot);
if (!is_zero_v3(td->ext->drot)) {
/* Correct back for delta rot. */
sub_eul_euleul(eul, eul, td->ext->drot, td->ext->rotOrder);
}
/* and apply */
protectedRotateBits(td->protectflag, eul, td->ext->irot);