Bugfix #4843 revisited

This is a new incarnation of compatible_eul(), a function called:

void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot)

It uses the two euler extraction methods as added by Brecht a while ago,
and checks for compatibility each, and then picks the best of the two
based on minimal difference with 'oldrot'.

Gives for rotation key inserting a much higher hitrate for OK eulers.
This commit is contained in:
2006-08-13 10:03:07 +00:00
parent e3d78dd4e1
commit bdb12f23cf
3 changed files with 52 additions and 54 deletions

View File

@@ -157,6 +157,8 @@ Mat3ToEul(
void compatible_eul(float *eul, float *oldrot);
void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot);
/**
* @section Quaternion arithmetic routines
*/
@@ -785,11 +787,7 @@ MinMax3(
float *max,
float *vec
);
void
Mat3ToEuln(
float tmat[][3],
float *eul
);
void
SizeToMat3(
float *size,

View File

@@ -2169,8 +2169,8 @@ void EulToMat4( float *eul,float mat[][4])
mat[3][3]= 1.0f;
}
void Mat3ToEul(float tmat[][3], float *eul)
/* returns two euler calculation methods, so we can pick the best */
static void mat3_to_eul2(float tmat[][3], float *eul1, float *eul2)
{
float cy, quat[4], mat[3][3];
@@ -2182,7 +2182,6 @@ void Mat3ToEul(float tmat[][3], float *eul)
cy = (float)sqrt(mat[0][0]*mat[0][0] + mat[0][1]*mat[0][1]);
if (cy > 16.0*FLT_EPSILON) {
float eul1[3], eul2[3];
eul1[0] = (float)atan2(mat[1][2], mat[2][2]);
eul1[1] = (float)atan2(-mat[0][2], cy);
@@ -2192,6 +2191,21 @@ void Mat3ToEul(float tmat[][3], float *eul)
eul2[1] = (float)atan2(-mat[0][2], -cy);
eul2[2] = (float)atan2(-mat[0][1], -mat[0][0]);
} else {
eul1[0] = (float)atan2(-mat[2][1], mat[1][1]);
eul1[1] = (float)atan2(-mat[0][2], cy);
eul1[2] = 0.0f;
VecCopyf(eul2, eul1);
}
}
void Mat3ToEul(float tmat[][3], float *eul)
{
float eul1[3], eul2[3];
mat3_to_eul2(tmat, eul1, eul2);
/* return best, which is just the one with lowest values it in */
if( fabs(eul1[0])+fabs(eul1[1])+fabs(eul1[2]) > fabs(eul2[0])+fabs(eul2[1])+fabs(eul2[2])) {
VecCopyf(eul, eul2);
@@ -2199,40 +2213,7 @@ void Mat3ToEul(float tmat[][3], float *eul)
else {
VecCopyf(eul, eul1);
}
} else {
eul[0] = (float)atan2(-mat[2][1], mat[1][1]);
eul[1] = (float)atan2(-mat[0][2], cy);
eul[2] = 0.0f;
}
}
void Mat3ToEuln( float tmat[][3], float *eul)
{
float sin1, cos1, sin2, cos2, sin3, cos3;
sin1 = -tmat[2][0];
cos1 = (float)sqrt(1 - sin1*sin1);
if ( fabs(cos1) > FLT_EPSILON ) {
sin2 = tmat[2][1] / cos1;
cos2 = tmat[2][2] / cos1;
sin3 = tmat[1][0] / cos1;
cos3 = tmat[0][0] / cos1;
}
else {
sin2 = -tmat[1][2];
cos2 = tmat[1][1];
sin3 = 0.0;
cos3 = 1.0;
}
eul[0] = (float)atan2(sin3, cos3);
eul[1] = (float)atan2(sin1, cos1);
eul[2] = (float)atan2(sin2, cos2);
}
void QuatToEul( float *quat, float *eul)
{
@@ -2384,10 +2365,9 @@ void compatible_eul(float *eul, float *oldrot)
if(dz > 0.0) eul[2] -= 2.0*M_PI; else eul[2]+= 2.0*M_PI;
}
/* this return was there from ancient days... but why! probably because the code sucks :)
/* the method below was there from ancient days... but why! probably because the code sucks :)
*/
return;
#if 0
/* calc again */
dx= eul[0] - oldrot[0];
dy= eul[1] - oldrot[1];
@@ -2411,10 +2391,32 @@ void compatible_eul(float *eul, float *oldrot)
if(dy > 0.0) eul[1] -= M_PI; else eul[1]+= M_PI;
if(dz > 0.0) eul[2] -= M_PI; else eul[2]+= M_PI;
}
#endif
}
/* uses 2 methods to retrieve eulers, and picks the closest */
void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot)
{
float eul1[3], eul2[3];
float d1, d2;
mat3_to_eul2(mat, eul1, eul2);
compatible_eul(eul1, oldrot);
compatible_eul(eul2, oldrot);
d1= fabs(eul1[0]-oldrot[0]) + fabs(eul1[1]-oldrot[1]) + fabs(eul1[2]-oldrot[2]);
d2= fabs(eul2[0]-oldrot[0]) + fabs(eul2[1]-oldrot[1]) + fabs(eul2[2]-oldrot[2]);
/* return best, which is just the one with lowest difference */
if( d1 > d2) {
VecCopyf(eul, eul2);
}
else {
VecCopyf(eul, eul1);
}
}
/* ******************************************** */

View File

@@ -80,8 +80,6 @@
#include "BKE_utildefines.h"
#include "BKE_bad_level_calls.h"/* popmenu and error */
#include "BDR_editobject.h" /* compatible_eul */
#include "BSE_view.h"
#include "BLI_arithb.h"
@@ -1739,8 +1737,8 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) {
EulToMat3(eul, obmat);
/* mat = transform, obmat = object rotation */
Mat3MulMat3(fmat, mat, obmat);
Mat3ToEul(fmat, eul);
compatible_eul(eul, td->ext->irot);
Mat3ToCompatibleEul(fmat, eul, td->ext->irot);
/* correct back for delta rot */
if(tdi->flag & TOB_IPODROT) {
@@ -1768,8 +1766,8 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) {
EulToMat3(eul, obmat);
/* mat = transform, obmat = object rotation */
Mat3MulMat3(fmat, smat, obmat);
Mat3ToEul(fmat, eul);
compatible_eul(eul, td->ext->irot);
Mat3ToCompatibleEul(fmat, eul, td->ext->irot);
/* correct back for delta rot */
VecSubf(eul, eul, td->ext->drot);