diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-07-13 21:27:32 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-07-13 21:30:16 +0300 |
commit | 406b9aa7b1ead0ff2757a463bc7efe9fdcee5fbe (patch) | |
tree | 70272b7c803598d5875f711db6c1ddbdfc019477 /source/blender | |
parent | 6f7926c61c94ea9bd2969ebfcc7e09994ffe901d (diff) |
Fix T45402: Transform crash w/ project+align snap
Only euler rotations were checked for.
Also delta rotations caused random/unusable output.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/transform/transform.h | 2 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_generics.c | 107 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_snap.c | 20 |
3 files changed, 110 insertions, 19 deletions
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index b826b7f9c73..815b07f3cd5 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -711,6 +711,8 @@ void calculatePropRatio(TransInfo *t); void getViewVector(TransInfo *t, float coord[3], float vec[3]); +void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot); + /*********************** Transform Orientations ******************************/ void initTransformOrientation(struct bContext *C, TransInfo *t); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index c2ebfaceb8f..e56b0eb2a60 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1956,3 +1956,110 @@ void calculatePropRatio(TransInfo *t) } } } + +/** + * Rotate an element, low level code, ignore protected channels. + * (use for objects or pose-bones) + * Similar to #ElementRotation. + */ +void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot) +{ + float totmat[3][3]; + float smat[3][3]; + float fmat[3][3]; + float obmat[3][3]; + + float dmat[3][3]; /* delta rotation */ + float dmat_inv[3][3]; + + mul_m3_m3m3(totmat, mat, td->mtx); + mul_m3_m3m3(smat, td->smtx, mat); + + /* logic from BKE_object_rot_to_mat3 */ + if (use_drot) { + if (td->ext->rotOrder > 0) { + eulO_to_mat3(dmat, td->ext->drot, td->ext->rotOrder); + } + else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) { +#if 0 + axis_angle_to_mat3(dmat, td->ext->drotAxis, td->ext->drotAngle); +#else + unit_m3(dmat); +#endif + } + else { + float tquat[4]; + normalize_qt_qt(tquat, td->ext->dquat); + quat_to_mat3(dmat, tquat); + } + + invert_m3_m3(dmat_inv, dmat); + } + + + if (td->ext->rotOrder == ROT_MODE_QUAT) { + float quat[4]; + + /* calculate the total rotatation */ + quat_to_mat3(obmat, td->ext->iquat); + if (use_drot) { + mul_m3_m3m3(obmat, dmat, obmat); + } + + /* mat = transform, obmat = object rotation */ + mul_m3_m3m3(fmat, smat, obmat); + + if (use_drot) { + mul_m3_m3m3(fmat, dmat_inv, fmat); + } + + mat3_to_quat(quat, fmat); + + /* apply */ + copy_qt_qt(td->ext->quat, quat); + } + else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) { + float axis[3], angle; + + /* calculate the total rotatation */ + axis_angle_to_mat3(obmat, td->ext->irotAxis, td->ext->irotAngle); + if (use_drot) { + mul_m3_m3m3(obmat, dmat, obmat); + } + + /* mat = transform, obmat = object rotation */ + mul_m3_m3m3(fmat, smat, obmat); + + if (use_drot) { + mul_m3_m3m3(fmat, dmat_inv, fmat); + } + + mat3_to_axis_angle(axis, &angle, fmat); + + /* apply */ + copy_v3_v3(td->ext->rotAxis, axis); + *td->ext->rotAngle = angle; + } + else { + float eul[3]; + + /* calculate the total rotatation */ + eulO_to_mat3(obmat, td->ext->irot, td->ext->rotOrder); + if (use_drot) { + mul_m3_m3m3(obmat, dmat, obmat); + } + + /* mat = transform, obmat = object rotation */ + mul_m3_m3m3(fmat, smat, obmat); + + if (use_drot) { + mul_m3_m3m3(fmat, dmat_inv, fmat); + } + + mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat); + + /* apply */ + copy_v3_v3(td->ext->rot, eul); + } +} + diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index e86b11f1df3..99d9836014c 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -343,31 +343,13 @@ void applyProject(TransInfo *t) /* handle alignment as well */ const float *original_normal; float mat[3][3]; - float totmat[3][3], smat[3][3]; - float eul[3], fmat[3][3]; - float obmat[3][3]; /* In pose mode, we want to align normals with Y axis of bones... */ original_normal = td->axismtx[2]; rotation_between_vecs_to_mat3(mat, original_normal, no); - mul_m3_m3m3(totmat, mat, td->mtx); - mul_m3_m3m3(smat, td->smtx, totmat); - - /* calculate the total rotatation in eulers */ - add_v3_v3v3(eul, td->ext->irot, td->ext->drot); /* we have to correct for delta rot */ - eulO_to_mat3(obmat, eul, td->ext->rotOrder); - /* mat = transform, obmat = object rotation */ - 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); - - /* and apply */ - copy_v3_v3(td->ext->rot, eul); + transform_data_ext_rotate(td, mat, true); /* TODO support constraints for rotation too? see ElementRotation */ } |