Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gavrilov <angavrilov@gmail.com>2018-10-05 21:02:57 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2018-10-05 21:52:01 +0300
commita33a4e132eef24261b12acecfe69a8d41aebfaa1 (patch)
treefebab7b9b40731e34c4d41fd5ab7c8bc540d3832 /source/blender/blenkernel/intern/armature.c
parent8044743741fe4dd3bc45df1a5b6180ccdc0baf3b (diff)
Add and use a utility for computing B-Bone roll from custom handles.
This also fixes a stability problem with the start handle due to an incorrect matrix multiplication order.
Diffstat (limited to 'source/blender/blenkernel/intern/armature.c')
-rw-r--r--source/blender/blenkernel/intern/armature.c43
1 files changed, 19 insertions, 24 deletions
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 198cc526865..17a708fc3ba 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -650,7 +650,7 @@ void b_bone_spline_setup(bPoseChannel *pchan, int rest, Mat4 result_array[MAX_BB
int BKE_compute_b_bone_spline(BBoneSplineParameters *param, Mat4 result_array[MAX_BBONE_SUBDIV])
{
float scalemat[4][4], iscalemat[4][4];
- float result[3][3], mat3[3][3], imat3[3][3];
+ float mat3[3][3];
float h1[3], roll1, h2[3], roll2;
float data[MAX_BBONE_SUBDIV + 1][4], *fp;
int a;
@@ -678,14 +678,8 @@ int BKE_compute_b_bone_spline(BBoneSplineParameters *param, Mat4 result_array[MA
if (!param->prev_bbone) {
/* Find the previous roll to interpolate. */
- copy_m3_m4(result, param->prev_mat); /* the desired rotation at beginning of next bone */
-
- vec_roll_to_mat3(h1, 0.0f, mat3); /* the result of vec_roll without roll */
-
- invert_m3_m3(imat3, mat3);
- mul_m3_m3m3(mat3, result, imat3); /* the matrix transforming vec_roll to desired roll */
-
- roll1 = atan2f(mat3[2][0], mat3[2][2]);
+ copy_m3_m4(mat3, param->prev_mat);
+ mat3_vec_to_roll(mat3, h1, &roll1);
}
}
else {
@@ -707,14 +701,8 @@ int BKE_compute_b_bone_spline(BBoneSplineParameters *param, Mat4 result_array[MA
normalize_v3(h2);
/* Find the next roll to interpolate as well. */
- copy_m3_m4(result, param->next_mat); /* the desired rotation at beginning of next bone */
-
- vec_roll_to_mat3(h2, 0.0f, mat3); /* the result of vec_roll without roll */
-
- invert_m3_m3(imat3, mat3);
- mul_m3_m3m3(mat3, imat3, result); /* the matrix transforming vec_roll to desired roll */
-
- roll2 = atan2f(mat3[2][0], mat3[2][2]);
+ copy_m3_m4(mat3, param->next_mat);
+ mat3_vec_to_roll(mat3, h2, &roll2);
}
else {
h2[0] = 0.0f; h2[1] = 1.0f; h2[2] = 0.0f;
@@ -1716,21 +1704,28 @@ void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float
/* Computes vector and roll based on a rotation.
* "mat" must contain only a rotation, and no scaling. */
-void mat3_to_vec_roll(float mat[3][3], float r_vec[3], float *r_roll)
+void mat3_to_vec_roll(const float mat[3][3], float r_vec[3], float *r_roll)
{
if (r_vec) {
copy_v3_v3(r_vec, mat[1]);
}
if (r_roll) {
- float vecmat[3][3], vecmatinv[3][3], rollmat[3][3];
+ mat3_vec_to_roll(mat, mat[1], r_roll);
+ }
+}
- vec_roll_to_mat3(mat[1], 0.0f, vecmat);
- invert_m3_m3(vecmatinv, vecmat);
- mul_m3_m3m3(rollmat, vecmatinv, mat);
+/* Computes roll around the vector that best approximates the matrix.
+ * If vec is the Y vector from purely rotational mat, result should be exact. */
+void mat3_vec_to_roll(const float mat[3][3], const float vec[3], float *r_roll)
+{
+ float vecmat[3][3], vecmatinv[3][3], rollmat[3][3];
- *r_roll = atan2f(rollmat[2][0], rollmat[2][2]);
- }
+ vec_roll_to_mat3(vec, 0.0f, vecmat);
+ invert_m3_m3(vecmatinv, vecmat);
+ mul_m3_m3m3(rollmat, vecmatinv, mat);
+
+ *r_roll = atan2f(rollmat[2][0], rollmat[2][2]);
}
/* Calculates the rest matrix of a bone based on its vector and a roll around that vector. */