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 */
|
||||
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]);
|
||||
|
@@ -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;
|
||||
|
@@ -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};
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user