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.
This commit is contained in:
@@ -40,10 +40,10 @@ extern "C" {
|
|||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
void unit_qt(float q[4]);
|
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 */
|
/* 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_v3(float q[4], float r[3]);
|
||||||
void mul_qt_fl(float q[4], float f);
|
void mul_qt_fl(float q[4], float f);
|
||||||
void mul_fac_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 sub_qt_qtqt(float q[4], float a[4], float b[4]);
|
||||||
|
|
||||||
void invert_qt(float q[4]);
|
void invert_qt(float q[4]);
|
||||||
|
void invert_qt_qt(float *q1, const float *q2);
|
||||||
void conjugate_qt(float q[4]);
|
void conjugate_qt(float q[4]);
|
||||||
float dot_qtqt(float a[4], float b[4]);
|
float dot_qtqt(float a[4], float b[4]);
|
||||||
void normalize_qt(float q[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);
|
void vec_to_quat(float q[4], float vec[3], short axis, short upflag);
|
||||||
/* note: v1 and v2 must be normalized */
|
/* 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_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 */
|
/* 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]);
|
void mat3_to_quat_is_ok(float q[4], float mat[3][3]);
|
||||||
|
@@ -36,7 +36,7 @@ void unit_qt(float *q)
|
|||||||
q[1]= q[2]= q[3]= 0.0f;
|
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[0]= q2[0];
|
||||||
q1[1]= q2[1];
|
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);
|
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;
|
float t0,t1,t2;
|
||||||
|
|
||||||
@@ -104,6 +104,12 @@ void invert_qt(float *q)
|
|||||||
mul_qt_fl(q, 1.0f/f);
|
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 */
|
/* simple mult */
|
||||||
void mul_qt_fl(float *q, float f)
|
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);
|
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)
|
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;
|
float q2[4], nor[3], *fp, mat[3][3], angle, si, co, x2, y2, z2, len1;
|
||||||
|
@@ -600,23 +600,66 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
|
|||||||
/* check for view snap */
|
/* check for view snap */
|
||||||
if (vod->axis_snap){
|
if (vod->axis_snap){
|
||||||
int i;
|
int i;
|
||||||
float viewmat[3][3];
|
float viewquat_inv[4];
|
||||||
|
float zaxis[3]={0,0,1};
|
||||||
|
invert_qt_qt(viewquat_inv, rv3d->viewquat);
|
||||||
|
|
||||||
|
mul_qt_v3(viewquat_inv, zaxis);
|
||||||
quat_to_mat3( viewmat,rv3d->viewquat);
|
|
||||||
|
|
||||||
for (i = 0 ; i < 39; i++){
|
for (i = 0 ; i < 39; i++){
|
||||||
float snapmat[3][3];
|
|
||||||
float view = (int)snapquats[i][4];
|
float view = (int)snapquats[i][4];
|
||||||
|
float viewquat_inv_test[4];
|
||||||
|
float zaxis_test[3]={0,0,1};
|
||||||
|
|
||||||
quat_to_mat3( snapmat,snapquats[i]);
|
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 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -190,9 +190,7 @@ static char Quaternion_Difference_doc[] =
|
|||||||
|
|
||||||
static PyObject *Quaternion_Difference(QuaternionObject * self, QuaternionObject * value)
|
static PyObject *Quaternion_Difference(QuaternionObject * self, QuaternionObject * value)
|
||||||
{
|
{
|
||||||
float quat[QUAT_SIZE], tempQuat[QUAT_SIZE];
|
float quat[QUAT_SIZE];
|
||||||
double dot = 0.0f;
|
|
||||||
int x;
|
|
||||||
|
|
||||||
if (!QuaternionObject_Check(value)) {
|
if (!QuaternionObject_Check(value)) {
|
||||||
PyErr_SetString( PyExc_TypeError, "quat.difference(value): expected a quaternion argument" );
|
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))
|
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
copy_qt_qt(tempQuat, self->quat);
|
rotation_between_quats_to_quat(quat, self->quat, value->quat);
|
||||||
conjugate_qt(tempQuat);
|
|
||||||
dot = sqrt(dot_qtqt(tempQuat, tempQuat));
|
|
||||||
|
|
||||||
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);
|
return newQuaternionObject(quat, Py_NEW, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user