Merge branch 'master' into blender2.8

This commit is contained in:
2017-12-19 14:15:19 +11:00
8 changed files with 88 additions and 13 deletions

View File

@@ -97,6 +97,11 @@ float angle_normalized_qtqt(const float q1[4], const float q2[4]);
float angle_qt(const float q[4]);
float angle_qtqt(const float q1[4], const float q2[4]);
float angle_signed_normalized_qt(const float q[4]);
float angle_signed_normalized_qtqt(const float q1[4], const float q2[4]);
float angle_signed_qt(const float q[4]);
float angle_signed_qtqt(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]);

View File

@@ -511,6 +511,14 @@ void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q
}
/* -------------------------------------------------------------------- */
/** \name Quaternion Angle
*
* Unlike the angle between vectors, this does NOT return the shortest angle.
* See signed functions below for this.
*
* \{ */
float angle_normalized_qt(const float q[4])
{
BLI_ASSERT_UNIT_QUAT(q);
@@ -548,6 +556,64 @@ float angle_qtqt(const float q1[4], const float q2[4])
return angle_normalized_qtqt(quat1, quat2);
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Quaternion Angle (Signed)
*
* Angles with quaternion calculation can exceed 180d,
* Having signed versions of these functions allows 'fabsf(angle_signed_qtqt(...))'
* to give us the shortest angle between quaternions.
* With higher precision than subtracting pi afterwards.
*
* \{ */
float angle_signed_normalized_qt(const float q[4])
{
BLI_ASSERT_UNIT_QUAT(q);
if (q[0] >= 0.0f) {
return 2.0f * saacos(q[0]);
}
else {
return -2.0f * saacos(-q[0]);
}
}
float angle_signed_normalized_qtqt(const float q1[4], const float q2[4])
{
if (dot_qtqt(q1, q2) >= 0.0f) {
return angle_normalized_qtqt(q1, q2);
}
else {
float q2_copy[4];
negate_v4_v4(q2_copy, q2);
return -angle_normalized_qtqt(q1, q2_copy);
}
}
float angle_signed_qt(const float q[4])
{
float tquat[4];
normalize_qt_qt(tquat, q);
return angle_signed_normalized_qt(tquat);
}
float angle_signed_qtqt(const float q1[4], const float q2[4])
{
if (dot_qtqt(q1, q2) >= 0.0f) {
return angle_qtqt(q1, q2);
}
else {
float q2_copy[4];
negate_v4_v4(q2_copy, q2);
return -angle_qtqt(q1, q2_copy);
}
}
/** \} */
void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag)
{
const float eps = 1e-4f;

View File

@@ -718,14 +718,18 @@ static void slide_dist(EdgeHalf *e, BMVert *v, float d, float slideco[3])
/* Is co not on the edge e? if not, return the closer end of e in ret_closer_v */
static bool is_outside_edge(EdgeHalf *e, const float co[3], BMVert **ret_closer_v)
{
float d_squared;
float h[3], u[3], lambda, lenu, *l1 = e->e->v1->co;
d_squared = dist_squared_to_line_segment_v3(co, e->e->v1->co, e->e->v2->co);
if (d_squared > BEVEL_EPSILON_BIG * BEVEL_EPSILON_BIG) {
if (len_squared_v3v3(co, e->e->v1->co) > len_squared_v3v3(co, e->e->v2->co))
*ret_closer_v = e->e->v2;
else
*ret_closer_v = e->e->v1;
sub_v3_v3v3(u, e->e->v2->co, l1);
sub_v3_v3v3(h, co, l1);
lenu = normalize_v3(u);
lambda = dot_v3v3(u, h);
if (lambda <= -BEVEL_EPSILON_BIG * lenu) {
*ret_closer_v = e->e->v1;
return true;
}
else if (lambda >= (1.0f + BEVEL_EPSILON_BIG) * lenu) {
*ret_closer_v = e->e->v2;
return true;
}
else {

View File

@@ -273,7 +273,7 @@ void ED_view3d_smooth_view_ex(
* this means small rotations wont lag */
if (sview->quat && !sview->ofs && !sview->dist) {
/* scale the time allowed by the rotation */
sms.time_allowed *= (double)angle_normalized_qtqt(sms.dst.quat, sms.src.quat) / M_PI; /* 180deg == 1.0 */
sms.time_allowed *= (double)fabsf(angle_signed_normalized_qtqt(sms.dst.quat, sms.src.quat)) / M_PI; /* 180deg == 1.0 */
}
/* ensure it shows correct */
@@ -1069,7 +1069,7 @@ char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon)
char view;
for (view = RV3D_VIEW_FRONT; view <= RV3D_VIEW_BOTTOM; view++) {
if (angle_qtqt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT]) < epsilon) {
if (fabsf(angle_signed_qtqt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT])) < epsilon) {
return view;
}
}