BLI_math: ensure non-negative matrices for mat3_to_quat calculations

Making the callers responsible for this isn't practical as matrices are
often passed indirectly to a functions such as mat3_to_axis_angle,
BKE_object_mat3_to_rot & BKE_pchan_mat3_to_rot.
Or the matrix is combined from other matrices which could be negative.

Given quaternions calculated from negative matrices are completely
invalid and checking only needs to negate matrices with a negative
determinant, move the check into mat3_to_quat and related functions.

Add mat3_normalized_to_quat_fast for cases no error checking on the
input matrix is needed such as blending rotations.
This commit is contained in:
2022-08-25 12:45:43 +10:00
parent 8593228a13
commit a7650c6206
8 changed files with 64 additions and 58 deletions

View File

@@ -543,13 +543,7 @@ static PyObject *Quaternion_rotate(QuaternionObject *self, PyObject *value)
length = normalize_qt_qt(tquat, self->quat);
quat_to_mat3(self_rmat, tquat);
mul_m3_m3m3(rmat, other_rmat, self_rmat);
normalize_m3(rmat);
/* This check could also be performed on `other_rmat`, use the final result instead to ensure
* float imprecision doesn't allow the multiplication to make `rmat` negative. */
if (is_negative_m3(rmat)) {
negate_m3(rmat);
}
mat3_normalized_to_quat(self->quat, rmat);
mat3_to_quat(self->quat, rmat);
mul_qt_fl(self->quat, length); /* maintain length after rotating */
(void)BaseMath_WriteCallback(self);