diff options
author | Campbell Barton <ideasman42@gmail.com> | 2010-07-26 04:11:14 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2010-07-26 04:11:14 +0400 |
commit | e4a7087982b827edfa6652091a4bc7e2a32b6778 (patch) | |
tree | 480ecf6ff88e40f09a4ad9b0f5a965d13a726fec /source/blender | |
parent | cc061d075f4368f7a8d380becb0688bbea14832a (diff) |
bugfix [#22836] Alt+MMB view alignment don't respect all axes directions
also moved rotation_between_quats_to_quat into BLI_math from python mathutils.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenlib/BLI_math_rotation.h | 6 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_rotation.c | 27 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_edit.c | 65 | ||||
-rw-r--r-- | source/blender/python/generic/mathutils_quat.c | 12 |
4 files changed, 85 insertions, 25 deletions
diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h index 388a9176d53..f3da20f91c2 100644 --- a/source/blender/blenlib/BLI_math_rotation.h +++ b/source/blender/blenlib/BLI_math_rotation.h @@ -40,10 +40,10 @@ extern "C" { /* init */ void unit_qt(float q[4]); -void copy_qt_qt(float q[4], float a[4]); +void copy_qt_qt(float q[4], const float a[4]); /* arithmetic */ -void mul_qt_qtqt(float q[4], float a[4], float b[4]); +void mul_qt_qtqt(float q[4], const float a[4], const float b[4]); void mul_qt_v3(float q[4], float r[3]); void mul_qt_fl(float q[4], float f); void mul_fac_qt_fl(float q[4], float f); @@ -51,6 +51,7 @@ void mul_fac_qt_fl(float q[4], float f); void sub_qt_qtqt(float q[4], float a[4], float b[4]); void invert_qt(float q[4]); +void invert_qt_qt(float *q1, const float *q2); void conjugate_qt(float q[4]); float dot_qtqt(float a[4], float b[4]); void normalize_qt(float q[4]); @@ -72,6 +73,7 @@ void tri_to_quat(float q[4], float a[3], float b[3], float c[3]); void vec_to_quat(float q[4], float vec[3], short axis, short upflag); /* note: v1 and v2 must be normalized */ void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3]); +void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q2[4]); /* TODO: don't what this is, but it's not the same as mat3_to_quat */ void mat3_to_quat_is_ok(float q[4], float mat[3][3]); diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index 6b5bf7743ef..a8cacb60f05 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -36,7 +36,7 @@ void unit_qt(float *q) q[1]= q[2]= q[3]= 0.0f; } -void copy_qt_qt(float *q1, float *q2) +void copy_qt_qt(float *q1, const float *q2) { q1[0]= q2[0]; q1[1]= q2[1]; @@ -49,7 +49,7 @@ int is_zero_qt(float *q) return (q[0] == 0 && q[1] == 0 && q[2] == 0 && q[3] == 0); } -void mul_qt_qtqt(float *q, float *q1, float *q2) +void mul_qt_qtqt(float *q, const float *q1, const float *q2) { float t0,t1,t2; @@ -104,6 +104,12 @@ void invert_qt(float *q) mul_qt_fl(q, 1.0f/f); } +void invert_qt_qt(float *q1, const float *q2) +{ + copy_qt_qt(q1, q2); + invert_qt(q1); +} + /* simple mult */ void mul_qt_fl(float *q, float f) { @@ -336,6 +342,23 @@ void rotation_between_vecs_to_quat(float *q, const float v1[3], const float v2[3 axis_angle_to_quat(q, axis, angle); } +void rotation_between_quats_to_quat(float *q, const float q1[4], const float q2[4]) +{ + float tquat[4]; + double dot = 0.0f; + int x; + + copy_qt_qt(tquat, q1); + conjugate_qt(tquat); + dot = 1.0f / dot_qtqt(tquat, tquat); + + for(x = 0; x < 4; x++) + tquat[x] *= dot; + + mul_qt_qtqt(q, tquat, q2); +} + + void vec_to_quat(float *q,float *vec, short axis, short upflag) { float q2[4], nor[3], *fp, mat[3][3], angle, si, co, x2, y2, z2, len1; diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index bce4a7e8f58..aee4b2515ec 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -600,23 +600,66 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y) /* check for view snap */ if (vod->axis_snap){ int i; - float viewmat[3][3]; + float viewquat_inv[4]; + float zaxis[3]={0,0,1}; + invert_qt_qt(viewquat_inv, rv3d->viewquat); - - quat_to_mat3( viewmat,rv3d->viewquat); + mul_qt_v3(viewquat_inv, zaxis); for (i = 0 ; i < 39; i++){ - float snapmat[3][3]; + float view = (int)snapquats[i][4]; + float viewquat_inv_test[4]; + float zaxis_test[3]={0,0,1}; + + invert_qt_qt(viewquat_inv_test, snapquats[i]); + mul_qt_v3(viewquat_inv_test, zaxis_test); + + if(angle_v3v3(zaxis_test, zaxis) < DEG2RAD(45/3)) { + /* find the best roll */ + float quat_roll[4], quat_final[4], quat_best[4]; + float viewquat_align[4]; /* viewquat aligned to zaxis_test */ + float viewquat_align_inv[4]; /* viewquat aligned to zaxis_test */ + float best_angle = FLT_MAX; + int j; + + /* viewquat_align is the original viewquat aligned to the snapped axis + * for testing roll */ + rotation_between_vecs_to_quat(viewquat_align, zaxis_test, zaxis); + normalize_qt(viewquat_align); + mul_qt_qtqt(viewquat_align, rv3d->viewquat, viewquat_align); + normalize_qt(viewquat_align); + invert_qt_qt(viewquat_align_inv, viewquat_align); + + /* find best roll */ + for(j= 0; j<8; j++) { + float angle; + float xaxis1[3]={1,0,0}; + float xaxis2[3]={1,0,0}; + float quat_final_inv[4]; + + axis_angle_to_quat(quat_roll, zaxis_test, j * DEG2RAD(45.0)); + normalize_qt(quat_roll); + + mul_qt_qtqt(quat_final, snapquats[i], quat_roll); + normalize_qt(quat_final); + + /* compare 2 vector angles to find the least roll */ + invert_qt_qt(quat_final_inv, quat_final); + mul_qt_v3(viewquat_align_inv, xaxis1); + mul_qt_v3(quat_final_inv, xaxis2); + angle= angle_v3v3(xaxis1, xaxis2); + + if(angle <= best_angle) { + best_angle= angle; + copy_qt_qt(quat_best, quat_final); + if(j) view= 0; /* view grid assumes certain up axis */ + } + } - quat_to_mat3( snapmat,snapquats[i]); + copy_qt_qt(rv3d->viewquat, quat_best); + rv3d->view= view; /* if we snap to a rolled camera the grid is invalid */ - if ((dot_v3v3(snapmat[0], viewmat[0]) > thres) && - (dot_v3v3(snapmat[1], viewmat[1]) > thres) && - (dot_v3v3(snapmat[2], viewmat[2]) > thres) - ) { - copy_qt_qt(rv3d->viewquat, snapquats[i]); - rv3d->view= view; break; } } diff --git a/source/blender/python/generic/mathutils_quat.c b/source/blender/python/generic/mathutils_quat.c index fe0d3cde308..480b724111d 100644 --- a/source/blender/python/generic/mathutils_quat.c +++ b/source/blender/python/generic/mathutils_quat.c @@ -190,9 +190,7 @@ static char Quaternion_Difference_doc[] = static PyObject *Quaternion_Difference(QuaternionObject * self, QuaternionObject * value) { - float quat[QUAT_SIZE], tempQuat[QUAT_SIZE]; - double dot = 0.0f; - int x; + float quat[QUAT_SIZE]; if (!QuaternionObject_Check(value)) { PyErr_SetString( PyExc_TypeError, "quat.difference(value): expected a quaternion argument" ); @@ -202,14 +200,8 @@ static PyObject *Quaternion_Difference(QuaternionObject * self, QuaternionObject if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value)) return NULL; - copy_qt_qt(tempQuat, self->quat); - conjugate_qt(tempQuat); - dot = sqrt(dot_qtqt(tempQuat, tempQuat)); + rotation_between_quats_to_quat(quat, self->quat, value->quat); - for(x = 0; x < QUAT_SIZE; x++) { - tempQuat[x] /= (float)(dot * dot); - } - mul_qt_qtqt(quat, tempQuat, value->quat); return newQuaternionObject(quat, Py_NEW, NULL); } |